from typing import Any from aiogram import F, Router from aiogram.types import CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup from aiogram.utils.keyboard import InlineKeyboardBuilder from sqlalchemy.ext.asyncio import AsyncSession from handlers.buttons import BACK from core.settings.tariffs_config import TARIFFS_CONFIG, update_tariffs_config from filters.admin import IsAdminFilter from ..panel.keyboard import AdminPanelCallback router = Router() router.callback_query.filter(IsAdminFilter()) PACK_MODES = ["", "traffic", "devices", "all"] def format_pack_mode_label(mode: str | None) -> str: """Возвращает человекочитаемое название режима пакетов.""" if not mode: return "выкл" if mode == "traffic": return "только трафик" if mode == "devices": return "только устройства" if mode == "all": return "трафик и устройства" return f"неизвестно ({mode})" def build_tariffs_settings_kb() -> InlineKeyboardMarkup: """Клавиатура основного экрана настроек тарификации.""" allow_downgrade = bool(TARIFFS_CONFIG.get("ALLOW_DOWNGRADE", True)) pack_mode = TARIFFS_CONFIG.get("KEY_ADDONS_PACK_MODE") or "" recalc_enabled = bool(TARIFFS_CONFIG.get("KEY_ADDONS_RECALC_PRICE", False)) builder = InlineKeyboardBuilder() builder.row( InlineKeyboardButton( text=f"Понижение: {'вкл' if allow_downgrade else 'выкл'}", callback_data=AdminPanelCallback(action="settings_tariffs_toggle_downgrade").pack(), ) ) builder.row( InlineKeyboardButton( text=f"Режим пакетов: {format_pack_mode_label(pack_mode)}", callback_data=AdminPanelCallback(action="settings_tariffs_packs").pack(), ) ) builder.row( InlineKeyboardButton( text=f"Перерасчёт при докупке: {'да' if recalc_enabled else 'нет'}", callback_data=AdminPanelCallback(action="settings_tariffs_toggle_addons_recalc").pack(), ) ) builder.row( InlineKeyboardButton( text=BACK, callback_data=AdminPanelCallback(action="settings").pack(), ) ) return builder.as_markup() def build_tariffs_settings_text() -> str: """Текст основного экрана настроек тарификации.""" allow_downgrade = bool(TARIFFS_CONFIG.get("ALLOW_DOWNGRADE", True)) pack_mode = TARIFFS_CONFIG.get("KEY_ADDONS_PACK_MODE") or "" recalc_enabled = bool(TARIFFS_CONFIG.get("KEY_ADDONS_RECALC_PRICE", False)) lines: list[str] = [ "⚙️ Настройки тарификации", "", f"• Понижение условий при изменении: {'включено' if allow_downgrade else 'выключено'}", f"• Режим доплат: {format_pack_mode_label(pack_mode)}", f"• Перерасчёт при докупке: {'да' if recalc_enabled else 'нет'}", "", "ℹ️ Как работают режимы доплат:", "", "🔹 Пакеты", "
Позволяет докупать трафик и устройства к активной подписке неограниченное количество раз.", "При продлении подписки все параметры возвращаются к исходно сконфигурированному тарифу.", "
\n\n🔹 Базовый конфигуратор (выкл. режим пакетов)", "
Позволяет выбрать параметры тарифа из доступных опций.", "Выбранные условия сохраняются и будут использоваться при последующих продлениях.", "При включённом понижении клиент сможет понижать условия тарифа.
", ] return "\n".join(lines) async def refresh_tariffs_settings_screen(callback: CallbackQuery) -> None: """Обновляет основной экран настроек тарификации.""" await callback.message.edit_text( build_tariffs_settings_text(), reply_markup=build_tariffs_settings_kb(), ) await callback.answer() def build_tariffs_packs_kb() -> InlineKeyboardMarkup: """Клавиатура экрана выбора режима пакетов.""" current = TARIFFS_CONFIG.get("KEY_ADDONS_PACK_MODE") or "" builder = InlineKeyboardBuilder() builder.row( InlineKeyboardButton( text=f"{'✅ ' if current == '' else ''}Выкл", callback_data=AdminPanelCallback(action="settings_tariffs_mode_off").pack(), ) ) builder.row( InlineKeyboardButton( text=f"{'✅ ' if current == 'traffic' else ''}Только трафик", callback_data=AdminPanelCallback(action="settings_tariffs_mode_traffic").pack(), ) ) builder.row( InlineKeyboardButton( text=f"{'✅ ' if current == 'devices' else ''}Только устройства", callback_data=AdminPanelCallback(action="settings_tariffs_mode_devices").pack(), ) ) builder.row( InlineKeyboardButton( text=f"{'✅ ' if current == 'all' else ''}Трафик и устройства", callback_data=AdminPanelCallback(action="settings_tariffs_mode_all").pack(), ) ) builder.row( InlineKeyboardButton( text=BACK, callback_data=AdminPanelCallback(action="settings_tariffs").pack(), ) ) return builder.as_markup() def build_tariffs_packs_text() -> str: """Текст экрана выбора режима пакетов.""" current = TARIFFS_CONFIG.get("KEY_ADDONS_PACK_MODE") or "" lines: list[str] = [ "📦 Режим доплат пакетами", "", "При активной подписке можно продавать не новый тариф, а доплаты к текущим лимитам.", "", "Режимы:", "
", "• Выкл — доплаты пакетами отключены, работает обычный конфигуратор лимитов (клиент меняет конфигурацию тарифа для продления).", "• Только трафик — пользователь докупает ГБ до продления, количество устройств не меняется.", "• Только устройства — пользователь докупает устройства до продления, лимит трафика не меняется.", "• Трафик и устройства — можно одновременно докупать и трафик, и устройства до продления как единый пакет.", f"
\nТекущий режим: {format_pack_mode_label(current)}", "", "Выберите режим, который покажет варианты для доплаты.\n ❗Доплаты не переносятся при продлении.", ] return "\n".join(lines) async def refresh_tariffs_packs_screen(callback: CallbackQuery) -> None: """Обновляет экран выбора режима пакетов.""" await callback.message.edit_text( build_tariffs_packs_text(), reply_markup=build_tariffs_packs_kb(), ) await callback.answer() @router.callback_query(AdminPanelCallback.filter(F.action == "settings_tariffs")) async def open_tariffs_settings(callback: CallbackQuery, session: AsyncSession) -> None: """Открывает основной экран настроек тарификации.""" await refresh_tariffs_settings_screen(callback) @router.callback_query(AdminPanelCallback.filter(F.action == "settings_tariffs_toggle_downgrade")) async def toggle_tariffs_downgrade(callback: CallbackQuery, session: AsyncSession) -> None: """Переключает флаг понижения условий.""" current = bool(TARIFFS_CONFIG.get("ALLOW_DOWNGRADE", True)) new_config: dict[str, Any] = dict(TARIFFS_CONFIG) new_config["ALLOW_DOWNGRADE"] = not current await update_tariffs_config(session, new_config) await refresh_tariffs_settings_screen(callback) @router.callback_query(AdminPanelCallback.filter(F.action == "settings_tariffs_toggle_addons_recalc")) async def toggle_tariffs_addons_recalc(callback: CallbackQuery, session: AsyncSession) -> None: """Переключает перерасчёт при докупке.""" current = bool(TARIFFS_CONFIG.get("KEY_ADDONS_RECALC_PRICE", False)) new_config: dict[str, Any] = dict(TARIFFS_CONFIG) new_config["KEY_ADDONS_RECALC_PRICE"] = not current await update_tariffs_config(session, new_config) await refresh_tariffs_settings_screen(callback) @router.callback_query(AdminPanelCallback.filter(F.action == "settings_tariffs_packs")) async def open_tariffs_packs(callback: CallbackQuery, session: AsyncSession) -> None: """Открывает экран выбора режима пакетов.""" await refresh_tariffs_packs_screen(callback) @router.callback_query( AdminPanelCallback.filter( F.action.in_([ "settings_tariffs_mode_off", "settings_tariffs_mode_traffic", "settings_tariffs_mode_devices", "settings_tariffs_mode_all", ]) ) ) async def set_tariffs_pack_mode( callback: CallbackQuery, callback_data: AdminPanelCallback, session: AsyncSession, ) -> None: """Сохраняет выбранный режим пакетов и обновляет экран.""" action = callback_data.action if action == "settings_tariffs_mode_off": new_mode = "" elif action == "settings_tariffs_mode_traffic": new_mode = "traffic" elif action == "settings_tariffs_mode_devices": new_mode = "devices" elif action == "settings_tariffs_mode_all": new_mode = "all" else: new_mode = TARIFFS_CONFIG.get("KEY_ADDONS_PACK_MODE") or "" new_config: dict[str, Any] = dict(TARIFFS_CONFIG) new_config["KEY_ADDONS_PACK_MODE"] = new_mode await update_tariffs_config(session, new_config) await refresh_tariffs_packs_screen(callback)