From 72685a7038f6c3f8250fa9a249c992bfac4143e8 Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Wed, 8 May 2024 11:51:34 +0530 Subject: [PATCH 1/5] Adds support for doctors and nurses discussions threads in Discussion Notes --- care/facility/api/serializers/patient.py | 8 ++++++++ care/facility/api/viewsets/patient.py | 2 ++ .../migrations/0429_patientnotes_thread.py | 19 +++++++++++++++++++ care/facility/models/patient.py | 10 ++++++++++ 4 files changed, 39 insertions(+) create mode 100644 care/facility/migrations/0429_patientnotes_thread.py diff --git a/care/facility/api/serializers/patient.py b/care/facility/api/serializers/patient.py index f526db1b73..2e5a214c90 100644 --- a/care/facility/api/serializers/patient.py +++ b/care/facility/api/serializers/patient.py @@ -25,6 +25,7 @@ PatientContactDetails, PatientMetaInfo, PatientNotes, + PatientNoteThreadChoices, PatientRegistration, ) from care.facility.models.bed import ConsultationBed @@ -514,6 +515,9 @@ class PatientNotesSerializer(serializers.ModelSerializer): allow_null=True, read_only=True, ) + thread = serializers.ChoiceField( + choices=PatientNoteThreadChoices, required=True, allow_null=False + ) def validate_empty_values(self, data): if not data.get("note", "").strip(): @@ -548,6 +552,8 @@ def create(self, validated_data): return instance def update(self, instance, validated_data): + validated_data.pop("thread", None) # Disallow changing thread of the note. + user = self.context["request"].user note = validated_data.get("note") @@ -572,6 +578,7 @@ class Meta: "note", "facility", "consultation", + "thread", "created_by_object", "user_type", "created_date", @@ -583,6 +590,7 @@ class Meta: "id", "created_date", "modified_date", + "user_type", "last_edited_by", "last_edited_date", ) diff --git a/care/facility/api/viewsets/patient.py b/care/facility/api/viewsets/patient.py index e7c5d618af..aed6928fbe 100644 --- a/care/facility/api/viewsets/patient.py +++ b/care/facility/api/viewsets/patient.py @@ -62,6 +62,7 @@ Facility, FacilityPatientStatsHistory, PatientNotes, + PatientNoteThreadChoices, PatientRegistration, ShiftingRequest, ) @@ -813,6 +814,7 @@ def list(self, request, *args, **kwargs): class PatientNotesFilterSet(filters.FilterSet): + thread = filters.ChoiceFilter(choices=PatientNoteThreadChoices.choices) consultation = filters.CharFilter(field_name="consultation__external_id") diff --git a/care/facility/migrations/0429_patientnotes_thread.py b/care/facility/migrations/0429_patientnotes_thread.py new file mode 100644 index 0000000000..5bc534b787 --- /dev/null +++ b/care/facility/migrations/0429_patientnotes_thread.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.8 on 2024-05-07 15:49 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("facility", "0428_alter_patientmetainfo_occupation"), + ] + + operations = [ + migrations.AddField( + model_name="patientnotes", + name="thread", + field=models.IntegerField( + choices=[(10, "DOCTORS"), (20, "NURSES")], db_index=True, default=10 + ), + ), + ] diff --git a/care/facility/models/patient.py b/care/facility/models/patient.py index 786ff584b7..aad9afb8d9 100644 --- a/care/facility/models/patient.py +++ b/care/facility/models/patient.py @@ -732,6 +732,11 @@ class PatientMobileOTP(BaseModel): otp = models.CharField(max_length=10) +class PatientNoteThreadChoices(models.IntegerChoices): + DOCTORS = 10, "DOCTORS" + NURSES = 20, "NURSES" + + class PatientNotes(FacilityBaseModel, ConsultationRelatedPermissionMixin): patient = models.ForeignKey( PatientRegistration, on_delete=models.PROTECT, null=False, blank=False @@ -748,6 +753,11 @@ class PatientNotes(FacilityBaseModel, ConsultationRelatedPermissionMixin): on_delete=models.SET_NULL, null=True, ) + thread = models.IntegerField( + choices=PatientNoteThreadChoices.choices, + db_index=True, + default=PatientNoteThreadChoices.DOCTORS, + ) note = models.TextField(default="", blank=True) def get_related_consultation(self): From 44df226cee43b0a77e35989897df50e8b6d7954f Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Wed, 8 May 2024 11:54:27 +0530 Subject: [PATCH 2/5] switch to using small integer field --- care/facility/migrations/0429_patientnotes_thread.py | 4 ++-- care/facility/models/patient.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/care/facility/migrations/0429_patientnotes_thread.py b/care/facility/migrations/0429_patientnotes_thread.py index 5bc534b787..a98057a7b1 100644 --- a/care/facility/migrations/0429_patientnotes_thread.py +++ b/care/facility/migrations/0429_patientnotes_thread.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.8 on 2024-05-07 15:49 +# Generated by Django 4.2.8 on 2024-05-08 06:24 from django.db import migrations, models @@ -12,7 +12,7 @@ class Migration(migrations.Migration): migrations.AddField( model_name="patientnotes", name="thread", - field=models.IntegerField( + field=models.SmallIntegerField( choices=[(10, "DOCTORS"), (20, "NURSES")], db_index=True, default=10 ), ), diff --git a/care/facility/models/patient.py b/care/facility/models/patient.py index aad9afb8d9..94a06f0f5f 100644 --- a/care/facility/models/patient.py +++ b/care/facility/models/patient.py @@ -753,7 +753,7 @@ class PatientNotes(FacilityBaseModel, ConsultationRelatedPermissionMixin): on_delete=models.SET_NULL, null=True, ) - thread = models.IntegerField( + thread = models.SmallIntegerField( choices=PatientNoteThreadChoices.choices, db_index=True, default=PatientNoteThreadChoices.DOCTORS, From 5bf032d7985702131e5e0e0461420891c4283ed8 Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Wed, 8 May 2024 12:09:34 +0530 Subject: [PATCH 3/5] updated and fixes based on test cases --- care/facility/api/serializers/patient.py | 4 +++- care/facility/tests/test_patient_api.py | 9 ++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/care/facility/api/serializers/patient.py b/care/facility/api/serializers/patient.py index 2e5a214c90..680022c7d0 100644 --- a/care/facility/api/serializers/patient.py +++ b/care/facility/api/serializers/patient.py @@ -516,7 +516,7 @@ class PatientNotesSerializer(serializers.ModelSerializer): read_only=True, ) thread = serializers.ChoiceField( - choices=PatientNoteThreadChoices, required=True, allow_null=False + choices=PatientNoteThreadChoices, required=False, allow_null=False ) def validate_empty_values(self, data): @@ -525,6 +525,8 @@ def validate_empty_values(self, data): return super().validate_empty_values(data) def create(self, validated_data): + if "thread" not in validated_data: + raise serializers.ValidationError({"thread": "This field is required"}) user_type = User.REVERSE_TYPE_MAP[validated_data["created_by"].user_type] # If the user is a doctor and the note is being created in the home facility # then the user type is doctor else it is a remote specialist diff --git a/care/facility/tests/test_patient_api.py b/care/facility/tests/test_patient_api.py index d86f7fdd20..bf0af8838d 100644 --- a/care/facility/tests/test_patient_api.py +++ b/care/facility/tests/test_patient_api.py @@ -4,6 +4,7 @@ from rest_framework import status from rest_framework.test import APITestCase +from care.facility.models import PatientNoteThreadChoices from care.facility.models.icd11_diagnosis import ( ConditionVerificationStatus, ICD11Diagnosis, @@ -22,6 +23,7 @@ class ExpectedPatientNoteKeys(Enum): MODIFIED_DATE = "modified_date" LAST_EDITED_BY = "last_edited_by" LAST_EDITED_DATE = "last_edited_date" + THREAD = "thread" USER_TYPE = "user_type" @@ -131,6 +133,7 @@ def create_patient_note( data = { "facility": patient.facility or self.facility, "note": note, + "thread": PatientNoteThreadChoices.DOCTORS, } data.update(kwargs) self.client.force_authenticate(user=created_by) @@ -140,7 +143,11 @@ def test_patient_notes(self): self.client.force_authenticate(user=self.state_admin) patientId = self.patient.external_id response = self.client.get( - f"/api/v1/patient/{patientId}/notes/?consultation={self.consultation.external_id}" + f"/api/v1/patient/{patientId}/notes/", + { + "consultation": self.consultation.external_id, + "thread": PatientNoteThreadChoices.DOCTORS, + }, ) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertIsInstance(response.json()["results"], list) From 992d5749bb739cb96b24d1df502f6ef5850de406 Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Thu, 9 May 2024 19:50:22 +0530 Subject: [PATCH 4/5] rebase migrations --- ...429_patientnotes_thread.py => 0430_patientnotes_thread.py} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename care/facility/migrations/{0429_patientnotes_thread.py => 0430_patientnotes_thread.py} (77%) diff --git a/care/facility/migrations/0429_patientnotes_thread.py b/care/facility/migrations/0430_patientnotes_thread.py similarity index 77% rename from care/facility/migrations/0429_patientnotes_thread.py rename to care/facility/migrations/0430_patientnotes_thread.py index a98057a7b1..b166277e33 100644 --- a/care/facility/migrations/0429_patientnotes_thread.py +++ b/care/facility/migrations/0430_patientnotes_thread.py @@ -1,11 +1,11 @@ -# Generated by Django 4.2.8 on 2024-05-08 06:24 +# Generated by Django 4.2.8 on 2024-05-09 14:20 from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ("facility", "0428_alter_patientmetainfo_occupation"), + ("facility", "0429_double_pain_scale"), ] operations = [ From 53a91efa3275f7f74ab9f88446de132f38c4d9c4 Mon Sep 17 00:00:00 2001 From: vigneshhari Date: Sun, 12 May 2024 12:42:05 +0530 Subject: [PATCH 5/5] Remake migrations --- ...430_patientnotes_thread.py => 0431_patientnotes_thread.py} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename care/facility/migrations/{0430_patientnotes_thread.py => 0431_patientnotes_thread.py} (78%) diff --git a/care/facility/migrations/0430_patientnotes_thread.py b/care/facility/migrations/0431_patientnotes_thread.py similarity index 78% rename from care/facility/migrations/0430_patientnotes_thread.py rename to care/facility/migrations/0431_patientnotes_thread.py index b166277e33..f243c24cd1 100644 --- a/care/facility/migrations/0430_patientnotes_thread.py +++ b/care/facility/migrations/0431_patientnotes_thread.py @@ -1,11 +1,11 @@ -# Generated by Django 4.2.8 on 2024-05-09 14:20 +# Generated by Django 4.2.10 on 2024-05-12 07:11 from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ("facility", "0429_double_pain_scale"), + ("facility", "0430_alter_asset_support_phone"), ] operations = [