Skip to content

Commit

Permalink
Implementation of a state machine and workflow logic for action
Browse files Browse the repository at this point in the history
  • Loading branch information
Stéphane Diacquenod committed Feb 7, 2023
1 parent 9bcea4b commit 63af006
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 21 deletions.
31 changes: 28 additions & 3 deletions conformity/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,32 @@ def __init__(self, *args, **kwargs):
self.fields['create_date'].disabled = True
self.fields['update_date'].disabled = True

if self.get_initial_for_field(self.fields['status'], 'status') is Action.Status.CANCELED.value \
or self.get_initial_for_field(self.fields['status'], 'status') is Action.Status.ENDED.value:
for key, value in self.fields.items():
generic_fields = ['title', 'owner', 'status', 'status_comment']
analyse_fields = ['organization', 'associated_conformity', 'associated_findings', 'description']
plan_fields = ['plan_start_date', 'plan_end_date', 'plan_comment']
implement_fields = ['implement_start_date', 'implement_end_date', 'implement_status', 'implement_comment']
control_fields = ['control_date', 'control_comment', 'control_user']

'''Disable everything and enable only the on matching the current status'''
for key, value in self.fields.items():
if key not in generic_fields:
self.fields[key].disabled = True

if self.get_initial_for_field(self.fields['status'], 'status') is Action.Status.ANALYSING.value:
for key in analyse_fields:
self.fields[key].disabled = False
elif self.get_initial_for_field(self.fields['status'], 'status') is Action.Status.PLANNING.value:
for key in plan_fields:
self.fields[key].disabled = False
elif self.get_initial_for_field(self.fields['status'], 'status') is Action.Status.IMPLEMENTING.value:
for key in implement_fields:
self.fields[key].disabled = False
elif self.get_initial_for_field(self.fields['status'], 'status') is Action.Status.CONTROLLING.value:
for key in control_fields:
self.fields[key].disabled = False
elif self.get_initial_for_field(self.fields['status'], 'status') is Action.Status.CANCELED.value:
for key in generic_fields:
self.fields[key].disabled = True
elif self.get_initial_for_field(self.fields['status'], 'status') is Action.Status.ENDED.value:
for key in generic_fields:
self.fields[key].disabled = True
18 changes: 18 additions & 0 deletions conformity/migrations/0022_action_status_comment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 4.1.5 on 2023-02-07 04:42

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('conformity', '0021_alter_action_status'),
]

operations = [
migrations.AddField(
model_name='action',
name='status_comment',
field=models.CharField(blank=True, max_length=4096),
),
]
19 changes: 19 additions & 0 deletions conformity/migrations/0023_alter_action_organization.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 4.1.5 on 2023-02-07 04:55

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('conformity', '0022_action_status_comment'),
]

operations = [
migrations.AlterField(
model_name='action',
name='organization',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='conformity.organization'),
),
]
20 changes: 12 additions & 8 deletions conformity/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ class Meta:
ordering = ['name']

def __str__(self):
return str(self.name)
return str(self.name + ": " + self.title)

def natural_key(self):
return self.name
Expand Down Expand Up @@ -395,25 +395,29 @@ class Status(models.TextChoices):
PLANNING = '2', _('Planning')
IMPLEMENTING = '3', _('Implementing')
CONTROLLING = '4', _('Controlling')
ENDED = '5', _('Closed')
"""MISC status"""
FROZEN = '7', _('Frozen')
ENDED = '8', _('Closed')
CANCELED = '9', _('Canceled')

' Analyse Phase'
' Generic'
title = models.CharField(max_length=256)
description = models.CharField(max_length=4096, blank=True)
create_date = models.DateField(default=timezone.now)
update_date = models.DateField(default=timezone.now)
organization = models.ForeignKey(Organization, on_delete=models.CASCADE)
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, blank=True)
associated_conformity = models.ManyToManyField(Conformity, blank=True)
associated_findings = models.ManyToManyField(Finding, blank=True)
#TODO associated_risks = models.ManyToManyField(Risk, blank=True)
status = models.CharField(
max_length=5,
choices=Status.choices,
default=Status.ANALYSING,
)
status_comment = models.CharField(max_length=4096, blank=True)

' Analyse Phase'
description = models.CharField(max_length=4096, blank=True)
organization = models.ForeignKey(Organization, on_delete=models.CASCADE, blank=True, null=True)
associated_conformity = models.ManyToManyField(Conformity, blank=True)
associated_findings = models.ManyToManyField(Finding, blank=True)
#TODO associated_risks = models.ManyToManyField(Risk, blank=True)

