class PrescriptionSupplierSerializer(serializers.ModelSerializer): id = serializers.CharField(source="external_id", read_only=True) scheme = ChoiceField(choices=PrescriptionSupplier.SchemeChoices) status = ChoiceField(choices=PrescriptionSupplier.StatusChoices) consultation_object = PrescriptionSupplierConsultationSerializer( source="consultation", read_only=True) facility_object = FacilityBasicInfoSerializer(source="facility", read_only=True) consultation = ExternalIdSerializerField( required=True, queryset=PatientConsultation.objects.all()) facility = ExternalIdSerializerField(required=True, queryset=Facility.objects.all()) class Meta: model = PrescriptionSupplier exclude = ("deleted", "external_id") read_only_fields = TIMESTAMP_FIELDS def create(self, validated_data): instance = super().create(validated_data) instance.updated_user = self.context["request"].user instance.save() def update(self, instance, validated_data): instance = super().update(instance, validated_data) instance.updated_user = self.context["request"].user instance.save() return instance
class PatientConsultationSerializer(serializers.ModelSerializer): id = serializers.CharField(source="external_id", read_only=True) facility_name = serializers.CharField(source="facility.name", read_only=True) suggestion_text = ChoiceField( choices=PatientConsultation.SUGGESTION_CHOICES, read_only=True, source="suggestion") symptoms = serializers.MultipleChoiceField(choices=SYMPTOM_CHOICES) category = ChoiceField(choices=CATEGORY_CHOICES, required=False) admitted_to = ChoiceField(choices=ADMIT_CHOICES, required=False) referred_to_object = FacilityBasicInfoSerializer(source="referred_to", read_only=True) referred_to = ExternalIdSerializerField(queryset=Facility.objects.all(), required=False) patient = ExternalIdSerializerField( queryset=PatientRegistration.objects.all()) facility = ExternalIdSerializerField(queryset=Facility.objects.all()) class Meta: model = PatientConsultation read_only = TIMESTAMP_FIELDS exclude = ( "deleted", "external_id", ) def validate_bed_number(self, bed_number): try: if not self.initial_data["admitted"]: bed_number = None except KeyError: bed_number = None return bed_number def validate(self, obj): validated = super().validate(obj) print(validated) if validated["suggestion"] is SuggestionChoices.R and not validated.get( "referred_to"): raise ValidationError({ "referred_to": [ f"This field is required as the suggestion is {SuggestionChoices.R}." ] }) if (validated["suggestion"] is SuggestionChoices.A and validated.get("admitted") and not validated.get("admission_date")): raise ValidationError({ "admission_date": [f"This field is required as the patient has been admitted."] }) return validated
class PatientSampleSerializer(serializers.ModelSerializer): id = serializers.UUIDField(source="external_id", read_only=True) patient_name = serializers.CharField(read_only=True, source="patient.name") patient_has_sari = serializers.BooleanField(read_only=True, source="patient.has_SARI") patient_has_confirmed_contact = serializers.BooleanField( read_only=True, source="patient.contact_with_confirmed_carrier") patient_has_suspected_contact = serializers.BooleanField( read_only=True, source="patient.contact_with_suspected_carrier") patient_travel_history = serializers.CharField( read_only=True, source="patient.countries_travelled") facility = ExternalIdSerializerField(read_only=True, source="consultation.facility") facility_object = FacilityBasicInfoSerializer( source="consultation.facility", read_only=True) sample_type = ChoiceField(choices=SAMPLE_TYPE_CHOICES, required=False) status = ChoiceField(choices=PatientSample.SAMPLE_TEST_FLOW_CHOICES, required=False) result = ChoiceField(choices=PatientSample.SAMPLE_TEST_RESULT_CHOICES, required=False) icmr_category = ChoiceField(choices=PatientSample.PATIENT_ICMR_CATEGORY, required=False) patient = ExternalIdSerializerField( required=False, queryset=PatientRegistration.objects.all()) consultation = ExternalIdSerializerField( required=False, queryset=PatientConsultation.objects.all()) date_of_sample = serializers.DateTimeField(required=False) date_of_result = serializers.DateTimeField(required=False) notes = serializers.CharField(required=False, allow_blank=True) testing_facility = ExternalIdSerializerField( queryset=Facility.objects.all(), required=False) testing_facility_object = FacilityBasicInfoSerializer( source="testing_facility", read_only=True) class Meta: model = PatientSample read_only_fields = ( "id", "facility", ) exclude = TIMESTAMP_FIELDS + ("external_id", ) def create(self, validated_data): validated_data.pop("status", None) validated_data.pop("result", None) return super(PatientSampleSerializer, self).create(validated_data)
class PatientTransferSerializer(serializers.ModelSerializer): facility_object = FacilityBasicInfoSerializer(source="facility", read_only=True) facility = ExternalIdSerializerField(write_only=True, queryset=Facility.objects.all()) patient = serializers.UUIDField(source="external_id", read_only=True) class Meta: model = PatientRegistration fields = ("facility", "date_of_birth", "patient", "facility_object") def validate_date_of_birth(self, value): if self.instance and self.instance.date_of_birth != value: raise serializers.ValidationError("Date of birth does not match") return value def create(self, validated_data): raise NotImplementedError def save(self, **kwargs): self.instance.facility = self.validated_data["facility"] PatientConsultation.objects.filter(patient=self.instance, discharge_date__isnull=True).update( discharge_date=localtime(now())) self.instance.save()
class FacilityPatientStatsHistorySerializer(serializers.ModelSerializer): id = serializers.CharField(source="external_id", read_only=True) entry_date = serializers.DateField( default=make_aware(datetime.datetime.today()).date()) facility = ExternalIdSerializerField(queryset=Facility.objects.all(), read_only=True) class Meta: model = FacilityPatientStatsHistory exclude = ( "deleted", "external_id", ) read_only_fields = ( "id", "facility", ) def create(self, validated_data): instance, _ = FacilityPatientStatsHistory.objects.update_or_create( facility=validated_data["facility"], entry_date=validated_data["entry_date"], defaults={ **validated_data, "deleted": False }, ) return instance
class UserSkillSerializer(ModelSerializer): id = UUIDField(source="external_id", read_only=True) skill = ExternalIdSerializerField(write_only=True, required=True, queryset=Skill.objects.all()) skill_object = SkillSerializer(source="skill", read_only=True) class Meta: model = UserSkill fields = ("id", "skill", "skill_object")
class PatientConsultationSerializer(serializers.ModelSerializer): id = serializers.CharField(source="external_id", read_only=True) facility_name = serializers.CharField(source="facility.name", read_only=True) suggestion_text = ChoiceField( choices=PatientConsultation.SUGGESTION_CHOICES, read_only=True, source="suggestion", ) symptoms = serializers.MultipleChoiceField(choices=SYMPTOM_CHOICES) category = ChoiceField(choices=CATEGORY_CHOICES, required=False) admitted_to = ChoiceField(choices=ADMIT_CHOICES, required=False) referred_to_object = FacilityBasicInfoSerializer(source="referred_to", read_only=True) referred_to = ExternalIdSerializerField(queryset=Facility.objects.all(), required=False) patient = ExternalIdSerializerField( queryset=PatientRegistration.objects.all()) facility = ExternalIdSerializerField(queryset=Facility.objects.all()) assigned_to_object = UserBaseMinimumSerializer(source="assigned_to", read_only=True) assigned_to = serializers.PrimaryKeyRelatedField( queryset=User.objects.all(), required=False, allow_null=True) action = ChoiceField(choices=PatientRegistration.ActionChoices, write_only=True, required=False) review_time = serializers.IntegerField(default=-1, write_only=True, required=False) last_edited_by = UserBaseMinimumSerializer(read_only=True) created_by = UserBaseMinimumSerializer(read_only=True) class Meta: model = PatientConsultation read_only = TIMESTAMP_FIELDS + ( "discharge_date", "last_edited_by", "created_by", ) exclude = ("deleted", "external_id") def validate_bed_number(self, bed_number): try: if not self.initial_data["admitted"]: bed_number = None except KeyError: bed_number = None return bed_number def update(self, instance, validated_data): instance.last_edited_by = self.context["request"].user if instance.discharge_date: raise ValidationError({ "consultation": [f"Discharged Consultation data cannot be updated"] }) if instance.suggestion == SuggestionChoices.OP: instance.discharge_date = localtime(now()) instance.save() if "action" in validated_data or "review_time" in validated_data: patient = instance.patient if "action" in validated_data: action = validated_data.pop("action") patient.action = action if "review_time" in validated_data: review_time = validated_data.pop("review_time") if review_time >= 0: patient.review_time = localtime( now()) + timedelta(minutes=review_time) patient.save() return super().update(instance, validated_data) def create(self, validated_data): action = -1 review_time = -1 if "action" in validated_data: action = validated_data.pop("action") if "review_time" in validated_data: review_time = validated_data.pop("review_time") if validated_data["patient"].last_consultation: if self.context["request"].user == validated_data[ "patient"].last_consultation.assigned_to: return ValidationError( { "Permission Denied": "Only Facility Admins can create consultation for a Patient" }, ) consultation = super().create(validated_data) consultation.created_by = self.context["request"].user consultation.last_edited_by = self.context["request"].user consultation.save() patient = consultation.patient if consultation.suggestion == SuggestionChoices.OP: consultation.discharge_date = localtime(now()) consultation.save() patient.is_active = False patient.allow_transfer = True patient.last_consultation = consultation if action != -1: patient.action = action if review_time > 0: patient.review_time = localtime( now()) + timedelta(minutes=review_time) patient.save() NotificationGenerator( event=Notification.Event.PATIENT_CONSULTATION_CREATED, caused_by=self.context["request"].user, caused_object=consultation, facility=patient.facility, ).generate() return consultation def update(self, instance, validated_data): consultation = super().update(instance, validated_data) NotificationGenerator( event=Notification.Event.PATIENT_CONSULTATION_UPDATED, caused_by=self.context["request"].user, caused_object=consultation, facility=consultation.patient.facility, ).generate() return consultation def validate(self, obj): validated = super().validate(obj) if validated["suggestion"] is SuggestionChoices.R and not validated.get( "referred_to"): raise ValidationError({ "referred_to": [ f"This field is required as the suggestion is {SuggestionChoices.R}." ] }) if (validated["suggestion"] is SuggestionChoices.A and validated.get("admitted") and not validated.get("admission_date")): raise ValidationError({ "admission_date": [f"This field is required as the patient has been admitted."] }) if "action" in validated: if validated["action"] == PatientRegistration.ActionEnum.REVIEW: if "review_time" not in validated: raise ValidationError({ "review_time": [ f"This field is required as the patient has been requested Review." ] }) if validated["review_time"] <= 0: raise ValidationError({ "review_time": [f"This field value is must be greater than 0."] }) return validated