diff --git a/app/controllers/mailings_controller.rb b/app/controllers/mailings_controller.rb index 45fe9e4..15b92d9 100644 --- a/app/controllers/mailings_controller.rb +++ b/app/controllers/mailings_controller.rb @@ -1,6 +1,6 @@ class MailingsController < ApplicationController before_action :require_current_project! - before_action :set_mailing, only: %i[show edit update destroy queue test_send test_preview refresh_recipients update_recipients preview] + before_action :set_mailing, only: %i[show edit update destroy queue cancel test_send test_preview refresh_recipients update_recipients preview] before_action :load_form_collections, only: %i[new create edit update] def index @@ -139,6 +139,20 @@ class MailingsController < ApplicationController redirect_to @mailing, alert: e.message end + def cancel + unless @mailing.sending? + redirect_to @mailing, alert: "Solo un invio in corso può essere fermato." + return + end + + pending = @mailing.pending_count + @mailing.queued_count + @mailing.cancel_send! + redirect_to dashboard_mailings_path, + notice: "Invio fermato. #{@mailing.sent_count} già inviate, #{pending} annullate in coda." + rescue StandardError => e + redirect_to @mailing, alert: e.message + end + def test_send assign_test_preview to = @test_to.to_s.strip diff --git a/app/models/mailing.rb b/app/models/mailing.rb index 3011f92..18ff949 100644 --- a/app/models/mailing.rb +++ b/app/models/mailing.rb @@ -72,6 +72,10 @@ class Mailing < ApplicationRecord status == "sent" end + def cancelled? + status == "cancelled" + end + def editable? draft? end @@ -187,6 +191,17 @@ class Mailing < ApplicationRecord update!(status: "sent", completed_at: Time.current, next_send_at: nil) end + def cancel_send! + raise "Solo un invio in corso può essere fermato" unless sending? + + transaction do + mailing_recipients.where(status: %w[pending queued]).find_each do |recipient| + recipient.update!(status: "skipped", skip_reason: "invio annullato") + end + update!(status: "cancelled", next_send_at: nil, completed_at: Time.current) + end + end + private def send_window_order diff --git a/app/models/mailing_recipient.rb b/app/models/mailing_recipient.rb index 930bfb3..eae4933 100644 --- a/app/models/mailing_recipient.rb +++ b/app/models/mailing_recipient.rb @@ -47,10 +47,13 @@ class MailingRecipient < ApplicationRecord def deliver! with_lock do return if status.in?(%w[sent skipped]) + return abort_delivery!("invio annullato") unless mailing.sending? update!(status: "queued") end + return unless mailing.sending? + html = rendered_html subject_line = rendered_subject_line CampaignMailer.outreach(self, html: html, subject: subject_line).deliver_now @@ -63,6 +66,10 @@ class MailingRecipient < ApplicationRecord private + def abort_delivery!(reason) + update!(status: "skipped", skip_reason: reason) + end + def record_success!(subject_line) transaction do update!(status: "sent", sent_at: Time.current, rendered_subject: subject_line, error_message: nil) diff --git a/app/views/mailings/_progress_card.html.erb b/app/views/mailings/_progress_card.html.erb index 113e11d..9d6f212 100644 --- a/app/views/mailings/_progress_card.html.erb +++ b/app/views/mailings/_progress_card.html.erb @@ -30,4 +30,11 @@ <% elsif mailing.pending_count.positive? %>
Prossima email in lavorazione.
<% end %> + <% if mailing.sending? %> +