Private
Public Access
forked from FOSS/AutoShop-Djimbo-Simple
360 lines
14 KiB
Python
360 lines
14 KiB
Python
# - *- 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>
|
||
"""),
|
||
)
|