jam-cloud/ruby/lib/jam_ruby/models/email_batch.rb

151 lines
4.1 KiB
Ruby

module JamRuby
class EmailBatch < ActiveRecord::Base
self.table_name = "email_batches"
attr_accessible :from_email, :subject, :test_emails, :body
attr_accessible :lock_version, :qualified_count, :sent_count, :started_at, :completed_at
VAR_FIRST_NAME = '@FIRSTNAME'
VAR_LAST_NAME = '@LASTNAME'
DEFAULT_SENDER = "support@jamkazam.com"
include AASM
aasm do
state :pending, :initial => true
state :testing
state :tested
state :batching
state :batched
state :disabled
event :enable do
transitions :from => :disabled, :to => :pending
end
event :reset do
transitions :from => [:disabled, :testing, :tested, :batching, :batched, :pending], :to => :pending
end
event :do_test_run, :before => :running_tests do
transitions :from => [:pending, :tested, :batched], :to => :testing
end
event :did_test_run, :after => :ran_tests do
transitions :from => :testing, :to => :tested
end
event :do_batch_run, :before => :running_batch do
transitions :from => [:tested, :pending, :batched], :to => :batching
end
event :did_batch_run, :after => :ran_batch do
transitions :from => :batching, :to => :batched
end
event :disable do
transitions :from => [:pending, :tested, :batched], :to => :disabled
end
end
# has_many :email_batch_results, :class_name => 'JamRuby::EmailBatchResult'
def self.create_with_params(params)
obj = self.new
obj.update_with_params(params)
obj.save!
obj
end
def update_with_params(params)
self.from_email = params[:from_email].strip
self.subject = params[:subject].strip
self.test_emails = params[:test_emails].strip
self.body = params[:body].strip
self
end
def deliver_batch
self.perform_event('do_batch_run!')
User.email_opt_in.pluck(:id).find_in_batches(batch_size: 1000) do |user_ids|
BatchMailer.send_batch_email(self.id, user_ids).deliver
end
end
def test_count
self.test_emails.split(',').count
end
def test_users
self.test_emails.split(',').collect do |ee|
ee.strip!
uu = User.new
uu.email = ee
uu.first_name = ee.match(/^(.*)@/)[1].to_s
uu.last_name = 'Test'
uu
end
end
def send_test_batch
self.perform_event('do_test_run!')
BatchMailer.send_batch_email_test(self.id).deliver
end
def merged_body(user)
body.gsub(VAR_FIRST_NAME, user.first_name).gsub(VAR_LAST_NAME, user.last_name)
end
def did_send(emails)
self.update_with_conflict_validation({ :sent_count => self.sent_count + emails.size })
if self.sent_count >= self.qualified_count
if batching?
self.perform_event('did_batch_run!')
elsif testing?
self.perform_event('did_test_run!')
end
end
end
def perform_event(event_name)
num_try = 0
self.send(event_name)
rescue ActiveRecord::StaleObjectError
num_try += 1
if 5 > num_try
self.reload
retry
end
end
def update_with_conflict_validation(*args)
num_try = 0
update_attributes(*args)
rescue ActiveRecord::StaleObjectError
num_try += 1
if 5 > num_try
self.reload
retry
end
end
def running_batch
self.update_with_conflict_validation({:qualified_count => User.email_opt_in.count,
:sent_count => 0,
:started_at => Time.now
})
end
def running_tests
self.update_with_conflict_validation({:qualified_count => self.test_count,
:sent_count => 0,
:started_at => Time.now
})
end
def ran_tests
self.update_with_conflict_validation({ :completed_at => Time.now })
end
def ran_batch
self.update_with_conflict_validation({ :completed_at => Time.now })
end
end
end