Class: Effective::Order

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(atts = nil, &block) ⇒ Order

Effective::Order.new(items: Product.first) Effective::Order.new(items: [Product.first, Product.second], user: User.first) Effective::Order.new(items: Product.first, user: User.first, billing_address: Effective::Address.new, shipping_address: Effective::Address.new)



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
309
310
311
312
313
314
# File 'app/models/effective/order.rb', line 283

def initialize(atts = nil, &block)
  super(status: :pending) # Initialize with status pending

  return self unless atts.present?

  if atts.kind_of?(Hash)
    items = Array(atts[:item]) + Array(atts[:items])

    self.user = atts[:user] || items.first.try(:user)

    if (address = atts[:billing_address]).present?
      self.billing_address = address
      self.billing_address.full_name ||= user.to_s.presence
    end

    if (address = atts[:shipping_address]).present?
      self.shipping_address = address
      self.shipping_address.full_name ||= user.to_s.presence
    end

    atts.except(:item, :items, :user, :billing_address, :shipping_address).each do |key, value|
      self.send("#{key}=", value)
    end

    add(items) if items.present?
  else # Attributes are not a Hash
    self.user = atts.user if atts.respond_to?(:user)
    add(atts)
  end

  self
end

Instance Attribute Details

#confirmed_checkoutObject

Set on the Checkout Step 1



41
42
43
# File 'app/models/effective/order.rb', line 41

def confirmed_checkout
  @confirmed_checkout
end

#send_mark_as_paid_email_to_buyerObject

Set by Admin::Orders#mark_as_paid



45
46
47
# File 'app/models/effective/order.rb', line 45

def send_mark_as_paid_email_to_buyer
  @send_mark_as_paid_email_to_buyer
end

#send_payment_request_to_buyerObject

Settings in the /admin action forms



44
45
46
# File 'app/models/effective/order.rb', line 44

def send_payment_request_to_buyer
  @send_payment_request_to_buyer
end

#skip_buyer_validationsObject

Set by Admin::Orders#create



46
47
48
# File 'app/models/effective/order.rb', line 46

def skip_buyer_validations
  @skip_buyer_validations
end

#terms_and_conditionsObject

Yes, I agree to the terms and conditions



40
41
42
# File 'app/models/effective/order.rb', line 40

def terms_and_conditions
  @terms_and_conditions
end

Instance Method Details

#add(*items, quantity: 1) ⇒ Object

Items can be an Effective::Cart, an Effective::order, a single acts_as_purchasable, or multiple acts_as_purchasables add(Product.first) => returns an Effective::OrderItem add(Product.first, current_cart) => returns an array of Effective::OrderItems



342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
# File 'app/models/effective/order.rb', line 342

def add(*items, quantity: 1)
  raise 'unable to alter a purchased order' if purchased?
  raise 'unable to alter a declined order' if declined?

  cart_items = items.flatten.flat_map do |item|
    if item.kind_of?(Effective::Cart)
      item.cart_items.to_a
    elsif item.kind_of?(ActsAsPurchasable)
      Effective::CartItem.new(quantity: quantity, purchasable: item)
    elsif item.kind_of?(Effective::Order)
      # Duplicate an existing order
      self.note_to_buyer ||= item.note_to_buyer
      self.note_internal ||= item.note_internal
      self.cc ||= item.cc

      item.order_items.select { |oi| oi.purchasable.kind_of?(Effective::Product) }.map do |oi|
        purchasable = oi.purchasable

        product = Effective::Product.new(name: purchasable.purchasable_name, price: purchasable.price, tax_exempt: purchasable.tax_exempt)

        # Copy over any extended attributes that may have been created
        atts = purchasable.dup.attributes.except('name', 'price', 'tax_exempt', 'purchased_order_id').compact

        atts.each do |k, v|
          next unless product.respond_to?("#{k}=") && product.respond_to?(k)
          product.send("#{k}=", v) if product.send(k).blank?
        end

        Effective::CartItem.new(quantity: oi.quantity, purchasable: product)
      end
    else
      raise 'add() expects one or more acts_as_purchasable objects, or an Effective::Cart'
    end
  end.compact

  # Make sure to reset stored aggregates
  assign_attributes(subtotal: nil, tax_rate: nil, tax: nil, amount_owing: nil, surcharge_percent: nil, surcharge: nil, total: nil)

  retval = cart_items.map do |item|
    order_items.build(
      name: item.name,
      quantity: item.quantity,
      price: item.price,
      tax_exempt: (item.tax_exempt || false),
    ).tap { |order_item| order_item.purchasable = item.purchasable }
  end

  retval.size == 1 ? retval.first : retval
