feat: pallets and boxes for deals
This commit is contained in:
		@@ -10,6 +10,7 @@ import models.secondary
 | 
			
		||||
from models import User, Service, Client, DealProductService, deal_relations, GroupBillRequest
 | 
			
		||||
from models.deal import *
 | 
			
		||||
from models.deal_group import DealGroup
 | 
			
		||||
from models.shipping import ShippingProduct
 | 
			
		||||
from schemas.client import ClientDetailsSchema
 | 
			
		||||
from schemas.deal import *
 | 
			
		||||
from services.auth import AuthService
 | 
			
		||||
@@ -331,7 +332,13 @@ class DealService(BaseService):
 | 
			
		||||
                .joinedload(DealStatusHistory.user),
 | 
			
		||||
                selectinload(Deal.status_history)
 | 
			
		||||
                .noload(DealStatusHistory.deal),
 | 
			
		||||
 | 
			
		||||
                selectinload(Deal.pallets)
 | 
			
		||||
                .selectinload(Pallet.shipping_products)
 | 
			
		||||
                .selectinload(ShippingProduct.product)
 | 
			
		||||
                .noload(Product.barcodes),
 | 
			
		||||
                selectinload(Deal.boxes)
 | 
			
		||||
                .selectinload(Box.product)
 | 
			
		||||
                .noload(Product.barcodes),
 | 
			
		||||
            )
 | 
			
		||||
            .where(Deal.id == deal_id)
 | 
			
		||||
        )
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										121
									
								
								services/shipping.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								services/shipping.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,121 @@
 | 
			
		||||
from sqlalchemy import select, and_
 | 
			
		||||
 | 
			
		||||
from models import Deal, Pallet, Box
 | 
			
		||||
from models.shipping import ShippingProduct
 | 
			
		||||
from schemas.shipping import *
 | 
			
		||||
