182 lines
8.2 KiB
Python
182 lines
8.2 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.appointments_repository import AppointmentsRepository
|
||
from app.application.patients_repository import PatientsRepository
|
||
from app.application.users_repository import UsersRepository
|
||
from app.domain.entities.appointment import AppointmentEntity
|
||
from app.domain.models import Appointment
|
||
from app.infrastructure.appointment_types_service import AppointmentTypesService
|
||
from app.infrastructure.patients_service import PatientsService
|
||
from app.infrastructure.users_service import UsersService
|
||
|
||
|
||
class AppointmentsService:
|
||
def __init__(self, db: AsyncSession):
|
||
self.appointments_repository = AppointmentsRepository(db)
|
||
self.appointment_types_repository = AppointmentTypesRepository(db)
|
||
self.users_repository = UsersRepository(db)
|
||
self.patients_repository = PatientsRepository(db)
|
||
|
||
async def get_all_appointments(self, start_date: date | None = None, end_date: date | None = None) -> list[
|
||
AppointmentEntity]:
|
||
appointments = await self.appointments_repository.get_all(start_date=start_date, end_date=end_date)
|
||
return [self.model_to_entity(appointment) for appointment in appointments]
|
||
|
||
async def get_appointments_by_doctor_id(self, doctor_id: int, start_date: date | None = None,
|
||
end_date: date | None = None) -> Optional[list[AppointmentEntity]]:
|
||
doctor = await self.users_repository.get_by_id(doctor_id)
|
||
if not doctor:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_400_BAD_REQUEST,
|
||
detail='Доктор с таким ID не найден',
|
||
)
|
||
appointments = await self.appointments_repository.get_by_doctor_id(doctor_id, start_date=start_date,
|
||
end_date=end_date)
|
||
return [self.model_to_entity(appointment) for appointment in appointments]
|
||
|
||
async def get_upcoming_appointments_by_doctor_id(self, doctor_id: int) -> Optional[list[AppointmentEntity]]:
|
||
doctor = await self.users_repository.get_by_id(doctor_id)
|
||
if not doctor:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_400_BAD_REQUEST,
|
||
detail='Доктор с таким ID не найден',
|
||
)
|
||
appointments = await self.appointments_repository.get_upcoming_by_doctor_id(doctor_id)
|
||
return [self.model_to_entity(appointment) for appointment in appointments]
|
||
|
||
async def get_appointment_reminders(self, current_date: date) -> list[AppointmentEntity]:
|
||
appointments = await self.appointments_repository.get_reminders(current_date)
|
||
return [self.model_to_entity(appointment) for appointment in appointments]
|
||
|
||
async def get_appointments_by_patient_id(self, patient_id: int, start_date: date | None = None,
|
||
end_date: date | None = None) -> Optional[list[AppointmentEntity]]:
|
||
patient = await self.patients_repository.get_by_id(patient_id)
|
||
if not patient:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_400_BAD_REQUEST,
|
||
detail='Пациент с таким ID не найден',
|
||
)
|
||
appointments = await self.appointments_repository.get_by_patient_id(patient_id, start_date=start_date,
|
||
end_date=end_date)
|
||
return [self.model_to_entity(appointment) for appointment in appointments]
|
||
|
||
async def create_appointment(self, appointment: AppointmentEntity, doctor_id: int) -> Optional[AppointmentEntity]:
|
||
patient = await self.patients_repository.get_by_id(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 не найден',
|
||
)
|
||
|
||
appointment.doctor_id = doctor_id
|
||
|
||
appointment_type = await self.appointment_types_repository.get_by_id(appointment.type_id)
|
||
|
||
if not appointment_type:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_400_BAD_REQUEST,
|
||
detail='Тип приема с таким ID не найден',
|
||
)
|
||
|
||
appointment_model = self.entity_to_model(appointment)
|
||
|
||
await self.appointments_repository.create(appointment_model)
|
||
|
||
return self.model_to_entity(appointment_model)
|
||
|
||
async def update_appointment(self, appointment_id: int, appointment: AppointmentEntity) -> Optional[
|
||
AppointmentEntity
|
||
]:
|
||
appointment_model = await self.appointments_repository.get_by_id(appointment_id)
|
||
|
||
if not appointment_model:
|
||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Прием не найден")
|
||
|
||
patient = await self.patients_repository.get_by_id(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(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(appointment.type_id)
|
||
|
||
if not appointment_type:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_400_BAD_REQUEST,
|
||
detail='Тип приема с таким ID не найден',
|
||
)
|
||
|
||
appointment_model.results = appointment.results
|
||
appointment_model.days_until_the_next_appointment = appointment.days_until_the_next_appointment
|
||
appointment_model.appointment_datetime = appointment.appointment_datetime
|
||
appointment_model.patient_id = appointment.patient_id
|
||
appointment_model.doctor_id = appointment.doctor_id
|
||
appointment_model.type_id = appointment.type_id
|
||
|
||
await self.appointments_repository.update(appointment_model)
|
||
|
||
return self.model_to_entity(appointment_model)
|
||
|
||
@staticmethod
|
||
def entity_to_model(appointment: AppointmentEntity) -> Appointment:
|
||
appointment_model = Appointment(
|
||
results=appointment.results,
|
||
days_until_the_next_appointment=appointment.days_until_the_next_appointment,
|
||
appointment_datetime=appointment.appointment_datetime,
|
||
patient_id=appointment.patient_id,
|
||
doctor_id=appointment.doctor_id,
|
||
type_id=appointment.type_id,
|
||
)
|
||
|
||
if appointment.id is not None:
|
||
appointment_model.id = appointment.id
|
||
|
||
return appointment_model
|
||
|
||
@staticmethod
|
||
def model_to_entity(appointment: Appointment) -> AppointmentEntity:
|
||
appointment_entity = AppointmentEntity(
|
||
id=appointment.id,
|
||
results=appointment.results,
|
||
days_until_the_next_appointment=appointment.days_until_the_next_appointment,
|
||
appointment_datetime=appointment.appointment_datetime,
|
||
patient_id=appointment.patient_id,
|
||
doctor_id=appointment.doctor_id,
|
||
type_id=appointment.type_id,
|
||
)
|
||
|
||
if appointment.patient is not None:
|
||
appointment_entity.patient = PatientsService.model_to_entity(appointment.patient)
|
||
|
||
if appointment.doctor is not None:
|
||
appointment_entity.doctor = UsersService.model_to_entity(appointment.doctor)
|
||
|
||
if appointment.type is not None:
|
||
appointment_entity.type = AppointmentTypesService.model_to_entity(appointment.type)
|
||
|
||
return appointment_entity
|