end

#amount_owingObject



500
501
502
# File 'app/models/effective/order.rb', line 500

def amount_owing
  self[:amount_owing] || get_amount_owing()
end

#assign_confirmed_if_valid!Object

This lets us skip to the confirmed workflow for an admin…



661
662
663
664
665
666
667
668
669
670
# File 'app/models/effective/order.rb', line 661

def assign_confirmed_if_valid!
  return unless pending?

  assign_attributes(status: :confirmed)
  return true if valid?

  self.errors.clear
  assign_attributes(status: :pending)
  false
end

#billing_first_nameObject



448
449
450
# File 'app/models/effective/order.rb', line 448

def billing_first_name
  billing_name.to_s.split(' ').first
end

#billing_last_nameObject



452
453
454
# File 'app/models/effective/order.rb', line 452

def billing_last_name
  Array(billing_name.to_s.split(' ')[1..-1]).join(' ')
end

#confirm!Object

Used by admin checkout only



655
656
657
658
# File 'app/models/effective/order.rb', line 655

def confirm!
  return false if purchased?
  confirmed!
end

#custom_order?Boolean

A custom order is one that was created by an admin We allow custom orders to have their order items updated

Returns:

  • (Boolean)


466
467
468
# File 'app/models/effective/order.rb', line 466

def custom_order?
  order_items.all? { |oi| oi.purchasable_type == 'Effective::Product' }
end

#decline!(payment: 'none', provider: 'none', card: 'none', validate: true, email: false) ⇒ Object

We only turn on the email when done by a delayed payment or from a rake script.



818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
# File 'app/models/effective/order.rb', line 818

def decline!(payment: 'none', provider: 'none', card: 'none', validate: true, email: false)
  return false if declined?
  raise('order already purchased') if purchased?

  assign_attributes(
    skip_buyer_validations: true,

    status: :declined,
    purchased_at: nil,
    purchased_by: nil,

    payment: payment_to_h(payment),
    payment_provider: provider,
    payment_card: (card.presence || 'none')
  )

  if current_user&.email.present?
    assign_attributes(email: current_user.email)
  end

  error = nil

  Effective::Order.transaction do
    begin
      run_purchasable_callbacks(:before_decline)
      save!(validate: validate)
      run_purchasable_callbacks(:after_decline)
    rescue ActiveRecord::RecordInvalid => e
      self.status = status_was
      error = e.message
    end
  end

  raise "Failed to decline order: #{error || errors.full_messages.to_sentence}" unless error.nil?

  send_declined_notifications! if email

  true
end

#declined_reasonObject



858
859
860
861
862
# File 'app/models/effective/order.rb', line 858

def declined_reason
  return unless declined?

  delayed_payment_purchase_result.presence || 'credit card declined'
end

#defer!(provider: 'none', email: true, validate: true) ⇒ Object



778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
# File 'app/models/effective/order.rb', line 778

def defer!(provider: 'none', email: true, validate: true)
  raise('order already purchased') if purchased?

  # Assign attributes
  assign_attributes(
    payment_provider: provider,

    status: :deferred,
    purchased_at: nil,
    purchased_by: nil,

    deferred_at: (deferred_at.presence || Time.zone.now),
    deferred_by: (deferred_by.presence || current_user)
  )

  if current_user&.email.present?
    assign_attributes(email: current_user.email)
  end

  error = nil

  begin
    Effective::Order.transaction do
      run_purchasable_callbacks(:before_defer)
      save!(validate: validate)
      run_purchasable_callbacks(:after_defer)
    end
  rescue ActiveRecord::RecordInvalid => e
    self.status = status_was
    error = e.message
  end

  raise "Failed to defer order: #{error || errors.full_messages.to_sentence}" unless error.nil?

  send_payment_request_to_buyer! if email

  true
