Private
Public Access
forked from FOSS/AutoShop-Djimbo-Simple
Initial local state
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
# - *- coding: utf- 8 - *-
|
||||
from aiogram import Dispatcher
|
||||
|
||||
from tgbot.routers import main_errors, main_start, main_missed
|
||||
from tgbot.routers.admin import admin_menu, admin_functions, admin_payments, admin_products, admin_settings
|
||||
from tgbot.routers.user import user_menu, user_transactions, user_products
|
||||
from tgbot.utils.misc.bot_filters import IsAdmin, IsPrivate
|
||||
|
||||
|
||||
# Регистрация всех роутеров
|
||||
def register_all_routers(dp: Dispatcher):
|
||||
# Подключение фильтров
|
||||
main_errors.router.message.filter(IsPrivate())
|
||||
main_errors.router.callback_query.filter(IsPrivate())
|
||||
main_start.router.message.filter(IsPrivate())
|
||||
main_start.router.callback_query.filter(IsPrivate())
|
||||
main_missed.router.message.filter(IsPrivate())
|
||||
main_missed.router.callback_query.filter(IsPrivate())
|
||||
|
||||
user_menu.router.message.filter(IsPrivate())
|
||||
user_menu.router.callback_query.filter(IsPrivate())
|
||||
user_products.router.message.filter(IsPrivate())
|
||||
user_products.router.callback_query.filter(IsPrivate())
|
||||
user_transactions.router.message.filter(IsPrivate())
|
||||
user_transactions.router.callback_query.filter(IsPrivate())
|
||||
|
||||
admin_menu.router.message.filter(IsPrivate(), IsAdmin()) # Работа message роутера только для админов
|
||||
admin_menu.router.callback_query.filter(IsPrivate(), IsAdmin()) # Работа callback роутера только для админов
|
||||
admin_functions.router.message.filter(IsPrivate(), IsAdmin()) # Работа message роутера только для админов
|
||||
admin_functions.router.callback_query.filter(IsPrivate(), IsAdmin()) # Работа callback роутера только для админов
|
||||
admin_payments.router.message.filter(IsPrivate(), IsAdmin()) # Работа message роутера только для админов
|
||||
admin_payments.router.callback_query.filter(IsPrivate(), IsAdmin()) # Работа callback роутера только для админов
|
||||
admin_settings.router.message.filter(IsPrivate(), IsAdmin()) # Работа message роутера только для админов
|
||||
admin_settings.router.callback_query.filter(IsPrivate(), IsAdmin()) # Работа callback роутера только для админов
|
||||
admin_products.router.message.filter(IsPrivate(), IsAdmin()) # Работа message роутера только для админов
|
||||
admin_products.router.callback_query.filter(IsPrivate(), IsAdmin()) # Работа callback роутера только для админов
|
||||
|
||||
# Подключение обязательных роутеров
|
||||
dp.include_router(main_errors.router) # Роутер ошибки
|
||||
dp.include_router(main_start.router) # Роутер основных команд
|
||||
|
||||
# Подключение пользовательских роутеров (юзеров и админов)
|
||||
dp.include_router(user_menu.router) # Юзер роутер
|
||||
dp.include_router(admin_menu.router) # Админ роутер
|
||||
dp.include_router(user_products.router) # Юзер роутер
|
||||
dp.include_router(user_transactions.router) # Юзер роутер
|
||||
dp.include_router(admin_functions.router) # Админ роутер
|
||||
dp.include_router(admin_payments.router) # Админ роутер
|
||||
dp.include_router(admin_settings.router) # Админ роутер
|
||||
dp.include_router(admin_products.router) # Админ роутер
|
||||
|
||||
# Подключение обязательных роутеров
|
||||
dp.include_router(main_missed.router) # Роутер пропущенных апдейтов
|
||||
@@ -0,0 +1,327 @@
|
||||
# - *- 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, 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__)
|
||||
|
||||
|
||||
# Поиск чеков и профилей
|
||||
@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("<b>🔍 Отправьте айди/логин пользователя или номер чека</b>")
|
||||
|
||||
|
||||
# Рассылка
|
||||
@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(
|
||||
"<b>📢 Отправьте пост для рассылки пользователям</b>\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"<b>📢 Отправить <code>{len(get_users)}</code> юзерам данный пост?</b>",
|
||||
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"<b>📢 Рассылка началась... (0/{len(get_users)})</b>")
|
||||
|
||||
await asyncio.create_task(functions_mail_make(bot, send_message, call))
|
||||
else:
|
||||
await call.message.edit_text("<b>📢 Вы отменили отправку рассылки ✅</b>")
|
||||
|
||||
|
||||
################################################################################
|
||||
##################################### ПОИСК ####################################
|
||||
# Принятие айди/логина пользователя или чека для поиска
|
||||
@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(
|
||||
"<b>❌ Вы не указали поисковые данные</b>\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(
|
||||
"<b>❌ Данные не были найдены</b>\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"""
|
||||
<b>🧾 Чек: <code>#{purchase.purchase_receipt}</code></b>
|
||||
🎁 Товар: <code>{purchase.purchase_position_name} | {purchase.purchase_count}шт | {purchase.purchase_price}₽</code>
|
||||
🕰 Дата покупки: <code>{convert_date(purchase.purchase_unix)}</code>
|
||||
🔗 Товары: <a href='{link_items}'>кликабельно</a>
|
||||
"""),
|
||||
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(
|
||||
"<b>💰 Введите сумму для выдачи баланса</b>",
|
||||
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(
|
||||
"<b>❌ Данные были введены неверно</b>\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(
|
||||
"<b>❌ Сумма выдачи не может быть меньше 1 и больше 1 000 000 000</b>\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"<b>💰 Вам было выдано <code>{message.text}₽</code></b>",
|
||||
)
|
||||
except Exception:
|
||||
bot_logger.debug("Не удалось уведомить пользователя %s о выдаче баланса", user_id, exc_info=True)
|
||||
|
||||
await message.answer(
|
||||
f"👤 Пользователь: <a href='tg://user?id={get_user.user_id}'>{get_user.user_name}</a>\n"
|
||||
f"💰 Выдача баланса: <code>{message.text}₽</code> | <code>{get_user.user_balance}₽</code> -> <code>{round(get_user.user_balance + get_amount, 2)}₽</code>"
|
||||
)
|
||||
|
||||
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(
|
||||
"<b>💰 Введите сумму для изменения баланса</b>",
|
||||
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(
|
||||
"<b>❌ Данные были введены неверно</b>\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(
|
||||
"<b>❌ Сумма изменения не может быть больше или меньше (-)1 000 000 000</b>\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"👤 Пользователь: <a href='tg://user?id={get_user.user_id}'>{get_user.user_name}</a>\n"
|
||||
f"💰 Установка баланса: <code>{message.text}₽</code> | <code>{get_user.user_balance}₽</code> -> <code>{get_amount}₽</code>"
|
||||
)
|
||||
|
||||
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(
|
||||
"<b>💌 Введите сообщение для отправки</b>\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 = "<b>💌 Сообщение от администратора:</b>\n" + f"<code>{clear_html(message.text)}</code>"
|
||||
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("<b>❌ Не удалось отправить сообщение</b>")
|
||||
else:
|
||||
await message.reply("<b>✅ Сообщение было успешно доставлено</b>")
|
||||
|
||||
await open_profile_admin(bot, message.from_user.id, get_user)
|
||||
@@ -0,0 +1,120 @@
|
||||
# - *- coding: utf- 8 - *-
|
||||
import os
|
||||
|
||||
import aiofiles
|
||||
from aiogram import Router, Bot, F
|
||||
from aiogram.filters import Command
|
||||
from aiogram.types import Message, FSInputFile
|
||||
from aiogram.utils.media_group import MediaGroupBuilder
|
||||
|
||||
from tgbot.data.config import PATH_LOGS, PATH_DATABASE
|
||||
from tgbot.keyboards.reply_main import payments_frep, settings_frep, functions_frep, items_frep
|
||||
from tgbot.utils.const_functions import get_date
|
||||
from tgbot.utils.misc.bot_models import FSM, ARS
|
||||
from tgbot.utils.misc_functions import get_statistics
|
||||
|
||||
router = Router(name=__name__)
|
||||
|
||||
|
||||
# Платежные системы
|
||||
@router.message(F.text == "🔑 Платежные системы")
|
||||
async def admin_payments(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await message.answer(
|
||||
"<b>🔑 Настройка платежных системы</b>",
|
||||
reply_markup=payments_frep(),
|
||||
)
|
||||
|
||||
|
||||
# Настройки бота
|
||||
@router.message(F.text == "⚙️ Настройки")
|
||||
async def admin_settings(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await message.answer(
|
||||
"<b>⚙️ Основные настройки бота</b>",
|
||||
reply_markup=settings_frep(),
|
||||
)
|
||||
|
||||
|
||||
# Общие функции
|
||||
@router.message(F.text == "🔆 Общие функции")
|
||||
async def admin_functions(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await message.answer(
|
||||
"<b>🔆 Общие функции бота</b>",
|
||||
reply_markup=functions_frep(),
|
||||
)
|
||||
|
||||
|
||||
# Управление товарами
|
||||
@router.message(F.text == "🎁 Управление товарами")
|
||||
async def admin_products(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await message.answer(
|
||||
"<b>🎁 Редактирование товаров</b>",
|
||||
reply_markup=items_frep(),
|
||||
)
|
||||
|
||||
|
||||
# Статистика бота
|
||||
@router.message(F.text == "📊 Статистика")
|
||||
async def admin_statistics(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await message.answer(await get_statistics())
|
||||
|
||||
|
||||
# Получение базы данных
|
||||
@router.message(Command(commands=['db', 'database']))
|
||||
async def admin_database(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await message.answer_document(
|
||||
FSInputFile(PATH_DATABASE),
|
||||
caption=f"<b>📦 #BACKUP | <code>{get_date()}</code></b>",
|
||||
)
|
||||
|
||||
|
||||
# Получение логов
|
||||
@router.message(Command(commands=['log', 'logs']))
|
||||
async def admin_log(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
media_group = MediaGroupBuilder(
|
||||
caption=f"<b>🖨 #LOGS | <code>{get_date()}</code></b>",
|
||||
)
|
||||
|
||||
if os.path.isfile(PATH_LOGS):
|
||||
media_group.add_document(media=FSInputFile(PATH_LOGS))
|
||||
|
||||
if os.path.isfile("tgbot/data/sv_log_err.log"):
|
||||
media_group.add_document(media=FSInputFile("tgbot/data/sv_log_err.log"))
|
||||
|
||||
if os.path.isfile("tgbot/data/sv_log_out.log"):
|
||||
media_group.add_document(media=FSInputFile("tgbot/data/sv_log_out.log"))
|
||||
|
||||
await message.answer_media_group(media=media_group.build())
|
||||
|
||||
|
||||
# Очистка логов
|
||||
@router.message(Command(commands=['clear_log', 'clear_logs', 'log_clear', 'logs_clear']))
|
||||
async def admin_log_clear(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
if os.path.isfile(PATH_LOGS):
|
||||
async with aiofiles.open(PATH_LOGS, "w") as file:
|
||||
await file.write(f"{get_date()} | LOGS WAS CLEAR")
|
||||
|
||||
if os.path.isfile("tgbot/data/sv_log_err.log"):
|
||||
async with aiofiles.open("tgbot/data/sv_log_err.log", "w") as file:
|
||||
await file.write(f"{get_date()} | LOGS ERR WAS CLEAR")
|
||||
|
||||
if os.path.isfile("tgbot/data/sv_log_out.log"):
|
||||
async with aiofiles.open("tgbot/data/sv_log_out.log", "w") as file:
|
||||
await file.write(f"{get_date()} | LOGS OUT WAS CLEAR")
|
||||
|
||||
await message.answer("<b>🖨 Логи были успешно очищены</b>")
|
||||
@@ -0,0 +1,355 @@
|
||||
# - *- coding: utf- 8 - *-
|
||||
from aiogram import Router, Bot, F
|
||||
from aiogram.filters import StateFilter
|
||||
from aiogram.types import CallbackQuery, Message
|
||||
|
||||
from tgbot.database import Paymentsx
|
||||
from tgbot.keyboards.inline_admin import payment_yoomoney_finl, close_finl, payment_cryptobot_finl, payment_stars_finl
|
||||
from tgbot.services.api_cryptobot import CryptobotAPI
|
||||
from tgbot.services.api_stars import StarsAPI
|
||||
from tgbot.services.api_yoomoney import YoomoneyAPI
|
||||
from tgbot.utils.const_functions import ded, is_number, to_number
|
||||
from tgbot.utils.misc.bot_logging import bot_logger
|
||||
from tgbot.utils.misc.bot_models import FSM, ARS
|
||||
|
||||
router = Router(name=__name__)
|
||||
|
||||
|
||||
# Управление - CryptoBot
|
||||
@router.message(F.text == "🔷 CryptoBot")
|
||||
async def payments_cryptobot_open(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await message.answer(
|
||||
"<b>🔷 Управление - CryptoBot</b>",
|
||||
reply_markup=await payment_cryptobot_finl(),
|
||||
)
|
||||
|
||||
|
||||
# Управление - ЮMoney
|
||||
@router.message(F.text == "🔮 ЮMoney")
|
||||
async def payments_yoomoney_open(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await message.answer(
|
||||
"<b>🔮 Управление - ЮMoney</b>",
|
||||
reply_markup=await payment_yoomoney_finl(),
|
||||
)
|
||||
|
||||
|
||||
# Управление - Звёзды
|
||||
@router.message(F.text == "⭐️ Звёзды")
|
||||
async def payments_stars_open(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await message.answer(
|
||||
"<b>⭐️ Управление - Звёзды</b>",
|
||||
reply_markup=await payment_stars_finl(),
|
||||
)
|
||||
|
||||
|
||||
################################################################################
|
||||
################################### CRYPTOBOT ##################################
|
||||
# Баланс - CryptoBot
|
||||
@router.callback_query(F.data == "payment_cryptobot_balance")
|
||||
async def payments_cryptobot_balance(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
response = await (
|
||||
await CryptobotAPI.connect(
|
||||
bot=bot,
|
||||
arSession=arSession,
|
||||
update=call,
|
||||
skipping_error=True,
|
||||
)
|
||||
).balance()
|
||||
|
||||
await call.message.answer(
|
||||
response,
|
||||
reply_markup=close_finl(),
|
||||
)
|
||||
|
||||
|
||||
# Информация - CryptoBot
|
||||
@router.callback_query(F.data == "payment_cryptobot_check")
|
||||
async def payments_cryptobot_check(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
status, response = await (
|
||||
await CryptobotAPI.connect(
|
||||
bot=bot,
|
||||
arSession=arSession,
|
||||
update=call,
|
||||
skipping_error=True,
|
||||
)
|
||||
).check()
|
||||
|
||||
await call.message.answer(
|
||||
response,
|
||||
reply_markup=close_finl(),
|
||||
)
|
||||
|
||||
|
||||
# Изменение - CryptoBot
|
||||
@router.callback_query(F.data == "payment_cryptobot_edit")
|
||||
async def payments_cryptobot_edit(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.set_state("here_cryptobot_token")
|
||||
await call.message.edit_text(
|
||||
ded(f"""
|
||||
<b>🔷 Изменение @CryptoBot кошелька - <a href='https://teletype.in/@djimbox/djimboshop-cryptobot'>Инструкция</a></b>
|
||||
➖➖➖➖➖➖➖➖➖➖
|
||||
▪️ Создайте Приложение в "Crypto Pay" и отправьте токен
|
||||
"""),
|
||||
disable_web_page_preview=True,
|
||||
)
|
||||
|
||||
|
||||
# Выключатель - CryptoBot
|
||||
@router.callback_query(F.data.startswith("payment_cryptobot_status:"))
|
||||
async def payments_cryptobot_status(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
get_status = call.data.split(":")[1]
|
||||
|
||||
get_payments = await Paymentsx().get()
|
||||
|
||||
if get_status == "True" and get_payments.cryptobot_token == "None":
|
||||
return await call.answer("❌ Токен данной платежной системы не был добавлен", True)
|
||||
|
||||
await Paymentsx().update(status_cryptobot=get_status)
|
||||
|
||||
await call.message.edit_text(
|
||||
"<b>🔷 Управление - CryptoBot</b>",
|
||||
reply_markup=await payment_cryptobot_finl(),
|
||||
)
|
||||
|
||||
|
||||
############################## ПРИНЯТИЕ CRYPTOBOT ##############################
|
||||
# Принятие токена Cryptobot
|
||||
@router.message(StateFilter("here_cryptobot_token"))
|
||||
async def payments_cryptobot_get(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
get_token = message.text
|
||||
|
||||
await state.clear()
|
||||
|
||||
cache_message = await message.answer("<b>🔷 Проверка введённых CryptoBot данных... 🔄</b>")
|
||||
|
||||
status, response = await (
|
||||
await CryptobotAPI.connect(
|
||||
bot=bot,
|
||||
arSession=arSession,
|
||||
update=message,
|
||||
skipping_error=True,
|
||||
token=get_token,
|
||||
)
|
||||
).check()
|
||||
|
||||
if status:
|
||||
await Paymentsx().update(cryptobot_token=get_token)
|
||||
await cache_message.edit_text("<b>🔷 CryptoBot кошелёк был успешно изменён ✅</b>")
|
||||
else:
|
||||
await cache_message.edit_text("<b>🔷 Не удалось изменить CryptoBot кошелёк ❌</b>")
|
||||
|
||||
await message.answer(
|
||||
"<b>🔷 Управление - CryptoBot</b>",
|
||||
reply_markup=await payment_cryptobot_finl(),
|
||||
)
|
||||
|
||||
|
||||
################################################################################
|
||||
#################################### ЮMoney ####################################
|
||||
# Баланс - ЮMoney
|
||||
@router.callback_query(F.data == "payment_yoomoney_balance")
|
||||
async def payments_yoomoney_balance(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
response = await (
|
||||
await YoomoneyAPI.connect(
|
||||
bot=bot,
|
||||
arSession=arSession,
|
||||
update=call,
|
||||
skipping_error=True,
|
||||
)
|
||||
).balance()
|
||||
|
||||
await call.message.answer(
|
||||
response,
|
||||
reply_markup=close_finl(),
|
||||
)
|
||||
|
||||
|
||||
# Информация - ЮMoney
|
||||
@router.callback_query(F.data == "payment_yoomoney_check")
|
||||
async def payments_yoomoney_check(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
response = await (
|
||||
await YoomoneyAPI.connect(
|
||||
bot=bot,
|
||||
arSession=arSession,
|
||||
update=call,
|
||||
skipping_error=True,
|
||||
)
|
||||
).check()
|
||||
|
||||
await call.message.answer(
|
||||
response,
|
||||
reply_markup=close_finl(),
|
||||
)
|
||||
|
||||
|
||||
# Изменение - ЮMoney
|
||||
@router.callback_query(F.data == "payment_yoomoney_edit")
|
||||
async def payments_yoomoney_edit(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
response = await (
|
||||
await YoomoneyAPI.connect(
|
||||
bot=bot,
|
||||
arSession=arSession,
|
||||
)
|
||||
).authorization_get()
|
||||
|
||||
await state.set_state("here_yoomoney_token")
|
||||
await call.message.edit_text(
|
||||
ded(f"""
|
||||
<b>🔮 Изменение ЮMoney кошелька - <a href='https://teletype.in/@djimbox/djimboshop-yoomoney'>Инструкция</a></b>
|
||||
➖➖➖➖➖➖➖➖➖➖
|
||||
▪️ Отправьте ссылку/код из адресной строки
|
||||
▪️ {response}
|
||||
"""),
|
||||
disable_web_page_preview=True,
|
||||
)
|
||||
|
||||
|
||||
# Выключатель - ЮMoney
|
||||
@router.callback_query(F.data.startswith("payment_yoomoney_status:"))
|
||||
async def payments_yoomoney_status(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
get_status = call.data.split(":")[1]
|
||||
|
||||
get_payments = await Paymentsx().get()
|
||||
|
||||
if get_status == "True" and get_payments.yoomoney_token == "None":
|
||||
return await call.answer("❌ Токен данной платежной системы не был добавлен", True)
|
||||
|
||||
await Paymentsx().update(status_yoomoney=get_status)
|
||||
|
||||
await call.message.edit_text(
|
||||
"<b>🔮 Управление - ЮMoney</b>",
|
||||
reply_markup=await payment_yoomoney_finl(),
|
||||
)
|
||||
|
||||
|
||||
################################ ПРИНЯТИЕ ЮMONEY ###############################
|
||||
# Принятие токена ЮMoney
|
||||
@router.message(StateFilter("here_yoomoney_token"))
|
||||
async def payments_yoomoney_get(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
get_code = message.text
|
||||
|
||||
try:
|
||||
get_code = get_code[get_code.index("code=") + 5:].replace(" ", "")
|
||||
except Exception:
|
||||
bot_logger.debug("ЮMoney code= не найден в сообщении, пробую использовать текст как код", exc_info=True)
|
||||
|
||||
cache_message = await message.answer("<b>🔮 Проверка введённых ЮMoney данных... 🔄</b>")
|
||||
|
||||
status, token, response = await (
|
||||
await YoomoneyAPI.connect(
|
||||
bot=bot,
|
||||
arSession=arSession,
|
||||
)
|
||||
).authorization_enter(str(get_code))
|
||||
|
||||
if status:
|
||||
await Paymentsx().update(yoomoney_token=token)
|
||||
|
||||
await cache_message.edit_text(response)
|
||||
|
||||
await state.clear()
|
||||
await message.answer(
|
||||
"<b>🔮 Управление - ЮMoney</b>",
|
||||
reply_markup=await payment_yoomoney_finl(),
|
||||
)
|
||||
|
||||
|
||||
################################################################################
|
||||
#################################### ЗВЁЗДЫ ####################################
|
||||
# Баланс - Звёзды
|
||||
@router.callback_query(F.data == "payment_stars_balance")
|
||||
async def payments_stars_balance(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
response = await (
|
||||
await StarsAPI.connect(
|
||||
bot=bot,
|
||||
arSession=arSession,
|
||||
update=call,
|
||||
skipping_error=True,
|
||||
)
|
||||
).balance()
|
||||
|
||||
await call.message.answer(
|
||||
response,
|
||||
reply_markup=close_finl(),
|
||||
)
|
||||
|
||||
|
||||
# Информация - Звёзды
|
||||
@router.callback_query(F.data == "payment_stars_check")
|
||||
async def payments_stars_check(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
status, response = await (
|
||||
await StarsAPI.connect(
|
||||
bot=bot,
|
||||
arSession=arSession,
|
||||
update=call,
|
||||
skipping_error=True,
|
||||
)
|
||||
).check()
|
||||
|
||||
await call.message.answer(
|
||||
response,
|
||||
reply_markup=close_finl(),
|
||||
)
|
||||
|
||||
|
||||
# Изменение - Звёзды
|
||||
@router.callback_query(F.data == "payment_stars_edit")
|
||||
async def payments_stars_edit(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
get_payments = await Paymentsx().get()
|
||||
|
||||
await state.set_state("here_stars_course")
|
||||
await call.message.edit_text(
|
||||
ded(f"""
|
||||
<b>⭐️ Изменение курса Telegram Stars</b>
|
||||
➖➖➖➖➖➖➖➖➖➖
|
||||
▪️ Текущий курс: <code>1 ⭐️ = {get_payments.stars_course}₽</code>
|
||||
▪️ Отправьте новый курс в рублях за одну звезду
|
||||
"""),
|
||||
disable_web_page_preview=True,
|
||||
)
|
||||
|
||||
|
||||
# Выключатель - Звёзды
|
||||
@router.callback_query(F.data.startswith("payment_stars_status:"))
|
||||
async def payments_stars_status(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
get_status = call.data.split(":")[1]
|
||||
|
||||
await Paymentsx().update(status_stars=get_status)
|
||||
|
||||
await call.message.edit_text(
|
||||
"<b>⭐️ Управление - Звёзды</b>",
|
||||
reply_markup=await payment_stars_finl(),
|
||||
)
|
||||
|
||||
|
||||
############################# ПРИНЯТИЕ КУРСА ЗВЁЗД #############################
|
||||
# Принятие курса Telegram Stars
|
||||
@router.message(StateFilter("here_stars_course"))
|
||||
async def payments_stars_course_get(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
if not is_number(message.text):
|
||||
return await message.answer(
|
||||
"<b>❌ Введите число. Например: <code>1.5</code></b>"
|
||||
)
|
||||
|
||||
stars_course = float(to_number(message.text))
|
||||
|
||||
if stars_course <= 0:
|
||||
return await message.answer("<b>❌ Курс должен быть больше нуля</b>")
|
||||
|
||||
await Paymentsx().update(stars_course=stars_course)
|
||||
await state.clear()
|
||||
|
||||
await message.answer(
|
||||
f"<b>⭐️ Курс Telegram Stars изменён: <code>1 ⭐️ = {stars_course}₽</code></b>",
|
||||
)
|
||||
|
||||
await message.answer(
|
||||
"<b>⭐️ Управление - Звёзды</b>",
|
||||
reply_markup=await payment_stars_finl(),
|
||||
)
|
||||
@@ -0,0 +1,969 @@
|
||||
# - *- coding: utf- 8 - *-
|
||||
from aiogram import Router, Bot, F
|
||||
from aiogram.filters import StateFilter
|
||||
from aiogram.types import CallbackQuery, Message, ReactionTypeEmoji
|
||||
|
||||
from tgbot.database import Categoryx, Itemx, Positionx, Settingsx
|
||||
from tgbot.keyboards.inline_admin import close_finl
|
||||
from tgbot.keyboards.inline_admin_page import (
|
||||
category_edit_swipe_fp,
|
||||
position_add_swipe_fp,
|
||||
position_edit_category_swipe_fp,
|
||||
position_edit_swipe_fp,
|
||||
item_add_position_swipe_fp,
|
||||
item_add_category_swipe_fp,
|
||||
item_delete_swipe_fp,
|
||||
)
|
||||
from tgbot.keyboards.inline_admin_products import (
|
||||
category_edit_delete_finl,
|
||||
position_edit_clear_finl,
|
||||
position_edit_delete_finl,
|
||||
position_edit_cancel_finl,
|
||||
category_edit_cancel_finl,
|
||||
products_removes_finl,
|
||||
products_removes_categories_finl,
|
||||
products_removes_positions_finl,
|
||||
products_removes_items_finl,
|
||||
item_add_finish_finl,
|
||||
)
|
||||
from tgbot.services.api_discord import DiscordAPI
|
||||
from tgbot.services.api_hosting_text import HostingAPI
|
||||
from tgbot.utils.const_functions import clear_list, is_number, to_number, del_message, ded, clear_html, gen_id
|
||||
from tgbot.utils.misc.bot_logging import bot_logger
|
||||
from tgbot.utils.misc.bot_models import FSM, ARS
|
||||
from tgbot.utils.text_functions import category_open_admin, position_open_admin, item_open_admin
|
||||
|
||||
router = Router(name=__name__)
|
||||
|
||||
|
||||
# Создание новой категории
|
||||
@router.message(F.text == "🗃 Создать категорию ➕")
|
||||
async def prod_category_add(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await state.set_state("here_category_name")
|
||||
await message.answer("<b>🗃 Введите название для категории</b>")
|
||||
|
||||
|
||||
# Выбор категории для редактирования
|
||||
@router.message(F.text == "🗃 Изменить категорию 🖍")
|
||||
async def prod_category_edit(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
get_categories = await Categoryx().get_all()
|
||||
|
||||
if len(get_categories) >= 1:
|
||||
await message.answer(
|
||||
"<b>🗃 Выберите категорию для изменения 🖍</b>",
|
||||
reply_markup=await category_edit_swipe_fp(0),
|
||||
)
|
||||
else:
|
||||
await message.answer("<b>❌ Отсутствуют категории для изменения категорий</b>")
|
||||
|
||||
|
||||
# Создание новой позиции
|
||||
@router.message(F.text == "📁 Создать позицию ➕")
|
||||
async def prod_position_add(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
get_categories = await Categoryx().get_all()
|
||||
|
||||
if len(get_categories) >= 1:
|
||||
await message.answer(
|
||||
"<b>📁 Выберите категорию для позиции ➕</b>",
|
||||
reply_markup=await position_add_swipe_fp(0),
|
||||
)
|
||||
else:
|
||||
await message.answer("<b>❌ Отсутствуют категории для создания позиции</b>")
|
||||
|
||||
|
||||
# Выбор позиции для редактирования
|
||||
@router.message(F.text == "📁 Изменить позицию 🖍")
|
||||
async def prod_position_edit(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
get_categories = await Categoryx().get_all()
|
||||
|
||||
if len(get_categories) >= 1:
|
||||
await message.answer(
|
||||
"<b>📁 Выберите позицию для изменения 🖍</b>",
|
||||
reply_markup=await position_edit_category_swipe_fp(0),
|
||||
)
|
||||
else:
|
||||
await message.answer("<b>❌ Отсутствуют категории для изменения позиций</b>")
|
||||
|
||||
|
||||
# Страницы товаров для добавления
|
||||
@router.message(F.text == "🎁 Добавить товары ➕")
|
||||
async def prod_item_add(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
get_categories = await Categoryx().get_all()
|
||||
|
||||
if len(get_categories) >= 1:
|
||||
await message.answer(
|
||||
"<b>🎁 Выберите позицию для товаров ➕</b>",
|
||||
reply_markup=await item_add_category_swipe_fp(0),
|
||||
)
|
||||
else:
|
||||
await message.answer("<b>❌ Отсутствуют позиции для добавления товара</b>")
|
||||
|
||||
|
||||
# Удаление категорий, позиций или товаров
|
||||
@router.message(F.text == "❌ Удаление")
|
||||
async def prod_removes(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await message.answer(
|
||||
"<b>🎁 Выберите раздел который хотите удалить ❌</b>\n",
|
||||
reply_markup=products_removes_finl(),
|
||||
)
|
||||
|
||||
|
||||
################################################################################
|
||||
############################### СОЗДАНИЕ КАТЕГОРИИ #############################
|
||||
# Принятие названия категории для её создания
|
||||
@router.message(F.text, StateFilter('here_category_name'))
|
||||
async def prod_category_add_name_get(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
if len(message.text) > 50:
|
||||
return await message.answer(
|
||||
"<b>❌ Название не может превышать 50 символов</b>\n"
|
||||
"🗃 Введите название для категории",
|
||||
)
|
||||
|
||||
await state.clear()
|
||||
|
||||
category_id = gen_id(12)
|
||||
await Categoryx().add(category_id, clear_html(message.text))
|
||||
|
||||
await category_open_admin(bot, message.from_user.id, category_id, 0)
|
||||
|
||||
|
||||
################################################################################
|
||||
############################### ИЗМЕНЕНИЕ КАТЕГОРИИ ############################
|
||||
# Страница выбора категорий для редактирования
|
||||
@router.callback_query(F.data.startswith("category_edit_swipe:"))
|
||||
async def prod_category_edit_swipe(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
remover = int(call.data.split(":")[1])
|
||||
|
||||
await call.message.edit_text(
|
||||
"<b>🗃 Выберите категорию для изменения 🖍</b>",
|
||||
reply_markup=await category_edit_swipe_fp(remover),
|
||||
)
|
||||
|
||||
|
||||
# Выбор текущей категории для редактирования
|
||||
@router.callback_query(F.data.startswith("category_edit_open:"))
|
||||
async def prod_category_edit_open(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
category_id = int(call.data.split(":")[1])
|
||||
remover = int(call.data.split(":")[2])
|
||||
|
||||
await state.clear()
|
||||
|
||||
await del_message(call.message)
|
||||
await category_open_admin(bot, call.from_user.id, category_id, remover)
|
||||
|
||||
|
||||
############################ САМО ИЗМЕНЕНИЕ КАТЕГОРИИ ##########################
|
||||
# Изменение названия категории
|
||||
@router.callback_query(F.data.startswith("category_edit_name:"))
|
||||
async def prod_category_edit_name(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
category_id = int(call.data.split(":")[1])
|
||||
remover = int(call.data.split(":")[2])
|
||||
|
||||
await state.update_data(here_category_id=category_id)
|
||||
await state.update_data(here_remover=remover)
|
||||
await state.set_state("here_category_edit_name")
|
||||
|
||||
await del_message(call.message)
|
||||
|
||||
await call.message.answer(
|
||||
"<b>🗃 Введите новое название для категории</b>",
|
||||
reply_markup=category_edit_cancel_finl(category_id, remover),
|
||||
)
|
||||
|
||||
|
||||
# Принятие нового названия для категории
|
||||
@router.message(F.text, StateFilter('here_category_edit_name'))
|
||||
async def prod_category_edit_name_get(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
category_id = (await state.get_data())['here_category_id']
|
||||
remover = (await state.get_data())['here_remover']
|
||||
|
||||
if len(message.text) > 50:
|
||||
return await message.answer(
|
||||
"<b>❌ Название не может превышать 50 символов</b>\n"
|
||||
"🗃 Введите новое название для категории",
|
||||
reply_markup=category_edit_cancel_finl(category_id, remover),
|
||||
)
|
||||
|
||||
await state.clear()
|
||||
|
||||
await Categoryx().update(category_id, category_name=clear_html(message.text))
|
||||
await category_open_admin(bot, message.from_user.id, category_id, remover)
|
||||
|
||||
|
||||
# Удаление категории
|
||||
@router.callback_query(F.data.startswith("category_edit_delete:"))
|
||||
async def prod_category_edit_delete(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
category_id = int(call.data.split(":")[1])
|
||||
remover = int(call.data.split(":")[2])
|
||||
|
||||
await call.message.edit_text(
|
||||
"<b>❗ Вы действительно хотите удалить категорию и все её данные?</b>",
|
||||
reply_markup=category_edit_delete_finl(category_id, remover),
|
||||
)
|
||||
|
||||
|
||||
# Подтверждение удаления категории
|
||||
@router.callback_query(F.data.startswith("category_edit_delete_confirm:"))
|
||||
async def prod_category_edit_delete_confirm(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
category_id = int(call.data.split(":")[1])
|
||||
remover = int(call.data.split(":")[2])
|
||||
|
||||
await Categoryx().delete(category_id=category_id)
|
||||
await Positionx().delete(category_id=category_id)
|
||||
await Itemx().delete(category_id=category_id)
|
||||
|
||||
await call.answer("🗃 Категория и все её данные были успешно удалены ✅", True)
|
||||
|
||||
get_categories = await Categoryx().get_all()
|
||||
|
||||
if len(get_categories) >= 1:
|
||||
await call.message.edit_text(
|
||||
"<b>🗃 Выберите категорию для изменения 🖍</b>",
|
||||
reply_markup=await category_edit_swipe_fp(remover),
|
||||
)
|
||||
else:
|
||||
await del_message(call.message)
|
||||
|
||||
|
||||
################################################################################
|
||||
############################### ДОБАВЛЕНИЕ ПОЗИЦИИ #############################
|
||||
# Cтраницы выбора категорий для расположения позиции
|
||||
@router.callback_query(F.data.startswith("position_add_swipe:"))
|
||||
async def prod_position_add_swipe(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
remover = int(call.data.split(":")[1])
|
||||
|
||||
await call.message.edit_text(
|
||||
"<b>📁 Выберите категорию для позиции ➕</b>",
|
||||
reply_markup=await position_add_swipe_fp(remover),
|
||||
)
|
||||
|
||||
|
||||
# Выбор категории для создания позиции
|
||||
@router.callback_query(F.data.startswith("position_add_open:"))
|
||||
async def prod_position_add_open(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
category_id = int(call.data.split(":")[1])
|
||||
|
||||
await state.update_data(here_category_id=category_id)
|
||||
await state.set_state("here_position_name")
|
||||
|
||||
await call.message.edit_text("<b>📁 Введите название для позиции</b>")
|
||||
|
||||
|
||||
# Принятие названия для создания позиции
|
||||
@router.message(F.text, StateFilter('here_position_name'))
|
||||
async def prod_position_add_name_get(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
if len(message.text) > 50:
|
||||
return await message.answer(
|
||||
"<b>❌ Название не может превышать 50 символов</b>\n"
|
||||
"📁 Введите название для позиции",
|
||||
)
|
||||
|
||||
await state.update_data(here_position_name=clear_html(message.text))
|
||||
await state.set_state("here_position_price")
|
||||
|
||||
await message.answer("<b>📁 Введите цену для позиции</b>")
|
||||
|
||||
|
||||
# Принятие цены позиции для её создания
|
||||
@router.message(F.text, StateFilter('here_position_price'))
|
||||
async def prod_position_add_price_get(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
if not is_number(message.text):
|
||||
return await message.answer(
|
||||
"<b>❌ Данные были введены неверно</b>\n"
|
||||
"📁 Введите цену для позиции",
|
||||
)
|
||||
|
||||
if to_number(message.text) > 10_000_000 or to_number(message.text) < 0:
|
||||
return await message.answer(
|
||||
"<b>❌ Цена не может быть меньше 0₽ или больше 10 000 000₽</b>\n"
|
||||
"📁 Введите цену для позиции",
|
||||
)
|
||||
|
||||
category_id = (await state.get_data())['here_category_id']
|
||||
position_name = (await state.get_data())['here_position_name']
|
||||
position_price = to_number(message.text)
|
||||
position_desc = "None"
|
||||
position_photo = "None"
|
||||
position_id = gen_id(12)
|
||||
await state.clear()
|
||||
|
||||
await Positionx().add(
|
||||
category_id=category_id,
|
||||
position_id=position_id,
|
||||
position_name=position_name,
|
||||
position_price=position_price,
|
||||
position_desc=position_desc,
|
||||
position_photo=position_photo,
|
||||
)
|
||||
|
||||
await position_open_admin(bot, position_id, message.from_user.id)
|
||||
|
||||
|
||||
################################################################################
|
||||
############################ РЕДАКТИРОВАНИЕ ПОЗИЦИИ ############################
|
||||
# Страницы выбора категории для редактирования позиции
|
||||
@router.callback_query(F.data.startswith("position_edit_category_swipe:"))
|
||||
async def prod_position_edit_category_swipe(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
remover = int(call.data.split(":")[1])
|
||||
|
||||
await call.message.edit_text(
|
||||
"<b>📁 Выберите позицию для изменения 🖍</b>",
|
||||
reply_markup=await position_edit_category_swipe_fp(remover),
|
||||
)
|
||||
|
||||
|
||||
# Открытие категории для выбора позиции
|
||||
@router.callback_query(F.data.startswith("position_edit_category_open:"))
|
||||
async def prod_position_edit_category_open(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
category_id = int(call.data.split(":")[1])
|
||||
|
||||
get_category = await Categoryx().get_required(category_id=category_id)
|
||||
get_positions = await Positionx().gets(category_id=category_id)
|
||||
|
||||
if len(get_positions) >= 1:
|
||||
await call.message.edit_text(
|
||||
"<b>📁 Выберите позицию для изменения 🖍</b>",
|
||||
reply_markup=await position_edit_swipe_fp(0, category_id),
|
||||
)
|
||||
else:
|
||||
await call.answer(f"📁 Позиции в категории {get_category.category_name} отсутствуют")
|
||||
|
||||
|
||||
# Страницы выбора позиции для редактирования
|
||||
@router.callback_query(F.data.startswith("position_edit_swipe:"))
|
||||
async def prod_position_edit_swipe(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
category_id = int(call.data.split(":")[1])
|
||||
remover = int(call.data.split(":")[2])
|
||||
|
||||
await del_message(call.message)
|
||||
|
||||
await call.message.answer(
|
||||
"<b>📁 Выберите позицию для изменения 🖍</b>",
|
||||
reply_markup=await position_edit_swipe_fp(remover, category_id),
|
||||
)
|
||||
|
||||
|
||||
# Выбор позиции для редактирования
|
||||
@router.callback_query(F.data.startswith("position_edit_open:"))
|
||||
async def prod_position_edit_open(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
position_id = int(call.data.split(":")[1])
|
||||
remover = int(call.data.split(":")[2])
|
||||
|
||||
await state.clear()
|
||||
|
||||
await del_message(call.message)
|
||||
await position_open_admin(bot, position_id, call.from_user.id)
|
||||
|
||||
|
||||
############################ САМО ИЗМЕНЕНИЕ ПОЗИЦИИ ############################
|
||||
# Изменение названия позиции
|
||||
@router.callback_query(F.data.startswith("position_edit_name:"))
|
||||
async def prod_position_edit_name(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
position_id = int(call.data.split(":")[1])
|
||||
remover = int(call.data.split(":")[2])
|
||||
|
||||
await state.update_data(here_position_id=position_id)
|
||||
await state.update_data(here_remover=remover)
|
||||
await state.set_state("here_position_edit_name")
|
||||
|
||||
await del_message(call.message)
|
||||
await call.message.answer(
|
||||
"<b>📁 Введите новое название для позиции</b>",
|
||||
reply_markup=position_edit_cancel_finl(position_id, remover),
|
||||
)
|
||||
|
||||
|
||||
# Принятие названия позиции для её изменения
|
||||
@router.message(F.text, StateFilter('here_position_edit_name'))
|
||||
async def prod_position_edit_name_get(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
position_id = (await state.get_data())['here_position_id']
|
||||
remover = (await state.get_data())['here_remover']
|
||||
|
||||
if len(message.text) > 50:
|
||||
return await message.answer(
|
||||
"<b>❌ Название не может превышать 50 символов</b>\n"
|
||||
"📁 Введите новое название для позиции",
|
||||
reply_markup=position_edit_cancel_finl(position_id, remover),
|
||||
)
|
||||
|
||||
await state.clear()
|
||||
|
||||
await Positionx().update(position_id, position_name=clear_html(message.text))
|
||||
await position_open_admin(bot, position_id, message.from_user.id)
|
||||
|
||||
|
||||
# Изменение цены позиции
|
||||
@router.callback_query(F.data.startswith("position_edit_price:"))
|
||||
async def prod_position_edit_price(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
position_id = int(call.data.split(":")[1])
|
||||
remover = int(call.data.split(":")[2])
|
||||
|
||||
await state.update_data(here_position_id=position_id)
|
||||
await state.update_data(here_remover=remover)
|
||||
await state.set_state("here_position_edit_price")
|
||||
|
||||
await del_message(call.message)
|
||||
await call.message.answer(
|
||||
"<b>📁 Введите новую цену для позиции</b>",
|
||||
reply_markup=position_edit_cancel_finl(position_id, remover),
|
||||
)
|
||||
|
||||
|
||||
# Принятие цены позиции для её изменения
|
||||
@router.message(F.text, StateFilter('here_position_edit_price'))
|
||||
async def prod_position_edit_price_get(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
position_id = (await state.get_data())['here_position_id']
|
||||
remover = (await state.get_data())['here_remover']
|
||||
|
||||
if not is_number(message.text):
|
||||
return await message.answer(
|
||||
"<b>❌ Данные были введены неверно</b>\n"
|
||||
"📁 Введите новую цену для позиции",
|
||||
reply_markup=position_edit_cancel_finl(position_id, remover),
|
||||
)
|
||||
|
||||
if to_number(message.text) > 10_000_000 or to_number(message.text) < 0:
|
||||
return await message.answer(
|
||||
"<b>❌ Цена не может быть меньше 0₽ или больше 10 000 000₽</b>\n"
|
||||
"📁 Введите новую цену для позиции",
|
||||
reply_markup=position_edit_cancel_finl(position_id, remover),
|
||||
)
|
||||
|
||||
await state.clear()
|
||||
|
||||
await Positionx().update(position_id, position_price=to_number(message.text))
|
||||
await position_open_admin(bot, position_id, message.from_user.id)
|
||||
|
||||
|
||||
# Изменение описания позиции
|
||||
@router.callback_query(F.data.startswith("position_edit_desc:"))
|
||||
async def prod_position_edit_desc(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
position_id = int(call.data.split(":")[1])
|
||||
remover = int(call.data.split(":")[2])
|
||||
|
||||
await state.update_data(here_position_id=position_id)
|
||||
await state.update_data(here_remover=remover)
|
||||
await state.set_state("here_position_edit_desc")
|
||||
|
||||
await del_message(call.message)
|
||||
await call.message.answer(
|
||||
ded(f"""
|
||||
<b>📁 Введите новое описание для позиции</b>
|
||||
❕ Вы можете использовать HTML разметку
|
||||
❕ Отправьте <code>0</code> чтобы пропустить
|
||||
"""),
|
||||
reply_markup=position_edit_cancel_finl(position_id, remover),
|
||||
)
|
||||
|
||||
|
||||
# Принятие описания позиции для её изменения
|
||||
@router.message(F.text, StateFilter('here_position_edit_desc'))
|
||||
async def prod_position_edit_desc_get(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
position_id = (await state.get_data())['here_position_id']
|
||||
remover = (await state.get_data())['here_remover']
|
||||
|
||||
if len(message.text) > 1200:
|
||||
return await message.answer(
|
||||
ded(f"""
|
||||
<b>❌ Описание не может превышать 1200 символов</b>
|
||||
📁 Введите новое описание для позиции
|
||||
❕ Вы можете использовать HTML разметку
|
||||
❕ Отправьте <code>0</code> чтобы пропустить
|
||||
"""),
|
||||
reply_markup=position_edit_cancel_finl(position_id, remover),
|
||||
)
|
||||
|
||||
try:
|
||||
if message.text != "0":
|
||||
await (await message.answer(message.text)).delete()
|
||||
|
||||
position_desc = message.text
|
||||
else:
|
||||
position_desc = "None"
|
||||
except Exception:
|
||||
bot_logger.debug("Некорректная HTML-разметка описания позиции", exc_info=True)
|
||||
return await message.answer(
|
||||
ded(f"""
|
||||
<b>❌ Ошибка синтаксиса HTML</b>
|
||||
📁 Введите новое описание для позиции
|
||||
❕ Вы можете использовать HTML разметку
|
||||
❕ Отправьте <code>0</code> чтобы пропустить
|
||||
"""),
|
||||
reply_markup=position_edit_cancel_finl(position_id, remover),
|
||||
)
|
||||
|
||||
await state.clear()
|
||||
|
||||
await Positionx().update(position_id, position_desc=position_desc)
|
||||
await position_open_admin(bot, position_id, message.from_user.id)
|
||||
|
||||
|
||||
# Изменение изображения позиции
|
||||
@router.callback_query(F.data.startswith("position_edit_photo:"))
|
||||
async def prod_position_edit_photo(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
position_id = int(call.data.split(":")[1])
|
||||
remover = int(call.data.split(":")[2])
|
||||
|
||||
get_settings = await Settingsx().get()
|
||||
|
||||
if get_settings.misc_discord_webhook_url == "None":
|
||||
return await call.answer("🧿 Отсутствует Дискорд вебхук, добавьте его в настройках", True)
|
||||
|
||||
await state.update_data(here_position_id=position_id)
|
||||
await state.update_data(here_remover=remover)
|
||||
await state.set_state("here_position_edit_photo")
|
||||
|
||||
await del_message(call.message)
|
||||
await call.message.answer(
|
||||
"<b>📁 Отправьте новое изображение для позиции</b>\n"
|
||||
"❕ Отправьте <code>0</code> чтобы пропустить.",
|
||||
reply_markup=position_edit_cancel_finl(position_id, remover),
|
||||
)
|
||||
|
||||
|
||||
# Принятие нового фото для позиции
|
||||
@router.message((F.text == "0") | F.photo, StateFilter('here_position_edit_photo'))
|
||||
async def prod_position_edit_photo_get(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
position_id = (await state.get_data())['here_position_id']
|
||||
remover = (await state.get_data())['here_remover']
|
||||
|
||||
get_settings = await Settingsx().get()
|
||||
|
||||
if get_settings.misc_discord_webhook_url == "None":
|
||||
return await message.answer(
|
||||
"<b>🧿 Отсутствует Дискорд вебхук, добавьте его в настройках</b>"
|
||||
)
|
||||
|
||||
position_photo = "None"
|
||||
|
||||
if message.photo is not None:
|
||||
cache_message = await message.answer(
|
||||
"<b>♻️ Подождите, фотография загружается...</b>"
|
||||
)
|
||||
|
||||
file_path = (await bot.get_file(message.photo[-1].file_id)).file_path
|
||||
photo_path = await bot.download_file(file_path)
|
||||
|
||||
pay_image_status, pay_image_url = await (
|
||||
await DiscordAPI.connect(
|
||||
bot=bot,
|
||||
arSession=arSession,
|
||||
update=message,
|
||||
)
|
||||
).upload_photo(photo_path.read())
|
||||
|
||||
if pay_image_status:
|
||||
position_photo = pay_image_url
|
||||
|
||||
await del_message(cache_message)
|
||||
|
||||
await state.clear()
|
||||
|
||||
await Positionx().update(position_id, position_photo=position_photo)
|
||||
await position_open_admin(bot, position_id, message.from_user.id)
|
||||
|
||||
|
||||
# Выгрузка товаров
|
||||
@router.callback_query(F.data.startswith("position_edit_items:"))
|
||||
async def prod_position_edit_items(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
position_id = int(call.data.split(":")[1])
|
||||
remover = int(call.data.split(":")[2])
|
||||
|
||||
get_position = await Positionx().get_required(position_id=position_id)
|
||||
get_items = await Itemx().gets(position_id=position_id)
|
||||
|
||||
if len(get_items) >= 1:
|
||||
save_items = "\n\n".join([item.item_data for item in get_items])
|
||||
|
||||
link_items = await (
|
||||
await HostingAPI.connect(
|
||||
bot=bot,
|
||||
arSession=arSession,
|
||||
)
|
||||
).upload_text(save_items)
|
||||
|
||||
await call.message.answer(
|
||||
f"<b>🎁 Все товары позиции: <code>{get_position.position_name}</code>\n"
|
||||
f"🔗 Ссылка: <a href='{link_items}'>кликабельно</a></b>",
|
||||
reply_markup=close_finl(),
|
||||
disable_web_page_preview=True,
|
||||
)
|
||||
await call.answer(cache_time=5)
|
||||
else:
|
||||
await call.answer("❕ В данной позиции отсутствуют товары", True)
|
||||
|
||||
|
||||
# Удаление позиции
|
||||
@router.callback_query(F.data.startswith("position_edit_delete:"))
|
||||
async def prod_position_edit_delete(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
position_id = int(call.data.split(":")[1])
|
||||
remover = int(call.data.split(":")[2])
|
||||
|
||||
await del_message(call.message)
|
||||
|
||||
await call.message.answer(
|
||||
"<b>📁 Вы действительно хотите удалить позицию? ❌</b>",
|
||||
reply_markup=position_edit_delete_finl(position_id, remover),
|
||||
)
|
||||
|
||||
|
||||
# Подтверждение удаления позиции
|
||||
@router.callback_query(F.data.startswith("position_edit_delete_confirm:"))
|
||||
async def prod_position_edit_delete_confirm(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
position_id = int(call.data.split(":")[1])
|
||||
remover = int(call.data.split(":")[2])
|
||||
|
||||
get_position = await Positionx().get_required(position_id=position_id)
|
||||
get_positions = await Positionx().gets(category_id=get_position.category_id)
|
||||
|
||||
await Itemx().delete(position_id=position_id)
|
||||
await Positionx().delete(position_id=position_id)
|
||||
|
||||
await call.answer("📁 Вы успешно удалили позицию и её товары ✅")
|
||||
|
||||
if len(get_positions) >= 1:
|
||||
await call.message.edit_text(
|
||||
"<b>📁 Выберите позицию для изменения 🖍</b>",
|
||||
reply_markup=await position_edit_swipe_fp(remover, get_position.category_id),
|
||||
)
|
||||
else:
|
||||
await del_message(call.message)
|
||||
|
||||
|
||||
# Очистка позиции
|
||||
@router.callback_query(F.data.startswith("position_edit_clear:"))
|
||||
async def prod_position_edit_clear(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
position_id = int(call.data.split(":")[1])
|
||||
remover = int(call.data.split(":")[2])
|
||||
|
||||
await del_message(call.message)
|
||||
await call.message.answer(
|
||||
"<b>📁 Вы хотите удалить все товары в позиции?</b>",
|
||||
reply_markup=position_edit_clear_finl(position_id, remover),
|
||||
)
|
||||
|
||||
|
||||
# Согласие на очистку позиции
|
||||
@router.callback_query(F.data.startswith("position_edit_clear_confirm:"))
|
||||
async def prod_position_edit_clear_confirm(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
position_id = int(call.data.split(":")[1])
|
||||
remover = int(call.data.split(":")[2])
|
||||
|
||||
await Itemx().delete(position_id=position_id)
|
||||
await call.answer("📁 Вы успешно удалили все товары в позиции ✅")
|
||||
|
||||
await del_message(call.message)
|
||||
await position_open_admin(bot, position_id, call.from_user.id)
|
||||
|
||||
|
||||
################################################################################
|
||||
############################### ДОБАВЛЕНИЕ ТОВАРОВ #############################
|
||||
# Страницы выбора категории для добавления товара
|
||||
@router.callback_query(F.data.startswith("item_add_category_swipe:"))
|
||||
async def prod_item_add_category_swipe(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
remover = int(call.data.split(":")[1])
|
||||
|
||||
await call.message.edit_text(
|
||||
"<b>🎁 Выберите позицию для товаров ➕</b>",
|
||||
reply_markup=await item_add_category_swipe_fp(remover),
|
||||
)
|
||||
|
||||
|
||||
# Открытие категории для выбора позиции
|
||||
@router.callback_query(F.data.startswith("item_add_category_open:"))
|
||||
async def prod_item_add_category_open(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
category_id = int(call.data.split(":")[1])
|
||||
remover = int(call.data.split(":")[2])
|
||||
|
||||
get_category = await Categoryx().get_required(category_id=category_id)
|
||||
get_positions = await Positionx().gets(category_id=category_id)
|
||||
|
||||
await del_message(call.message)
|
||||
|
||||
if len(get_positions) >= 1:
|
||||
await call.message.answer(
|
||||
"<b>🎁 Выберите позицию для товаров ➕</b>",
|
||||
reply_markup=await item_add_position_swipe_fp(0, category_id),
|
||||
)
|
||||
else:
|
||||
await call.answer(f"🎁 Позиции в категории {get_category.category_name} отсутствуют")
|
||||
|
||||
|
||||
# Страницы выбора позиции для добавления товара
|
||||
@router.callback_query(F.data.startswith("item_add_position_swipe:"))
|
||||
async def prod_item_add_position_swipe(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
category_id = int(call.data.split(":")[1])
|
||||
remover = int(call.data.split(":")[2])
|
||||
|
||||
await call.message.edit_text(
|
||||
"<b>🎁 Выберите позицию для товаров ➕</b>",
|
||||
reply_markup=await item_add_position_swipe_fp(remover, category_id),
|
||||
)
|
||||
|
||||
|
||||
# Выбор позиции для добавления товаров
|
||||
@router.callback_query(F.data.startswith("item_add_position_open:"), flags={'rate': 0})
|
||||
async def prod_item_add_position_open(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
position_id = int(call.data.split(":")[1])
|
||||
|
||||
get_position = await Positionx().get_required(position_id=position_id)
|
||||
get_settings = await Settingsx().get()
|
||||
|
||||
await state.update_data(here_add_item_category_id=get_position.category_id)
|
||||
await state.update_data(here_add_item_position_id=get_position.position_id)
|
||||
await state.update_data(here_add_item_count=0)
|
||||
await state.set_state("here_add_items")
|
||||
|
||||
await del_message(call.message)
|
||||
|
||||
if get_settings.misc_method_prod == "skip":
|
||||
await call.message.answer(
|
||||
ded(f"""
|
||||
<b>🎁 Отправляйте данные товаров</b>
|
||||
❗ Товары разделяются одной пустой строчкой. Пример:
|
||||
<code>Данные товара...
|
||||
|
||||
Данные товара...
|
||||
|
||||
Данные товара...</code>
|
||||
"""),
|
||||
reply_markup=item_add_finish_finl(position_id),
|
||||
)
|
||||
else:
|
||||
await call.message.answer(
|
||||
ded(f"""
|
||||
<b>🎁 Отправляйте данные товаров</b>
|
||||
❗ Товары каждой новой строчкой. Пример:
|
||||
<code>Данные товара...
|
||||
Данные товара...
|
||||
Данные товара...</code>
|
||||
"""),
|
||||
reply_markup=item_add_finish_finl(position_id),
|
||||
)
|
||||
|
||||
|
||||
# Завершение загрузки товаров
|
||||
@router.callback_query(F.data.startswith('item_add_position_finish:'), flags={'rate': 0})
|
||||
async def prod_item_add_finish(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
position_id = int(call.data.split(":")[1])
|
||||
|
||||
try:
|
||||
count_items = (await state.get_data())['here_add_item_count']
|
||||
except Exception:
|
||||
bot_logger.debug("В state нет счетчика добавленных товаров", exc_info=True)
|
||||
count_items = 0
|
||||
|
||||
await state.clear()
|
||||
|
||||
await call.message.edit_reply_markup()
|
||||
await call.message.answer(
|
||||
"<b>🎁 Загрузка товаров была успешно завершена ✅\n"
|
||||
f"❕ Загружено товаров: <code>{count_items}шт</code></b>",
|
||||
)
|
||||
|
||||
await position_open_admin(bot, position_id, call.from_user.id)
|
||||
|
||||
|
||||
# Принятие данных товара
|
||||
@router.message(F.text, StateFilter('here_add_items'), flags={'rate': 0})
|
||||
async def prod_item_add_get(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
cache_message = await message.answer("<b>⌛ Ждите, товары добавляются..</b>")
|
||||
|
||||
get_settings = await Settingsx().get()
|
||||
|
||||
if get_settings.misc_method_prod == "skip":
|
||||
get_items = clear_list(message.text.split("\n\n"))
|
||||
else:
|
||||
get_items = clear_list(message.text.split("\n"))
|
||||
|
||||
item_count = (await state.get_data())['here_add_item_count']
|
||||
category_id = (await state.get_data())['here_add_item_category_id']
|
||||
position_id = (await state.get_data())['here_add_item_position_id']
|
||||
|
||||
await state.update_data(here_add_item_count=item_count + len(get_items))
|
||||
|
||||
await Itemx().add(
|
||||
user_id=message.from_user.id,
|
||||
category_id=category_id,
|
||||
position_id=position_id,
|
||||
item_datas=get_items,
|
||||
)
|
||||
|
||||
await cache_message.edit_text(
|
||||
f"<b>🎁 Товары в кол-ве <u>{len(get_items)}шт</u> были успешно добавлены ✅</b>",
|
||||
reply_markup=item_add_finish_finl(position_id),
|
||||
)
|
||||
|
||||
|
||||
################################################################################
|
||||
############################### УДАЛЕНИЕ ТОВАРОВ ###############################
|
||||
# Страницы удаления товаров
|
||||
@router.callback_query(F.data.startswith("item_delete_swipe:"))
|
||||
async def prod_item_delete_swipe(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
position_id = int(call.data.split(":")[1])
|
||||
remover = int(call.data.split(":")[2])
|
||||
|
||||
get_items = await Itemx().gets(position_id=position_id)
|
||||
get_position = await Positionx().get_required(position_id=position_id)
|
||||
|
||||
if len(get_items) >= 1:
|
||||
await del_message(call.message)
|
||||
|
||||
await call.message.answer(
|
||||
"<b>🎁 Выберите товар для удаления</b>",
|
||||
reply_markup=await item_delete_swipe_fp(remover, position_id),
|
||||
)
|
||||
else:
|
||||
await call.answer(f"🎁 Товары в позиции {get_position.position_name} отсутствуют", True)
|
||||
|
||||
|
||||
# Удаление товара
|
||||
@router.callback_query(F.data.startswith("item_delete_open:"))
|
||||
async def prod_item_delete_open(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
item_id = int(call.data.split(":")[1])
|
||||
|
||||
await del_message(call.message)
|
||||
await item_open_admin(bot, item_id, call.from_user.id)
|
||||
|
||||
|
||||
# Подтверждение удаления товара
|
||||
@router.callback_query(F.data.startswith("item_delete_confirm:"))
|
||||
async def prod_item_delete_confirm_open(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
item_id = int(call.data.split(":")[1])
|
||||
|
||||
get_item = await Itemx().get_required(item_id=item_id)
|
||||
get_items = await Itemx().gets(position_id=get_item.position_id)
|
||||
|
||||
await Itemx().delete(item_id=item_id)
|
||||
|
||||
await call.message.edit_reply_markup()
|
||||
await call.message.react([ReactionTypeEmoji(emoji="🔥")])
|
||||
|
||||
if len(get_items) >= 1:
|
||||
await call.message.answer(
|
||||
"<b>🎁 Выберите товар для удаления</b>",
|
||||
reply_markup=await item_delete_swipe_fp(0, get_item.position_id),
|
||||
)
|
||||
|
||||
|
||||
################################################################################
|
||||
############################### УДАЛЕНИЕ РАЗДЕЛОВ ##############################
|
||||
# Возвращение к меню удаления разделов
|
||||
@router.callback_query(F.data == "prod_removes_return")
|
||||
async def prod_removes_return(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await call.message.edit_text(
|
||||
"<b>🎁 Выберите раздел который хотите удалить ❌</b>\n",
|
||||
reply_markup=products_removes_finl(),
|
||||
)
|
||||
|
||||
|
||||
# Удаление всех категорий
|
||||
@router.callback_query(F.data == "prod_removes_categories")
|
||||
async def prod_removes_categories(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
get_categories = len(await Categoryx().get_all())
|
||||
get_positions = len(await Positionx().get_all())
|
||||
get_items = len(await Itemx().get_all())
|
||||
|
||||
await call.message.edit_text(
|
||||
ded(f"""
|
||||
<b>❌ Вы действительно хотите удалить все категории, позиции и товары?</b>
|
||||
🗃 Категорий: <code>{get_categories}шт</code>
|
||||
📁 Позиций: <code>{get_positions}шт</code>
|
||||
🎁 Товаров: <code>{get_items}шт</code>
|
||||
"""),
|
||||
reply_markup=products_removes_categories_finl(),
|
||||
)
|
||||
|
||||
|
||||
# Подтверждение удаления всех категорий (позиций и товаров включительно)
|
||||
@router.callback_query(F.data == "prod_removes_categories_confirm")
|
||||
async def prod_removes_categories_confirm(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
get_categories = len(await Categoryx().get_all())
|
||||
get_positions = len(await Positionx().get_all())
|
||||
get_items = len(await Itemx().get_all())
|
||||
|
||||
await Categoryx().clear()
|
||||
await Positionx().clear()
|
||||
await Itemx().clear()
|
||||
|
||||
await call.message.edit_text(
|
||||
ded(f"""
|
||||
<b>✅ Вы успешно удалили все категории</b>
|
||||
🗃 Категорий: <code>{get_categories}шт</code>
|
||||
📁 Позиций: <code>{get_positions}шт</code>
|
||||
🎁 Товаров: <code>{get_items}шт</code>
|
||||
""")
|
||||
)
|
||||
|
||||
|
||||
# Удаление всех позиций
|
||||
@router.callback_query(F.data == "prod_removes_positions")
|
||||
async def prod_removes_positions(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
get_positions = len(await Positionx().get_all())
|
||||
get_items = len(await Itemx().get_all())
|
||||
|
||||
await call.message.edit_text(
|
||||
ded(f"""
|
||||
<b>❌ Вы действительно хотите удалить все позиции и товары?</b>
|
||||
📁 Позиций: <code>{get_positions}шт</code>
|
||||
🎁 Товаров: <code>{get_items}шт</code>
|
||||
"""),
|
||||
reply_markup=products_removes_positions_finl(),
|
||||
)
|
||||
|
||||
|
||||
# Подтверждение удаления всех позиций (товаров включительно)
|
||||
@router.callback_query(F.data == "prod_removes_positions_confirm")
|
||||
async def prod_position_remove(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
get_positions = len(await Positionx().get_all())
|
||||
get_items = len(await Itemx().get_all())
|
||||
|
||||
await Positionx().clear()
|
||||
await Itemx().clear()
|
||||
|
||||
await call.message.edit_text(
|
||||
ded(f"""
|
||||
<b>✅ Вы успешно удалили все позиции</b>
|
||||
📁 Позиций: <code>{get_positions}шт</code>
|
||||
🎁 Товаров: <code>{get_items}шт</code>
|
||||
""")
|
||||
)
|
||||
|
||||
|
||||
# Удаление всех товаров
|
||||
@router.callback_query(F.data == "prod_removes_items")
|
||||
async def prod_removes_items(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
get_items = len(await Itemx().get_all())
|
||||
|
||||
await call.message.edit_text(
|
||||
f"<b>❌ Вы действительно хотите удалить все товары?</b>\n"
|
||||
f"🎁 Товаров: <code>{get_items}шт</code>",
|
||||
reply_markup=products_removes_items_finl(),
|
||||
)
|
||||
|
||||
|
||||
# Согласие на удаление всех товаров
|
||||
@router.callback_query(F.data == "prod_removes_items_confirm")
|
||||
async def prod_item_remove(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
get_items = len(await Itemx().get_all())
|
||||
|
||||
await Itemx().clear()
|
||||
|
||||
await call.message.edit_text(
|
||||
f"<b>✅ Вы успешно удалили все товары</b>\n"
|
||||
f"🎁 Товаров: <code>{get_items}шт</code>"
|
||||
)
|
||||
@@ -0,0 +1,376 @@
|
||||
# - *- coding: utf- 8 - *-
|
||||
from aiogram import Router, Bot, F
|
||||
from aiogram.filters import StateFilter
|
||||
from aiogram.types import CallbackQuery, Message
|
||||
|
||||
from tgbot.database import Settingsx, Userx
|
||||
from tgbot.keyboards.inline_admin import settings_status_finl, settings_finl
|
||||
from tgbot.services.api_discord import DiscordDJ, DiscordAPI
|
||||
from tgbot.utils.const_functions import ded
|
||||
from tgbot.utils.misc.bot_logging import bot_logger
|
||||
from tgbot.utils.misc.bot_models import FSM, ARS
|
||||
from tgbot.utils.misc_functions import send_admins, insert_tags
|
||||
|
||||
router = Router(name=__name__)
|
||||
|
||||
|
||||
# Изменение данных
|
||||
@router.message(F.text == "🖍 Изменить данные")
|
||||
async def settings_data_edit(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await message.answer(
|
||||
"<b>🖍 Изменение данных бота</b>",
|
||||
reply_markup=await settings_finl(),
|
||||
)
|
||||
|
||||
|
||||
# Выключатели бота
|
||||
@router.message(F.text == "🕹 Выключатели")
|
||||
async def settings_status_edit(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await message.answer(
|
||||
"<b>🕹 Включение и выключение основных функций</b>",
|
||||
reply_markup=await settings_status_finl(),
|
||||
)
|
||||
|
||||
|
||||
################################################################################
|
||||
################################## ВЫКЛЮЧАТЕЛИ #################################
|
||||
# Включение/выключение тех работ
|
||||
@router.callback_query(F.data.startswith("settings_status_work:"))
|
||||
async def settings_status_work(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
get_status = call.data.split(":")[1]
|
||||
|
||||
get_user = await Userx().get_required(user_id=call.from_user.id)
|
||||
await Settingsx().update(status_work=get_status)
|
||||
|
||||
if get_status == "True":
|
||||
send_text = "🔴 Отправил бота на технические работы"
|
||||
else:
|
||||
send_text = "🟢 Вывел бота из технических работ"
|
||||
|
||||
await send_admins(
|
||||
bot=bot,
|
||||
text=ded(f"""
|
||||
👤 Администратор <a href='tg://user?id={get_user.user_id}'>{get_user.user_name}</a>
|
||||
{send_text}
|
||||
"""),
|
||||
not_me=get_user.user_id,
|
||||
)
|
||||
|
||||
await call.message.edit_reply_markup(reply_markup=await settings_status_finl())
|
||||
|
||||
|
||||
# Включение/выключение покупок
|
||||
@router.callback_query(F.data.startswith("settings_status_buy:"))
|
||||
async def settings_status_buy(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
get_status = call.data.split(":")[1]
|
||||
|
||||
get_user = await Userx().get_required(user_id=call.from_user.id)
|
||||
await Settingsx().update(status_buy=get_status)
|
||||
|
||||
if get_status == "True":
|
||||
send_text = "🟢 Включил покупки в боте"
|
||||
else:
|
||||
send_text = "🔴 Выключил покупки в боте"
|
||||
|
||||
await send_admins(
|
||||
bot=bot,
|
||||
text=ded(f"""
|
||||
👤 Администратор <a href='tg://user?id={get_user.user_id}'>{get_user.user_name}</a>
|
||||
{send_text}
|
||||
"""),
|
||||
not_me=get_user.user_id,
|
||||
)
|
||||
|
||||
await call.message.edit_reply_markup(reply_markup=await settings_status_finl())
|
||||
|
||||
|
||||
# Включение/выключение пополнений
|
||||
@router.callback_query(F.data.startswith("settings_status_refill:"))
|
||||
async def settings_status_refill(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
get_status = call.data.split(":")[1]
|
||||
|
||||
get_user = await Userx().get_required(user_id=call.from_user.id)
|
||||
await Settingsx().update(status_refill=get_status)
|
||||
|
||||
if get_status == "True":
|
||||
send_text = "🟢 Включил пополнения в боте"
|
||||
else:
|
||||
send_text = "🔴 Выключил пополнения в боте"
|
||||
|
||||
await send_admins(
|
||||
bot,
|
||||
f"👤 Администратор <a href='tg://user?id={get_user.user_id}'>{get_user.user_name}</a>\n"
|
||||
f"{send_text}",
|
||||
not_me=get_user.user_id,
|
||||
)
|
||||
|
||||
await call.message.edit_reply_markup(reply_markup=await settings_status_finl())
|
||||
|
||||
|
||||
# Включение/выключение уведомлений о покупках
|
||||
@router.callback_query(F.data.startswith("settings_notification_buy:"))
|
||||
async def settings_notification_buy(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
get_status = call.data.split(":")[1]
|
||||
|
||||
get_user = await Userx().get_required(user_id=call.from_user.id)
|
||||
await Settingsx().update(notification_buy=get_status)
|
||||
|
||||
if get_status == "True":
|
||||
send_text = "🟢 Включил уведомления о покупках в боте"
|
||||
else:
|
||||
send_text = "🔴 Выключил уведомления о покупках в боте"
|
||||
|
||||
await send_admins(
|
||||
bot,
|
||||
f"👤 Администратор <a href='tg://user?id={get_user.user_id}'>{get_user.user_name}</a>\n"
|
||||
f"{send_text}",
|
||||
not_me=get_user.user_id,
|
||||
)
|
||||
|
||||
await call.message.edit_reply_markup(reply_markup=await settings_status_finl())
|
||||
|
||||
|
||||
# Включение/выключение уведомлений о пополнениях
|
||||
@router.callback_query(F.data.startswith("settings_notification_refill:"))
|
||||
async def settings_notification_refill(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
get_status = call.data.split(":")[1]
|
||||
|
||||
get_user = await Userx().get_required(user_id=call.from_user.id)
|
||||
await Settingsx().update(notification_refill=get_status)
|
||||
|
||||
if get_status == "True":
|
||||
send_text = "🟢 Включил уведомления о пополнениях в боте"
|
||||
else:
|
||||
send_text = "🔴 Выключил уведомления о пополнениях в боте"
|
||||
|
||||
await send_admins(
|
||||
bot,
|
||||
f"👤 Администратор <a href='tg://user?id={get_user.user_id}'>{get_user.user_name}</a>\n"
|
||||
f"{send_text}",
|
||||
not_me=get_user.user_id,
|
||||
)
|
||||
|
||||
await call.message.edit_reply_markup(reply_markup=await settings_status_finl())
|
||||
|
||||
|
||||
################################################################################
|
||||
############################### ИЗМЕНЕНИЕ ДАННЫХ ###############################
|
||||
# Изменение FAQ
|
||||
@router.callback_query(F.data == "settings_edit_faq")
|
||||
async def settings_faq_edit(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await state.set_state("here_settings_faq")
|
||||
await call.message.edit_text(
|
||||
ded("""
|
||||
<b>❔ Введите новый текст для FAQ</b>
|
||||
❕ Вы можете использовать заготовленный синтаксис и HTML разметку:
|
||||
▪️ <code>{username}</code> - логин пользоваля
|
||||
▪️ <code>{user_id}</code> - айди пользователя
|
||||
▪️ <code>{firstname}</code> - имя пользователя
|
||||
""")
|
||||
)
|
||||
|
||||
|
||||
# Изменение поддержки
|
||||
@router.callback_query(F.data == "settings_edit_support")
|
||||
async def settings_support_edit(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await state.set_state("here_settings_support")
|
||||
await call.message.edit_text(
|
||||
"<b>☎️ Отправьте юзернейм для поддержки</b>\n"
|
||||
"❕ Юзернейм пользователя/бота/канала/чата",
|
||||
)
|
||||
|
||||
|
||||
# Изменение отображения/скрытия категорий без товаров
|
||||
@router.callback_query(F.data.startswith("settings_edit_hide_category:"))
|
||||
async def settings_edit_hide_category(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
status = call.data.split(":")[1]
|
||||
|
||||
await Settingsx().update(misc_hide_category=status)
|
||||
|
||||
await call.message.edit_text(
|
||||
"<b>🖍 Изменение данных бота</b>",
|
||||
reply_markup=await settings_finl(),
|
||||
)
|
||||
|
||||
|
||||
# Изменение отображения/скрытия позиций без товаров
|
||||
@router.callback_query(F.data.startswith("settings_edit_hide_position:"))
|
||||
async def settings_edit_hide_position(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
status = call.data.split(":")[1]
|
||||
|
||||
await Settingsx().update(misc_hide_position=status)
|
||||
|
||||
await call.message.edit_text(
|
||||
"<b>🖍 Изменение данных бота</b>",
|
||||
reply_markup=await settings_finl(),
|
||||
)
|
||||
|
||||
|
||||
# Изменение метода добавления товаров
|
||||
@router.callback_query(F.data.startswith("settings_edit_method_prod:"))
|
||||
async def settings_edit_method_prod(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
method = call.data.split(":")[1]
|
||||
|
||||
await Settingsx().update(misc_method_prod=method)
|
||||
|
||||
await call.message.edit_text(
|
||||
"<b>🖍 Изменение данных бота</b>",
|
||||
reply_markup=await settings_finl(),
|
||||
)
|
||||
|
||||
|
||||
# Изменение дискорд вебхука
|
||||
@router.callback_query(F.data == "settings_edit_discord_webhook")
|
||||
async def settings_discord_edit(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
get_discord_public_webhook = await (
|
||||
DiscordDJ(
|
||||
arSession=arSession,
|
||||
bot=bot,
|
||||
)
|
||||
).export_webhook()
|
||||
|
||||
await state.set_state("here_settings_discord_webhook")
|
||||
await call.message.edit_text(
|
||||
ded(f"""
|
||||
<b>🧿 Отправьте новый вебхук дискорда</b>
|
||||
❕ Для удаления вебхука введите <code>0</code>
|
||||
❕ Вы можете использовать публичный вебхук, но ответственность за его использование лежит только на вас
|
||||
▪️ Публичный вебхук: <code>{get_discord_public_webhook}</code>
|
||||
""")
|
||||
)
|
||||
|
||||
|
||||
# Изменение текстового хостинга по умолчанию
|
||||
@router.callback_query(F.data == "settings_edit_hosting_text")
|
||||
async def settings_edit_hosting_text(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
get_settings = await Settingsx().get()
|
||||
|
||||
if get_settings.misc_hosting_text == "telegraph":
|
||||
await Settingsx().update(misc_hosting_text="pastie")
|
||||
elif get_settings.misc_hosting_text == "pastie":
|
||||
await Settingsx().update(misc_hosting_text="friendpaste")
|
||||
elif get_settings.misc_hosting_text == "friendpaste":
|
||||
await Settingsx().update(misc_hosting_text="snippet")
|
||||
elif get_settings.misc_hosting_text == "snippet":
|
||||
await Settingsx().update(misc_hosting_text="telegraph")
|
||||
|
||||
await call.message.edit_text(
|
||||
"<b>🖍 Изменение данных бота</b>",
|
||||
reply_markup=await settings_finl(),
|
||||
)
|
||||
|
||||
|
||||
################################################################################
|
||||
################################ ПРИНЯТИЕ ДАННЫХ ###############################
|
||||
# Принятие FAQ
|
||||
@router.message(F.text, StateFilter("here_settings_faq"))
|
||||
async def settings_faq_get(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
get_message = await insert_tags(message.from_user.id, message.text)
|
||||
|
||||
try:
|
||||
await (await message.answer(get_message)).delete()
|
||||
except Exception:
|
||||
bot_logger.debug("Некорректная HTML-разметка FAQ", exc_info=True)
|
||||
return await message.answer(
|
||||
"<b>❌ Ошибка синтаксиса HTML</b>\n"
|
||||
"❔ Введите новый текст для FAQ",
|
||||
)
|
||||
|
||||
await state.clear()
|
||||
await Settingsx().update(misc_faq=message.text)
|
||||
|
||||
await message.answer(
|
||||
"<b>🖍 Изменение данных бота</b>",
|
||||
reply_markup=await settings_finl(),
|
||||
)
|
||||
|
||||
|
||||
# Принятие поддержки
|
||||
@router.message(F.text, StateFilter("here_settings_support"))
|
||||
async def settings_support_get(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
get_support = message.text
|
||||
|
||||
if get_support.startswith("@"):
|
||||
get_support = get_support[1:]
|
||||
|
||||
await Settingsx().update(misc_support=get_support)
|
||||
await state.clear()
|
||||
|
||||
await message.answer(
|
||||
"<b>🖍 Изменение данных бота</b>",
|
||||
reply_markup=await settings_finl(),
|
||||
)
|
||||
|
||||
|
||||
# Принятие дискорд вебхука
|
||||
@router.message(F.text, StateFilter("here_settings_discord_webhook"))
|
||||
async def settings_discord_get(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
get_discord_webhook = message.text
|
||||
|
||||
# Удаление вебхука
|
||||
if get_discord_webhook == "0":
|
||||
await Settingsx().update(
|
||||
misc_discord_webhook_url="None",
|
||||
misc_discord_webhook_name="None",
|
||||
)
|
||||
|
||||
return await message.answer(
|
||||
"<b>⚙️ Настройки бота</b>",
|
||||
reply_markup=await settings_finl(),
|
||||
)
|
||||
|
||||
# Добавление нового вебхука
|
||||
cache_message = await message.answer("<b>♻️ Проверка дискорд вебхука..</b>")
|
||||
|
||||
if "api" in get_discord_webhook and "webhooks" in get_discord_webhook:
|
||||
discord_webhook_status, discord_webhook_name = await (
|
||||
await DiscordAPI.connect(
|
||||
bot=bot,
|
||||
arSession=arSession,
|
||||
update=message,
|
||||
webhook_url=get_discord_webhook,
|
||||
skipping_error=True,
|
||||
)
|
||||
).check()
|
||||
|
||||
if discord_webhook_status:
|
||||
await state.clear()
|
||||
|
||||
await Settingsx().update(
|
||||
misc_discord_webhook_url=message.text,
|
||||
misc_discord_webhook_name=discord_webhook_name,
|
||||
)
|
||||
|
||||
return await cache_message.edit_text(
|
||||
"<b>⚙️ Настройки бота</b>",
|
||||
reply_markup=await settings_finl(),
|
||||
)
|
||||
|
||||
# Обработка ошибки добавления вебхука
|
||||
get_discord_public_webhook = await (
|
||||
DiscordDJ(
|
||||
arSession=arSession,
|
||||
bot=bot,
|
||||
)
|
||||
).export_webhook()
|
||||
|
||||
await cache_message.edit_text(
|
||||
ded(f"""
|
||||
<b>❌ Указан некорректный вебхук</b>
|
||||
➖➖➖➖➖➖➖➖➖➖
|
||||
🧿 Отправьте новый вебхук дискорда
|
||||
❕ Для удаления вебхука введите <code>0</code>
|
||||
❕ Вы можете использовать публичный вебхук, но ответственность за его использование лежит только на вас
|
||||
▪️ Публичный вебхук: <code>{get_discord_public_webhook}</code>
|
||||
""")
|
||||
)
|
||||
@@ -0,0 +1,35 @@
|
||||
# - *- coding: utf- 8 - *-
|
||||
from aiogram import Router
|
||||
from aiogram.filters import ExceptionMessageFilter
|
||||
from aiogram.handlers import ErrorHandler
|
||||
|
||||
from tgbot.utils.misc.bot_logging import bot_logger
|
||||
|
||||
router = Router(name=__name__)
|
||||
|
||||
|
||||
# Игнорирование повторного редактирования без падения handler-а
|
||||
@router.errors(ExceptionMessageFilter(
|
||||
"Bad Request: message is not modified: specified new message content and reply markup are exactly the same as a current content and reply markup of the message")
|
||||
)
|
||||
class MessageNotModifiedHandler(ErrorHandler):
|
||||
# Debug-запись о повторном edit
|
||||
async def handle(self):
|
||||
bot_logger.debug(
|
||||
"Телеграм отказал в повторном редактировании сообщения: %s",
|
||||
self.exception_message,
|
||||
exc_info=True,
|
||||
)
|
||||
|
||||
|
||||
# Логирование всех ошибок, которые дошли до aiogram error router
|
||||
@router.errors()
|
||||
class UnknownErrorHandler(ErrorHandler):
|
||||
# Запись traceback неизвестной ошибки
|
||||
async def handle(self):
|
||||
bot_logger.error(
|
||||
"Ошибка handler-а: %s | %s",
|
||||
self.exception_name,
|
||||
self.exception_message,
|
||||
exc_info=True,
|
||||
)
|
||||
@@ -0,0 +1,37 @@
|
||||
# - *- coding: utf- 8 - *-
|
||||
from aiogram import Router, Bot, F
|
||||
from aiogram.types import CallbackQuery, Message
|
||||
|
||||
from tgbot.utils.const_functions import del_message, ded
|
||||
from tgbot.utils.misc.bot_models import FSM, ARS
|
||||
|
||||
router = Router(name=__name__)
|
||||
|
||||
|
||||
# Колбэк с удалением сообщения
|
||||
@router.callback_query(F.data == "close_this")
|
||||
async def main_missed_callback_close(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
await del_message(call.message)
|
||||
|
||||
|
||||
# Колбэк с обработкой кнопки
|
||||
@router.callback_query(F.data == "...")
|
||||
async def main_missed_callback_answer(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
await call.answer(cache_time=30)
|
||||
|
||||
|
||||
# Обработка всех колбэков которые потеряли стейты после перезапуска скрипта
|
||||
@router.callback_query()
|
||||
async def main_missed_callback(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
await call.answer("❗️ Кнопка недействительна. Повторите действия заново", True)
|
||||
|
||||
|
||||
# Обработка всех неизвестных команд
|
||||
@router.message()
|
||||
async def main_missed_message(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await message.answer(
|
||||
ded(f"""
|
||||
♦️ Неизвестная команда
|
||||
♦️ Введите /start
|
||||
"""),
|
||||
)
|
||||
@@ -0,0 +1,146 @@
|
||||
# - *- coding: utf- 8 - *-
|
||||
from aiogram import Router, Bot, F
|
||||
from aiogram.filters import StateFilter
|
||||
from aiogram.types import Message, CallbackQuery
|
||||
|
||||
from tgbot.database import Settingsx, Positionx, Categoryx
|
||||
from tgbot.keyboards.inline_user import user_support_finl
|
||||
from tgbot.keyboards.inline_user_page import prod_item_position_swipe_fp
|
||||
from tgbot.keyboards.reply_main import menu_frep
|
||||
from tgbot.utils.const_functions import ded
|
||||
from tgbot.utils.misc.bot_filters import IsBuy, IsRefill, IsWork
|
||||
from tgbot.utils.misc.bot_models import FSM, ARS
|
||||
from tgbot.utils.text_functions import position_open_user
|
||||
|
||||
# Игнор-колбэки покупок
|
||||
prohibit_buy = (
|
||||
'buy_category_swipe',
|
||||
'buy_category_open',
|
||||
'buy_position_swipe',
|
||||
'buy_position_open',
|
||||
'buy_item_open',
|
||||
'buy_item_confirm',
|
||||
)
|
||||
|
||||
# Игнор-колбэки пополнений
|
||||
prohibit_refill = (
|
||||
'user_refill',
|
||||
'user_refill_method',
|
||||
'Pay:Cryptobot',
|
||||
'Pay:Yoomoney',
|
||||
'Pay:',
|
||||
)
|
||||
|
||||
router = Router(name=__name__)
|
||||
|
||||
|
||||
################################################################################
|
||||
########################### СТАТУС ТЕХНИЧЕСКИХ РАБОТ ###########################
|
||||
# Фильтр на технические работы - сообщение
|
||||
@router.message(IsWork())
|
||||
async def filter_work_message(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
get_settings = await Settingsx().get()
|
||||
|
||||
if get_settings.misc_support != "None":
|
||||
return await message.answer(
|
||||
"<b>⛔ Бот находится на технических работах</b>",
|
||||
reply_markup=user_support_finl(get_settings.misc_support),
|
||||
)
|
||||
|
||||
await message.answer("<b>⛔ Бот находится на технических работах</b>")
|
||||
|
||||
|
||||
# Фильтр на технические работы - колбэк
|
||||
@router.callback_query(IsWork())
|
||||
async def filter_work_callback(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await call.answer("⛔ Бот находится на технических работах.", True)
|
||||
|
||||
|
||||
################################################################################
|
||||
################################# СТАТУС ПОКУПОК ###############################
|
||||
# Фильтр на доступность покупок - сообщение
|
||||
@router.message(IsBuy(), F.text == "🎁 Купить")
|
||||
@router.message(IsBuy(), StateFilter('here_item_count'))
|
||||
async def filter_buy_message(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await message.answer("<b>⛔ Покупки временно отключены</b>")
|
||||
|
||||
|
||||
# Фильтр на доступность покупок - колбэк
|
||||
@router.callback_query(IsBuy(), F.data.startswith(prohibit_buy))
|
||||
async def filter_buy_callback(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await call.answer("⛔ Покупки временно отключены.", True)
|
||||
|
||||
|
||||
################################################################################
|
||||
############################### СТАТУС ПОПОЛНЕНИЙ ##############################
|
||||
# Фильтр на доступность пополнения - сообщение
|
||||
@router.message(IsRefill(), StateFilter('here_refill_amount'))
|
||||
async def filter_refill_message(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await message.answer("<b>⛔ Пополнение временно отключено</b>")
|
||||
|
||||
|
||||
# Фильтр на доступность пополнения - колбэк
|
||||
@router.callback_query(IsRefill(), F.data.startswith(prohibit_refill))
|
||||
async def filter_refill_callback(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await call.answer("⛔ Пополнение временно отключено.", True)
|
||||
|
||||
|
||||
################################################################################
|
||||
#################################### ПРОЧЕЕ ####################################
|
||||
# Открытие главного меню
|
||||
@router.message(F.text.in_(('🔙 Главное меню', '/start')))
|
||||
async def main_start(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await message.answer(
|
||||
ded("""
|
||||
🔸 Бот готов к использованию.
|
||||
🔸 Если не появились вспомогательные кнопки
|
||||
🔸 Введите /start
|
||||
"""),
|
||||
reply_markup=menu_frep(message.from_user.id),
|
||||
)
|
||||
|
||||
|
||||
# Открытие диплинков
|
||||
@router.message(F.text.startswith('/start '))
|
||||
async def main_start_deeplink(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
deepling_args = message.text[7:]
|
||||
|
||||
if deepling_args.startswith("p_"):
|
||||
position_id_raw = deepling_args[2:]
|
||||
|
||||
if not position_id_raw.isdigit():
|
||||
return
|
||||
|
||||
position_id = int(position_id_raw)
|
||||
get_position = await Positionx().get(position_id=position_id)
|
||||
|
||||
if get_position is not None:
|
||||
await position_open_user(bot, message.from_user.id, position_id, 0)
|
||||
elif deepling_args.startswith("c_"):
|
||||
category_id_raw = deepling_args[2:]
|
||||
|
||||
if not category_id_raw.isdigit():
|
||||
return
|
||||
|
||||
category_id = int(category_id_raw)
|
||||
get_category = await Categoryx().get(category_id=category_id)
|
||||
|
||||
if get_category is not None:
|
||||
await message.answer(
|
||||
f"<b>🎁 Текущая категория: <code>{get_category.category_name}</code></b>",
|
||||
reply_markup=await prod_item_position_swipe_fp(0, category_id),
|
||||
)
|
||||
@@ -0,0 +1,187 @@
|
||||
# - *- coding: utf- 8 - *-
|
||||
import asyncio
|
||||
|
||||
from aiogram import Router, Bot, F
|
||||
from aiogram.filters import Command
|
||||
from aiogram.types import CallbackQuery, Message
|
||||
|
||||
from tgbot.data.config import BOT_VERSION, get_text_desc, get_text_warning
|
||||
from tgbot.database import Purchasesx, Settingsx
|
||||
from tgbot.keyboards.inline_user import user_support_finl
|
||||
from tgbot.keyboards.inline_user_page import *
|
||||
from tgbot.services.api_hosting_text import HostingAPI
|
||||
from tgbot.utils.const_functions import ded, del_message, convert_date
|
||||
from tgbot.utils.misc.bot_models import FSM, ARS
|
||||
from tgbot.utils.misc_functions import insert_tags
|
||||
from tgbot.utils.products_functions import get_items_available
|
||||
from tgbot.utils.text_functions import open_profile_user
|
||||
|
||||
router = Router(name=__name__)
|
||||
|
||||
|
||||
# Открытие товаров
|
||||
@router.message(F.text == "🎁 Купить")
|
||||
async def user_shop(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
get_categories = await get_categories_items()
|
||||
|
||||
if len(get_categories) >= 1:
|
||||
await message.answer(
|
||||
"<b>🎁 Выберите нужный вам товар</b>",
|
||||
reply_markup=await prod_item_category_swipe_fp(0),
|
||||
)
|
||||
else:
|
||||
await message.answer("<b>🎁 Увы, товары в данное время отсутствуют</b>")
|
||||
|
||||
|
||||
# Открытие профиля
|
||||
@router.message(F.text == "👤 Профиль")
|
||||
async def user_profile(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await open_profile_user(bot, message.from_user.id)
|
||||
|
||||
|
||||
# Проверка товаров в наличии
|
||||
@router.message(F.text == "🧮 Наличие товаров")
|
||||
async def user_available(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
items_available, remover_max, remover_now = await get_items_available(0)
|
||||
|
||||
if len(items_available) >= 1:
|
||||
await message.answer(
|
||||
items_available,
|
||||
reply_markup=prod_available_swipe_fp(remover_now, remover_max),
|
||||
)
|
||||
else:
|
||||
await message.answer("<b>🎁 Увы, товары в данное время отсутствуют</b>")
|
||||
|
||||
|
||||
# Открытие FAQ
|
||||
@router.message(F.text.in_(('❔ FAQ', '/faq')))
|
||||
async def user_faq(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
get_settings = await Settingsx().get()
|
||||
|
||||
if get_settings.misc_faq == "None":
|
||||
return await message.answer(
|
||||
ded(f"""
|
||||
❔ Текст FAQ не указан. Измените его в настройках бота.
|
||||
|
||||
➖➖➖➖➖➖➖➖➖➖
|
||||
{get_text_desc()}
|
||||
|
||||
➖➖➖➖➖➖➖➖➖➖
|
||||
{get_text_warning()}
|
||||
"""),
|
||||
disable_web_page_preview=True,
|
||||
)
|
||||
|
||||
await message.answer(
|
||||
await insert_tags(message.from_user.id, get_settings.misc_faq),
|
||||
disable_web_page_preview=True,
|
||||
)
|
||||
|
||||
|
||||
# Открытие сообщения с ссылкой на поддержку
|
||||
@router.message(F.text.in_(('☎️ Поддержка', '/support')))
|
||||
async def user_support(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
get_settings = await Settingsx().get()
|
||||
|
||||
if get_settings.misc_support == "None":
|
||||
return await message.answer(
|
||||
ded(f"""
|
||||
☎️ Контакты поддержки не указаны. Измените их в настройках бота.
|
||||
|
||||
➖➖➖➖➖➖➖➖➖➖
|
||||
{get_text_desc()}
|
||||
|
||||
➖➖➖➖➖➖➖➖➖➖
|
||||
{get_text_warning()}
|
||||
"""),
|
||||
disable_web_page_preview=True,
|
||||
)
|
||||
|
||||
await message.answer(
|
||||
"<b>☎️ Нажмите кнопку ниже для связи с Администратором</b>",
|
||||
reply_markup=user_support_finl(get_settings.misc_support),
|
||||
)
|
||||
|
||||
|
||||
# Получение версии бота
|
||||
@router.message(Command(commands=['version']))
|
||||
async def admin_version(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await message.answer(f"<b>❇️ Текущая версия бота: <code>{BOT_VERSION}</code></b>")
|
||||
|
||||
|
||||
# Получение информации о боте
|
||||
@router.message(Command(commands=['dj_desc']))
|
||||
async def admin_desc(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await message.answer(get_text_desc(), disable_web_page_preview=True)
|
||||
|
||||
|
||||
################################################################################
|
||||
# Переход к профилю
|
||||
@router.callback_query(F.data == "user_profile")
|
||||
async def user_profile_return(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
await state.clear()
|
||||
|
||||
await del_message(call.message)
|
||||
await open_profile_user(bot, call.from_user.id)
|
||||
|
||||
|
||||
# Просмотр истории покупок
|
||||
@router.callback_query(F.data == "user_purchases")
|
||||
async def user_purchases(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
get_purchases = await Purchasesx().gets(user_id=call.from_user.id)
|
||||
get_purchases = get_purchases[-5:]
|
||||
|
||||
if len(get_purchases) >= 1:
|
||||
await call.answer("🎁 Последние 5 покупок")
|
||||
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"""
|
||||
<b>🧾 Чек: <code>#{purchase.purchase_receipt}</code></b>
|
||||
▪️ Товар: <code>{purchase.purchase_position_name} | {purchase.purchase_count}шт | {purchase.purchase_price}₽</code>
|
||||
▪️ Дата покупки: <code>{convert_date(purchase.purchase_unix)}</code>
|
||||
▪️ Товары: <a href='{link_items}'>кликабельно</a>
|
||||
"""),
|
||||
disable_web_page_preview=True,
|
||||
)
|
||||
|
||||
await asyncio.sleep(0.2)
|
||||
|
||||
await open_profile_user(bot, call.from_user.id)
|
||||
else:
|
||||
await call.answer("❗ У вас отсутствуют покупки", True)
|
||||
|
||||
|
||||
# Страницы наличия товаров
|
||||
@router.callback_query(F.data.startswith("user_available_swipe:"))
|
||||
async def user_available_swipe(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
remover = int(call.data.split(":")[1])
|
||||
|
||||
items_available, remover_max, remover_now = await get_items_available(remover)
|
||||
|
||||
await call.message.edit_text(
|
||||
items_available,
|
||||
reply_markup=prod_available_swipe_fp(remover_now, remover_max),
|
||||
)
|
||||
@@ -0,0 +1,276 @@
|
||||
# - *- 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 Positionx, Userx, Categoryx, Itemx, Paymentsx, Purchasesx, Settingsx
|
||||
from tgbot.keyboards.inline_user import refill_method_buy_finl
|
||||
from tgbot.keyboards.inline_user_page import *
|
||||
from tgbot.keyboards.inline_user_products import products_buy_confirm_finl, products_return_finl
|
||||
from tgbot.keyboards.reply_main import menu_frep
|
||||
from tgbot.utils.const_functions import ded, del_message, convert_date, send_admins
|
||||
from tgbot.utils.misc.bot_models import FSM, ARS
|
||||
from tgbot.utils.products_functions import get_positions_items
|
||||
from tgbot.utils.text_functions import position_open_user
|
||||
|
||||
router = Router(name=__name__)
|
||||
|
||||
|
||||
# Страницы выбора категории для покупки товара
|
||||
@router.callback_query(F.data.startswith("buy_category_swipe:"))
|
||||
async def user_buy_category_swipe(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
remover = int(call.data.split(":")[1])
|
||||
|
||||
await call.message.edit_text(
|
||||
"<b>🎁 Выберите нужный вам товар</b>",
|
||||
reply_markup=await prod_item_category_swipe_fp(remover),
|
||||
)
|
||||
|
||||
|
||||
# Открытие категории с выбором позиции для покупки товара
|
||||
@router.callback_query(F.data.startswith("buy_category_open:"))
|
||||
async def user_buy_category_open(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
category_id = int(call.data.split(":")[1])
|
||||
remover = int(call.data.split(":")[2])
|
||||
|
||||
get_category = await Categoryx().get_required(category_id=category_id)
|
||||
get_positions = await get_positions_items(category_id)
|
||||
|
||||
if len(get_positions) >= 1:
|
||||
await del_message(call.message)
|
||||
|
||||
await call.message.answer(
|
||||
f"<b>🎁 Текущая категория: <code>{get_category.category_name}</code></b>",
|
||||
reply_markup=await prod_item_position_swipe_fp(remover, category_id),
|
||||
)
|
||||
else:
|
||||
await call.answer(
|
||||
f"❕ Товары в категории {get_category.category_name} отсутствуют",
|
||||
True,
|
||||
cache_time=5,
|
||||
)
|
||||
|
||||
|
||||
# Страницы выбора позиции для покупки товара
|
||||
@router.callback_query(F.data.startswith("buy_position_swipe:"))
|
||||
async def user_buy_position_swipe(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
category_id = int(call.data.split(":")[1])
|
||||
remover = int(call.data.split(":")[2])
|
||||
|
||||
get_category = await Categoryx().get_required(category_id=category_id)
|
||||
|
||||
await del_message(call.message)
|
||||
await call.message.answer(
|
||||
f"<b>🎁 Текущая категория: <code>{get_category.category_name}</code></b>",
|
||||
reply_markup=await prod_item_position_swipe_fp(remover, category_id),
|
||||
)
|
||||
|
||||
|
||||
# Открытие позиции для покупки товара
|
||||
@router.callback_query(F.data.startswith("buy_position_open:"))
|
||||
async def user_buy_position_open(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
position_id = int(call.data.split(":")[1])
|
||||
remover = int(call.data.split(":")[2])
|
||||
|
||||
await state.clear()
|
||||
|
||||
await del_message(call.message)
|
||||
await position_open_user(bot, call.from_user.id, position_id, remover)
|
||||
|
||||
|
||||
#################################### ПОКУПКА ###################################
|
||||
# Покупка товара
|
||||
@router.callback_query(F.data.startswith("buy_item_open:"))
|
||||
async def user_buy_open(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
position_id = int(call.data.split(":")[1])
|
||||
remover = int(call.data.split(":")[2])
|
||||
|
||||
get_payments = await Paymentsx().get()
|
||||
get_position = await Positionx().get_required(position_id=position_id)
|
||||
get_items = await Itemx().gets(position_id=position_id)
|
||||
get_user = await Userx().get_required(user_id=call.from_user.id)
|
||||
|
||||
# Проверка, имеется ли на балансе пользователя достаточно средств
|
||||
if get_user.user_balance < get_position.position_price:
|
||||
if get_payments.status_cryptobot == "True" or get_payments.status_yoomoney == "True":
|
||||
await call.message.answer(
|
||||
"<b>❗ На вашем счёте недостаточно средств</b>\n"
|
||||
"💰 Выберите способ пополнения баланса",
|
||||
reply_markup=await refill_method_buy_finl(),
|
||||
)
|
||||
|
||||
return await call.answer(cache_time=5)
|
||||
else:
|
||||
return await call.answer("❗ У вас недостаточно средств. Пополните баланс", True)
|
||||
|
||||
if len(get_items) < 1:
|
||||
return await call.answer("❗ Товаров нет в наличии", True)
|
||||
|
||||
# Максимальное количество товаров к покупке, подстроенные под баланс пользователя
|
||||
if get_position.position_price != 0:
|
||||
max_buy_count = int(get_user.user_balance / get_position.position_price)
|
||||
|
||||
if max_buy_count > len(get_items):
|
||||
available_count = len(get_items)
|
||||
else:
|
||||
available_count = max_buy_count
|
||||
else:
|
||||
available_count = len(get_items)
|
||||
|
||||
# Если в наличии всего один товар, то пропустить ввод количества товаров к покупке
|
||||
if available_count == 1:
|
||||
await state.clear()
|
||||
|
||||
await del_message(call.message)
|
||||
|
||||
await call.message.answer(
|
||||
ded(f"""
|
||||
<b>🎁 Вы действительно хотите купить товар(ы)?</b>
|
||||
➖➖➖➖➖➖➖➖➖➖
|
||||
▪️ Товар: <code>{get_position.position_name}</code>
|
||||
▪️ Количество: <code>1шт</code>
|
||||
▪️ Сумма к покупке: <code>{get_position.position_price}₽</code>
|
||||
"""),
|
||||
reply_markup=products_buy_confirm_finl(position_id, get_position.category_id, 1),
|
||||
)
|
||||
else:
|
||||
await state.update_data(here_buy_position_id=position_id)
|
||||
await state.set_state("here_item_count")
|
||||
|
||||
await del_message(call.message)
|
||||
await call.message.answer(
|
||||
ded(f"""
|
||||
<b>🎁 Введите количество товаров для покупки</b>
|
||||
❕ От <code>1</code> до <code>{available_count}</code>
|
||||
➖➖➖➖➖➖➖➖➖➖
|
||||
▪️ Товар: <code>{get_position.position_name}</code> - <code>{get_position.position_price}₽</code>
|
||||
▪️ Ваш баланс: <code>{get_user.user_balance}₽</code>
|
||||
"""),
|
||||
reply_markup=products_return_finl(position_id, get_position.category_id),
|
||||
)
|
||||
|
||||
|
||||
# Принятие количества товаров для покупки
|
||||
@router.message(F.text, StateFilter("here_item_count"))
|
||||
async def user_buy_count(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
position_id = (await state.get_data())['here_buy_position_id']
|
||||
|
||||
get_position = await Positionx().get_required(position_id=position_id)
|
||||
get_user = await Userx().get_required(user_id=message.from_user.id)
|
||||
get_items = await Itemx().gets(position_id=position_id)
|
||||
|
||||
# Максимальное количество товаров к покупке, подстроенные под баланс пользователя
|
||||
if get_position.position_price != 0:
|
||||
get_count = int(get_user.user_balance / get_position.position_price)
|
||||
|
||||
if get_count > len(get_items):
|
||||
get_count = len(get_items)
|
||||
else:
|
||||
get_count = len(get_items)
|
||||
|
||||
send_message = ded(f"""
|
||||
🎁 Введите количество товаров для покупки
|
||||
❕ От <code>1</code> до <code>{get_count}</code>
|
||||
➖➖➖➖➖➖➖➖➖➖
|
||||
▪️ Товар: <code>{get_position.position_name}</code> - <code>{get_position.position_price}₽</code>
|
||||
▪️ Ваш баланс: <code>{get_user.user_balance}₽</code>
|
||||
""")
|
||||
|
||||
# Если было введено не число
|
||||
if not message.text.isdigit():
|
||||
return await message.answer(
|
||||
f"<b>❌ Данные были введены неверно</b>\n" + send_message,
|
||||
reply_markup=products_return_finl(position_id, get_position.category_id),
|
||||
)
|
||||
|
||||
get_count = int(message.text)
|
||||
amount_pay = round(get_position.position_price * get_count, 2)
|
||||
|
||||
# Если товаров нет в наличии
|
||||
if len(get_items) < 1:
|
||||
await state.clear()
|
||||
return await message.answer("<b>🎁 Товар который вы хотели купить, закончился</b>")
|
||||
|
||||
# Если введено кол-во товаров меньше 1 или меньше кол-ва имеющегося в наличии
|
||||
if get_count < 1 or get_count > len(get_items):
|
||||
return await message.answer(
|
||||
f"<b>❌ Неверное количество товаров</b>\n" + send_message,
|
||||
reply_markup=products_return_finl(position_id, get_position.category_id),
|
||||
)
|
||||
|
||||
# Если баланс пользователя меньше, чем общая цена покупки
|
||||
if get_user.user_balance < amount_pay:
|
||||
return await message.answer(
|
||||
f"<b>❌ Недостаточно средств на счете</b>\n" + send_message,
|
||||
reply_markup=products_return_finl(position_id, get_position.category_id),
|
||||
)
|
||||
|
||||
await state.clear()
|
||||
|
||||
await message.answer(
|
||||
ded(f"""
|
||||
<b>🎁 Вы действительно хотите купить товар(ы)?</b>
|
||||
➖➖➖➖➖➖➖➖➖➖
|
||||
▪️ Товар: <code>{get_position.position_name}</code>
|
||||
▪️ Количество: <code>{get_count}шт</code>
|
||||
▪️ Сумма к покупке: <code>{amount_pay}₽</code>
|
||||
"""),
|
||||
reply_markup=products_buy_confirm_finl(position_id, get_position.category_id, get_count),
|
||||
)
|
||||
|
||||
|
||||
# Подтверждение покупки товара
|
||||
@router.callback_query(F.data.startswith("buy_item_confirm:"))
|
||||
async def user_buy_confirm(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
position_id = int(call.data.split(":")[1])
|
||||
purchase_count = int(call.data.split(":")[2])
|
||||
|
||||
await call.message.edit_text("⏳")
|
||||
|
||||
purchase_result = await Purchasesx().buy(
|
||||
user_id=call.from_user.id,
|
||||
position_id=position_id,
|
||||
requested_count=purchase_count,
|
||||
)
|
||||
|
||||
if purchase_result == "USER_NOT_FOUND":
|
||||
return await call.message.edit_text("<b>❌ Пользователь не был найден</b>")
|
||||
elif purchase_result == "POSITION_NOT_FOUND":
|
||||
return await call.message.edit_text("<b>❌ Позиция не была найдена</b>")
|
||||
elif purchase_result == "NOT_ENOUGH_ITEMS":
|
||||
return await call.message.edit_text("<b>❌ В наличии недостаточно товаров. Попробуйте другое кол-во</b>")
|
||||
elif purchase_result == "NOT_ENOUGH_BALANCE":
|
||||
return await call.message.edit_text("<b>❌ На вашем балансе недостаточно средств</b>")
|
||||
|
||||
get_user = await Userx().get_required(user_id=call.from_user.id)
|
||||
get_settings = await Settingsx().get()
|
||||
|
||||
for items in purchase_result.items:
|
||||
await call.message.answer("\n\n".join(items), parse_mode="None")
|
||||
await asyncio.sleep(0.3)
|
||||
|
||||
await del_message(call.message)
|
||||
await call.message.answer(
|
||||
ded(f"""
|
||||
<b>✅ Вы успешно купили товар(ы)</b>
|
||||
➖➖➖➖➖➖➖➖➖➖
|
||||
▪️ Чек: <code>#{purchase_result.receipt}</code>
|
||||
▪️ Товар: <code>{purchase_result.position_name} | {purchase_result.purchase_count}шт | {purchase_result.purchase_price}₽</code>
|
||||
▪️ Дата покупки: <code>{convert_date(purchase_result.purchase_unix)}</code>
|
||||
"""),
|
||||
reply_markup=menu_frep(call.from_user.id),
|
||||
)
|
||||
|
||||
if get_settings.notification_buy == "True":
|
||||
await send_admins(
|
||||
bot,
|
||||
ded(f"""
|
||||
<b>🎁 Покупка товара</b>
|
||||
|
||||
▪️ Пользователь: <b>@{get_user.user_login}</b> | <a href='tg://user?id={get_user.user_id}'>{get_user.user_name}</a> | <code>{get_user.user_id}</code>
|
||||
▪️ Товар: <code>{purchase_result.position_name} | {purchase_result.purchase_count}шт | {purchase_result.purchase_price}₽</code>
|
||||
▪️ Чек: <code>#{purchase_result.receipt}</code>
|
||||
""")
|
||||
)
|
||||
@@ -0,0 +1,407 @@
|
||||
# - *- coding: utf- 8 - *-
|
||||
from typing import Optional, Tuple
|
||||
|
||||
from aiogram import Router, Bot, F
|
||||
from aiogram.filters import StateFilter
|
||||
from aiogram.types import CallbackQuery, Message, PreCheckoutQuery
|
||||
|
||||
from tgbot.database import Paymentsx, Refillx, Userx, Settingsx
|
||||
from tgbot.keyboards.inline_user import refill_bill_finl, refill_method_finl
|
||||
from tgbot.services.api_cryptobot import CryptobotAPI
|
||||
from tgbot.services.api_stars import StarsAPI
|
||||
from tgbot.services.api_yoomoney import YoomoneyAPI
|
||||
from tgbot.utils.const_functions import is_number, to_number, gen_id, ded
|
||||
from tgbot.utils.misc.bot_logging import bot_logger
|
||||
from tgbot.utils.misc.bot_models import FSM, ARS
|
||||
from tgbot.utils.misc_functions import send_admins
|
||||
|
||||
min_refill_rub = 5 # Минимальная сумма пополнения в рублях
|
||||
|
||||
router = Router(name=__name__)
|
||||
|
||||
|
||||
# Выбор способа пополнения
|
||||
@router.callback_query(F.data == "user_refill")
|
||||
async def refill_method_list(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
get_payments = await Paymentsx().get()
|
||||
|
||||
if (
|
||||
get_payments.status_cryptobot == "False" and
|
||||
get_payments.status_yoomoney == "False" and
|
||||
get_payments.status_stars == "False"
|
||||
):
|
||||
return await call.answer("❗️ Пополнения временно недоступны", True)
|
||||
|
||||
await call.message.edit_text(
|
||||
"<b>💰 Выберите способ пополнения баланса</b>",
|
||||
reply_markup=await refill_method_finl(),
|
||||
)
|
||||
|
||||
|
||||
# Выбор способа пополнения
|
||||
@router.callback_query(F.data.startswith("user_refill_method:"))
|
||||
async def refill_method_select(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
refill_method = call.data.split(":")[1]
|
||||
|
||||
get_payments = await Paymentsx().get()
|
||||
|
||||
if refill_method == "Cryptobot" and get_payments.status_cryptobot == "False":
|
||||
return await call.answer("❌ Пополнение данным способом временно недоступно", True)
|
||||
elif refill_method == "Yoomoney" and get_payments.status_yoomoney == "False":
|
||||
return await call.answer("❌ Пополнение данным способом временно недоступно", True)
|
||||
elif refill_method == "Stars" and get_payments.status_stars == "False":
|
||||
return await call.answer("❌ Пополнение данным способом временно недоступно", True)
|
||||
|
||||
await state.update_data(here_refill_method=refill_method)
|
||||
|
||||
await state.set_state("here_refill_amount")
|
||||
await call.message.edit_text("<b>💰 Введите сумму пополнения</b>")
|
||||
|
||||
|
||||
################################################################################
|
||||
################################### ВВОД СУММЫ #################################
|
||||
# Принятие суммы для пополнения средств
|
||||
@router.message(F.text, StateFilter("here_refill_amount"))
|
||||
async def refill_amount_get(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
if not is_number(message.text):
|
||||
return await message.answer(
|
||||
ded(f"""
|
||||
<b>❌ Данные были введены неверно</b>
|
||||
💰 Введите сумму для пополнения средств
|
||||
"""),
|
||||
)
|
||||
|
||||
if to_number(message.text) < min_refill_rub or to_number(message.text) > 150_000:
|
||||
return await message.answer(
|
||||
ded(f"""
|
||||
<b>❌ Неверная сумма пополнения</b>
|
||||
❗️ Cумма не должна быть меньше <code>{min_refill_rub}₽</code> и больше <code>150 000₽</code>
|
||||
💰 Введите сумму для пополнения средств
|
||||
"""),
|
||||
)
|
||||
|
||||
cache_message = await message.answer("<b>♻️ Подождите, платёж генерируется..</b>")
|
||||
|
||||
refill_amount = to_number(message.text)
|
||||
refill_method = (await state.get_data())['here_refill_method']
|
||||
await state.clear()
|
||||
|
||||
# Генерация платежа
|
||||
if refill_method == "Cryptobot":
|
||||
bill_message, bill_link, bill_receipt = await (
|
||||
await CryptobotAPI.connect(
|
||||
bot=bot,
|
||||
arSession=arSession,
|
||||
update=cache_message,
|
||||
)
|
||||
).bill(refill_amount)
|
||||
elif refill_method == "Yoomoney":
|
||||
bill_message, bill_link, bill_receipt = await (
|
||||
await YoomoneyAPI.connect(
|
||||
bot=bot,
|
||||
arSession=arSession,
|
||||
update=cache_message,
|
||||
)
|
||||
).bill(refill_amount)
|
||||
elif refill_method == "Stars":
|
||||
bill_message, bill_link, bill_receipt = await (
|
||||
await StarsAPI.connect(
|
||||
bot=bot,
|
||||
arSession=arSession,
|
||||
update=cache_message,
|
||||
)
|
||||
).bill(refill_amount)
|
||||
else:
|
||||
return await cache_message.edit_text(
|
||||
f"<b>❌ Данный способ пополнения не найден. Попробуйте позже: {refill_method}</b>"
|
||||
)
|
||||
|
||||
# Обработка статуса генерации платежа
|
||||
if bill_message:
|
||||
await cache_message.edit_text(
|
||||
bill_message,
|
||||
reply_markup=refill_bill_finl(bill_link, bill_receipt, refill_method),
|
||||
)
|
||||
else:
|
||||
await cache_message.edit_text(
|
||||
f"<b>❌ Не удалось сгенерировать платёж. Попробуйте позже</b>"
|
||||
)
|
||||
|
||||
|
||||
################################################################################
|
||||
############################### ПРОВЕРКА ПЛАТЕЖЕЙ ##############################
|
||||
# Проверка оплаты - ЮMoney
|
||||
@router.callback_query(F.data.startswith('Pay:Yoomoney'))
|
||||
async def refill_check_yoomoney(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
pay_method = call.data.split(":")[1]
|
||||
pay_receipt = call.data.split(":")[2]
|
||||
|
||||
pay_status, pay_amount = await (
|
||||
await YoomoneyAPI.connect(
|
||||
bot=bot,
|
||||
arSession=arSession,
|
||||
update=call,
|
||||
)
|
||||
).bill_check(pay_receipt)
|
||||
|
||||
if pay_status == 0:
|
||||
refill_status = await refill_success(
|
||||
bot=bot,
|
||||
call=call,
|
||||
pay_method=pay_method,
|
||||
pay_amount=pay_amount,
|
||||
pay_receipt=int(pay_receipt),
|
||||
pay_comment=pay_receipt,
|
||||
)
|
||||
|
||||
if refill_status == "ALREADY":
|
||||
await call.answer("❗ Ваше пополнение уже зачислено.", True, cache_time=60)
|
||||
await delete_refill_message(bot, call.message.chat.id, call.message.message_id)
|
||||
elif refill_status == "USER_NOT_FOUND":
|
||||
await call.answer("❗ Пользователь не найден. Напишите в поддержку.", True, cache_time=30)
|
||||
elif pay_status == 1:
|
||||
await call.answer("❗️ Не удалось проверить платёж. Попробуйте позже", True, cache_time=30)
|
||||
elif pay_status == 2:
|
||||
await call.answer("❗️ Оплата не была найдена. Попробуйте позже", True, cache_time=5)
|
||||
elif pay_status == 3:
|
||||
await call.answer("❗️ Оплата была произведена не в рублях", True, cache_time=5)
|
||||
else:
|
||||
await call.answer(f"❗ Неизвестная ошибка {pay_status}. Обратитесь в поддержку.", True, cache_time=5)
|
||||
|
||||
|
||||
# Проверка оплаты - Cryptobot
|
||||
@router.callback_query(F.data.startswith('Pay:Cryptobot'))
|
||||
async def refill_check_cryptobot(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
pay_method = call.data.split(":")[1]
|
||||
pay_comment = call.data.split(":")[2]
|
||||
|
||||
pay_status, pay_amount = await (
|
||||
await CryptobotAPI.connect(
|
||||
bot=bot,
|
||||
arSession=arSession,
|
||||
update=call,
|
||||
)
|
||||
).bill_check(pay_comment)
|
||||
|
||||
if pay_status == 0:
|
||||
refill_status = await refill_success(
|
||||
bot=bot,
|
||||
call=call,
|
||||
pay_method=pay_method,
|
||||
pay_amount=pay_amount,
|
||||
pay_comment=pay_comment,
|
||||
)
|
||||
|
||||
if refill_status == "ALREADY":
|
||||
await call.answer("❗ Ваше пополнение уже зачислено.", True, cache_time=60)
|
||||
await delete_refill_message(bot, call.message.chat.id, call.message.message_id)
|
||||
elif refill_status == "USER_NOT_FOUND":
|
||||
await call.answer("❗ Пользователь не найден. Напишите в поддержку.", True, cache_time=30)
|
||||
elif pay_status == 1:
|
||||
await call.answer("❗️ Не удалось проверить платёж. Попробуйте позже", True, cache_time=30)
|
||||
elif pay_status == 2:
|
||||
await call.answer("❗️ Оплата не была найдена. Попробуйте позже", True, cache_time=5)
|
||||
elif pay_status == 3:
|
||||
await call.answer("❗️ Вы не успели оплатить счёт", True, cache_time=5)
|
||||
await call.message.edit_reply_markup()
|
||||
else:
|
||||
await call.answer(f"❗ Неизвестная ошибка {pay_status}. Обратитесь в поддержку.", True, cache_time=5)
|
||||
|
||||
|
||||
# Проверка оплаты - Звёзды
|
||||
@router.callback_query(F.data.startswith('Pay:Stars'))
|
||||
async def refill_check_stars(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
pay_method = call.data.split(":")[1]
|
||||
pay_receipt = int(call.data.split(":")[2])
|
||||
|
||||
pay_status, pay_amount = await (
|
||||
await StarsAPI.connect(
|
||||
bot=bot,
|
||||
arSession=arSession,
|
||||
update=call,
|
||||
)
|
||||
).bill_check(pay_receipt)
|
||||
|
||||
if pay_status == 0:
|
||||
refill_status = await refill_success(
|
||||
bot=bot,
|
||||
call=call,
|
||||
pay_method=pay_method,
|
||||
pay_amount=pay_amount,
|
||||
pay_receipt=pay_receipt,
|
||||
)
|
||||
|
||||
if refill_status == "ALREADY":
|
||||
await call.answer("❗ Ваше пополнение уже зачислено.", True, cache_time=60)
|
||||
await delete_refill_message(bot, call.message.chat.id, call.message.message_id)
|
||||
elif refill_status == "USER_NOT_FOUND":
|
||||
await call.answer("❗ Пользователь не найден. Напишите в поддержку.", True, cache_time=30)
|
||||
elif pay_status == 1:
|
||||
await call.answer("❗️ Не удалось проверить платёж. Попробуйте позже", True, cache_time=30)
|
||||
elif pay_status == 2:
|
||||
await call.answer("❗️ Оплата не была найдена. Попробуйте позже", True, cache_time=5)
|
||||
else:
|
||||
await call.answer(f"❗ Неизвестная ошибка {pay_status}. Обратитесь в поддержку.", True, cache_time=5)
|
||||
|
||||
|
||||
################################################################################
|
||||
#################################### ЗВЁЗДЫ ####################################
|
||||
# Подтверждение платежа Telegram Stars
|
||||
@router.pre_checkout_query()
|
||||
async def refill_stars_pre_checkout(query: PreCheckoutQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||
await (
|
||||
await StarsAPI.connect(
|
||||
bot=bot,
|
||||
arSession=arSession,
|
||||
update=query,
|
||||
)
|
||||
).answer_pre_checkout(query)
|
||||
|
||||
|
||||
# Автоматическое зачисление Telegram Stars
|
||||
@router.message(F.successful_payment)
|
||||
async def refill_stars_success(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||
payment = message.successful_payment
|
||||
|
||||
if payment is None:
|
||||
return
|
||||
|
||||
stars_api = await StarsAPI.connect(
|
||||
bot=bot,
|
||||
arSession=arSession,
|
||||
update=message,
|
||||
)
|
||||
|
||||
try:
|
||||
pay_receipt, pay_amount, pay_comment, bill_chat_id, bill_message_id = (
|
||||
stars_api.parse_successful_payment(payment)
|
||||
)
|
||||
except ValueError:
|
||||
bot_logger.warning("Некорректная successful_payment для Telegram Stars", exc_info=True)
|
||||
return
|
||||
|
||||
refill_status, receipt = await save_refill_success(
|
||||
bot=bot,
|
||||
user_id=message.from_user.id,
|
||||
pay_method="Stars",
|
||||
pay_amount=pay_amount,
|
||||
pay_receipt=pay_receipt,
|
||||
pay_comment=pay_comment,
|
||||
)
|
||||
|
||||
if refill_status == "ok":
|
||||
if bill_chat_id == message.chat.id:
|
||||
await delete_refill_message(bot, bill_chat_id, bill_message_id)
|
||||
|
||||
await message.answer(
|
||||
ded(f"""
|
||||
<b>💰 Вы пополнили баланс на сумму <code>{pay_amount}₽</code>. Удачи ❤️
|
||||
🧾 Чек: <code>#{receipt}</code></b>
|
||||
""")
|
||||
)
|
||||
elif refill_status == "ALREADY":
|
||||
if bill_chat_id == message.chat.id:
|
||||
await delete_refill_message(bot, bill_chat_id, bill_message_id)
|
||||
|
||||
await message.answer("<b>❗ Ваше пополнение уже было зачислено.</b>")
|
||||
elif refill_status == "USER_NOT_FOUND":
|
||||
await message.answer("<b>❗ Пользователь не найден. Напишите в поддержку.</b>")
|
||||
|
||||
|
||||
################################################################################
|
||||
#################################### ПРОЧЕЕ ####################################
|
||||
# Зачисление средств
|
||||
async def refill_success(
|
||||
bot: Bot,
|
||||
call: CallbackQuery,
|
||||
pay_method: str,
|
||||
pay_amount: float,
|
||||
pay_receipt: Optional[int] = None,
|
||||
pay_comment: Optional[str] = None,
|
||||
):
|
||||
user_id = call.from_user.id
|
||||
|
||||
if pay_receipt is None:
|
||||
pay_receipt = gen_id(12)
|
||||
if pay_comment is None:
|
||||
pay_comment = ""
|
||||
|
||||
response_success, receipt = await save_refill_success(
|
||||
bot=bot,
|
||||
user_id=user_id,
|
||||
pay_method=pay_method,
|
||||
pay_amount=pay_amount,
|
||||
pay_receipt=pay_receipt,
|
||||
pay_comment=pay_comment,
|
||||
)
|
||||
|
||||
if response_success != "ok":
|
||||
return response_success
|
||||
|
||||
await call.message.answer(
|
||||
ded(f"""
|
||||
<b>💰 Вы пополнили баланс на сумму <code>{pay_amount}₽</code>. Удачи ❤️
|
||||
🧾 Чек: <code>#{receipt}</code></b>
|
||||
""")
|
||||
)
|
||||
await delete_refill_message(bot, call.message.chat.id, call.message.message_id)
|
||||
|
||||
return response_success
|
||||
|
||||
|
||||
# Удаление сообщения со счётом
|
||||
async def delete_refill_message(bot: Bot, chat_id: Optional[int], message_id: Optional[int]) -> None:
|
||||
if chat_id is None or message_id is None:
|
||||
return
|
||||
|
||||
try:
|
||||
await bot.delete_message(chat_id=chat_id, message_id=message_id)
|
||||
except Exception:
|
||||
bot_logger.warning("Не удалось удалить сообщение со счётом", exc_info=True)
|
||||
|
||||
|
||||
# Сохранение пополнения и уведомление админов
|
||||
async def save_refill_success(
|
||||
bot: Bot,
|
||||
user_id: int,
|
||||
pay_method: str,
|
||||
pay_amount: float,
|
||||
pay_receipt: int,
|
||||
pay_comment: str,
|
||||
) -> Tuple[str, int]:
|
||||
if pay_method == "Yoomoney":
|
||||
text_method = "ЮMoney"
|
||||
elif pay_method == "Cryptobot":
|
||||
text_method = "CryptoBot"
|
||||
elif pay_method == "Stars":
|
||||
text_method = "Telegram Stars"
|
||||
else:
|
||||
text_method = f"Unknown - {pay_method}"
|
||||
|
||||
response_success = await Refillx().success(
|
||||
user_id=user_id,
|
||||
pay_receipt=pay_receipt,
|
||||
pay_comment=pay_comment,
|
||||
pay_amount=pay_amount,
|
||||
pay_method=pay_method,
|
||||
)
|
||||
|
||||
if response_success != "ok":
|
||||
return response_success, pay_receipt
|
||||
|
||||
get_user = await Userx().get_required(user_id=user_id)
|
||||
get_settings = await Settingsx().get()
|
||||
|
||||
if get_settings.notification_refill == "True":
|
||||
await send_admins(
|
||||
bot,
|
||||
ded(f"""
|
||||
<b>💰 Пополнение баланса</b>
|
||||
|
||||
▪️ Пользователь: <b>@{get_user.user_login}</b> | <a href='tg://user?id={user_id}'>{get_user.user_name}</a> | <code>{user_id}</code>
|
||||
▪️ Сумма пополнения: <code>{pay_amount}₽</code> <code>({text_method})</code>
|
||||
▪️ Чек: <code>#{pay_receipt}</code>
|
||||
""")
|
||||
)
|
||||
|
||||
return response_success, pay_receipt
|
||||
Reference in New Issue
Block a user