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)