from collections.abc import Sequence from dataclasses import dataclass, field from typing import ClassVar from anydi import singleton from fansifter_common.auth.requests import AuthRequest from fansifter_common.auth.services import AuthService from fansifter_common.auth.types import Permission from dmp.ad_reporting.dtos import ( AdReportingCampaign, AdReportingCampaignCriteria, AdReportingSummary, ) from dmp.ad_reporting.enums import AdReportingObjective, AdReportingPlatform from dmp.ad_reporting.repositories import AdReportingCampaignRepository from dmp.ad_reporting.services import ( AdReportingAccountService, AdReportingReportService, ) from dmp.ad_reporting.services.benchmark import ( AdReportingBenchmarkService, ) from dmp.ad_reporting.types import AdReportingCampaignOrderBy @dataclass(kw_only=True) class GetAdReportingReportCampaignsRequest(AuthRequest): DEFAULT_LIMIT: ClassVar[int] = 25 DEFAULT_OFFSET: ClassVar[int] = 0 DEFAULT_ORDER_BY: ClassVar[list[AdReportingCampaignOrderBy]] = ["name.desc"] report_id: str search: str | None global_participant_id: str | None countries: list[str] | None = None platform: AdReportingPlatform | None objective: AdReportingObjective | None order_by: list[AdReportingCampaignOrderBy] limit: int offset: int @dataclass class GetAdReportingReportCampaignsResponse: items: Sequence[AdReportingCampaign] summary: AdReportingSummary # deprecated total: int = field(init=False) def __post_init__(self) -> None: self.total = self.summary.total @singleton class GetAdReportingReportCampaignsHandler: access_permission = Permission( "ad_campaign", "view" ) # TODO: upd after ad report logic change permission = Permission("ad_report", "view") def __init__( self, auth_service: AuthService, campaign_repository: AdReportingCampaignRepository, account_service: AdReportingAccountService, report_service: AdReportingReportService, benchmark_service: AdReportingBenchmarkService, ) -> None: self.auth_service = auth_service self.campaign_repository = campaign_repository self.account_service = account_service self.report_service = report_service self.benchmark_service = benchmark_service def handle( self, request: GetAdReportingReportCampaignsRequest ) -> GetAdReportingReportCampaignsResponse: report = self.report_service.get_report( report_id=request.report_id, identity_id=request.identity_id, ) self.auth_service.check_owned_resource( report.identity_id, permission=self.permission, resource_id=report.id, ) account_access = self.auth_service.authorize_for_permission( request.identity_id, permission=self.access_permission ) if not report.campaign_ids: return GetAdReportingReportCampaignsResponse( items=[], summary=AdReportingSummary(), ) criteria = AdReportingCampaignCriteria( search=request.search, global_participant_id=request.global_participant_id, platform=request.platform, objective=request.objective, campaign_ids=set(report.campaign_ids), countries=request.countries, ) summary = self.campaign_repository.summary_by_criteria(criteria) if summary.total == 0: return GetAdReportingReportCampaignsResponse( items=[], summary=AdReportingSummary(), ) campaigns = self.campaign_repository.find_by_criteria( criteria, order_by=request.order_by, limit=request.limit, offset=request.offset, ) ad_account_labels = self.account_service.get_ad_account_labels( account_ids={campaign.account_id for campaign in campaigns}, platform=request.platform, account_access=account_access, ) for campaign in campaigns: campaign.accounts = ad_account_labels.get(campaign.account_id, set()) campaign.report_id = report.id campaign.report_name = report.name if not request.countries or len(request.countries) <= 1: allowed_ad_account_labels = ( self.account_service.get_allowed_ad_account_labels( account_access=account_access, ) ) self.benchmark_service.prefetch_campaign_benchmarks( items=campaigns, allowed_ad_account_labels=allowed_ad_account_labels, countries=request.countries, ) return GetAdReportingReportCampaignsResponse(items=campaigns, summary=summary)