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)