spree_core 2.3.1 → 2.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/helpers/spree/base_helper.rb +3 -3
- data/app/models/spree/ability.rb +1 -0
- data/app/models/spree/app_configuration.rb +0 -1
- data/app/models/spree/base.rb +6 -0
- data/app/models/spree/calculator/flat_percent_item_total.rb +9 -3
- data/app/models/spree/calculator/flexi_rate.rb +1 -1
- data/app/models/spree/calculator/percent_on_line_item.rb +1 -1
- data/app/models/spree/calculator/tiered_flat_rate.rb +37 -0
- data/app/models/spree/calculator/tiered_percent.rb +44 -0
- data/app/models/spree/credit_card.rb +35 -14
- data/app/models/spree/inventory_unit.rb +1 -0
- data/app/models/spree/item_adjustments.rb +3 -2
- data/app/models/spree/line_item.rb +2 -2
- data/app/models/spree/order.rb +36 -20
- data/app/models/spree/order/checkout.rb +60 -24
- data/app/models/spree/order_contents.rb +3 -6
- data/app/models/spree/order_populator.rb +1 -1
- data/app/models/spree/order_updater.rb +19 -4
- data/app/models/spree/payment.rb +4 -0
- data/app/models/spree/payment/processing.rb +6 -2
- data/app/models/spree/price.rb +10 -0
- data/app/models/spree/product.rb +81 -54
- data/app/models/spree/promotion/actions/create_adjustment.rb +2 -11
- data/app/models/spree/promotion/actions/create_item_adjustments.rb +2 -19
- data/app/models/spree/promotion_handler/cart.rb +14 -2
- data/app/models/spree/promotion_handler/coupon.rb +8 -2
- data/app/models/spree/return_authorization.rb +2 -2
- data/app/models/spree/shipping_rate.rb +2 -2
- data/app/models/spree/stock/availability_validator.rb +3 -7
- data/app/models/spree/stock/estimator.rb +1 -1
- data/app/models/spree/stock/package.rb +1 -0
- data/app/models/spree/stock_item.rb +6 -1
- data/app/models/spree/stock_location.rb +4 -0
- data/app/models/spree/tax_rate.rb +15 -2
- data/app/models/spree/variant.rb +8 -3
- data/app/models/spree/zone.rb +2 -2
- data/config/locales/en.yml +33 -3
- data/db/default/spree/countries.rb +2 -1
- data/db/migrate/20130807024302_rename_adjustment_fields.rb +2 -5
- data/db/migrate/20140804185157_add_default_to_shipment_cost.rb +10 -0
- data/lib/generators/spree/custom_user/templates/authentication_helpers.rb.tt +12 -4
- data/lib/generators/spree/install/install_generator.rb +8 -0
- data/lib/spree/core.rb +1 -0
- data/lib/spree/core/adjustment_source.rb +26 -0
- data/lib/spree/core/controller_helpers.rb +10 -9
- data/lib/spree/core/controller_helpers/order.rb +18 -5
- data/lib/spree/core/engine.rb +6 -2
- data/lib/spree/core/importer/order.rb +52 -9
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/permitted_attributes.rb +4 -4
- data/lib/spree/testing_support/authorization_helpers.rb +1 -1
- data/lib/spree/testing_support/factories/product_factory.rb +1 -1
- metadata +27 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b7bfe527c1516e5d8393c4cb6a23bf795bff2f8d
|
4
|
+
data.tar.gz: dd9c6e528157dd843740ff2cd5bc86d6fa906192
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0fb13c6c497d8ab9d920e6f950a532e16524f305e2591e82b12bd1ae1aa47d53f2a8ca0fd293d588c8b8ed32d3bac49c2a2cfef851a1ba9b237b7149994c9f60
|
7
|
+
data.tar.gz: 5ea8cacb10c49bf4afaa936a9ae348d13979a1f30855214e491aff0abf9ca9ba3f495f7d38c295a1266b4be9ab26e5adbf47c5dc464b72fc0555b2fc2740f1d8
|
@@ -68,10 +68,10 @@ module Spree
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def flash_messages(opts = {})
|
71
|
-
|
71
|
+
ignore_types = ["order_completed"].concat(Array(opts[:ignore_types]).map(&:to_s) || [])
|
72
72
|
|
73
73
|
flash.each do |msg_type, text|
|
74
|
-
unless
|
74
|
+
unless ignore_types.include?(msg_type)
|
75
75
|
concat(content_tag :div, text, class: "flash #{msg_type}")
|
76
76
|
end
|
77
77
|
end
|
@@ -118,7 +118,7 @@ module Spree
|
|
118
118
|
countries.collect do |country|
|
119
119
|
country.name = Spree.t(country.iso, scope: 'country_names', default: country.name)
|
120
120
|
country
|
121
|
-
end.
|
121
|
+
end.sort_by { |c| c.name.parameterize }
|
122
122
|
end
|
123
123
|
|
124
124
|
def seo_url(taxon)
|
data/app/models/spree/ability.rb
CHANGED
@@ -57,7 +57,6 @@ module Spree
|
|
57
57
|
preference :promotions_per_page, :integer, default: 15
|
58
58
|
preference :redirect_https_to_http, :boolean, :default => false
|
59
59
|
preference :require_master_price, :boolean, default: true
|
60
|
-
preference :shipment_inc_vat, :boolean, default: false
|
61
60
|
preference :shipping_instructions, :boolean, default: false # Request instructions/info for shipping
|
62
61
|
preference :show_only_complete_orders_by_default, :boolean, default: true
|
63
62
|
preference :show_variant_full_price, :boolean, default: false #Displays variant full price or difference with product price. Default false to be compatible with older behavior
|
data/app/models/spree/base.rb
CHANGED
@@ -5,5 +5,11 @@ class Spree::Base < ActiveRecord::Base
|
|
5
5
|
self.preferences = default_preferences.merge(preferences) if has_attribute?(:preferences)
|
6
6
|
end
|
7
7
|
|
8
|
+
if Kaminari.config.page_method_name != :page
|
9
|
+
def self.page num
|
10
|
+
send Kaminari.config.page_method_name, num
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
8
14
|
self.abstract_class = true
|
9
15
|
end
|
@@ -8,9 +8,15 @@ module Spree
|
|
8
8
|
Spree.t(:flat_percent)
|
9
9
|
end
|
10
10
|
|
11
|
-
def compute(
|
12
|
-
|
13
|
-
|
11
|
+
def compute(object)
|
12
|
+
computed_amount = (object.amount * preferred_flat_percent / 100).round(2)
|
13
|
+
|
14
|
+
# We don't want to cause the promotion adjustments to push the order into a negative total.
|
15
|
+
if computed_amount > object.amount
|
16
|
+
object.amount
|
17
|
+
else
|
18
|
+
computed_amount
|
19
|
+
end
|
14
20
|
end
|
15
21
|
end
|
16
22
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require_dependency 'spree/calculator'
|
2
|
+
|
3
|
+
module Spree
|
4
|
+
class Calculator::TieredFlatRate < Calculator
|
5
|
+
preference :base_amount, :decimal, default: 0
|
6
|
+
preference :tiers, :hash, default: {}
|
7
|
+
|
8
|
+
before_validation do
|
9
|
+
# Convert tier values to decimals. Strings don't do us much good.
|
10
|
+
if preferred_tiers.is_a?(Hash)
|
11
|
+
self.preferred_tiers = Hash[*preferred_tiers.flatten.map(&:to_f)]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
validate :preferred_tiers_content
|
16
|
+
|
17
|
+
def self.description
|
18
|
+
Spree.t(:tiered_flat_rate)
|
19
|
+
end
|
20
|
+
|
21
|
+
def compute(object)
|
22
|
+
base, amount = preferred_tiers.sort.reverse.detect{ |b,_| object.amount >= b }
|
23
|
+
amount || preferred_base_amount
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def preferred_tiers_content
|
28
|
+
if preferred_tiers.is_a? Hash
|
29
|
+
unless preferred_tiers.keys.all?{ |k| k.is_a?(Numeric) && k > 0 }
|
30
|
+
errors.add(:base, :keys_should_be_positive_number)
|
31
|
+
end
|
32
|
+
else
|
33
|
+
errors.add(:preferred_tiers, :should_be_hash)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require_dependency 'spree/calculator'
|
2
|
+
|
3
|
+
module Spree
|
4
|
+
class Calculator::TieredPercent < Calculator
|
5
|
+
preference :base_percent, :decimal, default: 0
|
6
|
+
preference :tiers, :hash, default: {}
|
7
|
+
|
8
|
+
before_validation do
|
9
|
+
# Convert tier values to decimals. Strings don't do us much good.
|
10
|
+
if preferred_tiers.is_a?(Hash)
|
11
|
+
self.preferred_tiers = Hash[*preferred_tiers.flatten.map(&:to_f)]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
validates :preferred_base_percent, numericality: {
|
16
|
+
greater_than_or_equal_to: 0,
|
17
|
+
less_than_or_equal_to: 100
|
18
|
+
}
|
19
|
+
validate :preferred_tiers_content
|
20
|
+
|
21
|
+
def self.description
|
22
|
+
Spree.t(:tiered_percent)
|
23
|
+
end
|
24
|
+
|
25
|
+
def compute(object)
|
26
|
+
base, percent = preferred_tiers.sort.reverse.detect{ |b,_| object.amount >= b }
|
27
|
+
(object.amount * (percent || preferred_base_percent) / 100).round(2)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
def preferred_tiers_content
|
32
|
+
if preferred_tiers.is_a? Hash
|
33
|
+
unless preferred_tiers.keys.all?{ |k| k.is_a?(Numeric) && k > 0 }
|
34
|
+
errors.add(:base, :keys_should_be_positive_number)
|
35
|
+
end
|
36
|
+
unless preferred_tiers.values.all?{ |k| k.is_a?(Numeric) && k >= 0 && k <= 100 }
|
37
|
+
errors.add(:base, :values_should_be_percent)
|
38
|
+
end
|
39
|
+
else
|
40
|
+
errors.add(:preferred_tiers, :should_be_hash)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -3,14 +3,17 @@ module Spree
|
|
3
3
|
belongs_to :payment_method
|
4
4
|
has_many :payments, as: :source
|
5
5
|
|
6
|
-
|
6
|
+
before_create :set_missing_info
|
7
7
|
|
8
|
-
attr_accessor :
|
8
|
+
attr_accessor :encrypted_data,
|
9
|
+
:number,
|
10
|
+
:imported,
|
11
|
+
:verification_value
|
9
12
|
|
10
13
|
validates :month, :year, numericality: { only_integer: true }, if: :require_card_numbers?, on: :create
|
11
|
-
validates :number, presence: true, if: :require_card_numbers?, on: :create
|
14
|
+
validates :number, presence: true, if: :require_card_numbers?, on: :create, unless: :imported
|
12
15
|
validates :name, presence: true, if: :require_card_numbers?, on: :create
|
13
|
-
validates :verification_value, presence: true, if: :require_card_numbers?, on: :create
|
16
|
+
validates :verification_value, presence: true, if: :require_card_numbers?, on: :create, unless: :imported
|
14
17
|
|
15
18
|
validate :expiry_not_in_the_past
|
16
19
|
|
@@ -60,12 +63,6 @@ module Spree
|
|
60
63
|
end
|
61
64
|
end
|
62
65
|
|
63
|
-
def set_last_digits
|
64
|
-
number.to_s.gsub!(/\s/,'')
|
65
|
-
verification_value.to_s.gsub!(/\s/,'')
|
66
|
-
self.last_digits ||= number.to_s.length <= 4 ? number : number.to_s.slice(-4..-1)
|
67
|
-
end
|
68
|
-
|
69
66
|
def try_type_from_number
|
70
67
|
numbers = number.delete(' ') if number
|
71
68
|
CARD_TYPES.find{|type, pattern| return type.to_s if numbers =~ pattern}.to_s
|
@@ -91,7 +88,7 @@ module Spree
|
|
91
88
|
|
92
89
|
# Indicates whether its possible to void the payment.
|
93
90
|
def can_void?(payment)
|
94
|
-
!payment.void?
|
91
|
+
!payment.failed? && !payment.void?
|
95
92
|
end
|
96
93
|
|
97
94
|
# Indicates whether its possible to credit the payment. Note that most gateways require that the
|
@@ -132,9 +129,13 @@ module Spree
|
|
132
129
|
|
133
130
|
def expiry_not_in_the_past
|
134
131
|
if year.present? && month.present?
|
135
|
-
|
136
|
-
|
137
|
-
|
132
|
+
if month.to_i < 1 || month.to_i > 12
|
133
|
+
errors.add(:base, :expiry_invalid)
|
134
|
+
else
|
135
|
+
time = Time.zone.parse("#{year}-#{month}-1")
|
136
|
+
if time < Time.zone.now.to_time.beginning_of_month
|
137
|
+
errors.add(:base, :card_expired)
|
138
|
+
end
|
138
139
|
end
|
139
140
|
end
|
140
141
|
end
|
@@ -142,5 +143,25 @@ module Spree
|
|
142
143
|
def require_card_numbers?
|
143
144
|
!self.encrypted_data.present? && !self.has_payment_profile?
|
144
145
|
end
|
146
|
+
|
147
|
+
def set_last_digits
|
148
|
+
number.to_s.gsub!(/\s/,'')
|
149
|
+
verification_value.to_s.gsub!(/\s/,'')
|
150
|
+
self.last_digits ||= number.to_s.length <= 4 ? number : number.to_s.slice(-4..-1)
|
151
|
+
end
|
152
|
+
|
153
|
+
def set_missing_info
|
154
|
+
set_last_digits
|
155
|
+
if has_payment_profile?
|
156
|
+
if matching_card = self.class.where(gateway_customer_profile_id: self.gateway_customer_profile_id, gateway_payment_profile_id: self.gateway_payment_profile_id).first
|
157
|
+
self.cc_type = matching_card.cc_type
|
158
|
+
self.last_digits = matching_card.last_digits
|
159
|
+
self.month = matching_card.month
|
160
|
+
self.name = matching_card.name
|
161
|
+
self.year = matching_card.year
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
145
166
|
end
|
146
167
|
end
|
@@ -47,8 +47,9 @@ module Spree
|
|
47
47
|
included_tax_total = 0
|
48
48
|
additional_tax_total = 0
|
49
49
|
run_callbacks :tax_adjustments do
|
50
|
-
|
51
|
-
|
50
|
+
tax = (item.respond_to?(:all_adjustments) ? item.all_adjustments : item.adjustments).tax
|
51
|
+
included_tax_total = tax.included.reload.map(&:update!).compact.sum
|
52
|
+
additional_tax_total = tax.additional.reload.map(&:update!).compact.sum
|
52
53
|
end
|
53
54
|
|
54
55
|
item.update_columns(
|
@@ -97,7 +97,7 @@ module Spree
|
|
97
97
|
|
98
98
|
private
|
99
99
|
def update_inventory
|
100
|
-
if changed? || target_shipment.present?
|
100
|
+
if (changed? || target_shipment.present?) && self.order.has_checkout_step?("delivery")
|
101
101
|
Spree::OrderInventory.new(self.order, self).verify(target_shipment)
|
102
102
|
end
|
103
103
|
end
|
@@ -119,7 +119,7 @@ module Spree
|
|
119
119
|
|
120
120
|
def ensure_proper_currency
|
121
121
|
unless currency == order.currency
|
122
|
-
errors.add(:currency,
|
122
|
+
errors.add(:currency, :must_match_order_currency)
|
123
123
|
end
|
124
124
|
end
|
125
125
|
end
|
data/app/models/spree/order.rb
CHANGED
@@ -3,25 +3,20 @@ require 'spree/order/checkout'
|
|
3
3
|
|
4
4
|
module Spree
|
5
5
|
class Order < Spree::Base
|
6
|
-
include Checkout
|
7
|
-
include CurrencyUpdater
|
6
|
+
include Spree::Order::Checkout
|
7
|
+
include Spree::Order::CurrencyUpdater
|
8
8
|
|
9
9
|
checkout_flow do
|
10
10
|
go_to_state :address
|
11
11
|
go_to_state :delivery
|
12
|
-
go_to_state :payment, if: ->(order)
|
13
|
-
# TODO there should be a better fix work around for the issues this is
|
14
|
-
# resolving we shouldn't be setting shipments cost every time a order
|
15
|
-
# object is loaded
|
16
|
-
order.set_shipments_cost if order.shipments.any?
|
17
|
-
order.payment_required?
|
18
|
-
end
|
12
|
+
go_to_state :payment, if: ->(order) { order.payment_required? }
|
19
13
|
go_to_state :confirm, if: ->(order) { order.confirmation_required? }
|
20
14
|
go_to_state :complete
|
21
15
|
remove_transition from: :delivery, to: :confirm
|
22
16
|
end
|
23
17
|
|
24
18
|
attr_reader :coupon_code
|
19
|
+
attr_accessor :temporary_address
|
25
20
|
|
26
21
|
if Spree.user_class
|
27
22
|
belongs_to :user, class_name: Spree.user_class.to_s
|
@@ -79,6 +74,7 @@ module Spree
|
|
79
74
|
|
80
75
|
validates :email, presence: true, if: :require_email
|
81
76
|
validates :email, email: true, if: :require_email, allow_blank: true
|
77
|
+
validates :number, uniqueness: true
|
82
78
|
validate :has_available_shipment
|
83
79
|
|
84
80
|
make_permalink field: :number
|
@@ -95,6 +91,8 @@ module Spree
|
|
95
91
|
scope :created_between, ->(start_date, end_date) { where(created_at: start_date..end_date) }
|
96
92
|
scope :completed_between, ->(start_date, end_date) { where(completed_at: start_date..end_date) }
|
97
93
|
|
94
|
+
scope :reverse_chronological, -> { order(created_at: :desc) }
|
95
|
+
|
98
96
|
def self.by_customer(customer)
|
99
97
|
joins(:user).where("#{Spree.user_class.table_name}.email" => customer)
|
100
98
|
end
|
@@ -258,15 +256,18 @@ module Spree
|
|
258
256
|
end
|
259
257
|
end
|
260
258
|
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
259
|
+
def generate_order_number(digits = 9)
|
260
|
+
self.number ||= loop do
|
261
|
+
# Make a random number.
|
262
|
+
random = "R#{Array.new(digits){rand(10)}.join}"
|
263
|
+
# Use the random number if no other order exists with it.
|
264
|
+
if self.class.exists?(number: random)
|
265
|
+
# If over half of all possible options are taken add another digit.
|
266
|
+
digits += 1 if self.class.count > (10 ** digits / 2)
|
267
|
+
else
|
268
|
+
break random
|
269
|
+
end
|
270
|
+
end
|
270
271
|
end
|
271
272
|
|
272
273
|
def shipped_shipments
|
@@ -296,7 +297,11 @@ module Spree
|
|
296
297
|
end
|
297
298
|
|
298
299
|
def outstanding_balance
|
299
|
-
|
300
|
+
if self.state == 'canceled' && self.payments.present? && self.payments.completed.size > 0
|
301
|
+
-1 * payment_total
|
302
|
+
else
|
303
|
+
total - payment_total
|
304
|
+
end
|
300
305
|
end
|
301
306
|
|
302
307
|
def outstanding_balance?
|
@@ -403,6 +408,12 @@ module Spree
|
|
403
408
|
line_items.select(&:insufficient_stock?)
|
404
409
|
end
|
405
410
|
|
411
|
+
def ensure_line_items_are_in_stock
|
412
|
+
if insufficient_stock_lines.present?
|
413
|
+
errors.add(:base, Spree.t(:insufficient_stock_lines_present)) and return false
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
406
417
|
def merge!(order, user = nil)
|
407
418
|
order.line_items.each do |line_item|
|
408
419
|
next unless line_item.currency == currency
|
@@ -572,7 +583,7 @@ module Spree
|
|
572
583
|
self.ensure_updated_shipments
|
573
584
|
end
|
574
585
|
|
575
|
-
def reload
|
586
|
+
def reload(options=nil)
|
576
587
|
remove_instance_variable(:@tax_zone) if defined?(@tax_zone)
|
577
588
|
super
|
578
589
|
end
|
@@ -581,6 +592,10 @@ module Spree
|
|
581
592
|
included_tax_total + additional_tax_total
|
582
593
|
end
|
583
594
|
|
595
|
+
def quantity
|
596
|
+
line_items.sum(:quantity)
|
597
|
+
end
|
598
|
+
|
584
599
|
private
|
585
600
|
|
586
601
|
def link_by_email
|
@@ -620,6 +635,7 @@ module Spree
|
|
620
635
|
|
621
636
|
send_cancel_email
|
622
637
|
self.update_column(:payment_state, 'credit_owed') unless shipped?
|
638
|
+
self.update!
|
623
639
|
end
|
624
640
|
|
625
641
|
def send_cancel_email
|
@@ -38,8 +38,8 @@ module Spree
|
|
38
38
|
# To avoid multiple occurrences of the same transition being defined
|
39
39
|
# On first definition, state_machines will not be defined
|
40
40
|
state_machines.clear if respond_to?(:state_machines)
|
41
|
-
state_machine :state, :
|
42
|
-
klass.next_event_transitions.each { |t| transition(t.merge(:
|
41
|
+
state_machine :state, initial: :cart, use_transactions: false, action: :save_state do
|
42
|
+
klass.next_event_transitions.each { |t| transition(t.merge(on: :next)) }
|
43
43
|
|
44
44
|
# Persist the state on the order
|
45
45
|
after_transition do |order, transition|
|
@@ -54,23 +54,23 @@ module Spree
|
|
54
54
|
end
|
55
55
|
|
56
56
|
event :cancel do
|
57
|
-
transition :
|
57
|
+
transition to: :canceled, if: :allow_cancel?
|
58
58
|
end
|
59
59
|
|
60
60
|
event :return do
|
61
|
-
transition :
|
61
|
+
transition to: :returned, from: :awaiting_return, unless: :awaiting_returns?
|
62
62
|
end
|
63
63
|
|
64
64
|
event :resume do
|
65
|
-
transition :
|
65
|
+
transition to: :resumed, from: :canceled, if: :canceled?
|
66
66
|
end
|
67
67
|
|
68
68
|
event :authorize_return do
|
69
|
-
transition :
|
69
|
+
transition to: :awaiting_return
|
70
70
|
end
|
71
71
|
|
72
72
|
if states[:payment]
|
73
|
-
before_transition :
|
73
|
+
before_transition to: :complete do |order|
|
74
74
|
if order.payment_required? && order.payments.empty?
|
75
75
|
order.errors.add(:base, Spree.t(:no_payment_found))
|
76
76
|
false
|
@@ -80,28 +80,32 @@ module Spree
|
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
|
-
before_transition :
|
83
|
+
before_transition from: :cart, do: :ensure_line_items_present
|
84
84
|
|
85
85
|
if states[:address]
|
86
|
-
before_transition :
|
86
|
+
before_transition from: :address, do: :create_tax_charge!
|
87
|
+
before_transition to: :address, do: :assign_default_addresses!
|
88
|
+
before_transition from: :address, do: :persist_user_address!
|
87
89
|
end
|
88
90
|
|
89
91
|
if states[:payment]
|
90
|
-
before_transition :
|
91
|
-
before_transition :
|
92
|
+
before_transition to: :payment, do: :set_shipments_cost
|
93
|
+
before_transition to: :payment, do: :create_tax_charge!
|
92
94
|
end
|
93
95
|
|
94
96
|
if states[:delivery]
|
95
|
-
before_transition :
|
96
|
-
before_transition :
|
97
|
-
before_transition :
|
97
|
+
before_transition to: :delivery, do: :create_proposed_shipments
|
98
|
+
before_transition to: :delivery, do: :ensure_available_shipping_rates
|
99
|
+
before_transition from: :delivery, do: :apply_free_shipping_promotions
|
98
100
|
end
|
99
101
|
|
100
|
-
|
101
|
-
after_transition :to => :resumed, :do => :after_resume
|
102
|
-
after_transition :to => :canceled, :do => :after_cancel
|
102
|
+
before_transition to: :resumed, do: :ensure_line_items_are_in_stock
|
103
103
|
|
104
|
-
after_transition :
|
104
|
+
after_transition to: :complete, do: :finalize!
|
105
|
+
after_transition to: :resumed, do: :after_resume
|
106
|
+
after_transition to: :canceled, do: :after_cancel
|
107
|
+
|
108
|
+
after_transition from: any - :cart, to: any - [:confirm, :complete] do |order|
|
105
109
|
order.update_totals
|
106
110
|
order.persist_totals
|
107
111
|
end
|
@@ -113,7 +117,7 @@ module Spree
|
|
113
117
|
def self.go_to_state(name, options={})
|
114
118
|
self.checkout_steps[name] = options
|
115
119
|
previous_states.each do |state|
|
116
|
-
add_transition({:
|
120
|
+
add_transition({from: state, to: name}.merge(options))
|
117
121
|
end
|
118
122
|
if options[:if]
|
119
123
|
self.previous_states << name
|
@@ -217,12 +221,17 @@ module Spree
|
|
217
221
|
success = false
|
218
222
|
@updating_params = params
|
219
223
|
run_callbacks :updating_from_params do
|
220
|
-
attributes = @updating_params[:order] ? @updating_params[:order].permit(permitted_params) : {}
|
224
|
+
attributes = @updating_params[:order] ? @updating_params[:order].permit(permitted_params).delete_if { |k,v| v.nil? } : {}
|
221
225
|
|
222
226
|
# Set existing card after setting permitted parameters because
|
223
227
|
# rails would slice parameters containg ruby objects, apparently
|
224
|
-
|
225
|
-
|
228
|
+
#
|
229
|
+
# Need to check both outside and inside :order beacuse frontend
|
230
|
+
# sends existing_card out of :order
|
231
|
+
existing_card_id = @updating_params[:existing_card] || (@updating_params[:order] ? @updating_params[:order][:existing_card] : nil)
|
232
|
+
|
233
|
+
if existing_card_id.present?
|
234
|
+
credit_card = CreditCard.find existing_card_id
|
226
235
|
if credit_card.user_id != self.user_id || credit_card.user_id.blank?
|
227
236
|
raise Core::GatewayError.new Spree.t(:invalid_credit_card)
|
228
237
|
end
|
@@ -239,27 +248,54 @@ module Spree
|
|
239
248
|
end
|
240
249
|
|
241
250
|
success = self.update_attributes(attributes)
|
251
|
+
set_shipments_cost if self.shipments.any?
|
242
252
|
end
|
243
253
|
|
244
254
|
@updating_params = nil
|
245
255
|
success
|
246
256
|
end
|
247
257
|
|
258
|
+
def assign_default_addresses!
|
259
|
+
if self.user
|
260
|
+
self.bill_address = user.bill_address.try(:clone) if !self.bill_address_id && user.bill_address.try(:valid?)
|
261
|
+
# Skip setting ship address if order doesn't have a delivery checkout step
|
262
|
+
# to avoid triggering validations on shipping address
|
263
|
+
self.ship_address = user.ship_address.try(:clone) if !self.ship_address_id && user.ship_address.try(:valid?) && self.checkout_steps.include?("delivery")
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
def persist_user_address!
|
268
|
+
if !self.temporary_address && self.user && self.user.respond_to?(:persist_order_address) && self.bill_address_id
|
269
|
+
self.user.persist_order_address(self)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
248
273
|
private
|
249
274
|
# For payment step, filter order parameters to produce the expected nested
|
250
275
|
# attributes for a single payment and its source, discarding attributes
|
251
276
|
# for payment methods other than the one selected
|
277
|
+
#
|
278
|
+
# In case a existing credit card is provided it needs to build the payment
|
279
|
+
# attributes from scratch so we can set the amount. example payload:
|
280
|
+
#
|
281
|
+
# {
|
282
|
+
# "order": {
|
283
|
+
# "existing_card": "2"
|
284
|
+
# }
|
285
|
+
# }
|
286
|
+
#
|
252
287
|
def update_params_payment_source
|
253
288
|
if has_checkout_step?("payment") && self.payment?
|
254
289
|
if @updating_params[:payment_source].present?
|
255
|
-
source_params = @updating_params.delete(:payment_source)[@updating_params[:order][:payments_attributes].first[:payment_method_id].
|
290
|
+
source_params = @updating_params.delete(:payment_source)[@updating_params[:order][:payments_attributes].first[:payment_method_id].to_s]
|
256
291
|
|
257
292
|
if source_params
|
258
293
|
@updating_params[:order][:payments_attributes].first[:source_attributes] = source_params
|
259
294
|
end
|
260
295
|
end
|
261
296
|
|
262
|
-
if
|
297
|
+
if @updating_params[:order][:payments_attributes] || @updating_params[:order][:existing_card]
|
298
|
+
@updating_params[:order][:payments_attributes] ||= [{}]
|
263
299
|
@updating_params[:order][:payments_attributes].first[:amount] = self.total
|
264
300
|
end
|
265
301
|
end
|