feat: add RESET_TRAFFIC_ON_TARIFF_SWITCH admin setting

New boolean setting (default: True) controls whether user traffic
is reset when switching between tariff plans.

Changes:
- config.py: add RESET_TRAFFIC_ON_TARIFF_SWITCH setting
- system_settings_service.py: category override (TRAFFIC) + hints
- pricing.py: admin bot handler toggle entry
- cabinet/routes/subscription.py: pass reset_traffic to RemnaWave on switch
- webapi/routes/miniapp.py: same for miniapp tariff switch
- tariff_purchase.py: use setting in 3 switch handlers (was hardcoded)
- subscription_auto_purchase_service.py: separate tariff switch vs payment logic
- crud/subscription.py: conditional traffic_used_gb reset on tariff change
This commit is contained in:
Fringg
2026-02-27 09:57:37 +03:00
parent f605d8a39c
commit 4eaedd33bf
8 changed files with 66 additions and 13 deletions
+14 -3
View File
@@ -4082,13 +4082,24 @@ async def switch_tariff(
user.subscription.updated_at = datetime.now(UTC)
await db.commit()
# Sync with RemnaWave
# Sync with RemnaWave (optionally reset traffic based on admin setting)
should_reset_traffic = settings.RESET_TRAFFIC_ON_TARIFF_SWITCH
try:
subscription_service = SubscriptionService()
if getattr(user, 'remnawave_uuid', None):
await subscription_service.update_remnawave_user(db, user.subscription)
await subscription_service.update_remnawave_user(
db,
user.subscription,
reset_traffic=should_reset_traffic,
reset_reason='смена тарифа',
)
else:
await subscription_service.create_remnawave_user(db, user.subscription)
await subscription_service.create_remnawave_user(
db,
user.subscription,
reset_traffic=should_reset_traffic,
reset_reason='смена тарифа',
)
except Exception as e:
logger.error('Failed to sync tariff switch with RemnaWave', error=e)
+1
View File
@@ -134,6 +134,7 @@ class Settings(BaseSettings):
DEFAULT_DEVICE_LIMIT: int = 1
DEFAULT_TRAFFIC_RESET_STRATEGY: str = 'MONTH'
RESET_TRAFFIC_ON_PAYMENT: bool = False
RESET_TRAFFIC_ON_TARIFF_SWITCH: bool = True
MAX_DEVICES_LIMIT: int = 20
TRIAL_WARNING_HOURS: int = 2
+6 -1
View File
@@ -444,7 +444,12 @@ async def extend_subscription(
if traffic_limit_gb is not None:
old_traffic = subscription.traffic_limit_gb
subscription.traffic_used_gb = 0.0
# Сброс использованного трафика: при смене тарифа — по настройке, при продлении — всегда
if is_tariff_change:
if settings.RESET_TRAFFIC_ON_TARIFF_SWITCH:
subscription.traffic_used_gb = 0.0
else:
subscription.traffic_used_gb = 0.0
if is_tariff_change:
# При СМЕНЕ тарифа сбрасываем все докупки трафика
+7
View File
@@ -180,6 +180,13 @@ CORE_PRICING_ENTRIES: tuple[SettingEntry, ...] = (
label_en='🔄 Reset traffic on payment',
action='toggle',
),
SettingEntry(
key='RESET_TRAFFIC_ON_TARIFF_SWITCH',
section='core',
label_ru='🔄 Сбрасывать трафик при смене тарифа',
label_en='🔄 Reset traffic on tariff switch',
action='toggle',
),
SettingEntry(
key='DEFAULT_TRAFFIC_RESET_STRATEGY',
section='core',
+5 -5
View File
@@ -2274,7 +2274,7 @@ async def confirm_tariff_switch(
await subscription_service.create_remnawave_user(
db,
subscription,
reset_traffic=True,
reset_traffic=settings.RESET_TRAFFIC_ON_TARIFF_SWITCH,
reset_reason='переключение тарифа',
)
except Exception as e:
@@ -2446,13 +2446,13 @@ async def confirm_daily_tariff_switch(
await db.commit()
await db.refresh(subscription)
# Обновляем пользователя в Remnawave (create_remnawave_user также сбрасывает устройства)
# Обновляем пользователя в Remnawave (сброс трафика по админ-настройке)
try:
subscription_service = SubscriptionService()
await subscription_service.create_remnawave_user(
db,
subscription,
reset_traffic=True,
reset_traffic=settings.RESET_TRAFFIC_ON_TARIFF_SWITCH,
reset_reason='смена на суточный тариф',
)
except Exception as e:
@@ -3023,13 +3023,13 @@ async def confirm_instant_switch(
await db.commit()
await db.refresh(subscription)
# Обновляем пользователя в Remnawave
# Обновляем пользователя в Remnawave (сброс трафика по админ-настройке)
try:
subscription_service = SubscriptionService()
await subscription_service.create_remnawave_user(
db,
subscription,
reset_traffic=False, # Не сбрасываем трафик при переключении
reset_traffic=settings.RESET_TRAFFIC_ON_TARIFF_SWITCH,
reset_reason='мгновенное переключение тарифа',
)
except Exception as e:
@@ -454,8 +454,11 @@ async def _auto_extend_subscription(
)
subscription_service = SubscriptionService()
# При смене тарифа ВСЕГДА сбрасываем трафик, иначе по настройке
should_reset_traffic = is_tariff_change or settings.RESET_TRAFFIC_ON_PAYMENT
# Сброс трафика: при смене тарифа — по RESET_TRAFFIC_ON_TARIFF_SWITCH, при оплате — по RESET_TRAFFIC_ON_PAYMENT
should_reset_traffic = (
(is_tariff_change and settings.RESET_TRAFFIC_ON_TARIFF_SWITCH)
or settings.RESET_TRAFFIC_ON_PAYMENT
)
try:
await subscription_service.update_remnawave_user(
db,
+20
View File
@@ -220,6 +220,7 @@ class BotConfigurationService:
'SALES_MODE': 'SUBSCRIPTIONS_CORE',
'DEFAULT_TRAFFIC_RESET_STRATEGY': 'TRAFFIC',
'RESET_TRAFFIC_ON_PAYMENT': 'TRAFFIC',
'RESET_TRAFFIC_ON_TARIFF_SWITCH': 'TRAFFIC',
'TRAFFIC_SELECTION_MODE': 'TRAFFIC',
'FIXED_TRAFFIC_LIMIT_GB': 'TRAFFIC',
'AVAILABLE_SUBSCRIPTION_PERIODS': 'PERIODS',
@@ -879,6 +880,25 @@ class BotConfigurationService:
'format': 'Булево значение.',
'example': 'true',
},
'RESET_TRAFFIC_ON_TARIFF_SWITCH': {
'description': (
'Автоматически сбрасывает счётчик использованного трафика '
'при переключении пользователя на другой тарифный план. '
'Сброс происходит через RemnaWave API.'
),
'format': 'Булево значение: выберите "Включить" или "Выключить".',
'example': 'Включено — трафик обнуляется при каждой смене тарифа.',
'warning': 'При отключении использованный трафик сохранится после смены тарифа.',
},
'RESET_TRAFFIC_ON_PAYMENT': {
'description': (
'Автоматически сбрасывает счётчик использованного трафика '
'при любой оплате или продлении подписки.'
),
'format': 'Булево значение: выберите "Включить" или "Выключить".',
'example': 'Выключено по умолчанию.',
'warning': 'При включении трафик будет обнуляться при каждом продлении подписки.',
},
}
@classmethod
+8 -2
View File
@@ -6991,10 +6991,16 @@ async def switch_tariff_endpoint(
await db.refresh(subscription)
await db.refresh(user)
# Синхронизируем с RemnaWave
# Синхронизируем с RemnaWave (опционально сбрасываем трафик по настройке)
should_reset_traffic = settings.RESET_TRAFFIC_ON_TARIFF_SWITCH
try:
service = SubscriptionService()
await service.update_remnawave_user(db, subscription)
await service.update_remnawave_user(
db,
subscription,
reset_traffic=should_reset_traffic,
reset_reason='смена тарифа',
)
except Exception as e:
logger.error('Ошибка синхронизации с RemnaWave при смене тарифа', error=e)