Exemplo n.º 1
0
    def test_check_birthdate(self, patientd):
        """
        check no bithdate later
        """

        d = datetime.date(3000, 1, 1)
        patientd['birthdate'] = d
        s = PatientSerializer(data=patientd)
        with pytest.raises(serializers.ValidationError):
            s.is_valid(raise_exception=True), "sould return validation error"
Exemplo n.º 2
0
    def test_retrieve_patient_list(self, apiclient):

        factory.create_batch(Patient, 12, FACTORY_CLASS=FacPatient)
        resp = apiclient.get(reverse('patient-list'))
        patients = Patient.objects.all()
        req = APIRequestFactory().get(reverse('patient-list'))
        ser = PatientSerializer(patients, many=True, context={'request': req})
        assert resp.data == ser.data
Exemplo n.º 3
0
    def test_retrive_patients(self):
        """Test retrieving patients"""
        Patient.objects.create(doctor=self.user,
                               name='Jan',
                               surname='Kowalski')
        Patient.objects.create(doctor=self.user,
                               name='Janek',
                               surname='Kowalski')

        res = self.client.get(PATIENTS_URL)

        patients = Patient.objects.all().order_by('-surname')
        serializer = PatientSerializer(patients, many=True)

        self.assertEqual(res.status_code, status.HTTP_200_OK)
        self.assertEqual(res.data, serializer.data)
Exemplo n.º 4
0
    def test_serializer(self):
        doctor_user = User.objects.create(username=PATIENT_USERNAME,
                                          password=PATIENT_PASSWORD,
                                          email=PATIENT_EMAIL)
        doctor = Doctor.objects.create(user=doctor_user,
                                       first_name=PATIENT_FIRST_NAME,
                                       last_name=PATIENT_LAST_NAME)
        expected_json = \
        '{{"username": "******", "password": "******", "email": "{2}", "first_name": "{3}", "last_name": "{4}" }}' \
            .format(PATIENT_USERNAME,
                    PATIENT_PASSWORD,
                    PATIENT_EMAIL,
                    PATIENT_FIRST_NAME,
                    PATIENT_LAST_NAME)

        actual_json = PatientSerializer.serialize(doctor)
        self.assertEqual(expected_json, actual_json)
