Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds M2M Consultation Diagnosis model #1690

Merged
merged 30 commits into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
4b5be5c
Add ConsultationDiagnosis M2M model and migrations
rithviknishad Oct 29, 2023
d2e4419
ABDM: Update FHIR utils with ConsultationDiagnoses M2M relation
rithviknishad Oct 29, 2023
a8b7c3b
Update HCX: Update diagnoses in make_claim with M2M relation
rithviknishad Oct 29, 2023
f8017ac
API: Adds serializers, viewsets and api route
rithviknishad Oct 29, 2023
eab044f
Unlock `unconfirmed` and `differential` verification status
rithviknishad Oct 30, 2023
906e197
uncomplicate things....
rithviknishad Oct 30, 2023
d41fd70
minor fixes
rithviknishad Oct 30, 2023
c80b83c
more bug fixes.... :/
rithviknishad Oct 30, 2023
703f4a1
gracefully handle invalid icd11 objects
rithviknishad Oct 30, 2023
091e1f2
fix `load_icd11_diagnoses_data` re-run issue
rithviknishad Oct 31, 2023
88291a3
Update Discharge Summary
rithviknishad Oct 31, 2023
3e5c614
Annotate CSV export by diagoses
rithviknishad Oct 31, 2023
d7dcc1a
fix create_disgnoses not working
rithviknishad Oct 31, 2023
c30e7b3
minor fix
rithviknishad Oct 31, 2023
6346ec8
fix existing tests
rithviknishad Oct 31, 2023
451ef67
add tests
rithviknishad Oct 31, 2023
75c9684
Merge branch 'master' into consultation_diagnoses_m2m
rithviknishad Oct 31, 2023
74e5466
squash migrations
rithviknishad Oct 31, 2023
a40f4c8
improve coverage by a tiny factor
rithviknishad Oct 31, 2023
964830a
Add authz, optimizations to model, proper validation message
rithviknishad Nov 3, 2023
d2cafb9
fix validation
rithviknishad Nov 3, 2023
555c784
fix authz
rithviknishad Nov 3, 2023
846c190
fix typo
rithviknishad Nov 3, 2023
b5d3de0
fix patient notes
rithviknishad Nov 3, 2023
3843cd3
Add chapter information to ICD serialization (#1696)
rithviknishad Nov 3, 2023
31c3b2a
HCX: update diagnoses in make claim
rithviknishad Nov 3, 2023
74fc48a
avoid redundant permission checks
rithviknishad Nov 8, 2023
9984a50
fix errors
rithviknishad Nov 8, 2023
0f6d8a3
make code pretty
rithviknishad Nov 8, 2023
8923d0d
Apply suggestions from code review
rithviknishad Nov 8, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 14 additions & 16 deletions care/abdm/utils/fhir.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@
from fhir.resources.reference import Reference

from care.facility.models.file_upload import FileUpload
from care.facility.models.icd11_diagnosis import REVERSE_CONDITION_VERIFICATION_STATUSES
from care.facility.models.patient_investigation import InvestigationValue
from care.facility.static_data.icd11 import ICDDiseases
from care.facility.static_data.icd11 import get_icd11_diagnosis_object_by_id


class Fhir:
Expand Down Expand Up @@ -136,8 +137,8 @@

return self._organization_profile

def _condition(self, diagnosis_id, provisional=False):
diagnosis = ICDDiseases.by.id[diagnosis_id]
def _condition(self, diagnosis_id, verification_status):
diagnosis = get_icd11_diagnosis_object_by_id(diagnosis_id)

Check warning on line 141 in care/abdm/utils/fhir.py

View check run for this annotation

Codecov / codecov/patch

care/abdm/utils/fhir.py#L141

Added line #L141 was not covered by tests
[code, label] = diagnosis.label.split(" ", 1)
condition_profile = Condition(
id=diagnosis_id,
Expand All @@ -158,8 +159,10 @@
coding=[
Coding(
system="http://terminology.hl7.org/CodeSystem/condition-ver-status",
code="provisional" if provisional else "confirmed",
display="Provisional" if provisional else "Confirmed",
code=verification_status,
display=REVERSE_CONDITION_VERIFICATION_STATUSES[
verification_status
],
)
]
),
Expand Down Expand Up @@ -368,20 +371,15 @@
"period": Period(start=period_start, end=period_end),
"diagnosis": list(
map(
lambda diagnosis: EncounterDiagnosis(
lambda consultation_diagnosis: EncounterDiagnosis(
condition=self._reference(
self._condition(diagnosis),
self._condition(
consultation_diagnosis.diagnosis_id,
consultation_diagnosis.verification_status,
),
)
),
self.consultation.icd11_diagnoses,
)
)
+ list(
map(
lambda diagnosis: EncounterDiagnosis(
condition=self._reference(self._condition(diagnosis))
),
self.consultation.icd11_provisional_diagnoses,
self.consultation.diagnoses.all(),
)
)
if include_diagnosis
Expand Down
127 changes: 127 additions & 0 deletions care/facility/api/serializers/consultation_diagnosis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
from typing import Any

from rest_framework import serializers

from care.facility.models import (
INACTIVE_CONDITION_VERIFICATION_STATUSES,
ConsultationDiagnosis,
)
from care.facility.models.icd11_diagnosis import ICD11Diagnosis
from care.facility.static_data.icd11 import get_icd11_diagnosis_object_by_id
from care.users.api.serializers.user import UserBaseMinimumSerializer


class ConsultationCreateDiagnosisSerializer(serializers.ModelSerializer):
def validate_verification_status(self, value):
if value in INACTIVE_CONDITION_VERIFICATION_STATUSES:
raise serializers.ValidationError("Verification status not allowed")

Check warning on line 17 in care/facility/api/serializers/consultation_diagnosis.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/consultation_diagnosis.py#L17

Added line #L17 was not covered by tests
return value

class Meta:
model = ConsultationDiagnosis
fields = ("diagnosis", "verification_status", "is_principal")


class ConsultationDiagnosisSerializer(serializers.ModelSerializer):
id = serializers.UUIDField(source="external_id", read_only=True)
diagnosis = serializers.PrimaryKeyRelatedField(
queryset=ICD11Diagnosis.objects.all(), required=True, allow_null=False
)
diagnosis_object = serializers.SerializerMethodField()
created_by = UserBaseMinimumSerializer(read_only=True)

def get_diagnosis_object(self, obj):
return get_icd11_diagnosis_object_by_id(obj.diagnosis_id, as_dict=True)

class Meta:
model = ConsultationDiagnosis
exclude = (
"consultation",
"external_id",
"deleted",
)
read_only_fields = (
"created_by",
"created_date",
"modified_date",
"is_migrated",
)

def get_consultation_external_id(self):
return self.context["request"].parser_context["kwargs"][
"consultation_external_id"
]

def validate_diagnosis(self, value):
if self.instance and value != self.instance.diagnosis:
raise serializers.ValidationError("Diagnosis cannot be changed")

if (
not self.instance
and ConsultationDiagnosis.objects.filter(
consultation__external_id=self.get_consultation_external_id(),
diagnosis=value,
).exists()
):
raise serializers.ValidationError(
"Diagnosis already exists for consultation"
)

return value

def validate_verification_status(self, value):
if not self.instance and value in INACTIVE_CONDITION_VERIFICATION_STATUSES:
raise serializers.ValidationError("Verification status not allowed")
return value

def validate_is_principal(self, value):
if not value:
return value

qs = ConsultationDiagnosis.objects.filter(
consultation__external_id=self.get_consultation_external_id(),
is_principal=True,
)

if self.instance:
qs = qs.exclude(id=self.instance.id)

if qs.exists():
raise serializers.ValidationError(
"Consultation already has a principal diagnosis. Unset the existing principal diagnosis first."
)

return value

def update(self, instance, validated_data):
if (
"verification_status" in validated_data
and validated_data["verification_status"]
in INACTIVE_CONDITION_VERIFICATION_STATUSES
):
instance.is_principal = False
return super().update(instance, validated_data)

def validate(self, attrs: Any) -> Any:
validated = super().validate(attrs)

if (
"verification_status" in validated
and validated["verification_status"]
in INACTIVE_CONDITION_VERIFICATION_STATUSES
):
validated["is_principal"] = False

if "is_principal" in validated and validated["is_principal"]:
verification_status = validated.get(
"verification_status",
self.instance.verification_status if self.instance else None,
)
if verification_status in INACTIVE_CONDITION_VERIFICATION_STATUSES:
raise serializers.ValidationError(

Check warning on line 121 in care/facility/api/serializers/consultation_diagnosis.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/consultation_diagnosis.py#L121

Added line #L121 was not covered by tests
{
"is_principal": "Refuted/Entered in error diagnoses cannot be marked as Principal Diagnosis"
}
)

return validated
Loading
Loading