diff --git a/care/facility/api/viewsets/patient.py b/care/facility/api/viewsets/patient.py index 839974dac4..46cceb621c 100644 --- a/care/facility/api/viewsets/patient.py +++ b/care/facility/api/viewsets/patient.py @@ -224,26 +224,22 @@ def filter_bed_not_null(self, queryset, name, value): def filter_by_diagnoses(self, queryset, name, value): if not value: return queryset - - diagnosis_ids = value.split(",") - queryset = queryset.filter( - last_consultation__diagnoses__diagnosis_id__in=diagnosis_ids - ) - + filter_q = Q(last_consultation__diagnoses__diagnosis_id__in=value.split(",")) if name == "diagnoses": - return queryset.exclude( + filter_q &= ~Q( last_consultation__diagnoses__verification_status__in=INACTIVE_CONDITION_VERIFICATION_STATUSES ) - - verification_status = { - "diagnoses_unconfirmed": ConditionVerificationStatus.UNCONFIRMED, - "diagnoses_provisional": ConditionVerificationStatus.PROVISIONAL, - "diagnoses_differential": ConditionVerificationStatus.DIFFERENTIAL, - "diagnoses_confirmed": ConditionVerificationStatus.CONFIRMED, - }[name] - return queryset.filter( - last_consultation__diagnoses__verification_status=verification_status - ) + else: + verification_status = { + "diagnoses_unconfirmed": ConditionVerificationStatus.UNCONFIRMED, + "diagnoses_provisional": ConditionVerificationStatus.PROVISIONAL, + "diagnoses_differential": ConditionVerificationStatus.DIFFERENTIAL, + "diagnoses_confirmed": ConditionVerificationStatus.CONFIRMED, + }[name] + filter_q &= Q( + last_consultation__diagnoses__verification_status=verification_status + ) + return queryset.filter(filter_q) class PatientDRYFilter(DRYPermissionFiltersBase): diff --git a/care/facility/tests/test_patient_api.py b/care/facility/tests/test_patient_api.py index f4512c1ed3..633f5ede75 100644 --- a/care/facility/tests/test_patient_api.py +++ b/care/facility/tests/test_patient_api.py @@ -4,6 +4,10 @@ from rest_framework import status from rest_framework.test import APITestCase +from care.facility.models.icd11_diagnosis import ( + ConditionVerificationStatus, + ICD11Diagnosis, +) from care.facility.models.patient_base import NewDischargeReasonEnum from care.utils.tests.test_utils import TestUtils @@ -244,6 +248,27 @@ def setUpTestData(cls): cls.consultation.save() cls.patient.last_consultation = cls.consultation cls.patient.save() + cls.diagnoses = ICD11Diagnosis.objects.filter(is_leaf=True)[10:15] + cls.create_consultation_diagnosis( + cls.consultation, + cls.diagnoses[0], + verification_status=ConditionVerificationStatus.CONFIRMED, + ) + cls.create_consultation_diagnosis( + cls.consultation, + cls.diagnoses[1], + verification_status=ConditionVerificationStatus.DIFFERENTIAL, + ) + cls.create_consultation_diagnosis( + cls.consultation, + cls.diagnoses[2], + verification_status=ConditionVerificationStatus.PROVISIONAL, + ) + cls.create_consultation_diagnosis( + cls.consultation, + cls.diagnoses[3], + verification_status=ConditionVerificationStatus.UNCONFIRMED, + ) def get_base_url(self) -> str: return "/api/v1/patient/" @@ -272,6 +297,64 @@ def test_filter_by_location(self): response.data["results"][0]["id"], str(self.patient.external_id) ) + def test_filter_by_diagnoses(self): + self.client.force_authenticate(user=self.user) + res = self.client.get( + self.get_base_url(), + {"diagnoses": ",".join([str(x.id) for x in self.diagnoses])}, + ) + self.assertContains(res, self.patient.external_id) + res = self.client.get(self.get_base_url(), {"diagnoses": self.diagnoses[4].id}) + self.assertNotContains(res, self.patient.external_id) + + def test_filter_by_diagnoses_unconfirmed(self): + self.client.force_authenticate(user=self.user) + res = self.client.get( + self.get_base_url(), + {"diagnoses_unconfirmed": self.diagnoses[3].id}, + ) + self.assertContains(res, self.patient.external_id) + res = self.client.get( + self.get_base_url(), {"diagnoses_unconfirmed": self.diagnoses[2].id} + ) + self.assertNotContains(res, self.patient.external_id) + + def test_filter_by_diagnoses_provisional(self): + self.client.force_authenticate(user=self.user) + res = self.client.get( + self.get_base_url(), + {"diagnoses_provisional": self.diagnoses[2].id}, + ) + self.assertContains(res, self.patient.external_id) + res = self.client.get( + self.get_base_url(), {"diagnoses_provisional": self.diagnoses[3].id} + ) + self.assertNotContains(res, self.patient.external_id) + + def test_filter_by_diagnoses_differential(self): + self.client.force_authenticate(user=self.user) + res = self.client.get( + self.get_base_url(), + {"diagnoses_differential": self.diagnoses[1].id}, + ) + self.assertContains(res, self.patient.external_id) + res = self.client.get( + self.get_base_url(), {"diagnoses_differential": self.diagnoses[0].id} + ) + self.assertNotContains(res, self.patient.external_id) + + def test_filter_by_diagnoses_confirmed(self): + self.client.force_authenticate(user=self.user) + res = self.client.get( + self.get_base_url(), + {"diagnoses_confirmed": self.diagnoses[0].id}, + ) + self.assertContains(res, self.patient.external_id) + res = self.client.get( + self.get_base_url(), {"diagnoses_confirmed": self.diagnoses[2].id} + ) + self.assertNotContains(res, self.patient.external_id) + class PatientTransferTestCase(TestUtils, APITestCase): @classmethod diff --git a/care/utils/tests/test_utils.py b/care/utils/tests/test_utils.py index 4110f70631..55140dfc4e 100644 --- a/care/utils/tests/test_utils.py +++ b/care/utils/tests/test_utils.py @@ -26,6 +26,11 @@ from care.facility.models.asset import Asset, AssetLocation from care.facility.models.bed import Bed, ConsultationBed from care.facility.models.facility import FacilityUser +from care.facility.models.icd11_diagnosis import ( + ConditionVerificationStatus, + ConsultationDiagnosis, + ICD11Diagnosis, +) from care.users.models import District, State @@ -389,6 +394,22 @@ def create_consultation_bed( data.update(kwargs) return ConsultationBed.objects.create(**data) + @classmethod + def create_consultation_diagnosis( + cls, + consultation: PatientConsultation, + diagnosis: ICD11Diagnosis, + verification_status: ConditionVerificationStatus, + **kwargs, + ): + data = { + "consultation": consultation, + "diagnosis": diagnosis, + "verification_status": verification_status, + } + data.update(kwargs) + return ConsultationDiagnosis.objects.create(**data) + @classmethod def clone_object(cls, obj, save=True): new_obj = obj._meta.model.objects.get(pk=obj.id)