Files
eminuxCRM/app/models/mailing.rb
T
eminuxandCursor c4e5f289cf
CI / scan_ruby (push) Failing after 11m20s
CI / scan_js (push) Successful in 10m35s
CI / lint (push) Has been cancelled
Commit iniziale di eminuxCRM: CRM Rails con pipeline, campagne email e Docker.
Include autenticazione, progetti isolati, mail marketing HTML con SMTP, test A/B e editor WYSIWYG.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-17 23:01:48 +02:00

108 lines
2.7 KiB
Ruby

class Mailing < ApplicationRecord
include Auditable
include HtmlBlankable
belongs_to :project
belongs_to :mail_identity
belongs_to :mail_template, optional: true
belongs_to :mail_template_b, class_name: "MailTemplate", optional: true
has_many :mailing_recipients, dependent: :destroy
has_many :organizations, through: :mailing_recipients
has_many_attached :files
validates :name, :subject, :body_html, presence: true
validates :status, inclusion: { in: Catalog::MAILING_STATUSES.keys }
validates :audience, inclusion: { in: Catalog::MAILING_AUDIENCES.keys }
validates :ab_assignment, inclusion: { in: Catalog::MAILING_AB_ASSIGNMENTS.keys }
validates :interval_seconds, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 86_400 }
validates :subject_b, :body_html_b, presence: true, if: :ab_test?
clears_blank_html :body_html, :body_html_b
scope :recent, -> { order(created_at: :desc) }
scope :for_project, ->(project) { where(project_id: project.id) }
def status_label
Catalog.label_for(Catalog::MAILING_STATUSES, status)
end
def audience_label
Catalog.label_for(Catalog::MAILING_AUDIENCES, audience)
end
def ab_assignment_label
Catalog.label_for(Catalog::MAILING_AB_ASSIGNMENTS, ab_assignment)
end
def ab_from_record?
ab_assignment == "from_record"
end
def subject_for(variant)
ab_test? && variant.to_s.upcase == "B" ? subject_b : subject
end
def body_for(variant)
ab_test? && variant.to_s.upcase == "B" ? body_html_b : body_html
end
def variant_pending_count(variant)
mailing_recipients.pending.where(ab_variant: variant).count
end
def variant_sent_count(variant)
mailing_recipients.sent.where(ab_variant: variant).count
end
def draft?
status == "draft"
end
def sending?
status == "sending"
end
def sent?
status == "sent"
end
def editable?
draft?
end
def pending_count
mailing_recipients.pending.count
end
def skipped_count
mailing_recipients.skipped.count
end
def sent_count
mailing_recipients.sent.count
end
def failed_count
mailing_recipients.failed.count
end
def rebuild_recipients!
mailing_recipients.delete_all
Mailings::RecipientBuilder.new(self).call
end
def queue_send!
raise "Nessun destinatario da inviare" if pending_count.zero?
update!(status: "sending", queued_at: Time.current)
first = mailing_recipients.pending.order(:id).first
SendMailingRecipientJob.perform_later(first.id)
end
def mark_finished_if_done!
return unless sending?
return if mailing_recipients.pending.exists? || mailing_recipients.queued.exists?
update!(status: "sent", completed_at: Time.current)
end
end