Class: CampaignDelivery

Inherits:
ApplicationRecord show all
Defined in:
app/models/campaign_delivery.rb

Overview

== Schema Information

Table name: campaign_deliveries
Database name: primary

id :integer not null, primary key
state :string
created_at :datetime not null
updated_at :datetime not null
campaign_email_id :integer
communication_recipient_id :integer
subscriber_id :integer

Indexes

index_campaign_deliveries_on_communication_recipient_id (communication_recipient_id) WHERE (communication_recipient_id IS NOT NULL) USING hash
index_campaign_deliveries_on_state (state)
index_campaign_deliveries_on_subscriber_id (subscriber_id)
unique_subscriber (campaign_email_id,subscriber_id) UNIQUE

Foreign Keys

fk_rails_... (campaign_email_id => campaign_actions.id)
fk_rails_... (communication_recipient_id => communication_recipients.id) ON DELETE => cascade
fk_rails_... (subscriber_id => subscribers.id)

Constant Summary

Constants included from Schedulable

Schedulable::SIMPLE_FORM_OPTIONS

Instance Attribute Summary collapse

Belongs to collapse

Has many collapse

Instance Method Summary collapse

Methods inherited from ApplicationRecord

ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation

Methods included from Schedulable

config

Methods included from Models::AfterCommittable

#after_commit

Methods included from Models::EventPublishable

#publish_event

Instance Attribute Details

#resend_deliveryObject

Returns the value of attribute resend_delivery.



37
38
39
# File 'app/models/campaign_delivery.rb', line 37

def resend_delivery
  @resend_delivery
end

Instance Method Details

#campaign_emailCampaignEmail



30
# File 'app/models/campaign_delivery.rb', line 30

belongs_to :campaign_email

#communication_recipientCommunicationRecipient



32
# File 'app/models/campaign_delivery.rb', line 32

belongs_to :communication_recipient, optional: true

#communicationsActiveRecord::Relation<Communication>

Returns:

See Also:



33
# File 'app/models/campaign_delivery.rb', line 33

has_many :communications, as: :resource

#generate_communicationObject



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'app/models/campaign_delivery.rb', line 76

def generate_communication
  # Advisory lock guards against two CampaignDeliveryWorker jobs racing on
  # the same delivery — the in-memory `queued?` checks in the worker and
  # below don't survive concurrent loads, and `send_immediately: true`
  # transitions the Communication straight to `sent`, so a stale-state
  # second pass would happily build a duplicate. Non-blocking: if another
  # worker holds the lock it's already handling this delivery, skip.
  self.class.with_advisory_lock_result(
    "campaign_delivery_#{id}_generate_communication", timeout_seconds: 0
  ) do
    next if communications.reload.exists?

    comm = CommunicationBuilder.new(
      sender_party: campaign_email.sender,
      sender: campaign_email.sender_email,
      resource: self,
      source_id: campaign_email.source_id,
      email_template_id: campaign_email.email_template_id,
      recipient_party: subscriber.party,
      emails: subscriber.email_address,
      category: campaign_email.campaign.category
    ).create(send_immediately: true, skip_suppression_check: true)
    update(communication_recipient_id: comm.communication_recipients.first&.id)
  end
end

#has_duplicate_subscriber?Boolean

Returns:

  • (Boolean)


132
133
134
135
136
137
# File 'app/models/campaign_delivery.rb', line 132

def has_duplicate_subscriber?
  # find any existing deliveries for the same email address which have already gone past the pending stage
  CampaignDelivery.joins(:subscriber).exists?([
                                                'subscribers.email_address = ? and campaign_deliveries.campaign_email_id = ? and campaign_deliveries.state != ?', subscriber.email_address, campaign_email_id, 'pending'
                                              ])
end

#invalid_email?Boolean

Returns:

  • (Boolean)


102
103
104
105
106
# File 'app/models/campaign_delivery.rb', line 102

def invalid_email?
  return true if subscriber.email_address.blank?

  !Truemail.valid?(subscriber.email_address)
end

#post_communication_exception_hookObject



116
117
118
# File 'app/models/campaign_delivery.rb', line 116

def post_communication_exception_hook
  exception
end

#post_communication_sent_hookObject



108
109
110
# File 'app/models/campaign_delivery.rb', line 108

def post_communication_sent_hook
  sent
end

#post_communication_suppressed_hookObject



112
113
114
# File 'app/models/campaign_delivery.rb', line 112

def post_communication_suppressed_hook
  suppressed
end

#subscriberSubscriber

Returns:

See Also:



31
# File 'app/models/campaign_delivery.rb', line 31

belongs_to :subscriber

#subscriber_inactive?Boolean

Returns:

  • (Boolean)


128
129
130
# File 'app/models/campaign_delivery.rb', line 128

def subscriber_inactive?
  Party.joins('left join parties customers on customers.id = parties.customer_id').where(id: ContactPoint.emails.where(detail: subscriber.email_address).select(:party_id)).where("parties.state in ('closed','bankrupt') or parties.inactive = true or customers.state in ('closed','bankrupt')").exists?
end

#subscriber_on_suppression_list?Boolean

Returns:

  • (Boolean)


120
121
122
# File 'app/models/campaign_delivery.rb', line 120

def subscriber_on_suppression_list?
  EmailPreference.where(email: subscriber.email_address).where("disable_#{campaign_email.campaign.category} is true").exists?
end

#subscriber_previously_bounced?Boolean

Returns:

  • (Boolean)


124
125
126
# File 'app/models/campaign_delivery.rb', line 124

def subscriber_previously_bounced?
  ContactPoint.exists?(category: 'email', detail: subscriber.email_address, state: 'failed')
end

#to_sObject



139
140
141
# File 'app/models/campaign_delivery.rb', line 139

def to_s
  "Campaign: #{campaign_email&.campaign&.name || 'missing'}"
end