Class: Registration

Inherits:
ActiveRecord::Base
  • Object
show all
Includes:
ActiveMerchant::Billing::Integrations, DmCore::Concerns::HasCustomFields, DmEvent::Concerns::RegistrationStateEmail, DmEvent::Concerns::RegistrationStateMachine
Defined in:
app/models/registration.rb

Overview

Important: one reason to link off of the user_profile instead of the user is so that we can support registrations without requiring an account. We can create a “userless” profile, that has all the necessary information. This is instead of duplicating all those fields in the registration table.


Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#payment_comment_textObject

Returns the value of attribute payment_comment_text.



22
23
24
# File 'app/models/registration.rb', line 22

def payment_comment_text
  @payment_comment_text
end

Class Method Details

.csv_columns(workshop) ⇒ Object

Setup the columns for exporting data as csv.




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
# File 'app/models/registration.rb', line 191

def self.csv_columns(workshop)
  column_definitions = []
  column_definitions <<     ["Receipt Code",      "'R-' + item.receipt_code", 75] # 'R-' makes sure Numbers treats as a String, not a Date
  column_definitions <<     ['Process State',     'item.aasm_state', 100]
  column_definitions <<     ["Full Name",         "item.full_name", 100]
  column_definitions <<     ["Last Name",         "item.last_name.capitalize", 100]
  column_definitions <<     ["First Name",        "item.first_name.capitalize", 100]
  column_definitions <<     ["Email",             "item.email.downcase", 150]
  column_definitions <<     ["Address",           "item.address", 150]
  column_definitions <<     ["Address2",          "item.address2"]
  column_definitions <<     ["City",              "item.city.capitalize", 100]
  column_definitions <<     ["State",             "item.state.capitalize"]
  column_definitions <<     ["Zipcode",           "item.zipcode"]
  column_definitions <<     ["Country",           "item.country.code"]

  column_definitions <<     ['Registered on',     'item.created_at.to_date', 75, {type: 'DateTime', numberformat: 'd mmm, yyyy'}]

  column_definitions <<     ["Price",             "item.workshop_price.price.to_f", nil, {type: 'Number', numberformat: '#,##0.00'}]
  column_definitions <<     ["Price Description", "item.workshop_price.price_description"]
  column_definitions <<     ["Price Sub Descr",   "item.workshop_price.sub_description"]
  column_definitions <<     ["Discount",          "item.discount.to_f", nil, {type: 'Number', numberformat: '#,##0.00'}]
  column_definitions <<     ["Paid",              "item.amount_paid.to_f", nil, {type: 'Number', numberformat: '#,##0.00'}]
  column_definitions <<     ["Balance",           "item.balance_owed.to_f", nil, {type: 'Number', numberformat: '#,##0.00'}]

  # ---- add the extra fields defined in the workshop record
  workshop.custom_field_defs.each_with_index do | x, index |
    case x.field_type
    when 'check_box_collection'
      column_definitions << [ "#{x.column_name}", "(z = item.custom_fields.detect { |y| y.custom_field_def_id == #{x.id} }) ? z.value : ''", nil, {type: 'list', custom_field: true}]
    when 'divider'
    else
      column_definitions << [ "#{x.column_name}", "(z = item.custom_fields.detect { |y| y.custom_field_def_id == #{x.id} }) ? z.value : ''", nil, {custom_field: true}]
    end
  end
  return column_definitions
end

.number_of(state, options = {}) ⇒ Object

Return the number of items specified, in particular the number of items in a particular state




127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'app/models/registration.rb', line 127

def self.number_of(state, options = {})
  query = (options[:only_confirmed] ? where.not(confirmed_on: nil) : all)
  case state
  when :attending
    attending.count
  when :unpaid
    #--- the number of unpaid is the same as the number of accepted
    number_of(:accepted)
  when :checkedin
    query.where.not(checkin_at: 0).where(archived_on: nil).count
  when :archived
    query.where.not(archived_on: nil).count
  when :registrations
    #--- don't count any canceled
    query.where(archived_on: nil).where.not(aasm_state: 'canceled').where.not(aasm_state: 'refunded').count
  when :at_price
    #--- number of registrations for a particular price
    query.where(archived_on: nil).where("(aasm_state = 'paid' OR aasm_state = 'accepted')").where(workshop_price_id: options[:price_id]).count
  when :for_all_prices
    #--- array of counts per price
    query.where(archived_on: nil).where("(aasm_state = 'paid' OR aasm_state = 'accepted')").group(:workshop_price_id).count
  when :discounted
    attending.discounted.count
  when :discounted_total
    total = attending.discounted.to_a.sum(&:discount)
    (total == 0) ? Money.new(0) : total
  when :user_updated
    #--- how many users updated their record
    query.where(archived_on: nil).where("(aasm_state = 'paid' OR aasm_state = 'accepted')").where.not(user_updated_at: nil).count
  when :confirmed
    #--- how many users confirmed their attendance
    where.not(confirmed_on: nil).where(archived_on: nil).where("(aasm_state = 'paid' OR aasm_state = 'accepted')").count
  else
    #--- must be wanting to count the process states
    query.where(archived_on: nil, aasm_state: state).count
  end
end

.receiptcode_to_id(receiptcode) ⇒ Object

receipt code is simply the record id + 1100




76
77
78
# File 'app/models/registration.rb', line 76

def self.receiptcode_to_id(receiptcode)
  return receipt_code.split('-')[1].to_i
end

Instance Method Details

#balance_owedObject

