fix: multi-tariff Stage 3 critical fixes — panel sync UUID, admin grant, wheel

- remnawave_service: sync_users_to_panel uses sub.remnawave_uuid in
  multi-tariff instead of user.remnawave_uuid (was targeting wrong panel user)
- admin/users: admin_buy_subscription_execute saves UUID to
  subscription.remnawave_uuid in multi-tariff (was saving to user)
- wheel_service: _process_days_payment and _apply_prize require subscription
  in multi-tariff mode, fallback converts to balance bonus for prizes
This commit is contained in:
Fringg
2026-03-26 08:26:09 +03:00
parent c6bedc6a06
commit 49db5f5eed
3 changed files with 49 additions and 2 deletions
+4 -1
View File
@@ -4942,7 +4942,10 @@ async def admin_buy_subscription_execute(callback: types.CallbackQuery, db_user:
remnawave_user = await api.create_user(**create_kwargs)
if remnawave_user and hasattr(remnawave_user, 'uuid'):
target_user.remnawave_uuid = remnawave_user.uuid
if settings.is_multi_tariff_enabled() and subscription:
subscription.remnawave_uuid = remnawave_user.uuid
else:
target_user.remnawave_uuid = remnawave_user.uuid
await db.commit()
if remnawave_user:
+1 -1
View File
@@ -2161,7 +2161,7 @@ class RemnaWaveService:
create_kwargs['external_squad_uuid'] = sub.tariff.external_squad_uuid
# Определяем UUID для обновления
panel_uuid = user.remnawave_uuid
panel_uuid = sub.remnawave_uuid if settings.is_multi_tariff_enabled() else user.remnawave_uuid
# Если нет UUID в базе, ищем пользователя по telegram_id в панели
if not panel_uuid and user.telegram_id:
+44
View File
@@ -336,6 +336,8 @@ class FortuneWheelService:
Возвращает эквивалент в копейках.
"""
if not subscription:
if settings.is_multi_tariff_enabled():
raise ValueError('Необходимо указать подписку для оплаты днями (мульти-тариф)')
subscription = await get_subscription_by_user_id(db, user.id)
if not subscription or not subscription.is_active:
@@ -406,6 +408,21 @@ class FortuneWheelService:
if prize_type == WheelPrizeType.SUBSCRIPTION_DAYS.value:
# Дни подписки — use provided subscription or fallback
if not subscription:
if settings.is_multi_tariff_enabled():
# Multi-tariff: нельзя выбрать произвольную подписку, начисляем на баланс
await add_user_balance(
db,
user,
prize.prize_value_kopeks,
description=f'Выигрыш в колесе удачи: {prize.prize_value} дней (на баланс, мульти-тариф)',
create_transaction=True,
)
logger.info(
'Мульти-тариф: дни конвертированы в баланс (подписка не указана)',
prize_value=prize.prize_value,
user_id=user.id,
)
return None
subscription = await get_subscription_by_user_id(db, user.id)
if subscription:
# Проверяем суточный тариф - для него конвертируем дни в баланс
@@ -472,6 +489,21 @@ class FortuneWheelService:
if prize_type == WheelPrizeType.TRAFFIC_GB.value:
# Бонусный трафик — use provided subscription or fallback
if not subscription:
if settings.is_multi_tariff_enabled():
# Multi-tariff: нельзя выбрать произвольную подписку, начисляем на баланс
await add_user_balance(
db,
user,
prize.prize_value_kopeks,
description=f'Выигрыш в колесе удачи: {prize.prize_value}GB (на баланс, мульти-тариф)',
create_transaction=True,
)
logger.info(
'Мульти-тариф: трафик конвертирован в баланс (подписка не указана)',
prize_value=prize.prize_value,
user_id=user.id,
)
return None
subscription = await get_subscription_by_user_id(db, user.id)
if subscription and subscription.traffic_limit_gb > 0:
subscription.traffic_limit_gb += prize.prize_value
@@ -583,6 +615,18 @@ class FortuneWheelService:
# Single-tariff: auto-resolve
target_subscription = await get_subscription_by_user_id(db, user.id)
# Multi-tariff guard: subscription_id is required for days payment
if (
settings.is_multi_tariff_enabled()
and not target_subscription
and payment_type == WheelSpinPaymentType.SUBSCRIPTION_DAYS.value
):
return SpinResult(
success=False,
error='subscription_required',
message='Выберите подписку для оплаты днями',
)
# 2. Обрабатываем оплату
if payment_type == WheelSpinPaymentType.TELEGRAM_STARS.value:
if not availability.can_pay_stars: