class DoctorScheduleBasicSerializer(serializers.ModelSerializer): start_time = TimeDimSerializer() end_time = TimeDimSerializer() start_date = DateDimSerializer() end_date = DateDimSerializer() days_split = serializers.SerializerMethodField('repr_days_split') def repr_days_split(self, obj): return obj.split_days() class Meta: model = DoctorSchedule fields = ('id', 'start_time', 'end_time', 'start_date', 'end_date', 'days', 'days_split', 'medical_institution')
class PatientAppointmentHistoryListSerializer(serializers.ModelSerializer): schedule_day = DateDimSerializer() time_start = TimeDimSerializer() time_end = TimeDimSerializer() queue_status = serializers.SerializerMethodField('repr_queue_status') status_display = serializers.SerializerMethodField('repr_status_display') type = serializers.SerializerMethodField('repr_type') medical_institution = MedicalInstitutionSerializer() appointment_url = serializers.SerializerMethodField('repr_appointment_url') def repr_queue_status(self, obj): if obj.status in QUEUE_INACTIVE: return 'inactive' elif obj.status in QUEUE_ACTIVE: return 'active' else: return 'waiting' def repr_type(self, obj): return obj.get_type_display() def repr_status_display(self, obj): return obj.get_status_display() def repr_appointment_url(self, obj): return f"{reverse('doctor_profile_patient_appointment_detail')}?appointment={obj.id}" class Meta: model = PatientAppointment fields = ('id', 'schedule_day', 'time_start', 'time_end', 'queue_status', 'status_display', 'type', 'medical_institution', 'appointment_url')
class DoctorScheduleDayBasicSerializer(serializers.ModelSerializer): day = DateDimSerializer() actual_start_time = TimeDimSerializer() actual_end_time = TimeDimSerializer() class Meta: model = DoctorScheduleDay fields = ('id', 'day', 'doctor', 'medical_institution', 'schedule', 'doctor_is_in', 'doctor_stepped_out', 'actual_start_time', 'actual_end_time')
class DoctorScheduleSerializer(serializers.ModelSerializer): start_time = TimeDimSerializer() end_time = TimeDimSerializer() start_date = DateDimSerializer() end_date = DateDimSerializer() doctor = DoctorProfileSerializer() medical_institution = MedicalInstitutionPublicSerializer() days_split = serializers.SerializerMethodField('repr_days_split') mi_queue = serializers.SerializerMethodField('repr_mi_queue') def repr_mi_queue(self, obj): return reverse( 'doctor_profile_schedule_detail', kwargs={'medical_institution': obj.medical_institution.slug}) def repr_days_split(self, obj): return obj.split_days() class Meta: model = DoctorSchedule fields = ('id', 'start_time', 'end_time', 'start_date', 'end_date', 'doctor', 'medical_institution', 'days', 'days_split', 'mi_queue')
class PatientAppointmentSerializer(serializers.ModelSerializer): patient = BaseProfilePrivateSerializerFull() schedule_day = DateDimSerializer() time_start = TimeDimSerializer() time_end = TimeDimSerializer() type = serializers.SerializerMethodField('repr_type') def repr_type(self, obj): return obj.get_type_display() class Meta: model = PatientAppointment fields = ( 'id', 'schedule_day', 'time_start', 'time_end', 'patient', 'doctor', 'medical_institution', 'schedule_day_object', 'type', )
class DoctorScheduleCollisionSerializer(serializers.Serializer): medical_institution = MedicalInstitutionSerializer() day = DateDimSerializer() schedule = DoctorScheduleSerializer() start_time = TimeDimSerializer() end_time = TimeDimSerializer()
class PatientQueuePrivateSerializer(serializers.ModelSerializer): patient = BaseProfilePrivateSerializerFull() schedule_day = DateDimSerializer() time_start = TimeDimSerializer() time_end = TimeDimSerializer() prior_visits = serializers.SerializerMethodField('repr_prior_visits') queue_status = serializers.SerializerMethodField('repr_queue_status') status_display = serializers.SerializerMethodField('repr_status_display') type = serializers.SerializerMethodField('repr_type') medical_institution = MedicalInstitutionSerializer() last_visit = serializers.SerializerMethodField('repr_last_visit') patient_url = serializers.SerializerMethodField('repr_patient_url') schedule = serializers.SerializerMethodField('repr_schedule') biometrics = serializers.SerializerMethodField('repr_biometrics') def repr_biometrics(self, obj): try: biometrics = Biometric.objects.get(profile=obj.patient) serializer = BiometricSerializer(biometrics) return serializer.data except Biometric.DoesNotExist: return None def repr_schedule(self, obj): if obj.schedule_day_object: return obj.schedule_day_object.schedule.id return None def repr_prior_visits(self, obj): return PatientAppointment.objects.prior_visits( doctor=obj.doctor, patient=obj.patient).count() def repr_patient_url(self, obj): return reverse('doctor_profile_patient_detail', kwargs={'patient_id': obj.patient.id}) def repr_last_visit(self, obj): visit = PatientAppointment.objects.filter( doctor=obj.doctor, patient=obj.patient, schedule_day__date_obj__lte=obj.schedule_day.date_obj, status__in=QUEUE_NOT_CANCELLED_CODES).exclude( id=obj.id).order_by('-schedule_day__date_obj').first() if visit: return { 'date': f'{visit.schedule_day}', 'id': visit.id, 'url': f"{reverse('doctor_profile_patient_appointment_detail')}?appointment={visit.id}" } return {'date': None, 'id': None, 'url': ''} def repr_queue_status(self, obj): if obj.status in QUEUE_INACTIVE: return 'inactive' elif obj.status in QUEUE_ACTIVE: return 'active' else: return 'waiting' def repr_type(self, obj): return obj.get_type_display() def repr_status_display(self, obj): return obj.get_status_display() class Meta: model = PatientAppointment fields = ('id', 'metadata', 'status', 'schedule_day', 'time_start', 'time_end', 'patient', 'doctor', 'medical_institution', 'schedule_day_object', 'prior_visits', 'type', 'queue_status', 'queue_number', 'status_display', 'last_visit', 'patient_url', 'schedule', 'biometrics')
def post(self, request, *args, **kwargs): result, profile_type = is_doctor_or_receptionist(request.user) if not result: return Response("Incompatible user profile", status=status.HTTP_403_FORBIDDEN) doctor_id = request.data.get('doctor_id', None) try: doctor = DoctorProfile.objects.get(id=doctor_id) except DoctorProfile.DoesNotExist: return Response("Doctor does not exist!", status=status.HTTP_404_NOT_FOUND) medical_institution = get_object_or_404(MedicalInstitution, id=request.data.get('medical_institution_id', None)) mi_connection = get_object_or_404(MedicalInstitutionDoctor, doctor=doctor, medical_institution=medical_institution, is_approved=True) if type(profile_type) != DoctorProfile: """ person adding isn't the doctor, so check if receptionist is allowed """ connection = doctor.verify_receptionist(receptionist=request.user.receptionistprofile, medical_institution=medical_institution) if not connection: return Response("Receptionist is not authorized by this doctor for this medical institution", status=status.HTTP_403_FORBIDDEN) elif profile_type.id != doctor.id: return Response("This is not your schedule", status=status.HTTP_401_UNAUTHORIZED) start_time = TimeDim.objects.parse(request.data.get('start_time')) end_time = TimeDim.objects.parse(request.data.get('end_time')) start_date = DateDim.objects.parse_get(request.data.get('start_date')) end_date = DateDim.objects.parse_get(request.data.get('end_date')) days = request.data.get('days').split('^') if days == ['']: return Response("Which days should this schedule be applied to?", status=status.HTTP_400_BAD_REQUEST) schedule_data = { 'days': days, 'medical_institution': medical_institution, 'start_time': start_time, 'end_time': end_time, 'start_date': start_date, 'end_date': end_date, 'doctor': doctor, 'created_by': request.user } result, message, schedule = DoctorSchedule.objects.create(**schedule_data) if result: schedule_serializer = DoctorScheduleSerializer(schedule) return Response(schedule_serializer.data, status.HTTP_201_CREATED) else: if message == "Schedule Conflict": conflict_data = [] for conflict in schedule: d = { 'medical_institution': MedicalInstitutionSerializer(conflict['medical_institution']).data, 'day': DateDimSerializer(conflict['day']).data, 'schedule': DoctorScheduleSerializer(conflict['schedule']).data, 'start_time': TimeDimSerializer(conflict['start_time']).data, 'end_time': TimeDimSerializer(conflict['end_time']).data } conflict_data.append(d) return Response(conflict_data, status=status.HTTP_409_CONFLICT) elif message == "Invalid start and end time": return Response(message, status=status.HTTP_400_BAD_REQUEST) elif message == "Invalid start and end dates": return Response(message, status=status.HTTP_400_BAD_REQUEST)