from sqlalchemy import select, and_ from models import Card, Pallet, Box from models.shipping import ShippingProduct from schemas.shipping import * from services.base import BaseService class ShippingService(BaseService): async def create_pallet(self, card_id: int) -> CreatePalletResponse: deal = await self.session.get(Card, card_id) if not deal: return CreatePalletResponse(ok=False, message="Сделка не найдена") pallet = Pallet(card_id=card_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 _create_box(self, data: CreateBoxInCardSchema | CreateBoxInPalletSchema): box = Box(**data.model_dump()) self.session.add(box) await self.session.commit() async def _create_box_in_card(self, data: CreateBoxInCardSchema) -> tuple[bool, str]: card = await self.session.get(Card, data.card_id) if not card: return False, f"Сделка с ID:{data.card_id} не найдена" await self._create_box(data) return True, f"Короб для сделки ID:{data.card_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 create_box(self, request: CreateBoxRequest) -> CreateBoxResponse: data_keys = request.data.model_dump().keys() if "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_card(CreateBoxInCardSchema.model_validate(request.data)) return CreateBoxResponse(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="Запись о товаре на паллете успешно удалена")