Implement buy flow and migrate DTOs to schemas
Move DTO definitions from dto/ to schemas/ and update imports. Add buy handler with FSM state management for device selection, whitelist toggling, and duration choice. Include pricing logic, inline keyboards, and new configuration fields.
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from aiogram.utils.keyboard import InlineKeyboardBuilder
|
||||
|
||||
from config import settings
|
||||
from misc.utils import convert_duration_to_int
|
||||
from schemas.subscriptions import SubscriptionDuration
|
||||
|
||||
main_menu: InlineKeyboardMarkup = InlineKeyboardBuilder(
|
||||
[
|
||||
[
|
||||
@@ -14,6 +18,71 @@ main_menu: InlineKeyboardMarkup = InlineKeyboardBuilder(
|
||||
]
|
||||
).as_markup()
|
||||
|
||||
_return_to_menu_btn: InlineKeyboardButton = InlineKeyboardButton(
|
||||
text="⬅️ Назад", callback_data="menu:main"
|
||||
)
|
||||
|
||||
|
||||
def _return_btn(
|
||||
data: str = "menu:main", text: str = "⬅️ Назад"
|
||||
) -> InlineKeyboardButton:
|
||||
return InlineKeyboardButton(text=text, callback_data=data)
|
||||
|
||||
|
||||
return_to_menu: InlineKeyboardMarkup = InlineKeyboardBuilder(
|
||||
[[InlineKeyboardButton(text="⬅️ Назад", callback_data="menu:main")]]
|
||||
[[_return_to_menu_btn]]
|
||||
).as_markup()
|
||||
|
||||
|
||||
def devices_selector(current: int = settings.min_devices, whitelists: bool = False):
|
||||
builder = InlineKeyboardBuilder()
|
||||
|
||||
buttons = [
|
||||
InlineKeyboardButton(
|
||||
text=f"{'✅ ' if i == current else ''}{i}", callback_data=f"devices:{i}"
|
||||
)
|
||||
for i in range(settings.min_devices, settings.max_devices + 1)
|
||||
]
|
||||
builder.add(*buttons).adjust(6)
|
||||
|
||||
wl_icon = "✅ " if whitelists else ""
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text=f"{wl_icon}Обход Белых Списков (+100₽)",
|
||||
callback_data="whitelist:toggle",
|
||||
)
|
||||
)
|
||||
builder.row(InlineKeyboardButton(text="🟢", callback_data="confirm"))
|
||||
builder.row(_return_to_menu_btn)
|
||||
|
||||
return builder.as_markup()
|
||||
|
||||
|
||||
def duration_selector(
|
||||
current: SubscriptionDuration = SubscriptionDuration.MONTH,
|
||||
back_cb: str = "menu:main",
|
||||
) -> InlineKeyboardMarkup:
|
||||
builder = InlineKeyboardBuilder()
|
||||
duration_int = convert_duration_to_int(current)
|
||||
|
||||
durations = [
|
||||
(1, "1 Месяц"),
|
||||
(3, "3 Месяца"),
|
||||
(6, "6 Месяцев"),
|
||||
(12, "1 Год"),
|
||||
]
|
||||
|
||||
for val, label in durations:
|
||||
is_selected = val == duration_int
|
||||
|
||||
builder.button(
|
||||
text=f"{'✅ ' if is_selected else ''}{label}",
|
||||
callback_data=f"duration:{val}",
|
||||
)
|
||||
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="🛒 Перейти к оплате", callback_data="confirm")
|
||||
)
|
||||
builder.row(_return_btn(back_cb))
|
||||
|
||||
return builder.as_markup()
|
||||
|
||||
Reference in New Issue
Block a user