from typing import Any from aiogram import F, Router, types from aiogram.fsm.context import FSMContext from aiogram.fsm.state import State, StatesGroup from aiogram.types import CallbackQuery, Message from config import USERNAME_BOT from database import create_coupon, delete_coupon, get_all_coupons from filters.admin import IsAdminFilter from keyboards.admin.coupons_kb import AdminCouponDeleteCallback, build_coupons_kb, build_coupons_list_kb from keyboards.admin.panel_kb import AdminPanelCallback, build_admin_back_kb from logger import logger router = Router() class AdminCouponsState(StatesGroup): waiting_for_coupon_data = State() @router.callback_query( AdminPanelCallback.filter(F.action == "coupons"), IsAdminFilter(), ) async def handle_coupons( callback_query: CallbackQuery, ): await callback_query.message.edit_text(text="πŸ›  МСню управлСния ΠΊΡƒΠΏΠΎΠ½Π°ΠΌΠΈ:", reply_markup=build_coupons_kb()) @router.callback_query( AdminPanelCallback.filter(F.action == "coupons_create"), IsAdminFilter(), ) async def handle_coupons_create(callback_query: CallbackQuery, state: FSMContext): text = ( "🎫 Π’Π²Π΅Π΄ΠΈΡ‚Π΅ Π΄Π°Π½Π½Ρ‹Π΅ для создания ΠΊΡƒΠΏΠΎΠ½Π° Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅:\n\n" "πŸ“ ΠΊΠΎΠ΄ πŸ’° сумма πŸ”’ Π»ΠΈΠΌΠΈΡ‚\n\n" "ΠŸΡ€ΠΈΠΌΠ΅Ρ€: 'COUPON1 50 5' πŸ‘ˆ\n\n" ) await callback_query.message.edit_text( text=text, reply_markup=build_admin_back_kb("coupons"), ) await state.set_state(AdminCouponsState.waiting_for_coupon_data) @router.message(AdminCouponsState.waiting_for_coupon_data, IsAdminFilter()) async def handle_coupon_data_input(message: Message, state: FSMContext, session: Any): text = message.text.strip() parts = text.split() kb = build_admin_back_kb("coupons") if len(parts) != 3: text = ( "❌ НСкоррСктный Ρ„ΠΎΡ€ΠΌΠ°Ρ‚! πŸ“ ΠŸΠΎΠΆΠ°Π»ΡƒΠΉΡΡ‚Π°, Π²Π²Π΅Π΄ΠΈΡ‚Π΅ Π΄Π°Π½Π½Ρ‹Π΅ Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅:\n" "🏷️ ΠΊΠΎΠ΄ πŸ’° сумма πŸ”’ Π»ΠΈΠΌΠΈΡ‚\n" "ΠŸΡ€ΠΈΠΌΠ΅Ρ€: 'COUPON1 50 5' πŸ‘ˆ" ) await message.answer( text=text, reply_markup=kb, ) return try: coupon_code = parts[0] coupon_amount = float(parts[1]) usage_limit = int(parts[2]) except ValueError: text = "⚠️ ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΡΡ‚ΡŒ Π²Π²Π΅Π΄Π΅Π½Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…!\nπŸ’± Π‘ΡƒΠΌΠΌΠ° Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ числом, Π° Π»ΠΈΠΌΠΈΡ‚ β€” Ρ†Π΅Π»Ρ‹ΠΌ числом." await message.answer( text=text, reply_markup=kb, ) return try: await create_coupon(coupon_code, coupon_amount, usage_limit, session) text = ( f"βœ… ΠšΡƒΠΏΠΎΠ½ с ΠΊΠΎΠ΄ΠΎΠΌ {coupon_code} ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ создан!\n" f"πŸ’° Π‘ΡƒΠΌΠΌΠ°: {coupon_amount} Ρ€ΡƒΠ±Π»Π΅ΠΉ \n" f"πŸ”’ Π›ΠΈΠΌΠΈΡ‚ использования: {usage_limit} Ρ€Π°Π·\n" f"πŸ”— Бсылка: https://t.me/{USERNAME_BOT}?start=coupons_{coupon_code}\n" ) await message.answer(text=text, reply_markup=kb) await state.clear() except Exception as e: logger.error(f"Ошибка ΠΏΡ€ΠΈ создании ΠΊΡƒΠΏΠΎΠ½Π°: {e}") @router.callback_query( AdminPanelCallback.filter(F.action == "coupons_list"), IsAdminFilter(), ) async def handle_coupons_list(callback_query: CallbackQuery, session: Any): try: data = AdminPanelCallback.unpack(callback_query.data) page = data.page if data.page is not None else 1 per_page = 10 result = await get_all_coupons(session, page, per_page) coupons = result["coupons"] if not coupons: await callback_query.message.edit_text( text="❌ На Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π½Π΅Ρ‚ доступных ΠΊΡƒΠΏΠΎΠ½ΠΎΠ²!", reply_markup=build_admin_back_kb("coupons"), ) return kb = build_coupons_list_kb(coupons, result["current_page"], result["pages"]) coupon_list = "πŸ“œ Бписок всСх ΠΊΡƒΠΏΠΎΠ½ΠΎΠ²:\n\n" for coupon in coupons: coupon_list += ( f"🏷️ Код: {coupon['code']}\n" f"πŸ’° Π‘ΡƒΠΌΠΌΠ°: {coupon['amount']} Ρ€ΡƒΠ±Π»Π΅ΠΉ\n" f"πŸ”’ Π›ΠΈΠΌΠΈΡ‚ использования: {coupon['usage_limit']} Ρ€Π°Π·\n" f"βœ… Использовано: {coupon['usage_count']} Ρ€Π°Π·\n" f"πŸ”— Бсылка: https://t.me/{USERNAME_BOT}?start=coupons_{coupon['code']}\n" ) await callback_query.message.edit_text(text=coupon_list, reply_markup=kb) except Exception as e: logger.error(f"Ошибка ΠΏΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ списка ΠΊΡƒΠΏΠΎΠ½ΠΎΠ²: {e}") await callback_query.message.answer("ΠŸΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»Π° ошибка ΠΏΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ списка ΠΊΡƒΠΏΠΎΠ½ΠΎΠ².") @router.callback_query(AdminCouponDeleteCallback.filter(), IsAdminFilter()) async def handle_coupon_delete(callback_query: CallbackQuery, callback_data: AdminCouponDeleteCallback, session: Any): coupon_code = callback_data.coupon_code try: result = await delete_coupon(coupon_code, session) if result: await callback_query.message.edit_text(f"ΠšΡƒΠΏΠΎΠ½ {coupon_code} ΡƒΠ΄Π°Π»Ρ‘Π½!") else: await callback_query.message.edit_text(f"❌ ΠšΡƒΠΏΠΎΠ½ с ΠΊΠΎΠ΄ΠΎΠΌ {coupon_code} Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½.", show_alert=True) await update_coupons_list(callback_query.message, session) except Exception as e: logger.error(f"Ошибка ΠΏΡ€ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠΈ ΠΊΡƒΠΏΠΎΠ½Π°: {e}") await callback_query.message.edit_text("ΠŸΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»Π° ошибка ΠΏΡ€ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠΈ ΠΊΡƒΠΏΠΎΠ½Π°.", show_alert=True) async def update_coupons_list(message, session: Any, page: int = 1): per_page = 10 result = await get_all_coupons(session, page, per_page) coupons = result["coupons"] if not coupons: await message.edit_text( text="❌ На Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π½Π΅Ρ‚ доступных ΠΊΡƒΠΏΠΎΠ½ΠΎΠ²!", reply_markup=build_admin_back_kb("coupons"), ) return kb = build_coupons_list_kb(coupons, result["current_page"], result["pages"]) coupon_list = "πŸ“œ Бписок всСх ΠΊΡƒΠΏΠΎΠ½ΠΎΠ²:\n\n" for coupon in coupons: coupon_list += ( f"🏷️ Код: {coupon['code']}\n" f"πŸ’° Π‘ΡƒΠΌΠΌΠ°: {coupon['amount']} Ρ€ΡƒΠ±Π»Π΅ΠΉ\n" f"πŸ”’ Π›ΠΈΠΌΠΈΡ‚ использования: {coupon['usage_limit']} Ρ€Π°Π·\n" f"βœ… Использовано: {coupon['usage_count']} Ρ€Π°Π·\n" f"πŸ”— Бсылка: https://t.me/{USERNAME_BOT}?start=coupons_{coupon['code']}\n" ) await message.edit_text(text=coupon_list, reply_markup=kb)