Return the amount still owed, based on the current payments made. balance_owed is positive if payment is still required. Negative if there has been an overpayment




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

def balance_owed
  discounted_price - amount_paid
end

#delete_payment(payment_id) ⇒ Object

delete a payment and update the registrations total amount paid




279
280
281
282
283
284
285
286
287
288
289
# File 'app/models/registration.rb', line 279

def delete_payment(payment_id)
  payment = PaymentHistory.find(payment_id)
  if payment
    self.update_attribute(:amount_paid_cents, (self.amount_paid - self.workshop_price.to_base_currency(payment.total)).cents)
    payment.destroy
    suppress_transition_email
    self.send('accept!') if balance_owed.positive? && self.paid?
    return true
  end
  return false
end

#discountObject




93
94
95
96
97
98
99
100
101
102
# File 'app/models/registration.rb', line 93

def discount
  return Money.new(0, workshop.base_currency) if workshop_price.nil? || workshop_price.price.nil?

  unless discount_value.blank?
    cents = (discount_use_percent ? (workshop_price.price.cents * discount_value / 100) : (discount_value * 100))
  else
    cents = 0
  end
  Money.new(cents, workshop_price.price.currency)
end

#discounted_priceObject

Price with discount




88
89
90
# File 'app/models/registration.rb', line 88

def discounted_price
  price - discount
end

#manual_payment(payment_history, cost, total_currency, user_profile, options = { item_ref: '', payment_method: 'cash', bill_to_name: '', payment_date: Time.now, notify_data: nil, transaction_id: nil, status: '' }) ⇒ Object

Payment was entered manually, create the history record. You can tell it’s a manual entry if the user_profile is filled in - means a human did it.




231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# File 'app/models/registration.rb', line 231

def manual_payment(payment_history, cost, total_currency, ,
                   options = { item_ref: '', payment_method: 'cash', bill_to_name: '', payment_date: Time.now,
                               notify_data: nil, transaction_id: nil, status: '' } )
  amount            = Monetize.parse(cost, total_currency)
  
  if payment_history
    new_amount_paid = self.amount_paid - self.workshop_price.to_base_currency(payment_history.total) + self.workshop_price.to_base_currency(amount)
    payment_history.update_attributes(
      item_ref: options[:item_ref],
      cost: cost,
      total_cents: amount.cents,
      total_currency: amount.currency.iso_code,
      payment_method: options[:payment_method],
      bill_to_name: options[:bill_to_name],
      payment_date: options[:payment_date],
      user_profile_id: .id)
  else
    new_amount_paid = self.amount_paid + self.workshop_price.to_base_currency(amount)
    payment_history   = self.payment_histories.create(
        anchor_id: receipt_code,
        item_ref: options[:item_ref],
        cost: cost,
        quantity: 1,
        discount: 0,
        total_cents: amount.cents,
        total_currency: amount.currency.iso_code,
        payment_method: options[:payment_method],
        bill_to_name: options[:bill_to_name],
        payment_date: options[:payment_date],
        user_profile_id: ( ? .id : nil),
        notify_data: options[:notify_data],
        transaction_id: options[:transaction_id],
        status: ( ? "Completed" : options[:status])
    )
  end
      
  if payment_history.errors.empty?
    self.update_attribute(:amount_paid_cents, new_amount_paid.cents)
    self.reload
    self.send('paid!') if balance_owed.cents <= 0 && self.accepted?
  else
    logger.error("===> Error: Registration.manual_payment: #{payment_history.errors.inspect}")
  end
  return payment_history
end

#payment_owedObject

suggested amount of next payment. if a payment is within 20 of the balance_owed, then they should pay the balance




115
116
117
118
119
120
121
122
# File 'app/models/registration.rb', line 115

def payment_owed
  if workshop_price
    amount_20 = Money.new(2000, workshop_price.price.currency)
    (workshop_price.payment_price + amount_20) > balance_owed ? balance_owed : workshop_price.payment_price 
  else
    balance_owed
  end
end

#payment_reminder_due?Boolean

Is it time to send a payment reminder? Due first 7 days after inital registration. Then every 14 days after that


Returns:

  • (Boolean)


174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'app/models/registration.rb', line 174

def payment_reminder_due?
  if preferred_payment_reminder_hold_until.nil? || preferred_payment_reminder_hold_until < Time.now
    time_period = self.payment_reminder_sent_on.nil? ? (self.created_at + 7.days) : (self.payment_reminder_sent_on + 14.days)
    self.balance_owed > Money.new(0, workshop.base_currency) && time_period < Time.now
  end

  # if recurring_period since last paymnet
  # if 7 days after registration and no payment
  # if 14 days since last reminder and no payment
  # if resume_reminders is past
  # last_payment = payment_histories.order('created_on').last
  # if workshop_price.recurring?
  #   if 
end

#payment_urlObject

Return the payment page url, so that it can be used in emails




293
294
295
# File 'app/models/registration.rb', line 293

def payment_url
  DmEvent::Engine.routes.url_helpers.register_choose_payment_url(self.uuid, host: Account.current.url_host, locale: I18n.locale)
end

#priceObject

Price of this registration (without discount)




82
83
84
# File 'app/models/registration.rb', line 82

def price
  (workshop_price && workshop_price.price) ? workshop_price.price : Money.new(0, workshop.base_currency)
end

#unpaid?Boolean

check if the regsitration is unpaid


Returns:

  • (Boolean)


167
168
169
# File 'app/models/registration.rb', line 167

def unpaid?
  self.accepted? && self.archived_on == nil
end