Class: Caboose::Order

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/caboose/order.rb

Constant Summary collapse

STATUS_CART =
'cart'
STATUS_PENDING =
'pending'
STATUS_CANCELED =
'canceled'
STATUS_READY_TO_SHIP =
'ready to ship'
STATUS_SHIPPED =
'shipped'
STATUS_TESTING =
'testing'
FINANCIAL_STATUS_PENDING =
'pending'
FINANCIAL_STATUS_AUTHORIZED =
'authorized'
FINANCIAL_STATUS_CAPTURED =
'captured'
FINANCIAL_STATUS_REFUNDED =
'refunded'
FINANCIAL_STATUS_VOIDED =
'voided'

Instance Method Summary collapse

Instance Method Details

#authorized?Boolean

Returns:

  • (Boolean)


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

def authorized?
  self.financial_status == 'authorized'
end

#calculateObject



132
133
134
135
136
137
138
139
140
141
142
# File 'app/models/caboose/order.rb', line 132

def calculate
  self.update_column(:subtotal  , self.calculate_subtotal  )
  self.update_column(:tax       , self.calculate_tax       )
  self.update_column(:shipping  , self.calculate_shipping  )
  self.update_column(:handling  , self.calculate_handling  )
  self.update_column(:gift_wrap , self.calculate_gift_wrap )
  self.update_column(:discount  , self.calculate_discount  )
  self.update_column(:total     , self.calculate_total     )
  self.update_column(:cost      , self.calculate_cost      )
  self.update_column(:profit    , self.calculate_profit    )
end

#calculate_costObject



191
192
193
194
195
196
197
198
199
200
# File 'app/models/caboose/order.rb', line 191

def calculate_cost      
  x = 0.0
  invalid_cost = false
  self.line_items.each do |li|
    invalid_cost = true if li.variant.nil? || li.variant.cost.nil?
    x = x + (li.variant.cost * li.quantity)
  end
  return 0.00 if invalid_cost
  return x            
end

#calculate_discountObject



178
179
180
181
182
183
184
185
# File 'app/models/caboose/order.rb', line 178

def calculate_discount             
  x = 0.0
  if self.discounts && self.discounts.count > 0
    self.discounts.each{ |d| x = x + d.amount }
  end
  x = x + self.custom_discount if self.custom_discount
  return x
end

#calculate_gift_wrapObject



168
169
170
171
172
173
174
175
176
# File 'app/models/caboose/order.rb', line 168

def calculate_gift_wrap      
  x = 0.0
  self.line_items.each do |li|
    next if !li.gift_wrap
    next if !li.variant.product.allow_gift_wrap
    x = x + li.variant.product.gift_wrap_price * li.quantity
  end
  return x
end

#calculate_handlingObject



163
164
165
166
# File 'app/models/caboose/order.rb', line 163

def calculate_handling
  return 0.0 if self.site.nil? || self.site.store_config.nil?      
  self.subtotal * self.site.store_config.handling_percentage.to_f
end

#calculate_profitObject



202
203
204
205
# File 'app/models/caboose/order.rb', line 202

def calculate_profit
  return 0.00 if self.cost.nil?
  return (self.total - (self.tax ? self.tax : 0.00) - (self.shipping ? self.shipping : 0.00) - (self.handling ? self.handling : 0.00) - (self.gift_wrap ? self.gift_wrap : 0.00)) - self.cost
end

#calculate_shippingObject



156
157
158
159
160
161
# File 'app/models/caboose/order.rb', line 156

def calculate_shipping      
  return 0.0 if self.order_packages.nil? || self.order_packages.count == 0
  x = 0.0
  self.order_packages.all.each{ |op| x = x + op.total }
  return x
end

#calculate_subtotalObject



144
145
146
147
148
149
150
# File 'app/models/caboose/order.rb', line 144

def calculate_subtotal
  return 0.0 if self.line_items.empty?
  self.line_items.each{ |li| li.verify_unit_price } # Make sure the unit prices are populated        
  x = 0.0      
  self.line_items.each{ |li| x = x + (li.unit_price * li.quantity) } # Fixed issue with quantity 
  return x
end

#calculate_taxObject



152
153
154
# File 'app/models/caboose/order.rb', line 152

def calculate_tax      
  return TaxCalculator.tax(self)
end

#calculate_totalObject



187
188
189
# File 'app/models/caboose/order.rb', line 187

def calculate_total
  return (self.subtotal + self.tax + self.shipping + self.handling + self.gift_wrap) - self.discount
end

#captureObject



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

def capture
  PaymentProcessor.capture(self)
end

#capture_fundsObject

