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.models import AdReportingReport from dmp.ad_reporting.repositories import ( AdReportingCampaignRepository, AdReportingReportRepository, ) from dmp.ad_reporting.services import AdReportingAccountService from dmp.ad_reporting.validators import AdReportingReportValidator from dmp.adapters.db import DefaultDB, ReportingDB, transactional @dataclass(kw_only=True) class CreateAdReportingReportRequest(AuthRequest): name: 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 CreateAdReportingReportHandler: access_permission = Permission( "ad_campaign", "view" ) # TODO: upd after ad report logic change permission = Permission("ad_report", "create") def __init__( self, db: DefaultDB, reporting_db: ReportingDB, auth_service: AuthService, report_validator: AdReportingReportValidator, report_repository: AdReportingReportRepository, campaign_repository: AdReportingCampaignRepository, account_service: AdReportingAccountService, ) -> None: self.db = db self.reporting_db = reporting_db self.auth_service = auth_service self.report_validator = report_validator self.report_repository = report_repository self.campaign_repository = campaign_repository self.account_service = account_service @transactional def handle(self, request: CreateAdReportingReportRequest) -> AdReportingReport: self.auth_service.check_owned_resource( request.identity_id, permission=self.permission, ) account_access = self.auth_service.authorize_for_permission( request.identity_id, permission=self.access_permission, ) # Get available account ids account_ids = self.account_service.get_allowed_account_ids(account_access) if request.campaign_ids: campaign_ids = set( self.campaign_repository.find_ids_by_criteria( AdReportingCampaignCriteria( campaign_ids=request.campaign_ids, account_ids=account_ids, ) ) ) 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=account_ids, countries=request.countries, ) ) ) if not campaign_ids: raise AdReportingCampaignNotFoundError # Validate campaign ids self.report_validator.validate_allowed_campaign_ids( campaign_ids=campaign_ids, account_ids=account_ids ) # Validate report name self.report_validator.validate_name( name=request.name, identity_id=request.identity_id ) # Create report report = AdReportingReport( name=request.name, campaign_ids=list(campaign_ids), identity_id=request.identity_id, ) self.report_repository.add(report) return report