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))
|