Skip to content

Commit

Permalink
fix(daily_rounds): added validations to serializer fields
Browse files Browse the repository at this point in the history
  • Loading branch information
aeswibon committed Mar 13, 2024
1 parent e435d9e commit bdbb64f
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 4 deletions.
92 changes: 89 additions & 3 deletions care/facility/api/serializers/daily_round.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
COVID_CATEGORY_CHOICES,
PatientRegistration,
)
from care.facility.models.base import covert_choice_dict
from care.facility.models.bed import Bed
from care.facility.models.daily_round import DailyRound
from care.facility.models.notification import Notification
Expand All @@ -29,6 +30,9 @@
from care.utils.queryset.facility import get_home_facility_queryset
from config.serializers import ChoiceField

SymptomChoiceDict = covert_choice_dict(SYMPTOM_CHOICES)
VentilatorInterfaceChoiceDict = covert_choice_dict(DailyRound.VentilatorInterfaceChoice)


class DailyRoundSerializer(serializers.ModelSerializer):
id = serializers.CharField(source="external_id", read_only=True)
Expand All @@ -38,11 +42,13 @@ class DailyRoundSerializer(serializers.ModelSerializer):
deprecated_covid_category = ChoiceField(
choices=COVID_CATEGORY_CHOICES, required=False
) # Deprecated
patient_category = ChoiceField(choices=CATEGORY_CHOICES, required=False)
patient_category = ChoiceField(choices=CATEGORY_CHOICES, required=True)
current_health = ChoiceField(choices=CURRENT_HEALTH_CHOICES, required=False)

action = ChoiceField(
choices=PatientRegistration.ActionChoices, write_only=True, required=False
choices=PatientRegistration.ActionChoices,
write_only=True,
required=False,
)
review_interval = serializers.IntegerField(
source="consultation__review_interval", required=False
Expand Down Expand Up @@ -294,7 +300,10 @@ def create(self, validated_data):
"last_updated_by_telemedicine"
]
daily_round_obj.consultation.save(
update_fields=["last_updated_by_telemedicine", "review_interval"]
update_fields=[
"last_updated_by_telemedicine",
"review_interval",
]
)
daily_round_obj.save(
update_fields=[
Expand All @@ -314,6 +323,48 @@ def create(self, validated_data):
)
return daily_round_obj

def validate_bp(self, bp):
if not bp:
return bp

Check warning on line 328 in care/facility/api/serializers/daily_round.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/daily_round.py#L328

Added line #L328 was not covered by tests

systolic = bp.get("systolic")
diastolic = bp.get("diastolic")
mean = bp.get("mean")

Check warning on line 332 in care/facility/api/serializers/daily_round.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/daily_round.py#L330-L332

Added lines #L330 - L332 were not covered by tests

if not all(key in bp for key in ["systolic", "diastolic", "mean"]):
raise ValidationError(

Check warning on line 335 in care/facility/api/serializers/daily_round.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/daily_round.py#L335

Added line #L335 was not covered by tests
"This field must contain systolic, diastolic, and mean"
)

if (
systolic not in range(0, 251)
or diastolic not in range(0, 181)
or mean not in range(0, (systolic + 2 * diastolic) // 3 + 1)
):
raise ValidationError("Invalid BP values")

Check warning on line 344 in care/facility/api/serializers/daily_round.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/daily_round.py#L344

Added line #L344 was not covered by tests

return bp

Check warning on line 346 in care/facility/api/serializers/daily_round.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/daily_round.py#L346

Added line #L346 was not covered by tests

def validate_ventilator_interface(self, ventilator_interface):
if (
not ventilator_interface
or ventilator_interface == VentilatorInterfaceChoiceDict["UNKNOWN"]
):
return ventilator_interface

Check warning on line 353 in care/facility/api/serializers/daily_round.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/daily_round.py#L353

Added line #L353 was not covered by tests

if "ventilator_mode" not in self.initial_data:
raise ValidationError(

Check warning on line 356 in care/facility/api/serializers/daily_round.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/daily_round.py#L356

Added line #L356 was not covered by tests
"Ventilator Mode is required when Ventilator Interface is selected."
)

if ventilator_interface == VentilatorInterfaceChoiceDict["OXYGEN_SUPPORT"]:
if "ventilator_oxygen_modality" not in self.initial_data:
raise ValidationError(

Check warning on line 362 in care/facility/api/serializers/daily_round.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/daily_round.py#L362

Added line #L362 was not covered by tests
"Ventilator Oxygen Modality field is required when Ventilator Interface is set to Oxygen support."
)

return ventilator_interface

Check warning on line 366 in care/facility/api/serializers/daily_round.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/daily_round.py#L366

Added line #L366 was not covered by tests

def validate(self, attrs):
validated = super().validate(attrs)
validated["consultation"] = self.context["consultation"]
Expand Down Expand Up @@ -342,6 +393,41 @@ def validate(self, attrs):
}
)

if (
"rounds_type" in validated
and validated["rounds_type"] == DailyRound.RoundsType.NORMAL.value
and "temperature" not in validated
):
raise ValidationError(

Check warning on line 401 in care/facility/api/serializers/daily_round.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/daily_round.py#L401

Added line #L401 was not covered by tests
{"temperature": ["This field is required for Ventilator Rounds."]}
)

if "in_prone_position" in validated and validated["in_prone_position"]:
if (
"left_pupil_size" in validated
or "right_pupil_size" in validated
or "left_pupil_size_detail" in validated
or "right_pupil_size_detail" in validated
):
raise ValidationError(

Check warning on line 412 in care/facility/api/serializers/daily_round.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/daily_round.py#L412

Added line #L412 was not covered by tests
{
"pupil_size": [
"Pupil size cannot be recorded when patient is in prone position."
]
}
)

if "additional_symptoms" in validated:
if SymptomChoiceDict["OTHERS"] in validated["additional_symptoms"]:
if "other_symptoms" not in validated:
raise ValidationError(

Check warning on line 423 in care/facility/api/serializers/daily_round.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/daily_round.py#L423

Added line #L423 was not covered by tests
{
"other_symptoms": [
"This field is required if OTHERS is selected in Additional Symptoms."
]
}
)

if "bed" in validated:
external_id = validated.pop("bed")["external_id"]
if external_id:
Expand Down
4 changes: 3 additions & 1 deletion care/facility/tests/test_patient_daily_rounds_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def setUpTestData(cls) -> None:
"rounds_type": "NORMAL",
"patient_category": "Comfort",
"action": "DISCHARGE_RECOMMENDED",
"temperature": "98.6",
"taken_at": datetime.datetime.now().isoformat(),
}

Expand All @@ -70,7 +71,8 @@ def test_action_in_log_update(
id=self.consultation_with_bed.patient_id
)
self.assertEqual(
patient.action, PatientRegistration.ActionEnum.DISCHARGE_RECOMMENDED.value
patient.action,
PatientRegistration.ActionEnum.DISCHARGE_RECOMMENDED.value,
)

def test_log_update_without_bed_for_admission(
Expand Down

0 comments on commit bdbb64f

Please sign in to comment.