from collections import defaultdict from anydi import singleton from fansifter_common.auth.account import Account, AccountAccess from dmp.ad_reporting.enums import AdReportingPlatform from dmp.google.services import GoogleUserAdAccountService from dmp.meta.services import MetaUserAdAccountService from dmp.tiktok.services import TikTokUserAdAccountService UserAdAccountService = ( MetaUserAdAccountService | TikTokUserAdAccountService | GoogleUserAdAccountService ) @singleton class AdReportingAccountService: def __init__( self, meta_user_ad_account_service: MetaUserAdAccountService, tiktok_user_ad_account_service: TikTokUserAdAccountService, google_user_ad_account_service: GoogleUserAdAccountService, ) -> None: self.meta_user_ad_account_service = meta_user_ad_account_service self.tiktok_user_ad_account_service = tiktok_user_ad_account_service self.google_user_ad_account_service = google_user_ad_account_service self.platform_service: dict[AdReportingPlatform, UserAdAccountService] = { AdReportingPlatform.META: self.meta_user_ad_account_service, AdReportingPlatform.TIKTOK: self.tiktok_user_ad_account_service, AdReportingPlatform.GOOGLE: self.google_user_ad_account_service, } def get_ad_account_labels( self, account_ids: set[str], account_access: AccountAccess | None = None, platform: AdReportingPlatform | None = None, ) -> dict[str, set[Account]]: ad_account_labels: dict[str, set[Account]] = defaultdict(set) # Get Meta account ids if platform in [None, AdReportingPlatform.META]: ad_account_labels.update( self._get_ad_account_labels( AdReportingPlatform.META, ad_accounts_ids=account_ids, account_access=account_access, ) ) # Get TikTok account ids if platform in [None, AdReportingPlatform.TIKTOK]: ad_account_labels.update( self._get_ad_account_labels( AdReportingPlatform.TIKTOK, ad_accounts_ids=account_ids, account_access=account_access, ) ) # Get Google account ids if platform in [None, AdReportingPlatform.GOOGLE]: ad_account_labels.update( self._get_ad_account_labels( AdReportingPlatform.GOOGLE, ad_accounts_ids=account_ids, account_access=account_access, ) ) return ad_account_labels def get_allowed_ad_account_labels( self, account_access: AccountAccess, platform: AdReportingPlatform | None = None ) -> dict[str, set[Account]]: ad_account_labels: dict[str, set[Account]] = defaultdict(set) # Get Meta account ids if platform in [None, AdReportingPlatform.META]: ad_account_labels.update( self._get_allowed_ad_account_labels( AdReportingPlatform.META, vendor_ids=account_access.vendor_ids, subaccount_ids=account_access.subaccount_ids, ) ) # Get TikTok account ids if platform in [None, AdReportingPlatform.TIKTOK]: ad_account_labels.update( self._get_allowed_ad_account_labels( AdReportingPlatform.TIKTOK, vendor_ids=account_access.vendor_ids, subaccount_ids=account_access.subaccount_ids, ) ) if platform in [None, AdReportingPlatform.GOOGLE]: ad_account_labels.update( self._get_allowed_ad_account_labels( AdReportingPlatform.GOOGLE, vendor_ids=account_access.vendor_ids, subaccount_ids=account_access.subaccount_ids, ) ) return ad_account_labels def get_allowed_account_ids( self, account_access: AccountAccess, platform: AdReportingPlatform | None = None ) -> set[str]: ad_account_labels = self.get_allowed_ad_account_labels( account_access, platform=platform ) return set(ad_account_labels.keys()) def _get_ad_account_labels( self, platform: AdReportingPlatform, *, ad_accounts_ids: set[str], account_access: AccountAccess | None = None, ) -> dict[str, set[Account]]: ad_account_labels = defaultdict(set) user_ad_accounts = self.platform_service[platform].get_ad_accounts( ad_accounts_ids=ad_accounts_ids ) if not account_access: for user_ad_account in user_ad_accounts: ad_account_labels[user_ad_account.ad_account.external_id].add( Account( vendor_id=user_ad_account.vendor_id, subaccount_id=user_ad_account.subaccount_id, ) ) else: for user_ad_account in user_ad_accounts: account = Account( vendor_id=user_ad_account.vendor_id, subaccount_id=user_ad_account.subaccount_id, ) if account_access.has_access(account): ad_account_labels[user_ad_account.ad_account.external_id].add( account ) return ad_account_labels def _get_allowed_ad_account_labels( self, platform: AdReportingPlatform, *, vendor_ids: list[int], subaccount_ids: list[int], ) -> dict[str, set[Account]]: ad_account_labels = defaultdict(set) user_ad_accounts = self.platform_service[platform].get_labels_ad_accounts( vendor_ids=vendor_ids, subaccount_ids=subaccount_ids ) for user_ad_account in user_ad_accounts: ad_account_labels[user_ad_account.ad_account.external_id].add( Account( vendor_id=user_ad_account.vendor_id, subaccount_id=user_ad_account.subaccount_id, ) ) return ad_account_labels