class SignUpSerializer(serializers.ModelSerializer): user_type = ChoiceField(choices=User.TYPE_CHOICES) gender = ChoiceField(choices=GENDER_CHOICES) password = serializers.CharField(write_only=True) phone_number = PhoneNumberIsPossibleField() alt_phone_number = PhoneNumberIsPossibleField(required=False, allow_blank=True) class Meta: model = User fields = ( "id", "username", "first_name", "last_name", "email", "password", "user_type", "ward", "local_body", "district", "state", "phone_number", "alt_phone_number", "gender", "age", ) def create(self, validated_data): validated_data["password"] = make_password( validated_data.get("password")) return super().create(validated_data)
class PatientSearchSerializer(serializers.ModelSerializer): gender = ChoiceField(choices=GENDER_CHOICES) phone_number = PhoneNumberIsPossibleField() class Meta: model = PatientSearch fields = "__all__"
class PatientSearchSerializer(serializers.ModelSerializer): gender = ChoiceField(choices=GENDER_CHOICES) phone_number = PhoneNumberIsPossibleField() facility_id = serializers.IntegerField(read_only=True, allow_null=True) class Meta: model = PatientSearch exclude = ("date_of_birth", "year_of_birth")
class PatientSearchSerializer(serializers.ModelSerializer): gender = ChoiceField(choices=GENDER_CHOICES) phone_number = PhoneNumberIsPossibleField() patient_id = serializers.UUIDField(source="external_id", read_only=True) # facility_id = serializers.UUIDField(read_only=True, allow_null=True) class Meta: model = PatientSearch exclude = ("date_of_birth", "year_of_birth", "external_id", "id") + TIMESTAMP_FIELDS
def test_phone_number(self): # map -> input value -> output value # if output value is None, the it is invalid test_cases = { "7795937091": "+917795937091", "07795937091": "+917795937091", "+917795937091": "+917795937091", "+1 470-485-8757": "+14704858757", "+18944775567": "+18944775567", "+911234": None, } for ip, op in test_cases.items(): if op is None: with self.assertRaises(ValidationError): PhoneNumberIsPossibleField().to_internal_value(ip) else: self.assertEqual(PhoneNumberIsPossibleField().to_internal_value(ip), op)
class PatientSearchSerializer(serializers.ModelSerializer): gender = ChoiceField(choices=GENDER_CHOICES) phone_number = PhoneNumberIsPossibleField() facility_id = serializers.SerializerMethodField(read_only=True) class Meta: model = PatientSearch fields = "__all__" def get_facility_id(self, obj): facility_id = None patient_det = PatientRegistration.objects.filter( id=obj.patient_id).values("facility_id") if patient_det: facility_id = patient_det[0].get("facility_id") return facility_id def to_representation(self, instance): ret = super().to_representation(instance) del ret["year_of_birth"] del ret["date_of_birth"] return ret
class UserSerializer(SignUpSerializer): user_type = ChoiceField(choices=User.TYPE_CHOICES, read_only=True) is_superuser = serializers.BooleanField(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) alt_phone_number = PhoneNumberIsPossibleField(required=False, allow_blank=True) class Meta: model = User fields = ( "id", "username", "first_name", "last_name", "email", "user_type", "local_body", "district", "state", "phone_number", "alt_phone_number", "gender", "age", "is_superuser", "verified", "local_body_object", "district_object", "state_object", ) read_only_fields = ("is_superuser", "verified", "user_type", "ward", "local_body", "district", "state") extra_kwargs = {"url": {"lookup_field": "username"}}
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 = serializers.SerializerMethodField(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) 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
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.IntegerField(source="facility_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 = serializers.SerializerMethodField(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) countries_travelled = serializers.CharField(required=False, allow_blank=True) class Meta: model = PatientRegistration exclude = ("created_by", "deleted", "patient_search_id", "year_of_birth") include = ("contacted_patients",) 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 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(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"]}) 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", []) 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) 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", []) 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) return patient