class PatientNotesSerializer(serializers.ModelSerializer): facility = FacilityBasicInfoSerializer(read_only=True) created_by_object = UserBaseMinimumSerializer(source="created_by", read_only=True) class Meta: model = PatientNotes fields = ("note", "facility", "created_by_object", "created_date") read_only_fields = ("created_date", )
class FileUploadListSerializer(serializers.ModelSerializer): id = serializers.UUIDField(source="external_id", read_only=True) uploaded_by = UserBaseMinimumSerializer(read_only=True) class Meta: model = FileUpload fields = ("id", "name", "uploaded_by", "created_date") read_only_fields = ("associating_id", "name", "created_date")
class AssetTransactionSerializer(ModelSerializer): id = UUIDField(source="external_id", read_only=True) asset = AssetBareMinimumSerializer(read_only=True) from_location = AssetLocationSerializer(read_only=True) to_location = AssetLocationSerializer(read_only=True) performed_by = UserBaseMinimumSerializer(read_only=True) class Meta: model = AssetTransaction exclude = ("deleted", "external_id")
class FileUploadRetrieveSerializer(serializers.ModelSerializer): id = serializers.UUIDField(source="external_id", read_only=True) uploaded_by = UserBaseMinimumSerializer(read_only=True) read_signed_url = serializers.CharField(read_only=True) class Meta: model = FileUpload fields = ("id", "name", "uploaded_by", "created_date", "read_signed_url", "file_category") read_only_fields = ("associating_id", "name", "created_date")
def get_users(self, request, external_id): user_type_filter = None if "user_type" in request.GET: if request.GET["user_type"] in User.TYPE_VALUE_MAP: user_type_filter = User.TYPE_VALUE_MAP[ request.GET["user_type"]] users = self.get_object().users.all() if user_type_filter: users = users.filter(user_type=user_type_filter) users = users.order_by("-last_login") data = UserBaseMinimumSerializer(users, many=True) return Response(data.data)
class ResourceRequestCommentSerializer(serializers.ModelSerializer): created_by_object = UserBaseMinimumSerializer(source="created_by", read_only=True) def create(self, validated_data): validated_data["created_by"] = self.context["request"].user return super().create(validated_data) class Meta: model = ResourceRequestComment exclude = ("deleted", "request") read_only_fields = TIMESTAMP_FIELDS + ("created_by",)
def get_users(self, request, external_id): user_type_filter = None if "user_type" in request.GET: if request.GET["user_type"] in User.TYPE_VALUE_MAP: user_type_filter = User.TYPE_VALUE_MAP[request.GET["user_type"]] facility = Facility.objects.filter(external_id=external_id).first() if not facility: return Response({"facility": "does not exist"}, status=status.HTTP_404_NOT_FOUND) users = facility.users.all() if user_type_filter: users = users.filter(user_type=user_type_filter) users = users.order_by("-last_login") data = UserBaseMinimumSerializer(users, many=True) return Response(data.data)
class NotificationSerializer(serializers.ModelSerializer): id = serializers.UUIDField(source="external_id", read_only=True) caused_by = UserBaseMinimumSerializer(read_only=True) event = ChoiceField(choices=Notification.EventChoices, read_only=True) event_type = ChoiceField(choices=Notification.EventTypeChoices, read_only=True) class Meta: model = Notification exclude = ("deleted", "modified_date", "intended_for", "medium_sent", "external_id") read_only_fields = ( "message", "caused_objects", "created_date", )
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
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) sub_category = ChoiceField(choices=RESOURCE_SUB_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 + ("external_id", )
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 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
class ShiftingSerializer(serializers.ModelSerializer): id = serializers.UUIDField(source="external_id", read_only=True) status = ChoiceField(choices=SHIFTING_STATUS_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) 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 "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 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"]}) return super().create(validated_data) class Meta: model = ShiftingRequest exclude = ("deleted",) read_only_fields = TIMESTAMP_FIELDS