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.adapters.db import DefaultDB, transactional from dmp.app_connections.services import AdsConnectionService from dmp.google.exceptions import GoogleAdAccountNotFoundError from dmp.google.models import GoogleAdAccount, GoogleAdReportingConnection from dmp.google.repositories import ( GoogleAdAccountRepository, GoogleAdReportingConnectionRepository, GoogleUserAdAccountRepository, GoogleUserConnectionRepository, ) @dataclass class DeleteGoogleUserAdAccountRequest(AuthRequest): ad_account_id: str @singleton class DeleteGoogleUserAdAccountHandler: permission = Permission("ad_account", "delete") def __init__( self, db: DefaultDB, auth_service: AuthService, ad_account_repository: GoogleAdAccountRepository, user_ad_account_repository: GoogleUserAdAccountRepository, user_connection_repository: GoogleUserConnectionRepository, ad_reporting_connection_repository: GoogleAdReportingConnectionRepository, ads_connection_service: AdsConnectionService, ) -> None: self.db = db self.auth_service = auth_service self.ad_account_repository = ad_account_repository self.user_ad_account_repository = user_ad_account_repository self.user_connection_repository = user_connection_repository self.ad_reporting_connection_repository = ad_reporting_connection_repository self.ads_connection_service = ads_connection_service @transactional def handle(self, request: DeleteGoogleUserAdAccountRequest) -> None: user_ad_account = ( self.user_ad_account_repository.get_by_ad_account_id_and_identity_id( ad_account_id=request.ad_account_id, identity_id=request.identity_id ) ) # Delete user ad account if user_ad_account: self.auth_service.check_account_owned_resource( request.identity_id, account=user_ad_account.account, permission=self.permission, resource_identity_id=user_ad_account.identity_id, resource_id=request.ad_account_id, ) self.user_ad_account_repository.delete(user_ad_account) ad_account: GoogleAdAccount | None = user_ad_account.ad_account else: ad_account = self.ad_account_repository.get(request.ad_account_id) if not ad_account: raise GoogleAdAccountNotFoundError # Remove ad account from user connection user_connections = self.user_connection_repository.find_by_identity_ids( identity_ids=[request.identity_id] ) for user_connection in user_connections: for connection_ad_account in user_connection.connection_ad_accounts: if connection_ad_account.ad_account_id == ad_account.id: user_connection.remove_connection_ad_account(connection_ad_account) if not user_connection.connection_ad_accounts: self.user_connection_repository.delete(user_connection) # Store deleted ad reporting connections deleted_ad_reporting_connections: list[GoogleAdReportingConnection] = [] # Remove ad account from ad reporting connection ad_reporting_connections = ( self.ad_reporting_connection_repository.find_by_identity_ids( identity_ids=[request.identity_id] ) ) for ad_reporting_connection in ad_reporting_connections: ad_reporting_connection.remove_ad_account(ad_account) if not ad_reporting_connection.ad_accounts: self.ad_reporting_connection_repository.delete(ad_reporting_connection) deleted_ad_reporting_connections.append(ad_reporting_connection) # Delete Fivetran ad reporting connection for ad_reporting_connection in deleted_ad_reporting_connections: self.ads_connection_service.delete_fivetran_ad_account( ad_reporting_connection, ad_account_external_id=ad_account.external_id ) return None