feat: adding services kit to deal

This commit is contained in:
2025-09-16 18:13:19 +04:00
parent 98d3026e0d
commit 1a9dbd857a
10 changed files with 102 additions and 62 deletions

View File

@ -1,9 +1,11 @@
from typing import Optional from typing import Optional
from sqlalchemy import Select, select from sqlalchemy import Select, select, delete
from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload
from models import Deal
from modules.fulfillment_base.models import DealService from modules.fulfillment_base.models import DealService
from modules.fulfillment_base.models.service import ServicesKit
from modules.fulfillment_base.schemas.deal_service import ( from modules.fulfillment_base.schemas.deal_service import (
UpdateDealServiceSchema, UpdateDealServiceSchema,
CreateDealServiceSchema, CreateDealServiceSchema,
@ -51,3 +53,19 @@ class DealServiceRepository(
async def delete(self, obj: DealService): async def delete(self, obj: DealService):
await self.session.delete(obj) await self.session.delete(obj)
await self.session.commit() 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()

View File

@ -16,7 +16,6 @@ class ProductServiceRepository(
RepUpdateMixin[DealProductService, UpdateProductServiceSchema], RepUpdateMixin[DealProductService, UpdateProductServiceSchema],
): ):
entity_class = DealProductService entity_class = DealProductService
entity_not_found_msg = "Связь услуги с товаром не найдена"
session: AsyncSession session: AsyncSession
async def get_by_id( async def get_by_id(

View File

@ -61,18 +61,6 @@ async def delete_deal_product(
return await DealProductService(session).delete(deal_id, product_id) 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 # endregion
@ -134,4 +122,16 @@ async def copy_product_services(
return await ProductServiceService(session).duplicate_product_services(request) 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 # endregion

View File

@ -56,3 +56,15 @@ async def delete_deal_service(
service_id: int = Path(alias="serviceId"), service_id: int = Path(alias="serviceId"),
): ):
return await DealServiceService(session).delete(deal_id, service_id) 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)

View File

@ -40,12 +40,6 @@ class UpdateDealProductRequest(BaseSchema):
entity: UpdateDealProductSchema entity: UpdateDealProductSchema
class DealProductAddKitRequest(BaseSchema):
deal_id: int
product_id: int
kit_id: int
# endregion # endregion
# region Response # region Response
@ -67,8 +61,4 @@ class DeleteDealProductResponse(BaseResponse):
pass pass
class DealProductAddKitResponse(BaseResponse):
pass
# endregion # endregion

View File

@ -40,6 +40,11 @@ class UpdateDealServiceRequest(BaseSchema):
entity: UpdateDealServiceSchema entity: UpdateDealServiceSchema
class DealAddKitRequest(BaseSchema):
deal_id: int
kit_id: int
# endregion # endregion
# region Response # region Response
@ -61,4 +66,7 @@ class DeleteDealServiceResponse(BaseResponse):
pass pass
class DealAddKitResponse(BaseResponse):
pass
# endregion # endregion

View File

@ -45,6 +45,12 @@ class ProductServicesDuplicateRequest(BaseSchema):
target_deal_product_ids: list[int] target_deal_product_ids: list[int]
class DealProductAddKitRequest(BaseSchema):
deal_id: int
product_id: int
kit_id: int
# endregion # endregion
# region Response # region Response
@ -66,4 +72,8 @@ class ProductServicesDuplicateResponse(BaseResponse):
pass pass
class DealProductAddKitResponse(BaseResponse):
pass
# endregion # endregion

View File

@ -1,19 +1,13 @@
from fastapi import HTTPException
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from modules.fulfillment_base.models import DealProduct from modules.fulfillment_base.models import DealProduct
from modules.fulfillment_base.repositories import ( from modules.fulfillment_base.repositories import DealProductRepository
DealProductRepository,
ServicesKitRepository,
ProductServiceRepository,
)
from modules.fulfillment_base.schemas.deal_product import * from modules.fulfillment_base.schemas.deal_product import *
from services.mixins import ServiceGetAllMixin from services.mixins import ServiceGetAllMixin
class DealProductService(ServiceGetAllMixin[DealProduct, DealProductSchema]): class DealProductService(ServiceGetAllMixin[DealProduct, DealProductSchema]):
schema_class = DealProductSchema schema_class = DealProductSchema
entity_not_found_msg = "Связь товара со сделкой не найдена"
def __init__(self, session: AsyncSession): def __init__(self, session: AsyncSession):
self.repository = DealProductRepository(session) self.repository = DealProductRepository(session)
@ -34,33 +28,10 @@ class DealProductService(ServiceGetAllMixin[DealProduct, DealProductSchema]):
self, deal_id: int, product_id: int, data: UpdateDealProductRequest self, deal_id: int, product_id: int, data: UpdateDealProductRequest
) -> UpdateDealProductResponse: ) -> UpdateDealProductResponse:
entity = await self.repository.get_by_id(deal_id, product_id) 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) await self.repository.update(entity, data.entity)
return UpdateDealProductResponse(message="Товар сделки обновлен") return UpdateDealProductResponse(message="Товар сделки обновлен")
async def delete(self, deal_id: int, product_id: int) -> DeleteDealProductResponse: async def delete(self, deal_id: int, product_id: int) -> DeleteDealProductResponse:
entity = await self.repository.get_by_id(deal_id, product_id) 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) await self.repository.delete(entity)
return DeleteDealProductResponse(message="Товар удален из сделки") 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="Комплект добавлен в товар")

View File

@ -1,8 +1,12 @@
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from modules.fulfillment_base.models import DealService 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 modules.fulfillment_base.schemas.deal_service import *
from repositories import DealRepository
from services.mixins import ServiceGetAllMixin 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) entity = await self.repository.get_by_id(deal_id, service_id)
await self.repository.delete(entity) await self.repository.delete(entity)
return DeleteDealServiceResponse(message="Услуга удалена из сделки") 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="Комплект добавлен в сделку")

View File

@ -1,8 +1,11 @@
from fastapi import HTTPException
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from modules.fulfillment_base.models import DealProductService 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 * from modules.fulfillment_base.schemas.product_service import *
@ -34,8 +37,6 @@ class ProductServiceService:
data: UpdateProductServiceRequest, data: UpdateProductServiceRequest,
) -> UpdateProductServiceResponse: ) -> UpdateProductServiceResponse:
entity = await self.repository.get_by_id(deal_id, product_id, service_id) 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) await self.repository.update(entity, data.entity)
return UpdateProductServiceResponse(message="Услуга обновлена") return UpdateProductServiceResponse(message="Услуга обновлена")
@ -44,9 +45,6 @@ class ProductServiceService:
self, deal_id: int, product_id: int, service_id: int self, deal_id: int, product_id: int, service_id: int
) -> DeleteProductServiceResponse: ) -> DeleteProductServiceResponse:
entity = await self.repository.get_by_id(deal_id, product_id, service_id) 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) await self.repository.delete(entity)
return DeleteProductServiceResponse(message="Товар удален из сделки") return DeleteProductServiceResponse(message="Товар удален из сделки")
@ -63,3 +61,21 @@ class ProductServiceService:
request.deal_id, request.target_deal_product_ids, services_to_copy request.deal_id, request.target_deal_product_ids, services_to_copy
) )
return ProductServicesDuplicateResponse(message="Услуги продублированы") 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="Комплект добавлен в товар")