Capture funds from a previously authorized transaction



257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
# File 'app/models/caboose/order.rb', line 257

def capture_funds
  
  resp = StdClass.new      
  t = OrderTransaction.where(:order_id => self.id, :transaction_type => OrderTransaction::TYPE_AUTHORIZE, :success => true).first
        
  if self.financial_status == Order::FINANCIAL_STATUS_CAPTURED
    resp.error = "Funds for this order have already been captured."    
  elsif self.total > t.amount
    resp.error = "The order total exceeds the authorized amount."
  elsif t.nil?
    resp.error = "This order doesn't seem to be authorized."
  else
                    
    sc = self.site.store_config
    ot = Caboose::OrderTransaction.new(
      :order_id => self.id,
      :date_processed => DateTime.now.utc,
      :transaction_type => OrderTransaction::TYPE_CAPTURE,
      :amount => self.total
    )
    
    case sc.pp_name
      when 'authorize.net'
        transaction = AuthorizeNet::AIM::Transaction.new(sc.pp_username, sc.pp_password)
        response = transaction.prior_auth_capture(t.transaction_id, self.total)
        
        ot.success        = response.response_code && response.response_code == '1'            
        ot.transaction_id = response.transaction_id
        ot.auth_code      = response.authorization_code
        ot.response_code  = response.response_code            
        ot.save
        
        if ot.success
          self.date_captured = DateTime.now.utc
          self.save              
        end
                                
        self.update_attribute(:financial_status, Order::FINANCIAL_STATUS_CAPTURED)
        resp.success = 'Captured funds successfully'
                                
      when 'stripe'
        # TODO: Implement capture funds for stripe
        
      when 'payscape'
        # TODO: Implement capture funds for payscape

    end
    
  end
  
  return resp
end

#check_nil_fieldsObject



86
87
88
89
90
91
92
93
94
# File 'app/models/caboose/order.rb', line 86

def check_nil_fields
  self.subtotal        = 0.00 if self.subtotal.nil?       
  self.tax             = 0.00 if self.tax.nil?
  self.shipping        = 0.00 if self.shipping.nil?
  self.handling        = 0.00 if self.handling.nil?
  self.custom_discount = 0.00 if self.custom_discount.nil?
  self.discount        = 0.00 if self.discount.nil?
  self.total           = 0.00 if self.total.nil?
end

#decrement_quantitiesObject



96
97
98
99
100
# File 'app/models/caboose/order.rb', line 96

def decrement_quantities            
  self.line_items.each do |line_item|
    line_item.variant.update_attribute(:quantity_in_stock, line_item.variant.quantity_in_stock - line_item.quantity)
  end            
end

#determine_statusesObject



443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
# File 'app/models/caboose/order.rb', line 443

def determine_statuses
  
  auth    = false
  capture = false
  void    = false
  refund  = false
  
  self.order_transactions.each do |ot|
    auth    = true if ot.transaction_type == OrderTransaction::TYPE_AUTHORIZE && ot.success == true
    capture = true if ot.transaction_type == OrderTransaction::TYPE_CAPTURE   && ot.success == true
    void    = true if ot.transaction_type == OrderTransaction::TYPE_VOID      && ot.success == true
    refund  = true if ot.transaction_type == OrderTransaction::TYPE_REFUND    && ot.success == true
  end
  
  if    refund  then self.financial_status = Order::FINANCIAL_STATUS_REFUNDED
  elsif void    then self.financial_status = Order::FINANCIAL_STATUS_VOIDED
  elsif capture then self.financial_status = Order::FINANCIAL_STATUS_CAPTURED
  elsif auth    then self.financial_status = Order::FINANCIAL_STATUS_AUTHORIZED
  else               self.financial_status = Order::FINANCIAL_STATUS_PENDING
  end

  self.status = Order::STATUS_PENDING if self.status == Order::STATUS_CART && (refund || void || capture || auth) 
  
  self.save

end

#has_downloadable_items?Boolean

Returns:

  • (Boolean)


235
236
237
238
239
240
# File 'app/models/caboose/order.rb', line 235

def has_downloadable_items?
  self.line_items.each do |li|
    return true if li.variant.downloadable
  end
  return false
end

#has_empty_shipping_methods?Boolean

Returns:

  • (Boolean)


226
227
228
229
230
231
232
233
# File 'app/models/caboose/order.rb', line 226

def has_empty_shipping_methods?
  return true if self.order_packages.nil?
  return true if self.order_packages.count == 0
  self.order_packages.all.each do |op|
    return true if op.shipping_method_id.nil?
  end
  return false
end

#has_shippable_items?Boolean

