Aggiunge pulsante per fermare un invio email in corso.
Permette di annullare i destinatari ancora in coda mantenendo le email già inviate. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
class MailingsController < ApplicationController
|
class MailingsController < ApplicationController
|
||||||
before_action :require_current_project!
|
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]
|
before_action :load_form_collections, only: %i[new create edit update]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@@ -139,6 +139,20 @@ class MailingsController < ApplicationController
|
|||||||
redirect_to @mailing, alert: e.message
|
redirect_to @mailing, alert: e.message
|
||||||
end
|
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
|
def test_send
|
||||||
assign_test_preview
|
assign_test_preview
|
||||||
to = @test_to.to_s.strip
|
to = @test_to.to_s.strip
|
||||||
|
|||||||
@@ -72,6 +72,10 @@ class Mailing < ApplicationRecord
|
|||||||
status == "sent"
|
status == "sent"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def cancelled?
|
||||||
|
status == "cancelled"
|
||||||
|
end
|
||||||
|
|
||||||
def editable?
|
def editable?
|
||||||
draft?
|
draft?
|
||||||
end
|
end
|
||||||
@@ -187,6 +191,17 @@ class Mailing < ApplicationRecord
|
|||||||
update!(status: "sent", completed_at: Time.current, next_send_at: nil)
|
update!(status: "sent", completed_at: Time.current, next_send_at: nil)
|
||||||
end
|
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
|
private
|
||||||
|
|
||||||
def send_window_order
|
def send_window_order
|
||||||
|
|||||||
@@ -47,10 +47,13 @@ class MailingRecipient < ApplicationRecord
|
|||||||
def deliver!
|
def deliver!
|
||||||
with_lock do
|
with_lock do
|
||||||
return if status.in?(%w[sent skipped])
|
return if status.in?(%w[sent skipped])
|
||||||
|
return abort_delivery!("invio annullato") unless mailing.sending?
|
||||||
|
|
||||||
update!(status: "queued")
|
update!(status: "queued")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return unless mailing.sending?
|
||||||
|
|
||||||
html = rendered_html
|
html = rendered_html
|
||||||
subject_line = rendered_subject_line
|
subject_line = rendered_subject_line
|
||||||
CampaignMailer.outreach(self, html: html, subject: subject_line).deliver_now
|
CampaignMailer.outreach(self, html: html, subject: subject_line).deliver_now
|
||||||
@@ -63,6 +66,10 @@ class MailingRecipient < ApplicationRecord
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def abort_delivery!(reason)
|
||||||
|
update!(status: "skipped", skip_reason: reason)
|
||||||
|
end
|
||||||
|
|
||||||
def record_success!(subject_line)
|
def record_success!(subject_line)
|
||||||
transaction do
|
transaction do
|
||||||
update!(status: "sent", sent_at: Time.current, rendered_subject: subject_line, error_message: nil)
|
update!(status: "sent", sent_at: Time.current, rendered_subject: subject_line, error_message: nil)
|
||||||
|
|||||||
@@ -30,4 +30,11 @@
|
|||||||
<% elsif mailing.pending_count.positive? %>
|
<% elsif mailing.pending_count.positive? %>
|
||||||
<p class="mt-3 text-xs text-zinc-500">Prossima email in lavorazione.</p>
|
<p class="mt-3 text-xs text-zinc-500">Prossima email in lavorazione.</p>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
<% if mailing.sending? %>
|
||||||
|
<div class="mt-4 border-t border-zinc-100 pt-4 dark:border-zinc-800">
|
||||||
|
<%= button_to "Ferma invio", cancel_mailing_path(mailing), method: :post,
|
||||||
|
class: btn_danger,
|
||||||
|
form: { data: { turbo_confirm: "Fermare l'invio? Restano inviate #{mailing.sent_count} email, #{mailing.pending_count + mailing.queued_count} in coda verranno annullate." } } %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -30,6 +30,10 @@
|
|||||||
<% if @mailing.editable? %>
|
<% if @mailing.editable? %>
|
||||||
<%= link_to "Modifica contenuto", edit_mailing_path(@mailing), class: btn_secondary %>
|
<%= link_to "Modifica contenuto", edit_mailing_path(@mailing), class: btn_secondary %>
|
||||||
<%= button_to "Aggiorna lista", refresh_recipients_mailing_path(@mailing), method: :post, class: btn_secondary %>
|
<%= button_to "Aggiorna lista", refresh_recipients_mailing_path(@mailing), method: :post, class: btn_secondary %>
|
||||||
|
<% elsif @mailing.sending? %>
|
||||||
|
<%= button_to "Ferma invio", cancel_mailing_path(@mailing), method: :post,
|
||||||
|
class: btn_danger,
|
||||||
|
form: { data: { turbo_confirm: "Fermare l'invio? Le #{@mailing.sent_count} già inviate restano, #{@mailing.pending_count + @mailing.queued_count} in coda verranno annullate." } } %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ Rails.application.routes.draw do
|
|||||||
end
|
end
|
||||||
member do
|
member do
|
||||||
post :queue
|
post :queue
|
||||||
|
post :cancel
|
||||||
post :test_send
|
post :test_send
|
||||||
get :test_preview
|
get :test_preview
|
||||||
post :refresh_recipients
|
post :refresh_recipients
|
||||||
|
|||||||
@@ -184,4 +184,25 @@ class MailingsControllerTest < ActionDispatch::IntegrationTest
|
|||||||
assert_equal "B {{societa}}", mailing.subject_b
|
assert_equal "B {{societa}}", mailing.subject_b
|
||||||
assert_includes mailing.body_html_b, "Versione B dal template"
|
assert_includes mailing.body_html_b, "Versione B dal template"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "cancel stops pending recipients and keeps sent ones" do
|
||||||
|
login_as users(:admin)
|
||||||
|
follow_redirect! if response.redirect?
|
||||||
|
create_campaign_org(name: "Seconda societa", email: "seconda@example.com")
|
||||||
|
mailing = create_mailing(identity: @identity, audience: "to_send")
|
||||||
|
mailing.rebuild_recipients!
|
||||||
|
recipients = mailing.mailing_recipients.order(:id).to_a
|
||||||
|
assert recipients.size >= 2
|
||||||
|
recipients.first.update!(status: "sent", sent_at: Time.current)
|
||||||
|
mailing.update!(status: "sending", queued_at: Time.current, test_sent_at: Time.current, test_sent_to: "test@example.com")
|
||||||
|
|
||||||
|
post cancel_mailing_path(mailing, project_code: @project.code)
|
||||||
|
|
||||||
|
assert_redirected_to dashboard_mailings_path(project_code: @project.code)
|
||||||
|
assert_equal "cancelled", mailing.reload.status
|
||||||
|
assert_equal "sent", recipients.first.reload.status
|
||||||
|
assert_equal "skipped", recipients.second.reload.status
|
||||||
|
assert_equal "invio annullato", recipients.second.skip_reason
|
||||||
|
assert mailing.mailing_recipients.pending.none?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user