Skip to content

Commit

Permalink
Adding tests for symptoms (#2726)
Browse files Browse the repository at this point in the history
Adding tests for symptoms (#2726)
  • Loading branch information
DraKen0009 authored Jan 10, 2025
1 parent 9822191 commit 4511637
Show file tree
Hide file tree
Showing 6 changed files with 647 additions and 28 deletions.
49 changes: 32 additions & 17 deletions care/emr/api/viewsets/condition.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django.shortcuts import get_object_or_404
from django_filters import CharFilter, FilterSet, UUIDFilter
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.exceptions import PermissionDenied
from rest_framework.exceptions import ValidationError

from care.emr.api.viewsets.base import EMRModelViewSet, EMRQuestionnaireResponseMixin
from care.emr.api.viewsets.encounter_authz_base import EncounterBasedAuthorizationBase
Expand All @@ -13,10 +14,29 @@
CategoryChoices,
ConditionSpec,
ConditionSpecRead,
ConditionSpecUpdate,
)
from care.emr.resources.questionnaire.spec import SubjectType


class ValidateEncounterMixin:
"""
Mixin to validate encounter and its relationship with the patient.
"""

def validate_data(self, instance, model_obj=None):
# Ensure the encounter exists and matches the patient's external ID
if model_obj:
encounter = model_obj.encounter
else:
encounter = get_object_or_404(Encounter, external_id=instance.encounter)

if str(encounter.patient.external_id) != self.kwargs["patient_external_id"]:
raise ValidationError(
"Patient external ID mismatch with encounter's patient"
)


class ConditionFilters(FilterSet):
encounter = UUIDFilter(field_name="encounter__external_id")
clinical_status = CharFilter(field_name="clinical_status", lookup_expr="iexact")
Expand All @@ -27,11 +47,15 @@ class ConditionFilters(FilterSet):


class SymptomViewSet(
EncounterBasedAuthorizationBase, EMRQuestionnaireResponseMixin, EMRModelViewSet
ValidateEncounterMixin,
EncounterBasedAuthorizationBase,
EMRQuestionnaireResponseMixin,
EMRModelViewSet,
):
database_model = Condition
pydantic_model = ConditionSpec
pydantic_read_model = ConditionSpecRead
pydantic_update_model = ConditionSpecUpdate
# Filters
filterset_class = ConditionFilters
filter_backends = [DjangoFilterBackend]
Expand All @@ -45,13 +69,6 @@ def perform_create(self, instance):
instance.category = CategoryChoices.problem_list_item.value
super().perform_create(instance)

def authorize_create(self, instance: ConditionSpec):
encounter = Encounter.objects.get(external_id=instance.encounter)
if str(encounter.patient.external_id) != self.kwargs["patient_external_id"]:
err = "Malformed request"
raise PermissionDenied(err)
# Check if the user has access to the patient and write access to the encounter

def get_queryset(self):
# Check if the user has read access to the patient and their EMR Data
self.authorize_read_encounter()
Expand All @@ -70,11 +87,16 @@ def get_queryset(self):


class DiagnosisViewSet(
EncounterBasedAuthorizationBase, EMRQuestionnaireResponseMixin, EMRModelViewSet
ValidateEncounterMixin,
EncounterBasedAuthorizationBase,
EMRQuestionnaireResponseMixin,
EMRModelViewSet,
):
database_model = Condition
pydantic_model = ConditionSpec
pydantic_read_model = ConditionSpecRead
pydantic_update_model = ConditionSpecUpdate

# Filters
filterset_class = ConditionFilters
filter_backends = [DjangoFilterBackend]
Expand All @@ -88,13 +110,6 @@ def perform_create(self, instance):
instance.category = CategoryChoices.encounter_diagnosis.value
super().perform_create(instance)

def authorize_create(self, instance: ConditionSpec):
encounter = Encounter.objects.get(external_id=instance.encounter)
if str(encounter.patient.external_id) != self.kwargs["patient_external_id"]:
err = "Malformed request"
raise PermissionDenied(err)
# Check if the user has access to the patient and write access to the encounter

def get_queryset(self):
# Check if the user has read access to the patient and their EMR Data
self.authorize_read_encounter()
Expand Down
11 changes: 9 additions & 2 deletions care/emr/models/encounter.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,19 @@ def sync_organization_cache(self):
encounter_organization.organization.id,
}
)

facility_root_org = FacilityOrganization.objects.filter(
org_type="root", facility=self.facility
).first()
orgs = orgs.union({facility_root_org.id})
if facility_root_org:
orgs = orgs.union({facility_root_org.id})

self.facility_organization_cache = list(orgs)
self.save(update_fields=["facility_organization_cache"])
super().save(update_fields=["facility_organization_cache"])

def save(self, *args, **kwargs):
super().save(*args, **kwargs)
self.sync_organization_cache()


class EncounterOrganization(EMRBaseModel):
Expand Down
15 changes: 15 additions & 0 deletions care/emr/resources/condition/spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,18 @@ def perform_extra_serialization(cls, mapping, obj):
mapping["created_by"] = UserSpec.serialize(obj.created_by)
if obj.updated_by:
mapping["updated_by"] = UserSpec.serialize(obj.updated_by)


class ConditionSpecUpdate(BaseConditionSpec):
clinical_status: ClinicalStatusChoices | None = None
verification_status: VerificationStatusChoices
severity: SeverityChoices | None = None
code: Coding = Field(json_schema_extra={"slug": CARE_CODITION_CODE_VALUESET.slug})
onset: ConditionOnSetSpec = {}

@field_validator("code")
@classmethod
def validate_code(cls, code: int):
return validate_valueset(
"code", cls.model_fields["code"].json_schema_extra["slug"], code
)
Loading

0 comments on commit 4511637

Please sign in to comment.