diff --git a/care/facility/api/serializers/patient.py b/care/facility/api/serializers/patient.py index f526db1b73..9a54d49888 100644 --- a/care/facility/api/serializers/patient.py +++ b/care/facility/api/serializers/patient.py @@ -459,16 +459,32 @@ class PatientTransferSerializer(serializers.ModelSerializer): write_only=True, queryset=Facility.objects.all() ) patient = serializers.UUIDField(source="external_id", read_only=True) + last_consultation_discharge_date = serializers.DateTimeField( + write_only=True, required=True + ) class Meta: model = PatientRegistration - fields = ("facility", "year_of_birth", "patient", "facility_object") + fields = ( + "facility", + "year_of_birth", + "patient", + "facility_object", + "last_consultation_discharge_date", + ) def validate_year_of_birth(self, value): if self.instance and self.instance.year_of_birth != value: raise serializers.ValidationError("Year of birth does not match") return value + def validate_last_consultation_discharge_date(self, value): + if self.instance and self.instance.last_consultation.encounter_date >= value: + raise serializers.ValidationError( + "Discharge date should be after the last encounter date" + ) + return value + def create(self, validated_data): raise NotImplementedError @@ -481,14 +497,16 @@ def update(self, instance, validated_data): ).first() if consultation: - consultation.discharge_date = now() + consultation.discharge_date = validated_data[ + "last_consultation_discharge_date" + ] consultation.new_discharge_reason = NewDischargeReasonEnum.REFERRED consultation.current_bed = None consultation.save() ConsultationBed.objects.filter( consultation=consultation, end_date__isnull=True - ).update(end_date=now()) + ).update(end_date=validated_data["last_consultation_discharge_date"]) instance.save() return instance diff --git a/care/facility/api/serializers/patient_consultation.py b/care/facility/api/serializers/patient_consultation.py index ad0cd8ece3..41d323c67f 100644 --- a/care/facility/api/serializers/patient_consultation.py +++ b/care/facility/api/serializers/patient_consultation.py @@ -515,6 +515,7 @@ def validate_encounter_date(self, value): raise ValidationError( {"encounter_date": "This field value cannot be in the future."} ) + return value def validate_patient_no(self, value): @@ -623,6 +624,26 @@ def validate(self, attrs): if not self.instance and "create_diagnoses" not in validated: raise ValidationError({"create_diagnoses": ["This field is required."]}) + if "encounter_date" in validated and "patient" in validated: + last_consultation = ( + PatientConsultation.objects.filter( + patient=validated["patient"], discharge_date__isnull=False + ) + .order_by("-encounter_date") + .first() + ) + if ( + last_consultation + and validated["encounter_date"] <= last_consultation.discharge_date + ): + raise ValidationError( + { + "encounter_date": [ + "This field value must be greater than the last discharge date." + ] + } + ) + return validated diff --git a/care/facility/tests/test_patient_api.py b/care/facility/tests/test_patient_api.py index d86f7fdd20..ecd9b0305e 100644 --- a/care/facility/tests/test_patient_api.py +++ b/care/facility/tests/test_patient_api.py @@ -465,6 +465,7 @@ def test_patient_transfer(self): { "year_of_birth": 1992, "facility": self.destination_facility.external_id, + "last_consultation_discharge_date": now().isoformat(), }, ) self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -482,6 +483,22 @@ def test_patient_transfer(self): ) self.assertIsNotNone(self.consultation.discharge_date) + def test_patient_transfer_with_invalid_discharge_date(self): + self.client.force_authenticate(user=self.super_user) + response = self.client.post( + f"/api/v1/patient/{self.patient.external_id}/transfer/", + { + "year_of_birth": 1992, + "facility": self.destination_facility.external_id, + "last_consultation_discharge_date": "2000-01-01T00:00:00Z", # This is before the consultation date + }, + ) + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + self.assertEqual( + response.data["last_consultation_discharge_date"][0], + "Discharge date should be after the last encounter date", + ) + def test_transfer_with_active_consultation_same_facility(self): # Set the patient's facility to allow transfers self.patient.allow_transfer = True