Files
Birthday-Pool-Bot/birthday_pool_bot/telegram_bot/ui/handlers.py

1035 lines
38 KiB
Python
Raw 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.
from aiogram import types
from aiogram.enums import MessageOriginType, ParseMode
from aiogram.fsm.context import FSMContext
from birthday_pool_bot.dto import (
PaymentData,
Pool,
Subscription,
User,
)
from birthday_pool_bot.repositories.repositories import (
PoolsRepository,
SubscriptionsRepository,
UsersRepository,
)
from . import constants, logic
from .callback_data import PoolCallbackData, SubscriptionCallbackData
from .exceptions import FlowInternalError
from .states import (
NewSubscriptionPoolState,
NewSubscriptionState,
MenuState,
SetProfileBirthdayState,
SetProfileGiftPaymentDataState,
SetProfileNameState,
SetProfilePhoneState,
)
from .utils import get_telegram_user_full_name, parse_date, parse_phone
async def fallback_message_handler(
message: types.Message,
state: FSMContext,
):
await message.reply(text=constants.ERROR_MESSAGE)
await logic.show_menu(message=message)
await state.clear()
await state.set_state(MenuState.MENU)
async def menu_message_handler(
message: types.Message,
state: FSMContext,
):
await logic.show_menu(message=message)
await state.set_state(MenuState.MENU)
async def menu_callback_handler(
callback_query: types.CallbackQuery,
state: FSMContext,
):
await logic.show_menu(message=callback_query.message)
await state.set_state(MenuState.MENU)
async def profile_message_handler(
message: types.Message,
state: FSMContext,
user: User,
):
await logic.show_profile(message=message, user=user)
await state.set_state(MenuState.PROFILE)
async def ask_profile_name_message_handler(
message: types.Message,
state: FSMContext,
):
await logic.ask_profile_name(message=message)
await state.set_state(SetProfileNameState.WAITING_FOR_NAME)
async def set_profile_name_message_handler(
message: types.Message,
state: FSMContext,
user: User,
users_repository: UsersRepository,
):
user.name = message.text
async with users_repository.transaction():
user = await users_repository.update_user(user=user)
await logic.show_profile(message=message, user=user)
await state.set_state(MenuState.PROFILE)
async def ask_profile_phone_message_handler(
message: types.Message,
state: FSMContext,
):
await logic.ask_profile_phone(message=message)
await state.set_state(SetProfilePhoneState.WAITING_FOR_PHONE)
async def set_profile_phone_message_handler(
message: types.Message,
state: FSMContext,
user: User,
users_repository: UsersRepository,
):
if message.contact is None:
await message.reply(
text=(
"Некорректный ответ, пожалуйста, отправьте свой контакт нажатием на кнопку "
"`Поделиться контактом`"
),
parse_mode=ParseMode.MARKDOWN,
)
await logic.ask_profile_phone(message=message)
await state.set_state(SetProfilePhoneState.WAITING_FOR_PHONE)
return
phone_number = parse_phone(text=message.contact.phone_number)
if phone_number is None:
await message.reply(
text="Некорректный номер телефона, попробуйте ещё раз",
)
await state.set_state(SetProfilePhoneState.WAITING_FOR_PHONE)
return
user.phone = phone_number
async with users_repository.transaction():
user = await users_repository.update_user(user=user)
await logic.show_profile(message=message, user=user)
await state.set_state(MenuState.PROFILE)
async def ask_profile_birthdate_message_handler(
message: types.Message,
state: FSMContext,
):
await logic.ask_profile_birthdate(message=message)
await state.set_state(SetProfileBirthdayState.WAITING_FOR_DATE)
async def set_profile_birthdate_message_handler(
message: types.Message,
state: FSMContext,
user: User,
users_repository: UsersRepository,
):
birthday = parse_date(text=message.text)
if birthday is None:
await logic.ask_profile_birthdate(message=message)
await state.set_state(SetProfileBirthdayState.WAITING_FOR_DATE)
return
user.birthday = birthday
async with users_repository.transaction():
await users_repository.update_user(user=user)
await logic.show_profile(message=message, user=user)
await state.set_state(MenuState.PROFILE)
async def ask_profile_gift_payment_phone_message_handler(
message: types.Message,
state: FSMContext,
):
await logic.ask_profile_gift_payment_phone(message=message)
await state.set_state(SetProfileGiftPaymentDataState.WAITING_FOR_PHONE)
async def set_profile_gift_payment_phone_message_handler(
message: types.Message,
state: FSMContext,
):
phone_number = None
if message.contact is not None:
phone_number = message.contact.phone_number
elif message.text is not None:
phone_number = message.text
else:
await logic.ask_profile_gift_payment_phone(message=message)
await state.set_state(SetProfileGiftPaymentDataState.WAITING_FOR_PHONE)
return
phone_number = parse_phone(text=phone_number)
if phone_number is None:
await message.reply(
text="Некорректный номер телефон, попробуйте ещё раз",
)
await state.set_state(SetProfileGiftPaymentDataState.WAITING_FOR_PHONE)
return
await state.update_data(gift_payment_phone=phone_number)
await logic.ask_profile_gift_payment_bank(
message=message,
)
await state.set_state(SetProfileGiftPaymentDataState.WAITING_FOR_BANK)
async def ask_profile_gift_payment_bank_message_handler(
message: types.Message,
state: FSMContext,
):
await logic.ask_profile_gift_payment_bank(message=message)
await state.set_state(SetProfileGiftPaymentDataState.WAITING_FOR_BANK)
async def set_profile_gift_payment_bank_message_handler(
message: types.Message,
state: FSMContext,
user: User,
users_repository: UsersRepository,
):
data = await state.get_data()
if "gift_payment_phone" not in data:
await message.reply(text=constants.ERROR_MESSAGE)
await logic.ask_profile_gift_payment_phone(message=message)
await state.set_state(SetProfileGiftPaymentDataState.WAITING_FOR_PHONE)
return
phone = data["gift_payment_phone"]
bank_name = message.text
if bank_name not in constants.BANKS_MAP:
await message.reply(text="Неизвестный банк, попробуйте ещё раз")
await logic.ask_profile_gift_payment_bank(message=message)
await state.set_state(SetProfileGiftPaymentDataState.WAITING_FOR_BANK)
bank = constants.BANKS_MAP[bank_name]
user.gift_payment_data = PaymentData(
phone=phone,
bank=bank,
)
async with users_repository.transaction():
user = await users_repository.update_user(user=user)
await logic.show_profile(message=message, user=user)
await state.set_state(MenuState.PROFILE)
async def subscriptions_message_handler(
message: types.Message,
state: FSMContext,
user: User,
subscriptions_repository: SubscriptionsRepository,
):
await logic.show_subscriptions(
user=user,
subscriptions_repository=subscriptions_repository,
message=message,
)
await state.set_state(MenuState.SUBSCRIPTIONS)
async def subscriptions_callback_handler(
callback_query: types.CallbackQuery,
state: FSMContext,
user: User,
subscriptions_repository: SubscriptionsRepository,
):
await logic.show_subscriptions(
user=user,
subscriptions_repository=subscriptions_repository,
message=callback_query.message,
)
await state.set_state(MenuState.SUBSCRIPTIONS)
async def subscription_callback_handler(
callback_query: types.CallbackQuery,
state: FSMContext,
user: User,
subscriptions_repository: SubscriptionsRepository,
):
callback_data = SubscriptionCallbackData.unpack(callback_query.data)
await logic.show_subscription(
from_user_id=user.id,
to_user_id=callback_data.to_user_id,
subscriptions_repository=subscriptions_repository,
callback_query=callback_query,
)
await state.set_state(MenuState.SUBSCRIPTIONS)
async def delete_subscription_callback(
callback_query: types.CallbackQuery,
state: FSMContext,
user: User,
subscriptions_repository: SubscriptionsRepository,
):
callback_data = SubscriptionCallbackData.unpack(callback_query.data)
await logic.delete_subscription(
from_user_id=user.id,
to_user_id=callback_data.to_user_id,
subscriptions_repository=subscriptions_repository,
callback_query=callback_query,
)
await logic.show_subscriptions(
user=user,
subscriptions_repository=subscriptions_repository,
message=callback_query.message,
)
await state.set_state(MenuState.SUBSCRIPTIONS)
async def new_subscription_message_handler(
message: types.Message,
state: FSMContext,
):
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
async def new_subscription_callback_handler(
callback_query: types.CallbackQuery,
state: FSMContext,
):
await logic.ask_new_subscription_user(callback_query=callback_query)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
async def ask_new_subscription_user_message_handler(
message: types.Message,
state: FSMContext,
):
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
async def set_new_subscription_user_message_handler(
message: types.Message,
state: FSMContext,
user: User,
users_repository: UsersRepository,
subscriptions_repository: SubscriptionsRepository,
):
user_name, user_phone, user_telegram_id = None, None, None
async with users_repository.transaction():
if message.contact is not None:
subscription_users = await users_repository.get_users_by_primary_keys(
phone=message.contact.phone_number,
telegram_id=message.contact.user_id,
)
subscription_user = await users_repository.merge_users(*subscription_users)
user_name = get_telegram_user_full_name(message.contact)
user_phone = message.contact.phone_number
user_telegram_id = message.contact.user_id
elif message.forward_origin is not None:
if message.forward_origin.type == MessageOriginType.HIDDEN_USER:
await message.reply(
text="Пользователь скрыл свои данные, попробуйте отправить номер телефона или его контакт",
)
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
if message.forward_origin.type != MessageOriginType.USER:
await message.reply(
text="Это сообщение не от пользователя, попробуйте ещё раз",
)
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
user_name = get_telegram_user_full_name(message.forward_origin.sender_user)
user_telegram_id = message.forward_origin.sender_user.id
subscription_user = await users_repository.get_user_by_telegram_id(
telegram_id=user_telegram_id,
)
elif message.text:
user_phone = parse_phone(text=message.text)
if user_phone is None:
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
subscription_user = await users_repository.get_user_by_phone(phone=user_phone)
if subscription_user is None:
subscription_user = User(
name=user_name,
phone=user_phone,
telegram_id=user_telegram_id,
)
async with users_repository.transaction():
subscription_user = await users_repository.create_user(user=subscription_user)
if subscription_user.id == user.id:
await message.reply("Нельзя подписаться на самого себя")
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
async with subscriptions_repository.transaction():
subscription = await subscriptions_repository.get_subscription(
from_user_id=user.id,
to_user_id=subscription_user.id,
)
if subscription is not None:
await message.reply(text="У вас уже есть подписка на этого человека")
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
await state.update_data(
subscription_user_id=subscription_user.id,
)
if subscription_user.birthday is None:
await logic.ask_new_subscription_user_birthday(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_DATE)
return
await logic.ask_new_subscription_name(
message=message,
users_repository=users_repository,
subscription_user_id=subscription_user.id,
)
await state.set_state(NewSubscriptionState.WAITING_FOR_NAME)
async def ask_new_subscription_user_birthday_message_handler(
message: types.Message,
state: FSMContext,
):
await logic.ask_new_subscription_user_birthday(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_DATE)
async def set_new_subscription_user_birthday_message_handler(
message: types.Message,
state: FSMContext,
users_repository: UsersRepository,
):
birthday = parse_date(text=message.text)
if birthday is None:
await logic.ask_new_subscription_user_birthday(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_DATE)
return
state_data = await state.get_data()
subscription_user_id = state_data.get("subscription_user_id")
if subscription_user_id is None:
await message.reply(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
async with users_repository.transaction():
subscription_user = await users_repository.get_user_by_id(user_id=subscription_user_id)
if subscription_user is None:
await message.reply(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
subscription_user.birthday = birthday
await users_repository.update_user(user=subscription_user)
await logic.ask_new_subscription_name(
message=message,
users_repository=users_repository,
subscription_user_id=subscription_user.id,
)
await state.set_state(NewSubscriptionState.WAITING_FOR_NAME)
async def ask_new_subscription_name_message_handler(
message: types.Message,
state: FSMContext,
users_repository: UsersRepository,
):
state_data = await state.get_data()
subscription_user_id = state_data.get("subscription_user_id")
if subscription_user_id is None:
await message.reply(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
try:
await logic.ask_new_subscription_name(
message=message,
users_repository=users_repository,
subscription_user_id=subscription_user_id,
)
except FlowInternalError:
await message.reply(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
await state.set_state(NewSubscriptionState.WAITING_FOR_NAME)
async def set_new_subscription_name_message_handler(
message: types.Message,
state: FSMContext,
user: User,
pools_repository: PoolsRepository,
subscriptions_repository: SubscriptionsRepository,
users_repository: UsersRepository,
):
state_data = await state.get_data()
subscription_user_id = state_data.get("subscription_user_id")
if subscription_user_id is None:
await message.reply(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
async with users_repository.transaction():
subscription_user = await users_repository.get_user_by_id(user_id=subscription_user_id)
if subscription_user is None or subscription_user.birthday is None:
await message.reply(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
await state.update_data(subscription_name=message.text)
await logic.ask_new_subscription_pool_decision(
message=message,
pools_repository=pools_repository,
users_repository=users_repository,
subscription_user_id=subscription_user_id,
)
await state.set_state(NewSubscriptionState.WAITING_FOR_POOL_DECISION)
async def ask_new_subscription_pool_decision_message_handler(
message: types.Message,
state: FSMContext,
pools_repository: PoolsRepository,
users_repository: UsersRepository,
):
state_data = await state.get_data()
subscription_user_id = state_data.get("subscription_user_id")
if subscription_user_id is None:
await message.reply(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
try:
await logic.ask_new_subscription_pool_decision(
message=message,
pools_repository=pools_repository,
users_repository=users_repository,
subscription_user_id=subscription_user_id,
)
except FlowInternalError:
await message.reply(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
await state.set_state(NewSubscriptionState.WAITING_FOR_POOL_DECISION)
async def ask_new_subscription_pool_decision_callback_handler(
callback_query: types.Message,
state: FSMContext,
pools_repository: PoolsRepository,
users_repository: UsersRepository,
):
state_data = await state.get_data()
subscription_user_id = state_data.get("subscription_user_id")
if subscription_user_id is None:
await callback_query.answer(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=callback_query.message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
try:
await logic.ask_new_subscription_pool_decision(
message=callback_query.message,
pools_repository=pools_repository,
users_repository=users_repository,
subscription_user_id=subscription_user_id,
)
except FlowInternalError:
await message.reply(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=callback_query.message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
await state.set_state(NewSubscriptionState.WAITING_FOR_POOL_DECISION)
async def show_new_subscription_choosing_pools_message_handler(
message: types.Message,
state: FSMContext,
user: User,
users_repository: UsersRepository,
pools_repository: PoolsRepository,
):
state_data = await state.get_data()
subscription_user_id = state_data.get("subscription_user_id")
if subscription_user_id is None:
await message.reply(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
try:
await logic.show_new_subscription_choosing_pools(
user=user,
users_repository=users_repository,
pools_repository=pools_repository,
subscription_user_id=subscription_user_id,
message=message,
)
except FlowInternalError:
await message.reply(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
await state.set_state(NewSubscriptionState.WAITING_FOR_CHOOSE_POOL)
async def show_new_subscription_choosing_pools_callback_handler(
callback_query: types.CallbackQuery,
state: FSMContext,
user: User,
users_repository: UsersRepository,
pools_repository: PoolsRepository,
):
state_data = await state.get_data()
subscription_user_id = state_data.get("subscription_user_id")
if subscription_user_id is None:
await callback_query.answer(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=callback_query.message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
try:
await logic.show_new_subscription_choosing_pools(
user=user,
users_repository=users_repository,
pools_repository=pools_repository,
subscription_user_id=subscription_user_id,
message=callback_query.message,
)
except FlowInternalError:
await callback_query.answer(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=callback_query.message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
await state.set_state(NewSubscriptionState.WAITING_FOR_CHOOSE_POOL)
async def show_new_subscription_choosing_pool_callback_handler(
callback_query: types.CallbackQuery,
state: FSMContext,
pools_repository: PoolsRepository,
):
callback_data = PoolCallbackData.unpack(callback_query.data)
try:
await logic.show_new_subscription_choosing_pool(
pools_repository=pools_repository,
pool_id=callback_data.id,
callback_query=callback_query,
)
except FlowInternalError:
await callback_query.answer(text=constants.ERROR_MESSAGE)
await logic.show_new_subscription_choosing_pools(
user=user,
users_repository=users_repository,
pools_repository=pools_repository,
subscription_user_id=subscription_user_id,
)
await state.set_state(NewSubscriptionState.WAITING_FOR_CHOOSE_POOL)
return
await state.set_state(NewSubscriptionState.WAITING_FOR_CHOOSE_POOL)
async def choose_new_subscription_pool_callback_handler(
callback_query: types.CallbackQuery,
state: FSMContext,
users_repository: UsersRepository,
pools_repository: PoolsRepository,
):
state_data = await state.get_data()
subscription_user_id = state_data.get("subscription_user_id")
subscription_name = state_data.get("subscription_name")
if not all((subscription_user_id, subscription_name)):
await message.reply(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
async with users_repository.transaction():
subscription_user = await users_repository.get_user_by_id(
user_id=subscription_user_id,
)
if subscription_user is None:
await message.reply(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
callback_data = PoolCallbackData.unpack(callback_query.data)
async with pools_repository.transaction():
subscription_pool = await pools_repository.get_pool_by_id(
pool_id=callback_data.id,
)
if subscription_pool is None:
await callback_query.answer(text=constants.ERROR_MESSAGE)
await logic.show_new_subscription_choosing_pools(
user=user,
users_repository=users_repository,
pools_repository=pools_repository,
subscription_user_id=subscription_user_id,
callback_query=callback_query,
)
await state.set_state(NewSubscriptionState.WAITING_FOR_CHOOSE_POOL)
return
await state.update_data(
subscription_pool_id=callback_data.id,
)
try:
await logic.ask_new_subscription_confirmation(
message=callback_query.message,
users_repository=users_repository,
pools_repository=pools_repository,
subscription_name=subscription_name,
subscription_user_id=subscription_user_id,
subscription_pool_id=callback_data.id,
)
except FlowInternalError:
await callback_query.answer(text=constants.ERROR_MESSAGE)
await logic.show_new_subscription_choosing_pools(
message=callback_query.message,
users_repository=users_repository,
pools_repository=pools_repository,
subscription_name=subscription_name,
subscription_user_id=subscription_user_id,
subscription_pool_id=callback_data.id,
)
await state.set_state(NewSubscriptionState.WAITING_FOR_CHOOSE_POOL)
return
await state.set_state(NewSubscriptionState.WAITING_FOR_CONFIRMATION)
async def ask_new_subscription_pool_description_message_handler(
message: types.Message,
state: FSMContext,
):
await logic.ask_new_subscription_pool_description(message=message)
await state.set_state(NewSubscriptionPoolState.WAITING_FOR_DESCRIPTION)
async def set_new_subscription_pool_description_message_handler(
message: types.Message,
state: FSMContext,
):
description = message.text
await state.update_data(subscription_pool_description=description)
await logic.ask_new_subscription_pool_payment_phone(message=message)
await state.set_state(NewSubscriptionPoolState.WAITING_FOR_PAYMENT_PHONE)
async def ask_new_subscription_pool_payment_phone_message_handler(
message: types.Message,
state: FSMContext,
user: User,
):
await logic.ask_new_subscription_pool_payment_phone(message=message, user=user)
await state.set_state(NewSubscriptionPoolState.WAITING_FOR_PAYMENT_PHONE)
async def set_new_subscription_pool_payment_phone_message_handler(
message: types.Message,
state: FSMContext,
):
phone_number = None
if message.contact is not None:
phone_number = message.contact.phone_number
elif message.text is not None:
phone_number = message.text
else:
await message.reply(text="Некорректный номер телефона, попробуйте ещё раз")
await logic.ask_new_subscription_pool_payment_phone(message=message)
await state.set_state(NewSubscriptionPoolState.WAITING_FOR_PAYMENT_PHONE)
return
phone_number = parse_phone(text=phone_number)
if phone_number is None:
await message.reply(
text="Некорректный номер телефона, попробуйте ещё раз",
)
await state.set_state(NewSubscriptionPoolState.WAITING_FOR_PAYMENT_PHONE)
return
await state.update_data(subscription_pool_phone=phone_number)
await logic.ask_new_subscription_pool_payment_bank(message=message)
await state.set_state(NewSubscriptionPoolState.WAITING_FOR_PAYMENT_BANK)
async def set_new_subscription_pool_payment_data_from_profile_message_handler(
message: types.Message,
state: FSMContext,
user: User,
users_repository: UsersRepository,
pools_repository: PoolsRepository,
):
if user.gift_payment_data is None:
await message.reply(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_pool_payment_phone(message=message, user=user)
await state.set_state(NewSubscriptionPoolState.WAITING_FOR_PAYMENT_PHONE)
return
state_data = await state.get_data()
subscription_user_id = state_data.get("subscription_user_id")
subscription_name = state_data.get("subscription_name")
subscription_pool_description = state_data.get("subscription_pool_description")
if not all((subscription_user_id, subscription_name)):
await message.reply(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
await state.update_data(
subscription_pool_phone=user.gift_payment_data.phone,
subscription_pool_bank=user.gift_payment_data.bank,
)
await logic.ask_new_subscription_confirmation(
message=message,
users_repository=users_repository,
pools_repository=pools_repository,
subscription_name=subscription_name,
subscription_user_id=subscription_user_id,
subscription_pool_description=subscription_pool_description,
subscription_pool_phone=user.gift_payment_data.phone,
subscription_pool_bank=user.gift_payment_data.bank,
)
await state.set_state(NewSubscriptionState.WAITING_FOR_CONFIRMATION)
async def ask_new_subscription_pool_payment_bank_message_handler(
message: types.Message,
state: FSMContext,
):
await logic.ask_new_subscription_pool_payment_bank(message=message)
await state.set_state(NewSubscriptionPoolState.WAITING_FOR_PAYMENT_BANK)
async def set_new_subscription_pool_payment_bank_message_handler(
message: types.Message,
state: FSMContext,
users_repository: UsersRepository,
pools_repository: PoolsRepository,
):
state_data = await state.get_data()
subscription_user_id = state_data.get("subscription_user_id")
subscription_name = state_data.get("subscription_name")
subscription_pool_description = state_data.get("subscription_pool_description")
subscription_pool_phone = state_data.get("subscription_pool_phone")
if not all((subscription_user_id, subscription_name)):
await message.reply(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
if subscription_pool_phone is None:
await message.reply(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_pool_decision(message=message)
await state.set_state(NewSubscriptionPoolState.WAITING_FOR_DESCRIPTION)
return
async with users_repository.transaction():
subscription_user = await users_repository.get_user_by_id(
user_id=subscription_user_id,
)
if subscription_user is None:
await message.reply(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
bank_name = message.text
if bank_name not in constants.BANKS_MAP:
await message.reply(text="Неизвестный банк, попробуйте ещё раз")
await logic.ask_profile_gift_payment_bank(message=message)
await state.set_state(SetProfileGiftPaymentDataState.WAITING_FOR_BANK)
bank = constants.BANKS_MAP[bank_name]
await state.update_data(subscription_pool_bank=bank)
await logic.ask_new_subscription_confirmation(
message=message,
users_repository=users_repository,
pools_repository=pools_repository,
subscription_name=subscription_name,
subscription_user_id=subscription_user_id,
subscription_pool_description=subscription_pool_description,
subscription_pool_phone=subscription_pool_phone,
subscription_pool_bank=bank,
)
await state.set_state(NewSubscriptionState.WAITING_FOR_CONFIRMATION)
async def ask_new_subscription_confirmation_message_handler(
message: types.Message,
state: FSMContext,
users_repository: UsersRepository,
pools_repository: PoolsRepository,
):
state_data = await state.get_data()
subscription_user_id = state_data.get("subscription_user_id")
subscription_name = state_data.get("subscription_name")
subscription_pool_id = state_data.get("subscription_pool_id")
subscription_pool_description = state_data.get("subscription_pool_description")
subscription_pool_phone = state_data.get("subscription_pool_phone")
subscription_pool_bank = state_data.get("subscription_pool_bank")
if not all((subscription_user_id, subscription_name)):
await message.reply(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
async with users_repository.transaction():
subscription_user = await users_repository.get_user_by_id(
user_id=subscription_user_id,
)
if subscription_user is None:
await message.reply(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
try:
await logic.ask_new_subscription_confirmation(
message=message,
users_repository=users_repository,
pools_repository=pools_repository,
subscription_name=subscription_name,
subscription_user_id=subscription_user_id,
subscription_pool_id=subscription_pool_id,
subscription_pool_description=subscription_pool_description,
subscription_pool_phone=subscription_pool_phone,
subscription_pool_bank=subscription_pool_bank,
)
except FlowInternalError:
await message.reply(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
await state.set_state(NewSubscriptionState.WAITING_FOR_CONFIRMATION)
async def confirm_new_subscription_callback_handler(
callback_query: types.CallbackQuery,
state: FSMContext,
user: User,
pools_repository: PoolsRepository,
subscriptions_repository: SubscriptionsRepository,
users_repository: UsersRepository,
):
state_data = await state.get_data()
subscription_user_id = state_data.get("subscription_user_id")
subscription_name = state_data.get("subscription_name")
subscription_pool_id = state_data.get("subscription_pool_id")
subscription_pool_description = state_data.get("subscription_pool_description")
subscription_pool_phone = state_data.get("subscription_pool_phone")
subscription_pool_bank = state_data.get("subscription_pool_bank")
if not all((subscription_user_id, subscription_name)):
await callback_query.answer(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=callback_query.message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
async with users_repository.transaction():
subscription_user = await users_repository.get_user_by_id(
user_id=subscription_user_id,
)
if subscription_user is None:
await callback_query.answer(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=callback_query.message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
subscription_pool = None
if subscription_pool_id is not None:
async with pools_repository.transaction():
subscription_pool = await pools_repository.get_pool_by_id(
pool_id=subscription_pool_id,
)
if subscription_pool is None:
await callback_query.answer(text=constants.ERROR_MESSAGE)
await logic.ask_new_subscription_user(message=callback_query.message)
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
return
if subscription_pool is None and all((subscription_pool_phone, subscription_pool_bank)):
subscription_pool = Pool(
owner_id=user.id,
birthday_user_id=subscription_user.id,
description=subscription_pool_description,
payment_data=PaymentData(
phone=subscription_pool_phone,
bank=subscription_pool_bank,
),
)
async with pools_repository.transaction():
subscription_pool = await pools_repository.create_pool(pool=subscription_pool)
subscription_pool_id = subscription_pool.id
subscription = Subscription(
from_user_id=user.id,
to_user_id=subscription_user_id,
name=subscription_name,
pool_id=subscription_pool_id,
)
async with subscriptions_repository.transaction():
await subscriptions_repository.create_subscription(
subscription=subscription,
)
await logic.show_subscriptions(
user=user,
subscriptions_repository=subscriptions_repository,
message=callback_query.message,
)
await state.clear()
await state.set_state(MenuState.SUBSCRIPTIONS)