end

#delay!(payment:, payment_intent:, provider:, card:, email: false, validate: true) ⇒ Object

This was submitted via the deluxe_delayed provider checkout This is a special case of a deferred provider. We require the payment_intent and payment info



762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
# File 'app/models/effective/order.rb', line 762

def delay!(payment:, payment_intent:, provider:, card:, email: false, validate: true)
  raise('expected payment intent to be a String') unless payment_intent.kind_of?(String)
  raise('expected a delayed payment provider') unless EffectiveOrders.delayed_providers.include?(provider)
  raise('expected a delayed payment order with a delayed_payment_date') unless delayed_payment? && delayed_payment_date.present?

  assign_attributes(
    delayed_payment_intent: payment_intent, 
    delayed_payment_total: total(),

    payment: payment_to_h(payment),
    payment_card: (card.presence || 'none')
  )

  defer!(provider: provider, email: email, validate: validate)
end

#delayed?Boolean

A new order is created. If the delayed_payment and delayed_payment date are set, it’s a delayed order A delayed order is one in which we have to capture a payment intent for the amount of the order. Once it’s delayed and deferred we can purchase it at anytime.

Returns:

  • (Boolean)


548
549
550
# File 'app/models/effective/order.rb', line 548

def delayed?
  delayed_payment? && delayed_payment_date.present?
end

#delayed_payment_date_past?Boolean

Returns:

  • (Boolean)


569
570
571
572
# File 'app/models/effective/order.rb', line 569

def delayed_payment_date_past?
  return false unless delayed?
  delayed_payment_date <= Time.zone.now.to_date
end

#delayed_payment_date_today?Boolean

Returns:

  • (Boolean)


580
581
582
583
# File 'app/models/effective/order.rb', line 580

def delayed_payment_date_today?
  return false unless delayed?
  delayed_payment_date == Time.zone.now.to_date
end

#delayed_payment_date_upcoming?Boolean

This is checked by an effective_orders view helper. When upcoming we only collect card info.

Returns:

  • (Boolean)


575
576
577
578
# File 'app/models/effective/order.rb', line 575

def delayed_payment_date_upcoming?
  return false unless delayed?
  delayed_payment_date > Time.zone.now.to_date
end

#delayed_payment_infoObject



562
563
564
565
566
567
# File 'app/models/effective/order.rb', line 562

def delayed_payment_info
  return unless delayed? && deferred?
  return unless delayed_payment_date_upcoming?

  "Your #{delayed_payment_method} will be charged $#{'%0.2f' % total_to_f} on #{delayed_payment_date.strftime('%F')}"
end

#delayed_payment_methodObject



435
436
437
# File 'app/models/effective/order.rb', line 435

def delayed_payment_method
  payment_method_value if delayed?
end

#delayed_ready_to_purchase?Boolean

Returns:

  • (Boolean)


552
553
554
555
556
557
558
559
560
# File 'app/models/effective/order.rb', line 552

def delayed_ready_to_purchase?
  return false unless delayed? 
  return false unless deferred?
  return false unless delayed_payment_intent.present?
  return false if delayed_payment_date_upcoming?
  return false if delayed_payment_purchase_ran_at.present? # We ran before and probably failed

  true
end

#deluxe_delayed_purchase!Object



874
875
876
877
878
879
880
881
# File 'app/models/effective/order.rb', line 874

def deluxe_delayed_purchase!
  raise('expected a delayed order') unless delayed?
  raise('expected a deferred order') unless deferred?
  raise('expected delayed payment intent') unless delayed_payment_intent.present?
  raise('expected a deluxe_delayed payment provider') unless payment_provider == 'deluxe_delayed'

  Effective::DeluxeApi.new().purchase_delayed_orders!(self)
