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.exceptions import AdReportingInvalidReportIdError from dmp.ad_reporting.services import ( AdReportingCampaignService, AdReportingReportService, ) from dmp.adapters.db import DefaultDB, ReportingDB, transactional @dataclass(kw_only=True) class AddAdReportingCampaignToReportsRequest(AuthRequest): campaign_id: str report_ids: set[str] @singleton class AddAdReportingCampaignToReportsHandler: access_permission = Permission( "ad_campaign", "view" ) # TODO: upd after ad report logic change permission = Permission("ad_report", "edit") def __init__( self, db: DefaultDB, reporting_db: ReportingDB, auth_service: AuthService, campaign_service: AdReportingCampaignService, report_service: AdReportingReportService, ) -> None: self.db = db self.reporting_db = reporting_db self.auth_service = auth_service self.campaign_service = campaign_service self.report_service = report_service @transactional def handle(self, request: AddAdReportingCampaignToReportsRequest) -> None: account_access = self.auth_service.authorize_for_permission( request.identity_id, permission=self.access_permission ) campaign = self.campaign_service.get_allowed_campaign( account_access, campaign_id=request.campaign_id, ) report_by_id = { report.id: report for report in self.report_service.get_reports( identity_id=request.identity_id, report_ids=request.report_ids ) } for report_id in request.report_ids: if (report := report_by_id.get(report_id)) is None: raise AdReportingInvalidReportIdError(report_id=report_id) if campaign.id in report.campaign_ids: continue self.auth_service.check_owned_resource( report.identity_id, permission=self.permission, resource_id=report.id, ) report.campaign_ids.append(campaign.id) self.report_service.save_report(report) return None