1035 lines
38 KiB
Python
1035 lines
38 KiB
Python
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)
|