solidus_core 2.1.1 → 2.2.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of solidus_core might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Rakefile +0 -1
- data/app/assets/config/solidus_core_manifest.js +1 -0
- data/app/assets/javascripts/spree.js.erb +72 -0
- data/app/helpers/spree/store_helper.rb +5 -0
- data/app/jobs/spree/promotion_code_batch_job.rb +24 -0
- data/app/mailers/spree/promotion_code_batch_mailer.rb +13 -0
- data/app/models/concerns/spree/calculated_adjustments.rb +1 -1
- data/app/models/concerns/spree/ordered_property_value_list.rb +2 -2
- data/app/models/concerns/spree/user_address_book.rb +4 -4
- data/app/models/concerns/spree/user_methods.rb +7 -0
- data/app/models/concerns/spree/user_payment_source.rb +12 -5
- data/app/models/spree/address.rb +14 -3
- data/app/models/spree/adjustment.rb +13 -1
- data/app/models/spree/app_configuration.rb +0 -19
- data/app/models/spree/base.rb +2 -0
- data/app/models/spree/credit_card.rb +34 -43
- data/app/models/spree/gateway/bogus.rb +1 -1
- data/app/models/spree/gateway.rb +6 -4
- data/app/models/spree/inventory_unit.rb +3 -2
- data/app/models/spree/order/checkout.rb +187 -273
- data/app/models/spree/order.rb +137 -71
- data/app/models/spree/order_contents.rb +1 -1
- data/app/models/spree/order_inventory.rb +11 -11
- data/app/models/spree/order_promotion.rb +2 -0
- data/app/models/spree/order_update_attributes.rb +1 -8
- data/app/models/spree/order_updater.rb +67 -63
- data/app/models/spree/payment.rb +0 -1
- data/app/models/spree/payment_create.rb +27 -7
- data/app/models/spree/payment_method/store_credit.rb +3 -3
- data/app/models/spree/payment_method.rb +4 -1
- data/app/models/spree/payment_source.rb +45 -0
- data/app/models/spree/product/scopes.rb +24 -24
- data/app/models/spree/product.rb +4 -4
- data/app/models/spree/promotion.rb +2 -0
- data/app/models/spree/promotion_code/batch_builder.rb +63 -0
- data/app/models/spree/promotion_code.rb +1 -0
- data/app/models/spree/promotion_code_batch.rb +25 -0
- data/app/models/spree/promotion_handler/cart.rb +2 -2
- data/app/models/spree/promotion_handler/coupon.rb +1 -2
- data/app/models/spree/promotion_handler/free_shipping.rb +32 -21
- data/app/models/spree/promotion_handler/page.rb +1 -1
- data/app/models/spree/reimbursement.rb +1 -1
- data/app/models/spree/return_authorization.rb +0 -28
- data/app/models/spree/return_item.rb +1 -1
- data/app/models/spree/shipment.rb +4 -4
- data/app/models/spree/shipping_method.rb +2 -2
- data/app/models/spree/shipping_rate.rb +1 -1
- data/app/models/spree/stock/availability_validator.rb +16 -17
- data/app/models/spree/stock/coordinator.rb +3 -3
- data/app/models/spree/stock/package.rb +1 -1
- data/app/models/spree/stock/quantifier.rb +5 -4
- data/app/models/spree/stock_location.rb +2 -2
- data/app/models/spree/store.rb +2 -2
- data/app/models/spree/store_credit.rb +1 -1
- data/app/models/spree/tax/tax_helpers.rb +3 -3
- data/app/models/spree/tax_rate.rb +7 -1
- data/app/models/spree/taxonomy.rb +1 -1
- data/app/models/spree/variant/scopes.rb +5 -5
- data/app/models/spree/variant/vat_price_generator.rb +8 -5
- data/app/models/spree/variant.rb +1 -0
- data/app/models/spree/wallet/add_payment_sources_to_wallet.rb +19 -10
- data/app/models/spree/wallet/default_payment_builder.rb +6 -6
- data/app/models/spree/wallet.rb +71 -0
- data/app/models/spree/wallet_payment_source.rb +17 -0
- data/app/models/spree/zone.rb +1 -1
- data/app/views/spree/carton_mailer/shipped_email.text.erb +1 -1
- data/app/views/spree/promotion_code_batch_mailer/promotion_code_batch_errored.text.erb +2 -0
- data/app/views/spree/promotion_code_batch_mailer/promotion_code_batch_finished.text.erb +2 -0
- data/app/views/spree/reimbursement_mailer/reimbursement_email.html.erb +0 -7
- data/app/views/spree/reimbursement_mailer/reimbursement_email.text.erb +0 -5
- data/app/views/spree/shared/_error_messages.html.erb +1 -1
- data/app/views/spree/shipment_mailer/shipped_email.html.erb +1 -1
- data/config/initializers/assets.rb +1 -1
- data/config/initializers/friendly_id.rb +1 -1
- data/config/locales/en.yml +50 -12
- data/db/default/spree/store_credit.rb +2 -1
- data/db/migrate/20130826062534_add_depth_to_spree_taxons.rb +4 -6
- data/db/migrate/20160420044191_create_spree_wallet_payment_sources.rb +23 -0
- data/db/migrate/20160420181916_migrate_credit_cards_to_wallet_payment_sources.rb +26 -0
- data/db/migrate/20161017102621_create_spree_promotion_code_batch.rb +36 -0
- data/db/migrate/20161129035810_add_index_to_spree_payments_number.rb +5 -0
- data/db/migrate/20170223235001_remove_spree_store_credits_column.rb +5 -0
- data/lib/generators/spree/dummy/templates/rails/application.rb +1 -1
- data/lib/generators/spree/dummy/templates/rails/test.rb +1 -1
- data/lib/generators/spree/install/install_generator.rb +6 -5
- data/lib/spree/core/controller_helpers/payment_parameters.rb +54 -0
- data/lib/spree/core/engine.rb +6 -9
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +0 -1
- data/lib/spree/money.rb +18 -0
- data/lib/spree/permission_sets/default_customer.rb +1 -1
- data/lib/spree/permitted_attributes.rb +1 -1
- data/lib/spree/testing_support/authorization_helpers.rb +1 -0
- data/lib/spree/testing_support/capybara_ext.rb +13 -0
- data/lib/spree/testing_support/factories/order_factory.rb +5 -1
- data/lib/spree/testing_support/factories/payment_factory.rb +1 -1
- data/lib/spree/testing_support/factories/shipment_factory.rb +0 -1
- data/solidus_core.gemspec +3 -3
- data/spec/jobs/promotion_code_batch_job_spec.rb +65 -0
- data/spec/lib/calculated_adjustments_spec.rb +105 -1
- data/spec/lib/spree/core/testing_support/factories/order_factory_spec.rb +4 -1
- data/spec/lib/spree/core/testing_support/factories/payment_factory_spec.rb +8 -0
- data/spec/lib/spree/money_spec.rb +32 -0
- data/spec/lib/spree/permission_sets/default_customer_spec.rb +20 -0
- data/spec/mailers/promotion_code_batch_mailer_spec.rb +45 -0
- data/spec/models/spree/credit_card_spec.rb +86 -86
- data/spec/models/spree/gateway_spec.rb +3 -1
- data/spec/models/spree/inventory_unit_spec.rb +12 -4
- data/spec/models/spree/order/checkout_spec.rb +11 -32
- data/spec/models/spree/order/tax_spec.rb +2 -2
- data/spec/models/spree/order_contents_spec.rb +24 -1
- data/spec/models/spree/order_inventory_spec.rb +130 -83
- data/spec/models/spree/order_spec.rb +15 -117
- data/spec/models/spree/order_update_attributes_spec.rb +1 -44
- data/spec/models/spree/order_updater_spec.rb +10 -13
- data/spec/models/spree/payment_create_spec.rb +5 -1
- data/spec/models/spree/payment_method_spec.rb +16 -0
- data/spec/models/spree/payment_spec.rb +14 -8
- data/spec/models/spree/promotion_code/batch_builder_spec.rb +61 -0
- data/spec/models/spree/promotion_code_batch_spec.rb +58 -0
- data/spec/models/spree/promotion_code_spec.rb +4 -0
- data/spec/models/spree/promotion_spec.rb +3 -6
- data/spec/models/spree/return_authorization_spec.rb +0 -59
- data/spec/models/spree/shipment_spec.rb +4 -4
- data/spec/models/spree/stock/availability_validator_spec.rb +64 -9
- data/spec/models/spree/tax/item_adjuster_spec.rb +1 -2
- data/spec/models/spree/unit_cancel_spec.rb +0 -85
- data/spec/models/spree/user_spec.rb +3 -1
- data/spec/models/spree/variant/vat_price_generator_spec.rb +8 -2
- data/spec/models/spree/variant_spec.rb +16 -4
- data/spec/models/spree/wallet_payment_source_spec.rb +46 -0
- data/spec/models/spree/wallet_spec.rb +128 -0
- data/spec/support/concerns/payment_source.rb +64 -0
- metadata +51 -25
- data/app/assets/javascripts/spree.js.coffee.erb +0 -64
- data/app/models/spree/promotion_builder.rb +0 -55
- data/app/models/spree/promotion_code/code_builder.rb +0 -62
- data/config/initializers/premailer_assets.rb +0 -1
- data/lib/spree/core/unreturned_item_charger.rb +0 -106
- data/lib/tasks/exchanges.rake +0 -47
- data/spec/lib/spree/core/unreturned_item_charger_spec.rb +0 -126
- data/spec/lib/tasks/exchanges_spec.rb +0 -220
- data/spec/models/spree/promotion_builder_spec.rb +0 -120
- data/spec/models/spree/promotion_code/code_builder_spec.rb +0 -77
data/app/models/spree/order.rb
CHANGED
@@ -2,11 +2,11 @@ require 'spree/core/validators/email'
|
|
2
2
|
require 'spree/order/checkout'
|
3
3
|
|
4
4
|
module Spree
|
5
|
-
# The customers cart until completed, then acts as
|
5
|
+
# The customers cart until completed, then acts as permanent record of the transaction.
|
6
6
|
#
|
7
7
|
# `Spree::Order` is the heart of the Solidus system, as it acts as the customer's
|
8
8
|
# cart as they shop. Once an order is complete, it serves as the
|
9
|
-
#
|
9
|
+
# permanent record of their purchase. It has many responsibilities:
|
10
10
|
#
|
11
11
|
# * Records and validates attributes like `total` and relationships like
|
12
12
|
# `Spree::LineItem` as an ActiveRecord model.
|
@@ -43,17 +43,20 @@ module Spree
|
|
43
43
|
go_to_state :confirm
|
44
44
|
end
|
45
45
|
|
46
|
-
self.whitelisted_ransackable_associations = %w[shipments user promotions bill_address ship_address line_items]
|
46
|
+
self.whitelisted_ransackable_associations = %w[shipments user order_promotions promotions bill_address ship_address line_items]
|
47
47
|
self.whitelisted_ransackable_attributes = %w[completed_at created_at email number state payment_state shipment_state total store_id]
|
48
48
|
|
49
49
|
attr_reader :coupon_code
|
50
|
-
attr_accessor :temporary_address
|
50
|
+
attr_accessor :temporary_address
|
51
51
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
52
|
+
attr_accessor :temporary_payment_source
|
53
|
+
alias_method :temporary_credit_card, :temporary_payment_source
|
54
|
+
alias_method :temporary_credit_card=, :temporary_payment_source=
|
55
|
+
deprecate temporary_credit_card: :temporary_payment_source, deprecator: Spree::Deprecation
|
56
|
+
deprecate :temporary_credit_card= => :temporary_payment_source=, deprecator: Spree::Deprecation
|
56
57
|
|
58
|
+
# Customer info
|
59
|
+
belongs_to :user, class_name: Spree::UserClassHandle.new
|
57
60
|
belongs_to :bill_address, foreign_key: :bill_address_id, class_name: 'Spree::Address'
|
58
61
|
alias_attribute :billing_address, :bill_address
|
59
62
|
|
@@ -62,36 +65,48 @@ module Spree
|
|
62
65
|
alias_attribute :ship_total, :shipment_total
|
63
66
|
|
64
67
|
belongs_to :store, class_name: 'Spree::Store'
|
65
|
-
|
68
|
+
|
69
|
+
# Items
|
66
70
|
has_many :line_items, -> { order(:created_at, :id) }, dependent: :destroy, inverse_of: :order
|
67
|
-
has_many :
|
68
|
-
has_many :
|
69
|
-
|
71
|
+
has_many :variants, through: :line_items
|
72
|
+
has_many :products, through: :variants
|
73
|
+
|
74
|
+
# Shipping
|
75
|
+
has_many :inventory_units, inverse_of: :order
|
76
|
+
has_many :cartons, -> { distinct }, through: :inventory_units
|
77
|
+
has_many :shipments, dependent: :destroy, inverse_of: :order do
|
78
|
+
def states
|
79
|
+
pluck(:state).uniq
|
80
|
+
end
|
81
|
+
end
|
82
|
+
has_many :order_stock_locations, class_name: "Spree::OrderStockLocation"
|
83
|
+
has_many :stock_locations, through: :order_stock_locations
|
84
|
+
|
85
|
+
# Adjustments and promotions
|
70
86
|
has_many :adjustments, -> { order(:created_at) }, as: :adjustable, inverse_of: :adjustable, dependent: :destroy
|
71
87
|
has_many :line_item_adjustments, through: :line_items, source: :adjustments
|
72
88
|
has_many :shipment_adjustments, through: :shipments, source: :adjustments
|
73
|
-
has_many :inventory_units, inverse_of: :order
|
74
|
-
has_many :products, through: :variants
|
75
|
-
has_many :variants, through: :line_items
|
76
|
-
has_many :refunds, through: :payments
|
77
89
|
has_many :all_adjustments,
|
78
90
|
class_name: 'Spree::Adjustment',
|
79
91
|
foreign_key: :order_id,
|
80
92
|
dependent: :destroy,
|
81
93
|
inverse_of: :order
|
82
|
-
|
83
|
-
has_many :order_stock_locations, class_name: "Spree::OrderStockLocation"
|
84
|
-
has_many :stock_locations, through: :order_stock_locations
|
85
|
-
|
86
94
|
has_many :order_promotions, class_name: 'Spree::OrderPromotion'
|
87
95
|
has_many :promotions, through: :order_promotions
|
88
96
|
|
89
|
-
|
90
|
-
has_many :
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
97
|
+
# Payments
|
98
|
+
has_many :payments, dependent: :destroy, inverse_of: :order
|
99
|
+
|
100
|
+
# Returns
|
101
|
+
has_many :return_authorizations, dependent: :destroy, inverse_of: :order
|
102
|
+
has_many :reimbursements, inverse_of: :order
|
103
|
+
has_many :refunds, through: :payments
|
104
|
+
|
105
|
+
# Logging
|
106
|
+
has_many :state_changes, as: :stateful
|
107
|
+
belongs_to :created_by, class_name: Spree::UserClassHandle.new
|
108
|
+
belongs_to :approver, class_name: Spree::UserClassHandle.new
|
109
|
+
belongs_to :canceler, class_name: Spree::UserClassHandle.new
|
95
110
|
|
96
111
|
accepts_nested_attributes_for :line_items
|
97
112
|
accepts_nested_attributes_for :bill_address
|
@@ -111,6 +126,7 @@ module Spree
|
|
111
126
|
|
112
127
|
validates :email, presence: true, if: :require_email
|
113
128
|
validates :email, email: true, allow_blank: true
|
129
|
+
validates :guest_token, presence: { allow_nil: true }
|
114
130
|
validates :number, presence: true, uniqueness: { allow_blank: true }
|
115
131
|
validates :store_id, presence: true
|
116
132
|
|
@@ -134,7 +150,6 @@ module Spree
|
|
134
150
|
|
135
151
|
# shows completed orders first, by their completed_at date, then uncompleted orders by their created_at
|
136
152
|
scope :reverse_chronological, -> { order('spree_orders.completed_at IS NULL', completed_at: :desc, created_at: :desc) }
|
137
|
-
scope :unreturned_exchange, -> { joins(:shipments).where('spree_orders.created_at > spree_shipments.created_at') }
|
138
153
|
|
139
154
|
def self.by_customer(customer)
|
140
155
|
joins(:user).where("#{Spree.user_class.table_name}.email" => customer)
|
@@ -220,7 +235,7 @@ module Spree
|
|
220
235
|
# Returns the relevant zone (if any) to be used for taxation purposes.
|
221
236
|
# Uses default tax zone unless there is a specific match
|
222
237
|
def tax_zone
|
223
|
-
Zone.match(tax_address) || Zone.default_tax
|
238
|
+
Spree::Zone.match(tax_address) || Spree::Zone.default_tax
|
224
239
|
end
|
225
240
|
deprecate tax_zone: "Please use Spree::Order#tax_address instead.",
|
226
241
|
deprecator: Spree::Deprecation
|
@@ -235,7 +250,7 @@ module Spree
|
|
235
250
|
end
|
236
251
|
|
237
252
|
def updater
|
238
|
-
@updater ||= OrderUpdater.new(self)
|
253
|
+
@updater ||= Spree::OrderUpdater.new(self)
|
239
254
|
end
|
240
255
|
|
241
256
|
def update!
|
@@ -381,12 +396,12 @@ module Spree
|
|
381
396
|
|
382
397
|
def credit_cards
|
383
398
|
credit_card_ids = payments.from_credit_card.pluck(:source_id).uniq
|
384
|
-
CreditCard.where(id: credit_card_ids)
|
399
|
+
Spree::CreditCard.where(id: credit_card_ids)
|
385
400
|
end
|
386
401
|
|
387
402
|
def valid_credit_cards
|
388
403
|
credit_card_ids = payments.from_credit_card.valid.pluck(:source_id).uniq
|
389
|
-
CreditCard.where(id: credit_card_ids)
|
404
|
+
Spree::CreditCard.where(id: credit_card_ids)
|
390
405
|
end
|
391
406
|
|
392
407
|
# Finalizes an in progress order after checkout is complete.
|
@@ -418,7 +433,7 @@ module Spree
|
|
418
433
|
end
|
419
434
|
|
420
435
|
def deliver_order_confirmation_email
|
421
|
-
OrderMailer.confirm_email(self).deliver_later
|
436
|
+
Spree::OrderMailer.confirm_email(self).deliver_later
|
422
437
|
update_column(:confirmation_delivered, true)
|
423
438
|
end
|
424
439
|
|
@@ -429,10 +444,10 @@ module Spree
|
|
429
444
|
|
430
445
|
def available_payment_methods
|
431
446
|
@available_payment_methods ||= Spree::PaymentMethod
|
447
|
+
.active
|
432
448
|
.available_to_store(store)
|
433
449
|
.available_to_users
|
434
|
-
.
|
435
|
-
.sort_by(&:position)
|
450
|
+
.order(:position)
|
436
451
|
end
|
437
452
|
|
438
453
|
def insufficient_stock_lines
|
@@ -458,17 +473,14 @@ module Spree
|
|
458
473
|
|
459
474
|
def empty!
|
460
475
|
line_items.destroy_all
|
461
|
-
updater.update_item_count
|
462
476
|
adjustments.destroy_all
|
463
477
|
shipments.destroy_all
|
464
478
|
|
465
|
-
|
466
|
-
persist_totals
|
479
|
+
update!
|
467
480
|
end
|
468
481
|
|
469
|
-
|
470
|
-
|
471
|
-
end
|
482
|
+
alias_method :has_step?, :has_checkout_step?
|
483
|
+
deprecate has_step?: :has_checkout_step?, deprecator: Spree::Deprecation
|
472
484
|
|
473
485
|
def state_changed(name)
|
474
486
|
state = "#{name}_state"
|
@@ -509,8 +521,6 @@ module Spree
|
|
509
521
|
end
|
510
522
|
|
511
523
|
def create_proposed_shipments
|
512
|
-
return shipments if unreturned_exchange?
|
513
|
-
|
514
524
|
if completed?
|
515
525
|
raise CannotRebuildShipments.new(Spree.t(:cannot_rebuild_shipments_order_completed))
|
516
526
|
elsif shipments.any? { |s| !s.pending? }
|
@@ -559,9 +569,9 @@ module Spree
|
|
559
569
|
|
560
570
|
def set_shipments_cost
|
561
571
|
shipments.each(&:update_amounts)
|
562
|
-
|
563
|
-
persist_totals
|
572
|
+
update!
|
564
573
|
end
|
574
|
+
deprecate set_shipments_cost: :update!, deprecator: Spree::Deprecation
|
565
575
|
|
566
576
|
def is_risky?
|
567
577
|
payments.risky.count > 0
|
@@ -599,18 +609,6 @@ module Spree
|
|
599
609
|
guest_token
|
600
610
|
end
|
601
611
|
|
602
|
-
def unreturned_exchange?
|
603
|
-
# created_at - 1 is a hack to ensure that this doesn't blow up on MySQL,
|
604
|
-
# records loaded from the DB on MySQL will have a precision of 1 second,
|
605
|
-
# but records in memory may still have miliseconds on them, causing this
|
606
|
-
# to be true where it shouldn't be.
|
607
|
-
#
|
608
|
-
# FIXME: find a better way to determine if an order is an unreturned
|
609
|
-
# exchange
|
610
|
-
shipment = shipments.first
|
611
|
-
shipment.present? ? (shipment.created_at < created_at - 1) : false
|
612
|
-
end
|
613
|
-
|
614
612
|
def tax_total
|
615
613
|
additional_tax_total + included_tax_total
|
616
614
|
end
|
@@ -690,25 +688,90 @@ module Spree
|
|
690
688
|
Spree::Money.new(total_available_store_credit - total_applicable_store_credit, { currency: currency })
|
691
689
|
end
|
692
690
|
|
693
|
-
def
|
694
|
-
|
695
|
-
|
691
|
+
def bill_address_attributes=(attributes)
|
692
|
+
self.bill_address = Spree::Address.immutable_merge(bill_address, attributes)
|
693
|
+
end
|
694
|
+
|
695
|
+
def ship_address_attributes=(attributes)
|
696
|
+
self.ship_address = Spree::Address.immutable_merge(ship_address, attributes)
|
696
697
|
end
|
697
698
|
|
698
|
-
def
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
699
|
+
def assign_default_addresses!
|
700
|
+
if user
|
701
|
+
# this is one of 2 places still using User#bill_address
|
702
|
+
self.bill_address ||= user.bill_address if user.bill_address.try!(:valid?)
|
703
|
+
# Skip setting ship address if order doesn't have a delivery checkout step
|
704
|
+
# to avoid triggering validations on shipping address
|
705
|
+
self.ship_address ||= user.ship_address if user.ship_address.try!(:valid?) && checkout_steps.include?("delivery")
|
706
|
+
end
|
707
|
+
end
|
704
708
|
|
705
|
-
|
706
|
-
|
709
|
+
def persist_user_address!
|
710
|
+
if !temporary_address && user && user.respond_to?(:persist_order_address) && bill_address_id
|
711
|
+
user.persist_order_address(self)
|
707
712
|
end
|
708
713
|
end
|
709
714
|
|
715
|
+
def add_payment_sources_to_wallet
|
716
|
+
Spree::Config.
|
717
|
+
add_payment_sources_to_wallet_class.new(self).
|
718
|
+
add_to_wallet
|
719
|
+
end
|
720
|
+
alias_method :persist_user_credit_card, :add_payment_sources_to_wallet
|
721
|
+
deprecate persist_user_credit_card: :add_payment_sources_to_wallet, deprecator: Spree::Deprecation
|
722
|
+
|
723
|
+
def add_default_payment_from_wallet
|
724
|
+
builder = Spree::Config.default_payment_builder_class.new(self)
|
725
|
+
|
726
|
+
if payment = builder.build
|
727
|
+
payments << payment
|
728
|
+
|
729
|
+
if bill_address.nil?
|
730
|
+
# this is one of 2 places still using User#bill_address
|
731
|
+
self.bill_address = payment.source.try(:address) ||
|
732
|
+
user.bill_address
|
733
|
+
end
|
734
|
+
end
|
735
|
+
end
|
736
|
+
alias_method :assign_default_credit_card, :add_default_payment_from_wallet
|
737
|
+
deprecate assign_default_credit_card: :add_default_payment_from_wallet, deprecator: Spree::Deprecation
|
738
|
+
|
710
739
|
private
|
711
740
|
|
741
|
+
def process_payments_before_complete
|
742
|
+
return if !payment_required?
|
743
|
+
|
744
|
+
if payments.valid.empty?
|
745
|
+
errors.add(:base, Spree.t(:no_payment_found))
|
746
|
+
return false
|
747
|
+
end
|
748
|
+
|
749
|
+
if process_payments!
|
750
|
+
true
|
751
|
+
else
|
752
|
+
saved_errors = errors[:base]
|
753
|
+
payment_failed!
|
754
|
+
saved_errors.each { |error| errors.add(:base, error) }
|
755
|
+
false
|
756
|
+
end
|
757
|
+
end
|
758
|
+
|
759
|
+
# In case a existing credit card is provided it needs to build the payment
|
760
|
+
# attributes from scratch so we can set the amount. example payload:
|
761
|
+
#
|
762
|
+
# {
|
763
|
+
# "order": {
|
764
|
+
# "existing_card": "2"
|
765
|
+
# }
|
766
|
+
# }
|
767
|
+
#
|
768
|
+
def update_params_payment_source
|
769
|
+
if @updating_params[:order] && (@updating_params[:order][:payments_attributes] || @updating_params[:order][:existing_card])
|
770
|
+
@updating_params[:order][:payments_attributes] ||= [{}]
|
771
|
+
@updating_params[:order][:payments_attributes].first[:amount] = total
|
772
|
+
end
|
773
|
+
end
|
774
|
+
|
712
775
|
def associate_store
|
713
776
|
self.store ||= Spree::Store.default
|
714
777
|
end
|
@@ -723,7 +786,7 @@ module Spree
|
|
723
786
|
end
|
724
787
|
|
725
788
|
def ensure_inventory_units
|
726
|
-
if
|
789
|
+
if has_checkout_step?("delivery")
|
727
790
|
inventory_validator = Spree::Stock::InventoryValidator.new
|
728
791
|
|
729
792
|
errors = line_items.map { |line_item| inventory_validator.validate(line_item) }.compact
|
@@ -732,9 +795,12 @@ module Spree
|
|
732
795
|
end
|
733
796
|
|
734
797
|
def ensure_promotions_eligible
|
735
|
-
|
736
|
-
|
798
|
+
adjustment_changed = all_adjustments.eligible.promotion.any? do |adjustment|
|
799
|
+
!adjustment.calculate_eligibility
|
800
|
+
end
|
801
|
+
if adjustment_changed
|
737
802
|
restart_checkout_flow
|
803
|
+
update!
|
738
804
|
errors.add(:base, Spree.t(:promotion_total_changed_before_complete))
|
739
805
|
end
|
740
806
|
errors.empty?
|
@@ -770,7 +836,7 @@ module Spree
|
|
770
836
|
end
|
771
837
|
|
772
838
|
def send_cancel_email
|
773
|
-
OrderMailer.cancel_email(self).deliver_later
|
839
|
+
Spree::OrderMailer.cancel_email(self).deliver_later
|
774
840
|
end
|
775
841
|
|
776
842
|
def after_resume
|
@@ -18,13 +18,13 @@ module Spree
|
|
18
18
|
def verify(shipment = nil)
|
19
19
|
if order.completed? || shipment.present?
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
shipment
|
25
|
-
add_to_shipment(shipment,
|
26
|
-
elsif
|
27
|
-
remove(
|
21
|
+
existing_quantity = inventory_units.count
|
22
|
+
desired_quantity = line_item.quantity - existing_quantity
|
23
|
+
if desired_quantity > 0
|
24
|
+
shipment ||= determine_target_shipment
|
25
|
+
add_to_shipment(shipment, desired_quantity)
|
26
|
+
elsif desired_quantity < 0
|
27
|
+
remove(-desired_quantity, shipment)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -35,9 +35,7 @@ module Spree
|
|
35
35
|
|
36
36
|
private
|
37
37
|
|
38
|
-
def remove(
|
39
|
-
quantity = item_units.size - line_item.quantity
|
40
|
-
|
38
|
+
def remove(quantity, shipment = nil)
|
41
39
|
if shipment.present?
|
42
40
|
remove_from_shipment(shipment, quantity)
|
43
41
|
else
|
@@ -100,7 +98,9 @@ module Spree
|
|
100
98
|
removed_quantity += 1
|
101
99
|
end
|
102
100
|
|
103
|
-
|
101
|
+
if shipment.inventory_units.count.zero?
|
102
|
+
order.shipments.destroy(shipment)
|
103
|
+
end
|
104
104
|
|
105
105
|
# removing this from shipment, and adding to stock_location
|
106
106
|
if order.completed?
|
@@ -14,17 +14,10 @@ module Spree
|
|
14
14
|
# Assign the attributes to the order and save the order
|
15
15
|
# @return true if saved, otherwise false and errors will be set on the order
|
16
16
|
def apply
|
17
|
-
order.validate_payments_attributes(@payments_attributes)
|
18
|
-
|
19
17
|
assign_order_attributes
|
20
18
|
assign_payments_attributes
|
21
19
|
|
22
|
-
|
23
|
-
order.set_shipments_cost if order.shipments.any?
|
24
|
-
true
|
25
|
-
else
|
26
|
-
false
|
27
|
-
end
|
20
|
+
order.save
|
28
21
|
end
|
29
22
|
|
30
23
|
private
|
@@ -17,6 +17,7 @@ module Spree
|
|
17
17
|
def update
|
18
18
|
@order.transaction do
|
19
19
|
update_item_count
|
20
|
+
update_shipment_amounts
|
20
21
|
update_totals
|
21
22
|
if order.completed?
|
22
23
|
update_payment_state
|
@@ -32,6 +33,65 @@ module Spree
|
|
32
33
|
update_hooks.each { |hook| order.send hook }
|
33
34
|
end
|
34
35
|
|
36
|
+
# Updates the +shipment_state+ attribute according to the following logic:
|
37
|
+
#
|
38
|
+
# shipped when all Shipments are in the "shipped" state
|
39
|
+
# partial when at least one Shipment has a state of "shipped" and there is another Shipment with a state other than "shipped"
|
40
|
+
# or there are InventoryUnits associated with the order that have a state of "sold" but are not associated with a Shipment.
|
41
|
+
# ready when all Shipments are in the "ready" state
|
42
|
+
# backorder when there is backordered inventory associated with an order
|
43
|
+
# pending when all Shipments are in the "pending" state
|
44
|
+
#
|
45
|
+
# The +shipment_state+ value helps with reporting, etc. since it provides a quick and easy way to locate Orders needing attention.
|
46
|
+
def update_shipment_state
|
47
|
+
if order.backordered?
|
48
|
+
order.shipment_state = 'backorder'
|
49
|
+
else
|
50
|
+
# get all the shipment states for this order
|
51
|
+
shipment_states = shipments.states
|
52
|
+
if shipment_states.size > 1
|
53
|
+
# multiple shiment states means it's most likely partially shipped
|
54
|
+
order.shipment_state = 'partial'
|
55
|
+
else
|
56
|
+
# will return nil if no shipments are found
|
57
|
+
order.shipment_state = shipment_states.first
|
58
|
+
# TODO: inventory unit states?
|
59
|
+
# if order.shipment_state && order.inventory_units.where(:shipment_id => nil).exists?
|
60
|
+
# shipments exist but there are unassigned inventory units
|
61
|
+
# order.shipment_state = 'partial'
|
62
|
+
# end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
order.state_changed('shipment')
|
67
|
+
order.shipment_state
|
68
|
+
end
|
69
|
+
|
70
|
+
# Updates the +payment_state+ attribute according to the following logic:
|
71
|
+
#
|
72
|
+
# paid when +payment_total+ is equal to +total+
|
73
|
+
# balance_due when +payment_total+ is less than +total+
|
74
|
+
# credit_owed when +payment_total+ is greater than +total+
|
75
|
+
# failed when most recent payment is in the failed state
|
76
|
+
#
|
77
|
+
# The +payment_state+ value helps with reporting, etc. since it provides a quick and easy way to locate Orders needing attention.
|
78
|
+
def update_payment_state
|
79
|
+
last_state = order.payment_state
|
80
|
+
if payments.present? && payments.valid.size == 0 && order.outstanding_balance != 0
|
81
|
+
order.payment_state = 'failed'
|
82
|
+
elsif order.state == 'canceled' && order.payment_total == 0
|
83
|
+
order.payment_state = 'void'
|
84
|
+
else
|
85
|
+
order.payment_state = 'balance_due' if order.outstanding_balance > 0
|
86
|
+
order.payment_state = 'credit_owed' if order.outstanding_balance < 0
|
87
|
+
order.payment_state = 'paid' if !order.outstanding_balance?
|
88
|
+
end
|
89
|
+
order.state_changed('payment') if last_state != order.payment_state
|
90
|
+
order.payment_state
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
35
95
|
# This will update and select the best promotion adjustment, update tax
|
36
96
|
# adjustments, update cancellation adjustments, and then update the total
|
37
97
|
# fields (promo_total, included_tax_total, additional_tax_total, and
|
@@ -64,13 +124,16 @@ module Spree
|
|
64
124
|
update_adjustment_total
|
65
125
|
end
|
66
126
|
|
127
|
+
def update_shipment_amounts
|
128
|
+
shipments.each do |shipment|
|
129
|
+
shipment.update_amounts
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
67
133
|
# give each of the shipments a chance to update themselves
|
68
134
|
def update_shipments
|
69
135
|
shipments.each do |shipment|
|
70
|
-
next unless shipment.persisted?
|
71
136
|
shipment.update!(order)
|
72
|
-
shipment.refresh_rates
|
73
|
-
shipment.update_amounts
|
74
137
|
end
|
75
138
|
end
|
76
139
|
|
@@ -102,7 +165,7 @@ module Spree
|
|
102
165
|
end
|
103
166
|
|
104
167
|
def update_item_count
|
105
|
-
order.item_count = quantity
|
168
|
+
order.item_count = line_items.to_a.sum(&:quantity)
|
106
169
|
end
|
107
170
|
|
108
171
|
def update_item_total
|
@@ -114,65 +177,6 @@ module Spree
|
|
114
177
|
order.save!(validate: false)
|
115
178
|
end
|
116
179
|
|
117
|
-
# Updates the +shipment_state+ attribute according to the following logic:
|
118
|
-
#
|
119
|
-
# shipped when all Shipments are in the "shipped" state
|
120
|
-
# partial when at least one Shipment has a state of "shipped" and there is another Shipment with a state other than "shipped"
|
121
|
-
# or there are InventoryUnits associated with the order that have a state of "sold" but are not associated with a Shipment.
|
122
|
-
# ready when all Shipments are in the "ready" state
|
123
|
-
# backorder when there is backordered inventory associated with an order
|
124
|
-
# pending when all Shipments are in the "pending" state
|
125
|
-
#
|
126
|
-
# The +shipment_state+ value helps with reporting, etc. since it provides a quick and easy way to locate Orders needing attention.
|
127
|
-
def update_shipment_state
|
128
|
-
if order.backordered?
|
129
|
-
order.shipment_state = 'backorder'
|
130
|
-
else
|
131
|
-
# get all the shipment states for this order
|
132
|
-
shipment_states = shipments.states
|
133
|
-
if shipment_states.size > 1
|
134
|
-
# multiple shiment states means it's most likely partially shipped
|
135
|
-
order.shipment_state = 'partial'
|
136
|
-
else
|
137
|
-
# will return nil if no shipments are found
|
138
|
-
order.shipment_state = shipment_states.first
|
139
|
-
# TODO: inventory unit states?
|
140
|
-
# if order.shipment_state && order.inventory_units.where(:shipment_id => nil).exists?
|
141
|
-
# shipments exist but there are unassigned inventory units
|
142
|
-
# order.shipment_state = 'partial'
|
143
|
-
# end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
order.state_changed('shipment')
|
148
|
-
order.shipment_state
|
149
|
-
end
|
150
|
-
|
151
|
-
# Updates the +payment_state+ attribute according to the following logic:
|
152
|
-
#
|
153
|
-
# paid when +payment_total+ is equal to +total+
|
154
|
-
# balance_due when +payment_total+ is less than +total+
|
155
|
-
# credit_owed when +payment_total+ is greater than +total+
|
156
|
-
# failed when most recent payment is in the failed state
|
157
|
-
#
|
158
|
-
# The +payment_state+ value helps with reporting, etc. since it provides a quick and easy way to locate Orders needing attention.
|
159
|
-
def update_payment_state
|
160
|
-
last_state = order.payment_state
|
161
|
-
if payments.present? && payments.valid.size == 0 && order.outstanding_balance != 0
|
162
|
-
order.payment_state = 'failed'
|
163
|
-
elsif order.state == 'canceled' && order.payment_total == 0
|
164
|
-
order.payment_state = 'void'
|
165
|
-
else
|
166
|
-
order.payment_state = 'balance_due' if order.outstanding_balance > 0
|
167
|
-
order.payment_state = 'credit_owed' if order.outstanding_balance < 0
|
168
|
-
order.payment_state = 'paid' if !order.outstanding_balance?
|
169
|
-
end
|
170
|
-
order.state_changed('payment') if last_state != order.payment_state
|
171
|
-
order.payment_state
|
172
|
-
end
|
173
|
-
|
174
|
-
private
|
175
|
-
|
176
180
|
def round_money(n)
|
177
181
|
(n * 100).round / 100.0
|
178
182
|
end
|