209 lines
10 KiB
Python
209 lines
10 KiB
Python
from typing import Optional
|
||
from fastapi import HTTPException
|
||
from sqlalchemy.ext.asyncio import AsyncSession
|
||
from starlette import status
|
||
from datetime import date
|
||
|
||
from app.application.appointment_types_repository import AppointmentTypesRepository
|
||
from app.application.patients_repository import PatientsRepository
|
||
from app.application.scheduled_appointments_repository import ScheduledAppointmentsRepository
|
||
from app.application.users_repository import UsersRepository
|
||
from app.domain.entities.scheduled_appointment import ScheduledAppointmentEntity
|
||
from app.domain.models import ScheduledAppointment
|
||
|
||
|
||
class ScheduledAppointmentsService:
|
||
def __init__(self, db: AsyncSession):
|
||
self.scheduled_appointment_repository = ScheduledAppointmentsRepository(db)
|
||
self.appointment_types_repository = AppointmentTypesRepository(db)
|
||
self.users_repository = UsersRepository(db)
|
||
self.patients_repository = PatientsRepository(db)
|
||
|
||
async def get_all_scheduled_appointments(self, start_date: date | None = None, end_date: date | None = None) -> \
|
||
list[ScheduledAppointmentEntity]:
|
||
scheduled_appointments = await self.scheduled_appointment_repository.get_all(start_date=start_date,
|
||
end_date=end_date)
|
||
return [self.model_to_entity(scheduled_appointment) for scheduled_appointment in scheduled_appointments]
|
||
|
||
async def get_scheduled_appointments_by_doctor_id(self, doctor_id: int, start_date: date | None = None,
|
||
end_date: date | None = None) -> Optional[
|
||
list[ScheduledAppointmentEntity]]:
|
||
doctor = await self.users_repository.get_by_id(doctor_id)
|
||
if not doctor:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_400_BAD_REQUEST,
|
||
detail='Доктор с таким ID не найден',
|
||
)
|
||
scheduled_appointments = await self.scheduled_appointment_repository.get_by_doctor_id(doctor_id,
|
||
start_date=start_date,
|
||
end_date=end_date)
|
||
return [self.model_to_entity(scheduled_appointment) for scheduled_appointment in scheduled_appointments]
|
||
|
||
async def get_upcoming_scheduled_appointments_by_doctor_id(self, doctor_id: int) -> Optional[
|
||
list[ScheduledAppointmentEntity]]:
|
||
doctor = await self.users_repository.get_by_id(doctor_id)
|
||
if not doctor:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_400_BAD_REQUEST,
|
||
detail='Доктор с таким ID не найден',
|
||
)
|
||
scheduled_appointments = await self.scheduled_appointment_repository.get_upcoming_by_doctor_id(doctor_id)
|
||
return [self.model_to_entity(scheduled_appointment) for scheduled_appointment in scheduled_appointments]
|
||
|
||
async def get_scheduled_appointments_by_patient_id(self, patient_id: int, start_date: date | None = None,
|
||
end_date: date | None = None) -> Optional[
|
||
list[ScheduledAppointmentEntity]]:
|
||
patient = await self.patients_repository.get_by_id(patient_id)
|
||
if not patient:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_400_BAD_REQUEST,
|
||
detail='Пациент с таким ID не найден',
|
||
)
|
||
scheduled_appointments = await self.scheduled_appointment_repository.get_by_patient_id(patient_id,
|
||
start_date=start_date,
|
||
end_date=end_date)
|
||
return [self.model_to_entity(scheduled_appointment) for scheduled_appointment in scheduled_appointments]
|
||
|
||
async def create_scheduled_appointment(self, scheduled_appointment: ScheduledAppointmentEntity, doctor_id: int) -> \
|
||
Optional[ScheduledAppointmentEntity]:
|
||
patient = await self.patients_repository.get_by_id(scheduled_appointment.patient_id)
|
||
|
||
if not patient:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_400_BAD_REQUEST,
|
||
detail='Пациент с таким ID не найден',
|
||
)
|
||
|
||
doctor = await self.users_repository.get_by_id(doctor_id)
|
||
|
||
if not doctor:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_400_BAD_REQUEST,
|
||
detail='Доктор/пользователь с таким ID не найден',
|
||
)
|
||
|
||
scheduled_appointment.doctor_id = doctor_id
|
||
|
||
appointment_type = await self.appointment_types_repository.get_by_id(scheduled_appointment.type_id)
|
||
|
||
if not appointment_type:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_400_BAD_REQUEST,
|
||
detail='Тип приема с таким ID не найден',
|
||
)
|
||
|
||
scheduled_appointment_model = self.entity_to_model(scheduled_appointment)
|
||
|
||
await self.scheduled_appointment_repository.create(scheduled_appointment_model)
|
||
|
||
return self.model_to_entity(scheduled_appointment_model)
|
||
|
||
async def cancel_scheduled_appointment(self, scheduled_appointment_id: int, doctor_id: int):
|
||
scheduled_appointment_model = await self.scheduled_appointment_repository.get_by_id(scheduled_appointment_id)
|
||
|
||
if not scheduled_appointment_model:
|
||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Запланированный прием не найден")
|
||
|
||
if scheduled_appointment_model.is_canceled:
|
||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
|
||
detail="Scheduled appointment already cancelled")
|
||
|
||
doctor = await self.users_repository.get_by_id(doctor_id)
|
||
|
||
if not doctor:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_400_BAD_REQUEST,
|
||
detail='Доктор/пользователь с таким ID не найден',
|
||
)
|
||
|
||
if scheduled_appointment_model.doctor_id != doctor_id and doctor.role.title != 'Администратор':
|
||
raise HTTPException(
|
||
status_code=status.HTTP_403_FORBIDDEN,
|
||
detail='Доступ запрещен',
|
||
)
|
||
|
||
scheduled_appointment_model.is_canceled = True
|
||
|
||
await self.scheduled_appointment_repository.update(scheduled_appointment_model)
|
||
|
||
return self.model_to_entity(scheduled_appointment_model)
|
||
|
||
async def update_scheduled_appointment(self, scheduled_appointment_id: int,
|
||
scheduled_appointment: ScheduledAppointmentEntity) -> Optional[
|
||
ScheduledAppointmentEntity]:
|
||
scheduled_appointment_model = await self.scheduled_appointment_repository.get_by_id(scheduled_appointment_id)
|
||
|
||
if not scheduled_appointment_model:
|
||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Запланированный прием не найден")
|
||
|
||
patient = await self.patients_repository.get_by_id(scheduled_appointment.patient_id)
|
||
|
||
if not patient:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_400_BAD_REQUEST,
|
||
detail='Пациент с таким ID не найден',
|
||
)
|
||
|
||
doctor = await self.users_repository.get_by_id(scheduled_appointment.doctor_id)
|
||
|
||
if not doctor:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_400_BAD_REQUEST,
|
||
detail='Доктор/пользователь с таким ID не найден',
|
||
)
|
||
|
||
appointment_type = await self.appointment_types_repository.get_by_id(scheduled_appointment.type_id)
|
||
|
||
if not appointment_type:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_400_BAD_REQUEST,
|
||
detail='Тип приема с таким ID не найден',
|
||
)
|
||
|
||
scheduled_appointment_model.scheduled_datetime = scheduled_appointment.scheduled_datetime
|
||
scheduled_appointment_model.patient_id = scheduled_appointment.patient_id
|
||
scheduled_appointment_model.doctor_id = scheduled_appointment.doctor_id
|
||
scheduled_appointment_model.type_id = scheduled_appointment.type_id
|
||
scheduled_appointment_model.is_canceled = scheduled_appointment.is_canceled
|
||
|
||
await self.scheduled_appointment_repository.update(scheduled_appointment_model)
|
||
|
||
return self.model_to_entity(scheduled_appointment_model)
|
||
|
||
@staticmethod
|
||
def entity_to_model(scheduled_appointment: ScheduledAppointmentEntity) -> ScheduledAppointment:
|
||
scheduled_appointment_model = ScheduledAppointment(
|
||
scheduled_datetime=scheduled_appointment.scheduled_datetime,
|
||
patient_id=scheduled_appointment.patient_id,
|
||
doctor_id=scheduled_appointment.doctor_id,
|
||
type_id=scheduled_appointment.type_id,
|
||
is_canceled=scheduled_appointment.is_canceled,
|
||
)
|
||
|
||
if scheduled_appointment.id:
|
||
scheduled_appointment_model.id = scheduled_appointment.id
|
||
|
||
return scheduled_appointment_model
|
||
|
||
@staticmethod
|
||
def model_to_entity(scheduled_appointment: ScheduledAppointment) -> ScheduledAppointmentEntity:
|
||
scheduled_appointment_entity = ScheduledAppointmentEntity(
|
||
id=scheduled_appointment.id,
|
||
scheduled_datetime=scheduled_appointment.scheduled_datetime,
|
||
patient_id=scheduled_appointment.patient_id,
|
||
doctor_id=scheduled_appointment.doctor_id,
|
||
type_id=scheduled_appointment.type_id,
|
||
is_canceled=scheduled_appointment.is_canceled,
|
||
)
|
||
|
||
if scheduled_appointment.patient is not None:
|
||
scheduled_appointment_entity.patient = scheduled_appointment.patient
|
||
|
||
if scheduled_appointment.doctor is not None:
|
||
scheduled_appointment_entity.doctor = scheduled_appointment.doctor
|
||
|
||
if scheduled_appointment.type is not None:
|
||
scheduled_appointment_entity.type = scheduled_appointment.type
|
||
|
||
return scheduled_appointment_entity
|