97 lines
3.0 KiB
Python
97 lines
3.0 KiB
Python
from collections.abc import Iterable
|
|
|
|
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
|
|
from aiogram.utils.keyboard import InlineKeyboardBuilder
|
|
|
|
from config import RENEWAL_PRICES
|
|
from handlers.buttons import BACK, CUSTOM_AMOUNT
|
|
from handlers.payments.currency_rates import format_for_user
|
|
|
|
|
|
async def payment_options_for_user(
|
|
db_session,
|
|
tg_id: int,
|
|
language_code: str | None,
|
|
*,
|
|
force_currency: str | None = None,
|
|
) -> list[dict]:
|
|
items = []
|
|
for price_rub in RENEWAL_PRICES.values():
|
|
txt = await format_for_user(
|
|
db_session,
|
|
tg_id,
|
|
price_rub,
|
|
language_code,
|
|
force_currency=force_currency,
|
|
)
|
|
items.append({"text": txt, "callback_data": f"amount|{int(price_rub)}"})
|
|
return items
|
|
|
|
|
|
def payment_options(currency: str = "RUB") -> list[dict]:
|
|
return [{"text": f"{price} {currency}", "callback_data": f"amount|{price}"} for price in RENEWAL_PRICES.values()]
|
|
|
|
|
|
def build_amounts_keyboard(
|
|
*,
|
|
prefix: str,
|
|
pattern: str,
|
|
back_cb: str = "balance",
|
|
custom_cb: str | tuple[str, str] | None = None,
|
|
per_row: int = 2,
|
|
opts: Iterable[dict] | None = None,
|
|
) -> InlineKeyboardMarkup:
|
|
items = list(opts) if opts is not None else payment_options()
|
|
b = InlineKeyboardBuilder()
|
|
row = []
|
|
for i, item in enumerate(items, 1):
|
|
row.append(
|
|
InlineKeyboardButton(
|
|
text=item["text"],
|
|
callback_data=pattern.format(prefix=prefix, price=item["callback_data"].split("|", 1)[-1]),
|
|
)
|
|
)
|
|
if i % per_row == 0:
|
|
b.row(*row)
|
|
row = []
|
|
if row:
|
|
b.row(*row)
|
|
if custom_cb:
|
|
cb = custom_cb[1] if isinstance(custom_cb, tuple) else custom_cb
|
|
b.row(InlineKeyboardButton(text=CUSTOM_AMOUNT, callback_data=cb))
|
|
b.row(InlineKeyboardButton(text=BACK, callback_data=back_cb))
|
|
return b.as_markup()
|
|
|
|
|
|
def parse_amount_from_callback(data: str, *, prefixes: list[str]) -> int | None:
|
|
for p in prefixes:
|
|
if data.startswith(f"{p}_amount|"):
|
|
try:
|
|
return int(data.split("|", 1)[1])
|
|
except Exception:
|
|
return None
|
|
if data.startswith(f"{p}|amount|"):
|
|
try:
|
|
return int(data.rsplit("|", 1)[-1])
|
|
except Exception:
|
|
return None
|
|
if data.startswith(f"{p}|"):
|
|
try:
|
|
return int(data.split("|", 1)[1])
|
|
except Exception:
|
|
return None
|
|
return None
|
|
|
|
|
|
def pay_keyboard(url: str, *, pay_text: str, back_cb: str) -> InlineKeyboardMarkup:
|
|
b = InlineKeyboardBuilder()
|
|
b.row(InlineKeyboardButton(text=pay_text, url=url))
|
|
b.row(InlineKeyboardButton(text=BACK, callback_data=back_cb))
|
|
return b.as_markup()
|
|
|
|
|
|
def back_keyboard(back_cb: str) -> InlineKeyboardMarkup:
|
|
b = InlineKeyboardBuilder()
|
|
b.row(InlineKeyboardButton(text=BACK, callback_data=back_cb))
|
|
return b.as_markup()
|