from dataclasses import dataclass from anydi import singleton from fansifter_common.auth.account import Account from fansifter_common.auth.identity import Identity from fansifter_common.auth.services import AuthService from fansifter_common.auth.types import Permission from dmp.adapters.features import AUDIENCE_SHOW_SMS_CAMPAIGNS_PAGE, Features from dmp.audiences.dtos import AudienceCriteria from dmp.audiences.enums import AudienceTarget from dmp.audiences.exceptions import AudienceTargetNotSupportedError from dmp.audiences.filters import AudienceFilters from dmp.audiences.services import AudienceService from dmp.audiences.types import FanDataListId from dmp.audiences.validators import AudienceValidator from dmp.rosters.exceptions import FanDataListIdIsRequiredError from dmp.rosters.services import GlobalFanDataAccessService @dataclass(kw_only=True) class GetAudienceSizeRequest: identity: Identity vendor_id: int subaccount_id: int fandata_list_ids: list[FanDataListId] target: AudienceTarget filters: AudienceFilters @property def account(self) -> Account: return Account( vendor_id=self.vendor_id, subaccount_id=self.subaccount_id, ) @singleton class GetAudienceSizeHandler: ad_target_permission = Permission("audience", "view_ad_target") email_target_permission = Permission("audience", "view_email_target") text_target_permission = Permission("audience", "view_text_target") def __init__( self, auth_service: AuthService, audience_service: AudienceService, global_fandata_access_service: GlobalFanDataAccessService, audience_validator: AudienceValidator, features: Features, ) -> None: self.auth_service = auth_service self.audience_service = audience_service self.global_fandata_access_service = global_fandata_access_service self.audience_validator = audience_validator self.features = features def handle(self, request: GetAudienceSizeRequest) -> int: if not request.fandata_list_ids: raise FanDataListIdIsRequiredError match request.target: case AudienceTarget.EMAIL: self.auth_service.check_account_resource( request.identity.id, account=request.account, permission=self.email_target_permission, ) case AudienceTarget.ADS: self.auth_service.check_account_resource( request.identity.id, account=request.account, permission=self.ad_target_permission, ) case AudienceTarget.TEXT if self.features.is_on_for_identity( feature_flag_name=AUDIENCE_SHOW_SMS_CAMPAIGNS_PAGE, identity_id=request.identity.id, ): self.auth_service.check_account_resource( request.identity.id, account=request.account, permission=self.text_target_permission, ) case _: raise AudienceTargetNotSupportedError # Validate TEXT audience if request.target == AudienceTarget.TEXT: self.audience_validator.validate_artist_has_phone_number( fandata_list_ids=request.fandata_list_ids ) global_fandata_list_enabled = ( self.global_fandata_access_service.is_enabled_for_any_vendor( vendor_ids=[request.vendor_id], ) ) return self.audience_service.get_audience_size( AudienceCriteria.model_construct( fandata_list_ids=request.fandata_list_ids, vendor_id=request.vendor_id, subaccount_id=request.subaccount_id, identity=request.identity, filters=request.filters, target=request.target, is_global=global_fandata_list_enabled, ), ignore_city_error=True, ignore_main_rep_error=False, )