import logging from typing import TYPE_CHECKING from src import domain if TYPE_CHECKING: from .. import Usecase log = logging.getLogger(__name__) async def handle_subscription( self: 'Usecase', user_telegram_id: int, username: str | None, invite_link: str, first_name: str | None = None, last_name: str | None = None, ) -> None: placement_post = await self.database.get_placement_post_by_invite_link(invite_link) if not placement_post or not placement_post.placement: log.warning('PlacementPost not found for invite_link: %s', invite_link) return placement = placement_post.placement subscriber = await self.database.get_telegram_user(telegram_id=user_telegram_id) if not subscriber: subscriber = domain.TelegramUser( telegram_id=user_telegram_id, username=username, first_name=first_name, last_name=last_name, ) await self.database.create_telegram_user(subscriber) else: subscriber.username = username or subscriber.username subscriber.first_name = first_name or subscriber.first_name subscriber.last_name = last_name or subscriber.last_name await self.database.update_telegram_user(subscriber) active_subscription = await self.database.get_active_subscription_by_subscriber_and_project( subscriber.id, placement.project_id ) if active_subscription: # Пользователь уже подписан на канал через другой placement # Это не должно случиться (Telegram не даст подписаться дважды), # но если случилось - логируем и игнорируем log.warning( 'User %s (telegram_id: %s) already has active subscription to channel %s via placement %s, ' 'ignoring new subscription attempt via placement %s', subscriber.id, user_telegram_id, placement.project_id, active_subscription.placement_id, placement.id, ) return # Проверяем, была ли раньше подписка через ЭТОТ placement (для реактивации) # Note: Subscription now links to placement directly, not placement_post existing_sub = await self.database.get_subscription_by_subscriber_and_placement( subscriber.id, placement.id ) if existing_sub and existing_sub.status == domain.SubscriptionStatus.UNSUBSCRIBED: existing_sub.status = domain.SubscriptionStatus.ACTIVE existing_sub.unsubscribed_at = None await self.database.update_subscription(existing_sub) log.info( 'Subscription reactivated: subscriber %s (telegram_id: %s) resubscribed via same placement %s', subscriber.id, user_telegram_id, placement.id, ) return subscription = domain.Subscription( placement_id=placement.id, telegram_user_id=subscriber.id, invite_link=invite_link, ) await self.database.create_subscription(subscription) log.info( 'Subscription created: subscriber %s (telegram_id: %s) subscribed via placement %s (invite_link: %s)', subscriber.id, user_telegram_id, placement.id, invite_link, )