Class: Spree::Order
- Inherits:
-
Object
show all
- Extended by:
- DisplayMoney
- Includes:
- MemoizedData, Metadata, Metafields, NumberIdentifier, AddressBook, Checkout, CurrencyUpdater, Digital, GiftCard, Payments, StoreCredit, Webhooks, Searchable, Security::Orders, SingleStoreResource, VendorConcern
- Defined in:
- app/models/spree/order.rb,
app/models/spree/order/digital.rb,
app/models/spree/order/checkout.rb,
app/models/spree/order/payments.rb,
app/models/spree/order/webhooks.rb,
app/models/spree/order/gift_card.rb,
app/models/spree/order/address_book.rb,
app/models/spree/order/store_credit.rb,
app/models/spree/order/currency_updater.rb
Defined Under Namespace
Modules: AddressBook, Checkout, CurrencyUpdater, Digital, GiftCard, Payments, StoreCredit, Webhooks
Constant Summary
collapse
- PAYMENT_STATES =
%w(balance_due credit_owed failed paid void)
- SHIPMENT_STATES =
%w(backorder canceled partial pending ready shipped)
- LINE_ITEM_REMOVABLE_STATES =
%w(cart address delivery payment confirm resumed)
- MEMOIZED_METHODS =
%w(tax_zone)
- MONEY_THRESHOLD =
100_000_000
- MONEY_VALIDATION =
{
presence: true,
numericality: {
greater_than: -MONEY_THRESHOLD,
less_than: MONEY_THRESHOLD,
allow_blank: true
},
format: { with: /\A-?\d+(?:\.\d{1,2})?\z/, allow_blank: true }
}.freeze
- POSITIVE_MONEY_VALIDATION =
MONEY_VALIDATION.deep_dup.tap do |validation|
validation.fetch(:numericality)[:greater_than_or_equal_to] = 0
end.freeze
- NEGATIVE_MONEY_VALIDATION =
MONEY_VALIDATION.deep_dup.tap do |validation|
validation.fetch(:numericality)[:less_than_or_equal_to] = 0
end.freeze
- ASSOCIATED_USER_ATTRIBUTES =
[:user_id, :email, :bill_address_id, :ship_address_id]
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
money_methods
Methods included from Metadata
#metadata, #metadata=, #public_metadata=
Methods included from GiftCard
#apply_gift_card, #gift_card_total, #recalculate_gift_card, #redeem_gift_card, #remove_gift_card
Methods included from Webhooks
#send_order_canceled_webhook, #send_order_placed_webhook, #send_order_resumed_webhook
#bill_address_attributes=, #bill_address_id=, #clone_billing_address, #clone_shipping_address, #ship_address_attributes=, #ship_address_id=
#add_store_credit_payments, #available_store_credits, #could_use_store_credit?, #covered_by_store_credit?, #display_order_total_after_store_credit, #display_store_credit_remaining_after_capture, #display_total_applicable_store_credit, #display_total_applied_store_credit, #display_total_available_store_credit, #display_total_minus_store_credits, #order_total_after_store_credit, #remove_store_credit_payments, #total_applicable_store_credit, #total_applied_store_credit, #total_available_store_credit, #total_minus_store_credits, #using_store_credit?
Methods included from Digital
#create_digital_links, #digital?, #digital_line_items, #digital_links, #some_digital?, #with_digital_assets?
#price_from_line_item, #update_line_item_currencies!, #update_line_item_price!
Methods included from Checkout
included
Instance Attribute Details
#coupon_code ⇒ Object
Returns the value of attribute coupon_code.
114
115
116
|
# File 'app/models/spree/order.rb', line 114
def coupon_code
@coupon_code
end
|
#skip_market_resolution ⇒ Object
Returns the value of attribute skip_market_resolution.
203
204
205
|
# File 'app/models/spree/order.rb', line 203
def skip_market_resolution
@skip_market_resolution
end
|
#temporary_address ⇒ Object
Returns the value of attribute temporary_address.
115
116
117
|
# File 'app/models/spree/order.rb', line 115
def temporary_address
@temporary_address
end
|
#use_billing ⇒ Object
Returns the value of attribute use_billing.
203
204
205
|
# File 'app/models/spree/order.rb', line 203
def use_billing
@use_billing
end
|
#use_shipping ⇒ Object
Returns the value of attribute use_shipping.
203
204
205
|
# File 'app/models/spree/order.rb', line 203
def use_shipping
@use_shipping
end
|
Class Method Details
.find_by_param(param) ⇒ Spree::Order?
Find an order by prefixed ID first, falling back to number, then integer id for backwards compatibility
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
|
# File 'app/models/spree/order.rb', line 288
def self.find_by_param(param)
return nil if param.blank?
if param.to_s.include?('_')
decoded = decode_prefixed_id(param)
order = find_by(id: decoded) if decoded
return order if order
end
order = find_by(number: param)
return order if order
find_by(id: param) if param.to_s.match?(/\A\d+\z/)
end
|
.find_by_param!(param) ⇒ Spree::Order
Find an order by prefixed ID first, falling back to number, then integer id for backwards compatibility Raises ActiveRecord::RecordNotFound if not found
311
312
313
|
# File 'app/models/spree/order.rb', line 311
def self.find_by_param!(param)
find_by_param(param) || raise(ActiveRecord::RecordNotFound.new("Couldn't find Order with param=#{param}"))
end
|
.multi_search(query) ⇒ Object
Backward compatibility alias — remove in Spree 6.0
283
|
# File 'app/models/spree/order.rb', line 283
def self.multi_search(query) = search(query)
|
.register_update_hook(hook) ⇒ Object
Use this method in other gems that wish to register their own custom logic that should be called after Order#update
317
318
319
|
# File 'app/models/spree/order.rb', line 317
def self.register_update_hook(hook)
update_hooks.add(hook)
end
|
.search(query) ⇒ Object
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
|
# File 'app/models/spree/order.rb', line 260
def self.search(query)
sanitized_query = sanitize_query_for_search(query)
return none if query.blank?
query_pattern = "%#{sanitized_query}%"
conditions = []
conditions << arel_table[:number].lower.matches(query_pattern)
conditions << search_condition(Spree::Address, :firstname, sanitized_query)
conditions << search_condition(Spree::Address, :lastname, sanitized_query)
full_name = NameOfPerson::PersonName.full(sanitized_query)
if full_name.first.present? && full_name.last.present?
conditions << search_condition(Spree::Address, :firstname, full_name.first)
conditions << search_condition(Spree::Address, :lastname, full_name.last)
end
left_joins(:bill_address).where(arel_table[:email].lower.eq(query.downcase)).or(where(conditions.reduce(:or)))
end
|
Instance Method Details
#all_inventory_units_returned? ⇒ Boolean
468
469
470
|
# File 'app/models/spree/order.rb', line 468
def all_inventory_units_returned?
inventory_units.all?(&:returned?)
end
|
#all_line_items ⇒ Object
958
959
960
|
# File 'app/models/spree/order.rb', line 958
def all_line_items
line_items
end
|
#all_line_items_invalid? ⇒ Boolean
Checks if all line items cannot be shipped
745
746
747
|
# File 'app/models/spree/order.rb', line 745
def all_line_items_invalid?
line_items_without_shipping_rates.size == line_items.count
end
|
#allow_cancel? ⇒ Boolean
462
463
464
465
466
|
# File 'app/models/spree/order.rb', line 462
def allow_cancel?
return false if !completed? || canceled?
shipment_state.nil? || %w{ready backorder pending canceled}.include?(shipment_state)
end
|
#amount ⇒ Object
For compatibility with Calculator::PriceSack
322
323
324
|
# File 'app/models/spree/order.rb', line 322
def amount
line_items.inject(0.0) { |sum, li| sum + li.amount }
end
|
#amount_due ⇒ Object
56
57
58
|
# File 'app/models/spree/order.rb', line 56
def amount_due
[outstanding_balance - total_applied_store_credit, 0].max
end
|
#analytics_subtotal ⇒ Float
Returns the subtotal used for analytics integrations It’s a sum of the item total and the promo total
339
340
341
|
# File 'app/models/spree/order.rb', line 339
def analytics_subtotal
(item_total + line_items.sum(:promo_total)).to_f
end
|
Applies user promotions when login after filling the cart
869
870
871
|
# File 'app/models/spree/order.rb', line 869
def approve!
Spree.order_approve_service.call(order: self)
end
|
837
838
839
|
# File 'app/models/spree/order.rb', line 837
def approved?
!!approved_at
end
|
833
834
835
|
# File 'app/models/spree/order.rb', line 833
def approved_by(user = nil)
Spree.order_approve_service.call(order: self, approver: user)
end
|
Associates the specified user with the order. Delegates to Cart::Associate service.
478
479
480
|
# File 'app/models/spree/order.rb', line 478
def associate_user!(user, override_email = true)
Spree.cart_associate_service.call(guest_order: self, user: user, override_email: override_email)
end
|
#available_payment_methods(store = nil) ⇒ Object
621
622
623
624
625
|
# File 'app/models/spree/order.rb', line 621
def available_payment_methods(store = nil)
Spree::Deprecation.warn('`Order#available_payment_methods` is deprecated and will be removed in Spree 5.5. Use `collect_frontend_payment_methods` instead.')
@available_payment_methods ||= collect_payment_methods(store)
end
|
#backordered? ⇒ Boolean
405
406
407
|
# File 'app/models/spree/order.rb', line 405
def backordered?
shipments.any?(&:backordered?)
end
|
#backordered_variants ⇒ Array<Spree::Variant>
Returns the backordered variants for the order
565
566
567
568
569
570
|
# File 'app/models/spree/order.rb', line 565
def backordered_variants
variants.
where(track_inventory: true).
joins(:stock_items, :product).
where(Spree::StockItem.table_name => { count_on_hand: ..0, backorderable: true })
end
|
#can_approve? ⇒ Boolean
841
842
843
|
# File 'app/models/spree/order.rb', line 841
def can_approve?
!approved?
end
|
#can_be_deleted? ⇒ Boolean
850
851
852
|
# File 'app/models/spree/order.rb', line 850
def can_be_deleted?
!completed? && payments.completed.empty?
end
|
#can_be_destroyed? ⇒ Boolean
845
846
847
848
|
# File 'app/models/spree/order.rb', line 845
def can_be_destroyed?
Spree::Deprecation.warn('Spree::Order#can_be_destroyed? is deprecated and will be removed in the next major version. Use Spree::Order#can_be_deleted? instead.')
can_be_deleted?
end
|
572
573
574
|
# File 'app/models/spree/order.rb', line 572
def can_ship?
complete? || resumed? || awaiting_return? || returned?
end
|
824
825
826
|
# File 'app/models/spree/order.rb', line 824
def canceled_by(user, canceled_at = nil)
Spree.order_cancel_service.call(order: self, canceler: user, canceled_at: canceled_at)
end
|
Returns item and whole order discount amount for Order without Shipment discounts (eg. Free Shipping)
933
934
935
936
937
|
# File 'app/models/spree/order.rb', line 933
def cart_promo_total
all_adjustments.eligible.nonzero.promotion.
where.not(adjustable_type: 'Spree::Shipment').
sum(:amount)
end
|
#checkout_allowed? ⇒ Boolean
Indicates whether or not the user is allowed to proceed to checkout. Currently this is implemented as a check for whether or not there is at least one LineItem in the Order. Feel free to override this logic in your own application if you require additional steps before allowing a checkout.
377
378
379
|
# File 'app/models/spree/order.rb', line 377
def checkout_allowed?
line_items.exists?
end
|
#collect_backend_payment_methods ⇒ Object
886
887
888
|
# File 'app/models/spree/order.rb', line 886
def collect_backend_payment_methods
store.payment_methods.active.available_on_back_end.select { |pm| pm.available_for_order?(self) }
end
|
#collect_frontend_payment_methods ⇒ Object
890
891
892
|
# File 'app/models/spree/order.rb', line 890
def collect_frontend_payment_methods
store.payment_methods.active.available_on_front_end.select { |pm| pm.available_for_order?(self) }
end
|
347
348
349
|
# File 'app/models/spree/order.rb', line 347
def completed?
completed_at.present?
end
|
#confirmation_required? ⇒ Boolean
If true, causes the confirmation step to happen during the checkout process
392
393
394
395
396
397
398
399
|
# File 'app/models/spree/order.rb', line 392
def confirmation_required?
Spree::Config[:always_include_confirm_step] ||
payments.valid.map(&:payment_method).compact.any?(&:confirmation_required?) ||
confirm?
end
|
#consider_risk ⇒ Object
854
855
856
|
# File 'app/models/spree/order.rb', line 854
def consider_risk
considered_risky! if is_risky? && !approved?
end
|
#considered_risky! ⇒ Object
858
859
860
861
862
863
|
# File 'app/models/spree/order.rb', line 858
def considered_risky!
update_column(:considered_risky, true)
publish_event('order.updated')
end
|
#create_proposed_shipments ⇒ Object
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
|
# File 'app/models/spree/order.rb', line 709
def create_proposed_shipments
all_adjustments.shipping.delete_all
shipment_ids = shipments.map(&:id)
StateChange.where(stateful_type: 'Spree::Shipment', stateful_id: shipment_ids).delete_all
ShippingRate.where(shipment_id: shipment_ids).delete_all
shipments.delete_all
inventory_units.on_hand_or_backordered.delete_all
self.shipments = Spree::Stock::Coordinator.new(self).shipments
end
|
#create_shipment_tax_charge! ⇒ Object
507
508
509
|
# File 'app/models/spree/order.rb', line 507
def create_shipment_tax_charge!
Spree::TaxRate.adjust(self, shipments) if shipments.any?
end
|
#create_tax_charge! ⇒ Object
Creates new tax charges if there are any applicable rates. If prices already include taxes then price adjustments are created instead.
502
503
504
505
|
# File 'app/models/spree/order.rb', line 502
def create_tax_charge!
Spree::TaxRate.adjust(self, line_items)
Spree::TaxRate.adjust(self, shipments) if shipments.any?
end
|
#delivery_required? ⇒ Boolean
Does this order require a delivery (physical or digital).
382
383
384
|
# File 'app/models/spree/order.rb', line 382
def delivery_required?
true end
|
#disassociate_user! ⇒ Object
482
483
484
485
486
|
# File 'app/models/spree/order.rb', line 482
def disassociate_user!
nullified_attributes = ASSOCIATED_USER_ATTRIBUTES.index_with(nil)
update!(nullified_attributes)
end
|
#email_required? ⇒ Boolean
401
402
403
|
# File 'app/models/spree/order.rb', line 401
def email_required?
require_email
end
|
#empty! ⇒ Object
654
655
656
657
658
659
|
# File 'app/models/spree/order.rb', line 654
def empty!
raise Spree.t(:cannot_empty_completed_order) if completed?
result = Spree.cart_empty_service.call(order: self)
result.value
end
|
#ensure_line_item_variants_are_not_discontinued ⇒ Object
Check to see if any line item variants are discontinued. If so add error and restart checkout.
634
635
636
637
638
639
640
641
642
|
# File 'app/models/spree/order.rb', line 634
def ensure_line_item_variants_are_not_discontinued
if line_items.any? { |li| !li.variant || li.variant.discontinued? }
restart_checkout_flow
errors.add(:base, Spree.t(:discontinued_variants_present))
false
else
true
end
end
|
#ensure_line_items_are_in_stock ⇒ Object
644
645
646
647
648
649
650
651
652
|
# File 'app/models/spree/order.rb', line 644
def ensure_line_items_are_in_stock
if insufficient_stock_lines.present?
restart_checkout_flow
errors.add(:base, Spree.t(:insufficient_stock_lines_present))
false
else
true
end
end
|
#ensure_market_presence ⇒ Object
458
459
460
|
# File 'app/models/spree/order.rb', line 458
def ensure_market_presence
self.market ||= Spree::Current.market || store&.default_market
end
|
#ensure_store_presence ⇒ Object
454
455
456
|
# File 'app/models/spree/order.rb', line 454
def ensure_store_presence
self.store ||= Spree::Store.default
end
|
#ensure_updated_shipments ⇒ Object
Clean shipments and make order back to address state
At some point the might need to force the order to transition from address to delivery again so that proper updated shipments are created. e.g. customer goes back from payment step and changes order items
766
767
768
769
770
771
772
773
774
775
776
|
# File 'app/models/spree/order.rb', line 766
def ensure_updated_shipments
if shipments.any? && !completed?
shipments.destroy_all
update_column(:shipment_total, 0)
publish_event('order.updated')
restart_checkout_flow
end
end
|
#finalize! ⇒ Object
Finalizes an in progress order after checkout is complete. Called after transition to complete state when payments will have been processed
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
|
# File 'app/models/spree/order.rb', line 582
def finalize!
all_adjustments.each(&:close)
updater.update_payment_state
shipments.each do |shipment|
shipment.update!(self)
shipment.finalize!
end
updater.update_shipment_state
save!
updater.run_hooks
touch :completed_at
send_order_placed_webhook
consider_risk
publish_order_completed_event
end
|
#find_line_item_by_variant(variant, options = {}) ⇒ Object
493
494
495
496
497
498
|
# File 'app/models/spree/order.rb', line 493
def find_line_item_by_variant(variant, options = {})
line_items.detect do |line_item|
line_item.variant_id == variant.id &&
Spree.cart_compare_line_items_service.new.call(order: self, line_item: line_item, options: options).value
end
end
|
#fulfill! ⇒ Object
606
607
608
609
610
|
# File 'app/models/spree/order.rb', line 606
def fulfill!
shipments.each { |shipment| shipment.update!(self) if shipment.persisted? }
updater.update_shipment_state
save!
end
|
#full_name ⇒ Object
540
541
542
543
544
545
546
|
# File 'app/models/spree/order.rb', line 540
def full_name
@full_name ||= if user.present? && user.name.present?
user.full_name
else
billing_address&.full_name || email
end
end
|
#fully_discounted? ⇒ Boolean
Also known as:
fully_discounted
determines whether the inventory is fully discounted
Returns
899
900
901
|
# File 'app/models/spree/order.rb', line 899
def fully_discounted?
adjustment_total + line_items.map(&:final_amount).sum == 0.0
end
|
#fully_shipped? ⇒ Boolean
705
706
707
|
# File 'app/models/spree/order.rb', line 705
def fully_shipped?
shipments.shipped.size == shipments.size
end
|
#has_free_shipping? ⇒ Boolean
939
940
941
942
943
944
|
# File 'app/models/spree/order.rb', line 939
def has_free_shipping?
shipment_adjustments.
joins(:promotion_action).
where(spree_adjustments: { eligible: true, source_type: 'Spree::PromotionAction' },
spree_promotion_actions: { type: 'Spree::Promotion::Actions::FreeShipping' }).exists?
end
|
881
882
883
884
|
# File 'app/models/spree/order.rb', line 881
def has_non_reimbursement_related_refunds?
refunds.non_reimbursement.exists? ||
payments.offset_payment.exists? end
|
#has_step?(step) ⇒ Boolean
665
666
667
|
# File 'app/models/spree/order.rb', line 665
def has_step?(step)
checkout_steps.include?(step)
end
|
#insufficient_stock_lines ⇒ Object
627
628
629
|
# File 'app/models/spree/order.rb', line 627
def insufficient_stock_lines
line_items.select(&:insufficient_stock?)
end
|
814
815
816
|
# File 'app/models/spree/order.rb', line 814
def is_risky?
!payments.risky.empty?
end
|
#line_items_without_shipping_rates ⇒ Array<Spree::LineItem>
Returns line items that have no shipping rates
736
737
738
739
740
|
# File 'app/models/spree/order.rb', line 736
def line_items_without_shipping_rates
@line_items_without_shipping_rates ||= shipments.map do |shipment|
shipment.manifest.map(&:line_item) if shipment.shipping_rates.blank?
end.flatten.compact
end
|
#log_state_changes(state_name:, old_state:, new_state:) ⇒ Object
680
681
682
683
684
685
686
687
|
# File 'app/models/spree/order.rb', line 680
def log_state_changes(state_name:, old_state:, new_state:)
state_changes.create(
previous_state: old_state,
next_state: new_state,
name: state_name,
user_id: user_id
)
end
|
#merger ⇒ Object
450
451
452
|
# File 'app/models/spree/order.rb', line 450
def merger
@merger ||= Spree::OrderMerger.new(self)
end
|
#name ⇒ Object
534
535
536
537
538
|
# File 'app/models/spree/order.rb', line 534
def name
if (address = bill_address || ship_address)
address.full_name
end
end
|
#order_refunded? ⇒ Boolean
Checks if the order is fully refunded
353
354
355
356
357
358
|
# File 'app/models/spree/order.rb', line 353
def order_refunded?
return false if item_count.zero?
return false if refunds_total.zero?
payment_state.in?(%w[void failed]) || refunds_total == total_minus_store_credits - additional_tax_total.abs
end
|
#outstanding_balance ⇒ Object
518
519
520
521
522
523
524
|
# File 'app/models/spree/order.rb', line 518
def outstanding_balance
if canceled?
-1 * payment_total
else
total - (payment_total + reimbursement_paid_total)
end
end
|
#outstanding_balance? ⇒ Boolean
530
531
532
|
# File 'app/models/spree/order.rb', line 530
def outstanding_balance?
outstanding_balance != 0
end
|
Helper methods for checkout steps
613
614
615
|
# File 'app/models/spree/order.rb', line 613
def paid?
payments.valid.completed.size == payments.valid.size && payments.valid.sum(:amount) >= total
end
|
#partially_refunded? ⇒ Boolean
Checks if the order is partially refunded
366
367
368
369
370
371
|
# File 'app/models/spree/order.rb', line 366
def partially_refunded?
return false if item_count.zero?
return false if payment_state.in?(%w[void failed]) || refunds.empty?
refunds_total < total_minus_store_credits - additional_tax_total.abs
end
|
Returns the payment method for the order
551
552
553
|
# File 'app/models/spree/order.rb', line 551
def payment_method
payments.valid.not_store_credits.first&.payment_method
end
|
#payment_methods ⇒ Object
617
618
619
|
# File 'app/models/spree/order.rb', line 617
def payment_methods
@payment_methods ||= store.payment_methods.active.available_on_front_end.select { |pm| pm.available_for_order?(self) }
end
|
#payment_required? ⇒ Boolean
Is this a free order in which case the payment step should be skipped
387
388
389
|
# File 'app/models/spree/order.rb', line 387
def payment_required?
total.to_f > 0.0
end
|
Returns the payment source for the order
558
559
560
|
# File 'app/models/spree/order.rb', line 558
def payment_source
payments.valid.not_store_credits.first&.source
end
|
#pre_tax_item_amount ⇒ Object
Sum of all line item amounts pre-tax
327
328
329
|
# File 'app/models/spree/order.rb', line 327
def pre_tax_item_amount
line_items.sum(:pre_tax_amount)
end
|
#pre_tax_total ⇒ Object
Sum of all line item and shipment pre-tax
332
333
334
|
# File 'app/models/spree/order.rb', line 332
def pre_tax_total
pre_tax_item_amount + shipments.sum(:pre_tax_amount)
end
|
904
905
906
|
# File 'app/models/spree/order.rb', line 904
def promo_code
Spree::CouponCode.find_by(order: self, promotion: promotions).try(:code) || promotions.pluck(:code).compact.first
end
|
#quantity ⇒ Object
877
878
879
|
# File 'app/models/spree/order.rb', line 877
def quantity
line_items.sum(:quantity)
end
|
#quantity_of(variant, options = {}) ⇒ Object
488
489
490
491
|
# File 'app/models/spree/order.rb', line 488
def quantity_of(variant, options = {})
line_item = find_line_item_by_variant(variant, options)
line_item ? line_item.quantity : 0
end
|
#quick_checkout? ⇒ Boolean
Check if the shipping address is a quick checkout address quick checkout addresses are incomplete as wallet providers like Apple Pay and Google Pay do not provide all the address fields until the checkout is completed (confirmed) on their side
413
414
415
|
# File 'app/models/spree/order.rb', line 413
def quick_checkout?
shipping_address.present? && shipping_address.quick_checkout?
end
|
#quick_checkout_available? ⇒ Boolean
Check if quick checkout is available for this order Either fully digital or not digital at all
420
421
422
|
# File 'app/models/spree/order.rb', line 420
def quick_checkout_available?
payment_required? && shipments.count <= 1 && (digital? || !some_digital? || !delivery_required?)
end
|
#quick_checkout_require_address? ⇒ Boolean
Check if quick checkout requires an address collection If the order is digital or not delivery required, then we don’t need to collect an address
427
428
429
|
# File 'app/models/spree/order.rb', line 427
def quick_checkout_require_address?
!digital? && delivery_required?
end
|
#refresh_shipment_rates(shipping_method_filter = ShippingMethod::DISPLAY_ON_FRONT_END) ⇒ Object
790
791
792
|
# File 'app/models/spree/order.rb', line 790
def refresh_shipment_rates(shipping_method_filter = ShippingMethod::DISPLAY_ON_FRONT_END)
shipments.map { |s| s.refresh_rates(shipping_method_filter) }
end
|
#refunds_total ⇒ Object
360
361
362
|
# File 'app/models/spree/order.rb', line 360
def refunds_total
refunds.loaded? ? refunds.sum(&:amount) : refunds.sum(:amount)
end
|
#reimbursement_paid_total ⇒ Object
526
527
528
|
# File 'app/models/spree/order.rb', line 526
def reimbursement_paid_total
reimbursements.sum(&:paid_amount)
end
|
#remove_out_of_stock_items! ⇒ Object
Removes out-of-stock/discontinued items and populates warnings. Returns self (reloaded if items were removed) with warnings set.
65
66
67
68
69
70
71
72
|
# File 'app/models/spree/order.rb', line 65
def remove_out_of_stock_items!
result = Spree::Cart::RemoveOutOfStockItems.call(order: self)
return self unless result.success?
order, _messages, warnings = result.value
order.warnings = warnings || []
order
end
|
#requires_ship_address? ⇒ Boolean
962
963
964
|
# File 'app/models/spree/order.rb', line 962
def requires_ship_address?
!digital?
end
|
#restart_checkout_flow ⇒ Object
778
779
780
781
782
783
784
785
786
787
788
|
# File 'app/models/spree/order.rb', line 778
def restart_checkout_flow
update_columns(
state: 'cart',
updated_at: Time.current
)
publish_event('order.updated')
next! unless line_items.empty?
end
|
#set_shipments_cost ⇒ Object
798
799
800
801
802
803
|
# File 'app/models/spree/order.rb', line 798
def set_shipments_cost
shipments.each(&:update_amounts)
updater.update_shipment_total
updater.update_adjustment_total
persist_totals
end
|
701
702
703
|
# File 'app/models/spree/order.rb', line 701
def shipped?
%w(partial shipped).include?(shipment_state)
end
|
#shipping_discount ⇒ Object
343
344
345
|
# File 'app/models/spree/order.rb', line 343
def shipping_discount
shipment_adjustments.non_tax.eligible.sum(:amount) * - 1
end
|
#shipping_eq_billing_address? ⇒ Boolean
794
795
796
|
# File 'app/models/spree/order.rb', line 794
def shipping_eq_billing_address?
bill_address == ship_address
end
|
#shipping_method ⇒ Object
805
806
807
808
809
810
811
812
|
# File 'app/models/spree/order.rb', line 805
def shipping_method
Spree::ShippingMethod.
where(id: shipments.with_selected_shipping_method.limit(1).pluck(:shipping_method_id)).
limit(1).
first
end
|
#state_changed(name) ⇒ Object
669
670
671
672
673
674
675
676
677
678
|
# File 'app/models/spree/order.rb', line 669
def state_changed(name)
state = "#{name}_state"
if persisted?
old_state = send("#{state}_was")
new_state = send(state)
unless old_state == new_state
log_state_changes(state_name: name, old_state: old_state, new_state: new_state)
end
end
end
|
#tax_address ⇒ Object
Returns the address for taxation based on configuration
438
439
440
|
# File 'app/models/spree/order.rb', line 438
def tax_address
Spree::Config[:tax_using_ship_address] ? ship_address : bill_address
end
|
#tax_total ⇒ Object
873
874
875
|
# File 'app/models/spree/order.rb', line 873
def tax_total
included_tax_total + additional_tax_total
end
|
#tax_zone ⇒ Object
Returns the relevant zone (if any) to be used for taxation purposes. Uses default tax zone unless there is a specific match
433
434
435
|
# File 'app/models/spree/order.rb', line 433
def tax_zone
@tax_zone ||= Zone.match(tax_address) || Zone.default_tax
end
|
#to_csv(_store = nil) ⇒ Object
946
947
948
949
950
951
952
953
954
955
956
|
# File 'app/models/spree/order.rb', line 946
def to_csv(_store = nil)
metafields_for_csv ||= Spree::MetafieldDefinition.for_resource_type('Spree::Order').order(:namespace, :key).map do |mf_def|
metafields.find { |mf| mf.metafield_definition_id == mf_def.id }&.csv_value
end
csv_lines = []
all_line_items.each_with_index do |line_item, index|
csv_lines << Spree::CSV::OrderLineItemPresenter.new(self, line_item, index, metafields_for_csv).call
end
csv_lines
end
|
#total_weight ⇒ BigDecimal
Returns the total weight of the inventory units in the order This is used to calculate the shipping rates for the order
729
730
731
|
# File 'app/models/spree/order.rb', line 729
def total_weight
@total_weight ||= line_items.joins(:variant).includes(:variant).map(&:item_weight).sum
end
|
#uneditable? ⇒ Boolean
576
577
578
|
# File 'app/models/spree/order.rb', line 576
def uneditable?
complete? || canceled? || returned?
end
|
#update_line_item_prices! ⇒ Object
511
512
513
514
515
516
|
# File 'app/models/spree/order.rb', line 511
def update_line_item_prices!
transaction do
line_items.reload.each(&:update_price)
save!
end
end
|
#update_with_updater! ⇒ Object
446
447
448
|
# File 'app/models/spree/order.rb', line 446
def update_with_updater!
updater.update
end
|
#updater ⇒ Object
442
443
444
|
# File 'app/models/spree/order.rb', line 442
def updater
@updater ||= Spree.order_updater.new(self)
end
|
#use_all_coupon_codes ⇒ Object
Returns the valid coupon promotions for the order
924
925
926
927
928
|
# File 'app/models/spree/order.rb', line 924
def valid_coupon_promotions
promotions.
where(id: valid_promotion_ids).
coupons
end
|
Returns the IDs of the valid promotions for the order
916
917
918
919
920
|
# File 'app/models/spree/order.rb', line 916
def valid_promotion_ids
all_adjustments.eligible.nonzero.promotion.promotion.eligible.nonzero.promotion.
joins("INNER JOIN #{Spree::PromotionAction.table_name} ON #{Spree::PromotionAction.table_name}.id = #{Spree::Adjustment.table_name}.source_id").
pluck("#{Spree::PromotionAction.table_name}.promotion_id").compact.uniq
end
|
Returns the valid promotions for the order
910
911
912
|
# File 'app/models/spree/order.rb', line 910
def valid_promotions
order_promotions.includes(:promotion).where(promotion_id: valid_promotion_ids).uniq(&:promotion_id)
end
|