# - *- coding: utf- 8 - *- import asyncio from aiogram import Router, Bot, F from aiogram.filters import StateFilter from aiogram.types import CallbackQuery, Message from tgbot.database import Purchasesx, Refillx, ReferralWithdrawalx, Userx from tgbot.keyboards.inline_admin import profile_edit_return_finl, mail_confirm_finl from tgbot.services.api_hosting_text import HostingAPI from tgbot.utils.const_functions import ( is_number, to_number, del_message, ded, clear_html, convert_date, ) from tgbot.utils.misc.bot_logging import bot_logger from tgbot.utils.misc.bot_models import FSM, ARS from tgbot.utils.misc_functions import functions_mail_make from tgbot.utils.text_functions import ( open_profile_admin, refill_open_admin, purchase_open_admin, ) router = Router(name=__name__) def withdrawal_method_title(withdrawal_method: str) -> str: if withdrawal_method == "Cryptobot": return "CryptoBot" return withdrawal_method @router.callback_query(F.data.startswith("referral_withdrawal_complete:")) async def referral_withdrawal_complete( call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS ): withdrawal_id_raw = call.data.split(":", 1)[1] if not withdrawal_id_raw.isdigit(): return await call.answer("❌ Заявка не найдена", True) status, withdrawal = await ReferralWithdrawalx().complete( withdrawal_id=int(withdrawal_id_raw), admin_id=call.from_user.id, ) if status == "ALREADY_PROCESSED": return await call.answer("❌ Заявка уже обработана", True) if status != "ok" or withdrawal is None: return await call.answer("❌ Не удалось обработать заявку", True) method_title = withdrawal_method_title(withdrawal.withdrawal_method) get_user = await Userx().get_required(user_id=withdrawal.user_id) await call.message.edit_text( ded(f""" ✅ Заявка на вывод выполнена ▪️ Номер заявки: #{withdrawal.increment} ▪️ Пользователь: @{get_user.user_login} | {get_user.user_name} | {get_user.user_id} ▪️ Сумма: {withdrawal.withdrawal_amount}₽ ▪️ Способ: {method_title} ▪️ Реквизиты: {withdrawal.withdrawal_recipient} """), reply_markup=None, ) try: await bot.send_message( withdrawal.user_id, ded(f""" ✅ Заявка на вывод выполнена ▪️ Номер заявки: #{withdrawal.increment} ▪️ Сумма: {withdrawal.withdrawal_amount}₽ ▪️ Способ: {method_title} """), ) except Exception: bot_logger.warning( "Не удалось отправить пользователю уведомление о выполненном выводе", exc_info=True, ) await call.answer("✅ Заявка выполнена", True) @router.callback_query(F.data.startswith("referral_withdrawal_reject:")) async def referral_withdrawal_reject( call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS ): withdrawal_id_raw = call.data.split(":", 1)[1] if not withdrawal_id_raw.isdigit(): return await call.answer("❌ Заявка не найдена", True) status, withdrawal = await ReferralWithdrawalx().reject( withdrawal_id=int(withdrawal_id_raw), admin_id=call.from_user.id, ) if status == "ALREADY_PROCESSED": return await call.answer("❌ Заявка уже обработана", True) if status != "ok" or withdrawal is None: return await call.answer("❌ Не удалось обработать заявку", True) get_user = await Userx().get_required(user_id=withdrawal.user_id) method_title = withdrawal_method_title(withdrawal.withdrawal_method) await call.message.edit_text( ded(f""" ❌ Заявка на вывод отклонена ▪️ Номер заявки: #{withdrawal.increment} ▪️ Пользователь: @{get_user.user_login} | {get_user.user_name} | {get_user.user_id} ▪️ Сумма возвращена на реферальный баланс: {withdrawal.withdrawal_amount}₽ ▪️ Способ: {method_title} ▪️ Реквизиты: {withdrawal.withdrawal_recipient} """), reply_markup=None, ) try: await bot.send_message( withdrawal.user_id, ded(f""" ❌ Заявка на вывод отклонена ▪️ Номер заявки: #{withdrawal.increment} ▪️ Сумма возвращена на реферальный баланс: {withdrawal.withdrawal_amount}₽ """), ) except Exception: bot_logger.warning( "Не удалось отправить пользователю уведомление об отклонённом выводе", exc_info=True, ) await call.answer("❌ Заявка отклонена", True) # Поиск чеков и профилей @router.message(F.text == "🔍 Поиск") async def functions_find(message: Message, bot: Bot, state: FSM, arSession: ARS): await state.clear() await state.set_state("here_find") await message.answer("🔍 Отправьте айди/логин пользователя или номер чека") # Рассылка @router.message(F.text == "📢 Рассылка") async def functions_mail(message: Message, bot: Bot, state: FSM, arSession: ARS): await state.clear() await state.set_state("here_mail_message") await message.answer( "📢 Отправьте пост для рассылки пользователям\n" "❕ Поддерживаются посты с любыми медиафайлами", ) ################################################################################ ################################### РАССЫЛКА ################################### # Принятие текста для рассылки @router.message(StateFilter("here_mail_message")) async def functions_mail_get(message: Message, bot: Bot, state: FSM, arSession: ARS): await state.update_data(here_mail_message=message) await state.set_state("here_mail_confirm") get_users = await Userx().get_all() await message.reply( f"📢 Отправить {len(get_users)} юзерам данный пост?", reply_markup=mail_confirm_finl(), ) # Подтверждение отправки рассылки @router.callback_query( F.data.startswith("mail_confirm:"), StateFilter("here_mail_confirm") ) async def functions_mail_confirm( call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS ): get_status = call.data.split(":")[1] send_message = (await state.get_data())["here_mail_message"] await state.clear() if get_status == "Yes": get_users = await Userx().get_all() await call.message.edit_text( f"📢 Рассылка началась... (0/{len(get_users)})" ) await asyncio.create_task(functions_mail_make(bot, send_message, call)) else: await call.message.edit_text("📢 Вы отменили отправку рассылки ✅") ################################################################################ ##################################### ПОИСК #################################### # Принятие айди/логина пользователя или чека для поиска @router.message(F.text, StateFilter("here_find")) @router.message(F.text.lower().startswith((".find", "find"))) async def functions_find_get(message: Message, bot: Bot, state: FSM, arSession: ARS): find_data = message.text.lower() if ".find" in find_data or "find" in find_data: if len(find_data.split(" ")) >= 2: if ".find" in find_data or "find" in find_data: find_data = message.text.split(" ")[1] else: return await message.answer( "❌ Вы не указали поисковые данные\n" "🔍 Отправьте айди/логин пользователя или номер чека", ) if find_data.startswith("@") or find_data.startswith("#"): find_data = find_data[1:] if find_data.isdigit(): get_user = await Userx().get(user_id=find_data) else: get_user = await Userx().get(user_login=find_data.lower()) get_refill = await Refillx().get(refill_receipt=find_data) get_purchase = await Purchasesx().get(purchase_receipt=find_data) if get_user is None and get_refill is None and get_purchase is None: return await message.answer( "❌ Данные не были найдены\n" "🔍 Отправьте айди/логин пользователя или номер чека", ) await state.clear() if get_user is not None: return await open_profile_admin(bot, message.from_user.id, get_user) if get_refill is not None: return await refill_open_admin(bot, message.from_user.id, get_refill) if get_purchase is not None: return await purchase_open_admin( bot, arSession, message.from_user.id, get_purchase ) ################################################################################ ############################## УПРАВЛЕНИЕ ПРОФИЛЕМ ############################# # Обновление профиля пользователя @router.callback_query(F.data.startswith("admin_user_refresh:")) async def functions_user_refresh( call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS ): user_id = int(call.data.split(":")[1]) get_user = await Userx().get_required(user_id=user_id) await state.clear() await del_message(call.message) await open_profile_admin(bot, call.from_user.id, get_user) # Покупки пользователя @router.callback_query(F.data.startswith("admin_user_purchases:")) async def functions_user_purchases( call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS ): user_id = int(call.data.split(":")[1]) get_user = await Userx().get_required(user_id=user_id) get_purchases = await Purchasesx().gets(user_id=user_id) get_purchases = get_purchases[-10:] if len(get_purchases) < 1: return await call.answer("❗ У пользователя отсутствуют покупки", True) await call.answer("🎁 Последние 10 покупок") await del_message(call.message) for purchase in get_purchases: link_items = await ( await HostingAPI.connect( bot=bot, arSession=arSession, ) ).upload_text(purchase.purchase_data) await call.message.answer( ded(f""" 🧾 Чек: #{purchase.purchase_receipt} 🎁 Товар: {purchase.purchase_position_name} | {purchase.purchase_count}шт | {purchase.purchase_price}₽ 🕰 Дата покупки: {convert_date(purchase.purchase_unix)} 🔗 Товары: кликабельно """), disable_web_page_preview=True, ) await asyncio.sleep(0.2) await open_profile_admin(bot, call.from_user.id, get_user) # Выдача баланса пользователю @router.callback_query(F.data.startswith("admin_user_balance_add:")) async def functions_user_balance_add( call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS ): user_id = int(call.data.split(":")[1]) await state.update_data(here_user=user_id) await state.set_state("here_user_add") await call.message.edit_text( "💰 Введите сумму для выдачи баланса", reply_markup=profile_edit_return_finl(user_id), ) # Принятие суммы для выдачи баланса пользователю @router.message(F.text, StateFilter("here_user_add")) async def functions_user_balance_add_get( message: Message, bot: Bot, state: FSM, arSession: ARS ): user_id = (await state.get_data())["here_user"] if not is_number(message.text): return await message.answer( "❌ Данные были введены неверно\n" "💰 Введите сумму для выдачи баланса", reply_markup=profile_edit_return_finl(user_id), ) get_amount = to_number(message.text) if get_amount <= 0 or get_amount > 1_000_000_000: return await message.answer( "❌ Сумма выдачи не может быть меньше 1 и больше 1 000 000 000\n" "💰 Введите сумму для выдачи баланса", reply_markup=profile_edit_return_finl(user_id), ) await state.clear() get_user = await Userx().get_required(user_id=user_id) await Userx().update( user_id, user_balance=round(get_user.user_balance + get_amount, 2), user_give=round(get_user.user_give + get_amount, 2), ) try: await bot.send_message( user_id, f"💰 Вам было выдано {message.text}₽", ) except Exception: bot_logger.debug( "Не удалось уведомить пользователя %s о выдаче баланса", user_id, exc_info=True, ) await message.answer( f"👤 Пользователь: {get_user.user_name}\n" f"💰 Выдача баланса: {message.text}₽ | {get_user.user_balance}₽ -> {round(get_user.user_balance + get_amount, 2)}₽" ) get_user = await Userx().get_required(user_id=user_id) await open_profile_admin(bot, message.from_user.id, get_user) # Изменение баланса пользователю @router.callback_query(F.data.startswith("admin_user_balance_set:")) async def functions_user_balance_set( call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS ): user_id = int(call.data.split(":")[1]) await state.update_data(here_user=user_id) await state.set_state("here_user_set") await call.message.edit_text( "💰 Введите сумму для изменения баланса", reply_markup=profile_edit_return_finl(user_id), ) # Принятие суммы для изменения баланса пользователя @router.message(F.text, StateFilter("here_user_set")) async def functions_user_balance_set_get( message: Message, bot: Bot, state: FSM, arSession: ARS ): user_id = (await state.get_data())["here_user"] if not is_number(message.text): return await message.answer( "❌ Данные были введены неверно\n" "💰 Введите сумму для изменения баланса", reply_markup=profile_edit_return_finl(user_id), ) get_amount = to_number(message.text) if get_amount < -1_000_000_000 or get_amount > 1_000_000_000: return await message.answer( "❌ Сумма изменения не может быть больше или меньше (-)1 000 000 000\n" "💰 Введите сумму для изменения баланса", reply_markup=profile_edit_return_finl(user_id), ) await state.clear() get_user = await Userx().get_required(user_id=user_id) if get_amount > get_user.user_balance: user_give = get_amount - get_user.user_give else: user_give = 0 await Userx().update( user_id, user_balance=get_amount, user_give=round(get_user.user_give + user_give, 2), ) await message.answer( f"👤 Пользователь: {get_user.user_name}\n" f"💰 Установка баланса: {message.text}₽ | {get_user.user_balance}₽ -> {get_amount}₽" ) get_user = await Userx().get_required(user_id=user_id) await open_profile_admin(bot, message.from_user.id, get_user) # Отправка сообщения пользователю @router.callback_query(F.data.startswith("admin_user_message:")) async def functions_user_user_message( call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS ): user_id = int(call.data.split(":")[1]) await state.update_data(here_user_id=user_id) await state.set_state("here_user_message") await call.message.edit_text( "💌 Введите сообщение для отправки\n" "⚠️ Сообщение будет сразу отправлено пользователю.", reply_markup=profile_edit_return_finl(user_id), ) # Принятие сообщения для отправки пользователю @router.message(F.text, StateFilter("here_user_message")) async def functions_user_user_message_get( message: Message, bot: Bot, state: FSM, arSession: ARS ): user_id = (await state.get_data())["here_user_id"] await state.clear() get_message = ( "💌 Сообщение от администратора:\n" + f"{clear_html(message.text)}" ) get_user = await Userx().get_required(user_id=user_id) try: await bot.send_message(user_id, get_message) except Exception: bot_logger.debug( "Не удалось отправить сообщение пользователю %s", user_id, exc_info=True ) await message.reply("❌ Не удалось отправить сообщение") else: await message.reply("✅ Сообщение было успешно доставлено") await open_profile_admin(bot, message.from_user.id, get_user)