from dataclasses import dataclass from anydi import singleton from fansifter_common.auth.requests import AuthAccountRequest from fansifter_common.auth.services import AuthService from fansifter_common.auth.types import Permission from ows_text_campaigns.adapters.db.decorators import transactional from ows_text_campaigns.artist.services import ArtistSettingsService from ows_text_campaigns.campaigns.exceptions import CampaignMustBeDraftError from ows_text_campaigns.campaigns.models import Campaign from ows_text_campaigns.campaigns.services import CampaignService from ows_text_campaigns.campaigns.validators import CampaignValidator from ows_text_campaigns.rosters.services import GlobalFanDataAccessService @dataclass(kw_only=True) class UpdateCampaignRequest(AuthAccountRequest): campaign_id: str name: str global_participant_id: str audience_id: str | None @singleton class UpdateCampaignHandler: permission = Permission("text_campaign", "edit") audience_permission = Permission("audience", "create_text_target") def __init__( self, auth_service: AuthService, campaign_service: CampaignService, campaign_validator: CampaignValidator, artist_settings_service: ArtistSettingsService, global_fandata_access_service: GlobalFanDataAccessService, ) -> None: self.auth_service = auth_service self.campaign_service = campaign_service self.campaign_validator = campaign_validator self.artist_settings_service = artist_settings_service self.global_fandata_access_service = global_fandata_access_service @transactional def handle(self, request: UpdateCampaignRequest) -> Campaign: campaign = self.campaign_service.get_campaign(request.campaign_id) # Check if user has permission to edit campaign self.auth_service.check_account_resource( request.identity_id, account=request.account, permission=self.permission, resource_id=campaign.id, ) # Check if text campaign is not draft if not campaign.is_draft: raise CampaignMustBeDraftError # Validate and set name self.campaign_validator.validate_name( name=request.name, account=request.account, campaign=campaign, ) # Validate audience id if request.audience_id: audience = self.campaign_validator.validate_audience_id( audience_id=request.audience_id, account=request.account, ) else: audience = None # Check if audience is allowed for text campaign self.auth_service.authorize_account( request.identity_id, account=request.account, permission=self.audience_permission, ) # Validate global participant id self.artist_settings_service.validate_global_participant_id( global_participant_id=request.global_participant_id, ) # Validate main rep only artist if global fandata list is enabled for vendor global_fandata_list_enabled = ( self.global_fandata_access_service.is_enabled_for_vendor(request.vendor_id) ) if global_fandata_list_enabled: self.campaign_validator.validate_main_rep_only_artist( global_participant_id=request.global_participant_id, account=request.account, ) # Get artist configured settings artist_settings = self.artist_settings_service.get_configured_settings( global_participant_id=request.global_participant_id, ) campaign.name = request.name campaign.account = request.account campaign.global_participant_id = artist_settings.global_participant_id campaign.updated_by = request.identity_id campaign.audience = audience self.campaign_service.save_campaign(campaign) return campaign