from dataclasses import dataclass 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 from dmp.ad_reporting.enums import AdReportingObjective, AdReportingPlatform from dmp.ad_reporting.exceptions import ( AdReportingCampaignNotFoundError, ) from dmp.ad_reporting.repositories import AdReportingCampaignRepository from dmp.ad_reporting.services import ( AdReportingAccountService, AdReportingReportService, ) from dmp.adapters.db import DefaultDB, ReportingDB, transactional @dataclass(kw_only=True) class AddAdReportingReportToCampaignsRequest(AuthRequest): report_id: str campaign_ids: set[str] | None search: str | None global_participant_id: str | None countries: list[str] | None = None platform: AdReportingPlatform | None objective: AdReportingObjective | None @singleton class AddAdReportingReportToCampaignsHandler: report_permission = Permission("ad_report", "edit") campaign_permission = Permission("ad_campaign", "view") def __init__( self, db: DefaultDB, reporting_db: ReportingDB, auth_service: AuthService, campaign_repository: AdReportingCampaignRepository, report_service: AdReportingReportService, account_service: AdReportingAccountService, ) -> None: self.db = db self.reporting_db = reporting_db self.auth_service = auth_service self.campaign_repository = campaign_repository self.report_service = report_service self.account_service = account_service @transactional def handle(self, request: AddAdReportingReportToCampaignsRequest) -> int: report = self.report_service.get_report( identity_id=request.identity_id, report_id=request.report_id, ) self.auth_service.check_owned_resource( report.identity_id, permission=self.report_permission, resource_id=report.id, ) account_access = self.auth_service.authorize_for_permission( request.identity_id, permission=self.campaign_permission, ) ad_account_labels = self.account_service.get_allowed_ad_account_labels( account_access ) if not ad_account_labels: raise AdReportingCampaignNotFoundError if request.campaign_ids: campaign_ids = set( self.campaign_repository.find_ids_by_criteria( AdReportingCampaignCriteria( campaign_ids=request.campaign_ids, account_ids=set(ad_account_labels.keys()), ) ) ) else: campaign_ids = set( self.campaign_repository.find_ids_by_criteria( AdReportingCampaignCriteria( search=request.search, global_participant_id=request.global_participant_id, platform=request.platform, objective=request.objective, account_ids=set(ad_account_labels.keys()), countries=request.countries, ) ) ) if not campaign_ids: raise AdReportingCampaignNotFoundError new_campaign_ids = campaign_ids - set(report.campaign_ids) if new_campaign_ids: report.campaign_ids.extend(new_campaign_ids) self.report_service.save_report(report) return len(new_campaign_ids)