From f9eb6a7ae6a82dbc12b499be356cbd08c7dc7243 Mon Sep 17 00:00:00 2001 From: Ali Zaidi Date: Fri, 24 Sep 2021 12:43:17 +0100 Subject: [PATCH 1/3] Add Department model. --- api/flags/tests/test_create_flags.py | 3 ++- .../migrations/0002_auto_20210924_1241.py | 27 +++++++++++++++++++ api/teams/models.py | 8 ++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 api/teams/migrations/0002_auto_20210924_1241.py diff --git a/api/flags/tests/test_create_flags.py b/api/flags/tests/test_create_flags.py index a1bd4d6be..4b6cbd8ef 100644 --- a/api/flags/tests/test_create_flags.py +++ b/api/flags/tests/test_create_flags.py @@ -29,7 +29,8 @@ def test_gov_user_can_create_flags(self): self.assertEqual(response_data["colour"], FlagColours.ORANGE) self.assertEqual(response_data["label"], "This is label") self.assertEqual( - response_data["team"], {"id": str(self.team.id), "name": self.team.name, "part_of_ecju": None}, + response_data["team"], + {"id": str(self.team.id), "name": self.team.name, "part_of_ecju": None, "department": None}, ) @parameterized.expand( diff --git a/api/teams/migrations/0002_auto_20210924_1241.py b/api/teams/migrations/0002_auto_20210924_1241.py new file mode 100644 index 000000000..482a1a4ef --- /dev/null +++ b/api/teams/migrations/0002_auto_20210924_1241.py @@ -0,0 +1,27 @@ +# Generated by Django 3.1.12 on 2021-09-24 11:41 + +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + ('teams', '0001_squashed_0003_auto_20210325_0812'), + ] + + operations = [ + migrations.CreateModel( + name='Department', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('name', models.TextField(unique=True)), + ], + ), + migrations.AddField( + model_name='team', + name='department', + field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='teams', to='teams.department'), + ), + ] diff --git a/api/teams/models.py b/api/teams/models.py index c33c91500..b5d3a1496 100644 --- a/api/teams/models.py +++ b/api/teams/models.py @@ -3,6 +3,11 @@ from django.db import models +class Department(models.Model): + id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + name = models.TextField(unique=True) + + class TeamManager(models.Manager): def get_by_natural_key(self, name): return self.get(name=name) @@ -12,6 +17,9 @@ class Team(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) name = models.TextField(default=None, unique=True) part_of_ecju = models.BooleanField(default=None, null=True) + department = models.ForeignKey( + Department, null=True, blank=True, default=None, on_delete=models.SET_NULL, related_name="teams" + ) objects = TeamManager() From 31a03daac8dfa5bee1030a35edf9fe205a50153a Mon Sep 17 00:00:00 2001 From: Ali Zaidi Date: Fri, 24 Sep 2021 13:39:21 +0100 Subject: [PATCH 2/3] Add DepartmentSLA model. --- api/cases/migrations/0050_departmentsla.py | 24 ++++++++++++++++++++++ api/cases/models.py | 8 +++++++- 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 api/cases/migrations/0050_departmentsla.py diff --git a/api/cases/migrations/0050_departmentsla.py b/api/cases/migrations/0050_departmentsla.py new file mode 100644 index 000000000..022c2404f --- /dev/null +++ b/api/cases/migrations/0050_departmentsla.py @@ -0,0 +1,24 @@ +# Generated by Django 3.1.12 on 2021-09-24 12:39 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('teams', '0002_auto_20210924_1241'), + ('cases', '0049_auto_20210322_1838'), + ] + + operations = [ + migrations.CreateModel( + name='DepartmentSLA', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('sla_days', models.IntegerField()), + ('case', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='department_slas', to='cases.case')), + ('department', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='department_slas', to='teams.department')), + ], + ), + ] diff --git a/api/cases/models.py b/api/cases/models.py index 1dba2575c..4be108c39 100644 --- a/api/cases/models.py +++ b/api/cases/models.py @@ -34,7 +34,7 @@ from api.staticdata.statuses.enums import CaseStatusEnum from api.staticdata.statuses.libraries.get_case_status import get_case_status_by_status from api.staticdata.statuses.models import CaseStatus -from api.teams.models import Team +from api.teams.models import Team, Department from api.users.models import ( BaseUser, ExporterUser, @@ -249,6 +249,12 @@ class CaseAssignmentSla(models.Model): case = models.ForeignKey(Case, related_name="slas", on_delete=models.CASCADE) +class DepartmentSLA(models.Model): + sla_days = models.IntegerField() + department = models.ForeignKey(Department, on_delete=models.CASCADE, related_name="department_slas") + case = models.ForeignKey(Case, on_delete=models.CASCADE, related_name="department_slas") + + class CaseReferenceCode(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) reference_number = models.IntegerField() From 882eb5492d7d82c04aa76bc9a45e296bba0157ef Mon Sep 17 00:00:00 2001 From: Ali Zaidi Date: Fri, 24 Sep 2021 14:29:44 +0100 Subject: [PATCH 3/3] Update department SLA in task. --- api/cases/tasks.py | 12 +++++++++++- api/cases/tests/test_sla.py | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/api/cases/tasks.py b/api/cases/tasks.py index a0af7bc4a..8f4684cd7 100644 --- a/api/cases/tasks.py +++ b/api/cases/tasks.py @@ -10,7 +10,7 @@ from pytz import timezone as tz from api.cases.enums import CaseTypeSubTypeEnum -from api.cases.models import Case, CaseAssignmentSla, CaseQueue +from api.cases.models import Case, CaseAssignmentSla, CaseQueue, DepartmentSLA from api.cases.models import EcjuQuery from api.common.dates import is_weekend, is_bank_holiday from api.staticdata.statuses.enums import CaseStatusEnum @@ -106,12 +106,22 @@ def update_cases_sla(): ) with transaction.atomic(): for assignment in CaseQueue.objects.filter(case__in=cases): + # Update team SLAs try: assignment_sla = CaseAssignmentSla.objects.get(queue=assignment.queue, case=assignment.case) assignment_sla.sla_days += 1 assignment_sla.save() except CaseAssignmentSla.DoesNotExist: CaseAssignmentSla.objects.create(queue=assignment.queue, case=assignment.case, sla_days=1) + # Update department SLAs + department = assignment.queue.team.department + if department is not None: + try: + department_sla = DepartmentSLA.objects.get(department=department, case=assignment.case) + department_sla.sla_days += 1 + department_sla.save() + except DepartmentSLA.DoesNotExist: + DepartmentSLA.objects.create(department=department, case=assignment.case, sla_days=1) results = cases.select_for_update().update( sla_days=F("sla_days") + 1, sla_remaining_days=F("sla_remaining_days") - 1, sla_updated_at=date, diff --git a/api/cases/tests/test_sla.py b/api/cases/tests/test_sla.py index ee6899540..f1ab957ce 100644 --- a/api/cases/tests/test_sla.py +++ b/api/cases/tests/test_sla.py @@ -2,7 +2,6 @@ from unittest import mock from unittest.mock import patch -import pytest from django.conf import settings from django.urls import reverse from django.utils import timezone @@ -20,9 +19,10 @@ SLA_UPDATE_CUTOFF_TIME, HMRC_QUERY_TARGET_DAYS, ) -from api.cases.models import CaseAssignmentSla +from api.cases.models import CaseAssignmentSla, CaseQueue, DepartmentSLA from api.staticdata.statuses.enums import CaseStatusEnum from api.staticdata.statuses.libraries.get_case_status import get_case_status_by_status +from api.teams.models import Department from test_helpers.clients import DataTestClient HOUR_BEFORE_CUTOFF = time(SLA_UPDATE_CUTOFF_TIME.hour - 1, 0, 0) @@ -572,3 +572,31 @@ def test_sla_not_update_for_terminal( self.assertEqual(results, 0) self.assertEqual(case.sla_days, 1) self.assertEqual(case.sla_remaining_days, STANDARD_APPLICATION_TARGET_DAYS - 1) + + +class DepartmentSlaTests(DataTestClient): + @mock.patch("api.cases.tasks.is_weekend") + @mock.patch("api.cases.tasks.is_bank_holiday") + def test_department_sla_updated( + self, mock_is_weekend, mock_is_bank_holiday, + ): + # The following is to ensure that this test doesn't fail on + # non-working days. + mock_is_weekend.return_value = False + mock_is_bank_holiday.return_value = False + # Create & submit an application + application = self.create_draft_standard_application(self.organisation) + case = self.submit_application(application) + _set_submitted_at(case, HOUR_BEFORE_CUTOFF) + # Assign the application to our team + CaseQueue.objects.create(case=case, queue=self.queue) + # Create a test department + test_department = Department(name="test") + test_department.save() + # In order to move the department SLA counter, we need to assign + # our team to a department + self.team.department = test_department + self.team.save() + update_cases_sla.now() + department_sla = DepartmentSLA.objects.get(department=test_department) + self.assertEqual(department_sla.sla_days, 1)