class PatientListSerializer(serializers.ModelSerializer): id = serializers.CharField(source="external_id", read_only=True) facility = serializers.UUIDField(source="facility.external_id", allow_null=True, read_only=True) facility_object = FacilityBasicInfoSerializer(source="facility", read_only=True) ward_object = WardSerializer(source="ward", read_only=True) local_body_object = LocalBodySerializer(source="local_body", read_only=True) district_object = DistrictSerializer(source="district", read_only=True) state_object = StateSerializer(source="state", read_only=True) last_consultation = PatientConsultationSerializer(read_only=True) blood_group = ChoiceField(choices=BLOOD_GROUP_CHOICES, required=True) disease_status = ChoiceField(choices=DISEASE_STATUS_CHOICES, default=DiseaseStatusEnum.SUSPECTED.value) source = ChoiceField(choices=PatientRegistration.SourceChoices) assigned_to_object = UserBaseMinimumSerializer(source="assigned_to", read_only=True) class Meta: model = PatientRegistration exclude = ( "created_by", "deleted", "ongoing_medication", "patient_search_id", "year_of_birth", "meta_info", "countries_travelled_old", "allergies", "external_id", ) read_only = TIMESTAMP_FIELDS
def get_last_consultation(self, obj): last_consultation = PatientConsultation.objects.filter( patient=obj).last() if not last_consultation: return None return PatientConsultationSerializer(last_consultation).data
class PatientDetailSerializer(PatientListSerializer): class MedicalHistorySerializer(serializers.Serializer): disease = ChoiceField(choices=DISEASE_CHOICES) details = serializers.CharField(required=False, allow_blank=True) class PatientTeleConsultationSerializer(serializers.ModelSerializer): class Meta: model = PatientTeleConsultation fields = "__all__" phone_number = PhoneNumberIsPossibleField() facility = serializers.UUIDField(source="facility.external_id", allow_null=True, required=False) medical_history = serializers.ListSerializer( child=MedicalHistorySerializer(), required=False) tele_consultation_history = serializers.ListSerializer( child=PatientTeleConsultationSerializer(), read_only=True) last_consultation = PatientConsultationSerializer(read_only=True) facility_object = FacilitySerializer(source="facility", read_only=True) # nearest_facility_object = FacilitySerializer( # source="nearest_facility", read_only=True # ) source = ChoiceField( choices=PatientRegistration.SourceChoices, default=PatientRegistration.SourceEnum.CARE.value, ) disease_status = ChoiceField(choices=DISEASE_STATUS_CHOICES, default=DiseaseStatusEnum.SUSPECTED.value) meta_info = PatientMetaInfoSerializer(required=False, allow_null=True) contacted_patients = PatientContactDetailsSerializer(many=True, required=False, allow_null=True) test_type = ChoiceField( choices=PatientRegistration.TestTypeChoices, required=False, default=PatientRegistration.TestTypeEnum.UNK.value, ) last_edited = UserBaseMinimumSerializer(read_only=True) created_by = UserBaseMinimumSerializer(read_only=True) vaccine_name = serializers.ChoiceField( choices=PatientRegistration.vaccineChoices, required=False, allow_null=True) assigned_to_object = UserBaseMinimumSerializer(source="assigned_to", read_only=True) assigned_to = serializers.PrimaryKeyRelatedField( queryset=User.objects.all(), required=False, allow_null=True) class Meta: model = PatientRegistration exclude = ( "deleted", "patient_search_id", "year_of_birth", "countries_travelled_old", "external_id", ) include = ("contacted_patients", ) read_only = TIMESTAMP_FIELDS + ("last_edited", "created_by", "is_active") # def get_last_consultation(self, obj): # last_consultation = PatientConsultation.objects.filter(patient=obj).last() # if not last_consultation: # return None # return PatientConsultationSerializer(last_consultation).data def validate_facility(self, value): if value is not None and Facility.objects.filter( id=value).first() is None: raise serializers.ValidationError("facility not found") return value def validate_countries_travelled(self, value): if not value: value = [] if not isinstance(value, list): value = [value] return value def validate(self, attrs): validated = super().validate(attrs) if not self.partial and not validated.get("age") and not validated.get( "date_of_birth"): raise serializers.ValidationError({ "non_field_errors": [f"Either age or date_of_birth should be passed"] }) if validated.get("is_vaccinated"): if validated.get("number_of_doses") == 0: raise serializers.ValidationError( "Number of doses cannot be 0") if validated.get("vaccine_name") == None: raise serializers.ValidationError( "Vaccine name cannot be null") return validated def create(self, validated_data): with transaction.atomic(): medical_history = validated_data.pop("medical_history", []) meta_info = validated_data.pop("meta_info", {}) contacted_patients = validated_data.pop("contacted_patients", []) if "facility" in validated_data: external_id = validated_data.pop("facility")["external_id"] if external_id: validated_data["facility_id"] = Facility.objects.get( external_id=external_id).id validated_data["created_by"] = self.context["request"].user patient = super().create(validated_data) diseases = [] for disease in medical_history: diseases.append(Disease(patient=patient, **disease)) if diseases: Disease.objects.bulk_create(diseases, ignore_conflicts=True) if meta_info: meta_info_obj = PatientMetaInfo.objects.create(**meta_info) patient.meta_info = meta_info_obj patient.save() if contacted_patients: contacted_patient_objs = [ PatientContactDetails(**data, patient=patient) for data in contacted_patients ] PatientContactDetails.objects.bulk_create( contacted_patient_objs) patient.last_edited = self.context["request"].user patient.save() NotificationGenerator( event=Notification.Event.PATIENT_CREATED, caused_by=self.context["request"].user, caused_object=patient, facility=patient.facility, ).generate() return patient def update(self, instance, validated_data): with transaction.atomic(): medical_history = validated_data.pop("medical_history", []) meta_info = validated_data.pop("meta_info", {}) contacted_patients = validated_data.pop("contacted_patients", []) if "facility" in validated_data: external_id = validated_data.pop("facility")["external_id"] if external_id: validated_data["facility_id"] = Facility.objects.get( external_id=external_id).id patient = super().update(instance, validated_data) Disease.objects.filter(patient=patient).update(deleted=True) diseases = [] for disease in medical_history: diseases.append(Disease(patient=patient, **disease)) if diseases: Disease.objects.bulk_create(diseases, ignore_conflicts=True) if meta_info: for key, value in meta_info.items(): setattr(patient.meta_info, key, value) patient.meta_info.save() if self.partial is not True: # clear the list and enter details if PUT patient.contacted_patients.all().delete() if contacted_patients: contacted_patient_objs = [ PatientContactDetails(**data, patient=patient) for data in contacted_patients ] PatientContactDetails.objects.bulk_create( contacted_patient_objs) patient.last_edited = self.context["request"].user patient.save() NotificationGenerator( event=Notification.Event.PATIENT_UPDATED, caused_by=self.context["request"].user, caused_object=patient, facility=patient.facility, ).generate() return patient