diff options
Diffstat (limited to 'ctrack/organisations')
16 files changed, 163 insertions, 310 deletions
diff --git a/ctrack/organisations/admin.py b/ctrack/organisations/admin.py index 203baa9..d3e6284 100644 --- a/ctrack/organisations/admin.py +++ b/ctrack/organisations/admin.py @@ -1,5 +1,7 @@ from django.contrib import admin +from ctrack.caf.models import CAF + from .models import ( Address, AddressType, @@ -18,6 +20,10 @@ def get_organisation_name(person): return Organisation.objects.filter(person__id=person.id).first().name +def get_first_caf(org): + return CAF.objects.filter(organisation__id=org.id).first().version + + # We need this to ensure the column header in the admin does't read the func name get_organisation_name.short_description = "Organisation" diff --git a/ctrack/organisations/migrations/0001_initial.py b/ctrack/organisations/migrations/0001_initial.py index a420fa1..c5ab495 100644 --- a/ctrack/organisations/migrations/0001_initial.py +++ b/ctrack/organisations/migrations/0001_initial.py @@ -1,5 +1,6 @@ -# Generated by Django 2.2.9 on 2020-04-03 14:07 +# Generated by Django 2.2.12 on 2020-08-27 09:40 +import django.contrib.auth from django.db import migrations, models import django.db.models.deletion import django_extensions.db.fields @@ -14,23 +15,6 @@ class Migration(migrations.Migration): operations = [ migrations.CreateModel( - name='Address', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('line1', models.CharField(max_length=255)), - ('line2', models.CharField(blank=True, max_length=255)), - ('line3', models.CharField(blank=True, max_length=255)), - ('city', models.CharField(max_length=100)), - ('county', models.CharField(blank=True, max_length=100)), - ('postcode', models.CharField(max_length=10)), - ('country', models.CharField(max_length=100)), - ('other_details', models.CharField(blank=True, max_length=255)), - ], - options={ - 'verbose_name_plural': 'Addresses', - }, - ), - migrations.CreateModel( name='AddressType', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), @@ -50,31 +34,16 @@ class Migration(migrations.Migration): ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=255)), ('slug', django_extensions.db.fields.AutoSlugField(blank=True, editable=False, populate_from=['name'])), - ('oes', models.BooleanField()), + ('oes', models.BooleanField(default=True)), ('designation_type', models.IntegerField(choices=[(1, 'Automatic'), (2, 'Reserve Power'), (3, 'NA')], default=1)), ('registered_company_name', models.CharField(blank=True, max_length=255)), ('registered_company_number', models.CharField(blank=True, max_length=100)), ('date_updated', models.DateField(auto_now=True)), - ('comments', models.TextField(max_length=500)), + ('comments', models.TextField(blank=True, max_length=500, null=True)), ('active', models.BooleanField(default=True)), ], ), migrations.CreateModel( - name='Role', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=100)), - ], - ), - migrations.CreateModel( - name='Submode', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('descriptor', models.CharField(max_length=100)), - ('mode', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='organisations.Mode')), - ], - ), - migrations.CreateModel( name='Person', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), @@ -100,10 +69,83 @@ class Migration(migrations.Migration): ('comments', models.TextField(blank=True, max_length=1000)), ('organisation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='organisations.Organisation')), ('predecessor', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='previous_person', to='organisations.Person')), - ('role', models.ManyToManyField(to='organisations.Role')), ], options={ 'verbose_name_plural': 'People', }, ), + migrations.CreateModel( + name='Role', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100)), + ], + ), + migrations.CreateModel( + name='Submode', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('descriptor', models.CharField(max_length=100)), + ('mode', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='organisations.Mode')), + ], + ), + migrations.CreateModel( + name='Stakeholder', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('person', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='organisations.Person')), + ], + ), + migrations.AddField( + model_name='person', + name='role', + field=models.ManyToManyField(to='organisations.Role'), + ), + migrations.AddField( + model_name='organisation', + name='submode', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='organisations.Submode'), + ), + migrations.CreateModel( + name='IncidentReport', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('person_involved', models.CharField(blank=True, max_length=100, verbose_name='Name of person reporting/detecting incident')), + ('role', models.CharField(blank=True, help_text='Role of person reporting/detecting incident', max_length=100)), + ('phone_number', models.CharField(max_length=30)), + ('email', models.EmailField(max_length=254)), + ('internal_incident_number', models.CharField(blank=True, max_length=30)), + ('date_time_incident_detected', models.DateTimeField(verbose_name='Date/Time incident detected')), + ('date_time_incident_reported', models.DateTimeField(auto_now=True, verbose_name='Date/Time incident reported')), + ('incident_type', models.CharField(choices=[('Cyber', 'Cyber'), ('Non-Cyber', 'Non-Cyber'), ('Both', 'Both'), ('Power Outage', 'Power Outage')], help_text='This can be appoximate', max_length=20)), + ('incident_status', models.CharField(choices=[('Detected', 'Detected'), ('Suspected', 'Suspected'), ('Resolved', 'Resolved')], max_length=20)), + ('incident_stage', models.CharField(choices=[('Ongoing', 'Ongoing'), ('Ended', 'Ended'), ('Ongoing but managed', 'Ongoing but managed')], max_length=20)), + ('summary', models.TextField(help_text='Please provide a summary of your understanding of the incident, including any impact to services and/or users.')), + ('mitigations', models.TextField(help_text='What investigations and/or mitigations have you or a third party performed or plan to perform?', verbose_name='Investigations or mitigations')), + ('others_informed', models.TextField(help_text='Who else has been informed about this incident?(CSIRT, NCSC, NCA, etc)', verbose_name='Others parties informed')), + ('next_steps', models.TextField(help_text='What are your planned next steps?', verbose_name='Planned next steps')), + ('dft_handle_status', models.CharField(choices=[('QUEUED', 'QUEUED'), ('REVIEWING', 'REVIEWING'), ('WAITING', 'WAITING'), ('COMPLETED', 'COMPLETED')], default='QUEUED', max_length=20)), + ('organisation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='organisations.Organisation')), + ('reporting_person', models.ForeignKey(on_delete=models.SET(django.contrib.auth.get_user_model), to='organisations.Person', verbose_name='Person reporting the incident')), + ], + ), + migrations.CreateModel( + name='Address', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('line1', models.CharField(max_length=255)), + ('line2', models.CharField(blank=True, max_length=255)), + ('line3', models.CharField(blank=True, max_length=255)), + ('city', models.CharField(max_length=100)), + ('county', models.CharField(blank=True, max_length=100)), + ('postcode', models.CharField(max_length=10)), + ('country', models.CharField(max_length=100)), + ('other_details', models.CharField(blank=True, max_length=255)), + ('organisation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='addresses', to='organisations.Organisation')), + ('type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='organisations.AddressType', verbose_name='Address Type')), + ], + options={ + 'verbose_name_plural': 'Addresses', + }, + ), ] diff --git a/ctrack/organisations/migrations/0002_auto_20200403_1407.py b/ctrack/organisations/migrations/0002_auto_20200403_1407.py deleted file mode 100644 index d9f3aed..0000000 --- a/ctrack/organisations/migrations/0002_auto_20200403_1407.py +++ /dev/null @@ -1,44 +0,0 @@ -# Generated by Django 2.2.9 on 2020-04-03 14:07 - -import ctrack.organisations.models -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('organisations', '0001_initial'), - ] - - operations = [ - migrations.AddField( - model_name='person', - name='updated_by', - field=models.ForeignKey(on_delete=models.SET(ctrack.organisations.models.Person.get_sentinel_user), to=settings.AUTH_USER_MODEL), - ), - migrations.AddField( - model_name='organisation', - name='submode', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='organisations.Submode'), - ), - migrations.AddField( - model_name='organisation', - name='updated_by', - field=models.ForeignKey(on_delete=models.SET(ctrack.organisations.models.Organisation.get_sentinel_user), to=settings.AUTH_USER_MODEL), - ), - migrations.AddField( - model_name='address', - name='organisation', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='addresses', to='organisations.Organisation'), - ), - migrations.AddField( - model_name='address', - name='type', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='organisations.AddressType', verbose_name='Address Type'), - ), - ] diff --git a/ctrack/organisations/migrations/0003_auto_20200424_1607.py b/ctrack/organisations/migrations/0003_auto_20200424_1607.py deleted file mode 100644 index 75268a0..0000000 --- a/ctrack/organisations/migrations/0003_auto_20200424_1607.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 2.2.9 on 2020-04-24 16:07 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('organisations', '0002_auto_20200403_1407'), - ] - - operations = [ - migrations.AlterField( - model_name='organisation', - name='comments', - field=models.TextField(blank=True, max_length=500, null=True), - ), - ] diff --git a/ctrack/organisations/migrations/0004_auto_20200513_1441.py b/ctrack/organisations/migrations/0004_auto_20200513_1441.py deleted file mode 100644 index 180211a..0000000 --- a/ctrack/organisations/migrations/0004_auto_20200513_1441.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.0.5 on 2020-05-13 14:41 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('organisations', '0003_auto_20200424_1607'), - ] - - operations = [ - migrations.AlterField( - model_name='organisation', - name='oes', - field=models.BooleanField(default=True), - ), - ] diff --git a/ctrack/organisations/migrations/0005_auto_20200525_1502.py b/ctrack/organisations/migrations/0005_auto_20200525_1502.py deleted file mode 100644 index 921fdbb..0000000 --- a/ctrack/organisations/migrations/0005_auto_20200525_1502.py +++ /dev/null @@ -1,29 +0,0 @@ -# Generated by Django 3.0.5 on 2020-05-25 15:02 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('organisations', '0004_auto_20200513_1441'), - ] - - operations = [ - migrations.RemoveField( - model_name='organisation', - name='updated_by', - ), - migrations.RemoveField( - model_name='person', - name='updated_by', - ), - migrations.CreateModel( - name='Stakeholder', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('person', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='organisations.Person')), - ], - ), - ] diff --git a/ctrack/organisations/migrations/0006_incidentreport.py b/ctrack/organisations/migrations/0006_incidentreport.py deleted file mode 100644 index 0528aaa..0000000 --- a/ctrack/organisations/migrations/0006_incidentreport.py +++ /dev/null @@ -1,35 +0,0 @@ -# Generated by Django 2.2.12 on 2020-05-29 12:56 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('organisations', '0005_auto_20200525_1502'), - ] - - operations = [ - migrations.CreateModel( - name='IncidentReport', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('role', models.CharField(help_text='Please identify your role', max_length=100)), - ('phone_number', models.CharField(max_length=30)), - ('email', models.EmailField(max_length=254)), - ('internal_incident_number', models.CharField(blank=True, max_length=30)), - ('date_time_incident_detected', models.DateTimeField(help_text='This can be approximate', verbose_name='Date/Time incident detected')), - ('date_time_incident_reported', models.DateTimeField(verbose_name='Date/Time incident reported')), - ('incident_type', models.CharField(choices=[('cyber', 'Cyber'), ('non-cyber', 'Non-Cyber'), ('both', 'Both'), ('power', 'Power Outage')], help_text='This can be appoximate', max_length=10)), - ('incident_status', models.CharField(choices=[('detected', 'Detected'), ('suspected', 'Suspected'), ('resolved', 'Resolved')], max_length=10)), - ('incident_stage', models.CharField(choices=[('ongoing', 'Ongoing'), ('ended', 'Ended'), ('managed', 'Ongoing but managed')], max_length=10)), - ('summary', models.TextField(help_text='Please provide a summary of your understanding of the incident, including any impact to services and/or users.')), - ('mitigations', models.TextField(help_text='What investigations and/or mitigations have you or a third party performed or plan to perform?', verbose_name='Investigations or mitigations')), - ('others_informed', models.TextField(help_text='Who else has been informed about this incident?(CSIRT, NCSC, NCA, etc)', verbose_name='Others parties informed')), - ('next_steps', models.TextField(help_text='What are your planned next steps?', verbose_name='Planned next steps')), - ('organisation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='organisations.Organisation')), - ('reporting_person', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='organisations.Person', verbose_name='Person reporting the incident')), - ], - ), - ] diff --git a/ctrack/organisations/migrations/0007_auto_20200529_1520.py b/ctrack/organisations/migrations/0007_auto_20200529_1520.py deleted file mode 100644 index 59a5089..0000000 --- a/ctrack/organisations/migrations/0007_auto_20200529_1520.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 2.2.12 on 2020-05-29 15:20 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('organisations', '0006_incidentreport'), - ] - - operations = [ - migrations.AddField( - model_name='incidentreport', - name='dft_handle_status', - field=models.CharField(choices=[('queued', 'QUEUED'), ('reviewing', 'REVIEWING'), ('waiting', 'WAITING'), ('completed', 'COMPLETE')], default='queued', max_length=20), - ), - migrations.AlterField( - model_name='incidentreport', - name='date_time_incident_reported', - field=models.DateTimeField(auto_now=True, verbose_name='Date/Time incident reported'), - ), - ] diff --git a/ctrack/organisations/migrations/0008_auto_20200529_1545.py b/ctrack/organisations/migrations/0008_auto_20200529_1545.py deleted file mode 100644 index 1c4cec6..0000000 --- a/ctrack/organisations/migrations/0008_auto_20200529_1545.py +++ /dev/null @@ -1,38 +0,0 @@ -# Generated by Django 2.2.12 on 2020-05-29 15:45 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('organisations', '0007_auto_20200529_1520'), - ] - - operations = [ - migrations.AlterField( - model_name='incidentreport', - name='date_time_incident_detected', - field=models.DateTimeField(verbose_name='Date/Time incident detected'), - ), - migrations.AlterField( - model_name='incidentreport', - name='dft_handle_status', - field=models.CharField(choices=[('QUEUED', 'QUEUED'), ('REVIEWING', 'REVIEWING'), ('WAITING', 'WAITING'), ('COMPLETED', 'COMPLETED')], default='QUEUED', max_length=20), - ), - migrations.AlterField( - model_name='incidentreport', - name='incident_stage', - field=models.CharField(choices=[('Ongoing', 'Ongoing'), ('Ended', 'Ended'), ('Ongoing but managed', 'Ongoing but managed')], max_length=20), - ), - migrations.AlterField( - model_name='incidentreport', - name='incident_status', - field=models.CharField(choices=[('Detected', 'Detected'), ('Suspected', 'Suspected'), ('Resolved', 'Resolved')], max_length=20), - ), - migrations.AlterField( - model_name='incidentreport', - name='incident_type', - field=models.CharField(choices=[('Cyber', 'Cyber'), ('Non-Cyber', 'Non-Cyber'), ('Both', 'Both'), ('Power Outage', 'Power Outage')], help_text='This can be appoximate', max_length=20), - ), - ] diff --git a/ctrack/organisations/migrations/0009_incidentreport_person_involved.py b/ctrack/organisations/migrations/0009_incidentreport_person_involved.py deleted file mode 100644 index ea4799c..0000000 --- a/ctrack/organisations/migrations/0009_incidentreport_person_involved.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 2.2.12 on 2020-05-29 16:01 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('organisations', '0008_auto_20200529_1545'), - ] - - operations = [ - migrations.AddField( - model_name='incidentreport', - name='person_involved', - field=models.CharField(blank=True, max_length=100, verbose_name='Name of person reporting/detecting incident'), - ), - ] diff --git a/ctrack/organisations/migrations/0010_auto_20200529_1602.py b/ctrack/organisations/migrations/0010_auto_20200529_1602.py deleted file mode 100644 index 2986d36..0000000 --- a/ctrack/organisations/migrations/0010_auto_20200529_1602.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 2.2.12 on 2020-05-29 16:02 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('organisations', '0009_incidentreport_person_involved'), - ] - - operations = [ - migrations.AlterField( - model_name='incidentreport', - name='role', - field=models.CharField(blank=True, help_text='Role of person reporting/detecting incident', max_length=100), - ), - ] diff --git a/ctrack/organisations/migrations/0011_auto_20200531_1441.py b/ctrack/organisations/migrations/0011_auto_20200531_1441.py deleted file mode 100644 index 3dced7d..0000000 --- a/ctrack/organisations/migrations/0011_auto_20200531_1441.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 2.2.12 on 2020-05-31 14:41 - -import django.contrib.auth -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('organisations', '0010_auto_20200529_1602'), - ] - - operations = [ - migrations.AlterField( - model_name='incidentreport', - name='reporting_person', - field=models.ForeignKey(on_delete=models.SET(django.contrib.auth.get_user_model), to='organisations.Person', verbose_name='Person reporting the incident'), - ), - ] diff --git a/ctrack/organisations/models.py b/ctrack/organisations/models.py index 9eb0a23..f91dabf 100644 --- a/ctrack/organisations/models.py +++ b/ctrack/organisations/models.py @@ -153,7 +153,19 @@ class Organisation(models.Model): return self.person_set.filter(primary_nis_contact=True) def applicable_systems(self): - return self.applicablesystem_set.all() + # return self.applicablesystem_set.all() + ess = self.essentialservice_set.all() + out = [] + for es in ess: + out.extend(es.systems.all()) + return out + + def systems(self): + ess = self.essentialservice_set.all() + out = [] + for es in ess: + out.extend(list(es.systems.all())) + return out class Address(models.Model): diff --git a/ctrack/organisations/templates/organisations/organisation_detail.html b/ctrack/organisations/templates/organisations/organisation_detail.html index 8c9ac3b..a86adf1 100644 --- a/ctrack/organisations/templates/organisations/organisation_detail.html +++ b/ctrack/organisations/templates/organisations/organisation_detail.html @@ -65,6 +65,33 @@ </div> </div> </div> + + <div class="row"> + <div class="col-md-12 my-2"> + <div class="card bg-light"> + <div class="card-body"> + <div class="card-title">Essential Services</div> + <div class="table table-responsive"> + <table class="table"> + {% if applicable_systems|length > 0 %} + {% for es in essential_services %} + <tr> + <td style="width: 18%">{{ es.name }}</td> + <td>{{ es.description }}<br> + <span class="text-muted"> | <a href="#" class="small">Edit System</a></span> + </td> + </tr> + {% endfor %} + {% else %} + <p>button to create new one here</p> + {% endif %} + </table> + </div> + </div> + </div> + </div> + </div> + <div class="row"> <div class="col-md-12 my-2"> <div class="card bg-light"> @@ -79,7 +106,7 @@ <tr> <td><a href="{% url "caf:ass_detail" ass.id %}">{{ ass.name }}</a></td> <td>{{ ass.function }}<br> - <a href="{% url "caf:detail" ass.caf.pk %}" class="small"> + <a href="{% url "caf:detail" ass.pk %}" class="small"> {{ ass.caf }} </a> <span class="text-muted"> | <a href="#" class="small">Edit System</a></span> </td> @@ -95,21 +122,13 @@ </div> </div> </div> + + <div class="row"> <div class="col-md-12 my-2"> <div class="card bg-light"> <div class="card-body"> - <div class="card-title">OES Engagements<a href="{% url "register:create" %}" class="btn btn-primary btn-sm float-right">Add - new...</a></div> - <div class="table table-responsive"> - <table class="table"> - {% if engagement_events|length > 0 %} - {% for event in engagement_events %} - <tr> - <td><a href="#">{{ event.type}}</a></td> - <td>{{ event.short_description }}</td> - </tr> - {% endfor %} + <div class="card-title">OES Engagements<a href="{% url "register:create" %}" class="btn btn-primary btn-sm float-right">Add new...</a></div> <div class="table table-responsive"> <table class="table"> {% if engagement_events|length > 0 %} {% for event in engagement_events %} <tr> <td><a href="#">{{ event.type}}</a></td> <td>{{ event.short_description }}</td> </tr> {% endfor %} {% else %} <a class="btn btn-primary" href="{% url "register:create" %}" role="button">Add new...</a> diff --git a/ctrack/organisations/tests/test_models.py b/ctrack/organisations/tests/test_models.py index c6314af..108d0ce 100644 --- a/ctrack/organisations/tests/test_models.py +++ b/ctrack/organisations/tests/test_models.py @@ -1,7 +1,14 @@ +import random + import pytest + from slugify import slugify from ctrack.organisations.models import IncidentReport, Organisation +from ctrack.caf.models import CAF, Grading +from ctrack.caf.tests.factories import ApplicableSystemFactory +from ctrack.caf.models import EssentialService +from ctrack.core.utils import fnames pytestmark = pytest.mark.django_db @@ -21,3 +28,27 @@ def test_update_organisation(org_with_people): def test_new_address(addr): # The address "has" an organisation assert addr.organisation.name + + +def test_essential_service(org): + q1 = Grading.objects.create(descriptor="Q1", description="baws", type="QUALITY") + c1 = Grading.objects.create( + descriptor="C1", description="baws_c", type="CONFIDENCE" + ) + caf = CAF.objects.create( + quality_grading=q1, + organisation=org, + confidence_grading=c1, + triage_review_date=None, + triage_review_inspector=None, + ) + ass = ApplicableSystemFactory.create(name=random.choice(fnames), caf=caf,) + ass2 = ApplicableSystemFactory.create(name=random.choice(fnames), caf=caf,) + es = EssentialService.objects.create( + name="Test ES", description="Test ES Description", organisation=org + ) + es.systems.add(ass, ass2) + assert es.organisation.name == org.name + assert es.name == "Test ES" + assert es.systems.count() == 2 + assert ass.name in [s.name for s in org.systems()] diff --git a/ctrack/organisations/views.py b/ctrack/organisations/views.py index 394966a..7652783 100644 --- a/ctrack/organisations/views.py +++ b/ctrack/organisations/views.py @@ -10,6 +10,7 @@ from ctrack.register.models import EngagementEvent from .forms import AddressInlineFormSet, IncidentReportForm, OrganisationCreateForm from .models import IncidentReport, Organisation, Person +from ctrack.caf.models import EssentialService class PersonListView(LoginRequiredMixin, PermissionRequiredMixin, ListView): @@ -66,6 +67,7 @@ class OrganisationDetailView(LoginRequiredMixin, PermissionRequiredMixin, Detail org = kwargs["object"] peoples = org.person_set.all() engagement_events = EngagementEvent.objects.filter(participants__in=peoples) + essential_services = EssentialService.objects.filter(organisation=org) no_addr = org.addresses.count() if no_addr > 1: context["no_addr"] = no_addr @@ -77,9 +79,10 @@ class OrganisationDetailView(LoginRequiredMixin, PermissionRequiredMixin, Detail context["addr"] = addr people = org.person_set.all() context["people"] = people - applicable_systems = org.applicablesystem_set.all() + applicable_systems = org.applicable_systems() context["applicable_systems"] = applicable_systems context["engagement_events"] = engagement_events + context["essential_services"] = essential_services return context |