diff --git a/api/cases/models.py b/api/cases/models.py index d54dc7b9c2..5598a5c247 100644 --- a/api/cases/models.py +++ b/api/cases/models.py @@ -14,7 +14,6 @@ from queryable_properties.managers import QueryablePropertiesManager from queryable_properties.properties import queryable_property - from api.audit_trail.enums import AuditType from api.cases.enums import ( AdviceType, @@ -53,6 +52,7 @@ UserOrganisationRelationship, ExporterNotification, ) +from api.users.enums import SystemUser from lite_content.lite_api import strings denial_reasons_logger = logging.getLogger(settings.DENIAL_REASONS_DELETION_LOGGER) @@ -313,6 +313,24 @@ def set_sub_status(self, sub_status_id): payload={"sub_status": self.sub_status.name, "status": CaseStatusEnum.get_text(self.status.status)}, ) + def create_system_mention(self, case_note_text, mention_user): + """ + Create a LITE system mention e.g. exporter responded to an ECJU query + """ + from api.audit_trail import service as audit_trail_service + + case_note = CaseNote(text=case_note_text, case=self, user=BaseUser.objects.get(id=SystemUser.id)) + case_note.save() + case_note_mentions = CaseNoteMentions(user=mention_user, case_note=case_note) + case_note_mentions.save() + audit_payload = { + "mention_users": [f"{mention_user.full_name} ({mention_user.team.name})"], + "additional_text": case_note_text, + } + audit_trail_service.create_system_user_audit( + verb=AuditType.CREATED_CASE_NOTE_WITH_MENTIONS, action_object=case_note, target=self, payload=audit_payload + ) + class CaseQueue(TimestampableModel): case = models.ForeignKey(Case, related_name="casequeues", on_delete=models.DO_NOTHING) diff --git a/api/cases/tests/test_case_ecju_queries.py b/api/cases/tests/test_case_ecju_queries.py index bbe3b89abf..6959031acb 100644 --- a/api/cases/tests/test_case_ecju_queries.py +++ b/api/cases/tests/test_case_ecju_queries.py @@ -23,6 +23,7 @@ from api.staticdata.statuses.libraries.get_case_status import get_case_status_by_status from test_helpers.clients import DataTestClient from api.users.tests.factories import ExporterUserFactory +from api.cases.models import CaseNoteMentions faker = Faker() @@ -679,6 +680,8 @@ def test_exporter_cannot_delete_documents_of_closed_query(self): @parameterized.expand(["this is some response text", ""]) def test_exporter_responding_to_query_creates_case_note_mention_for_caseworker(self, response_text): case = self.create_standard_application_case(self.organisation) + + # caseworker raises a query url = reverse("cases:case_ecju_queries", kwargs={"pk": case.id}) question_text = "this is the question text" data = {"question": question_text, "query_type": ECJUQueryType.ECJU} @@ -687,14 +690,35 @@ def test_exporter_responding_to_query_creates_case_note_mention_for_caseworker(s response_data = response.json() ecju_query = EcjuQuery.objects.get(case=case) + self.assertFalse(ecju_query.is_query_closed) self.assertEqual(status.HTTP_201_CREATED, response.status_code) self.assertEqual(response_data["ecju_query_id"], str(ecju_query.id)) self.assertEqual(question_text, ecju_query.question) self.assertIsNone(ecju_query.response) + # exporter responds to the query url = reverse("cases:case_ecju_query", kwargs={"pk": case.id, "ecju_pk": ecju_query.id}) data = {"response": response_text} + response = self.client.put(url, data, **self.exporter_headers) + ecju_query = EcjuQuery.objects.get(case=case) self.assertEqual(response.status_code, status.HTTP_201_CREATED) - self.assertEqual(list(response.json().keys()), ["ecju_query", "case_note", "case_note_mentions"]) + self.assertTrue(ecju_query.is_query_closed) + + # check case note mention is created + case_note_mentions = CaseNoteMentions.objects.first() + case_note = case_note_mentions.case_note + audit_object = Audit.objects.first() + + expected_gov_user = ecju_query.raised_by_user + expected_exporter_user = ecju_query.responded_by_user + expected_mention_users_text = f"{expected_gov_user.full_name} ({expected_gov_user.team.name})" + expected_case_note_text = f"{expected_exporter_user.get_full_name()} has responded to a query." + + self.assertEqual(case_note_mentions.user, expected_gov_user) + self.assertEqual(case_note.text, expected_case_note_text) + self.assertEqual( + audit_object.payload, + {"mention_users": [expected_mention_users_text], "additional_text": expected_case_note_text}, + ) diff --git a/api/cases/views/views.py b/api/cases/views/views.py index 29e67170f1..c7b44d4407 100644 --- a/api/cases/views/views.py +++ b/api/cases/views/views.py @@ -629,6 +629,8 @@ def put(self, request, pk, ecju_pk): data={"errors": "Enter a reason why you are closing the query"}, status=status.HTTP_400_BAD_REQUEST ) + exporter_user_full_name = getattr(get_user_by_pk(request.user.pk), "full_name", "Exporter user") + data = {"responded_by_user": str(request.user.pk)} if request.data.get("response"): @@ -653,14 +655,13 @@ def put(self, request, pk, ecju_pk): payload={"ecju_response": data.get("response")}, ) - # Create case note mention notification for case worker. - # LITE system is the user that creates the case note. - mentions_data = self._create_case_note_mention(request, ecju_query, serializer) - if "errors" in mentions_data.keys(): - return JsonResponse(data=mentions_data, status=status.HTTP_400_BAD_REQUEST) + ecju_query.case.create_system_mention( + case_note_text=f"{exporter_user_full_name} has responded to a query.", + mention_user=ecju_query.raised_by_user, + ) return JsonResponse( - data={"ecju_query": serializer.data, **mentions_data}, + data={"ecju_query": serializer.data}, status=status.HTTP_201_CREATED, ) else: @@ -668,40 +669,6 @@ def put(self, request, pk, ecju_pk): return JsonResponse(data={"errors": serializer.errors}, status=status.HTTP_400_BAD_REQUEST) - def _create_case_note_mention(self, request, ecju_query, ecju_query_serializer): - exporter_user_full_name = getattr(get_user_by_pk(request.user.pk), "full_name", "Exporter user") - case_note_data = { - "text": f"{exporter_user_full_name} has responded to a query.", - "case": ecju_query_serializer.instance.case.id, - "user": SystemUser.id, - } - case_note_serializer = CaseNoteSerializer(data=case_note_data) - if case_note_serializer.is_valid(): - case_note_serializer.save() - case_note_mentions_data = [ - {"user": ecju_query.raised_by_user.pk, "case_note": case_note_serializer.instance.id} - ] - case_note_mentions_serializer = CaseNoteMentionsSerializer( - data=case_note_mentions_data, - many=True, - ) - if case_note_mentions_serializer.is_valid(): - case_note_mentions_serializer.save() - audit_trail_service.create_system_user_audit( - verb=AuditType.CREATED_CASE_NOTE_WITH_MENTIONS, - action_object=case_note_serializer.instance, - target=ecju_query_serializer.instance.case, - payload={"mention_users": case_note_mentions_serializer.get_user_mention_names()}, - ) - return { - "case_note": case_note_serializer.data, - "case_note_mentions": case_note_mentions_serializer.data, - } - else: - return {"errors": case_note_mentions_serializer.errors} - else: - return {"errors": case_note_serializer.errors} - class EcjuQueryAddDocument(APIView): authentication_classes = (ExporterAuthentication,)