From b87535ad4842cbf1f99f6fc1e28b5932fa5e3baa Mon Sep 17 00:00:00 2001 From: Fringg Date: Thu, 5 Mar 2026 09:05:55 +0300 Subject: [PATCH] =?UTF-8?q?fix:=20=D0=B8=D0=B7=D0=BE=D0=BB=D0=B8=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D1=82=D1=8C=20stored=5Famount=20=D0=BE=D1=82?= =?UTF-8?q?=20downstream=20consumers=20=D0=B2=20create=5Ftransaction?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - stored_amount используется только для БД записи, оригинальный amount_kopeks передаётся в event emitter и contest service через abs() - Добавлен func.abs() в leaderboard конкурсов (referral_contest.py) - Предотвращает негативные суммы в событиях и рейтинге конкурсов --- app/database/crud/referral_contest.py | 2 +- app/database/crud/transaction.py | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/database/crud/referral_contest.py b/app/database/crud/referral_contest.py index 7629f813..dcbcfaee 100644 --- a/app/database/crud/referral_contest.py +++ b/app/database/crud/referral_contest.py @@ -197,7 +197,7 @@ async def get_contest_leaderboard( select( User, func.count(ReferralContestEvent.id).label('referral_count'), - func.coalesce(func.sum(ReferralContestEvent.amount_kopeks), 0).label('total_amount'), + func.coalesce(func.sum(func.abs(ReferralContestEvent.amount_kopeks)), 0).label('total_amount'), ) .join(User, User.id == ReferralContestEvent.referrer_id) .where( diff --git a/app/database/crud/transaction.py b/app/database/crud/transaction.py index fb9e1d1d..bb82f297 100644 --- a/app/database/crud/transaction.py +++ b/app/database/crud/transaction.py @@ -40,13 +40,13 @@ async def create_transaction( created_at: datetime | None = None, ) -> Transaction: # SUBSCRIPTION_PAYMENT — always store as negative (debit from user balance) - if type == TransactionType.SUBSCRIPTION_PAYMENT and amount_kopeks > 0: - amount_kopeks = -amount_kopeks + # Keep original for downstream consumers (events, contests) + stored_amount = -amount_kopeks if type == TransactionType.SUBSCRIPTION_PAYMENT and amount_kopeks > 0 else amount_kopeks transaction = Transaction( user_id=user_id, type=type.value, - amount_kopeks=amount_kopeks, + amount_kopeks=stored_amount, description=description, payment_method=payment_method.value if payment_method else None, external_id=external_id, @@ -62,7 +62,7 @@ async def create_transaction( logger.info( '💳 Создана транзакция: на ₽ для пользователя', type_value=type.value, - amount_kopeks=amount_kopeks / 100, + amount_kopeks=stored_amount / 100, user_id=user_id, ) @@ -76,8 +76,8 @@ async def create_transaction( 'transaction_id': transaction.id, 'user_id': user_id, 'type': type.value, - 'amount_kopeks': amount_kopeks, - 'amount_rubles': amount_kopeks / 100, + 'amount_kopeks': abs(amount_kopeks), + 'amount_rubles': abs(amount_kopeks) / 100, 'payment_method': payment_method.value if payment_method else None, 'external_id': external_id, 'is_completed': is_completed, @@ -103,7 +103,7 @@ async def create_transaction( await referral_contest_service.on_subscription_payment( db, user_id, - amount_kopeks, + abs(amount_kopeks), ) except Exception as exc: logger.debug('Не удалось записать событие конкурса для пользователя', user_id=user_id, exc=exc)