Skip to content

Commit

Permalink
made patient notes consultation specific (#1727)
Browse files Browse the repository at this point in the history
* made patient notes consultation specific

* link existing patient notes to consultations

* update migrations

---------

Co-authored-by: Bhavik Agarwal <[email protected]>
  • Loading branch information
sainak and Bhavik-ag authored Dec 7, 2023
1 parent 79c734a commit 1ce8fdc
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 4 deletions.
7 changes: 7 additions & 0 deletions care/facility/api/serializers/patient.py
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,12 @@ def save(self, **kwargs):
class PatientNotesSerializer(serializers.ModelSerializer):
facility = FacilityBasicInfoSerializer(read_only=True)
created_by_object = UserBaseMinimumSerializer(source="created_by", read_only=True)
consultation = ExternalIdSerializerField(
queryset=PatientConsultation.objects.all(),
required=False,
allow_null=True,
read_only=True,
)

def validate_empty_values(self, data):
if not data.get("note", "").strip():
Expand All @@ -501,6 +507,7 @@ class Meta:
fields = (
"note",
"facility",
"consultation",
"created_by_object",
"user_type",
"created_date",
Expand Down
7 changes: 7 additions & 0 deletions care/facility/api/viewsets/patient.py
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,10 @@ def list(self, request, *args, **kwargs):
return super(PatientSearchViewSet, self).list(request, *args, **kwargs)


class PatientNotesFilterSet(filters.FilterSet):
consultation = filters.CharFilter(field_name="consultation__external_id")


class PatientNotesViewSet(
ListModelMixin, RetrieveModelMixin, CreateModelMixin, GenericViewSet
):
Expand All @@ -636,6 +640,8 @@ class PatientNotesViewSet(
)
serializer_class = PatientNotesSerializer
permission_classes = (IsAuthenticated, DRYPermissions)
filter_backends = (filters.DjangoFilterBackend,)
filterset_class = PatientNotesFilterSet

def get_queryset(self):
user = self.request.user
Expand Down Expand Up @@ -671,6 +677,7 @@ def perform_create(self, serializer):
instance = serializer.save(
facility=patient.facility,
patient=patient,
consultation=patient.last_consultation,
created_by=self.request.user,
)

Expand Down
23 changes: 23 additions & 0 deletions care/facility/migrations/0398_patientnotes_consultation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 4.2.6 on 2023-10-18 12:18

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("facility", "0397_truncate_discharge_time"),
]

operations = [
migrations.AddField(
model_name="patientnotes",
name="consultation",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.PROTECT,
to="facility.patientconsultation",
),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Generated by Django 4.2.7 on 2023-11-23 12:42

from django.db import migrations, models


def link_patient_notes_to_consultation(apps, schema_editor):
PatientConsultation = apps.get_model("facility", "PatientConsultation")
PatientNotes = apps.get_model("facility", "PatientNotes")

consultations = PatientConsultation.objects.order_by("created_date").filter(
patient__in=models.Subquery(PatientNotes.objects.values("patient_id"))
)

for consultation in consultations:
notes = PatientNotes.objects.order_by("created_date").filter(
patient_id=consultation.patient_id,
created_date__gte=consultation.created_date,
)
if consultation.discharge_reason:
notes = notes.filter(
created_date__lte=consultation.modified_date,
)

notes.update(consultation=consultation)


class Migration(migrations.Migration):
dependencies = [
("facility", "0398_patientnotes_consultation"),
]

operations = [
migrations.RunPython(
code=link_patient_notes_to_consultation,
reverse_code=migrations.RunPython.noop,
),
]
3 changes: 3 additions & 0 deletions care/facility/models/patient.py
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,9 @@ class PatientNotes(FacilityBaseModel, ConsultationRelatedPermissionMixin):
patient = models.ForeignKey(
PatientRegistration, on_delete=models.PROTECT, null=False, blank=False
)
consultation = models.ForeignKey(
PatientConsultation, on_delete=models.PROTECT, null=True, blank=True
)
facility = models.ForeignKey(
Facility, on_delete=models.PROTECT, null=False, blank=False
)
Expand Down
25 changes: 22 additions & 3 deletions care/facility/tests/test_patient_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
class ExpectedPatientNoteKeys(Enum):
NOTE = "note"
FACILITY = "facility"
CONSULTATION = "consultation"
CREATED_BY_OBJECT = "created_by_object"
CREATED_DATE = "created_date"
USER_TYPE = "user_type"
Expand Down Expand Up @@ -97,6 +98,14 @@ def setUpTestData(cls) -> None:
"doctor2", cls.district, home_facility=cls.facility2, user_type=15
)
cls.patient = cls.create_patient(cls.district, cls.facility)
cls.consultation = cls.create_consultation(
patient_no="IP5678",
patient=cls.patient,
facility=cls.facility,
created_by=cls.user,
suggestion="A",
admission_date=now(),
)

def setUp(self):
super().setUp()
Expand All @@ -120,18 +129,28 @@ def create_patient_note(

def test_patient_notes(self):
patientId = self.patient.external_id
response = self.client.get(f"/api/v1/patient/{patientId}/notes/")
response = self.client.get(
f"/api/v1/patient/{patientId}/notes/?consultation={self.consultation.external_id}"
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertIsInstance(response.json()["results"], list)

# Test user_type field if user is not from same facility as patient
results = response.json()["results"]

# Test if all notes are from same consultation as requested
self.assertEqual(
str(self.consultation.external_id),
[note["consultation"] for note in results][0],
)

# Test created_by_local_user field if user is not from same facility as patient
data2 = response.json()["results"][0]

user_type_content2 = data2["user_type"]
self.assertEqual(user_type_content2, "RemoteSpecialist")

# Ensure only necessary data is being sent and no extra data
data = response.json()["results"][1]
data = results[1]

self.assertCountEqual(
data.keys(), [item.value for item in ExpectedPatientNoteKeys]
Expand Down
5 changes: 4 additions & 1 deletion care/utils/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,10 @@ def create_consultation(
}
)
data.update(kwargs)
return PatientConsultation.objects.create(**data)
consultation = PatientConsultation.objects.create(**data)
patient.last_consultation = consultation
patient.save()
return consultation

@classmethod
def create_asset_location(cls, facility: Facility, **kwargs) -> AssetLocation:
Expand Down

0 comments on commit 1ce8fdc

Please sign in to comment.