From d7f91c83584384ef5d0fc90a28debc722b2db79f Mon Sep 17 00:00:00 2001 From: "sMedia.tech" <81699471+smediainfo@users.noreply.github.com> Date: Fri, 20 Mar 2026 10:10:56 +0300 Subject: [PATCH] fix: include SUBSCRIPTION_PAYMENT in dashboard revenue calculations Guest/landing purchases create SUBSCRIPTION_PAYMENT transactions (not DEPOSIT), so they were excluded from income_today, total_income, revenue_by_period, and payment_methods breakdown. Also use func.abs() for SUBSCRIPTION_PAYMENT amounts since they are stored as negative values. Co-Authored-By: Claude Opus 4.6 (1M context) --- app/database/crud/transaction.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/database/crud/transaction.py b/app/database/crud/transaction.py index 0338f9ce..9192dfed 100644 --- a/app/database/crud/transaction.py +++ b/app/database/crud/transaction.py @@ -278,11 +278,11 @@ async def get_transactions_statistics( if not end_date: end_date = datetime.now(UTC) - # Доход считаем только по реальным платежам (исключаем колесо, промокоды, админские пополнения) + # Доход считаем по реальным платежам + прямые покупки подписок (лендинги) income_result = await db.execute( - select(func.coalesce(func.sum(Transaction.amount_kopeks), 0)).where( + select(func.coalesce(func.sum(func.abs(Transaction.amount_kopeks)), 0)).where( and_( - Transaction.type == TransactionType.DEPOSIT.value, + Transaction.type.in_([TransactionType.DEPOSIT.value, TransactionType.SUBSCRIPTION_PAYMENT.value]), Transaction.is_completed == True, Transaction.created_at >= start_date, Transaction.created_at <= end_date, @@ -343,7 +343,7 @@ async def get_transactions_statistics( ) .where( and_( - Transaction.type == TransactionType.DEPOSIT.value, + Transaction.type.in_([TransactionType.DEPOSIT.value, TransactionType.SUBSCRIPTION_PAYMENT.value]), Transaction.is_completed == True, Transaction.created_at >= start_date, Transaction.created_at <= end_date, @@ -363,11 +363,11 @@ async def get_transactions_statistics( ) transactions_today = today_result.scalar() - # Доход за сегодня - только реальные платежи + # Доход за сегодня — реальные платежи + прямые покупки подписок (лендинги) today_income_result = await db.execute( - select(func.coalesce(func.sum(Transaction.amount_kopeks), 0)).where( + select(func.coalesce(func.sum(func.abs(Transaction.amount_kopeks)), 0)).where( and_( - Transaction.type == TransactionType.DEPOSIT.value, + Transaction.type.in_([TransactionType.DEPOSIT.value, TransactionType.SUBSCRIPTION_PAYMENT.value]), Transaction.is_completed == True, Transaction.created_at >= today, Transaction.payment_method.in_(REAL_PAYMENT_METHODS), @@ -391,17 +391,17 @@ async def get_transactions_statistics( async def get_revenue_by_period(db: AsyncSession, days: int = 30) -> list[dict]: - """Доход по дням - только реальные платежи.""" + """Доход по дням — реальные платежи + прямые покупки подписок (лендинги).""" start_date = datetime.now(UTC) - timedelta(days=days) result = await db.execute( select( func.date(Transaction.created_at).label('date'), - func.coalesce(func.sum(Transaction.amount_kopeks), 0).label('amount'), + func.coalesce(func.sum(func.abs(Transaction.amount_kopeks)), 0).label('amount'), ) .where( and_( - Transaction.type == TransactionType.DEPOSIT.value, + Transaction.type.in_([TransactionType.DEPOSIT.value, TransactionType.SUBSCRIPTION_PAYMENT.value]), Transaction.is_completed == True, Transaction.created_at >= start_date, Transaction.payment_method.in_(REAL_PAYMENT_METHODS),