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>
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
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
|
||||
Reference in New Issue
Block a user