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:
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
# При СМЕНЕ тарифа сбрасываем все докупки трафика
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user