aboutsummaryrefslogtreecommitdiffstats
path: root/ctrack/organisations
diff options
context:
space:
mode:
Diffstat (limited to 'ctrack/organisations')
-rw-r--r--ctrack/organisations/admin.py6
-rw-r--r--ctrack/organisations/migrations/0001_initial.py114
-rw-r--r--ctrack/organisations/migrations/0002_auto_20200403_1407.py44
-rw-r--r--ctrack/organisations/migrations/0003_auto_20200424_1607.py18
-rw-r--r--ctrack/organisations/migrations/0004_auto_20200513_1441.py18
-rw-r--r--ctrack/organisations/migrations/0005_auto_20200525_1502.py29
-rw-r--r--ctrack/organisations/migrations/0006_incidentreport.py35
-rw-r--r--ctrack/organisations/migrations/0007_auto_20200529_1520.py23
-rw-r--r--ctrack/organisations/migrations/0008_auto_20200529_1545.py38
-rw-r--r--ctrack/organisations/migrations/0009_incidentreport_person_involved.py18
-rw-r--r--ctrack/organisations/migrations/0010_auto_20200529_1602.py18
-rw-r--r--ctrack/organisations/migrations/0011_auto_20200531_1441.py19
-rw-r--r--ctrack/organisations/models.py14
-rw-r--r--ctrack/organisations/templates/organisations/organisation_detail.html43
-rw-r--r--ctrack/organisations/tests/test_models.py31
-rw-r--r--ctrack/organisations/views.py5
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