from sqlalchemy import select, update from sqlalchemy.orm import joinedload from models import Service, ServiceCategory, ServicePriceRange from services.base import BaseService from schemas.service import ServiceGetAllResponse, ServiceSchema, ServiceGetAllCategoriesResponse, \ ServiceCategorySchema, ServiceCreateRequest, ServiceCreateResponse, ServiceCreateCategoryRequest, \ ServiceCreateCategoryResponse, ServiceUpdateRequest, ServiceUpdateResponse, ServiceDeleteResponse, \ ServiceDeleteRequest class ServiceService(BaseService): async def get_all(self) -> ServiceGetAllResponse: query = await (self.session .scalars(select(Service) .options(joinedload(Service.category)) .order_by(Service.category_id, Service.id))) services = [] for service in query.all(): services.append(ServiceSchema.model_validate(service)) return ServiceGetAllResponse(services=services) async def create(self, request: ServiceCreateRequest) -> ServiceCreateResponse: try: raw_service = request.service service_dict = raw_service.model_dump() service_dict['category_id'] = raw_service.category.id del service_dict['id'] del service_dict['category'] del service_dict['price_ranges'] service = Service(**service_dict) self.session.add(service) await self.session.flush() price_ranges = request.service.price_ranges for price_range in price_ranges: price_range_dict = price_range.model_dump() price_range_dict['service_id'] = service.id del price_range_dict['id'] price_range_obj = ServicePriceRange(**price_range_dict) self.session.add(price_range_obj) await self.session.commit() return ServiceCreateResponse(ok=True, message="Услуга успешно создана") except Exception as e: return ServiceCreateResponse(ok=False, message=f"Неудалось создать услугу, ошибка: {e}") async def update(self, request: ServiceUpdateRequest) -> ServiceUpdateResponse: try: raw_service = request.data service = await (self.session.get(Service, raw_service.id)) if not service: return ServiceUpdateResponse(ok=False, message="Услуга не найдена") service_dict = raw_service.dict() service_dict['category_id'] = raw_service.category.id del service_dict['category'] del service_dict['price_ranges'] await self.session.execute( update(Service) .where(Service.id == raw_service.id) .values(**service_dict) ) # checking if old price ranges are still in the request request_price_range_ids = [price_range.id for price_range in raw_service.price_ranges if price_range.id] price_ranges_to_delete = [] for price_range in service.price_ranges: if price_range.id not in request_price_range_ids: price_ranges_to_delete.append(price_range) for price_range in price_ranges_to_delete: await self.session.delete(price_range) await self.session.flush() for price_range in raw_service.price_ranges: price_range_dict = price_range.dict() price_range_dict['service_id'] = raw_service.id if price_range.id: await self.session.execute( update(ServicePriceRange) .where(ServicePriceRange.id == price_range.id) .values(**price_range_dict) ) else: del price_range_dict['id'] price_range_obj = ServicePriceRange(**price_range_dict) self.session.add(price_range_obj) await self.session.commit() return ServiceUpdateResponse(ok=True, message="Услуга успешно обновлена") except Exception as e: return ServiceUpdateResponse(ok=False, message=f"Неудалось обновить услугу, ошибка: {e}") async def delete(self, request: ServiceDeleteRequest) -> ServiceDeleteResponse: try: service = await (self.session .scalar(select(Service) .filter(Service.id == request.service_id))) if not service: return ServiceDeleteResponse(ok=False, message="Услуга не найдена") await self.session.delete(service) await self.session.commit() return ServiceDeleteResponse(ok=True, message="Услуга успешно удалена") except Exception as e: return ServiceDeleteResponse(ok=False, message=f"Неудалось удалить услугу, ошибка: {e}") async def create_category(self, request: ServiceCreateCategoryRequest) -> ServiceCreateCategoryResponse: try: raw_category = request.category category_dict = raw_category.model_dump() del category_dict['id'] category = ServiceCategory(**category_dict) self.session.add(category) await self.session.commit() return ServiceCreateCategoryResponse(ok=True, message="Категория успешно создана") except Exception as e: return ServiceCreateCategoryResponse(ok=False, message=f"Неудалось создать категорию, ошибка: {e}") async def get_all_categories(self) -> ServiceGetAllCategoriesResponse: query = await (self.session .scalars(select(ServiceCategory) .order_by(ServiceCategory.id))) categories = [] for category in query.all(): categories.append(ServiceCategorySchema.model_validate(category)) return ServiceGetAllCategoriesResponse(categories=categories)