Class: SubscriberList
Overview
== Schema Information
Table name: subscriber_lists
Database name: primary
id :integer not null, primary key
add_all_emails :boolean
customer_search_params :jsonb
list_type :string
name :string
created_at :datetime not null
updated_at :datetime not null
creator_id :integer
updater_id :integer
Constant Summary
collapse
- LIST_TYPES =
%w[email_static email_dynamic customer].freeze
Models::Auditable::ALWAYS_IGNORED
Constants included
from Schedulable
Schedulable::SIMPLE_FORM_OPTIONS
Instance Attribute Summary collapse
Has and belongs to many
collapse
Class Method Summary
collapse
Instance Method Summary
collapse
#all_skipped_columns, #audit_reference_data, #creator, #should_not_save_version, #stamp_record, #updater
ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation
config
#after_commit
#publish_event
Instance Attribute Details
#customer_search_params ⇒ Object
39
|
# File 'app/models/subscriber_list.rb', line 39
validates :customer_search_params, presence: true, if: :email_dynamic?
|
#imported_subscribers_csv ⇒ Object
Returns the value of attribute imported_subscribers_csv.
46
47
48
|
# File 'app/models/subscriber_list.rb', line 46
def imported_subscribers_csv
@imported_subscribers_csv
end
|
#list_type ⇒ Object
38
|
# File 'app/models/subscriber_list.rb', line 38
validates :name, :list_type, presence: true
|
#name ⇒ Object
38
|
# File 'app/models/subscriber_list.rb', line 38
validates :name, :list_type, presence: true
|
Class Method Details
.customers ⇒ ActiveRecord::Relation<SubscriberList>
A relation of SubscriberLists that are customers. Active Record Scope
36
|
# File 'app/models/subscriber_list.rb', line 36
scope :customers, -> { where(list_type: 'customer') }
|
.ensure_unique_name(name) ⇒ Object
48
49
50
51
52
53
|
# File 'app/models/subscriber_list.rb', line 48
def self.ensure_unique_name(name)
unique_name = name.dup
existing_list = where(name: unique_name).exists?
unique_name << " #{Time.current.to_fs(:compact)}" if existing_list unique_name
end
|
Instance Method Details
#campaigns ⇒ ActiveRecord::Relation<Campaign>
34
|
# File 'app/models/subscriber_list.rb', line 34
has_and_belongs_to_many :campaigns
|
#customer? ⇒ Boolean
59
60
61
|
# File 'app/models/subscriber_list.rb', line 59
def customer?
list_type == 'customer'
end
|
#email? ⇒ Boolean
55
56
57
|
# File 'app/models/subscriber_list.rb', line 55
def email?
%w[email_static email_dynamic].include?(list_type)
end
|
#email_dynamic? ⇒ Boolean
63
64
65
|
# File 'app/models/subscriber_list.rb', line 63
def email_dynamic?
list_type == 'email_dynamic'
end
|
#generate_subscribers ⇒ Object
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
|
# File 'app/models/subscriber_list.rb', line 167
def generate_subscribers
return true if list_type.in?(%w[email_static customer])
results = perform_search_query
email_addresses = []
if add_all_emails.to_b
customer_ids = results.where.not(state: %w[closed bankrupt]).reorder('').ids
email_addresses = ContactPoint.emails.under_customer_ids(customer_ids).distinct.pluck(:detail)
else
results.each do |search_result|
if (email = search_result.customer_main_email || search_result.customer_first_contact_email)
email_addresses << email
end
end
end
email_addresses.uniq!
timestamp = Time.current
logger.info "[generate_subscribers] Subscriber list generation candidates: #{subscribers.size}"
already_subscribed = subscribers.pluck(:email_address) & email_addresses
logger.info "[generate_subscribers] * already subscribed: #{already_subscribed.size}"
not_on_our_list = subscribers.where.not(email_address: already_subscribed)
logger.info "[generate_subscribers] * Inactivating those not on our candidate list: #{not_on_our_list.size}"
not_on_our_list.update_all(active: false, updated_at: timestamp)
if already_subscribed.present?
on_our_list_inactive = subscribers.where(email_address: already_subscribed).where.not(active: true)
logger.info "[generate_subscribers] * Activating those from our candidate list which were inactive: #{on_our_list_inactive.size}"
on_our_list_inactive.update_all(active: true, updated_at: timestamp)
existing_active_unsubscribed = subscribers.where(active: true).joins(:email_preference).merge(EmailPreference.completely_unsubscribed)
logger.info "[generate_subscribers] * De-activating #{existing_active_unsubscribed.size} subscribers who have completely unsubscribed"
existing_active_unsubscribed.update_all(active: false, updated_at: timestamp)
end
not_subscribed = email_addresses - already_subscribed
completely_unsubscribed_emails = EmailPreference.completely_unsubscribed.where(email: not_subscribed).pluck(:email)
logger.info "Out of #{not_subscribed.size} subscribers to add, removing #{completely_unsubscribed_emails.size} which are completely unsubcribed"
not_subscribed -= completely_unsubscribed_emails
if not_subscribed.present?
logger.info "[generate_subscribers] * Need to now create #{not_subscribed.size} new subscribers"
good_emails = not_subscribed.select { |email| email =~ ContactPoint::EMAIL_REGEXP } new_subscribers = good_emails.map do |email|
{ subscriber_list_id: id,
email_address: email,
active: true }
end
result = Subscriber.insert_all(new_subscribers) if new_subscribers.any?
logger.info "[generate_subscribers] created #{result&.rows&.size || 0} subscribers"
end
logger.info '[generate_subscribers] * All done with generate_subscribers'
true
end
|
#import_subscribers_from_csv ⇒ Object
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
# File 'app/models/subscriber_list.rb', line 67
def import_subscribers_from_csv
return if imported_subscribers_csv.blank?
emails = []
CSV.foreach(imported_subscribers_csv.path) do |row|
emails << row[0] if row[0].present?
end
if add_all_emails == true
emails.each do |email|
parties = Party.joins(:contact_points).merge(ContactPoint.emails.where(detail: email))
parties.each do |p|
if p.is_a?(Contact) && p.customer.present?
emails += p.customer.all_emails
elsif p.is_a?(Customer)
emails += p.all_emails
end
end
end
end
emails.uniq.each do |email|
subscribers << Subscriber.new(email_address: email) unless subscribers.any? { |s| s.email_address == email }
end
end
|
#name_and_type ⇒ Object
Label used by the subscriber-list picker on the campaign form. Includes
the creation date so duplicates with the same name are distinguishable.
Subscriber count is intentionally excluded โ for email_dynamic lists
it would fire perform_search_query_count (a full customer search) per
option on every render of the campaign form.
131
132
133
|
# File 'app/models/subscriber_list.rb', line 131
def name_and_type
"#{name} [#{list_type}] ยท #{created_at.to_date}"
end
|
161
162
163
164
165
|
# File 'app/models/subscriber_list.rb', line 161
def perform_search_query
assert_valid_customer_search_params!
cs = CustomerSearch.create(query_params: customer_search_params)
cs.perform(nil, nil, nil, false, nil, true, true)
end
|
155
156
157
158
159
|
# File 'app/models/subscriber_list.rb', line 155
def perform_search_query_count
assert_valid_customer_search_params!
cs = CustomerSearch.new(query_params: customer_search_params, selected_columns: [:id])
cs.fast_count
end
|
#subscriber_count ⇒ Object
135
136
137
138
139
140
141
|
# File 'app/models/subscriber_list.rb', line 135
def subscriber_count
if email_dynamic? && subscribers.empty?
perform_search_query_count
else
subscribers.active.size
end
end
|
#subscriber_counts_grouped ⇒ Object
143
144
145
146
147
148
149
150
151
152
153
|
# File 'app/models/subscriber_list.rb', line 143
def subscriber_counts_grouped
if email_dynamic? && subscribers.empty?
count = perform_search_query_count
{ 'active' => count }
else
{
'active' => subscribers.active.count,
'inactive' => subscribers.inactive.count
}
end
end
|
#subscribers ⇒ ActiveRecord::Relation<Subscriber>
No dependent: :destroy โ subscribers are disposed individually so the ones
with delivery activity are archived (kept) rather than deleted. dispose runs
before the list row is removed; archived subscribers are detached so the
subscriber_list_id ON DELETE CASCADE FK doesn't reclaim them.
33
|
# File 'app/models/subscriber_list.rb', line 33
has_many :subscribers, inverse_of: :subscriber_list
|