diff --git a/app/cabinet/routes/admin_users.py b/app/cabinet/routes/admin_users.py index 8addcfc9..c7adb187 100644 --- a/app/cabinet/routes/admin_users.py +++ b/app/cabinet/routes/admin_users.py @@ -206,10 +206,17 @@ async def _build_subscription_info_async(db: AsyncSession, subscription: Subscri return info -async def _sync_subscription_to_panel(db: AsyncSession, user: User, subscription: Subscription) -> dict: +async def _sync_subscription_to_panel( + db: AsyncSession, + user: User, + subscription: Subscription, + reset_traffic: bool = False, + reset_traffic_reason: str | None = None, +) -> dict: """ Sync user subscription to Remnawave panel. Creates user if not exists, updates if exists. + Optionally resets traffic after sync. Returns dict with changes/errors. """ try: @@ -335,6 +342,16 @@ async def _sync_subscription_to_panel(db: AsyncSession, user: User, subscription changes['panel_uuid'] = new_panel_user.uuid logger.info('Created user in Remnawave panel', user_id=user.id, uuid=new_panel_user.uuid) + # Reset traffic on panel if requested + if reset_traffic and user.remnawave_uuid: + try: + await api.reset_user_traffic(user.remnawave_uuid) + changes['traffic_reset'] = True + reason_text = f' ({reset_traffic_reason})' if reset_traffic_reason else '' + logger.info('Reset RemnaWave traffic for user', user_id=user.id, reason=reason_text) + except Exception as reset_exc: + logger.warning('Failed to reset RemnaWave traffic', user_id=user.id, error=reset_exc) + user.last_remnawave_sync = datetime.now(UTC) await db.commit() @@ -1075,17 +1092,11 @@ async def update_user_subscription( # Синхронизируем с RemnaWave (discovery/create + сброс трафика по админ-настройке) try: - result = await _sync_subscription_to_panel(db, user, subscription) - if settings.RESET_TRAFFIC_ON_TARIFF_SWITCH and result.get('action') in ('updated', 'created'): - from app.services.subscription_service import SubscriptionService - - subscription_service = SubscriptionService() - await subscription_service.update_remnawave_user( - db, - subscription, - reset_traffic=True, - reset_reason='смена тарифа (cabinet admin)', - ) + await _sync_subscription_to_panel( + db, user, subscription, + reset_traffic=settings.RESET_TRAFFIC_ON_TARIFF_SWITCH, + reset_traffic_reason='смена тарифа (cabinet admin)', + ) except Exception as e: logger.error('Failed to sync tariff switch with RemnaWave', error=e) diff --git a/app/services/payment/common.py b/app/services/payment/common.py index 334a68dc..e66c9155 100644 --- a/app/services/payment/common.py +++ b/app/services/payment/common.py @@ -352,21 +352,30 @@ async def send_cart_notification_after_topup( amount=fmt(amount_kopeks), balance=fmt(balance), cart_total=fmt(cart_total), missing=fmt(missing), ) - keyboard = types.InlineKeyboardMarkup( - inline_keyboard=[ - [ - types.InlineKeyboardButton( - text=texts.RETURN_TO_SUBSCRIPTION_CHECKOUT, - callback_data='return_to_saved_cart', - ) - ], - [types.InlineKeyboardButton(text=texts.MY_BALANCE_BUTTON, callback_data='menu_balance')], - [types.InlineKeyboardButton(text=texts.MAIN_MENU_BUTTON, callback_data='back_to_menu')], - ] - ) + if not message_text: + logger.warning('Missing cart notification template', language=getattr(user, 'language', 'ru')) + return False sent = False try: + keyboard = types.InlineKeyboardMarkup( + inline_keyboard=[ + [ + types.InlineKeyboardButton( + text=texts.get('RETURN_TO_SUBSCRIPTION_CHECKOUT', '⬅️ Checkout'), + callback_data='return_to_saved_cart', + ) + ], + [types.InlineKeyboardButton( + text=texts.get('MY_BALANCE_BUTTON', '💰 Balance'), + callback_data='menu_balance', + )], + [types.InlineKeyboardButton( + text=texts.get('MAIN_MENU_BUTTON', '🏠 Menu'), + callback_data='back_to_menu', + )], + ] + ) await bot.send_message( chat_id=user.telegram_id, text=message_text, @@ -374,10 +383,10 @@ async def send_cart_notification_after_topup( parse_mode='HTML', ) sent = True - logger.info('Отправлено уведомление с кнопкой возврата к оформлению подписки пользователю', user_id=user.id) + logger.info('Sent cart notification to user', user_id=user.id) except Exception as send_error: logger.error( - 'Ошибка отправки уведомления о корзине пользователю', + 'Failed to send cart notification to user', user_id=user.id, error=send_error, )