class MedicalHistorySerializer(serializers.Serializer): disease = ChoiceField(choices=DISEASE_CHOICES) details = serializers.CharField(required=False, allow_blank=True)
class PatientMetaInfoSerializer(serializers.ModelSerializer): occupation = ChoiceField(choices=PatientMetaInfo.OccupationChoices) class Meta: model = PatientMetaInfo fields = "__all__"
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) 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"]}) 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() 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() return patient
class ShiftingSerializer(serializers.ModelSerializer): id = serializers.UUIDField(source="external_id", read_only=True) status = ChoiceField(choices=SHIFTING_STATUS_CHOICES) breathlessness_level = ChoiceField(choices=BREATHLESSNESS_CHOICES) patient_object = PatientListSerializer(source="patient", read_only=True, required=False) orgin_facility_object = FacilityBasicInfoSerializer( source="orgin_facility", read_only=True, required=False) shifting_approving_facility_object = FacilityBasicInfoSerializer( source="shifting_approving_facility", read_only=True, required=False) assigned_facility_object = FacilityBasicInfoSerializer( source="assigned_facility", read_only=True, required=False) assigned_facility_type = ChoiceField(choices=FACILITY_TYPES) preferred_vehicle_choice = ChoiceField(choices=VEHICLE_CHOICES) orgin_facility = serializers.UUIDField(source="orgin_facility.external_id", allow_null=False, required=True) shifting_approving_facility = serializers.UUIDField( source="shifting_approving_facility.external_id", allow_null=False, required=True) assigned_facility = serializers.UUIDField( source="assigned_facility.external_id", allow_null=True, required=False) patient = serializers.UUIDField(source="patient.external_id", allow_null=False, required=True) assigned_to_object = UserBaseMinimumSerializer(source="assigned_to", read_only=True) created_by_object = UserBaseMinimumSerializer(source="created_by", read_only=True) last_edited_by_object = UserBaseMinimumSerializer(source="last_edited_by", read_only=True) def __init__(self, instance=None, **kwargs): if instance: kwargs["partial"] = True super().__init__(instance=instance, **kwargs) def update(self, instance, validated_data): LIMITED_RECIEVING_STATUS_ = [ "DESTINATION APPROVED", "DESTINATION REJECTED", "COMPLETED", ] LIMITED_RECIEVING_STATUS = [ REVERSE_SHIFTING_STATUS_CHOICES[x] for x in LIMITED_RECIEVING_STATUS_ ] LIMITED_SHIFTING_STATUS_ = [ "APPROVED", "REJECTED", "PATIENT TO BE PICKED UP", "TRANSPORTATION TO BE ARRANGED", "TRANSFER IN PROGRESS", "COMPLETED", "PENDING", "ON HOLD", ] LIMITED_SHIFTING_STATUS = [ REVERSE_SHIFTING_STATUS_CHOICES[x] for x in LIMITED_SHIFTING_STATUS_ ] LIMITED_ORGIN_STATUS = [] user = self.context["request"].user if "is_kasp" in validated_data: if validated_data[ "is_kasp"] != instance.is_kasp: # Check only when changed if not has_facility_permission( user, instance.shifting_approving_facility): raise ValidationError({"kasp": ["Permission Denied"]}) if "breathlessness_level" in validated_data: if not has_facility_permission( user, instance.shifting_approving_facility): del validated_data["breathlessness_level"] if "status" in validated_data: if validated_data["status"] in LIMITED_RECIEVING_STATUS: if instance.assigned_facility: if not has_facility_permission(user, instance.assigned_facility): raise ValidationError( {"status": ["Permission Denied"]}) else: raise ValidationError({"status": ["Permission Denied"]}) elif "status" in validated_data: if validated_data["status"] in LIMITED_SHIFTING_STATUS: if not has_facility_permission( user, instance.shifting_approving_facility): raise ValidationError( {"status": ["Permission Denied"]}) # Dont allow editing origin or patient if "orgin_facility" in validated_data: validated_data.pop("orgin_facility") if "patient" in validated_data: validated_data.pop("patient") if "shifting_approving_facility" in validated_data: shifting_approving_facility_external_id = validated_data.pop( "shifting_approving_facility")["external_id"] if shifting_approving_facility_external_id: validated_data[ "shifting_approving_facility_id"] = Facility.objects.get( external_id=shifting_approving_facility_external_id).id if "assigned_facility" in validated_data: assigned_facility_external_id = validated_data.pop( "assigned_facility")["external_id"] if assigned_facility_external_id: validated_data["assigned_facility_id"] = Facility.objects.get( external_id=assigned_facility_external_id).id instance.last_edited_by = self.context["request"].user return super().update(instance, validated_data) def create(self, validated_data): # Do Validity checks for each of these data if "status" in validated_data: validated_data.pop("status") validated_data["is_kasp"] = False orgin_facility_external_id = validated_data.pop( "orgin_facility")["external_id"] # validated_data["orgin_facility_id"] = Facility.objects.get(external_id=orgin_facility_external_id).id shifting_approving_facility_external_id = validated_data.pop( "shifting_approving_facility")["external_id"] validated_data[ "shifting_approving_facility_id"] = Facility.objects.get( external_id=shifting_approving_facility_external_id).id if "assigned_facility" in validated_data: assigned_facility_external_id = validated_data.pop( "assigned_facility")["external_id"] if assigned_facility_external_id: validated_data["assigned_facility_id"] = Facility.objects.get( external_id=assigned_facility_external_id).id patient_external_id = validated_data.pop("patient")["external_id"] patient = PatientRegistration.objects.get( external_id=patient_external_id) if patient.is_active == False: raise ValidationError( {"patient": ["Cannot shift discharged patient"]}) if patient.allow_transfer == False: patient.allow_transfer = True patient.save() validated_data["orgin_facility_id"] = patient.facility.id validated_data["patient_id"] = patient.id if ShiftingRequest.objects.filter(~Q(status__in=[30, 50, 80]), patient=patient).exists(): raise ValidationError( {"request": ["Shifting Request for Patient already exists"]}) validated_data["created_by"] = self.context["request"].user validated_data["last_edited_by"] = self.context["request"].user return super().create(validated_data) class Meta: model = ShiftingRequest exclude = ("deleted", ) read_only_fields = TIMESTAMP_FIELDS
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__" 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) disease_status = ChoiceField(choices=DISEASE_STATUS_CHOICES, default=DiseaseStatusEnum.SUSPECTED.value) class Meta: model = PatientRegistration exclude = ("created_by", "deleted") 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 create(self, validated_data): with transaction.atomic(): medical_history = validated_data.pop("medical_history", []) 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) return patient def update(self, instance, validated_data): with transaction.atomic(): medical_history = validated_data.pop("medical_history", []) 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) return patient
class DailyRoundSerializer(serializers.ModelSerializer): additional_symptoms = serializers.MultipleChoiceField( choices=SYMPTOM_CHOICES, required=False) patient_category = ChoiceField(choices=CATEGORY_CHOICES, required=False) current_health = ChoiceField(choices=CURRENT_HEALTH_CHOICES, required=False) admitted_to = ChoiceField(choices=ADMIT_CHOICES, required=True) action = ChoiceField(choices=PatientRegistration.ActionChoices, write_only=True, required=False) review_time = serializers.IntegerField(default=-1, write_only=True, required=False) class Meta: model = DailyRound exclude = ( "created_date", "modified_date", ) def update(self, instance, validated_data): if instance.consultation.discharge_date: raise ValidationError({ "consultation": [f"Discharged Consultation data cannot be updated"] }) if "action" in validated_data or "review_time" in validated_data: patient = instance.consultation.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): if "action" in validated_data or "review_time" in validated_data: patient = validated_data["consultation"].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().create(validated_data) def validate(self, obj): validated = super().validate(obj) if validated["consultation"].discharge_date: raise ValidationError({ "consultation": [f"Discharged Consultation data cannot be updated"] }) 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
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") 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() 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
class DailyRoundSerializer(serializers.ModelSerializer): additional_symptoms = serializers.MultipleChoiceField( choices=SYMPTOM_CHOICES, required=False) patient_category = ChoiceField(choices=CATEGORY_CHOICES, required=False) current_health = ChoiceField(choices=CURRENT_HEALTH_CHOICES, required=False) admitted_to = ChoiceField(choices=ADMIT_CHOICES, required=True) action = ChoiceField(choices=PatientRegistration.ActionChoices, write_only=True, required=False) review_time = serializers.IntegerField(default=-1, write_only=True, required=False) class Meta: model = DailyRound read_only_fields = ("last_updated_by_telemedicine", "created_by_telemedicine") exclude = ("deleted", ) def update(self, instance, validated_data): if instance.consultation.discharge_date: raise ValidationError({ "consultation": [f"Discharged Consultation data cannot be updated"] }) if "action" in validated_data or "review_time" in validated_data: patient = instance.consultation.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() validated_data["last_updated_by_telemedicine"] = False if self.context["request"].user == instance.consultation.assigned_to: validated_data["last_updated_by_telemedicine"] = True instance.consultation.save( update_fields=["last_updated_by_telemedicine"]) NotificationGenerator( event=Notification.Event.PATIENT_CONSULTATION_UPDATE_UPDATED, caused_by=self.context["request"].user, caused_object=instance, facility=instance.consultation.patient.facility, ).generate() return super().update(instance, validated_data) def create(self, validated_data): if "action" in validated_data or "review_time" in validated_data: patient = validated_data["consultation"].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() validated_data["created_by_telemedicine"] = False validated_data["last_updated_by_telemedicine"] = False if self.context["request"].user == validated_data[ "consultation"].assigned_to: validated_data["created_by_telemedicine"] = True validated_data["last_updated_by_telemedicine"] = True daily_round_obj = super().create(validated_data) daily_round_obj.consultation.last_updated_by_telemedicine = validated_data[ "last_updated_by_telemedicine"] daily_round_obj.consultation.save( update_fields=["last_updated_by_telemedicine"]) NotificationGenerator( event=Notification.Event.PATIENT_CONSULTATION_UPDATE_CREATED, caused_by=self.context["request"].user, caused_object=daily_round_obj, facility=daily_round_obj.consultation.patient.facility, ).generate() return daily_round_obj def validate(self, obj): validated = super().validate(obj) if validated["consultation"].discharge_date: raise ValidationError({ "consultation": [f"Discharged Consultation data cannot be updated"] }) 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
class PatientSampleFlowSerializer(serializers.ModelSerializer): status = ChoiceField(choices=PatientSample.SAMPLE_TEST_FLOW_CHOICES, required=False) class Meta: model = PatientSampleFlow fields = "__all__"
class ResourceRequestSerializer(serializers.ModelSerializer): id = serializers.UUIDField(source="external_id", read_only=True) status = ChoiceField(choices=RESOURCE_STATUS_CHOICES) orgin_facility_object = FacilityBasicInfoSerializer(source="orgin_facility", read_only=True, required=False) approving_facility_object = FacilityBasicInfoSerializer( source="approving_facility", read_only=True, required=False ) assigned_facility_object = FacilityBasicInfoSerializer(source="assigned_facility", read_only=True, required=False) category = ChoiceField(choices=RESOURCE_CATEGORY_CHOICES) orgin_facility = serializers.UUIDField(source="orgin_facility.external_id", allow_null=False, required=True) approving_facility = serializers.UUIDField( source="approving_facility.external_id", allow_null=False, required=True ) assigned_facility = serializers.UUIDField(source="assigned_facility.external_id", allow_null=True, required=False) assigned_to_object = UserBaseMinimumSerializer(source="assigned_to", read_only=True) created_by_object = UserBaseMinimumSerializer(source="created_by", read_only=True) last_edited_by_object = UserBaseMinimumSerializer(source="last_edited_by", read_only=True) def __init__(self, instance=None, **kwargs): if instance: kwargs["partial"] = True super().__init__(instance=instance, **kwargs) def update(self, instance, validated_data): LIMITED_RECIEVING_STATUS_ = [] LIMITED_RECIEVING_STATUS = [REVERSE_REQUEST_STATUS_CHOICES[x] for x in LIMITED_RECIEVING_STATUS_] LIMITED_REQUEST_STATUS_ = [ "ON HOLD", "APPROVED", "REJECTED", "TRANSPORTATION TO BE ARRANGED", "TRANSFER IN PROGRESS", "COMPLETED", ] LIMITED_REQUEST_STATUS = [REVERSE_REQUEST_STATUS_CHOICES[x] for x in LIMITED_REQUEST_STATUS_] LIMITED_ORGIN_STATUS = [] user = self.context["request"].user if "status" in validated_data: if validated_data["status"] in LIMITED_RECIEVING_STATUS: if instance.assigned_facility: if not has_facility_permission(user, instance.assigned_facility): raise ValidationError({"status": ["Permission Denied"]}) elif validated_data["status"] in LIMITED_REQUEST_STATUS: if not has_facility_permission(user, instance.approving_facility): raise ValidationError({"status": ["Permission Denied"]}) # Dont allow editing origin or patient if "orgin_facility" in validated_data: validated_data.pop("orgin_facility") if "approving_facility" in validated_data: approving_facility_external_id = validated_data.pop("approving_facility")["external_id"] if approving_facility_external_id: validated_data["approving_facility_id"] = Facility.objects.get( external_id=approving_facility_external_id ).id if "assigned_facility" in validated_data: assigned_facility_external_id = validated_data.pop("assigned_facility")["external_id"] if assigned_facility_external_id: validated_data["assigned_facility_id"] = Facility.objects.get( external_id=assigned_facility_external_id ).id instance.last_edited_by = self.context["request"].user new_instance = super().update(instance, validated_data) return new_instance def create(self, validated_data): # Do Validity checks for each of these data if "status" in validated_data: validated_data.pop("status") orgin_facility_external_id = validated_data.pop("orgin_facility")["external_id"] validated_data["orgin_facility_id"] = Facility.objects.get(external_id=orgin_facility_external_id).id request_approving_facility_external_id = validated_data.pop("approving_facility")["external_id"] validated_data["approving_facility_id"] = Facility.objects.get( external_id=request_approving_facility_external_id ).id if "assigned_facility" in validated_data: assigned_facility_external_id = validated_data.pop("assigned_facility")["external_id"] if assigned_facility_external_id: validated_data["assigned_facility_id"] = Facility.objects.get( external_id=assigned_facility_external_id ).id validated_data["created_by"] = self.context["request"].user validated_data["last_edited_by"] = self.context["request"].user return super().create(validated_data) class Meta: model = ResourceRequest exclude = ("deleted",) read_only_fields = TIMESTAMP_FIELDS
class AnticoagulantDrugInfoSerializer(serializers.Serializer): mode_of_transmission = ChoiceField(choices=ModeOfTransmissionChoices) name = serializers.CharField() duration = serializers.IntegerField()
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_fields = TIMESTAMP_FIELDS + ( "last_updated_by_telemedicine", "discharge_date", "last_edited_by", "created_by", "kasp_enabled_date", ) 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": ["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() validated_data["last_updated_by_telemedicine"] = self.context[ "request"].user == instance.assigned_to if "is_kasp" in validated_data: if validated_data["is_kasp"] and (not instance.is_kasp): validated_data["kasp_enabled_date"] = localtime(now()) if "assigned_to" in validated_data: if validated_data["assigned_to"] != instance.assigned_to: NotificationGenerator( event=Notification.Event.PATIENT_CONSULTATION_ASSIGNMENT, caused_by=self.context["request"].user, caused_object=instance, facility=instance.patient.facility, notification_mediums=[ Notification.Medium.SYSTEM, Notification.Medium.WHATSAPP ], ).generate() 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 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: raise ValidationError( { "Permission Denied": "Only Facility Staff can create consultation for a Patient" }, ) if validated_data["patient"].last_consultation: if not validated_data["patient"].last_consultation.discharge_date: raise ValidationError({ "consultation": "Exists please Edit Existing Consultation" }) if "is_kasp" in validated_data: if validated_data["is_kasp"]: validated_data["kasp_enabled_date"] = localtime(now()) 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() if consultation.assigned_to: NotificationGenerator( event=Notification.Event.PATIENT_CONSULTATION_ASSIGNMENT, caused_by=self.context["request"].user, caused_object=consultation, facility=consultation.patient.facility, notification_mediums=[ Notification.Medium.SYSTEM, Notification.Medium.WHATSAPP ], ).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