from anydi import singleton from fansifter_common.auth.account import Account from dmp.ad_reporting.dtos import ( AdReportingAd, AdReportingAdSet, AdReportingCampaign, AdReportingCampaignBenchmarkByAccountArtistCriteria, AdReportingCampaignBenchmarkByAccountCriteria, ) from dmp.ad_reporting.enums import AdReportingObjective, AdReportingPlatform from dmp.ad_reporting.models import ( AdReportingCampaignBenchmarkByAccountArtistDbt, AdReportingCampaignBenchmarkByAccountDbt, ) from dmp.ad_reporting.repositories import ( AdReportingCampaignBenchmarkByAccountArtistRepository, AdReportingCampaignBenchmarkByAccountRepository, ) @singleton class AdReportingBenchmarkService: def __init__( self, benchmark_by_account_repository: AdReportingCampaignBenchmarkByAccountRepository, benchmark_by_account_artist_repository: AdReportingCampaignBenchmarkByAccountArtistRepository, ) -> None: self.benchmark_by_account_repository = benchmark_by_account_repository self.benchmark_by_account_artist_repository = ( benchmark_by_account_artist_repository ) def prefetch_campaign_benchmarks( self, items: list[AdReportingCampaign] | list[AdReportingAd] | list[AdReportingAdSet], allowed_ad_account_labels: dict[str, set[Account]], countries: list[str] | None = None, ) -> None: # Get unique accounts (labels) accounts = { account for accounts in allowed_ad_account_labels.values() for account in accounts } # Get unique artists artists = { global_participant_id for item in items for global_participant_id in item.global_participant_ids } benchmarks = self._get_campaign_label_benchmarks( accounts=accounts, countries=countries, ) artist_benchmarks = self._get_campaign_label_artist_benchmarks( accounts=accounts, artists=artists, countries=countries, ) # Assign benchmark/artist_benchmark only if there is single one to assign for item in items: picked_benchmarks: list[AdReportingCampaignBenchmarkByAccountDbt] = [] picked_artist_benchmarks: list[ AdReportingCampaignBenchmarkByAccountArtistDbt ] = [] for account in item.accounts: benchmark = benchmarks.get( ( account.vendor_id, account.subaccount_id, item.platform, item.objective, ) ) if benchmark: picked_benchmarks.append(benchmark) for global_participant_id in item.global_participant_ids: artist_benchmark = artist_benchmarks.get( ( account.vendor_id, account.subaccount_id, item.platform, item.objective, global_participant_id, ) ) if artist_benchmark: picked_artist_benchmarks.append(artist_benchmark) if len(picked_benchmarks) == 1: item.benchmark = picked_benchmarks[0].rate if len(picked_artist_benchmarks) == 1: item.artist_benchmark = picked_artist_benchmarks[0].rate def _get_campaign_label_benchmarks( self, accounts: set[Account] | None, countries: list[str] | None ) -> dict[ tuple[int, int, AdReportingPlatform | None, AdReportingObjective | None], AdReportingCampaignBenchmarkByAccountDbt, ]: if accounts is None: return {} return { (item.vendor_id, item.subaccount_id, item.platform, item.objective): item for item in ( self.benchmark_by_account_repository.find_unique_by_criteria( criteria=AdReportingCampaignBenchmarkByAccountCriteria( accounts={ ",".join( [str(account.vendor_id), str(account.subaccount_id)] ) for account in accounts }, countries=countries, ) ) ) } def _get_campaign_label_artist_benchmarks( self, accounts: set[Account] | None, artists: set[str] | None, countries: list[str] | None, ) -> dict[ tuple[int, int, AdReportingPlatform | None, AdReportingObjective | None, str], AdReportingCampaignBenchmarkByAccountArtistDbt, ]: if accounts is None and artists is None: return {} return { ( item.vendor_id, item.subaccount_id, item.platform, item.objective, item.global_participant_id, ): item for item in ( self.benchmark_by_account_artist_repository.find_unique_by_criteria( criteria=AdReportingCampaignBenchmarkByAccountArtistCriteria( accounts={ ",".join( [str(account.vendor_id), str(account.subaccount_id)] ) for account in accounts or [] }, artists=artists, countries=countries, ) ) ) }