示例#1
0
文件: patient.py 项目: AJIL-PAUL/care
 class MedicalHistorySerializer(serializers.Serializer):
     disease = ChoiceField(choices=DISEASE_CHOICES)
     details = serializers.CharField(required=False, allow_blank=True)
示例#2
0
文件: patient.py 项目: AJIL-PAUL/care
class PatientMetaInfoSerializer(serializers.ModelSerializer):
    occupation = ChoiceField(choices=PatientMetaInfo.OccupationChoices)

    class Meta:
        model = PatientMetaInfo
        fields = "__all__"
示例#3
0
文件: patient.py 项目: AJIL-PAUL/care
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
示例#4
0
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
示例#5
0
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
示例#6
0
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
示例#7
0
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
示例#9
0
class PatientSampleFlowSerializer(serializers.ModelSerializer):
    status = ChoiceField(choices=PatientSample.SAMPLE_TEST_FLOW_CHOICES, required=False)

    class Meta:
        model = PatientSampleFlow
        fields = "__all__"
示例#10
0
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
示例#11
0
class AnticoagulantDrugInfoSerializer(serializers.Serializer):
    mode_of_transmission = ChoiceField(choices=ModeOfTransmissionChoices)
    name = serializers.CharField()
    duration = serializers.IntegerField()
示例#12
0
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