diff --git a/app/handlers/subscription/common.py b/app/handlers/subscription/common.py index 89bfcccf..6759f758 100644 --- a/app/handlers/subscription/common.py +++ b/app/handlers/subscription/common.py @@ -390,9 +390,15 @@ def get_traffic_switch_keyboard( language: str = "ru", subscription_end_date: datetime = None, discount_percent: int = 0, + base_traffic_gb: int = None, ) -> InlineKeyboardMarkup: from app.config import settings + # Если базовый трафик не передан, используем текущий + # (для обратной совместимости и случаев без докупленного трафика) + if base_traffic_gb is None: + base_traffic_gb = current_traffic_gb + months_multiplier = 1 period_text = "" if subscription_end_date: @@ -403,7 +409,8 @@ def get_traffic_switch_keyboard( packages = settings.get_traffic_packages() enabled_packages = [pkg for pkg in packages if pkg['enabled']] - current_price_per_month = settings.get_traffic_price(current_traffic_gb) + # Используем базовый трафик для определения цены текущего пакета + current_price_per_month = settings.get_traffic_price(base_traffic_gb) discounted_current_per_month, _ = apply_percentage_discount( current_price_per_month, discount_percent, @@ -422,7 +429,8 @@ def get_traffic_switch_keyboard( price_diff_per_month = discounted_price_per_month - discounted_current_per_month total_price_diff = price_diff_per_month * months_multiplier - if gb == current_traffic_gb: + # Сравниваем с базовым трафиком (без докупленного) + if gb == base_traffic_gb: emoji = "✅" action_text = " (текущий)" price_text = "" diff --git a/app/handlers/subscription/traffic.py b/app/handlers/subscription/traffic.py index 54f40d17..c5ac68cf 100644 --- a/app/handlers/subscription/traffic.py +++ b/app/handlers/subscription/traffic.py @@ -609,6 +609,10 @@ async def handle_switch_traffic( return current_traffic = subscription.traffic_limit_gb + # Вычисляем базовый трафик (без докупленного) для корректного расчёта цен + purchased_traffic = getattr(subscription, 'purchased_traffic_gb', 0) or 0 + base_traffic = current_traffic - purchased_traffic + period_hint_days = _get_period_hint_from_subscription(subscription) traffic_discount_percent = _get_addon_discount_percent_for_user( db_user, @@ -616,18 +620,25 @@ async def handle_switch_traffic( period_hint_days, ) + # Показываем информацию о докупленном трафике, если он есть + purchased_info = "" + if purchased_traffic > 0: + purchased_info = f"\n📦 Базовый пакет: {texts.format_traffic(base_traffic)}\n➕ Докуплено: {texts.format_traffic(purchased_traffic)}" + await callback.message.edit_text( f"🔄 Переключение лимита трафика\n\n" - f"Текущий лимит: {texts.format_traffic(current_traffic)}\n" + f"Текущий лимит: {texts.format_traffic(current_traffic)}{purchased_info}\n" f"Выберите новый лимит трафика:\n\n" f"💡 Важно:\n" f"• При увеличении - доплата за разницу\n" - f"• При уменьшении - возврат средств не производится", + f"• При уменьшении - возврат средств не производится\n" + f"• Докупленный трафик будет сброшен", reply_markup=get_traffic_switch_keyboard( current_traffic, db_user.language, subscription.end_date, traffic_discount_percent, + base_traffic_gb=base_traffic, ), parse_mode="HTML" ) @@ -645,11 +656,16 @@ async def confirm_switch_traffic( current_traffic = subscription.traffic_limit_gb + # Вычисляем базовый трафик (без докупленного) для корректного расчёта цены + purchased_traffic = getattr(subscription, 'purchased_traffic_gb', 0) or 0 + base_traffic = current_traffic - purchased_traffic + if new_traffic_gb == current_traffic: await callback.answer("ℹ️ Лимит трафика не изменился", show_alert=True) return - old_price_per_month = settings.get_traffic_price(current_traffic) + # Используем базовый трафик для определения текущей цены пакета + old_price_per_month = settings.get_traffic_price(base_traffic) new_price_per_month = settings.get_traffic_price(new_traffic_gb) months_remaining = get_remaining_months(subscription.end_date) @@ -766,6 +782,8 @@ async def execute_switch_traffic( ) subscription.traffic_limit_gb = new_traffic_gb + # Сбрасываем докупленный трафик при переключении пакета + subscription.purchased_traffic_gb = 0 subscription.updated_at = datetime.utcnow() await db.commit() diff --git a/app/handlers/tickets.py b/app/handlers/tickets.py index f43cfa87..df164c16 100644 --- a/app/handlers/tickets.py +++ b/app/handlers/tickets.py @@ -854,8 +854,9 @@ async def handle_ticket_reply( await state.clear() # Уведомить админов об ответе пользователя + logger.info(f"Attempting to notify admins about ticket reply #{ticket_id}") await notify_admins_about_ticket_reply(ticket, reply_text, db) - + except Exception as e: logger.error(f"Error adding ticket reply: {e}") texts = get_texts(db_user.language) @@ -1020,6 +1021,7 @@ async def notify_admins_about_new_ticket(ticket: Ticket, db: AsyncSession): async def notify_admins_about_ticket_reply(ticket: Ticket, reply_text: str, db: AsyncSession): """Уведомить админов об ответе пользователя на тикет""" + logger.info(f"notify_admins_about_ticket_reply called for ticket #{ticket.id}") try: from app.config import settings if not settings.is_admin_notifications_enabled(): @@ -1059,7 +1061,8 @@ async def notify_admins_about_ticket_reply(ticket: Ticket, reply_text: str, db: return service = AdminNotificationService(bot) - await service.send_ticket_event_notification(notification_text, None) + result = await service.send_ticket_event_notification(notification_text, None) + logger.info(f"Ticket #{ticket.id} reply notification sent: {result}") except Exception as e: logger.error(f"Error notifying admins about ticket reply: {e}") diff --git a/app/services/admin_notification_service.py b/app/services/admin_notification_service.py index dc9ab2d3..95224e34 100644 --- a/app/services/admin_notification_service.py +++ b/app/services/admin_notification_service.py @@ -1510,6 +1510,7 @@ class AdminNotificationService: except Exception: runtime_enabled = True if not (self._is_enabled() and runtime_enabled): + logger.info(f"Ticket notification skipped: _is_enabled={self._is_enabled()}, runtime_enabled={runtime_enabled}") return False return await self._send_message(text, reply_markup=keyboard, ticket_event=True)