' PLAN phase'
plan_start_date = models.DateField(null=True, blank=True)
Expand Down
27 changes: 22 additions & 5 deletions conformity/templates/conformity/action_form.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ <h1 class="h1 bi bi-pencil-square" xmlns="http://www.w3.org/1999/html"> Edit of
<div class="row justify-content-center">
<div class="col col-6">
{% bootstrap_field form.title layout='floating' %}
{% bootstrap_field form.organization layout='floating' %}
{% bootstrap_field form.owner layout='floating' %}
{% bootstrap_field form.status layout='floating' %}
{% bootstrap_field form.status_comment layout='floating' %}
<p class="text-center fw-lighter mx-3">Created on {{ form.create_date.value }}, laste update {{ form.update_date.value }}.</p>
<div class="accordion" id="accordion">
<div class="accordion-item">
Expand All @@ -27,6 +27,7 @@ <h2 class="accordion-header" id="headingAnalyse">
data-bs-parent="#accordion">
<div class="accordion-body text-bg-light">
{% bootstrap_field form.description layout='floating' %}
{% bootstrap_field form.organization layout='floating' %}
{% bootstrap_field form.associated_conformity layout='floating' %}
{% bootstrap_field form.associated_findings layout='floating' %}
</div>
Expand Down Expand Up @@ -97,19 +98,35 @@ <h2 class="accordion-header" id="headingControl">
document.getElementById('id_plan_end_date').type = 'Date'
</script>
<script>
if (document.getElementById('id_status').value == 'A') {
// Open the good accordion at page load
if (document.getElementById('id_status').value == '1') {
document.getElementById('id_status_comment').parentNode.classList.add("d-none");
document.getElementById('buttonAnalyse').classList.remove("collapsed");
document.getElementById('collapseAnalyse').classList.add("show");
} else if (document.getElementById('id_status').value == 'P') {
} else if (document.getElementById('id_status').value == '2') {
document.getElementById('id_status_comment').parentNode.classList.add("d-none");
document.getElementById('buttonPlan').classList.remove("collapsed");
document.getElementById('collapsePlan').classList.add("show");
} else if (document.getElementById('id_status').value == 'I') {
} else if (document.getElementById('id_status').value == '3') {
document.getElementById('id_status_comment').parentNode.classList.add("d-none");
document.getElementById('buttonImplement').classList.remove("collapsed");
document.getElementById('collapseImplement').classList.add("show");
} else if (document.getElementById('id_status').value == 'C') {
} else if (document.getElementById('id_status').value == '4') {
document.getElementById('id_status_comment').parentNode.classList.add("d-none");
document.getElementById('buttonControl').classList.remove("collapsed");
document.getElementById('collapseControl').classList.add("show");
}

// Display the field id_status_comment for MISC status
document.getElementById('id_status').onchange = function(){
if (document.getElementById('id_status').value > '5') {
document.getElementById('id_status_comment').parentNode.classList.remove("d-none");
document.getElementById('id_status_comment').required = true;
} else {
document.getElementById('id_status_comment').parentNode.classList.add("d-none");
document.getElementById('id_status_comment').required = false;
}
};
</script>
</form>
{% endblock %}
8 changes: 4 additions & 4 deletions conformity/templates/conformity/action_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ <h1 class="h1 bi bi-arrow-repeat"> Actions </h1>
{% if action.status == "4" %}
<i class="bi bi-hexagon-fill text-success"></i>
{% endif %}
{% if action.status == "7" %}
<i class="bi bi-hexagon"></i>
{% endif %}
{% if action.status == "8" %}
{% if action.status == "5" %}
<i class="bi bi-hexagon-fill"></i>
{% endif %}
{% if action.status == "7" %}
<i class="bi bi-hexagon text-danger"></i>
{% endif %}
{% if action.status == "9" %}
<i class="bi bi-hexagon-fill text-danger"></i>
{% endif %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{% block header %}
<h1 class="h1 bi bi-shield-shaded">
{{ conformity_list.0.organization }} conformity to {{ conformity_list.0.measure.policy }}:
<span class="badge rounded-pill bg-primary"> {{ conformity_list.0.status }}%</span>
<span class="badge rounded-pill bg-primary ms-3"> Conformity: {{ conformity_list.0.status }} %</span>
</h1>
{% endblock %}

Expand Down

0 comments on commit 63af006

Please sign in to comment.