Aggiunge filtri avanzati per i destinatari delle campagne email.
CI / scan_ruby (push) Failing after 18m40s
CI / scan_js (push) Successful in 11m46s
CI / lint (push) Failing after 13m8s

La scelta della lista passa da un wizard a tre passi, con anteprima del conteggio e lista congelata solo dopo la conferma.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-24 21:00:11 +02:00
co-authored by Cursor
parent 2db7504629
commit 1f946f63ba
19 changed files with 912 additions and 46 deletions
+29 -1
View File
@@ -22,6 +22,7 @@ class Mailing < ApplicationRecord
validates :send_window_start_minutes, :send_window_end_minutes, presence: true, if: :send_window_enabled?
validate :send_window_order
clears_blank_html :body_html, :body_html_b
before_validation :sync_audience_filters
scope :recent, -> { order(created_at: :desc) }
scope :for_project, ->(project) { where(project_id: project.id) }
@@ -33,7 +34,15 @@ class Mailing < ApplicationRecord
end
def audience_label
Catalog.label_for(Catalog::MAILING_AUDIENCES, audience)
parsed_audience_filters.summary_parts.join(" · ")
end
def parsed_audience_filters
Mailings::AudienceFilters.new(audience_filters.presence || { "preset" => audience.presence || "to_send" })
end
def audience_query
Mailings::AudienceQuery.new(project, parsed_audience_filters, mailing: self)
end
def ab_assignment_label
@@ -219,6 +228,25 @@ class Mailing < ApplicationRecord
private
def sync_audience_filters
source = stringify_audience_filters(audience_filters)
if will_save_change_to_audience? && !will_save_change_to_audience_filters?
source["preset"] = audience
elsif source["preset"].blank?
source["preset"] = audience.presence || "to_send"
end
filters = Mailings::AudienceFilters.new(source)
self.audience_filters = filters.to_h
self.audience = filters.preset
end
def stringify_audience_filters(value)
return {} if value.blank?
value.respond_to?(:to_unsafe_h) ? value.to_unsafe_h.deep_stringify_keys : value.to_h.deep_stringify_keys
end
def send_window_order
return unless send_window_enabled?
return if send_window_start_minutes.blank? || send_window_end_minutes.blank?