Exemplo n.º 5
0
class MedRecordSerializer(serializers.ModelSerializer):
    patient = PatientSerializer(allow_null=True)
    patient_address = AddressSerializer(allow_null=True)
    call_address = AddressSerializer(allow_null=True)
    mr_result = MRResultSerializer(allow_null=True)

    class Meta:
        model = MedRecord
        fields = [
            'id',
            'med_record_id',
            'call_card_id',
            'mis_id',
            'callcard',
            'crew',
            'operator_id',
            'mis_medrecord_id',

            'start_datetime',
            'time_crew',
            'time_depart',
            'time_patient',
            'time_transport',
            'time_hospital',
            'end_datetime',

            'patient',
            'patient_address',
            'call_address',
            'patient_address_src',
            'patient_document',

            'noresult',
            'mr_result',
            'is_hospital_record',
            'is_diagnosis_record',

            'mr_comment',
            'date_modified',
            'timestamp'
        ]

    def to_internal_value(self, data):
        logging.info("MedRecordSerializer: To to_internal_value")
        ret = OrderedDict()
        errors = OrderedDict()
        # operator_id required
        # if not 'operator_id' in data:
        operator_id = data.get('operator_id', None)
        if not operator_id:
            error = "Error: operator_id is required"
            logging.error(error)
            raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]})
        else:
            # operator_id must be in Staff list
            operator_id = data.get('operator_id', False)
            staff_q = Staff.objects.filter(mis_id=data['mis_id'], mis_staff_id=operator_id)
            if not staff_q.exists():
                error = "Error: operator_id must be in staff list"
                logging.error(error)
                raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]})
            data['operator_id'] = staff_q.first().id

        patient_address_src = data.get('patient_address_src', None)
        if patient_address_src:
            patient_address_src_qs = AddrDocType.objects.filter(name=patient_address_src)
            if patient_address_src_qs.exists():
                patient_address_src_obj = patient_address_src_qs.first()
                data['patient_address_src'] = patient_address_src_obj.id
            else:
                error = f"Bad patient_address_src: {data['patient_address_src']}"
                logging.error(error)
                raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]})
        else:
            data['patient_address_src'] = 1     # Невідомо

        noresult = data.get('noresult', None)
        if noresult:
            noresult_qs = NoResult.objects.filter(name=noresult)
            if noresult_qs.exists():
                noresult_obj = noresult_qs.first()
                data['noresult'] = noresult_obj.id
            else:
                error = f"Bad noresult: {data['noresult']}"
                logging.error(error)
                raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]})
        else:
            data['noresult'] = 1  # Результативний

        hospital = data.get('hospital', None)
        if hospital:
            data['is_hospital_record'] = True
        else:
            data['is_hospital_record'] = False

        if not self.instance:
            call_card_id = data.get('call_card_id', False)
            if not call_card_id:
                error = "Error: call_card_id is required!"
                logging.error(error)
                raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]})
            else:
                #call_card_id = data.get('call_card_id', False)
                call_card_qs = CallCard.objects.filter(call_card_id=call_card_id)
                if call_card_qs.exists():
                    call_card_obj = call_card_qs.first()
                    if int(call_card_obj.mis_id.id) != int(data['mis_id']):
                        error = f"CallCard [{data['call_card_id']}] doesnt belong to MIS [{data['mis_id']}]"
                        logging.error(error)
                        raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]})
                    data['callcard'] = call_card_obj.id
                    if call_card_obj.crew_id:
                        data['crew'] = call_card_obj.crew_id.id
                    else:
                        error = f"MedRecord: No crew in related CallCard {call_card_obj.call_card_id}"
                        logging.error(error)
                        raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]})
                else:
                    error = f"Bad call_card_id: {data['call_card_id']}"
                    logging.error(error)
                    raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]})

        fields = self._writable_fields
        for field in fields:
            validate_method = getattr(self, 'validate_' + field.field_name, None)
            primitive_value = data.get(field.source_attrs[0], False)
            if primitive_value:
                try:
                    validated_value = field.run_validation(primitive_value)
                    if validate_method is not None:
                        validated_value = validate_method(validated_value)
                except ValidationError as exc:
                    errors[field.field_name] = exc.detail
                except DjangoValidationError as exc:
                    errors[field.field_name] = get_error_detail(exc)
                except SkipField:
                    pass
                else:
                    set_value(ret, field.source_attrs, validated_value)

        if errors:
            raise ValidationError(errors)

        #ret = super().to_internal_value(data=data)
        return ret

    def to_representation(self, instance):
        mr_data = super().to_representation(instance)
        del mr_data['id']
        del mr_data['mis_id']
        del mr_data['callcard']

        mr_data['operator_id'] = Staff.objects.get(id=mr_data['operator_id']).mis_staff_id
        if mr_data['crew']:
            crew_obj = Crew.objects.get(id=mr_data['crew'])
            mr_data['crew'] = crew_obj.crew_id
        mr_data['noresult'] = NoResult.objects.get(id=mr_data['noresult']).name
        mr_data['patient_address_src'] = AddrDocType.objects.get(id=mr_data['patient_address_src']).name

        return mr_data

    def update(self, instance, validated_data):
        # logging.info(f'MedRecordSerializer: update()')
        validated_data = self.doMRCPC(validated_data=validated_data, instance=instance)
        # validated_data.pop("start_datetime")

        instance = super().update(instance=instance, validated_data=validated_data)
        return instance

    def create(self, validated_data):
        if 'id' in validated_data:
            return None

        validated_data = self.doMRCPC(validated_data=validated_data)
        with transaction.atomic():
            validated_data['med_record_id'] = self.createMRSlug()
            cc_obj = MedRecord.objects.create(**validated_data)

        return cc_obj

    def createMRSlug(self):
        today = date.today()
        if not MedRecordSlug.objects.filter(id=1).exists():
            slugdate = MedRecordSlug()
            slugdate.save()
        else:
            slugdate = MedRecordSlug.objects.get(id=1)

        if slugdate.date_modified.date() != today:
            logging.info("Next Day. Have to flush sequence")
            val = get_next_value('medrecord_number')
            number_int = get_next_value('medrecord_number', reset_value=(val + 1))
            logging.info(f"val: {val}, val1: {number_int}")
        else:
            #print("The same date. Keep sequence")
            number_int = get_next_value('medrecord_number')

        slugdate.save()

        number_str = str(number_int).zfill(6)
        slug = f'MR-{today.isoformat()}-{number_str}'
        return slug

    def doMRCPC(self, validated_data, instance=None):
        d_patient = validated_data.get('patient', False)
        if d_patient:
            #print('patient in validated_data')
            if instance is not None:
                if instance.patient is not None:
                    #print('instance exists')
                    patient_obj = super().update(instance.patient, d_patient)
                    validated_data['patient'] = patient_obj
                else:
                    #print('Creating patient instance1')
                    patient_obj = Patient.objects.create(**d_patient)
                    validated_data['patient'] = patient_obj
            else:
                #print('Creating patient instance2')
                patient_obj = Patient.objects.create(**d_patient)
                validated_data['patient'] = patient_obj

        d_complain = validated_data.get('complain', False)
        if d_complain:
            #print('complain in validated_data')
            if instance is not None:
                if instance.complain is not None:
                    #print('instance exists')
                    complain_obj = super().update(instance.complain, d_complain)
                    validated_data['complain'] = complain_obj
                else:
                    #print('Creating complain instance1')
                    complain_obj = Complain.objects.create(**d_complain)
                    validated_data['complain'] = complain_obj
            else:
                #print('Creating complain instance2')
                complain_obj = Complain.objects.create(**d_complain)
                validated_data['complain'] = complain_obj

        d_patient_address = validated_data.get('patient_address', False)
        if d_patient_address:
            if instance is not None:
                if instance.patient_address is not None:
                    patient_address_obj = super().update(instance.patient_address, d_patient_address)
                    validated_data['patient_address'] = patient_address_obj
                else:
                    patient_address_obj = Address.objects.create(**d_patient_address)
                    validated_data['patient_address'] = patient_address_obj
            else:
                patient_address_obj = Address.objects.create(**d_patient_address)
                validated_data['patient_address'] = patient_address_obj

        d_call_address = validated_data.get('call_address', False)
        if d_call_address:
            if instance is not None:
                if instance.call_address is not None:
                    call_address_obj = super().update(instance.call_address, d_call_address)
                    validated_data['call_address'] = call_address_obj
                else:
                    call_address_obj = Address.objects.create(**d_patient_address)
                    validated_data['call_address'] = call_address_obj
            else:
                call_address_obj = Address.objects.create(**d_call_address)
                validated_data['call_address'] = call_address_obj

        d_mr_result = validated_data.get('mr_result', False)
        if d_mr_result:
            if instance is not None:
                if instance.mr_result is not None:
                    mr_result_obj = super().update(instance.mr_result, d_mr_result)
                    validated_data['mr_result'] = mr_result_obj
                else:
                    mr_result_obj = MRResult.objects.create(**d_mr_result)
                    validated_data['mr_result'] = mr_result_obj
            else:
                mr_result_obj = MRResult.objects.create(**d_mr_result)
                validated_data['mr_result'] = mr_result_obj

        return validated_data