Returns:

  • (Boolean)


242
243
244
245
246
247
# File 'app/models/caboose/order.rb', line 242

def has_shippable_items?
  self.line_items.each do |li|
    return true if !li.variant.downloadable
  end
  return false
end

#has_taxable_items?Boolean

Returns:

  • (Boolean)


249
250
251
252
253
254
# File 'app/models/caboose/order.rb', line 249

def has_taxable_items?
  self.line_items.each do |li|
    return true if li.variant.taxable && li.variant.taxable == true
  end
  return false
end

#hide_prices_for_any_line_item?Boolean

Returns:

  • (Boolean)


470
471
472
473
474
475
# File 'app/models/caboose/order.rb', line 470

def hide_prices_for_any_line_item?
  self.line_items.each do |li|
    return true if li.hide_prices
  end
  return false
end

#increment_quantitiesObject



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

def increment_quantities            
  self.line_items.each do |line_item|
    line_item.variant.update_attribute(:quantity_in_stock, line_item.variant.quantity_in_stock - line_item.quantity)
  end            
end

#item_countObject



211
212
213
214
215
# File 'app/models/caboose/order.rb', line 211

def item_count
  count = 0
  self.line_items.each{ |li| count = count + li.quantity } if self.line_items
  return count
end

#refundObject



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

def refund
  PaymentProcessor.refund(self)
end

#resend_confirmationObject



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

def resend_confirmation
  OrdersMailer.configure_for_site(self.site_id).customer_new_order(self).deliver
end

#send_payment_authorization_emailObject

def refund

resp = StdClass.new
t = OrderTransaction.where(:order_id => self.id, :transaction_type => OrderTransaction::TYPE_CAPTURE, :success => true).first

if self.financial_status != Order::FINANCIAL_STATUS_CAPTURED
  resp.error = "This order hasn't been captured yet, you will need to void instead"
else

  sc = self.site.store_config
  case sc.pp_name
    when 'authorize.net'

  if PaymentProcessor.refund(order)
    order.update_attributes(
      :financial_status => Order::FINANCIAL_STATUS_REFUNDED,
      :status => Order::STATUS_CANCELED
    )

    response.success = 'Order refunded successfully'
  else
    response.error = 'Error refunding order'
  end

  #if order.calculate_net < (order.amount_discounted || 0) || PaymentProcessor.refund(order)
  #  order.financial_status = 'refunded'
  #  order.status = 'refunded'
  #  order.save
  #  
  #  if order.discounts.any?
  #    discount = order.discounts.first
  #    amount_to_refund = order.calculate_net < order.amount_discounted ? order.calculate_net : order.amount_discounted
  #    discount.update_attribute(:amount_current, amount_to_refund + discount.amount_current)
  #  end
  #  
  #  response.success = "Order refunded successfully"
  #else
  #  response.error = "Error refunding order."
  #end
end

render json: response

# return if !user_is_allowed('orders', 'edit')
#     
# response = Caboose::StdClass.new({
#   'refresh' => nil,
#   'error' => nil,
#   'success' => nil
# })
#     
# order = Order.find(params[:id])
#     
# if order.financial_status != 'captured'
#   response.error = "This order hasn't been captured yet, you will need to void instead"
# else
#   if PaymentProcessor.refund(order)
#     order.financial_status = 'refunded'
#     order.status = 'refunded'
#     order.save
#     
#     # Add the variant quantities ordered back
#     order.cancel
#     
#     response.success = "Order refunded successfully"
#   else
#     response.error = "Error refunding order."
#   end
# end
#     
# render :json => response

end



439
440
441
# File 'app/models/caboose/order.rb', line 439

def send_payment_authorization_email
  OrdersMailer.configure_for_site(self.site_id).customer_payment_authorization(self).deliver
end

#shipping_and_handlingObject



207
208
209
# File 'app/models/caboose/order.rb', line 207

def shipping_and_handling
  (self.shipping ? self.shipping : 0.0) + (self.handling ? self.handling : 0.0)      
end

#take_gift_card_fundsObject



217
218
219
220
221
222
223
224
# File 'app/models/caboose/order.rb', line 217

def take_gift_card_funds
  return if self.discounts.nil? || self.discounts.count == 0
  self.discounts.each do |d|        
    gc = d.gift_card
    gc.balance = gc.balance - d.amount
    gc.save
  end
end

#test?Boolean

Returns:

  • (Boolean)


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

def test?
  self.status == 'testing'
end

#voidObject

Void an authorized order



311
312
313
# File 'app/models/caboose/order.rb', line 311

def void
  PaymentProcessor.void(self)
end