From 1a9dbd857a7e6be751e1de068502bf28a2585b0f Mon Sep 17 00:00:00 2001 From: AlexSserb Date: Tue, 16 Sep 2025 18:13:19 +0400 Subject: [PATCH] feat: adding services kit to deal --- .../repositories/deal_service.py | 20 +++++++++++- .../repositories/product_service.py | 1 - .../fulfillment_base/routers/deal_product.py | 24 +++++++------- .../fulfillment_base/routers/deal_service.py | 12 +++++++ .../fulfillment_base/schemas/deal_product.py | 10 ------ .../fulfillment_base/schemas/deal_service.py | 8 +++++ .../schemas/product_service.py | 10 ++++++ .../fulfillment_base/services/deal_product.py | 31 +------------------ .../fulfillment_base/services/deal_service.py | 18 ++++++++++- .../services/product_service.py | 30 +++++++++++++----- 10 files changed, 102 insertions(+), 62 deletions(-) diff --git a/modules/fulfillment_base/repositories/deal_service.py b/modules/fulfillment_base/repositories/deal_service.py index 601d30f..9ad5050 100644 --- a/modules/fulfillment_base/repositories/deal_service.py +++ b/modules/fulfillment_base/repositories/deal_service.py @@ -1,9 +1,11 @@ from typing import Optional -from sqlalchemy import Select, select +from sqlalchemy import Select, select, delete from sqlalchemy.orm import joinedload +from models import Deal from modules.fulfillment_base.models import DealService +from modules.fulfillment_base.models.service import ServicesKit from modules.fulfillment_base.schemas.deal_service import ( UpdateDealServiceSchema, CreateDealServiceSchema, @@ -51,3 +53,19 @@ class DealServiceRepository( async def delete(self, obj: DealService): await self.session.delete(obj) await self.session.commit() + + async def delete_deal_services(self, deal_id: int): + stmt = delete(DealService).where(DealService.deal_id == deal_id) + await self.session.execute(stmt) + await self.session.flush() + + async def add_services_kit(self, deal: Deal, services_kit: ServicesKit): + for service in services_kit.services: + deal_service = DealService( + deal_id=deal.id, + service_id=service.id, + price=service.price, + quantity=1, + ) + self.session.add(deal_service) + await self.session.commit() diff --git a/modules/fulfillment_base/repositories/product_service.py b/modules/fulfillment_base/repositories/product_service.py index 4a0cae0..ec650bc 100644 --- a/modules/fulfillment_base/repositories/product_service.py +++ b/modules/fulfillment_base/repositories/product_service.py @@ -16,7 +16,6 @@ class ProductServiceRepository( RepUpdateMixin[DealProductService, UpdateProductServiceSchema], ): entity_class = DealProductService - entity_not_found_msg = "Связь услуги с товаром не найдена" session: AsyncSession async def get_by_id( diff --git a/modules/fulfillment_base/routers/deal_product.py b/modules/fulfillment_base/routers/deal_product.py index b67816f..1ea70da 100644 --- a/modules/fulfillment_base/routers/deal_product.py +++ b/modules/fulfillment_base/routers/deal_product.py @@ -61,18 +61,6 @@ async def delete_deal_product( return await DealProductService(session).delete(deal_id, product_id) -@router.post( - "/add-services-kit", - response_model=DealProductAddKitResponse, - operation_id="add_kit_to_deal_product", -) -async def add_kit_to_deal_product( - session: SessionDependency, - request: DealProductAddKitRequest, -): - return await DealProductService(session).add_services_kit(request) - - # endregion @@ -134,4 +122,16 @@ async def copy_product_services( return await ProductServiceService(session).duplicate_product_services(request) +@router.post( + "/add-services-kit", + response_model=DealProductAddKitResponse, + operation_id="add_kit_to_deal_product", +) +async def add_kit_to_deal_product( + session: SessionDependency, + request: DealProductAddKitRequest, +): + return await ProductServiceService(session).add_services_kit(request) + + # endregion diff --git a/modules/fulfillment_base/routers/deal_service.py b/modules/fulfillment_base/routers/deal_service.py index 810733a..70432d1 100644 --- a/modules/fulfillment_base/routers/deal_service.py +++ b/modules/fulfillment_base/routers/deal_service.py @@ -56,3 +56,15 @@ async def delete_deal_service( service_id: int = Path(alias="serviceId"), ): return await DealServiceService(session).delete(deal_id, service_id) + + +@router.post( + "/add-services-kit", + response_model=DealAddKitResponse, + operation_id="add_kit_to_deal", +) +async def add_kit_to_deal( + session: SessionDependency, + request: DealAddKitRequest, +): + return await DealServiceService(session).add_services_kit(request) diff --git a/modules/fulfillment_base/schemas/deal_product.py b/modules/fulfillment_base/schemas/deal_product.py index 425bcbc..ebb7ed2 100644 --- a/modules/fulfillment_base/schemas/deal_product.py +++ b/modules/fulfillment_base/schemas/deal_product.py @@ -40,12 +40,6 @@ class UpdateDealProductRequest(BaseSchema): entity: UpdateDealProductSchema -class DealProductAddKitRequest(BaseSchema): - deal_id: int - product_id: int - kit_id: int - - # endregion # region Response @@ -67,8 +61,4 @@ class DeleteDealProductResponse(BaseResponse): pass -class DealProductAddKitResponse(BaseResponse): - pass - - # endregion diff --git a/modules/fulfillment_base/schemas/deal_service.py b/modules/fulfillment_base/schemas/deal_service.py index c953c43..d821df6 100644 --- a/modules/fulfillment_base/schemas/deal_service.py +++ b/modules/fulfillment_base/schemas/deal_service.py @@ -40,6 +40,11 @@ class UpdateDealServiceRequest(BaseSchema): entity: UpdateDealServiceSchema +class DealAddKitRequest(BaseSchema): + deal_id: int + kit_id: int + + # endregion # region Response @@ -61,4 +66,7 @@ class DeleteDealServiceResponse(BaseResponse): pass +class DealAddKitResponse(BaseResponse): + pass + # endregion diff --git a/modules/fulfillment_base/schemas/product_service.py b/modules/fulfillment_base/schemas/product_service.py index cd3d57a..3dca98c 100644 --- a/modules/fulfillment_base/schemas/product_service.py +++ b/modules/fulfillment_base/schemas/product_service.py @@ -45,6 +45,12 @@ class ProductServicesDuplicateRequest(BaseSchema): target_deal_product_ids: list[int] +class DealProductAddKitRequest(BaseSchema): + deal_id: int + product_id: int + kit_id: int + + # endregion # region Response @@ -66,4 +72,8 @@ class ProductServicesDuplicateResponse(BaseResponse): pass +class DealProductAddKitResponse(BaseResponse): + pass + + # endregion diff --git a/modules/fulfillment_base/services/deal_product.py b/modules/fulfillment_base/services/deal_product.py index 9c73bee..506a095 100644 --- a/modules/fulfillment_base/services/deal_product.py +++ b/modules/fulfillment_base/services/deal_product.py @@ -1,19 +1,13 @@ -from fastapi import HTTPException from sqlalchemy.ext.asyncio import AsyncSession from modules.fulfillment_base.models import DealProduct -from modules.fulfillment_base.repositories import ( - DealProductRepository, - ServicesKitRepository, - ProductServiceRepository, -) +from modules.fulfillment_base.repositories import DealProductRepository from modules.fulfillment_base.schemas.deal_product import * from services.mixins import ServiceGetAllMixin class DealProductService(ServiceGetAllMixin[DealProduct, DealProductSchema]): schema_class = DealProductSchema - entity_not_found_msg = "Связь товара со сделкой не найдена" def __init__(self, session: AsyncSession): self.repository = DealProductRepository(session) @@ -34,33 +28,10 @@ class DealProductService(ServiceGetAllMixin[DealProduct, DealProductSchema]): self, deal_id: int, product_id: int, data: UpdateDealProductRequest ) -> UpdateDealProductResponse: entity = await self.repository.get_by_id(deal_id, product_id) - if not entity: - raise HTTPException(status_code=404, detail=self.entity_not_found_msg) - await self.repository.update(entity, data.entity) return UpdateDealProductResponse(message="Товар сделки обновлен") async def delete(self, deal_id: int, product_id: int) -> DeleteDealProductResponse: entity = await self.repository.get_by_id(deal_id, product_id) - if not entity: - raise HTTPException(status_code=404, detail=self.entity_not_found_msg) - await self.repository.delete(entity) return DeleteDealProductResponse(message="Товар удален из сделки") - - async def add_services_kit( - self, request: DealProductAddKitRequest - ) -> DealProductAddKitResponse: - services_kit_repo = ServicesKitRepository(self.repository.session) - services_kit = await services_kit_repo.get_by_id(request.kit_id) - - deal_product = await self.repository.get_by_id(request.deal_id, request.product_id) - - product_service_repo = ProductServiceRepository(self.repository.session) - await product_service_repo.delete_product_services( - request.deal_id, [request.product_id] - ) - - await self.repository.add_services_kit(deal_product, services_kit) - - return DealProductAddKitResponse(message="Комплект добавлен в товар") diff --git a/modules/fulfillment_base/services/deal_service.py b/modules/fulfillment_base/services/deal_service.py index 5744bef..3759559 100644 --- a/modules/fulfillment_base/services/deal_service.py +++ b/modules/fulfillment_base/services/deal_service.py @@ -1,8 +1,12 @@ from sqlalchemy.ext.asyncio import AsyncSession from modules.fulfillment_base.models import DealService -from modules.fulfillment_base.repositories import DealServiceRepository +from modules.fulfillment_base.repositories import ( + DealServiceRepository, + ServicesKitRepository, +) from modules.fulfillment_base.schemas.deal_service import * +from repositories import DealRepository from services.mixins import ServiceGetAllMixin @@ -35,3 +39,15 @@ class DealServiceService(ServiceGetAllMixin[DealService, DealServiceSchema]): entity = await self.repository.get_by_id(deal_id, service_id) await self.repository.delete(entity) return DeleteDealServiceResponse(message="Услуга удалена из сделки") + + async def add_services_kit(self, request: DealAddKitRequest) -> DealAddKitResponse: + services_kit_repo = ServicesKitRepository(self.repository.session) + services_kit = await services_kit_repo.get_by_id(request.kit_id) + + deal_repo = DealRepository(self.repository.session) + deal = await deal_repo.get_by_id(request.deal_id) + + await self.repository.delete_deal_services(request.deal_id) + await self.repository.add_services_kit(deal, services_kit) + + return DealAddKitResponse(message="Комплект добавлен в сделку") diff --git a/modules/fulfillment_base/services/product_service.py b/modules/fulfillment_base/services/product_service.py index f50cb66..0100b78 100644 --- a/modules/fulfillment_base/services/product_service.py +++ b/modules/fulfillment_base/services/product_service.py @@ -1,8 +1,11 @@ -from fastapi import HTTPException from sqlalchemy.ext.asyncio import AsyncSession from modules.fulfillment_base.models import DealProductService -from modules.fulfillment_base.repositories import ProductServiceRepository +from modules.fulfillment_base.repositories import ( + ProductServiceRepository, + ServicesKitRepository, + DealProductRepository, +) from modules.fulfillment_base.schemas.product_service import * @@ -34,8 +37,6 @@ class ProductServiceService: data: UpdateProductServiceRequest, ) -> UpdateProductServiceResponse: entity = await self.repository.get_by_id(deal_id, product_id, service_id) - if not entity: - raise HTTPException(status_code=404, detail=self.entity_not_found_msg) await self.repository.update(entity, data.entity) return UpdateProductServiceResponse(message="Услуга обновлена") @@ -44,9 +45,6 @@ class ProductServiceService: self, deal_id: int, product_id: int, service_id: int ) -> DeleteProductServiceResponse: entity = await self.repository.get_by_id(deal_id, product_id, service_id) - if not entity: - raise HTTPException(status_code=404, detail=self.entity_not_found_msg) - await self.repository.delete(entity) return DeleteProductServiceResponse(message="Товар удален из сделки") @@ -63,3 +61,21 @@ class ProductServiceService: request.deal_id, request.target_deal_product_ids, services_to_copy ) return ProductServicesDuplicateResponse(message="Услуги продублированы") + + async def add_services_kit( + self, request: DealProductAddKitRequest + ) -> DealProductAddKitResponse: + services_kit_repo = ServicesKitRepository(self.repository.session) + services_kit = await services_kit_repo.get_by_id(request.kit_id) + + deal_product_repo = DealProductRepository(self.repository.session) + deal_product = await deal_product_repo.get_by_id( + request.deal_id, request.product_id + ) + + await self.repository.delete_product_services( + request.deal_id, [request.product_id] + ) + await self.repository.add_services_kit(deal_product, services_kit) + + return DealProductAddKitResponse(message="Комплект добавлен в товар")