from services.base import BaseService
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ShippingService(BaseService):
 | 
			
		||||
    async def create_pallet(self, deal_id: int) -> CreatePalletResponse:
 | 
			
		||||
        deal = await self.session.get(Deal, deal_id)
 | 
			
		||||
        if not deal:
 | 
			
		||||
            return CreatePalletResponse(ok=False, message="Сделка не найдена")
 | 
			
		||||
 | 
			
		||||
        pallet = Pallet(deal_id=deal_id)
 | 
			
		||||
        self.session.add(pallet)
 | 
			
		||||
        await self.session.commit()
 | 
			
		||||
        return CreatePalletResponse(ok=True, message="Паллет успешно создан")
 | 
			
		||||
 | 
			
		||||
    async def delete_pallet(self, pallet_id: int) -> DeletePalletResponse:
 | 
			
		||||
        pallet = await self.session.get(Pallet, pallet_id)
 | 
			
		||||
        if not pallet:
 | 
			
		||||
            return DeletePalletResponse(ok=False, message="Паллет не найден")
 | 
			
		||||
 | 
			
		||||
        await self.session.delete(pallet)
 | 
			
		||||
        await self.session.commit()
 | 
			
		||||
        return DeletePalletResponse(ok=True, message="Паллет успешно удален")
 | 
			
		||||
 | 
			
		||||
    async def _update_box(self, data: UpdateBoxSchema) -> tuple[bool, str]:
 | 
			
		||||
        box = await self.session.get(Box, data.box_id)
 | 
			
		||||
        if not box:
 | 
			
		||||
            return False, f"Короб с ID:{data.box_id} не найден"
 | 
			
		||||
 | 
			
		||||
        box.quantity = data.quantity
 | 
			
		||||
        box.product_id = data.product_id
 | 
			
		||||
        await self.session.commit()
 | 
			
		||||
        return True, "Короб обновлен"
 | 
			
		||||
 | 
			
		||||
    async def _create_box(self, data: CreateBoxInDealSchema | CreateBoxInPalletSchema):
 | 
			
		||||
        box = Box(**data.model_dump())
 | 
			
		||||
        self.session.add(box)
 | 
			
		||||
        await self.session.commit()
 | 
			
		||||
 | 
			
		||||
    async def _create_box_in_deal(self, data: CreateBoxInDealSchema) -> tuple[bool, str]:
 | 
			
		||||
        deal = await self.session.get(Deal, data.deal_id)
 | 
			
		||||
        if not deal:
 | 
			
		||||
            return False, f"Сделка с ID:{data.deal_id} не найдена"
 | 
			
		||||
 | 
			
		||||
        await self._create_box(data)
 | 
			
		||||
 | 
			
		||||
        return True, f"Короб для сделки ID:{data.deal_id} добавлен"
 | 
			
		||||
 | 
			
		||||
    async def _create_box_in_pallet(self, data: CreateBoxInPalletSchema) -> tuple[bool, str]:
 | 
			
		||||
        pallet = await self.session.get(Pallet, data.pallet_id)
 | 
			
		||||
        if not pallet:
 | 
			
		||||
            return False, f"Паллет с ID:{data.pallet_id} не найден"
 | 
			
		||||
 | 
			
		||||
        await self._create_box(data)
 | 
			
		||||
 | 
			
		||||
        return True, f"Короб добавлен в паллет"
 | 
			
		||||
 | 
			
		||||
    async def update_box(self, request: UpdateBoxRequest) -> UpdateBoxResponse:
 | 
			
		||||
        data_keys = request.data.model_dump().keys()
 | 
			
		||||
        if "box_id" in data_keys:
 | 
			
		||||
            ok, message = await self._update_box(request.data)
 | 
			
		||||
        elif "pallet_id" in data_keys:
 | 
			
		||||
            ok, message = await self._create_box_in_pallet(CreateBoxInPalletSchema.model_validate(request.data))
 | 
			
		||||
        else:
 | 
			
		||||
            ok, message = await self._create_box_in_deal(CreateBoxInDealSchema.model_validate(request.data))
 | 
			
		||||
 | 
			
		||||
        return UpdateBoxResponse(ok=ok, message=message)
 | 
			
		||||
 | 
			
		||||
    async def delete_box(self, deal_id: int) -> DeleteBoxResponse:
 | 
			
		||||
        box = await self.session.get(Box, deal_id)
 | 
			
		||||
        if not box:
 | 
			
		||||
            return DeleteBoxResponse(ok=False, message=f"Короб с ID:{deal_id} не найден")
 | 
			
		||||
 | 
			
		||||
        await self.session.delete(box)
 | 
			
		||||
        await self.session.commit()
 | 
			
		||||
        return DeleteBoxResponse(ok=True, message="Короб успешно удален")
 | 
			
		||||
 | 
			
		||||
    async def _get_shipping_product(self, pallet_id: int, product_id: int) -> Optional[ShippingProduct]:
 | 
			
		||||
        stmt = (
 | 
			
		||||
            select(ShippingProduct)
 | 
			
		||||
            .where(
 | 
			
		||||
                and_(ShippingProduct.pallet_id == pallet_id, ShippingProduct.product_id == product_id)
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
        shipping_product = (await self.session.execute(stmt)).unique().one_or_none()
 | 
			
		||||
        return shipping_product[0] if shipping_product else None
 | 
			
		||||
 | 
			
		||||
    async def _update_shipping_product(self, data: UpdateShippingProductSchema) -> tuple[bool, str]:
 | 
			
		||||
        shipping_product = await self.session.get(ShippingProduct, data.shipping_product_id)
 | 
			
		||||
        shipping_product.product_id = data.product_id
 | 
			
		||||
        shipping_product.quantity = data.quantity
 | 
			
		||||
        await self.session.commit()
 | 
			
		||||
        return True, "Запись о товаре на паллете успешно изменена"
 | 
			
		||||
 | 
			
		||||
    async def _create_shipping_product(self, data: CreateShippingProductSchema) -> tuple[bool, str]:
 | 
			
		||||
        shipping_product = ShippingProduct(**data.model_dump())
 | 
			
		||||
        self.session.add(shipping_product)
 | 
			
		||||
        await self.session.commit()
 | 
			
		||||
        return True, "Запись о товаре на паллете успешно добавлена"
 | 
			
		||||
 | 
			
		||||
    async def update_shipping_product(self, request: UpdateShippingProductRequest) -> UpdateShippingProductResponse:
 | 
			
		||||
        data_keys = request.data.model_dump().keys()
 | 
			
		||||
        if "shipping_product_id" in data_keys:
 | 
			
		||||
            ok, message = await self._update_shipping_product(request.data)
 | 
			
		||||
        else:
 | 
			
		||||
            ok, message = await self._create_shipping_product(request.data)
 | 
			
		||||
 | 
			
		||||
        return UpdateShippingProductResponse(ok=ok, message=message)
 | 
			
		||||
 | 
			
		||||
    async def delete_shipping_product(self, shipping_product_id: int) -> DeleteShippingProductResponse:
 | 
			
		||||
        shipping_product = await self.session.get(ShippingProduct, shipping_product_id)
 | 
			
		||||
        if not shipping_product:
 | 
			
		||||
            return DeleteShippingProductResponse(ok=False, message=f"Запись для данного паллета и товара не найдена")
 | 
			
		||||
 | 
			
		||||
        await self.session.delete(shipping_product)
 | 
			
		||||
        await self.session.commit()
 | 
			
		||||
        return DeleteShippingProductResponse(ok=True, message="Запись о товаре на паллете успешно удалена")
 | 
			
		||||
		Reference in New Issue
	
	Block a user