from typing import Optional from fastapi import HTTPException from sqlalchemy.ext.asyncio import AsyncSession from starlette import status from app.application.lens_types_repository import LensTypesRepository from app.application.set_content_repository import SetContentRepository from app.application.sets_repository import SetsRepository from app.domain.entities.set_content import SetContentEntity from app.domain.models import SetContent from app.domain.models.lens import SideEnum class SetContentService: def __init__(self, db: AsyncSession): self.set_content_repository = SetContentRepository(db) self.set_repository = SetsRepository(db) self.lens_types_repository = LensTypesRepository(db) async def get_all_set_content(self) -> list[SetContentEntity]: set_content = await self.set_content_repository.get_all() return [ self.model_to_entity(content) for content in set_content ] async def get_content_by_set_id(self, set_id: int) -> Optional[list[SetContentEntity]]: _set = await self.set_repository.get_by_id(set_id) if not _set: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail='The set with this ID was not found', ) set_content = await self.set_content_repository.get_by_set_id(set_id) return [ self.model_to_entity(content) for content in set_content ] async def create_list_sets(self, set_id: int, sets_content: list[SetContentEntity]) -> Optional[ list[SetContentEntity]]: _set = await self.set_repository.get_by_id(set_id) if not _set: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail='The set with this ID was not found', ) sets_content_models = [] for content in sets_content: lens_type = await self.lens_types_repository.get_by_id(content.type_id) if not lens_type: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail='The lens type with this ID was not found', ) sets_content_models.append( self.entity_to_model(content, set_id, skip_id=True) ) await self.set_content_repository.create_list(sets_content_models) return [ self.model_to_entity(content) for content in sets_content_models ] async def create_set_content(self, set_id: int, set_content: SetContentEntity) -> Optional[SetContentEntity]: _set = await self.set_repository.get_by_id(set_id) if not _set: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail='The set with this ID was not found', ) lens_type = await self.lens_types_repository.get_by_id(set_content.type_id) if not lens_type: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail='The lens type with this ID was not found', ) _set = await self.set_repository.get_by_id(set_content.set_id) if not _set: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail='The set with this ID was not found', ) set_content_model = self.entity_to_model(set_content, set_id) await self.set_content_repository.create(set_content_model) return self.model_to_entity(set_content_model) async def update_set_content_by_set_id(self, set_id: int, sets_content: list[SetContentEntity]) -> Optional[ list[SetContentEntity] ]: _set = await self.set_repository.get_by_id(set_id) if not _set: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail='The set with this ID was not found', ) old_set_content = await self.set_content_repository.get_by_set_id(set_id) await self.set_content_repository.delete_list_sets( list(old_set_content) ) result = [] for content in sets_content: model_content = self.entity_to_model(content, set_id, skip_id=True) model_content = await self.set_content_repository.create(model_content) result.append(model_content) return [ self.model_to_entity(content) for content in result ] async def update_set_content(self, set_content_id: int, set_content: SetContentEntity) -> Optional[ SetContentEntity ]: set_content_model = await self.set_content_repository.get_by_id(set_content_id) if not set_content_model: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Set content not found") _set = await self.set_repository.get_by_id(set_content.set_id) if not _set: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail='The set with this ID was not found', ) try: side_enum = SideEnum(set_content_model.side) except ValueError: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Invalid side value: {set_content_model.side}. Must be 'левая' or 'правая'." ) set_content_model.tor = set_content.tor set_content_model.trial = set_content.trial set_content_model.esa = set_content.esa set_content_model.fvc = set_content.fvc set_content_model.preset_refraction = set_content.preset_refraction set_content_model.diameter = set_content.diameter set_content_model.periphery_toricity = set_content.periphery_toricity set_content_model.side = side_enum set_content_model.count = set_content.count set_content_model.type_id = set_content.type_id set_content_model.set_id = set_content.set_id await self.set_content_repository.update(set_content_model) return self.model_to_entity(set_content_model) async def delete_set_content(self, set_content_id: int) -> Optional[SetContentEntity]: set_content = await self.set_content_repository.get_by_id(set_content_id) if not set_content: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Set content not found") result = await self.set_content_repository.delete(set_content) return self.model_to_entity(result) @staticmethod def entity_to_model(set_content: SetContentEntity, set_id=None, skip_id=False) -> SetContent: if set_id is None: set_id = set_content.set_id try: side_enum = SideEnum(set_content.side) except ValueError: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Invalid side value: {set_content.side}. Must be 'левая' or 'правая'." ) set_content_model = SetContent( tor=set_content.tor, trial=set_content.trial, esa=set_content.esa, fvc=set_content.fvc, preset_refraction=set_content.preset_refraction, diameter=set_content.diameter, periphery_toricity=set_content.periphery_toricity, side=side_enum, count=set_content.count, type_id=set_content.type_id, set_id=set_id, ) if set_content.id is not None and not skip_id: set_content_model.id = set_content.id return set_content_model @staticmethod def model_to_entity(set_content_model: SetContent) -> SetContentEntity: return SetContentEntity( id=set_content_model.id, tor=set_content_model.tor, trial=set_content_model.trial, esa=set_content_model.esa, fvc=set_content_model.fvc, preset_refraction=set_content_model.preset_refraction, diameter=set_content_model.diameter, periphery_toricity=set_content_model.periphery_toricity, side=set_content_model.side.value, count=set_content_model.count, type_id=set_content_model.type_id, set_id=set_content_model.set_id, )