fix: eliminate referral system inconsistencies
- Fix balance history display: referral_reward, refund, poll_reward now
shown as credits (💰 +amount) instead of expenses
- Fix double-counting: remove all Transaction-based REFERRAL_REWARD sum
queries from crud/referral.py, admin_stats.py, admin_users.py —
ReferralEarning is now the single source of truth
- Unify "active referrals" definition across cabinet, bot, and admin:
JOIN Subscription WHERE status=ACTIVE AND end_date > now()
- Add payment_method IS NOT NULL guard to get_user_own_deposits() to
exclude referral rewards historically mistyped as deposits
- Replace hardcoded transaction type strings with TransactionType enum
values in referral_withdrawal_service.py
- Add Alembic data migration (0014) to fix historical transactions:
UPDATE deposit → referral_reward WHERE payment_method IS NULL and
description matches referral patterns
This commit is contained in:
@@ -686,53 +686,6 @@ async def get_top_referrers(
|
||||
if row.referrer_id in referrers_data:
|
||||
referrers_data[row.referrer_id]['earnings_month'] = row.total or 0
|
||||
|
||||
# Also add REFERRAL_REWARD transactions
|
||||
trans_total_query = await db.execute(
|
||||
select(Transaction.user_id.label('referrer_id'), func.sum(Transaction.amount_kopeks).label('total'))
|
||||
.where(Transaction.type == TransactionType.REFERRAL_REWARD.value)
|
||||
.group_by(Transaction.user_id)
|
||||
)
|
||||
for row in trans_total_query:
|
||||
if row.referrer_id in referrers_data:
|
||||
referrers_data[row.referrer_id]['earnings_total'] = referrers_data[row.referrer_id].get(
|
||||
'earnings_total', 0
|
||||
) + (row.total or 0)
|
||||
|
||||
trans_today_query = await db.execute(
|
||||
select(Transaction.user_id.label('referrer_id'), func.sum(Transaction.amount_kopeks).label('total'))
|
||||
.where(
|
||||
and_(Transaction.type == TransactionType.REFERRAL_REWARD.value, Transaction.created_at >= today_start)
|
||||
)
|
||||
.group_by(Transaction.user_id)
|
||||
)
|
||||
for row in trans_today_query:
|
||||
if row.referrer_id in referrers_data:
|
||||
referrers_data[row.referrer_id]['earnings_today'] = referrers_data[row.referrer_id].get(
|
||||
'earnings_today', 0
|
||||
) + (row.total or 0)
|
||||
|
||||
trans_week_query = await db.execute(
|
||||
select(Transaction.user_id.label('referrer_id'), func.sum(Transaction.amount_kopeks).label('total'))
|
||||
.where(and_(Transaction.type == TransactionType.REFERRAL_REWARD.value, Transaction.created_at >= week_ago))
|
||||
.group_by(Transaction.user_id)
|
||||
)
|
||||
for row in trans_week_query:
|
||||
if row.referrer_id in referrers_data:
|
||||
referrers_data[row.referrer_id]['earnings_week'] = referrers_data[row.referrer_id].get(
|
||||
'earnings_week', 0
|
||||
) + (row.total or 0)
|
||||
|
||||
trans_month_query = await db.execute(
|
||||
select(Transaction.user_id.label('referrer_id'), func.sum(Transaction.amount_kopeks).label('total'))
|
||||
.where(and_(Transaction.type == TransactionType.REFERRAL_REWARD.value, Transaction.created_at >= month_ago))
|
||||
.group_by(Transaction.user_id)
|
||||
)
|
||||
for row in trans_month_query:
|
||||
if row.referrer_id in referrers_data:
|
||||
referrers_data[row.referrer_id]['earnings_month'] = referrers_data[row.referrer_id].get(
|
||||
'earnings_month', 0
|
||||
) + (row.total or 0)
|
||||
|
||||
# Get user info for all referrers
|
||||
referrer_ids = list(referrers_data.keys())
|
||||
if referrer_ids:
|
||||
|
||||
@@ -26,6 +26,7 @@ from app.database.crud.user import (
|
||||
)
|
||||
from app.database.models import (
|
||||
PromoGroup,
|
||||
ReferralEarning,
|
||||
Subscription,
|
||||
SubscriptionServer,
|
||||
SubscriptionStatus,
|
||||
@@ -546,11 +547,9 @@ async def get_user_detail(
|
||||
referrals = await get_referrals(db, user.id)
|
||||
referrals_count = len(referrals)
|
||||
|
||||
# Calculate total referral earnings
|
||||
referral_earnings_q = select(func.sum(Transaction.amount_kopeks)).where(
|
||||
Transaction.user_id == user.id,
|
||||
Transaction.type == TransactionType.REFERRAL_REWARD.value,
|
||||
Transaction.is_completed == True,
|
||||
# Calculate total referral earnings (canonical source: ReferralEarning)
|
||||
referral_earnings_q = select(func.coalesce(func.sum(ReferralEarning.amount_kopeks), 0)).where(
|
||||
ReferralEarning.user_id == user.id
|
||||
)
|
||||
referral_earnings = (await db.execute(referral_earnings_q)).scalar() or 0
|
||||
|
||||
|
||||
@@ -9,7 +9,15 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import selectinload
|
||||
|
||||
from app.config import settings
|
||||
from app.database.models import AdvertisingCampaign, ReferralEarning, User, WithdrawalRequest, WithdrawalRequestStatus
|
||||
from app.database.models import (
|
||||
AdvertisingCampaign,
|
||||
ReferralEarning,
|
||||
Subscription,
|
||||
SubscriptionStatus,
|
||||
User,
|
||||
WithdrawalRequest,
|
||||
WithdrawalRequestStatus,
|
||||
)
|
||||
|
||||
from ..dependencies import get_cabinet_db, get_current_cabinet_user
|
||||
from ..schemas.referral import (
|
||||
@@ -38,12 +46,15 @@ async def get_referral_info(
|
||||
total_result = await db.execute(total_query)
|
||||
total_referrals = total_result.scalar() or 0
|
||||
|
||||
# Get active referrals (with subscription)
|
||||
# Get active referrals (with active subscription right now)
|
||||
active_query = (
|
||||
select(func.count())
|
||||
.select_from(User)
|
||||
.where(User.referred_by_id == user.id)
|
||||
.where(User.has_had_paid_subscription == True)
|
||||
select(func.count(func.distinct(User.id)))
|
||||
.join(Subscription, User.id == Subscription.user_id)
|
||||
.where(
|
||||
User.referred_by_id == user.id,
|
||||
Subscription.status == SubscriptionStatus.ACTIVE.value,
|
||||
Subscription.end_date > func.now(),
|
||||
)
|
||||
)
|
||||
active_result = await db.execute(active_query)
|
||||
active_referrals = active_result.scalar() or 0
|
||||
|
||||
@@ -5,7 +5,7 @@ from sqlalchemy import and_, func, select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import selectinload
|
||||
|
||||
from app.database.models import AdvertisingCampaignRegistration, ReferralEarning, User
|
||||
from app.database.models import AdvertisingCampaignRegistration, ReferralEarning, Subscription, SubscriptionStatus, User
|
||||
|
||||
|
||||
logger = structlog.get_logger(__name__)
|
||||
@@ -89,7 +89,7 @@ async def get_referral_earnings_sum(
|
||||
query = query.where(ReferralEarning.created_at <= end_date)
|
||||
|
||||
result = await db.execute(query)
|
||||
return result.scalar()
|
||||
return result.scalar() or 0
|
||||
|
||||
|
||||
async def get_referral_statistics(db: AsyncSession) -> dict:
|
||||
@@ -104,18 +104,7 @@ async def get_referral_statistics(db: AsyncSession) -> dict:
|
||||
active_referrers = active_referrers_result.scalar()
|
||||
|
||||
referral_paid_result = await db.execute(select(func.coalesce(func.sum(ReferralEarning.amount_kopeks), 0)))
|
||||
referral_paid = referral_paid_result.scalar()
|
||||
|
||||
from app.database.models import Transaction, TransactionType
|
||||
|
||||
transaction_paid_result = await db.execute(
|
||||
select(func.coalesce(func.sum(Transaction.amount_kopeks), 0)).where(
|
||||
Transaction.type == TransactionType.REFERRAL_REWARD.value
|
||||
)
|
||||
)
|
||||
transaction_paid = transaction_paid_result.scalar()
|
||||
|
||||
total_paid = referral_paid + transaction_paid
|
||||
total_paid = referral_paid_result.scalar()
|
||||
|
||||
referrals_stats_result = await db.execute(
|
||||
select(User.referred_by_id.label('referrer_id'), func.count(User.id).label('referrals_count'))
|
||||
@@ -132,15 +121,6 @@ async def get_referral_statistics(db: AsyncSession) -> dict:
|
||||
)
|
||||
referral_earnings = {row.referrer_id: row.referral_earnings for row in referral_earnings_result.all()}
|
||||
|
||||
transaction_earnings_result = await db.execute(
|
||||
select(
|
||||
Transaction.user_id.label('referrer_id'), func.sum(Transaction.amount_kopeks).label('transaction_earnings')
|
||||
)
|
||||
.where(Transaction.type == TransactionType.REFERRAL_REWARD.value)
|
||||
.group_by(Transaction.user_id)
|
||||
)
|
||||
transaction_earnings = {row.referrer_id: row.transaction_earnings for row in transaction_earnings_result.all()}
|
||||
|
||||
top_referrers_data = {}
|
||||
|
||||
for referrer_id, count in referrals_stats.items():
|
||||
@@ -153,11 +133,6 @@ async def get_referral_statistics(db: AsyncSession) -> dict:
|
||||
top_referrers_data[referrer_id] = {'referrals_count': 0, 'total_earned': 0}
|
||||
top_referrers_data[referrer_id]['total_earned'] += earnings or 0
|
||||
|
||||
for referrer_id, earnings in transaction_earnings.items():
|
||||
if referrer_id not in top_referrers_data:
|
||||
top_referrers_data[referrer_id] = {'referrals_count': 0, 'total_earned': 0}
|
||||
top_referrers_data[referrer_id]['total_earned'] += earnings or 0
|
||||
|
||||
sorted_referrers = sorted(
|
||||
top_referrers_data.items(), key=lambda x: (x[1]['total_earned'], x[1]['referrals_count']), reverse=True
|
||||
)
|
||||
@@ -197,37 +172,22 @@ async def get_referral_statistics(db: AsyncSession) -> dict:
|
||||
|
||||
today = datetime.now(UTC).replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
|
||||
today_referral_earnings_result = await db.execute(
|
||||
today_earnings_result = await db.execute(
|
||||
select(func.coalesce(func.sum(ReferralEarning.amount_kopeks), 0)).where(ReferralEarning.created_at >= today)
|
||||
)
|
||||
today_transaction_earnings_result = await db.execute(
|
||||
select(func.coalesce(func.sum(Transaction.amount_kopeks), 0)).where(
|
||||
and_(Transaction.type == TransactionType.REFERRAL_REWARD.value, Transaction.created_at >= today)
|
||||
)
|
||||
)
|
||||
today_earnings = today_referral_earnings_result.scalar() + today_transaction_earnings_result.scalar()
|
||||
today_earnings = today_earnings_result.scalar()
|
||||
|
||||
week_ago = datetime.now(UTC) - timedelta(days=7)
|
||||
week_referral_earnings_result = await db.execute(
|
||||
week_earnings_result = await db.execute(
|
||||
select(func.coalesce(func.sum(ReferralEarning.amount_kopeks), 0)).where(ReferralEarning.created_at >= week_ago)
|
||||
)
|
||||
week_transaction_earnings_result = await db.execute(
|
||||
select(func.coalesce(func.sum(Transaction.amount_kopeks), 0)).where(
|
||||
and_(Transaction.type == TransactionType.REFERRAL_REWARD.value, Transaction.created_at >= week_ago)
|
||||
)
|
||||
)
|
||||
week_earnings = week_referral_earnings_result.scalar() + week_transaction_earnings_result.scalar()
|
||||
week_earnings = week_earnings_result.scalar()
|
||||
|
||||
month_ago = datetime.now(UTC) - timedelta(days=30)
|
||||
month_referral_earnings_result = await db.execute(
|
||||
month_earnings_result = await db.execute(
|
||||
select(func.coalesce(func.sum(ReferralEarning.amount_kopeks), 0)).where(ReferralEarning.created_at >= month_ago)
|
||||
)
|
||||
month_transaction_earnings_result = await db.execute(
|
||||
select(func.coalesce(func.sum(Transaction.amount_kopeks), 0)).where(
|
||||
and_(Transaction.type == TransactionType.REFERRAL_REWARD.value, Transaction.created_at >= month_ago)
|
||||
)
|
||||
)
|
||||
month_earnings = month_referral_earnings_result.scalar() + month_transaction_earnings_result.scalar()
|
||||
month_earnings = month_earnings_result.scalar()
|
||||
|
||||
logger.info(
|
||||
'Реферальная статистика: рефералов, рефереров, выплачено копеек',
|
||||
@@ -264,8 +224,6 @@ async def get_top_referrers_by_period(
|
||||
Returns:
|
||||
Список словарей с данными рефереров
|
||||
"""
|
||||
from app.database.models import Transaction, TransactionType
|
||||
|
||||
now = datetime.now(UTC)
|
||||
if period == 'week':
|
||||
start_date = now - timedelta(days=7)
|
||||
@@ -292,18 +250,6 @@ async def get_top_referrers_by_period(
|
||||
)
|
||||
earnings = earnings_result.scalar() or 0
|
||||
|
||||
# Добавляем транзакции REFERRAL_REWARD
|
||||
trans_earnings_result = await db.execute(
|
||||
select(func.coalesce(func.sum(Transaction.amount_kopeks), 0)).where(
|
||||
and_(
|
||||
Transaction.user_id == row.referrer_id,
|
||||
Transaction.type == TransactionType.REFERRAL_REWARD.value,
|
||||
Transaction.created_at >= start_date,
|
||||
)
|
||||
)
|
||||
)
|
||||
earnings += trans_earnings_result.scalar() or 0
|
||||
|
||||
top_data.append(
|
||||
{'referrer_id': row.referrer_id, 'invited_count': row.invited_count, 'earnings_kopeks': earnings}
|
||||
)
|
||||
@@ -320,27 +266,8 @@ async def get_top_referrers_by_period(
|
||||
)
|
||||
referral_earnings = {row.referrer_id: row.ref_earnings for row in referral_earnings_result}
|
||||
|
||||
# Добавляем транзакции REFERRAL_REWARD
|
||||
transaction_earnings_result = await db.execute(
|
||||
select(
|
||||
Transaction.user_id.label('referrer_id'), func.sum(Transaction.amount_kopeks).label('trans_earnings')
|
||||
)
|
||||
.where(
|
||||
and_(Transaction.type == TransactionType.REFERRAL_REWARD.value, Transaction.created_at >= start_date)
|
||||
)
|
||||
.group_by(Transaction.user_id)
|
||||
)
|
||||
|
||||
# Объединяем заработки
|
||||
combined_earnings = dict(referral_earnings)
|
||||
for row in transaction_earnings_result:
|
||||
if row.referrer_id in combined_earnings:
|
||||
combined_earnings[row.referrer_id] += row.trans_earnings or 0
|
||||
else:
|
||||
combined_earnings[row.referrer_id] = row.trans_earnings or 0
|
||||
|
||||
# Сортируем и берём топ
|
||||
sorted_referrers = sorted(combined_earnings.items(), key=lambda x: x[1], reverse=True)[:limit]
|
||||
sorted_referrers = sorted(referral_earnings.items(), key=lambda x: x[1], reverse=True)[:limit]
|
||||
|
||||
top_data = []
|
||||
for referrer_id, earnings in sorted_referrers:
|
||||
@@ -400,22 +327,18 @@ async def get_user_referral_stats(db: AsyncSession, user_id: int) -> dict:
|
||||
month_ago = datetime.now(UTC) - timedelta(days=30)
|
||||
month_earned = await get_referral_earnings_sum(db, user_id, start_date=month_ago)
|
||||
|
||||
from app.database.models import Subscription, SubscriptionStatus
|
||||
|
||||
current_time = datetime.now(UTC)
|
||||
|
||||
active_referrals_result = await db.execute(
|
||||
select(func.count(User.id))
|
||||
select(func.count(func.distinct(User.id)))
|
||||
.join(Subscription, User.id == Subscription.user_id)
|
||||
.where(
|
||||
and_(
|
||||
User.referred_by_id == user_id,
|
||||
Subscription.status == SubscriptionStatus.ACTIVE.value,
|
||||
Subscription.end_date > current_time,
|
||||
Subscription.end_date > func.now(),
|
||||
)
|
||||
)
|
||||
)
|
||||
active_referrals = active_referrals_result.scalar()
|
||||
active_referrals = active_referrals_result.scalar() or 0
|
||||
|
||||
return {
|
||||
'invited_count': invited_count,
|
||||
|
||||
@@ -24,6 +24,15 @@ logger = structlog.get_logger(__name__)
|
||||
|
||||
TRANSACTIONS_PER_PAGE = 10
|
||||
|
||||
CREDIT_TRANSACTION_TYPES: frozenset[str] = frozenset(
|
||||
{
|
||||
TransactionType.DEPOSIT.value,
|
||||
TransactionType.REFERRAL_REWARD.value,
|
||||
TransactionType.REFUND.value,
|
||||
TransactionType.POLL_REWARD.value,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
async def route_payment_by_method(
|
||||
message: types.Message, db_user: User, amount_kopeks: int, state: FSMContext, payment_method: str
|
||||
@@ -277,10 +286,11 @@ async def show_balance_history(callback: types.CallbackQuery, db_user: User, db:
|
||||
text = '📊 <b>История операций</b>\n\n'
|
||||
|
||||
for transaction in unique_transactions:
|
||||
emoji = '💰' if transaction.type == TransactionType.DEPOSIT.value else '💸'
|
||||
is_credit = transaction.type in CREDIT_TRANSACTION_TYPES
|
||||
emoji = '💰' if is_credit else '💸'
|
||||
amount_text = (
|
||||
f'+{texts.format_price(transaction.amount_kopeks)}'
|
||||
if transaction.type == TransactionType.DEPOSIT.value
|
||||
if is_credit
|
||||
else f'-{texts.format_price(abs(transaction.amount_kopeks))}'
|
||||
)
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ from app.config import settings
|
||||
from app.database.models import (
|
||||
ReferralEarning,
|
||||
Transaction,
|
||||
TransactionType,
|
||||
User,
|
||||
WithdrawalRequest,
|
||||
WithdrawalRequestStatus,
|
||||
@@ -41,10 +42,14 @@ class ReferralWithdrawalService:
|
||||
async def get_user_own_deposits(self, db: AsyncSession, user_id: int) -> int:
|
||||
"""
|
||||
Получает сумму собственных пополнений пользователя (НЕ реферальные).
|
||||
Фильтрует по payment_method IS NOT NULL — реальные платежи всегда имеют payment_method.
|
||||
"""
|
||||
result = await db.execute(
|
||||
select(func.coalesce(func.sum(Transaction.amount_kopeks), 0)).where(
|
||||
Transaction.user_id == user_id, Transaction.type == 'deposit', Transaction.is_completed == True
|
||||
Transaction.user_id == user_id,
|
||||
Transaction.type == TransactionType.DEPOSIT.value,
|
||||
Transaction.is_completed == True,
|
||||
Transaction.payment_method.isnot(None),
|
||||
)
|
||||
)
|
||||
return result.scalar() or 0
|
||||
@@ -65,7 +70,7 @@ class ReferralWithdrawalService:
|
||||
result = await db.execute(
|
||||
select(func.coalesce(func.sum(Transaction.amount_kopeks), 0)).where(
|
||||
Transaction.user_id == user_id,
|
||||
Transaction.type.in_(['subscription_payment', 'withdrawal']),
|
||||
Transaction.type.in_([TransactionType.SUBSCRIPTION_PAYMENT.value, TransactionType.WITHDRAWAL.value]),
|
||||
Transaction.is_completed == True,
|
||||
)
|
||||
)
|
||||
@@ -83,7 +88,7 @@ class ReferralWithdrawalService:
|
||||
result = await db.execute(
|
||||
select(func.coalesce(func.sum(Transaction.amount_kopeks), 0)).where(
|
||||
Transaction.user_id == user_id,
|
||||
Transaction.type.in_(['subscription_payment', 'withdrawal']),
|
||||
Transaction.type.in_([TransactionType.SUBSCRIPTION_PAYMENT.value, TransactionType.WITHDRAWAL.value]),
|
||||
Transaction.is_completed == True,
|
||||
Transaction.created_at >= first_earning_date,
|
||||
)
|
||||
@@ -282,7 +287,7 @@ class ReferralWithdrawalService:
|
||||
)
|
||||
.where(
|
||||
Transaction.user_id.in_(referral_ids),
|
||||
Transaction.type == 'deposit',
|
||||
Transaction.type == TransactionType.DEPOSIT.value,
|
||||
Transaction.is_completed == True,
|
||||
Transaction.created_at >= month_ago,
|
||||
)
|
||||
@@ -331,7 +336,7 @@ class ReferralWithdrawalService:
|
||||
func.coalesce(func.sum(Transaction.amount_kopeks), 0).label('total_amount'),
|
||||
).where(
|
||||
Transaction.user_id.in_(referral_ids),
|
||||
Transaction.type == 'deposit',
|
||||
Transaction.type == TransactionType.DEPOSIT.value,
|
||||
Transaction.is_completed == True,
|
||||
)
|
||||
)
|
||||
@@ -499,7 +504,7 @@ class ReferralWithdrawalService:
|
||||
# Создаём транзакцию списания
|
||||
withdrawal_tx = Transaction(
|
||||
user_id=request.user_id,
|
||||
type='withdrawal',
|
||||
type=TransactionType.WITHDRAWAL.value,
|
||||
amount_kopeks=-request.amount_kopeks,
|
||||
description=f'Вывод реферального баланса (заявка #{request.id})',
|
||||
is_completed=True,
|
||||
|
||||
+11
-5
@@ -8,7 +8,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import selectinload
|
||||
|
||||
from app.config import settings
|
||||
from app.database.models import ReferralEarning, Transaction, TransactionType, User
|
||||
from app.database.models import ReferralEarning, Subscription, SubscriptionStatus, Transaction, TransactionType, User
|
||||
|
||||
|
||||
logger = structlog.get_logger(__name__)
|
||||
@@ -166,10 +166,16 @@ async def get_user_referral_summary(db: AsyncSession, user_id: int) -> dict:
|
||||
for row in earnings_by_type_result:
|
||||
earnings_by_type[row.reason] = {'count': row.count, 'total_amount_kopeks': row.total_amount}
|
||||
|
||||
active_referrals_count = 0
|
||||
for referral in referrals:
|
||||
if referral.last_activity and referral.last_activity >= month_ago:
|
||||
active_referrals_count += 1
|
||||
active_result = await db.execute(
|
||||
select(func.count(func.distinct(User.id)))
|
||||
.join(Subscription, User.id == Subscription.user_id)
|
||||
.where(
|
||||
User.referred_by_id == user_id,
|
||||
Subscription.status == SubscriptionStatus.ACTIVE.value,
|
||||
Subscription.end_date > func.now(),
|
||||
)
|
||||
)
|
||||
active_referrals_count = active_result.scalar() or 0
|
||||
|
||||
return {
|
||||
'invited_count': invited_count,
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
"""fix historical referral transactions recorded as deposit
|
||||
|
||||
Revision ID: 0014
|
||||
Revises: 0013
|
||||
Create Date: 2026-03-02
|
||||
|
||||
Data-only migration: updates transactions.type from 'deposit' to 'referral_reward'
|
||||
for historical referral commission records that were incorrectly saved as deposits.
|
||||
Discriminator: payment_method IS NULL (real deposits always have payment_method)
|
||||
plus description pattern matching as belt-and-suspenders safety.
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
|
||||
revision: str = '0014'
|
||||
down_revision: Union[str, None] = '0013'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.execute("""
|
||||
UPDATE transactions
|
||||
SET type = 'referral_reward'
|
||||
WHERE type = 'deposit'
|
||||
AND payment_method IS NULL
|
||||
AND (
|
||||
description ILIKE '%реферал%'
|
||||
OR description ILIKE '%referral%'
|
||||
OR description ILIKE '%комиссия%'
|
||||
OR description ILIKE '%бонус за первое пополнение%'
|
||||
OR description ILIKE '%бонус за реферала%'
|
||||
)
|
||||
""")
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.execute("""
|
||||
UPDATE transactions
|
||||
SET type = 'deposit'
|
||||
WHERE type = 'referral_reward'
|
||||
AND payment_method IS NULL
|
||||
AND (
|
||||
description ILIKE '%реферал%'
|
||||
OR description ILIKE '%referral%'
|
||||
OR description ILIKE '%комиссия%'
|
||||
OR description ILIKE '%бонус за первое пополнение%'
|
||||
OR description ILIKE '%бонус за реферала%'
|
||||
)
|
||||
""")
|
||||
Reference in New Issue
Block a user