Skip to content

Commit

Permalink
Update allergy_intolerance update spec and added tests (#2778)
Browse files Browse the repository at this point in the history
  • Loading branch information
sainak authored Jan 24, 2025
1 parent 5efcfbb commit 6add747
Show file tree
Hide file tree
Showing 3 changed files with 823 additions and 17 deletions.
28 changes: 19 additions & 9 deletions care/emr/api/viewsets/allergy_intolerance.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@
)
from care.emr.models import Patient
from care.emr.models.allergy_intolerance import AllergyIntolerance
from care.emr.models.encounter import Encounter
from care.emr.registries.system_questionnaire.system_questionnaire import (
InternalQuestionnaireRegistry,
)
from care.emr.resources.allergy_intolerance.spec import (
AllergyIntoleranceSpec,
AllergyIntoleranceReadSpec,
AllergyIntoleranceUpdateSpec,
AllergyIntoleranceWriteSpec,
AllergyIntrolanceSpecRead,
)
from care.emr.resources.questionnaire.spec import SubjectType
from care.security.authorization import AuthorizationController
Expand All @@ -32,7 +33,7 @@ class AllergyIntoleranceFilters(FilterSet):


@extend_schema_view(
create=extend_schema(request=AllergyIntoleranceSpec),
create=extend_schema(request=AllergyIntoleranceWriteSpec),
)
class AllergyIntoleranceViewSet(
EMRQuestionnaireResponseMixin,
Expand All @@ -44,9 +45,9 @@ class AllergyIntoleranceViewSet(
EMRUpsertMixin,
):
database_model = AllergyIntolerance
pydantic_model = AllergyIntoleranceSpec
pydantic_read_model = AllergyIntrolanceSpecRead
pydantic_update_model = AllergyIntoleranceWriteSpec
pydantic_model = AllergyIntoleranceWriteSpec
pydantic_read_model = AllergyIntoleranceReadSpec
pydantic_update_model = AllergyIntoleranceUpdateSpec
questionnaire_type = "allergy_intolerance"
questionnaire_title = "Allergy Intolerance"
questionnaire_description = "Allergy Intolerance"
Expand All @@ -59,15 +60,24 @@ def get_patient_obj(self):
Patient, external_id=self.kwargs["patient_external_id"]
)

def authorize_update(self, request_obj, model_instance):
self.authorize_create({})

def authorize_create(self, instance):
if not AuthorizationController.call(
"can_write_patient_obj", self.request.user, self.get_patient_obj()
):
raise PermissionDenied("You do not have permission to update encounter")

def authorize_update(self, request_obj, model_instance):
encounter = get_object_or_404(Encounter, external_id=request_obj.encounter)
if not AuthorizationController.call(
"can_update_encounter_obj",
self.request.user,
encounter,
):
raise PermissionDenied("You do not have permission to update encounter")

def clean_update_data(self, request_data):
return super().clean_update_data(request_data, keep_fields={"encounter"})

def get_queryset(self):
if not AuthorizationController.call(
"can_view_clinical_data", self.request.user, self.get_patient_obj()
Expand Down
34 changes: 26 additions & 8 deletions care/emr/resources/allergy_intolerance/spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,27 +52,39 @@ class BaseAllergyIntoleranceSpec(EMRResource):
id: UUID4 = None


class AllergyIntoleranceWriteSpec(BaseAllergyIntoleranceSpec):
class AllergyIntoleranceUpdateSpec(BaseAllergyIntoleranceSpec):
clinical_status: ClinicalStatusChoices
verification_status: VerificationStatusChoices
category: CategoryChoices
criticality: CriticalityChoices
last_occurrence: datetime.datetime | None = None
recorded_date: datetime.datetime | None = None
note: str | None = None
encounter: UUID4

onset: AllergyIntoleranceOnSetSpec = {}
@field_validator("encounter")
@classmethod
def validate_encounter_exists(cls, encounter):
if not Encounter.objects.filter(external_id=encounter).exists():
err = "Encounter not found"
raise ValueError(err)
return encounter

def perform_extra_deserialization(self, is_update, obj):
if not is_update:
if self.encounter:
obj.encounter = Encounter.objects.get(external_id=self.encounter)
obj.patient = obj.encounter.patient


class AllergyIntoleranceSpec(AllergyIntoleranceWriteSpec):
class AllergyIntoleranceWriteSpec(BaseAllergyIntoleranceSpec):
clinical_status: ClinicalStatusChoices
verification_status: VerificationStatusChoices
category: CategoryChoices
criticality: CriticalityChoices
last_occurrence: datetime.datetime | None = None
recorded_date: datetime.datetime | None = None
encounter: UUID4
code: Coding = Field(
{}, json_schema_extra={"slug": CARE_ALLERGY_CODE_VALUESET.slug}
)
onset: AllergyIntoleranceOnSetSpec = {}

@field_validator("code")
@classmethod
Expand All @@ -89,8 +101,12 @@ def validate_encounter_exists(cls, encounter):
raise ValueError(err)
return encounter

def perform_extra_deserialization(self, is_update, obj):
obj.encounter = Encounter.objects.get(external_id=self.encounter)
obj.patient = obj.encounter.patient


class AllergyIntrolanceSpecRead(BaseAllergyIntoleranceSpec):
class AllergyIntoleranceReadSpec(BaseAllergyIntoleranceSpec):
"""
Validation for deeper models may not be required on read, Just an extra optimisation
"""
Expand All @@ -115,3 +131,5 @@ 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)
if obj.encounter:
mapping["encounter"] = obj.encounter.external_id
Loading

0 comments on commit 6add747

Please sign in to comment.