end

#done?Boolean

Returns:

  • (Boolean)


460
461
462
# File 'app/models/effective/order.rb', line 460

def done?
  persisted? && (purchased? || declined? || voided? || abandoned?)
end

#duplicateObject



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

def duplicate
  Effective::Order.new(self)
end

#emailsObject

These are all the emails we send all notifications to



884
885
886
# File 'app/models/effective/order.rb', line 884

def emails
  ([purchased_by.try(:email)] + [email] + [user.try(:email)] + Array(organization.try(:billing_emails))).map(&:presence).compact.uniq
end

#emails_send_toObject

Doesn’t control anything. Purely for the flash messaging



889
890
891
# File 'app/models/effective/order.rb', line 889

def emails_send_to
  (emails + [cc.presence]).compact.uniq.to_sentence
end

#free?Boolean

Returns:

  • (Boolean)


536
537
538
# File 'app/models/effective/order.rb', line 536

def free?
  total == 0
end

#in_progress?Boolean

Returns:

  • (Boolean)


456
457
458
# File 'app/models/effective/order.rb', line 456

def in_progress?
  pending? || confirmed? || deferred?
end

#labelObject



413
414
415
416
417
418
419
420
421
422
423
424
425
# File 'app/models/effective/order.rb', line 413

def label
  if refund? && purchased?
    'Refund'
  elsif purchased?
    'Receipt'
  elsif refund? && (pending? || confirmed?)
    'Pending Refund'
  elsif (pending? || confirmed?)
    'Pending Order'
  else
    'Order'
  end
end

#mark_as_purchased!(current_user: nil) ⇒ Object

Call this as a way to skip over non consequential orders And mark some purchasables purchased This is different than the Mark as Paid payment processor



687
688
689
# File 'app/models/effective/order.rb', line 687

def mark_as_purchased!(current_user: nil)
  purchase!(skip_buyer_validations: true, email: false, skip_quickbooks: true, current_user: current_user)
end

#num_itemsObject



592
593
594
# File 'app/models/effective/order.rb', line 592

def num_items
  present_order_items.map { |oi| oi.quantity }.sum
end

#paymentObject



532
533
534
# File 'app/models/effective/order.rb', line 532

def payment
  Hash(self[:payment])
end

#payment_methodObject



431
432
433
# File 'app/models/effective/order.rb', line 431

def payment_method
  payment_method_value if purchased?
end

#pending!Object

This is called from admin/orders#create This is intended for use as an admin action only It skips any address or bad user validations It’s basically the same as save! on a new order, except it might send the payment request to buyer



640
641
642
643
644
645
646
647
648
649
650
651
652
# File 'app/models/effective/order.rb', line 640

def pending!
  return false if purchased?

  assign_attributes(status: :pending)
  self.addresses.clear if addresses.any? { |address| address.valid? == false }
  save!

  if send_payment_request_to_buyer?
    after_commit { send_payment_request_to_buyer! }
  end

  true
end

#pending_refund?Boolean

Returns:

  • (Boolean)


585
586
587
588
589
590
# File 'app/models/effective/order.rb', line 585

def pending_refund?
  return false if EffectiveOrders.buyer_purchases_refund?
  return false if purchased?

  refund?
end

#purchasablesObject



484
485
486
# File 'app/models/effective/order.rb', line 484

def purchasables
  present_order_items.map { |order_item| order_item.purchasable }.compact
end

#purchase!(payment: nil, provider: nil, card: nil, email: true, skip_buyer_validations: false, skip_quickbooks: false, current_user: nil) ⇒ Object

Effective::Order.new(items: Product.first, user: User.first).purchase!(email: false)



692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
# File 'app/models/effective/order.rb', line 692

