Fix bugs, add README and Makefile
This commit is contained in:
@@ -46,6 +46,7 @@ class Pool(BaseModel):
|
||||
payment_data: PaymentData
|
||||
|
||||
owner: User | None = None
|
||||
birthday_user: User | None = None
|
||||
|
||||
|
||||
class PoolFilter(BaseFilter):
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import uuid
|
||||
from datetime import timedelta
|
||||
from typing import AsyncContextManager, AsyncGenerator, Protocol
|
||||
from typing import Any
|
||||
|
||||
from birthday_pool_bot.dto import Pool, User
|
||||
import pathlib
|
||||
from datetime import timedelta
|
||||
from typing import AsyncContextManager, Generator, Protocol
|
||||
|
||||
|
||||
class MessengerInterface(Protocol):
|
||||
|
||||
@@ -2,6 +2,7 @@ import asyncio
|
||||
|
||||
import typer
|
||||
|
||||
from birthday_pool_bot.repositories import RepositoriesContainer
|
||||
from .service import NotificationsService
|
||||
from .settings import NotificationsSettings
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ from aiogram.enums import ParseMode
|
||||
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
||||
from apscheduler.triggers.cron import CronTrigger
|
||||
|
||||
from birthday_pool_bot.repositories import RepositoriesContainer
|
||||
from .settings import NotificationsSettings
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import contextvars
|
||||
from contextlib import asynccontextmanager, contextmanager
|
||||
from typing import Generic, TypeVar
|
||||
from typing import AsyncGenerator, Generator, Generic, TypeVar
|
||||
|
||||
from pydantic_filters import BasePagination, BaseSort
|
||||
from pydantic_filters.drivers.sqlalchemy import append_to_statement
|
||||
from sqlalchemy import func
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
@@ -9,7 +10,9 @@ from sqlalchemy.ext.asyncio import create_async_engine
|
||||
from sqlmodel import delete, insert, select, update
|
||||
from sqlmodel.ext.asyncio.session import AsyncSession
|
||||
|
||||
from birthday_pool_bot.interfaces import RepositoryInterface
|
||||
from .exceptions import AlreadyExistsError, HaveNoSessionError
|
||||
from .settings import RepositorySettings
|
||||
from .tables import BaseSQLModel
|
||||
|
||||
|
||||
DTOType = TypeVar("DTOType")
|
||||
|
||||
@@ -12,7 +12,7 @@ from .migrator import Migrator
|
||||
def callback(ctx: typer.Context):
|
||||
ctx.obj = ctx.obj or {}
|
||||
|
||||
settings = ctx.obj["settings"]
|
||||
settings: Settings = ctx.obj["settings"]
|
||||
ctx.obj["migrator"] = Migrator(settings=settings.repository)
|
||||
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ def upgrade() -> None:
|
||||
sa.Column("name", sqlmodel.sql.sqltypes.AutoString(), nullable=True),
|
||||
sa.Column("birthday", sa.Date(), nullable=True),
|
||||
sa.Column("phone", sqlmodel.sql.sqltypes.AutoString(), nullable=True),
|
||||
sa.Column("telegram_id", sa.Integer(), nullable=True),
|
||||
sa.Column("telegram_id", sa.BigInteger(), nullable=True),
|
||||
sa.Column("gift_payment_data", sa.JSON(), nullable=True),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
sa.UniqueConstraint("id"),
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
from pydantic_filters import OffsetPagination
|
||||
import uuid
|
||||
from typing import AsyncGenerator
|
||||
|
||||
from pydantic_filters import BasePagination, OffsetPagination
|
||||
from sqlalchemy.orm import joinedload
|
||||
|
||||
from birthday_pool_bot.dto import Pool, PoolFilter
|
||||
@@ -14,20 +17,38 @@ class PoolsRepository(BaseRepository[Pool, PoolFilter]):
|
||||
filter_ = PoolFilter(birthday_user_id={birthday_user_id})
|
||||
return await self.get_items_count(filter_=filter_)
|
||||
|
||||
async def get_pools_by_birthday_user_id(self, birthday_user_id: uuid.UUID) -> list[Pool]:
|
||||
async def get_pools_by_birthday_user_id(
|
||||
self,
|
||||
birthday_user_id: uuid.UUID,
|
||||
pagination: BasePagination | None = None,
|
||||
with_owner: bool = False,
|
||||
) -> AsyncGenerator[Pool]:
|
||||
filter_ = PoolFilter(birthday_user_id={birthday_user_id})
|
||||
return [pool async for pool in self.get_items(filter_=filter_)]
|
||||
options = []
|
||||
if with_owner:
|
||||
options.append(joinedload(DBPool.owner))
|
||||
|
||||
pools_generator = self.get_items(
|
||||
filter_=filter_,
|
||||
pagination=pagination,
|
||||
options=options,
|
||||
)
|
||||
async for pool in pools_generator:
|
||||
yield pool
|
||||
|
||||
async def get_pool_by_id(
|
||||
self,
|
||||
pool_id: uuid.UUID,
|
||||
with_owner: bool = False,
|
||||
with_birthday_user: bool = False,
|
||||
) -> Pool | None:
|
||||
filter_ = PoolFilter(id={pool_id})
|
||||
pagination = OffsetPagination(limit=1)
|
||||
options = []
|
||||
if with_owner:
|
||||
options.append(joinedload(DBPool.owner))
|
||||
if with_birthday_user:
|
||||
options.append(joinedload(DBPool.birthday_user))
|
||||
|
||||
pools_generator = self.get_items(
|
||||
filter_=filter_,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import uuid
|
||||
from typing import AsyncGenerator, Iterable
|
||||
|
||||
from pydantic_filters import BasePagination, OffsetPagination
|
||||
from sqlalchemy.orm import joinedload
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import uuid
|
||||
from datetime import date
|
||||
from typing import Container, Sequence, TypeVar
|
||||
|
||||
from pydantic_filters import OffsetPagination
|
||||
from sqlalchemy import Column, func, inspect, select
|
||||
from pydantic_filters import BasePagination, OffsetPagination
|
||||
from sqlalchemy import Column, func, inspect, or_, select, update
|
||||
from sqlmodel import SQLModel
|
||||
|
||||
from birthday_pool_bot.dto import User, UserFilter
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import uuid
|
||||
import enum
|
||||
from datetime import date
|
||||
from typing import Self, List
|
||||
from typing import Any, Self
|
||||
|
||||
import sqlalchemy as sa
|
||||
from pydantic import BaseModel
|
||||
from sqlmodel import SQLModel, Field, Relationship
|
||||
|
||||
from birthday_pool_bot.dto import (
|
||||
BankEnum,
|
||||
PaymentData as DTOPaymentData,
|
||||
Pool as DTOPool,
|
||||
Subscription as DTOSubscription,
|
||||
@@ -46,7 +45,10 @@ class User(BaseSQLModel, table=True):
|
||||
name: str | None = Field(nullable=True)
|
||||
birthday: date | None = Field(nullable=True)
|
||||
phone: str | None = Field(default=None, nullable=True)
|
||||
telegram_id: int | None = Field(default=None, nullable=True)
|
||||
telegram_id: int | None = Field(
|
||||
default=None,
|
||||
sa_column=sa.Column(sa.BigInteger(), nullable=True),
|
||||
)
|
||||
gift_payment_data: dict | None = Field(
|
||||
sa_column=sa.Column(sa.JSON, nullable=True),
|
||||
default_factory=dict,
|
||||
@@ -118,6 +120,12 @@ class Pool(BaseSQLModel, table=True):
|
||||
"lazy": None,
|
||||
},
|
||||
)
|
||||
birthday_user: User = Relationship(
|
||||
sa_relationship_kwargs={
|
||||
"primaryjoin": "User.id == Pool.birthday_user_id",
|
||||
"lazy": None,
|
||||
},
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_item(cls, item: DTOPool) -> Self:
|
||||
@@ -128,6 +136,11 @@ class Pool(BaseSQLModel, table=True):
|
||||
description=item.description,
|
||||
payment_data=item.payment_data.model_dump_json(),
|
||||
owner=None if item.owner is None else DTOUser.from_item(item.owner),
|
||||
birthday_user=(
|
||||
None
|
||||
if item.birthday_user is None else
|
||||
DTOUser.from_item(item.birthday_user)
|
||||
),
|
||||
)
|
||||
|
||||
def to_item(self) -> DTOPool:
|
||||
@@ -137,7 +150,8 @@ class Pool(BaseSQLModel, table=True):
|
||||
birthday_user_id=self.birthday_user_id,
|
||||
description=self.description,
|
||||
payment_data=DTOPaymentData.model_validate_json(self.payment_data),
|
||||
owner=None if self.owner is None else self.owner.to_item()
|
||||
owner=None if self.owner is None else self.owner.to_item(),
|
||||
birthday_user=None if self.birthday_user is None else self.birthday_user.to_item(),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ from .settings import TelegramBotSettings
|
||||
__all__ = (
|
||||
# cli
|
||||
"get_cli",
|
||||
# fabric
|
||||
"get_telegram_bot_service",
|
||||
# settings
|
||||
"TelegramBotSettings",
|
||||
)
|
||||
|
||||
@@ -3,6 +3,7 @@ import facet
|
||||
from aiogram.fsm.storage.memory import MemoryStorage
|
||||
|
||||
from birthday_pool_bot.repositories import RepositoriesContainer
|
||||
from .settings import TelegramBotSettings
|
||||
from .ui import setup_dispatcher
|
||||
|
||||
|
||||
|
||||
@@ -12,15 +12,15 @@ def get_telegram_bot_service(
|
||||
repositories_container: RepositoriesContainer,
|
||||
) -> BaseTelegramBotService:
|
||||
match settings.method:
|
||||
case TelegramBotMethodEnum.POLLING:
|
||||
case TelegramBotMethodEnum.POLLING.value:
|
||||
return TelegramBotPollingService(
|
||||
settings=settings,
|
||||
repositories_container=repositories_container,
|
||||
)
|
||||
case TelegramBotMethodEnum.WEBHOOK:
|
||||
case TelegramBotMethodEnum.WEBHOOK.value:
|
||||
return TelegramBotWebhookService(
|
||||
settings=settings,
|
||||
repositories_container=repositories_container,
|
||||
)
|
||||
case _:
|
||||
raise ValueError(f"Cannot create telegram bot with method '{settings.method.value}'")
|
||||
raise ValueError(f"Cannot create telegram bot with method '{settings.method}'")
|
||||
|
||||
@@ -3,6 +3,7 @@ from birthday_pool_bot.telegram_bot.base import BaseTelegramBotService
|
||||
|
||||
class TelegramBotPollingService(BaseTelegramBotService):
|
||||
async def listen_events(self):
|
||||
await self._bot.delete_webhook()
|
||||
await self._dispatcher._polling( # pylint: disable=protected-access
|
||||
bot=self._bot,
|
||||
polling_timeout=self._settings.timeout,
|
||||
|
||||
@@ -8,7 +8,7 @@ from birthday_pool_bot.telegram_bot.settings import TelegramBotSettings
|
||||
|
||||
class TelegramBotPollingSettings(TelegramBotSettings):
|
||||
method: Literal[TelegramBotMethodEnum.POLLING.value] = (
|
||||
TelegramBotMethodEnum.POLLING
|
||||
TelegramBotMethodEnum.POLLING.value
|
||||
)
|
||||
|
||||
timeout: PositiveInt = 10 # in seconds
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import enum
|
||||
import uuid
|
||||
from typing import Any
|
||||
|
||||
from aiogram.filters.callback_data import CallbackData
|
||||
from pydantic import Field
|
||||
|
||||
|
||||
class PaginatorCallbackData(CallbackData, prefix=""):
|
||||
@@ -18,7 +16,7 @@ class SubscriptionsCallbackData(PaginatorCallbackData, prefix="subscriptions"):
|
||||
pass
|
||||
|
||||
|
||||
class AddSubscriptionCallbackData(CallbackData, prefix="subscription_add"):
|
||||
class NewSubscriptionCallbackData(CallbackData, prefix="new_subscription"):
|
||||
pass
|
||||
|
||||
|
||||
@@ -27,7 +25,7 @@ class ConfirmAnswerEnum(str, enum.Enum):
|
||||
NO = "no"
|
||||
|
||||
|
||||
class AddSubscriptionConfirmCallbackData(CallbackData, prefix="subscription_add_confirm"):
|
||||
class NewSubscriptionConfirmCallbackData(CallbackData, prefix="new_subscription_confirm"):
|
||||
answer: ConfirmAnswerEnum
|
||||
|
||||
|
||||
@@ -43,5 +41,19 @@ class SubscriptionCallbackData(CallbackData, prefix="subscription"):
|
||||
action: SubscriptionActionEnum = SubscriptionActionEnum.SHOW
|
||||
|
||||
|
||||
class AddSubscriptionPoolsCallbackData(PaginatorCallbackData, prefix="subscription_add_pool"):
|
||||
to_user_id: uuid.UUID
|
||||
class PoolsCallbackData(PaginatorCallbackData, prefix="pools"):
|
||||
pass
|
||||
|
||||
|
||||
class PoolsBackCallbackData(CallbackData, prefix="pools_back"):
|
||||
pass
|
||||
|
||||
|
||||
class PoolActionEnum(str, enum.Enum):
|
||||
SHOW = "show"
|
||||
CHOOSE = "choose"
|
||||
|
||||
|
||||
class PoolCallbackData(CallbackData, prefix="pool"):
|
||||
id: uuid.UUID
|
||||
action: PoolActionEnum = PoolActionEnum.SHOW
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
import aiogram
|
||||
from aiogram.filters import Command
|
||||
from aiogram_dialog import DialogManager
|
||||
from birthday_pool_bot.repositories import RepositoriesContainer
|
||||
|
||||
from . import constants, handlers
|
||||
from .callback_data import (
|
||||
AddSubscriptionCallbackData,
|
||||
AddSubscriptionConfirmCallbackData,
|
||||
ConfirmAnswerEnum,
|
||||
MenuCallbackData,
|
||||
NewSubscriptionCallbackData,
|
||||
NewSubscriptionConfirmCallbackData,
|
||||
PoolActionEnum,
|
||||
PoolCallbackData,
|
||||
PoolsBackCallbackData,
|
||||
PoolsCallbackData,
|
||||
SubscriptionActionEnum,
|
||||
SubscriptionCallbackData,
|
||||
SubscriptionsCallbackData,
|
||||
@@ -16,12 +19,12 @@ from .callback_data import (
|
||||
from .middlewares import (
|
||||
AuthMiddleware,
|
||||
DependsMiddleware,
|
||||
TypingMiddleware,
|
||||
# TypingMiddleware,
|
||||
)
|
||||
from .states import (
|
||||
AddSubscriptionPoolState,
|
||||
AddSubscriptionState,
|
||||
MenuState,
|
||||
NewSubscriptionPoolState,
|
||||
NewSubscriptionState,
|
||||
SetProfileBirthdayState,
|
||||
SetProfileGiftPaymentDataState,
|
||||
SetProfileNameState,
|
||||
@@ -33,7 +36,7 @@ def setup_dispatcher(
|
||||
dispatcher: aiogram.Dispatcher,
|
||||
repositories_container: RepositoriesContainer,
|
||||
):
|
||||
typing_middleware = TypingMiddleware()
|
||||
# typing_middleware = TypingMiddleware()
|
||||
auth_middleware = AuthMiddleware(users_repository=repositories_container.users)
|
||||
users_repository_middleware = DependsMiddleware(
|
||||
name="users_repository",
|
||||
@@ -175,9 +178,9 @@ def setup_router(router: aiogram.Router) -> aiogram.Router:
|
||||
SubscriptionsCallbackData.filter(),
|
||||
)
|
||||
router.callback_query.register(
|
||||
handlers.add_subscription_callback_handler,
|
||||
handlers.new_subscription_callback_handler,
|
||||
MenuState.SUBSCRIPTIONS,
|
||||
AddSubscriptionCallbackData.filter(),
|
||||
NewSubscriptionCallbackData.filter(),
|
||||
)
|
||||
router.callback_query.register(
|
||||
handlers.menu_callback_handler,
|
||||
@@ -203,107 +206,132 @@ def setup_router(router: aiogram.Router) -> aiogram.Router:
|
||||
|
||||
### Add new subscription
|
||||
router.message.register(
|
||||
handlers.add_subscription_message_handler,
|
||||
AddSubscriptionState.WAITING_FOR_PHONE,
|
||||
handlers.new_subscription_message_handler,
|
||||
NewSubscriptionState.WAITING_FOR_PHONE,
|
||||
aiogram.F.text == constants.BACK_BUTTON,
|
||||
)
|
||||
router.message.register(
|
||||
handlers.set_add_subscription_user_message_handler,
|
||||
AddSubscriptionState.WAITING_FOR_PHONE,
|
||||
handlers.set_new_subscription_user_message_handler,
|
||||
NewSubscriptionState.WAITING_FOR_PHONE,
|
||||
)
|
||||
router.message.register(
|
||||
handlers.ask_add_subscription_user_message_handler,
|
||||
AddSubscriptionState.WAITING_FOR_DATE,
|
||||
handlers.ask_new_subscription_user_message_handler,
|
||||
NewSubscriptionState.WAITING_FOR_DATE,
|
||||
aiogram.F.text == constants.BACK_BUTTON,
|
||||
)
|
||||
router.message.register(
|
||||
handlers.set_add_subscription_user_birthday_message_handler,
|
||||
AddSubscriptionState.WAITING_FOR_DATE,
|
||||
handlers.set_new_subscription_user_birthday_message_handler,
|
||||
NewSubscriptionState.WAITING_FOR_DATE,
|
||||
)
|
||||
router.message.register(
|
||||
handlers.ask_add_subscription_user_message_handler,
|
||||
AddSubscriptionState.WAITING_FOR_NAME,
|
||||
handlers.ask_new_subscription_user_message_handler,
|
||||
NewSubscriptionState.WAITING_FOR_NAME,
|
||||
aiogram.F.text == constants.BACK_BUTTON,
|
||||
)
|
||||
router.message.register(
|
||||
handlers.set_add_subscription_name_message_handler,
|
||||
AddSubscriptionState.WAITING_FOR_NAME,
|
||||
handlers.set_new_subscription_name_message_handler,
|
||||
NewSubscriptionState.WAITING_FOR_NAME,
|
||||
)
|
||||
router.message.register(
|
||||
handlers.ask_add_subscription_pool_description_message_handler,
|
||||
AddSubscriptionState.WAITING_FOR_POOL_DECISION,
|
||||
handlers.ask_new_subscription_pool_description_message_handler,
|
||||
NewSubscriptionState.WAITING_FOR_POOL_DECISION,
|
||||
aiogram.F.text == constants.CREATE_POOL_BUTTON,
|
||||
)
|
||||
router.message.register(
|
||||
handlers.show_add_subscription_pools_message_handler,
|
||||
AddSubscriptionState.WAITING_FOR_POOL_DECISION,
|
||||
handlers.show_new_subscription_choosing_pools_message_handler,
|
||||
NewSubscriptionState.WAITING_FOR_POOL_DECISION,
|
||||
aiogram.F.text == constants.JOIN_EXISTING_POOL_BUTTON,
|
||||
)
|
||||
router.message.register(
|
||||
handlers.ask_add_subscription_confirmation_message_handler,
|
||||
AddSubscriptionState.WAITING_FOR_POOL_DECISION,
|
||||
handlers.ask_new_subscription_confirmation_message_handler,
|
||||
NewSubscriptionState.WAITING_FOR_POOL_DECISION,
|
||||
aiogram.F.text == constants.DECLINE_POOL_BUTTON,
|
||||
)
|
||||
router.message.register(
|
||||
handlers.ask_add_subscription_name_message_handler,
|
||||
AddSubscriptionState.WAITING_FOR_POOL_DECISION,
|
||||
handlers.ask_new_subscription_name_message_handler,
|
||||
NewSubscriptionState.WAITING_FOR_POOL_DECISION,
|
||||
aiogram.F.text == constants.BACK_BUTTON,
|
||||
)
|
||||
router.callback_query.register(
|
||||
handlers.confirm_add_subscription_callback_handler,
|
||||
AddSubscriptionState.WAITING_FOR_CONFIRMATION,
|
||||
AddSubscriptionConfirmCallbackData.filter(
|
||||
handlers.confirm_new_subscription_callback_handler,
|
||||
NewSubscriptionState.WAITING_FOR_CONFIRMATION,
|
||||
NewSubscriptionConfirmCallbackData.filter(
|
||||
aiogram.F.answer == ConfirmAnswerEnum.YES,
|
||||
),
|
||||
)
|
||||
router.callback_query.register(
|
||||
handlers.subscriptions_callback_handler,
|
||||
AddSubscriptionState.WAITING_FOR_CONFIRMATION,
|
||||
AddSubscriptionConfirmCallbackData.filter(
|
||||
NewSubscriptionState.WAITING_FOR_CONFIRMATION,
|
||||
NewSubscriptionConfirmCallbackData.filter(
|
||||
aiogram.F.answer == ConfirmAnswerEnum.NO,
|
||||
),
|
||||
)
|
||||
|
||||
#### Add new subscription pool
|
||||
router.message.register(
|
||||
handlers.ask_add_subscription_pool_payment_phone_message_handler,
|
||||
AddSubscriptionPoolState.WAITING_FOR_DESCRIPTION,
|
||||
handlers.ask_new_subscription_pool_payment_phone_message_handler,
|
||||
NewSubscriptionPoolState.WAITING_FOR_DESCRIPTION,
|
||||
aiogram.F.text == constants.SKIP_BUTTON,
|
||||
)
|
||||
router.message.register(
|
||||
handlers.ask_add_subscription_pool_decision_message_handler,
|
||||
AddSubscriptionPoolState.WAITING_FOR_DESCRIPTION,
|
||||
handlers.ask_new_subscription_pool_decision_message_handler,
|
||||
NewSubscriptionPoolState.WAITING_FOR_DESCRIPTION,
|
||||
aiogram.F.text == constants.BACK_BUTTON,
|
||||
)
|
||||
router.message.register(
|
||||
handlers.set_add_subscription_pool_description_message_handler,
|
||||
AddSubscriptionPoolState.WAITING_FOR_DESCRIPTION,
|
||||
handlers.set_new_subscription_pool_description_message_handler,
|
||||
NewSubscriptionPoolState.WAITING_FOR_DESCRIPTION,
|
||||
)
|
||||
router.message.register(
|
||||
handlers.set_add_subscription_pool_payment_data_from_profile_message_handler,
|
||||
AddSubscriptionPoolState.WAITING_FOR_PAYMENT_PHONE,
|
||||
handlers.set_new_subscription_pool_payment_data_from_profile_message_handler,
|
||||
NewSubscriptionPoolState.WAITING_FOR_PAYMENT_PHONE,
|
||||
aiogram.F.text == constants.USE_PROFILE_GIFT_PAYMENT_DATA,
|
||||
)
|
||||
router.message.register(
|
||||
handlers.ask_add_subscription_pool_description_message_handler,
|
||||
AddSubscriptionPoolState.WAITING_FOR_PAYMENT_PHONE,
|
||||
handlers.ask_new_subscription_pool_description_message_handler,
|
||||
NewSubscriptionPoolState.WAITING_FOR_PAYMENT_PHONE,
|
||||
aiogram.F.text == constants.BACK_BUTTON,
|
||||
)
|
||||
router.message.register(
|
||||
handlers.set_add_subscription_pool_payment_phone_message_handler,
|
||||
AddSubscriptionPoolState.WAITING_FOR_PAYMENT_PHONE,
|
||||
handlers.set_new_subscription_pool_payment_phone_message_handler,
|
||||
NewSubscriptionPoolState.WAITING_FOR_PAYMENT_PHONE,
|
||||
)
|
||||
router.message.register(
|
||||
handlers.set_add_subscription_pool_payment_phone_message_handler,
|
||||
AddSubscriptionPoolState.WAITING_FOR_PAYMENT_BANK,
|
||||
handlers.set_new_subscription_pool_payment_phone_message_handler,
|
||||
NewSubscriptionPoolState.WAITING_FOR_PAYMENT_BANK,
|
||||
aiogram.F.text == constants.BACK_BUTTON,
|
||||
)
|
||||
router.message.register(
|
||||
handlers.set_add_subscription_pool_payment_bank_message_handler,
|
||||
AddSubscriptionPoolState.WAITING_FOR_PAYMENT_BANK,
|
||||
handlers.set_new_subscription_pool_payment_bank_message_handler,
|
||||
NewSubscriptionPoolState.WAITING_FOR_PAYMENT_BANK,
|
||||
)
|
||||
|
||||
#### Choose pool for subscription
|
||||
router.callback_query.register(
|
||||
handlers.show_new_subscription_choosing_pools_callback_handler,
|
||||
NewSubscriptionState.WAITING_FOR_CHOOSE_POOL,
|
||||
PoolsCallbackData.filter(),
|
||||
)
|
||||
router.callback_query.register(
|
||||
handlers.ask_new_subscription_pool_decision_callback_handler,
|
||||
NewSubscriptionState.WAITING_FOR_CHOOSE_POOL,
|
||||
PoolsBackCallbackData.filter(),
|
||||
)
|
||||
router.callback_query.register(
|
||||
handlers.show_new_subscription_choosing_pool_callback_handler,
|
||||
NewSubscriptionState.WAITING_FOR_CHOOSE_POOL,
|
||||
PoolCallbackData.filter(aiogram.F.action == PoolActionEnum.SHOW),
|
||||
)
|
||||
router.callback_query.register(
|
||||
handlers.choose_new_subscription_pool_callback_handler,
|
||||
NewSubscriptionState.WAITING_FOR_CHOOSE_POOL,
|
||||
PoolCallbackData.filter(aiogram.F.action == PoolActionEnum.CHOOSE),
|
||||
)
|
||||
router.callback_query.register(
|
||||
handlers.show_new_subscription_choosing_pools_callback_handler,
|
||||
NewSubscriptionState.WAITING_FOR_CHOOSE_POOL,
|
||||
PoolsCallbackData.filter(),
|
||||
)
|
||||
|
||||
# Fallback
|
||||
router.message.register(handlers.fallback_message_handler)
|
||||
|
||||
@@ -1,21 +1,13 @@
|
||||
import asyncio
|
||||
import uuid
|
||||
|
||||
from aiogram import types, F, Router
|
||||
from aiogram import types
|
||||
from aiogram.enums import MessageOriginType, ParseMode
|
||||
from aiogram.filters import Command
|
||||
from aiogram.fsm.context import FSMContext
|
||||
from aiogram.utils.keyboard import InlineKeyboardBuilder, ReplyKeyboardBuilder
|
||||
from pydantic_core import PydanticCustomError
|
||||
from pydantic_filters import PagePagination
|
||||
from pydantic_extra_types.phone_numbers import PhoneNumber
|
||||
|
||||
from birthday_pool_bot.dto import (
|
||||
BankEnum,
|
||||
PaymentData,
|
||||
Pool,
|
||||
Subscription,
|
||||
SubscriptionFilter,
|
||||
User,
|
||||
)
|
||||
from birthday_pool_bot.repositories.repositories import (
|
||||
@@ -24,18 +16,11 @@ from birthday_pool_bot.repositories.repositories import (
|
||||
UsersRepository,
|
||||
)
|
||||
from . import constants, logic
|
||||
from .callback_data import (
|
||||
AddSubscriptionCallbackData,
|
||||
AddSubscriptionConfirmCallbackData,
|
||||
ConfirmAnswerEnum,
|
||||
MenuCallbackData,
|
||||
SubscriptionCallbackData,
|
||||
SubscriptionsCallbackData,
|
||||
)
|
||||
from .callback_data import PoolCallbackData, SubscriptionCallbackData
|
||||
from .exceptions import FlowInternalError
|
||||
from .states import (
|
||||
AddSubscriptionPoolState,
|
||||
AddSubscriptionState,
|
||||
NewSubscriptionPoolState,
|
||||
NewSubscriptionState,
|
||||
MenuState,
|
||||
SetProfileBirthdayState,
|
||||
SetProfileGiftPaymentDataState,
|
||||
@@ -322,31 +307,31 @@ async def delete_subscription_callback(
|
||||
await state.set_state(MenuState.SUBSCRIPTIONS)
|
||||
|
||||
|
||||
async def add_subscription_message_handler(
|
||||
async def new_subscription_message_handler(
|
||||
message: types.Message,
|
||||
state: FSMContext,
|
||||
):
|
||||
await logic.ask_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
await logic.ask_new_subscription_user(message=message)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
|
||||
|
||||
|
||||
async def add_subscription_callback_handler(
|
||||
async def new_subscription_callback_handler(
|
||||
callback_query: types.CallbackQuery,
|
||||
state: FSMContext,
|
||||
):
|
||||
await logic.ask_add_subscription_user(callback_query=callback_query)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
await logic.ask_new_subscription_user(callback_query=callback_query)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
|
||||
|
||||
|
||||
async def ask_add_subscription_user_message_handler(
|
||||
async def ask_new_subscription_user_message_handler(
|
||||
message: types.Message,
|
||||
state: FSMContext,
|
||||
):
|
||||
await logic.ask_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
await logic.ask_new_subscription_user(message=message)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
|
||||
|
||||
|
||||
async def set_add_subscription_user_message_handler(
|
||||
async def set_new_subscription_user_message_handler(
|
||||
message: types.Message,
|
||||
state: FSMContext,
|
||||
user: User,
|
||||
@@ -370,15 +355,15 @@ async def set_add_subscription_user_message_handler(
|
||||
await message.reply(
|
||||
text="Пользователь скрыл свои данные, попробуйте отправить номер телефона или его контакт",
|
||||
)
|
||||
await logic.ask_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
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_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
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
|
||||
@@ -390,8 +375,8 @@ async def set_add_subscription_user_message_handler(
|
||||
try:
|
||||
PhoneNumber._validate(user_phone, None)
|
||||
except PydanticCustomError:
|
||||
await logic.ask_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
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)
|
||||
|
||||
@@ -406,8 +391,8 @@ async def set_add_subscription_user_message_handler(
|
||||
|
||||
if subscription_user.id == user.id:
|
||||
await message.reply("Нельзя подписаться на самого себя")
|
||||
await logic.ask_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
await logic.ask_new_subscription_user(message=message)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
|
||||
return
|
||||
|
||||
async with subscriptions_repository.transaction():
|
||||
@@ -418,8 +403,8 @@ async def set_add_subscription_user_message_handler(
|
||||
|
||||
if subscription is not None:
|
||||
await message.reply(text="У вас уже есть подписка на этого человека")
|
||||
await logic.ask_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
await logic.ask_new_subscription_user(message=message)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
|
||||
return
|
||||
|
||||
await state.update_data(
|
||||
@@ -427,65 +412,65 @@ async def set_add_subscription_user_message_handler(
|
||||
)
|
||||
|
||||
if subscription_user.birthday is None:
|
||||
await logic.ask_add_subscription_user_birthday(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_DATE)
|
||||
await logic.ask_new_subscription_user_birthday(message=message)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_DATE)
|
||||
return
|
||||
|
||||
await logic.ask_add_subscription_name(
|
||||
await logic.ask_new_subscription_name(
|
||||
message=message,
|
||||
users_repository=users_repository,
|
||||
subscription_user_id=subscription_user.id,
|
||||
)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_NAME)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_NAME)
|
||||
|
||||
|
||||
async def ask_add_subscription_user_birthday_message_handler(
|
||||
async def ask_new_subscription_user_birthday_message_handler(
|
||||
message: types.Message,
|
||||
state: FSMContext,
|
||||
):
|
||||
await logic.ask_add_subscription_user_birthday(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_DATE)
|
||||
await logic.ask_new_subscription_user_birthday(message=message)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_DATE)
|
||||
|
||||
|
||||
async def set_add_subscription_user_birthday_message_handler(
|
||||
async def set_new_subscription_user_birthday_message_handler(
|
||||
message: types.Message,
|
||||
state: FSMContext,
|
||||
users_repository: UsersRepository,
|
||||
):
|
||||
birthday = parse_date(message=message)
|
||||
if birthday is None:
|
||||
await logic.ask_add_subscription_user_birthday(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_DATE)
|
||||
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_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
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_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
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_add_subscription_name(
|
||||
await logic.ask_new_subscription_name(
|
||||
message=message,
|
||||
users_repository=users_repository,
|
||||
subscription_user_id=subscription_user.id,
|
||||
)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_NAME)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_NAME)
|
||||
|
||||
|
||||
async def ask_add_subscription_name_message_handler(
|
||||
async def ask_new_subscription_name_message_handler(
|
||||
message: types.Message,
|
||||
state: FSMContext,
|
||||
users_repository: UsersRepository,
|
||||
@@ -494,26 +479,26 @@ async def ask_add_subscription_name_message_handler(
|
||||
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_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
await logic.ask_new_subscription_user(message=message)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
|
||||
return
|
||||
|
||||
try:
|
||||
await logic.ask_add_subscription_name(
|
||||
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_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
await logic.ask_new_subscription_user(message=message)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
|
||||
return
|
||||
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_NAME)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_NAME)
|
||||
|
||||
|
||||
async def set_add_subscription_name_message_handler(
|
||||
async def set_new_subscription_name_message_handler(
|
||||
message: types.Message,
|
||||
state: FSMContext,
|
||||
user: User,
|
||||
@@ -525,29 +510,29 @@ async def set_add_subscription_name_message_handler(
|
||||
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_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
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_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
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_add_subscription_pool_decision(
|
||||
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(AddSubscriptionState.WAITING_FOR_POOL_DECISION)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_POOL_DECISION)
|
||||
|
||||
|
||||
async def ask_add_subscription_pool_decision_message_handler(
|
||||
async def ask_new_subscription_pool_decision_message_handler(
|
||||
message: types.Message,
|
||||
state: FSMContext,
|
||||
pools_repository: PoolsRepository,
|
||||
@@ -557,12 +542,12 @@ async def ask_add_subscription_pool_decision_message_handler(
|
||||
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_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
await logic.ask_new_subscription_user(message=message)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
|
||||
return
|
||||
|
||||
try:
|
||||
await logic.ask_add_subscription_pool_decision(
|
||||
await logic.ask_new_subscription_pool_decision(
|
||||
message=message,
|
||||
pools_repository=pools_repository,
|
||||
users_repository=users_repository,
|
||||
@@ -570,72 +555,235 @@ async def ask_add_subscription_pool_decision_message_handler(
|
||||
)
|
||||
except FlowInternalError:
|
||||
await message.reply(text=constants.ERROR_MESSAGE)
|
||||
await logic.ask_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
await logic.ask_new_subscription_user(message=message)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
|
||||
return
|
||||
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_POOL_DECISION)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_POOL_DECISION)
|
||||
|
||||
|
||||
async def show_add_subscription_pools_message_handler(
|
||||
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_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
await logic.ask_new_subscription_user(message=message)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
|
||||
return
|
||||
|
||||
try:
|
||||
await logic.show_add_subscription_pools(
|
||||
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_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
await logic.ask_new_subscription_user(message=message)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
|
||||
return
|
||||
|
||||
await logic.ask_add_subscription_pool_description(message=message)
|
||||
await state.set_state(AddSubscriptionPoolState.WAITING_FOR_DESCRIPTION)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_CHOOSE_POOL)
|
||||
|
||||
|
||||
async def ask_add_subscription_pool_description_message_handler(
|
||||
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_add_subscription_pool_description(message=message)
|
||||
await state.set_state(AddSubscriptionPoolState.WAITING_FOR_DESCRIPTION)
|
||||
await logic.ask_new_subscription_pool_description(message=message)
|
||||
await state.set_state(NewSubscriptionPoolState.WAITING_FOR_DESCRIPTION)
|
||||
|
||||
|
||||
async def set_add_subscription_pool_description_message_handler(
|
||||
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_add_subscription_pool_payment_phone(message=message)
|
||||
await state.set_state(AddSubscriptionPoolState.WAITING_FOR_PAYMENT_PHONE)
|
||||
await logic.ask_new_subscription_pool_payment_phone(message=message)
|
||||
await state.set_state(NewSubscriptionPoolState.WAITING_FOR_PAYMENT_PHONE)
|
||||
|
||||
|
||||
async def ask_add_subscription_pool_payment_phone_message_handler(
|
||||
async def ask_new_subscription_pool_payment_phone_message_handler(
|
||||
message: types.Message,
|
||||
state: FSMContext,
|
||||
user: User,
|
||||
):
|
||||
await logic.ask_add_subscription_pool_payment_phone(message=message, user=user)
|
||||
await state.set_state(AddSubscriptionPoolState.WAITING_FOR_PAYMENT_PHONE)
|
||||
await logic.ask_new_subscription_pool_payment_phone(message=message, user=user)
|
||||
await state.set_state(NewSubscriptionPoolState.WAITING_FOR_PAYMENT_PHONE)
|
||||
|
||||
|
||||
async def set_add_subscription_pool_payment_phone_message_handler(
|
||||
async def set_new_subscription_pool_payment_phone_message_handler(
|
||||
message: types.Message,
|
||||
state: FSMContext,
|
||||
):
|
||||
@@ -646,8 +794,8 @@ async def set_add_subscription_pool_payment_phone_message_handler(
|
||||
phone_number = message.text
|
||||
else:
|
||||
await message.reply(text="Некорректный номер телефона, попробуйте ещё раз")
|
||||
await logic.ask_add_subscription_pool_payment_phone(message=message)
|
||||
await state.set_state(AddSubscriptionPoolState.WAITING_FOR_PAYMENT_PHONE)
|
||||
await logic.ask_new_subscription_pool_payment_phone(message=message)
|
||||
await state.set_state(NewSubscriptionPoolState.WAITING_FOR_PAYMENT_PHONE)
|
||||
return
|
||||
|
||||
try:
|
||||
@@ -656,16 +804,16 @@ async def set_add_subscription_pool_payment_phone_message_handler(
|
||||
await message.reply(
|
||||
text="Некорректный номер телефона, попробуйте ещё раз",
|
||||
)
|
||||
await state.set_state(AddSubscriptionPoolState.WAITING_FOR_PAYMENT_PHONE)
|
||||
await state.set_state(NewSubscriptionPoolState.WAITING_FOR_PAYMENT_PHONE)
|
||||
return
|
||||
|
||||
await state.update_data(subscription_pool_phone=phone_number)
|
||||
|
||||
await logic.ask_add_subscription_pool_payment_bank(message=message)
|
||||
await state.set_state(AddSubscriptionPoolState.WAITING_FOR_PAYMENT_BANK)
|
||||
await logic.ask_new_subscription_pool_payment_bank(message=message)
|
||||
await state.set_state(NewSubscriptionPoolState.WAITING_FOR_PAYMENT_BANK)
|
||||
|
||||
|
||||
async def set_add_subscription_pool_payment_data_from_profile_message_handler(
|
||||
async def set_new_subscription_pool_payment_data_from_profile_message_handler(
|
||||
message: types.Message,
|
||||
state: FSMContext,
|
||||
user: User,
|
||||
@@ -674,8 +822,8 @@ async def set_add_subscription_pool_payment_data_from_profile_message_handler(
|
||||
):
|
||||
if user.gift_payment_data is None:
|
||||
await message.reply(text=constants.ERROR_MESSAGE)
|
||||
await logic.ask_add_subscription_pool_payment_phone(message=message, user=user)
|
||||
await state.set_state(AddSubscriptionPoolState.WAITING_FOR_PAYMENT_PHONE)
|
||||
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()
|
||||
@@ -684,15 +832,15 @@ async def set_add_subscription_pool_payment_data_from_profile_message_handler(
|
||||
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_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
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_add_subscription_confirmation(
|
||||
await logic.ask_new_subscription_confirmation(
|
||||
message=message,
|
||||
users_repository=users_repository,
|
||||
pools_repository=pools_repository,
|
||||
@@ -702,18 +850,18 @@ async def set_add_subscription_pool_payment_data_from_profile_message_handler(
|
||||
subscription_pool_phone=user.gift_payment_data.phone,
|
||||
subscription_pool_bank=user.gift_payment_data.bank,
|
||||
)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_CONFIRMATION)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_CONFIRMATION)
|
||||
|
||||
|
||||
async def ask_add_subscription_pool_payment_bank_message_handler(
|
||||
async def ask_new_subscription_pool_payment_bank_message_handler(
|
||||
message: types.Message,
|
||||
state: FSMContext,
|
||||
):
|
||||
await logic.ask_add_subscription_pool_payment_bank(message=message)
|
||||
await state.set_state(AddSubscriptionPoolState.WAITING_FOR_PAYMENT_BANK)
|
||||
await logic.ask_new_subscription_pool_payment_bank(message=message)
|
||||
await state.set_state(NewSubscriptionPoolState.WAITING_FOR_PAYMENT_BANK)
|
||||
|
||||
|
||||
async def set_add_subscription_pool_payment_bank_message_handler(
|
||||
async def set_new_subscription_pool_payment_bank_message_handler(
|
||||
message: types.Message,
|
||||
state: FSMContext,
|
||||
users_repository: UsersRepository,
|
||||
@@ -726,13 +874,13 @@ async def set_add_subscription_pool_payment_bank_message_handler(
|
||||
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_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
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_add_subscription_pool_decision(message=message)
|
||||
await state.set_state(AddSubscriptionPoolState.WAITING_FOR_DESCRIPTION)
|
||||
await logic.ask_new_subscription_pool_decision(message=message)
|
||||
await state.set_state(NewSubscriptionPoolState.WAITING_FOR_DESCRIPTION)
|
||||
return
|
||||
|
||||
async with users_repository.transaction():
|
||||
@@ -741,8 +889,8 @@ async def set_add_subscription_pool_payment_bank_message_handler(
|
||||
)
|
||||
if subscription_user is None:
|
||||
await message.reply(text=constants.ERROR_MESSAGE)
|
||||
await logic.ask_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
await logic.ask_new_subscription_user(message=message)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
|
||||
return
|
||||
|
||||
bank_name = message.text
|
||||
@@ -754,7 +902,7 @@ async def set_add_subscription_pool_payment_bank_message_handler(
|
||||
bank = constants.BANKS_MAP[bank_name]
|
||||
await state.update_data(subscription_pool_bank=bank)
|
||||
|
||||
await logic.ask_add_subscription_confirmation(
|
||||
await logic.ask_new_subscription_confirmation(
|
||||
message=message,
|
||||
users_repository=users_repository,
|
||||
pools_repository=pools_repository,
|
||||
@@ -764,10 +912,10 @@ async def set_add_subscription_pool_payment_bank_message_handler(
|
||||
subscription_pool_phone=subscription_pool_phone,
|
||||
subscription_pool_bank=bank,
|
||||
)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_CONFIRMATION)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_CONFIRMATION)
|
||||
|
||||
|
||||
async def ask_add_subscription_confirmation_message_handler(
|
||||
async def ask_new_subscription_confirmation_message_handler(
|
||||
message: types.Message,
|
||||
state: FSMContext,
|
||||
users_repository: UsersRepository,
|
||||
@@ -782,8 +930,8 @@ async def ask_add_subscription_confirmation_message_handler(
|
||||
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_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
await logic.ask_new_subscription_user(message=message)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
|
||||
return
|
||||
|
||||
async with users_repository.transaction():
|
||||
@@ -792,12 +940,12 @@ async def ask_add_subscription_confirmation_message_handler(
|
||||
)
|
||||
if subscription_user is None:
|
||||
await message.reply(text=constants.ERROR_MESSAGE)
|
||||
await logic.ask_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
await logic.ask_new_subscription_user(message=message)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
|
||||
return
|
||||
|
||||
try:
|
||||
await logic.ask_add_subscription_confirmation(
|
||||
await logic.ask_new_subscription_confirmation(
|
||||
message=message,
|
||||
users_repository=users_repository,
|
||||
pools_repository=pools_repository,
|
||||
@@ -810,14 +958,14 @@ async def ask_add_subscription_confirmation_message_handler(
|
||||
)
|
||||
except FlowInternalError:
|
||||
await message.reply(text=constants.ERROR_MESSAGE)
|
||||
await logic.ask_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
await logic.ask_new_subscription_user(message=message)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_PHONE)
|
||||
return
|
||||
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_CONFIRMATION)
|
||||
await state.set_state(NewSubscriptionState.WAITING_FOR_CONFIRMATION)
|
||||
|
||||
|
||||
async def confirm_add_subscription_callback_handler(
|
||||
async def confirm_new_subscription_callback_handler(
|
||||
callback_query: types.CallbackQuery,
|
||||
state: FSMContext,
|
||||
user: User,
|
||||
@@ -833,9 +981,9 @@ async def confirm_add_subscription_callback_handler(
|
||||
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_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
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():
|
||||
@@ -843,9 +991,9 @@ async def confirm_add_subscription_callback_handler(
|
||||
user_id=subscription_user_id,
|
||||
)
|
||||
if subscription_user is None:
|
||||
await message.reply(text=constants.ERROR_MESSAGE)
|
||||
await logic.ask_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
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
|
||||
@@ -855,9 +1003,9 @@ async def confirm_add_subscription_callback_handler(
|
||||
pool_id=subscription_pool_id,
|
||||
)
|
||||
if subscription_pool is None:
|
||||
await message.reply(text=constants.ERROR_MESSAGE)
|
||||
await logic.ask_add_subscription_user(message=message)
|
||||
await state.set_state(AddSubscriptionState.WAITING_FOR_PHONE)
|
||||
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)):
|
||||
|
||||
@@ -1,17 +1,26 @@
|
||||
import uuid
|
||||
|
||||
from aiogram import types
|
||||
from aiogram.enums import ParseMode
|
||||
from aiogram.fsm.context import FSMContext
|
||||
from aiogram.utils.keyboard import InlineKeyboardBuilder, ReplyKeyboardBuilder
|
||||
from pydantic_filters import PagePagination
|
||||
|
||||
from birthday_pool_bot.dto import User
|
||||
from birthday_pool_bot.repositories.repositories import UsersRepository
|
||||
from birthday_pool_bot.dto import BankEnum, User
|
||||
from birthday_pool_bot.repositories.repositories import (
|
||||
PoolsRepository,
|
||||
SubscriptionsRepository,
|
||||
UsersRepository,
|
||||
)
|
||||
from . import constants
|
||||
from .callback_data import (
|
||||
AddSubscriptionCallbackData,
|
||||
AddSubscriptionConfirmCallbackData,
|
||||
ConfirmAnswerEnum,
|
||||
MenuCallbackData,
|
||||
NewSubscriptionCallbackData,
|
||||
NewSubscriptionConfirmCallbackData,
|
||||
PoolActionEnum,
|
||||
PoolCallbackData,
|
||||
PoolsCallbackData,
|
||||
PoolsBackCallbackData,
|
||||
SubscriptionActionEnum,
|
||||
SubscriptionCallbackData,
|
||||
SubscriptionsCallbackData,
|
||||
@@ -200,12 +209,12 @@ async def show_subscriptions(
|
||||
text = "Мои подписки:" if subscriptions else "Нет подписок"
|
||||
keyboard = InlineKeyboardBuilder()
|
||||
for subscription in subscriptions:
|
||||
keyboard.button(
|
||||
keyboard.row(types.InlineKeyboardButton(
|
||||
text=subscription.name,
|
||||
callback_data=SubscriptionCallbackData(
|
||||
to_user_id=subscription.to_user_id,
|
||||
).pack(),
|
||||
)
|
||||
))
|
||||
navigation_row = []
|
||||
if page > 1:
|
||||
navigation_row.append(types.InlineKeyboardButton(
|
||||
@@ -226,7 +235,7 @@ async def show_subscriptions(
|
||||
keyboard.row(
|
||||
types.InlineKeyboardButton(
|
||||
text="Добавить",
|
||||
callback_data=AddSubscriptionCallbackData().pack(),
|
||||
callback_data=NewSubscriptionCallbackData().pack(),
|
||||
),
|
||||
types.InlineKeyboardButton(
|
||||
text="Назад",
|
||||
@@ -273,7 +282,12 @@ async def show_subscription(
|
||||
)
|
||||
if subscription.pool is not None:
|
||||
if subscription.pool.owner_id == from_user_id:
|
||||
text += "Вы собираете деньги\n\n"
|
||||
bank_title = constants.BANKS_TITLE_MAP[subscription.pool.payment_data.bank]
|
||||
text += (
|
||||
"Вы собираете деньги на:\n"
|
||||
f"_Телефон_: {subscription.pool.payment_data.phone}\n"
|
||||
f"_Банк_: {bank_title}\n\n"
|
||||
)
|
||||
else:
|
||||
text += "Вы участвуете в сборе денег\n\n"
|
||||
keyboard = InlineKeyboardBuilder()
|
||||
@@ -333,7 +347,7 @@ async def delete_subscription(
|
||||
await callback_query.answer(text="Подписка успешно удалена")
|
||||
|
||||
|
||||
async def ask_add_subscription_user(
|
||||
async def ask_new_subscription_user(
|
||||
callback_query: types.CallbackQuery | None = None,
|
||||
message: types.Message | None = None,
|
||||
):
|
||||
@@ -367,7 +381,7 @@ async def ask_add_subscription_user(
|
||||
)
|
||||
|
||||
|
||||
async def ask_add_subscription_user_birthday(
|
||||
async def ask_new_subscription_user_birthday(
|
||||
message: types.Message,
|
||||
):
|
||||
text = (
|
||||
@@ -388,7 +402,7 @@ async def ask_add_subscription_user_birthday(
|
||||
)
|
||||
|
||||
|
||||
async def ask_add_subscription_name(
|
||||
async def ask_new_subscription_name(
|
||||
message: types.Message,
|
||||
users_repository: UsersRepository,
|
||||
subscription_user_id: uuid.UUID,
|
||||
@@ -422,7 +436,7 @@ async def ask_add_subscription_name(
|
||||
)
|
||||
|
||||
|
||||
async def ask_add_subscription_pool_decision(
|
||||
async def ask_new_subscription_pool_decision(
|
||||
message: types.Message,
|
||||
pools_repository: PoolsRepository,
|
||||
users_repository: UsersRepository,
|
||||
@@ -458,9 +472,11 @@ async def ask_add_subscription_pool_decision(
|
||||
)
|
||||
|
||||
|
||||
async def show_add_subscription_pools(
|
||||
async def show_new_subscription_choosing_pools(
|
||||
user: User,
|
||||
users_repository: UsersRepository,
|
||||
pools_repository: PoolsRepository,
|
||||
subscription_user_id: uuid.UUID,
|
||||
message: types.Message | None = None,
|
||||
callback_query: types.CallbackQuery | None = None,
|
||||
):
|
||||
@@ -470,31 +486,34 @@ async def show_add_subscription_pools(
|
||||
callback_data = SubscriptionsCallbackData.unpack(callback_query.data)
|
||||
page = callback_data.page
|
||||
|
||||
async with subscriptions_repository.transaction():
|
||||
total = await subscriptions_repository.get_user_subscriptions_count(user_id=user.id)
|
||||
async with pools_repository.transaction():
|
||||
total = await pools_repository.get_pools_by_birthday_user_id_count(
|
||||
birthday_user_id=subscription_user_id,
|
||||
)
|
||||
pages_count = total // per_page + int(bool(total % per_page))
|
||||
subscriptions = [
|
||||
subscription
|
||||
async for subscription in subscriptions_repository.get_user_subscriptions(
|
||||
user_id=user.id,
|
||||
pools = [
|
||||
pool
|
||||
async for pool in pools_repository.get_pools_by_birthday_user_id(
|
||||
birthday_user_id=subscription_user_id,
|
||||
pagination=PagePagination(page=page, per_page=per_page),
|
||||
with_owner=True,
|
||||
)
|
||||
]
|
||||
|
||||
text = "Сборы:" if subscriptions else "Нет сборов"
|
||||
text = "Сборы:" if pools else "Нет сборов"
|
||||
keyboard = InlineKeyboardBuilder()
|
||||
for subscription in subscriptions:
|
||||
keyboard.button(
|
||||
text=subscription.name,
|
||||
callback_data=SubscriptionCallbackData(
|
||||
to_user_id=subscription.to_user_id,
|
||||
for pool in pools:
|
||||
keyboard.row(types.InlineKeyboardButton(
|
||||
text=pool.owner.name or "Аноним",
|
||||
callback_data=PoolCallbackData(
|
||||
id=pool.id,
|
||||
).pack(),
|
||||
)
|
||||
))
|
||||
navigation_row = []
|
||||
if page > 1:
|
||||
navigation_row.append(types.InlineKeyboardButton(
|
||||
text="<",
|
||||
callback_data=SubscriptionsCallbackData(page=page - 1).pack(),
|
||||
callback_data=PoolsCallbackData(page=page - 1).pack(),
|
||||
))
|
||||
if pages_count > 1:
|
||||
navigation_row.append(types.InlineKeyboardButton(
|
||||
@@ -504,17 +523,13 @@ async def show_add_subscription_pools(
|
||||
if page < pages_count:
|
||||
navigation_row.append(types.InlineKeyboardButton(
|
||||
text=">",
|
||||
callback_data=SubscriptionsCallbackData(page=page + 1).pack(),
|
||||
callback_data=PoolsCallbackData(page=page + 1).pack(),
|
||||
))
|
||||
keyboard.row(*navigation_row)
|
||||
keyboard.row(
|
||||
types.InlineKeyboardButton(
|
||||
text="Добавить",
|
||||
callback_data=AddSubscriptionCallbackData().pack(),
|
||||
),
|
||||
types.InlineKeyboardButton(
|
||||
text="Назад",
|
||||
callback_data=MenuCallbackData().pack(),
|
||||
callback_data=PoolsBackCallbackData().pack(),
|
||||
),
|
||||
)
|
||||
reply_markup = keyboard.as_markup()
|
||||
@@ -535,7 +550,70 @@ async def show_add_subscription_pools(
|
||||
)
|
||||
|
||||
|
||||
async def ask_add_subscription_pool_description(
|
||||
async def show_new_subscription_choosing_pool(
|
||||
pools_repository: PoolsRepository,
|
||||
pool_id: uuid.UUID,
|
||||
message: types.Message | None = None,
|
||||
callback_query: types.CallbackQuery | None = None,
|
||||
):
|
||||
async with pools_repository.transaction():
|
||||
pool = await pools_repository.get_pool_by_id(
|
||||
pool_id=pool_id,
|
||||
with_owner=True,
|
||||
with_birthday_user=True,
|
||||
)
|
||||
if pool is None:
|
||||
raise FlowInternalError()
|
||||
|
||||
owner_name = (
|
||||
pool.owner.name
|
||||
or pool.owner.phone
|
||||
or pool.owner.telegram_id
|
||||
)
|
||||
birthday_user_name = (
|
||||
pool.birthday_user.name
|
||||
or pool.birthday_user.phone
|
||||
or pool.birthday_user.telegram_id
|
||||
)
|
||||
bank_name = constants.BANKS_TITLE_MAP[pool.payment_data.bank]
|
||||
text = (
|
||||
f"*{owner_name}* собирает деньги для {birthday_user_name}\n\n"
|
||||
"Данные для отправки подарка:\n"
|
||||
f"_Телефон_: {pool.payment_data.phone}\n"
|
||||
f"_Банк_: {bank_name}\n"
|
||||
)
|
||||
keyboard = InlineKeyboardBuilder()
|
||||
keyboard.button(
|
||||
text="Выбрать",
|
||||
callback_data=PoolCallbackData(
|
||||
id=pool_id,
|
||||
action=PoolActionEnum.CHOOSE,
|
||||
).pack(),
|
||||
)
|
||||
keyboard.button(
|
||||
text="Назад",
|
||||
callback_data=PoolsCallbackData().pack()
|
||||
)
|
||||
keyboard.adjust(2)
|
||||
reply_markup = keyboard.as_markup()
|
||||
|
||||
if message is not None:
|
||||
await message.reply(
|
||||
text=text,
|
||||
parse_mode=ParseMode.MARKDOWN,
|
||||
reply_markup=reply_markup,
|
||||
)
|
||||
elif callback_query is not None:
|
||||
await callback_query.message.edit_text(
|
||||
text=text,
|
||||
parse_mode=ParseMode.MARKDOWN,
|
||||
)
|
||||
await callback_query.message.edit_reply_markup(
|
||||
reply_markup=reply_markup,
|
||||
)
|
||||
|
||||
|
||||
async def ask_new_subscription_pool_description(
|
||||
message: types.Message,
|
||||
):
|
||||
keyboard = ReplyKeyboardBuilder()
|
||||
@@ -554,7 +632,7 @@ async def ask_add_subscription_pool_description(
|
||||
)
|
||||
|
||||
|
||||
async def ask_add_subscription_pool_payment_phone(
|
||||
async def ask_new_subscription_pool_payment_phone(
|
||||
message: types.Message,
|
||||
user: User,
|
||||
):
|
||||
@@ -589,7 +667,7 @@ async def ask_add_subscription_pool_payment_phone(
|
||||
)
|
||||
|
||||
|
||||
async def ask_add_subscription_pool_payment_bank(
|
||||
async def ask_new_subscription_pool_payment_bank(
|
||||
message: types.Message,
|
||||
):
|
||||
text = "Выберите банк для приёма платежей"
|
||||
@@ -611,7 +689,7 @@ async def ask_add_subscription_pool_payment_bank(
|
||||
)
|
||||
|
||||
|
||||
async def ask_add_subscription_confirmation(
|
||||
async def ask_new_subscription_confirmation(
|
||||
message: types.Message,
|
||||
users_repository: UsersRepository,
|
||||
pools_repository: PoolsRepository,
|
||||
@@ -663,13 +741,13 @@ async def ask_add_subscription_confirmation(
|
||||
keyboard = InlineKeyboardBuilder()
|
||||
keyboard.button(
|
||||
text="Да",
|
||||
callback_data=AddSubscriptionConfirmCallbackData(
|
||||
callback_data=NewSubscriptionConfirmCallbackData(
|
||||
answer=ConfirmAnswerEnum.YES,
|
||||
).pack(),
|
||||
)
|
||||
keyboard.button(
|
||||
text="Нет",
|
||||
callback_data=AddSubscriptionConfirmCallbackData(
|
||||
callback_data=NewSubscriptionConfirmCallbackData(
|
||||
answer=ConfirmAnswerEnum.NO,
|
||||
).pack(),
|
||||
)
|
||||
|
||||
@@ -24,15 +24,16 @@ class SetProfileGiftPaymentDataState(StatesGroup):
|
||||
WAITING_FOR_BANK = State()
|
||||
|
||||
|
||||
class AddSubscriptionState(StatesGroup):
|
||||
class NewSubscriptionState(StatesGroup):
|
||||
WAITING_FOR_PHONE = State()
|
||||
WAITING_FOR_DATE = State()
|
||||
WAITING_FOR_NAME = State()
|
||||
WAITING_FOR_POOL_DECISION = State()
|
||||
WAITING_FOR_CHOOSE_POOL = State()
|
||||
WAITING_FOR_CONFIRMATION = State()
|
||||
|
||||
|
||||
class AddSubscriptionPoolState(StatesGroup):
|
||||
class NewSubscriptionPoolState(StatesGroup):
|
||||
WAITING_FOR_DESCRIPTION = State()
|
||||
WAITING_FOR_PAYMENT_PHONE = State()
|
||||
WAITING_FOR_PAYMENT_BANK = State()
|
||||
|
||||
@@ -5,7 +5,7 @@ from aiogram import types
|
||||
from aiogram.types import User as TelegramUser
|
||||
|
||||
|
||||
BIRTHDATE_REGEXP = re.compile("^(?P<day>\d{2})\.(?P<month>\d{2})\.(?P<year>\d{4})$")
|
||||
BIRTHDATE_REGEXP = re.compile(r"^(?P<day>\d{2}).(?P<month>\d{2}).(?P<year>\d{4})$")
|
||||
|
||||
|
||||
def parse_date(message: types.Message) -> datetime.date:
|
||||
|
||||
@@ -3,6 +3,7 @@ from typing import Any
|
||||
import aiogram
|
||||
import fastapi
|
||||
import uvicorn
|
||||
import yarl
|
||||
|
||||
from birthday_pool_bot.telegram_bot.base import BaseTelegramBotService
|
||||
|
||||
@@ -14,9 +15,10 @@ class UvicornServer(uvicorn.Server):
|
||||
|
||||
class TelegramBotWebhookService(BaseTelegramBotService):
|
||||
async def listen_events(self):
|
||||
webhook_url = yarl.URL(str(self._settings.root_url)) / self._settings.root_path.lstrip("/")
|
||||
await self._bot.set_webhook(
|
||||
url=self._settings.url,
|
||||
secret_token=self._settings.secret_token,
|
||||
url=str(webhook_url),
|
||||
secret_token=self._settings.secret_access_key,
|
||||
)
|
||||
|
||||
await self.get_server().serve()
|
||||
@@ -26,10 +28,9 @@ class TelegramBotWebhookService(BaseTelegramBotService):
|
||||
root_url=self._settings.root_url,
|
||||
root_path=self._settings.root_path,
|
||||
)
|
||||
app.post("")(self.handler)
|
||||
|
||||
app.post(self._webhook_path)(self.handler)
|
||||
|
||||
config = uvicorn.Config(app=app, host="0.0.0.0", port=self._port)
|
||||
config = uvicorn.Config(app=app, host="0.0.0.0", port=self._settings.port)
|
||||
return UvicornServer(config)
|
||||
|
||||
async def handler(
|
||||
@@ -37,7 +38,7 @@ class TelegramBotWebhookService(BaseTelegramBotService):
|
||||
update: dict[str, Any],
|
||||
x_telegram_bot_api_secret_token: str | None = fastapi.Header(None),
|
||||
):
|
||||
if x_telegram_bot_api_secret_token != self._secret_token:
|
||||
if x_telegram_bot_api_secret_token != self._settings.secret_access_key:
|
||||
raise fastapi.HTTPException(
|
||||
status_code=fastapi.status.HTTP_403_FORBIDDEN,
|
||||
detail="Forbidden.",
|
||||
|
||||
@@ -7,7 +7,7 @@ from birthday_pool_bot.telegram_bot.settings import TelegramBotSettings
|
||||
|
||||
|
||||
class TelegramBotWebhookSettings(TelegramBotSettings):
|
||||
method: Literal[TelegramBotMethodEnum.WEBHOOK.value] = TelegramBotMethodEnum.WEBHOOK
|
||||
method: Literal[TelegramBotMethodEnum.WEBHOOK.value] = TelegramBotMethodEnum.WEBHOOK.value
|
||||
|
||||
root_url: AnyHttpUrl
|
||||
root_path: str = "/"
|
||||
|
||||
Reference in New Issue
Block a user