Files

360 lines
14 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# - *- coding: utf- 8 - *-
from math import isfinite
from urllib.parse import urlparse
import re
from aiogram import Bot, F, Router
from aiogram.filters import StateFilter
from aiogram.types import CallbackQuery, Message
from tgbot.database import ReferralWithdrawalx, Referralx, Settingsx, Userx
from tgbot.keyboards.inline_admin import referral_withdrawal_actions_finl
from tgbot.keyboards.inline_user import (
referral_menu_finl,
referral_transfer_method_finl,
referral_withdrawal_method_finl,
)
from tgbot.utils.const_functions import clear_html, ded, is_number, to_number
from tgbot.utils.misc.bot_models import ARS, FSM
from tgbot.utils.misc_functions import send_admins
router = Router(name=__name__)
def is_valid_withdrawal_recipient(withdrawal_method: str, recipient: str) -> bool:
if withdrawal_method == "Cryptobot":
return bool(re.fullmatch(r"@[A-Za-z][A-Za-z0-9_]{4,31}", recipient))
if withdrawal_method == "Lolzteam":
parsed_url = urlparse(recipient)
return parsed_url.scheme in ("http", "https") and parsed_url.hostname in (
"zelenka.guru",
"lolz.team",
"lolz.live",
"lolz.guru",
)
return False
def withdrawal_recipient_hint(withdrawal_method: str) -> str:
if withdrawal_method == "Cryptobot":
return (
"<b>📥 Введите @username получателя в CryptoBot</b>\n"
"➖➖➖➖➖➖➖➖➖➖\n"
"<i>Пример: @username</i>"
)
return (
"<b>📥 Введите ссылку на профиль получателя Lolzteam</b>\n"
"➖➖➖➖➖➖➖➖➖➖\n"
"<i>Подойдут ссылки с zelenka.guru, lolz.team, lolz.live или lolz.guru</i>"
)
def withdrawal_method_title(withdrawal_method: str) -> str:
if withdrawal_method == "Cryptobot":
return "CryptoBot"
return withdrawal_method
async def get_referral_menu_data(user_id: int, bot: Bot):
get_settings = await Settingsx().get()
if get_settings.status_referral != "True":
return None
get_user = await Userx().get_required(user_id=user_id)
get_referrals = await Referralx().gets(referrer_id=user_id)
bot_username = get_settings.misc_bot
if bot_username == "None":
bot_username = (await bot.get_me()).username or ""
referral_link = f"https://t.me/{bot_username}?start=r_{user_id}"
available_balance = round(
get_user.user_referral_balance - get_user.user_referral_hold,
2,
)
referral_text = ded(f"""
<b>🤝 Реферальная система</b>
➖➖➖➖➖➖➖➖➖➖
▪️ Приглашено пользователей: <code>{len(get_referrals)}</code>
▪️ Реферальный баланс: <code>{get_user.user_referral_balance}₽</code>
▪️ Доступно: <code>{available_balance}₽</code>
➖➖➖➖➖➖➖➖➖➖
▪️ Бонус за приглашение: <code>{get_settings.referral_bonus_rub}₽</code>
▪️ Доход с пополнений: <code>{get_settings.referral_refill_percent}%</code>
""")
return referral_text, referral_menu_finl(referral_link)
@router.message(F.text == "🤝 Реферальная система")
async def show_referral_menu(
message: Message,
bot: Bot,
state: FSM,
arSession: ARS,
user_id: int | None = None,
):
await state.clear()
user_id = user_id or message.from_user.id
referral_menu_data = await get_referral_menu_data(user_id, bot)
if referral_menu_data is None:
return await message.answer("<b>⛔ Реферальная система временно отключена</b>")
referral_text, referral_keyboard = referral_menu_data
await message.answer(
referral_text,
reply_markup=referral_keyboard,
disable_web_page_preview=True,
)
@router.callback_query(F.data == "referral_menu")
async def user_referral_menu_return(
call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS
):
await state.clear()
referral_menu_data = await get_referral_menu_data(call.from_user.id, bot)
if referral_menu_data is None:
return await call.answer("⛔ Реферальная система временно отключена", True)
referral_text, referral_keyboard = referral_menu_data
await call.message.edit_text(
referral_text,
reply_markup=referral_keyboard,
disable_web_page_preview=True,
)
@router.callback_query(F.data == "referral_transfer")
async def user_referral_transfer_start(
call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS
):
get_settings = await Settingsx().get()
if get_settings.status_referral != "True":
await state.clear()
return await call.answer("⛔ Реферальная система временно отключена", True)
await state.clear()
await state.set_state("here_referral_transfer_amount")
await call.message.edit_text(
"<b>💸 Введите сумму для перевода на основной баланс</b>",
reply_markup=referral_transfer_method_finl(),
)
@router.callback_query(F.data == "referral_withdrawal")
async def user_referral_withdrawal_start(
call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS
):
get_settings = await Settingsx().get()
if get_settings.status_referral != "True":
await state.clear()
return await call.answer("⛔ Реферальная система временно отключена", True)
await state.clear()
await call.message.edit_text(
"<b>📥 Выберите способ вывода средств</b>",
reply_markup=referral_withdrawal_method_finl(),
)
@router.callback_query(F.data.startswith("referral_withdrawal_method:"))
async def user_referral_withdrawal_method(
call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS
):
withdrawal_method = call.data.split(":", 1)[1]
if withdrawal_method not in ("Cryptobot", "Lolzteam"):
return await call.answer("❌ Способ вывода не найден", True)
get_settings = await Settingsx().get()
if get_settings.status_referral != "True":
await state.clear()
return await call.answer("⛔ Реферальная система временно отключена", True)
await state.clear()
await state.update_data(here_referral_withdrawal_method=withdrawal_method)
await state.set_state("here_referral_withdrawal_amount")
await call.message.edit_text("<b>📥 Введите сумму для вывода</b>")
@router.message(F.text, StateFilter("here_referral_withdrawal_amount"))
async def user_referral_withdrawal_amount(
message: Message, bot: Bot, state: FSM, arSession: ARS
):
get_settings = await Settingsx().get()
if get_settings.status_referral != "True":
await state.clear()
return await message.answer("<b>⛔ Реферальная система временно отключена</b>")
if not is_number(message.text):
return await message.answer("<b>❌ Введите положительную сумму в рублях</b>")
withdrawal_amount = float(to_number(message.text))
if not isfinite(withdrawal_amount) or withdrawal_amount <= 0:
return await message.answer("<b>❌ Введите положительную сумму в рублях</b>")
get_user = await Userx().get_required(user_id=message.from_user.id)
available_balance = round(
get_user.user_referral_balance - get_user.user_referral_hold, 2
)
if withdrawal_amount > available_balance:
return await message.answer(
"<b>❌ Недостаточно доступных средств на реферальном балансе</b>"
)
withdrawal_data = await state.get_data()
withdrawal_method = withdrawal_data.get("here_referral_withdrawal_method")
if withdrawal_method not in ("Cryptobot", "Lolzteam"):
await state.clear()
return await message.answer("<b>❌ Данные вывода устарели. Начните заново</b>")
await state.update_data(here_referral_withdrawal_amount=withdrawal_amount)
await state.set_state("here_referral_withdrawal_recipient")
await message.answer(withdrawal_recipient_hint(withdrawal_method))
@router.message(F.text, StateFilter("here_referral_withdrawal_recipient"))
async def user_referral_withdrawal_recipient(
message: Message, bot: Bot, state: FSM, arSession: ARS
):
get_settings = await Settingsx().get()
if get_settings.status_referral != "True":
await state.clear()
return await message.answer("<b>⛔ Реферальная система временно отключена</b>")
withdrawal_data = await state.get_data()
withdrawal_method = withdrawal_data.get("here_referral_withdrawal_method")
withdrawal_amount = withdrawal_data.get("here_referral_withdrawal_amount")
if withdrawal_method is None or withdrawal_amount is None:
await state.clear()
return await message.answer("<b>❌ Данные вывода устарели. Начните заново</b>")
withdrawal_recipient = clear_html(message.text).strip()
if not withdrawal_recipient:
return await message.answer(
"<b>❌ Введите реквизиты</b>\n"
f"{withdrawal_recipient_hint(withdrawal_method)}"
)
if not is_valid_withdrawal_recipient(withdrawal_method, withdrawal_recipient):
return await message.answer(
"<b>❌ Некорректные реквизиты</b>\n"
f"{withdrawal_recipient_hint(withdrawal_method)}"
)
withdrawal_status, withdrawal = await ReferralWithdrawalx().create_pending(
user_id=message.from_user.id,
withdrawal_amount=withdrawal_amount,
withdrawal_method=withdrawal_method,
withdrawal_recipient=withdrawal_recipient,
)
if withdrawal_status == "INSUFFICIENT_FUNDS":
return await message.answer(
"<b>❌ Недостаточно доступных средств на реферальном балансе</b>"
)
if withdrawal_status in ("INVALID_AMOUNT", "INVALID_RECIPIENT", "INVALID_METHOD"):
return await message.answer("<b>❌ Некорректные данные для вывода</b>")
if withdrawal_status == "USER_NOT_FOUND":
await state.clear()
return await message.answer(
"<b>❌ Пользователь не найден. Обратитесь в поддержку</b>"
)
if withdrawal_status != "ok" or withdrawal is None:
return await message.answer(
"<b>❌ Не удалось создать заявку. Попробуйте позже</b>"
)
await state.clear()
get_user = await Userx().get_required(user_id=message.from_user.id)
method_title = withdrawal_method_title(withdrawal.withdrawal_method)
await message.answer(
ded(f"""
<b>📥 Заявка на вывод создана</b>
➖➖➖➖➖➖➖➖➖➖
▪️ Номер заявки: <code>#{withdrawal.increment}</code>
▪️ Сумма: <code>{withdrawal.withdrawal_amount}₽</code>
▪️ Способ: <code>{method_title}</code>
"""),
)
await send_admins(
bot,
ded(f"""
<b>📥 Новая заявка на вывод</b>
▪️ Номер заявки: <code>#{withdrawal.increment}</code>
▪️ Пользователь: <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>{withdrawal.withdrawal_amount}₽</code>
▪️ Способ: <code>{method_title}</code>
▪️ Реквизиты: <code>{withdrawal.withdrawal_recipient}</code>
"""),
keyboard=referral_withdrawal_actions_finl(withdrawal.increment),
)
@router.message(F.text, StateFilter("here_referral_transfer_amount"))
async def user_referral_transfer_amount(
message: Message, bot: Bot, state: FSM, arSession: ARS
):
get_settings = await Settingsx().get()
if get_settings.status_referral != "True":
await state.clear()
return await message.answer("<b>⛔ Реферальная система временно отключена</b>")
if not is_number(message.text):
return await message.answer("<b>❌ Введите положительную сумму в рублях</b>")
transfer_amount = float(to_number(message.text))
if not isfinite(transfer_amount) or transfer_amount <= 0:
return await message.answer("<b>❌ Введите положительную сумму в рублях</b>")
transfer_status = await Referralx().transfer_to_main_balance(
user_id=message.from_user.id,
amount=transfer_amount,
)
if transfer_status == "INSUFFICIENT_FUNDS":
return await message.answer(
"<b>❌ Недостаточно доступных средств на реферальном балансе</b>"
)
if transfer_status == "INVALID_AMOUNT":
return await message.answer("<b>❌ Введите положительную сумму в рублях</b>")
if transfer_status == "USER_NOT_FOUND":
await state.clear()
return await message.answer(
"<b>❌ Пользователь не найден. Обратитесь в поддержку</b>"
)
if transfer_status != "ok":
return await message.answer(
"<b>❌ Не удалось выполнить перевод. Попробуйте позже</b>"
)
await state.clear()
get_user = await Userx().get_required(user_id=message.from_user.id)
await message.answer(
ded(f"""
<b>💸 Средства переведены на основной баланс</b>
➖➖➖➖➖➖➖➖➖➖
▪️ Переведено: <code>{round(transfer_amount, 2)}₽</code>
▪️ Основной баланс: <code>{get_user.user_balance}₽</code>
▪️ Реферальный баланс: <code>{get_user.user_referral_balance}₽</code>
"""),
)