Exemplo n.º 6
0
class CallCardSerializer(serializers.ModelSerializer):
    complain = ComplainSerializer(allow_null=True)
    patient = PatientSerializer(allow_null=True)
    call_address = AddressSerializer(allow_null=True)
    intercall = CCIntercallSerializer(allow_null=True)

    class Meta:
        model = CallCard
        fields = [
            'id',
            'call_card_id',
            'mis_id',
            'mis_user',
            'operator_id',
            'mis_call_card_id',
            'caller_number',
            'start_datetime',
            'end_datetime',
            'call_priority',
            'call_result',
            'call_station',
            'complain',
            'patient',
            'call_address',
            'intercall',
            'crew_id',
            'call_comment',
            'date_modified',
            'timestamp'
        ]
        #read_only_fields = ["start_datetime"]

    def to_internal_value(self, data):
        logging.info("CallCardSerializer: To to_internal_value")
        ret = OrderedDict()
        errors = OrderedDict()

        if not 'mis_id' in data:
            mis_obj = Mis.objects.get(mis_user=data['mis_user'])
            data['mis_id'] = mis_obj.id
            data['mis_user'] = mis_obj.mis_user.id
        data['start_datetime'] = data.get('start_datetime', timezone.now().isoformat())
        try:
            instance_start = datetime.fromisoformat(data['start_datetime'])
        except Exception as ex:
            logging.error(f"CallCardSerializer:: invalid start_datetime: {data['start_datetime']}")
            raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [ex]})

        data['call_station'] = data.get('call_station', "1")
        if data['start_datetime'] == "":
            error = "start_date_time may not be an empty string"
            logging.error(error)
            raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]})

        crew_id = data.get('crew_id', False)
        if crew_id:
            crew_q = Crew.objects.filter(mis_id=data['mis_id'],
                                         crew_id=data['crew_id'])
            if crew_q.exists():
                crew_obj = crew_q.first()
                if int(crew_obj.mis_id.id) != int(data['mis_id']):
                    error = f"Crew [{data['crew_id']}] doesnt belong to MIS [{data['mis_id']}]"
                    logging.error(error)
                    raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]})
                data['crew_id'] = crew_obj.id
            else:
                error = f"Bad mis_id:crew_id: {data['mis_id']}: {data['crew_id']}"
                logging.error(error)
                raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]})

        call_station = data.get('call_station', "1")
        if (type(call_station) == int) or call_station.isdigit():
            station_obj = CallStations.objects.get(id=call_station)
            if station_obj == None:
                error = f"Bad callStation: {call_station}"
                logging.error(error)
                raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]})
            data['call_station'] = station_obj.id
        else:
            station_obj = CallStations.objects.filter(station_name=call_station).first()
            if station_obj == None:
                error = f"Bad callStation: {call_station}"
                logging.error(error)
                raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]})
            data['call_station'] = station_obj.id
        call_priority = data.get('call_priority', False)
        if call_priority:
            if (type(call_priority) == int) or call_priority.isdigit():
                priority_obj = CallPriority.objects.get(id=call_priority)
                if priority_obj == None:
                    error = f"Bad call_priority: {call_priority}"
                    logging.error(error)
                    raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]})
                data['call_priority'] = priority_obj.id
            else:
                priority_obj = CallPriority.objects.filter(priority_name=call_priority).first()
                if priority_obj == None:
                    error = f"Bad call_priority: {call_priority}"
                    logging.error(error)
                    raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]})
                data['call_priority'] = priority_obj.id

        call_result = data.get('call_result', False)
        if call_result:
            if (type(call_result) == int) or call_result.isdigit():
                result_obj = CallResult.objects.get(id=call_result)
                if result_obj == None:
                    error = f"Bad call_result: {call_result}"
                    logging.error(error)
                    raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]})
                data['call_result'] = result_obj.id
            else:
                result_obj = CallResult.objects.filter(result_name=call_result).first()
                if result_obj == None:
                    error = f"Bad call_result: {call_result}"
                    logging.error(error)
                    raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]})
                data['call_result'] = result_obj.id

        # Comments to CallCard only by Operator103
        c_c = data.get('call_comment', None)
        if c_c:
            if data['call_station'] != 2:
                data.pop('call_comment')
            else:
                c_c = str(c_c)
                if len(c_c) > 254:
                    logging.warning("Stripping call_comment")
                    data['call_comment'] = c_c[:254]
                else:
                    data['call_comment'] = c_c

        # end_datetime is required
        end_datetime = data.get('end_datetime', None)
        if not end_datetime:
            error = "Error: end_datetime is required"
            logging.error(error)
            raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]})
        # operator_id required
        operator_id = data.get('operator_id', None)
        if not operator_id:
            error = "Error: operator_id is required"
            logging.error(error)
            raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]})
        # operator_id must be in Staff list
        staff_qs = Staff.objects.filter(mis_id=data['mis_id'], mis_staff_id=operator_id)
        if not staff_qs.exists():
            error = "Error: operator_id must be in staff list"
            logging.error(error)
            raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [error]})
        # Only Operator103 goes to CallCard
        operator_id_pk = staff_qs.first().id
        if data['call_station'] <= 2 | (not self.instance):
            data['operator_id'] = operator_id_pk
        else:
            data.pop('operator_id')

        # print(f'data[start_datetime]: {data["start_datetime"]}')
        fields = self._writable_fields
        for field in fields:
            validate_method = getattr(self, 'validate_' + field.field_name, None)
            primitive_value = data.get(field.source_attrs[0], False)
            if primitive_value:
                try:
                    validated_value = field.run_validation(primitive_value)
                    if validate_method is not None:
                        validated_value = validate_method(validated_value)
                except ValidationError as exc:
                    errors[field.field_name] = exc.detail
                except DjangoValidationError as exc:
                    errors[field.field_name] = get_error_detail(exc)
                except SkipField:
                    pass
                else:
                    set_value(ret, field.source_attrs, validated_value)

        if errors:
            raise ValidationError(errors)

        data['operator_id'] = operator_id_pk

        # Check if already Archive
        if self.instance and self.instance.call_station:
            if self.instance.call_station.station_name == "Архів":
                cc_slug = ret.get('call_card_id', None)
                logging.warning(f"CallCardSerializer:: The card# {cc_slug} is in Archive already. ")
                callrecord_start = datetime.fromisoformat(data['start_datetime'])
                logging.warning(f'callrecord_start : {callrecord_start.isoformat()}')
                logging.warning(f'callcard_end_time: {self.instance.end_datetime.isoformat()}')
                # logging.warning("CallCardSerializer:: puting call_station to Archive back")
                # ret['call_station'] = CallStations.objects.get(station_name="Архів")
                if callrecord_start < self.instance.end_datetime:
                    logging.warning("CallCardSerializer:: puting call_station to Archive back")
                    ret['call_station'] = CallStations.objects.get(station_name="Архів")

        #ret = super().to_internal_value(data=data)
        # print(f'ret [start_datetime]: {ret["start_datetime"]}')
        # print(ret)
        return ret

    def to_representation(self, instance):
        cc_data = super().to_representation(instance)
        del cc_data['id']
        del cc_data['mis_user']
        del cc_data['mis_id']

        if cc_data['crew_id']:
            crew_obj = Crew.objects.get(id=cc_data['crew_id'])
            cc_data['crew_id'] = crew_obj.crew_id

        # CallStation reverse presentation
        station_obj = CallStations.objects.get(id=cc_data['call_station'])
        cc_data['call_station'] = station_obj.station_name

        # CallResult reverse presentation
        if cc_data['call_result']:
            result_obj = CallResult.objects.get(id=cc_data['call_result'])
            cc_data['call_result'] = result_obj.result_name

        # CallPriority reverse presentation
        priority_obj = CallPriority.objects.get(id=cc_data['call_priority'])
        cc_data['call_priority'] = priority_obj.priority_name

        cc_data['operator_id'] = Staff.objects.get(id=cc_data['operator_id']).mis_staff_id

        # if not cc_data['intercall']:
        #     del cc_data['intercall']

        return cc_data

    def update(self, instance, validated_data):
        # logging.info(f'CallCardSerializer: update()')
        validated_data = self.doCPC(validated_data=validated_data, instance=instance)
        validated_data.pop("start_datetime")

        instance = super().update(instance=instance, validated_data=validated_data)
        return instance

    def create(self, validated_data):
        if 'id' in validated_data:
            return None

        validated_data = self.doCPC(validated_data=validated_data)
        with transaction.atomic():
            validated_data['call_card_id'] = self.createCCSlug()
            cc_obj = CallCard.objects.create(**validated_data)

        return cc_obj

    def createCCSlug(self):
        today = date.today()
        if not CallCardSlug.objects.filter(id=1).exists():
            slugdate = CallCardSlug()
            slugdate.save()
        else:
            slugdate = CallCardSlug.objects.get(id=1)

        if slugdate.date_modified.date() != today:
            val = get_next_value('callCard_number')
            number_int = get_next_value('callCard_number', reset_value=(val + 1))
        else:
            number_int = get_next_value('callCard_number')

        slugdate.save()

        number_str = str(number_int).zfill(6)
        slug = f'ER-{today.isoformat()}-{number_str}'
        return slug

    def doCPC(self, validated_data, instance=None):
        d_intercall = validated_data.get('intercall', False)
        if d_intercall:
            if instance is not None:
                if instance.intercall is not None:
                    intercall_obj = super().update(instance.intercall, d_intercall)
                    validated_data['intercall'] = intercall_obj
                else:
                    intercall_obj = CCIntercall.objects.create(**d_intercall)
                    validated_data['intercall'] = intercall_obj
            else:
                intercall_obj = CCIntercall.objects.create(**d_intercall)
                validated_data['intercall'] = intercall_obj
        d_patient = validated_data.get('patient', False)
        if d_patient:
            if instance is not None:
                if instance.patient is not None:
                    patient_obj = super().update(instance.patient, d_patient)
                    validated_data['patient'] = patient_obj
                else:
                    patient_obj = Patient.objects.create(**d_patient)
                    validated_data['patient'] = patient_obj
            else:
                patient_obj = Patient.objects.create(**d_patient)
                validated_data['patient'] = patient_obj

        d_complain = validated_data.get('complain', False)
        if d_complain:
            if instance is not None:
                if instance.complain is not None:
                    complain_obj = super().update(instance.complain, d_complain)
                    validated_data['complain'] = complain_obj
                else:
                    complain_obj = Complain.objects.create(**d_complain)
                    validated_data['complain'] = complain_obj
            else:
                complain_obj = Complain.objects.create(**d_complain)
                validated_data['complain'] = complain_obj

        d_call_address = validated_data.get('call_address', False)
        if d_call_address:
            if instance is not None:
                if instance.call_address is not None:
                    call_address_obj = super().update(instance.call_address, d_call_address)
                    validated_data['call_address'] = call_address_obj
                else:
                    call_address_obj = Address.objects.create(**d_call_address)
                    validated_data['call_address'] = call_address_obj
            else:
                call_address_obj = Address.objects.create(**d_call_address)
                validated_data['call_address'] = call_address_obj

        return validated_data
Exemplo n.º 7
0
 def list(self, request):
     queryset = self.get_queryset()
     serializer = PatientSerializer(queryset, many=True)
     return Response(serializer.data)
Exemplo n.º 8
0
 def test_phone_number_is_well_formated(self, patientd):
     a = patientd
     a['phonenumber'] = random.randrange(100000 - 88000)
     s = PatientSerializer(data=a)
     with pytest.raises(serializers.ValidationError):
         s.is_valid(raise_exception=True), " sould start with + or 0"
Exemplo n.º 9
0
 def test_postal_code_is_digit(self, patientd):
     patientd['postalcode'] = "aaaaa"
     s = PatientSerializer(data=patientd)
     with pytest.raises(serializers.ValidationError):
         s.is_valid(raise_exception=True), " postale code can't be chars"
Exemplo n.º 10
0
 def test_postal_code_max_size(self, patientd):
     patientd['postalcode'] = "123456"
     s = PatientSerializer(data=patientd)
     with pytest.raises(serializers.ValidationError):
         s.is_valid(raise_exception=True), " postale code can't be 6 digit"