from collections.abc import Sequence from dataclasses import dataclass 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 ( AdReportingCampaignCriteria, AdReportingCampaignIdName, ) from dmp.ad_reporting.enums import AdReportingObjective, AdReportingPlatform from dmp.ad_reporting.exceptions import AdReportingReportNotFoundError from dmp.ad_reporting.repositories import AdReportingCampaignRepository from dmp.ad_reporting.services import ( AdReportingAccountService, AdReportingReportService, ) @dataclass(kw_only=True) class GetAdReportingCampaignsNamesRequest(AuthRequest): DEFAULT_LIMIT: ClassVar[int] = 100 DEFAULT_OFFSET: ClassVar[int] = 0 search: str | None global_participant_id: str | None platform: AdReportingPlatform | None objective: AdReportingObjective | None report_id: str | None limit: int offset: int @dataclass(kw_only=True) class GetAdReportingCampaignsNamesResponse: items: Sequence[AdReportingCampaignIdName] total: int @singleton class GetAdReportingCampaignsNamesHandler: permission = Permission("ad_campaign", "view") report_permission = Permission("ad_report", "view") def __init__( self, auth_service: AuthService, campaign_repository: AdReportingCampaignRepository, account_service: AdReportingAccountService, report_service: AdReportingReportService, ) -> None: self.auth_service = auth_service self.campaign_repository = campaign_repository self.account_service = account_service self.report_service = report_service def handle( self, request: GetAdReportingCampaignsNamesRequest ) -> GetAdReportingCampaignsNamesResponse: criteria = AdReportingCampaignCriteria( search=request.search, global_participant_id=request.global_participant_id, platform=request.platform, objective=request.objective, ) if request.report_id: try: report = self.report_service.get_report( report_id=request.report_id, identity_id=request.identity_id, ) except AdReportingReportNotFoundError: return GetAdReportingCampaignsNamesResponse(items=[], total=0) self.auth_service.check_owned_resource( report.identity_id, permission=self.report_permission, resource_id=report.id, ) criteria.campaign_ids = set(report.campaign_ids) else: account_access = self.auth_service.authorize_for_permission( request.identity_id, permission=self.permission, ) ad_account_labels = self.account_service.get_allowed_ad_account_labels( account_access ) if not ad_account_labels: return GetAdReportingCampaignsNamesResponse(items=[], total=0) criteria.account_ids = set(ad_account_labels.keys()) total = self.campaign_repository.count_by_criteria(criteria) if total == 0: return GetAdReportingCampaignsNamesResponse(items=[], total=0) items = self.campaign_repository.find_id_names_by_criteria( criteria, limit=request.limit, offset=request.offset ) return GetAdReportingCampaignsNamesResponse(items=items, total=total)