fix: изолировать stored_amount от downstream consumers в create_transaction
- stored_amount используется только для БД записи, оригинальный amount_kopeks передаётся в event emitter и contest service через abs() - Добавлен func.abs() в leaderboard конкурсов (referral_contest.py) - Предотвращает негативные суммы в событиях и рейтинге конкурсов
This commit is contained in:
@@ -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(
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user