-
Notifications
You must be signed in to change notification settings - Fork 305
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* consultation depth backend Co-authored-by: Rithvik Nishad <[email protected]> Co-authored-by: Aakash Singh <[email protected]> * refactor * fix migrations * fix test and dummy data * add is_migrated field * add created by to symptoms bulk create * fix discharge summary * make onset date non nullable * fixes unknown field excluded * fix tests * fix validations * update bulk migration to exclude symptom if already created earlier for a consultation * add clinical_impression_status to indicate symptom status * update migrations * review suggestions * add trigger for marked as errors * fix validation * fix updates * rename consultation symptom to encounter symptom * fix unable to mark as entered in error * update discharge summary pdf * add test cases and minor fixes * allow create symptoms to be empty * update migration to ignore asymptomatic symptom * rebase migrations --------- Co-authored-by: Hritesh Shanty <[email protected]> Co-authored-by: Rithvik Nishad <[email protected]> Co-authored-by: rithviknishad <[email protected]>
- Loading branch information
1 parent
f051cab
commit de22042
Showing
20 changed files
with
1,154 additions
and
160 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
from copy import copy | ||
|
||
from django.db import transaction | ||
from django.utils.timezone import now | ||
from rest_framework import serializers | ||
|
||
from care.facility.events.handler import create_consultation_events | ||
from care.facility.models.encounter_symptom import ( | ||
ClinicalImpressionStatus, | ||
EncounterSymptom, | ||
Symptom, | ||
) | ||
from care.users.api.serializers.user import UserBaseMinimumSerializer | ||
|
||
|
||
class EncounterSymptomSerializer(serializers.ModelSerializer): | ||
id = serializers.UUIDField(source="external_id", read_only=True) | ||
created_by = UserBaseMinimumSerializer(read_only=True) | ||
updated_by = UserBaseMinimumSerializer(read_only=True) | ||
|
||
class Meta: | ||
model = EncounterSymptom | ||
exclude = ( | ||
"consultation", | ||
"external_id", | ||
"deleted", | ||
) | ||
read_only_fields = ( | ||
"created_date", | ||
"modified_date", | ||
"is_migrated", | ||
) | ||
|
||
def validate_onset_date(self, value): | ||
if value and value > now(): | ||
raise serializers.ValidationError("Onset date cannot be in the future") | ||
return value | ||
|
||
def validate(self, attrs): | ||
validated_data = super().validate(attrs) | ||
consultation = ( | ||
self.instance.consultation | ||
if self.instance | ||
else self.context["consultation"] | ||
) | ||
|
||
onset_date = ( | ||
self.instance.onset_date | ||
if self.instance | ||
else validated_data.get("onset_date") | ||
) | ||
if cure_date := validated_data.get("cure_date"): | ||
if cure_date < onset_date: | ||
raise serializers.ValidationError( | ||
{"cure_date": "Cure date should be after onset date"} | ||
) | ||
|
||
if validated_data.get("symptom") != Symptom.OTHERS and validated_data.get( | ||
"other_symptom" | ||
): | ||
raise serializers.ValidationError( | ||
{ | ||
"other_symptom": "Other symptom should be empty when symptom type is not OTHERS" | ||
} | ||
) | ||
|
||
if validated_data.get("symptom") == Symptom.OTHERS and not validated_data.get( | ||
"other_symptom" | ||
): | ||
raise serializers.ValidationError( | ||
{ | ||
"other_symptom": "Other symptom should not be empty when symptom type is OTHERS" | ||
} | ||
) | ||
|
||
if EncounterSymptom.objects.filter( | ||
consultation=consultation, | ||
symptom=validated_data.get("symptom"), | ||
other_symptom=validated_data.get("other_symptom") or "", | ||
cure_date__isnull=True, | ||
clinical_impression_status=ClinicalImpressionStatus.IN_PROGRESS, | ||
).exists(): | ||
raise serializers.ValidationError( | ||
{"symptom": "An active symptom with the same details already exists"} | ||
) | ||
|
||
return validated_data | ||
|
||
def create(self, validated_data): | ||
validated_data["consultation"] = self.context["consultation"] | ||
validated_data["created_by"] = self.context["request"].user | ||
|
||
with transaction.atomic(): | ||
instance: EncounterSymptom = super().create(validated_data) | ||
|
||
create_consultation_events( | ||
instance.consultation_id, | ||
instance, | ||
instance.created_by_id, | ||
instance.created_date, | ||
) | ||
|
||
return instance | ||
|
||
def update(self, instance, validated_data): | ||
validated_data["updated_by"] = self.context["request"].user | ||
|
||
with transaction.atomic(): | ||
old_instance = copy(instance) | ||
instance = super().update(instance, validated_data) | ||
|
||
create_consultation_events( | ||
instance.consultation_id, | ||
instance, | ||
instance.updated_by_id, | ||
instance.modified_date, | ||
old=old_instance, | ||
) | ||
|
||
return instance | ||
|
||
|
||
class EncounterCreateSymptomSerializer(serializers.ModelSerializer): | ||
class Meta: | ||
model = EncounterSymptom | ||
fields = ("symptom", "other_symptom", "onset_date", "cure_date") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
from django.shortcuts import get_object_or_404 | ||
from django_filters import rest_framework as filters | ||
from dry_rest_permissions.generics import DRYPermissions | ||
from rest_framework.permissions import IsAuthenticated | ||
from rest_framework.viewsets import ModelViewSet | ||
|
||
from care.facility.api.serializers.encounter_symptom import EncounterSymptomSerializer | ||
from care.facility.models.encounter_symptom import ( | ||
ClinicalImpressionStatus, | ||
EncounterSymptom, | ||
) | ||
from care.utils.queryset.consultation import get_consultation_queryset | ||
|
||
|
||
class EncounterSymptomFilter(filters.FilterSet): | ||
is_cured = filters.BooleanFilter(method="filter_is_cured") | ||
|
||
def filter_is_cured(self, queryset, name, value): | ||
if value: | ||
return queryset.filter(cure_date__isnull=False) | ||
return queryset.filter(cure_date__isnull=True) | ||
|
||
|
||
class EncounterSymptomViewSet(ModelViewSet): | ||
serializer_class = EncounterSymptomSerializer | ||
permission_classes = (IsAuthenticated, DRYPermissions) | ||
queryset = EncounterSymptom.objects.all() | ||
filter_backends = (filters.DjangoFilterBackend,) | ||
filterset_class = EncounterSymptomFilter | ||
lookup_field = "external_id" | ||
|
||
def get_consultation_obj(self): | ||
return get_object_or_404( | ||
get_consultation_queryset(self.request.user).filter( | ||
external_id=self.kwargs["consultation_external_id"] | ||
) | ||
) | ||
|
||
def get_queryset(self): | ||
consultation = self.get_consultation_obj() | ||
return self.queryset.filter(consultation_id=consultation.id) | ||
|
||
def get_serializer_context(self): | ||
context = super().get_serializer_context() | ||
context["consultation"] = self.get_consultation_obj() | ||
return context | ||
|
||
def perform_destroy(self, instance): | ||
serializer = self.get_serializer( | ||
instance, | ||
data={ | ||
"clinical_impression_status": ClinicalImpressionStatus.ENTERED_IN_ERROR | ||
}, | ||
partial=True, | ||
) | ||
serializer.is_valid(raise_exception=True) | ||
self.perform_update(serializer) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.