def purchase!(payment: nil, provider: nil, card: nil, email: true, skip_buyer_validations: false, skip_quickbooks: false, current_user: nil)
  return true if purchased?

  raise('unable to purchase voided order') if voided?

  # Assign attributes
  assign_attributes(
    skip_buyer_validations: skip_buyer_validations,

    status: :purchased,
    purchased_at: (purchased_at.presence || Time.zone.now),
    purchased_by: (purchased_by.presence || current_user),

    payment: payment_to_h(payment.presence || 'none'),
    payment_provider: (provider.presence || 'none'),
    payment_card: (card.presence || 'none'),

    delayed_payment_intent: nil # Do not store the delayed payment intent any longer
  )

  if current_user&.email.present?
    assign_attributes(email: current_user.email)
  end

  # Updates surcharge and total based on payment_provider
  assign_order_charges()

  begin
    Effective::Order.transaction do
      run_purchasable_callbacks(:before_purchase)

      save!
      update_purchasables_purchased_order!

      run_purchasable_callbacks(:after_purchase)
    end
  rescue ActiveRecord::RecordInvalid => e
    Effective::Order.transaction do
      save!(validate: false)
      update_purchasables_purchased_order!
    end

    raise(e)
  end

  send_order_receipts! if email
  after_commit { sync_quickbooks!(skip: skip_quickbooks) }

  true
end

#purchased?(provider = nil) ⇒ Boolean

Returns:

  • (Boolean)


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

def purchased?(provider = nil)
  return false if (status.to_sym != :purchased)
  return true if provider.nil? || payment_provider == provider.to_s
  false
end

#purchased_with_credit_card?Boolean

Returns:

  • (Boolean)


476
477
478
# File 'app/models/effective/order.rb', line 476

def purchased_with_credit_card?
  purchased? && EffectiveOrders.credit_card_payment_providers.include?(payment_provider)
end

#purchased_without_credit_card?Boolean

Returns:

  • (Boolean)


480
481
482
# File 'app/models/effective/order.rb', line 480

def purchased_without_credit_card?
  purchased? && EffectiveOrders.credit_card_payment_providers.exclude?(payment_provider)
end

#refund?Boolean

Returns:

  • (Boolean)


540
541
542
# File 'app/models/effective/order.rb', line 540

def refund?
  total.to_i < 0
end

#remove(*items) ⇒ Object



316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
# File 'app/models/effective/order.rb', line 316

def remove(*items)
  raise 'unable to alter a purchased order' if purchased?
  raise 'unable to alter a declined order' if declined?

  removed = items.map do |item|
    order_item = if item.kind_of?(Effective::OrderItem)
      order_items.find { |oi| oi == item }
    else
      order_items.find { |oi| oi.purchasable == item }
    end

    raise("Unable to find order item for #{item}") if order_item.blank?
    order_item
  end

  removed.each { |order_item| order_item.mark_for_destruction }

  # Make sure to reset stored aggregates
  assign_attributes(subtotal: nil, tax_rate: nil, tax: nil, amount_owing: nil, surcharge_percent: nil, surcharge: nil, total: nil)

  removed.length == 1 ? removed.first : removed
end

#reportable_scopesObject

effective_reports



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

def reportable_scopes
  { purchased: nil, not_purchased: nil, deferred: nil, refunds: nil, pending_refunds: nil }
end

#send_declined_notifications!Object



899
900
901
902
# File 'app/models/effective/order.rb', line 899

def send_declined_notifications!
  send_order_declined_to_admin! if send_order_declined_to_admin?
  send_order_declined_to_buyer! if send_order_declined_to_buyer?
end

#send_mark_as_paid_email_to_buyer?Boolean

Returns:

  • (Boolean)


628
629
630
# File 'app/models/effective/order.rb', line 628

def send_mark_as_paid_email_to_buyer?
  EffectiveResources.truthy?(send_mark_as_paid_email_to_buyer)
end

#send_order_declined_to_admin!Object



904
905
906
# File 'app/models/effective/order.rb', line 904

def send_order_declined_to_admin!
  EffectiveOrders.send_email(:order_declined_to_admin, self) if declined?
end

#send_order_declined_to_admin?Boolean

Returns:

  • (Boolean)


606
607
608
609
# File 'app/models/effective/order.rb', line 606

def send_order_declined_to_admin?
  return false if free? && !EffectiveOrders.send_order_receipts_when_free
  EffectiveOrders.send_order_declined_to_admin
