from datetime import date from typing import Optional, Literal, Tuple from fastapi import HTTPException from sqlalchemy.ext.asyncio import AsyncSession from starlette import status from app.application.lens_issues_repository import LensIssuesRepository from app.application.lenses_repository import LensesRepository from app.application.patients_repository import PatientsRepository from app.application.users_repository import UsersRepository from app.domain.entities.lens_issues import LensIssueEntity from app.domain.models import LensIssue from app.infrastructure.lenses_service import LensesService from app.infrastructure.patients_service import PatientsService from app.infrastructure.users_service import UsersService class LensIssuesService: def __init__(self, db: AsyncSession): self.lens_issues_repository = LensIssuesRepository(db) self.patient_repository = PatientsRepository(db) self.users_repository = UsersRepository(db) self.lenses_repository = LensesRepository(db) async def get_all_lens_issues( self, skip: int = 0, limit: int = 10, search: Optional[str] = None, sort_order: Literal["asc", "desc"] = "desc", start_date: Optional[date] = None, end_date: Optional[date] = None ) -> Tuple[list[LensIssueEntity], int]: lens_issues, total_count = await self.lens_issues_repository.get_all( skip=skip, limit=limit, search=search, sort_order=sort_order, start_date=start_date, end_date=end_date ) return ( [self.model_to_entity(lens_issue) for lens_issue in lens_issues], total_count ) async def get_lens_issues_by_patient_id(self, patient_id: int) -> list[LensIssueEntity]: patient = await self.patient_repository.get_by_id(patient_id) if not patient: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail='Пациент с таким ID не найден', ) lens_issues = await self.lens_issues_repository.get_by_patient_id(patient.id) print(lens_issues) return [ self.model_to_entity(lens_issue) for lens_issue in lens_issues ] async def create_lens_issue(self, lens_issue: LensIssueEntity, user_id: int) -> Optional[LensIssueEntity]: patient = await self.patient_repository.get_by_id(lens_issue.patient_id) if not patient: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail='Пациент с таким ID не найден', ) user = await self.users_repository.get_by_id(user_id) if not user: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail='Пользователь с таким ID не найден', ) lens_issue.doctor_id = user_id lens = await self.lenses_repository.get_by_id(lens_issue.lens_id) if not lens: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail='Линза с таким ID не найдена', ) if lens.issued: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail='Линза уже выдана', ) lens_issue_model = self.entity_to_model(lens_issue) await self.lens_issues_repository.create(lens_issue_model) lens.issued = True await self.lenses_repository.update(lens) return self.model_to_entity(lens_issue_model) @staticmethod def entity_to_model(lens_issue: LensIssueEntity) -> LensIssue: lens_issue_model = LensIssue( issue_date=lens_issue.issue_date, patient_id=lens_issue.patient_id, doctor_id=lens_issue.doctor_id, lens_id=lens_issue.lens_id, ) if lens_issue.id is not None: lens_issue_model.id = lens_issue.id return lens_issue_model @staticmethod def model_to_entity(lens_issue_model: LensIssue) -> LensIssueEntity: lens_issue_entity = LensIssueEntity( id=lens_issue_model.id, issue_date=lens_issue_model.issue_date, patient_id=lens_issue_model.patient_id, doctor_id=lens_issue_model.doctor_id, lens_id=lens_issue_model.lens_id, ) if lens_issue_model.doctor is not None: lens_issue_entity.doctor = UsersService.model_to_entity(lens_issue_model.doctor) if lens_issue_model.patient is not None: lens_issue_entity.patient = PatientsService.model_to_entity(lens_issue_model.patient) if lens_issue_model.lens is not None: lens_issue_entity.lens = LensesService.model_to_entity(lens_issue_model.lens) return lens_issue_entity