From d3bfe774c711628d4a997cebcfcdcee397e382b8 Mon Sep 17 00:00:00 2001 From: Machka Pasla <161734431+machka-pasla@users.noreply.github.com> Date: Sun, 20 Jul 2025 21:04:52 +0300 Subject: [PATCH] Refine purchase and promo messages --- bot/handlers/user/payment.py | 19 +++++++-------- bot/handlers/user/promo_user.py | 38 +++++++++++++++++++++++------- bot/services/promo_code_service.py | 16 +++++++------ locales/en.json | 1 + locales/ru.json | 1 + 5 files changed, 49 insertions(+), 26 deletions(-) diff --git a/bot/handlers/user/payment.py b/bot/handlers/user/payment.py index cc6f5e4..ac01da8 100644 --- a/bot/handlers/user/payment.py +++ b/bot/handlers/user/payment.py @@ -170,20 +170,17 @@ async def process_successful_payment(session: AsyncSession, bot: Bot, ) success_message = _("payment_successful_error_details") - try: - await bot.send_message(user_id, success_message) - except Exception as e_notify: - logging.error( - f"Failed to send final payment success message to user {user_id}: {e_notify}" - ) - config_link = activation_details.get("subscription_url") or _( "config_link_not_available" ) - details_message = _( - "payment_successful_full", - end_date=final_end_date_for_user.strftime("%d.%m.%Y %H:%M:%S"), - config_link=config_link, + details_message = ( + success_message + + "\n\n" + + _( + "payment_successful_full", + end_date=final_end_date_for_user.strftime("%d.%m.%Y %H:%M:%S"), + config_link=config_link, + ) ) details_markup = get_connect_and_main_keyboard( user_lang, i18n, settings, config_link diff --git a/bot/handlers/user/promo_user.py b/bot/handlers/user/promo_user.py index 03dad66..ebda618 100644 --- a/bot/handlers/user/promo_user.py +++ b/bot/handlers/user/promo_user.py @@ -10,7 +10,11 @@ from config.settings import Settings from bot.states.user_states import UserPromoStates from bot.services.promo_code_service import PromoCodeService from bot.services.subscription_service import SubscriptionService -from bot.keyboards.inline.user_keyboards import get_back_to_main_menu_markup +from bot.keyboards.inline.user_keyboards import ( + get_back_to_main_menu_markup, + get_connect_and_main_keyboard, +) +from datetime import datetime from bot.middlewares.i18n import JsonI18n from .start import send_main_menu @@ -126,24 +130,42 @@ async def process_promo_code_input(message: types.Message, state: FSMContext, code=hcode(code_input.upper())) else: - success, response_text_from_service = await promo_code_service.apply_promo_code( + success, result = await promo_code_service.apply_promo_code( session, user.id, code_input, current_lang) - response_to_user_text = response_text_from_service if success: await session.commit() logging.info( f"Promo code '{code_input}' successfully applied for user {user.id}." ) + + new_end_date = result if isinstance(result, datetime) else None + active = await subscription_service.get_active_subscription_details(session, user.id) + config_link = active.get("config_link") if active else None + config_link = config_link or _("config_link_not_available") + + response_to_user_text = _( + "promo_code_applied_success_full", + end_date=(new_end_date.strftime("%d.%m.%Y %H:%M:%S") if new_end_date else "N/A"), + config_link=config_link, + ) + reply_markup = get_connect_and_main_keyboard( + current_lang, i18n, settings, config_link + ) else: await session.rollback() logging.info( - f"Promo code '{code_input}' application failed for user {user.id}. Reason: {response_text_from_service}" + f"Promo code '{code_input}' application failed for user {user.id}. Reason: {result}" + ) + response_to_user_text = result + reply_markup = get_back_to_main_menu_markup( + current_lang, i18n ) - await message.answer(response_to_user_text, - reply_markup=get_back_to_main_menu_markup( - current_lang, i18n), - parse_mode="HTML") + await message.answer( + response_to_user_text, + reply_markup=reply_markup, + parse_mode="HTML", + ) await state.clear() logging.info( f"Promo code input '{code_input}' processing finished for user {message.from_user.id}. State cleared." diff --git a/bot/services/promo_code_service.py b/bot/services/promo_code_service.py index 55ed22c..a9bee97 100644 --- a/bot/services/promo_code_service.py +++ b/bot/services/promo_code_service.py @@ -1,4 +1,5 @@ import logging +from datetime import datetime from sqlalchemy.ext.asyncio import AsyncSession from typing import Optional, Tuple, Dict from aiogram import Bot @@ -23,9 +24,13 @@ class PromoCodeService: self.bot = bot self.i18n = i18n - async def apply_promo_code(self, session: AsyncSession, user_id: int, - code_input: str, - user_lang: str) -> Tuple[bool, str]: + async def apply_promo_code( + self, + session: AsyncSession, + user_id: int, + code_input: str, + user_lang: str, + ) -> Tuple[bool, datetime | str]: _ = lambda k, **kw: self.i18n.gettext(user_lang, k, **kw) code_input_upper = code_input.strip().upper() @@ -65,10 +70,7 @@ class PromoCodeService: code_input_upper, bonus_days, ) - return True, _("promo_code_applied_success", - code=code_input_upper, - bonus_days=bonus_days, - new_end_date=new_end_date.strftime('%Y-%m-%d')) + return True, new_end_date else: logging.error( diff --git a/locales/en.json b/locales/en.json index 1edcb7b..5bb4be4 100644 --- a/locales/en.json +++ b/locales/en.json @@ -59,6 +59,7 @@ "promo_code_already_used_by_user": "You have already used promo code {code}.", "promo_code_no_active_subscription": "You must have an active subscription to apply this promo code.", "promo_code_applied_success": "✅ Promo code {code} applied successfully!\nYour subscription is extended by {bonus_days} days and is now active until {new_end_date}.", + "promo_code_applied_success_full": "✅ Promo code applied successfully!\n\nSubscription active until: {end_date}\n\nConnection key:\n{config_link}\n\nTo connect, open the link and follow the instructions 👇", "error_applying_promo_bonus": "Failed to apply promo bonus. Please try again later or contact support.", "promo_input_cancelled_short": "Promo code entry cancelled.", diff --git a/locales/ru.json b/locales/ru.json index a0a8877..97b3cae 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -59,6 +59,7 @@ "promo_code_already_used_by_user": "Вы уже активировали промокод {code}.", "promo_code_no_active_subscription": "Для активации этого промокода у вас должна быть активная подписка.", "promo_code_applied_success": "✅ Промокод {code} успешно применен!\nВаша подписка продлена на {bonus_days} дней и теперь активна до {new_end_date}.", + "promo_code_applied_success_full": "✅ Промокод успешно применен!\n\nПодписка активна до: {end_date}\n\nКлюч подключения:\n{config_link}\n\nЧтобы подключиться, перейдите по ссылке и следуйте инструкции 👇", "error_applying_promo_bonus": "Не удалось применить бонус по промокоду. Пожалуйста, попробуйте позже или свяжитесь с поддержкой.", "promo_input_cancelled_short": "Ввод промокода отменен.",