feat: products quantity and total price in deal schemas

This commit is contained in:
2025-10-11 16:22:38 +04:00
parent 636821e74a
commit d8eba188c9
3 changed files with 84 additions and 7 deletions

View File

@ -1,9 +1,16 @@
from sqlalchemy import func
from sqlalchemy.orm import joinedload
from models import Deal, Board, DealStatusHistory
from modules.fulfillment_base.models import (
DealService,
Service,
DealProductService,
DealProduct,
)
from repositories.mixins import *
from schemas.base import SortDir
from schemas.deal import UpdateDealSchema, CreateDealSchema
from schemas.deal import UpdateDealSchema, CreateDealSchema, DealSchema
from utils.sorting import apply_sorting
@ -17,6 +24,49 @@ class DealRepository(
entity_class = Deal
entity_not_found_msg = "Сделка не найдена"
def _get_price_subquery(self):
deal_services_subquery = (
select(
DealService.deal_id,
func.sum(DealService.quantity * DealService.price).label("total_price"),
)
.join(Service)
.group_by(DealService.deal_id)
)
product_services_subquery = select(
select(
DealProductService.deal_id,
func.sum(DealProduct.quantity * DealProductService.price).label(
"total_price"
),
)
.join(DealProduct)
.group_by(DealProductService.deal_id)
.subquery()
)
union_subqueries = deal_services_subquery.union_all(
product_services_subquery
).subquery()
final_subquery = (
select(
union_subqueries.c.deal_id,
func.sum(union_subqueries.c.total_price).label("total_price"),
)
.group_by(union_subqueries.c.deal_id)
.subquery()
)
return final_subquery
def _get_products_quantity_subquery(self):
return (
select(
DealProduct.deal_id,
func.sum(DealProduct.quantity).label("products_quantity"),
)
.group_by(DealProduct.deal_id)
.subquery()
)
async def get_all(
self,
page: Optional[int],
@ -28,9 +78,23 @@ class DealRepository(
status_id: Optional[int],
id: Optional[int],
name: Optional[str],
) -> tuple[list[Deal], int]:
) -> tuple[list[tuple[Deal, int, int]], int]:
price_subquery = self._get_price_subquery()
products_quantity_subquery = self._get_products_quantity_subquery()
stmt = (
select(Deal)
select(
Deal,
func.coalesce(price_subquery.c.total_price, 0),
func.coalesce(products_quantity_subquery.c.products_quantity, 0),
)
.outerjoin(
price_subquery,
Deal.id == price_subquery.c.deal_id,
)
.outerjoin(
products_quantity_subquery,
Deal.id == products_quantity_subquery.c.deal_id,
)
.options(joinedload(Deal.status), joinedload(Deal.board))
.where(Deal.is_deleted.is_(False))
)
@ -56,8 +120,8 @@ class DealRepository(
if page and items_per_page:
stmt = self._apply_pagination(stmt, page, items_per_page)
result = await self.session.execute(stmt)
return list(result.scalars().all()), total_items
rows: list[tuple[Deal, int, int]] = (await self.session.execute(stmt)).all()
return rows, total_items
def _process_get_by_id_stmt(self, stmt: Select) -> Select:
return stmt.options(joinedload(Deal.status), joinedload(Deal.board))