208 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			208 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
from typing import Union
 | 
						||
 | 
						||
from sqlalchemy import select, update, insert, delete
 | 
						||
from sqlalchemy.orm import joinedload
 | 
						||
 | 
						||
from models import Service, ServiceCategory, ServicePriceRange, ServicesKit, services_kit_services
 | 
						||
from services.base import BaseService
 | 
						||
from schemas.service import *
 | 
						||
 | 
						||
 | 
						||
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)
 | 
						||
 | 
						||
    async def get_kit_by_name(self, name: str) -> Optional[ServicesKit]:
 | 
						||
        return await self.session.scalar(select(ServicesKit).where(ServicesKit.name == name))
 | 
						||
 | 
						||
    async def get_kit_by_id(self, kit_id: int) -> Optional[ServicesKit]:
 | 
						||
        return await self.session.scalar(select(ServicesKit).where(ServicesKit.id == kit_id))
 | 
						||
 | 
						||
    async def get_all_kits(self) -> GetAllServicesKitsResponse:
 | 
						||
        stmt = (
 | 
						||
            select(
 | 
						||
                ServicesKit
 | 
						||
            )
 | 
						||
            .order_by(
 | 
						||
                ServicesKit.id.desc()
 | 
						||
            )
 | 
						||
        )
 | 
						||
        kits = (await self.session.scalars(stmt)).all()
 | 
						||
        kits_schemas = GetServiceKitSchema.from_orm_list(kits)
 | 
						||
        return GetAllServicesKitsResponse(services_kits=kits_schemas)
 | 
						||
 | 
						||
    async def create_kit(self, request: CreateServicesKitRequest) -> CreateServicesKitResponse:
 | 
						||
        try:
 | 
						||
            if await self.get_kit_by_name(request.data.name):
 | 
						||
                return CreateServicesKitResponse(ok=False, message='Набор услуг с таким названием уже существует')
 | 
						||
            base_fields = request.data.model_dump_parent()
 | 
						||
            kit = ServicesKit(**base_fields)
 | 
						||
            self.session.add(kit)
 | 
						||
            await self.session.flush()
 | 
						||
            # Appending services
 | 
						||
            insert_data = []
 | 
						||
            for service_id in request.data.services_ids:
 | 
						||
                insert_data.append({
 | 
						||
                    'service_id': service_id,
 | 
						||
                    'services_kit_id': kit.id
 | 
						||
                })
 | 
						||
            if insert_data:
 | 
						||
                await self.session.execute(
 | 
						||
                    insert(services_kit_services),
 | 
						||
                    insert_data
 | 
						||
                )
 | 
						||
                await self.session.flush()
 | 
						||
            await self.session.commit()
 | 
						||
            return CreateServicesKitResponse(ok=True, message='Набор услуг успешно создан')
 | 
						||
 | 
						||
        except Exception as e:
 | 
						||
            return CreateServicesKitResponse(ok=False, message=str(e))
 | 
						||
 | 
						||
    async def update_kit(self, request: UpdateServicesKitRequest) -> UpdateServicesKitResponse:
 | 
						||
        try:
 | 
						||
            kit = await self.get_kit_by_id(request.data.id)
 | 
						||
            if not kit:
 | 
						||
                return UpdateServicesKitResponse(ok=False, message='Указанный набор услуг не существует')
 | 
						||
            base_fields = request.data.model_dump_parent()
 | 
						||
            stmt = update(ServicesKit).values(**base_fields).where(ServicesKit.id == request.data.id)
 | 
						||
            await self.session.execute(stmt)
 | 
						||
            await self.session.flush()
 | 
						||
 | 
						||
            # Deleting previous services
 | 
						||
            stmt = (
 | 
						||
                delete(
 | 
						||
                    services_kit_services
 | 
						||
                ).where(
 | 
						||
                    services_kit_services.c.services_kit_id == kit.id
 | 
						||
                )
 | 
						||
            )
 | 
						||
            await self.session.execute(stmt)
 | 
						||
            await self.session.flush()
 | 
						||
 | 
						||
            insert_data = []
 | 
						||
            for service_id in request.data.services_ids:
 | 
						||
                insert_data.append({
 | 
						||
                    'service_id': service_id,
 | 
						||
                    'services_kit_id': kit.id
 | 
						||
                })
 | 
						||
            if insert_data:
 | 
						||
                await self.session.execute(
 | 
						||
                    insert(services_kit_services),
 | 
						||
                    insert_data
 | 
						||
                )
 | 
						||
                await self.session.flush()
 | 
						||
            await self.session.commit()
 | 
						||
            return UpdateServicesKitResponse(ok=True, message='Набор услуг успешно обновлен')
 | 
						||
 | 
						||
        except Exception as e:
 | 
						||
            return UpdateServicesKitResponse(ok=False, message=str(e))
 |