From 8ebe016591256373a6baa454714eb0fef30e0c7d Mon Sep 17 00:00:00 2001 From: dev1lfreak Date: Wed, 17 Jun 2026 13:19:16 +0300 Subject: [PATCH] feat: add summary to completed orders --- .../repositories/i_order_repository.py | 6 ++++++ src/application/commands/orders_commands.py | 5 +++-- .../database/repositories/orders_repository.py | 15 ++++++++++++++- src/presentation/routing/orders.py | 8 +++++--- src/presentation/schemas/order.py | 7 ++++++- 5 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/application/abstractions/repositories/i_order_repository.py b/src/application/abstractions/repositories/i_order_repository.py index f0a41bc..c8742e7 100644 --- a/src/application/abstractions/repositories/i_order_repository.py +++ b/src/application/abstractions/repositories/i_order_repository.py @@ -1,4 +1,5 @@ from abc import ABC,abstractmethod +from decimal import Decimal from src.application.domain.entities.order import OrderEntity from src.application.domain.enums import OrderStatus @@ -25,6 +26,11 @@ class IOrderRepository(ABC): raise NotImplementedError + @abstractmethod + async def sum_by_date(self,*,year: int,month: int) -> Decimal: + raise NotImplementedError + + @abstractmethod async def count_all(self,*,search: str | None = None) -> int: raise NotImplementedError diff --git a/src/application/commands/orders_commands.py b/src/application/commands/orders_commands.py index 0c4e53e..ad3480f 100644 --- a/src/application/commands/orders_commands.py +++ b/src/application/commands/orders_commands.py @@ -52,7 +52,7 @@ class ListOrdersByDateCommand: @transactional - async def __call__(self, *, limit: int, offset: int, year: int, month: int | None = None) -> tuple[list[OrderEntity], int]: + async def __call__(self, *, limit: int, offset: int, year: int, month: int | None = None) -> tuple[list[OrderEntity], int, Decimal]: orders = await self._unit_of_work.order_repository.list_by_date( year=year, month=month, @@ -61,8 +61,9 @@ class ListOrdersByDateCommand: ) total = await self._unit_of_work.order_repository.count_by_date(year=year, month=month) + summary = await self._unit_of_work.order_repository.sum_by_date(year=year, month=month) - return orders, total + return orders, total, summary class GetOrderCommand: diff --git a/src/infrastructure/database/repositories/orders_repository.py b/src/infrastructure/database/repositories/orders_repository.py index 8f3030d..5bc98d6 100644 --- a/src/infrastructure/database/repositories/orders_repository.py +++ b/src/infrastructure/database/repositories/orders_repository.py @@ -126,6 +126,19 @@ class OrderRepository(IOrderRepository): return [self._to_entity(model) for model in res.scalars().all()] + async def sum_by_date(self, *, year: int, month: int) -> Decimal: + stmt = ( + select(func.coalesce(func.sum(OrderModel.service_fee), 0)) + .where( + extract("year", OrderModel.created_at) == year, + extract("month", OrderModel.created_at) == month, + OrderModel.status == OrderStatus.COMPLETED.value, + ) + ) + res = await self._session.execute(stmt) + return res.scalar_one() + + async def count_all(self,*,search: str | None = None) -> int: stmt = select(func.count()).select_from(OrderModel) search_filter = self._search_filter(search) @@ -135,7 +148,7 @@ class OrderRepository(IOrderRepository): return int(res.scalar_one()) - async def count_by_date(self,*,year: int,month: int ) -> int: + async def count_by_date(self,*,year: int,month: int) -> int: stmt = select(func.count()).select_from(OrderModel) stmt = stmt.where( extract("year", OrderModel.created_at) == year, diff --git a/src/presentation/routing/orders.py b/src/presentation/routing/orders.py index 4f64045..4fad851 100644 --- a/src/presentation/routing/orders.py +++ b/src/presentation/routing/orders.py @@ -11,6 +11,7 @@ from src.presentation.schemas.mappers import order_to_response from src.presentation.schemas.order import ( OrdersResponse, OrderResponse, + OrdersByDateResponse, OrderDetailResponse, ) from src.application.commands.orders_commands import ( @@ -69,7 +70,7 @@ async def get_order( ) -@orders_router.get('/filter/date', response_model=OrdersResponse) +@orders_router.get('/filter/date', response_model=OrdersByDateResponse) async def list_orders_by_date( year: int = Query(..., ge=2000, le=2100), month: int = Query(..., ge=1, le=12), @@ -78,8 +79,9 @@ async def list_orders_by_date( auth: AdminAuthContext = Depends(require_admin_access), command: ListOrdersByDateCommand = Depends(get_list_orders_by_date_command), ): - orders, total = await command(year=year, month=month, limit=limit, offset=offset) - return OrdersResponse( + orders, total, summary = await command(year=year, month=month, limit=limit, offset=offset) + return OrdersByDateResponse( items=[order_to_response(o) for o in orders], total=total, + summed_service_fees=summary, ) diff --git a/src/presentation/schemas/order.py b/src/presentation/schemas/order.py index 577493f..bc1b331 100644 --- a/src/presentation/schemas/order.py +++ b/src/presentation/schemas/order.py @@ -40,4 +40,9 @@ class OrderResponse(BaseModel): class OrdersResponse(BaseModel): items: list[OrderResponse] - total: int \ No newline at end of file + total: int + +class OrdersByDateResponse(BaseModel): + items: list[OrderResponse] + total: int + summed_service_fees: Decimal \ No newline at end of file