Class: Workarea::Checkout

Inherits:
Object
  • Object
show all
Defined in:
app/models/workarea/checkout.rb,
app/models/workarea/checkout/steps/base.rb,
app/models/workarea/checkout/steps/payment.rb,
app/models/workarea/checkout/fraud/analyzer.rb,
app/models/workarea/checkout/steps/shipping.rb,
app/models/workarea/checkout/collect_payment.rb,
app/models/workarea/checkout/steps/addresses.rb,
app/models/workarea/checkout/fraud/test_analyzer.rb,
app/models/workarea/checkout/fraud/no_decision_analyzer.rb

Defined Under Namespace

Modules: Fraud, Steps Classes: AutoComplete, CollectPayment, CreditCardParams, ShippingOptions

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(order, user = nil) ⇒ Checkout

Returns a new instance of Checkout.



5
6
7
8
# File 'app/models/workarea/checkout.rb', line 5

def initialize(order, user = nil)
  @order = order
  @user = user
end

Instance Attribute Details

#orderObject (readonly)

Returns the value of attribute order.



3
4
5
# File 'app/models/workarea/checkout.rb', line 3

def order
  @order
end

#userObject (readonly)

Returns the value of attribute user.



3
4
5
# File 'app/models/workarea/checkout.rb', line 3

def user
  @user
end

Instance Method Details

#adjust_tender_amounts!Boolean?

Recalculate the amounts on tenders if payment is persisted.

Returns:

  • (Boolean, nil)


227
228
229
230
# File 'app/models/workarea/checkout.rb', line 227

def adjust_tender_amounts!
  return unless payment.persisted?
  payment.adjust_tender_amounts(order.total_price)
end

#complete?Boolean

Whether this checkout needs any further information to place the order. Used to determine whether to redirect the user to the review checkout step.

Returns:

  • (Boolean)


173
174
175
# File 'app/models/workarea/checkout.rb', line 173

def complete?
  order.purchasable? && steps.map { |s| s.new(self) }.all?(&:complete?)
end

#continue_as(user) ⇒ void

This method returns an undefined value.

Transfer order to passed user. Checkout is then autocompleted as far as possible based on the User‘s save data without overriding information already provided in checkout.

Parameters:



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'app/models/workarea/checkout.rb', line 136

def continue_as(user)
  @user = user
  order.user_id = user.id
  payment.profile_id = payment_profile.try(:id)

  steps.each do |step|
    step_instance = step.new(self)

    unless step_instance.complete?
      step_instance.update(auto_complete.params)
    end
  end

  order.touch_checkout!
end

#emailString?

The current email for this checkout. Used to find payment profile.

Returns:



23
24
25
26
27
28
29
# File 'app/models/workarea/checkout.rb', line 23

def email
  if user.present?
    user.email
  elsif order.email.present?
    order.email
  end
end

#inventoryInventory::Transaction

The inventory transaction for this checkout. Uses serialized representation of transaction inventory requirements.



47
48
49
50
51
52
53
54
55
56
# File 'app/models/workarea/checkout.rb', line 47

def inventory
  @inventory ||= Inventory::Transaction.from_order(
    order.id,
    order.items.inject({}) do |memo, item|
      memo[item.sku] ||= 0
      memo[item.sku] += item.quantity
      memo
    end
  )
end

#payable?Boolean

Whether this checkout is valid to collect payment on.

Returns:

  • (Boolean)


219
220
221
# File 'app/models/workarea/checkout.rb', line 219

def payable?
  payment.valid? && payment_collection.valid?
end

#paymentPayment

The payment for this checkout.

Returns:



62
63
64
# File 'app/models/workarea/checkout.rb', line 62

def payment
  @payment ||= Payment.find_or_initialize_by(id: order.id)
end

#payment_collectionObject



74
75
76
# File 'app/models/workarea/checkout.rb', line 74

