diff --git a/app/handlers/subscription/purchase.py b/app/handlers/subscription/purchase.py index c2761afc..d45cb393 100644 --- a/app/handlers/subscription/purchase.py +++ b/app/handlers/subscription/purchase.py @@ -1430,6 +1430,13 @@ async def return_to_saved_cart( texts = get_texts(db_user.language) + # Проверяем режим корзины - если это тарифная корзина, перенаправляем на соответствующий обработчик + cart_mode = cart_data.get('cart_mode') + if cart_mode in ('tariff_purchase', 'daily_tariff_purchase', 'extend') and cart_data.get('tariff_id'): + from .tariff_purchase import return_to_saved_tariff_cart + await return_to_saved_tariff_cart(callback, state, db_user, db, cart_data) + return + preserved_metadata_keys = { 'saved_cart', 'missing_amount', diff --git a/app/handlers/subscription/tariff_purchase.py b/app/handlers/subscription/tariff_purchase.py index 62e9051f..d695a8c5 100644 --- a/app/handlers/subscription/tariff_purchase.py +++ b/app/handlers/subscription/tariff_purchase.py @@ -3140,6 +3140,148 @@ async def confirm_instant_switch( await callback.answer("Произошла ошибка при переключении тарифа", show_alert=True) +async def return_to_saved_tariff_cart( + callback: types.CallbackQuery, + state: FSMContext, + db_user: User, + db: AsyncSession, + cart_data: dict, +): + """Восстанавливает сохраненную корзину тарифа после пополнения баланса.""" + texts = get_texts(db_user.language) + cart_mode = cart_data.get('cart_mode') + tariff_id = cart_data.get('tariff_id') + + if not tariff_id: + await callback.answer("❌ Данные корзины повреждены", show_alert=True) + return + + tariff = await get_tariff_by_id(db, tariff_id) + if not tariff or not tariff.is_active: + await callback.answer("❌ Тариф больше недоступен", show_alert=True) + # Очищаем корзину + await user_cart_service.delete_user_cart(db_user.id) + return + + total_price = cart_data.get('total_price', 0) + user_balance = db_user.balance_kopeks or 0 + traffic = _format_traffic(tariff.traffic_limit_gb) + + # Проверяем баланс + if user_balance < total_price: + missing = total_price - user_balance + + if cart_mode == 'daily_tariff_purchase': + await callback.message.edit_text( + f"❌ Все еще недостаточно средств\n\n" + f"📦 Тариф: {tariff.name}\n" + f"🔄 Тип: Суточный\n" + f"💰 Стоимость: {_format_price_kopeks(total_price)}\n\n" + f"💳 Ваш баланс: {_format_price_kopeks(user_balance)}\n" + f"⚠️ Не хватает: {_format_price_kopeks(missing)}", + reply_markup=get_daily_tariff_insufficient_balance_keyboard(tariff_id, db_user.language), + parse_mode="HTML" + ) + elif cart_mode == 'extend': + period = cart_data.get('period_days', 30) + await callback.message.edit_text( + f"❌ Все еще недостаточно средств\n\n" + f"📦 Тариф: {tariff.name}\n" + f"📅 Период: {_format_period(period)}\n" + f"💰 Стоимость: {_format_price_kopeks(total_price)}\n\n" + f"💳 Ваш баланс: {_format_price_kopeks(user_balance)}\n" + f"⚠️ Не хватает: {_format_price_kopeks(missing)}", + reply_markup=get_tariff_insufficient_balance_keyboard(tariff_id, period, db_user.language), + parse_mode="HTML" + ) + else: # tariff_purchase + period = cart_data.get('period_days', 30) + await callback.message.edit_text( + f"❌ Все еще недостаточно средств\n\n" + f"📦 Тариф: {tariff.name}\n" + f"📅 Период: {_format_period(period)}\n" + f"💰 Стоимость: {_format_price_kopeks(total_price)}\n\n" + f"💳 Ваш баланс: {_format_price_kopeks(user_balance)}\n" + f"⚠️ Не хватает: {_format_price_kopeks(missing)}", + reply_markup=get_tariff_insufficient_balance_keyboard(tariff_id, period, db_user.language), + parse_mode="HTML" + ) + await callback.answer() + return + + # Баланс достаточен - показываем подтверждение + discount_percent = cart_data.get('discount_percent', 0) + + if cart_mode == 'daily_tariff_purchase': + daily_price = cart_data.get('daily_price_kopeks', total_price) + + await callback.message.edit_text( + f"✅ Подтверждение покупки\n\n" + f"📦 Тариф: {tariff.name}\n" + f"📊 Трафик: {traffic}\n" + f"📱 Устройств: {tariff.device_limit}\n" + f"🔄 Тип: Суточный\n" + f"💰 Стоимость в день: {_format_price_kopeks(daily_price)}\n\n" + f"💳 Ваш баланс: {_format_price_kopeks(user_balance)}\n" + f"После оплаты: {_format_price_kopeks(user_balance - daily_price)}", + reply_markup=get_daily_tariff_confirm_keyboard(tariff_id, db_user.language), + parse_mode="HTML" + ) + elif cart_mode == 'extend': + period = cart_data.get('period_days', 30) + + discount_text = "" + if discount_percent > 0: + original_price = int(total_price / (1 - discount_percent / 100)) + discount_text = f"\n🎁 Скидка: {discount_percent}% (-{_format_price_kopeks(original_price - total_price)})" + + await callback.message.edit_text( + f"✅ Подтверждение продления\n\n" + f"📦 Тариф: {tariff.name}\n" + f"📊 Трафик: {traffic}\n" + f"📱 Устройств: {tariff.device_limit}\n" + f"📅 Период: {_format_period(period)}\n" + f"{discount_text}\n" + f"💰 Итого: {_format_price_kopeks(total_price)}\n\n" + f"💳 Ваш баланс: {_format_price_kopeks(user_balance)}\n" + f"После оплаты: {_format_price_kopeks(user_balance - total_price)}", + reply_markup=InlineKeyboardMarkup(inline_keyboard=[ + [InlineKeyboardButton( + text="✅ Подтвердить продление", + callback_data=f"tariff_ext_confirm:{tariff_id}:{period}" + )], + [InlineKeyboardButton( + text=texts.BACK, + callback_data=f"tariff_extend:{tariff_id}" + )] + ]), + parse_mode="HTML" + ) + else: # tariff_purchase + period = cart_data.get('period_days', 30) + + discount_text = "" + if discount_percent > 0: + original_price = int(total_price / (1 - discount_percent / 100)) + discount_text = f"\n🎁 Скидка: {discount_percent}% (-{_format_price_kopeks(original_price - total_price)})" + + await callback.message.edit_text( + f"✅ Подтверждение покупки\n\n" + f"📦 Тариф: {tariff.name}\n" + f"📊 Трафик: {traffic}\n" + f"📱 Устройств: {tariff.device_limit}\n" + f"📅 Период: {_format_period(period)}\n" + f"{discount_text}\n" + f"💰 Итого: {_format_price_kopeks(total_price)}\n\n" + f"💳 Ваш баланс: {_format_price_kopeks(user_balance)}\n" + f"После оплаты: {_format_price_kopeks(user_balance - total_price)}", + reply_markup=get_tariff_confirm_keyboard(tariff_id, period, db_user.language), + parse_mode="HTML" + ) + + await callback.answer("✅ Корзина восстановлена!") + + def register_tariff_purchase_handlers(dp: Dispatcher): """Регистрирует обработчики покупки по тарифам.""" # Список тарифов (для режима tariffs)