import datetime import logging from typing import TYPE_CHECKING from src import domain, dto if TYPE_CHECKING: from .. import Usecase log = logging.getLogger(__name__) async def update_views_manually(self: 'Usecase', input: dto.UpdateViewsManuallyInput) -> dto.PurchaseOutput: async with self.database.transaction(): purchase = await self.database.get_purchase(input.user_id, input.purchase_id) if not purchase: log.warning('Purchase %s not found for user %s', input.purchase_id, input.user_id) raise domain.PurchaseNotFound(input.purchase_id) fetched_at = datetime.datetime.now(datetime.UTC) purchase.views_count = input.views_count purchase.views_availability = domain.PostViewsAvailability.MANUAL purchase.last_views_fetch_at = fetched_at await self.database.update_purchase(purchase) snapshot = domain.ViewsSnapshot( purchase_id=purchase.id, views_count=input.views_count, fetched_at=fetched_at, ) await self.database.create_views_snapshot(snapshot) log.info('Views manually updated for purchase %s: %d', purchase.id, input.views_count) return dto.PurchaseOutput( id=purchase.id, target_channel_id=purchase.target_channel_id, target_channel_title=purchase.target_channel.title, external_channel_id=purchase.external_channel_id, external_channel_title=purchase.external_channel.title, creative_id=purchase.creative_id, creative_name=purchase.creative.name, placement_date=purchase.placement_date, cost=purchase.cost, comment=purchase.comment, ad_post_url=purchase.ad_post_url, invite_link_type=purchase.invite_link_type, invite_link=purchase.invite_link, status=purchase.status, subscriptions_count=purchase.subscriptions_count, views_count=purchase.views_count, views_availability=purchase.views_availability, last_views_fetch_at=purchase.last_views_fetch_at, created_at=purchase.created_at, )