visus-plus/api/app/infrastructure/scheduled_appointments_service.py

212 lines
8.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from typing import Optional
from fastapi import HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from starlette import status
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) -> list[ScheduledAppointmentEntity]:
scheduled_appointments = await self.scheduled_appointment_repository.get_all()
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) -> Optional[
list[ScheduledAppointmentEntity]
]:
doctor = 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)
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) -> 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)
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):
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