end

#send_order_declined_to_buyer!Object



908
909
910
# File 'app/models/effective/order.rb', line 908

def send_order_declined_to_buyer!
  EffectiveOrders.send_email(:order_declined_to_buyer, self) if declined?
end

#send_order_declined_to_buyer?Boolean

Returns:

  • (Boolean)


611
612
613
614
# File 'app/models/effective/order.rb', line 611

def send_order_declined_to_buyer?
  return false if free? && !EffectiveOrders.send_order_receipts_when_free
  EffectiveOrders.send_order_declined_to_buyer
end

#send_order_receipt_to_admin!Object



912
913
914
# File 'app/models/effective/order.rb', line 912

def send_order_receipt_to_admin!
  EffectiveOrders.send_email(:order_receipt_to_admin, self) if purchased?
end

#send_order_receipt_to_admin?Boolean

Returns:

  • (Boolean)


596
597
598
599
# File 'app/models/effective/order.rb', line 596

def send_order_receipt_to_admin?
  return false if free? && !EffectiveOrders.send_order_receipts_when_free
  EffectiveOrders.send_order_receipt_to_admin
end

#send_order_receipt_to_buyer!Object Also known as: send_buyer_receipt!



916
917
918
# File 'app/models/effective/order.rb', line 916

def send_order_receipt_to_buyer!
  EffectiveOrders.send_email(:order_receipt_to_buyer, self) if purchased?
end

#send_order_receipt_to_buyer?Boolean

Returns:

  • (Boolean)


601
602
603
604
# File 'app/models/effective/order.rb', line 601

def send_order_receipt_to_buyer?
  return false if free? && !EffectiveOrders.send_order_receipts_when_free
  EffectiveOrders.send_order_receipt_to_buyer
end

#send_order_receipts!Object



893
894
895
896
897
# File 'app/models/effective/order.rb', line 893

def send_order_receipts!
  send_order_receipt_to_admin! if send_order_receipt_to_admin?
  send_order_receipt_to_buyer! if send_order_receipt_to_buyer?
  send_refund_notification! if send_refund_notification_to_admin?
end

#send_payment_request_to_buyer!Object



921
922
923
# File 'app/models/effective/order.rb', line 921

def send_payment_request_to_buyer!
  EffectiveOrders.send_email(:payment_request_to_buyer, self) unless purchased?
end

#send_payment_request_to_buyer?Boolean

Returns:

  • (Boolean)


616
617
618
619
620
621
# File 'app/models/effective/order.rb', line 616

def send_payment_request_to_buyer?
  return false if free? && !EffectiveOrders.send_order_receipts_when_free
  return false if refund?

  EffectiveResources.truthy?(send_payment_request_to_buyer)
end

#send_pending_order_invoice_to_buyer!Object



925
926
927
# File 'app/models/effective/order.rb', line 925

def send_pending_order_invoice_to_buyer!
  EffectiveOrders.send_email(:pending_order_invoice_to_buyer, self) unless purchased?
end

#send_refund_notification!Object



929
930
931
# File 'app/models/effective/order.rb', line 929

def send_refund_notification!
  EffectiveOrders.send_email(:refund_notification_to_admin, self) if refund?
end

#send_refund_notification_to_admin?Boolean

Returns:

  • (Boolean)


623
624
625
626
# File 'app/models/effective/order.rb', line 623

def send_refund_notification_to_admin?
  return false unless refund?
  EffectiveOrders.send_refund_notification_to_admin
end

#skip_buyer_validations?Boolean

Returns:

  • (Boolean)


632
633
634
# File 'app/models/effective/order.rb', line 632

def skip_buyer_validations?
  EffectiveResources.truthy?(skip_buyer_validations)
end

#skip_quickbooks!Object



756
757
758
# File 'app/models/effective/order.rb', line 756

def skip_quickbooks!
  sync_quickbooks!(skip: true)
end

#subtotalObject



488
489
490
# File 'app/models/effective/order.rb', line 488

def subtotal
  self[:subtotal] || get_subtotal()
