diff --git a/care/facility/api/serializers/patient.py b/care/facility/api/serializers/patient.py index f526db1b73..680022c7d0 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=False, allow_null=False + ) def validate_empty_values(self, data): if not data.get("note", "").strip(): @@ -521,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 @@ -548,6 +554,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 +580,7 @@ class Meta: "note", "facility", "consultation", + "thread", "created_by_object", "user_type", "created_date", @@ -583,6 +592,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 02ff220a44..f8e7d780dc 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/0431_patientnotes_thread.py b/care/facility/migrations/0431_patientnotes_thread.py new file mode 100644 index 0000000000..f243c24cd1 --- /dev/null +++ b/care/facility/migrations/0431_patientnotes_thread.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.10 on 2024-05-12 07:11 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("facility", "0430_alter_asset_support_phone"), + ] + + operations = [ + migrations.AddField( + model_name="patientnotes", + name="thread", + 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 786ff584b7..94a06f0f5f 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.SmallIntegerField( + choices=PatientNoteThreadChoices.choices, + db_index=True, + default=PatientNoteThreadChoices.DOCTORS, + ) note = models.TextField(default="", blank=True) def get_related_consultation(self): 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)