diff --git a/services/statistics/profit_statistics.py b/services/statistics/profit_statistics.py index ed3891f..69a5ef8 100644 --- a/services/statistics/profit_statistics.py +++ b/services/statistics/profit_statistics.py @@ -16,13 +16,20 @@ from services.statistics.expenses_statistics import ExpensesStatisticsService class ProfitStatisticsService(BaseService): @staticmethod def _get_sub_deals_created_at(date_from: datetime.date, date_to: datetime.date): - return ( + deals_created_at = ( select( Deal.id.label('deal_id'), - Deal.created_at.label('date'), + func.date_trunc( + 'day', + Deal.created_at, + ).label('date'), Deal.current_status, ) - .where(Deal.created_at.between(date_from, date_to)) + .subquery() + ) + return ( + select(deals_created_at) + .where(deals_created_at.c.date.between(date_from, date_to)) .subquery() ) @@ -39,7 +46,10 @@ class ProfitStatisticsService(BaseService): return ( select( Deal.id.label('deal_id'), - last_statuses.c.changed_at.label('date'), + func.date_trunc( + 'day', + last_statuses.c.changed_at, + ).label('date'), Deal.current_status, ) .join(last_statuses, last_statuses.c.deal_id == Deal.id) @@ -170,22 +180,22 @@ class ProfitStatisticsService(BaseService): func.count(stmt.c.deal_id).label("deals_count"), func.sum(stmt.c.revenue).label("revenue"), func.sum(stmt.c.profit).label("profit"), - literal(0).label("expenses"), ) .group_by(stmt.c.date) - .order_by(stmt.c.date.asc()) + .subquery() ) - missing_dates = ( - select(all_dates) - .where(all_dates.c.date.not_in( - select(deals.c.date) - )) - ) - deals_with_filled_gaps = union_all(deals, missing_dates).subquery() - return ( - select(deals_with_filled_gaps) - .order_by(deals_with_filled_gaps.c.date.asc()) + deals_with_filled_gaps = ( + select( + all_dates.c.date, + (all_dates.c.deals_count + func.coalesce(deals.c.deals_count, 0)).label("deals_count"), + (all_dates.c.revenue + func.coalesce(deals.c.revenue, 0)).label("revenue"), + (all_dates.c.profit + func.coalesce(deals.c.profit, 0)).label("profit"), + literal(0).label("expenses"), + ) + .join(deals, all_dates.c.date == deals.c.date, isouter=True) + .order_by(all_dates.c.date.asc()) ) + return deals_with_filled_gaps @staticmethod def _group_by_deals(stmt_union: Subquery):