def payment_collection
  @payment_collection ||= CollectPayment.new(self)
end

#payment_profileObject



66
67
68
69
70
71
72
# File 'app/models/workarea/checkout.rb', line 66

def payment_profile
  return nil if email.blank?

  @payment_profile ||= Payment::Profile.lookup(
    PaymentReference.new(user, order)
  )
end

#place_orderBoolean

This is the authoritative method to place an order. This includes telling payment and inventory to purchase the order, and aborting/rolling back if they fail.

Used in the checkouts controller to place the order.

Returns:

  • (Boolean)

    whether the order was successfully placed



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'app/models/workarea/checkout.rb', line 185

def place_order
  return false unless complete?
  return false unless shippable?
  return false unless payable?

  fraud_analyzer.decide!
  return false if fraud_analyzer.fraud_suspected?

  inventory.purchase
  return false unless inventory.captured?

  unless payment_collection.purchase
    inventory.rollback
    return false
  end

  result = order.place
  place_order_side_effects if result
  result
end

#reset!void

This method returns an undefined value.

Reset this checkout’s personal information. This is called when restarting checkout, such as after cookies expire or starting checkout as a guest.



117
118
119
120
121
122
123
124
125
126
# File 'app/models/workarea/checkout.rb', line 117

def reset!
  @user = nil
  order.reset_checkout!

  Shipping.where(order_id: order.id).destroy_all
  @shippings = nil

  Payment.where(id: order.id).destroy_all
  @payment = nil
end

#shippable?Boolean

Whether this checkout is valid to ship

Returns:

  • (Boolean)


210
211
212
213
# File 'app/models/workarea/checkout.rb', line 210

def shippable?
  !order.requires_shipping? ||
    shippings.all? { |s| ShippingOptions.new(order, s).valid? }
end

#shippingObject



31
32
33
34
# File 'app/models/workarea/checkout.rb', line 31

def shipping
  return nil unless order.requires_shipping?
  shippings.first
end

#shippingsObject



36
37
38
39
40
# File 'app/models/workarea/checkout.rb', line 36

def shippings
  return [] unless order.requires_shipping?
  @shippings ||= Shipping.by_order(order.id).to_a.presence ||
                 [Shipping.new(order_id: order.id)]
end

#start_as(user) ⇒ void

This method returns an undefined value.

Starts checkout and resets the order to be setup for the passed user.

If a User is passed, checkout is autocompleted as far as possible based on that User‘s saved data.

If the symbol ‘:guest`, a blank checkout will be started.

Parameters:



99
100
101
102
103
104
105
106
107
108
109
110
# File 'app/models/workarea/checkout.rb', line 99

def start_as(user)
  reset!

  unless user == :guest
    @user = user
    order.user_id = user.id
    update(auto_complete.params)
  end

  payment.profile_id = payment_profile.try(:id)
  order.touch_checkout!
end

#stepsArray<Class>

Classes used to update the data and check status on the checkout.

Returns:

  • (Array<Class>)


14
15
16
# File 'app/models/workarea/checkout.rb', line 14

def steps
  @steps ||= Workarea.config.checkout_steps.map(&:constantize)
end

#update(params = {}) ⇒ self

Complete checkout update. Updates all steps/data related to the checkout. This includes:

This method does not place the order and makes no guarantees about the updates succeeding.

Used in auto completing an order for a logged in user.

Parameters:

  • parameters (Hash)

    for updating

Returns:

  • (self)


163
164
165
# File 'app/models/workarea/checkout.rb', line 163

def update(params = {})
  steps.each { |s| s.new(self).update(params) }
end

#user_changed?Boolean

Whether the checkout has changed users. Determined by checking the current user for the Workarea::Checkout against the user set on the order

Returns:

  • (Boolean)


84
85
86
# File 'app/models/workarea/checkout.rb', line 84

def user_changed?
  user.present? && user.id.to_s != order.user_id
end