end

#surchargeObject



508
509
510
# File 'app/models/effective/order.rb', line 508

def surcharge
  self[:surcharge] || get_surcharge()
end

#surcharge_percentObject



504
505
506
# File 'app/models/effective/order.rb', line 504

def surcharge_percent
  self[:surcharge_percent] || get_surcharge_percent()
end

#surcharge_taxObject



512
513
514
# File 'app/models/effective/order.rb', line 512

def surcharge_tax
  self[:surcharge_tax] || get_surcharge_tax()
end

#sync_quickbooks!(skip:) ⇒ Object

We support two different Quickbooks synchronization gems: effective_qb_sync and effective_qb_online



744
745
746
747
748
749
750
751
752
753
754
# File 'app/models/effective/order.rb', line 744

def sync_quickbooks!(skip:)
  if EffectiveOrders.qb_online?
    skip ? EffectiveQbOnline.skip_order!(self) : EffectiveQbOnline.sync_order!(self)
  end

  if EffectiveOrders.qb_sync?
    skip ? EffectiveQbSync.skip_order!(self) : true # Nothing to do
  end

  true
end

#taxObject



496
497
498
# File 'app/models/effective/order.rb', line 496

def tax
  self[:tax] || get_tax()
end

#tax_rateObject



492
493
494
# File 'app/models/effective/order.rb', line 492

def tax_rate
  self[:tax_rate] || get_tax_rate()
end

#to_sObject



409
410
411
# File 'app/models/effective/order.rb', line 409

def to_s
  [label, ' #', to_param].join
end

#totalObject



516
517
518
# File 'app/models/effective/order.rb', line 516

def total
  self[:total] || get_total()
end

#total_labelObject



427
428
429
# File 'app/models/effective/order.rb', line 427

def total_label
  purchased? ? 'Total Paid' : 'Total Due'
end

#total_to_fObject



520
521
522
# File 'app/models/effective/order.rb', line 520

def total_to_f
  ((total || 0) / 100.0).to_f
end

#total_with_surchargeObject



524
525
526
# File 'app/models/effective/order.rb', line 524

def total_with_surcharge
  get_total_with_surcharge()
end

#total_without_surchargeObject



528
529
530
# File 'app/models/effective/order.rb', line 528

def total_without_surcharge
  get_total_without_surcharge()
end

#transaction_idObject

For moneris and moneris_checkout. Just a unique value. Must be 50 characters or fewer or will raise moneris error.



444
445
446
# File 'app/models/effective/order.rb', line 444

def transaction_id
  [to_param, billing_name.to_s.parameterize.first(20).presence, Time.zone.now.to_i, rand(1000..9999)].compact.join('-')
end

#unvoid!Object



869
870
871
872
# File 'app/models/effective/order.rb', line 869

def unvoid!
  raise('order must be voided to unvoid') unless voided?
  unvoided!(skip_buyer_validations: true)
end

#update_prices!Object



392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
# File 'app/models/effective/order.rb', line 392

def update_prices!
  raise('already purchased') if purchased?
  raise('must be pending or confirmed') unless pending? || confirmed?

  present_order_items.each do |item|
    purchasable = item.purchasable

    if purchasable.blank? || purchasable.marked_for_destruction?
      item.mark_for_destruction
    else
      item.assign_purchasable_attributes
    end
  end

  save!
end

#update_purchasable_attributesObject

Called by effective_memberships to update prices from purchasable fees Not called internally



674
675
676
# File 'app/models/effective/order.rb', line 674

def update_purchasable_attributes
  present_order_items.each { |oi| oi.update_purchasable_attributes }
end

#update_purchasable_attributes!Object



678
679
680
681
682
# File 'app/models/effective/order.rb', line 678

def update_purchasable_attributes!
  raise('cannot update purchasable attributes of a purchased order') if purchased?
  update_purchasable_attributes
  save!
end

#void!Object



864
865
866
867
# File 'app/models/effective/order.rb', line 864

def void!
  raise('already voided') if voided?
  voided!(skip_buyer_validations: true)
end