from dataclasses import dataclass from anydi import singleton from fansifter_common.adapters.sendgrid import SendGridClient from fansifter_common.auth.requests import AuthRequest from fansifter_common.auth.services import AuthService from fansifter_common.auth.types import Permission from email_campaigns.adapters.db.decorators import transactional from email_campaigns.campaigns.enums import EmailCampaignStatus from email_campaigns.campaigns.exceptions import ( CampaignAlreadyQueuedError, EmailCampaignMustBeScheduledError, ) from email_campaigns.campaigns.services import EmailCampaignService @dataclass(kw_only=True) class UnscheduleCampaignRequest(AuthRequest): campaign_id: str @singleton class UnscheduleCampaignHandler: permission = Permission("email_campaign", "schedule") def __init__( self, auth_service: AuthService, sendgrid_client: SendGridClient, campaign_service: EmailCampaignService, ) -> None: self.auth_service = auth_service self.sendgrid_client = sendgrid_client self.campaign_service = campaign_service @transactional def handle(self, request: UnscheduleCampaignRequest) -> None: campaign = self.campaign_service.get_campaign(request.campaign_id) self.auth_service.authorize_account( request.identity_id, permission=self.permission, account=campaign.account, ) # Do not allow un-scheduling of non-scheduled campaigns if not campaign.is_scheduled: raise EmailCampaignMustBeScheduledError # Do not allow un-scheduling of campaigns # that are scheduled to be sent in the period if self.campaign_service.should_enqueue_campaign(campaign): raise CampaignAlreadyQueuedError campaign.status = EmailCampaignStatus.DRAFT campaign.send_at = None campaign.scheduled_at = None campaign.send_at_timezone = None campaign.recipients_count = 0 campaign.updated_by = request.identity_id # Save the email campaign self.campaign_service.save_campaign(campaign)