diff --git a/app/controllers/mailings_controller.rb b/app/controllers/mailings_controller.rb index d057bdb..4dcbbed 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 cancel test_send test_preview refresh_recipients update_recipients preview audience update_audience] + before_action :set_mailing, only: %i[show edit update destroy queue pause resume cancel test_send test_preview refresh_recipients update_recipients preview audience update_audience] before_action :load_form_collections, only: %i[new create edit update] def index @@ -11,8 +11,9 @@ class MailingsController < ApplicationController @page_title = "Invii email" @mailings = Mailing.for_project(current_project).includes(:mail_identity).recent @mail_identities_count = MailIdentity.active.count - @active_mailings = @mailings.select(&:sending?) - @paused_mailings = @active_mailings.select { |mailing| mailing.next_send_at.present? && mailing.next_send_at > Time.current } + @active_mailings = @mailings.select { |mailing| mailing.sending? || mailing.paused? } + @window_paused_mailings = @mailings.select(&:sending?).select { |mailing| mailing.next_send_at.present? && mailing.next_send_at > Time.current } + @paused_mailings = @window_paused_mailings @completed_today = @mailings.count { |mailing| mailing.sent? && mailing.completed_at&.to_date == Time.zone.today } @failed_open = @mailings.sum(&:failed_count) end @@ -180,16 +181,42 @@ class MailingsController < ApplicationController redirect_to @mailing, alert: e.message end - def cancel + def pause unless @mailing.sending? - redirect_to @mailing, alert: "Solo un invio in corso può essere fermato." + redirect_to @mailing, alert: "Solo un invio in corso può essere messo in pausa." + return + end + + remaining = @mailing.pending_count + @mailing.queued_count + @mailing.pause_send! + redirect_to dashboard_mailings_path, + notice: "Invio in pausa. #{@mailing.sent_count} già inviate, #{remaining} pronte per quando riprendi." + rescue StandardError => e + redirect_to @mailing, alert: e.message + end + + def resume + unless @mailing.paused? + redirect_to @mailing, alert: "Solo un invio in pausa può essere ripreso." + return + end + + @mailing.resume_send! + redirect_to dashboard_mailings_path, notice: "Invio ripreso da dove era rimasto." + rescue StandardError => e + redirect_to @mailing, alert: e.message + end + + def cancel + unless @mailing.sending? || @mailing.paused? + redirect_to @mailing, alert: "Solo un invio in corso o in pausa può essere annullato." 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." + notice: "Invio annullato. #{@mailing.sent_count} già inviate, #{pending} in coda saltate." rescue StandardError => e redirect_to @mailing, alert: e.message end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 5a76373..bbf9028 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -163,6 +163,7 @@ module ApplicationHelper colors = { "draft" => "bg-zinc-100 text-zinc-700 dark:bg-zinc-800 dark:text-zinc-200", "sending" => "bg-amber-100 text-amber-800 dark:bg-amber-950 dark:text-amber-200", + "paused" => "bg-sky-100 text-sky-800 dark:bg-sky-950 dark:text-sky-200", "sent" => "bg-emerald-100 text-emerald-800 dark:bg-emerald-950 dark:text-emerald-200", "cancelled" => "bg-rose-100 text-rose-800 dark:bg-rose-950 dark:text-rose-200" } diff --git a/app/models/catalog.rb b/app/models/catalog.rb index 60394c3..891c77f 100644 --- a/app/models/catalog.rb +++ b/app/models/catalog.rb @@ -68,6 +68,7 @@ module Catalog MAILING_STATUSES = { "draft" => "Bozza", "sending" => "Invio in corso", + "paused" => "In pausa", "sent" => "Inviata", "cancelled" => "Annullata" }.freeze diff --git a/app/models/mailing.rb b/app/models/mailing.rb index a08e0c9..5b4ae2e 100644 --- a/app/models/mailing.rb +++ b/app/models/mailing.rb @@ -77,6 +77,10 @@ class Mailing < ApplicationRecord status == "sending" end + def paused? + status == "paused" + end + def sent? status == "sent" end @@ -215,8 +219,23 @@ class Mailing < ApplicationRecord update!(status: "sent", completed_at: Time.current, next_send_at: nil) end + def pause_send! + raise "Solo un invio in corso può essere messo in pausa" unless sending? + + update!(status: "paused", next_send_at: nil) + end + + def resume_send! + raise "Solo un invio in pausa può essere ripreso" unless paused? + raise "Nessun destinatario da inviare" if pending_count.zero? && queued_count.zero? + + update!(status: "sending") + enqueue_next_recipient!(mailing_recipients.pending.order(:id).first, from: Time.current) if pending_count.positive? + DrainOutboundJob.perform_later if mailing_recipients.queued.exists? + end + def cancel_send! - raise "Solo un invio in corso può essere fermato" unless sending? + raise "Solo un invio in corso o in pausa può essere annullato" unless sending? || paused? transaction do mailing_recipients.where(status: %w[pending queued]).find_each do |recipient| diff --git a/app/views/mailings/_progress_card.html.erb b/app/views/mailings/_progress_card.html.erb index 4146a40..e5dc5fd 100644 --- a/app/views/mailings/_progress_card.html.erb +++ b/app/views/mailings/_progress_card.html.erb @@ -31,11 +31,9 @@ <% elsif mailing.pending_count.positive? %>
Prossima email in lavorazione.
<% end %> - <% if mailing.sending? %> + <% if mailing.sending? || mailing.paused? %>