spree_core 2.4.7 → 2.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/models/friendly_id/slug_decorator.rb +3 -0
- data/app/models/spree/adjustment.rb +1 -1
- data/app/models/spree/calculator.rb +5 -0
- data/app/models/spree/customer_return.rb +22 -16
- data/app/models/spree/gateway/bogus.rb +4 -0
- data/app/models/spree/order.rb +14 -41
- data/app/models/spree/order_contents.rb +7 -8
- data/app/models/spree/order_merger.rb +65 -0
- data/app/models/spree/order_updater.rb +0 -5
- data/app/models/spree/payment.rb +5 -0
- data/app/models/spree/payment/processing.rb +2 -1
- data/app/models/spree/product.rb +7 -1
- data/app/models/spree/promotion_handler/cart.rb +18 -14
- data/app/models/spree/promotion_handler/coupon.rb +1 -1
- data/app/models/spree/shipment.rb +1 -1
- data/app/models/spree/stock/availability_validator.rb +10 -6
- data/app/models/spree/stock_item.rb +5 -1
- data/app/models/spree/stock_movement.rb +6 -1
- data/app/models/spree/tax_rate.rb +5 -1
- data/app/models/spree/variant.rb +1 -6
- data/config/initializers/user_class_extensions.rb +4 -0
- data/config/locales/en.yml +1 -1
- data/db/migrate/20150515211137_fix_adjustment_order_id.rb +70 -0
- data/db/migrate/20150522181728_add_deleted_at_to_friendly_id_slugs.rb +6 -0
- data/db/migrate/20150707204155_enable_acts_as_paranoid_on_calculators.rb +6 -0
- data/lib/spree/core/engine.rb +7 -0
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/testing_support/factories/order_factory.rb +11 -0
- metadata +13 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7a4b6e2afb0968da8792da3d641cde6a8628eb48
|
4
|
+
data.tar.gz: c2c33ca5c66f6f1c4f2165b4e388f14d82884e91
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d115ad863b2eecbf62c10eca8635ad099eef6ed3228da587d6b17238e5f1da29664d7eea5ecca3fc579f599c697147d1d097f657bd1e9a0e7e02e44d80944931
|
7
|
+
data.tar.gz: 3999bfb8c5830d8ecdfccc20fa5921a4e358ee925348f71611c66272683526cdbe57ab9207c327471f50bb40e839d12f143859d1c9bda97bd6c17caaa7a87de1
|
@@ -24,7 +24,7 @@ module Spree
|
|
24
24
|
class Adjustment < Spree::Base
|
25
25
|
belongs_to :adjustable, polymorphic: true, touch: true
|
26
26
|
belongs_to :source, polymorphic: true
|
27
|
-
belongs_to :order, class_name:
|
27
|
+
belongs_to :order, class_name: 'Spree::Order', inverse_of: :all_adjustments
|
28
28
|
|
29
29
|
validates :adjustable, presence: true
|
30
30
|
validates :order, presence: true
|
@@ -1,5 +1,10 @@
|
|
1
1
|
module Spree
|
2
2
|
class Calculator < Spree::Base
|
3
|
+
# Conditional check for backwards compatibilty since acts as paranoid was added late https://github.com/spree/spree/issues/5858
|
4
|
+
if connection.table_exists?(:spree_calculators) && connection.column_exists?(:spree_calculators, :deleted_at)
|
5
|
+
acts_as_paranoid
|
6
|
+
end
|
7
|
+
|
3
8
|
belongs_to :calculable, polymorphic: true
|
4
9
|
|
5
10
|
# This method calls a compute_<computable> method. must be overriden in concrete calculator.
|
@@ -2,21 +2,27 @@ module Spree
|
|
2
2
|
class CustomerReturn < Spree::Base
|
3
3
|
belongs_to :stock_location
|
4
4
|
|
5
|
-
has_many :return_items, inverse_of: :customer_return
|
6
|
-
has_many :return_authorizations, through: :return_items
|
7
5
|
has_many :reimbursements, inverse_of: :customer_return
|
6
|
+
has_many :return_authorizations, through: :return_items
|
7
|
+
has_many :return_items, inverse_of: :customer_return
|
8
8
|
|
9
9
|
after_create :process_return!
|
10
10
|
before_create :generate_number
|
11
11
|
|
12
12
|
validates :return_items, presence: true
|
13
13
|
validates :stock_location, presence: true
|
14
|
+
|
15
|
+
validate :must_have_return_authorization, on: :create
|
14
16
|
validate :return_items_belong_to_same_order
|
15
17
|
|
16
18
|
accepts_nested_attributes_for :return_items
|
17
19
|
|
18
|
-
def
|
19
|
-
return_items.
|
20
|
+
def completely_decided?
|
21
|
+
!return_items.undecided.exists?
|
22
|
+
end
|
23
|
+
|
24
|
+
def fully_reimbursed?
|
25
|
+
completely_decided? && return_items.accepted.includes(:reimbursement).all? { |return_item| return_item.reimbursement.try(:reimbursed?) }
|
20
26
|
end
|
21
27
|
|
22
28
|
def display_pre_tax_total
|
@@ -33,15 +39,21 @@ module Spree
|
|
33
39
|
order.try(:id)
|
34
40
|
end
|
35
41
|
|
36
|
-
def
|
37
|
-
|
42
|
+
def pre_tax_total
|
43
|
+
return_items.sum(:pre_tax_amount)
|
38
44
|
end
|
39
45
|
|
40
|
-
|
41
|
-
|
46
|
+
private
|
47
|
+
|
48
|
+
def inventory_units
|
49
|
+
return_items.flat_map(&:inventory_unit)
|
42
50
|
end
|
43
51
|
|
44
|
-
|
52
|
+
def must_have_return_authorization
|
53
|
+
if item = return_items.find { |ri| ri.return_authorization.blank? }
|
54
|
+
errors.add(:base, Spree.t(:missing_return_authorization, item_name: item.inventory_unit.variant.name))
|
55
|
+
end
|
56
|
+
end
|
45
57
|
|
46
58
|
def generate_number
|
47
59
|
self.number ||= loop do
|
@@ -56,15 +68,9 @@ module Spree
|
|
56
68
|
end
|
57
69
|
|
58
70
|
def return_items_belong_to_same_order
|
59
|
-
if return_items.select{ |return_item| return_item.inventory_unit.order_id != order_id }.any?
|
71
|
+
if return_items.select { |return_item| return_item.inventory_unit.order_id != order_id }.any?
|
60
72
|
errors.add(:base, Spree.t(:return_items_cannot_be_associated_with_multiple_orders))
|
61
73
|
end
|
62
74
|
end
|
63
|
-
|
64
|
-
def inventory_units
|
65
|
-
return_items.flat_map(&:inventory_unit)
|
66
|
-
end
|
67
|
-
|
68
75
|
end
|
69
76
|
end
|
70
|
-
|
@@ -60,6 +60,10 @@ module Spree
|
|
60
60
|
ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, :test => true, :authorization => '12345')
|
61
61
|
end
|
62
62
|
|
63
|
+
def cancel(_response_code)
|
64
|
+
ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345')
|
65
|
+
end
|
66
|
+
|
63
67
|
def test?
|
64
68
|
# Test mode is not really relevant with bogus gateway (no such thing as live server)
|
65
69
|
true
|
data/app/models/spree/order.rb
CHANGED
@@ -44,7 +44,7 @@ module Spree
|
|
44
44
|
alias_attribute :ship_total, :shipment_total
|
45
45
|
|
46
46
|
belongs_to :store, class_name: 'Spree::Store'
|
47
|
-
has_many :state_changes, as: :stateful
|
47
|
+
has_many :state_changes, as: :stateful, dependent: :destroy
|
48
48
|
has_many :line_items, -> { order("#{LineItem.table_name}.created_at ASC") }, dependent: :destroy, inverse_of: :order
|
49
49
|
has_many :payments, dependent: :destroy
|
50
50
|
has_many :return_authorizations, dependent: :destroy, inverse_of: :order
|
@@ -56,6 +56,11 @@ module Spree
|
|
56
56
|
has_many :products, through: :variants
|
57
57
|
has_many :variants, through: :line_items
|
58
58
|
has_many :refunds, through: :payments
|
59
|
+
has_many :all_adjustments,
|
60
|
+
class_name: 'Spree::Adjustment',
|
61
|
+
foreign_key: :order_id,
|
62
|
+
dependent: :destroy,
|
63
|
+
inverse_of: :order
|
59
64
|
|
60
65
|
has_and_belongs_to_many :promotions, join_table: 'spree_orders_promotions'
|
61
66
|
|
@@ -90,6 +95,7 @@ module Spree
|
|
90
95
|
make_permalink field: :number
|
91
96
|
|
92
97
|
delegate :update_totals, :persist_totals, :to => :updater
|
98
|
+
delegate :merge!, to: :merger
|
93
99
|
|
94
100
|
class_attribute :update_hooks
|
95
101
|
self.update_hooks = Set.new
|
@@ -135,11 +141,6 @@ module Spree
|
|
135
141
|
self.line_item_comparison_hooks.add(hook)
|
136
142
|
end
|
137
143
|
|
138
|
-
def all_adjustments
|
139
|
-
Adjustment.where("order_id = :order_id OR (adjustable_id = :order_id AND adjustable_type = 'Spree::Order')",
|
140
|
-
order_id: self.id)
|
141
|
-
end
|
142
|
-
|
143
144
|
# For compatiblity with Calculator::PriceSack
|
144
145
|
def amount
|
145
146
|
line_items.inject(0.0) { |sum, li| sum + li.amount }
|
@@ -245,6 +246,10 @@ module Spree
|
|
245
246
|
updater.update
|
246
247
|
end
|
247
248
|
|
249
|
+
def merger
|
250
|
+
@merger ||= Spree::OrderMerger.new(self)
|
251
|
+
end
|
252
|
+
|
248
253
|
def clone_billing_address
|
249
254
|
if bill_address and self.ship_address.nil?
|
250
255
|
self.ship_address = bill_address.clone
|
@@ -444,10 +449,10 @@ module Spree
|
|
444
449
|
end
|
445
450
|
|
446
451
|
##
|
447
|
-
# Check to see if any line item variants are soft
|
452
|
+
# Check to see if any line item variants are soft deleted.
|
448
453
|
# If so add error and restart checkout.
|
449
454
|
def ensure_line_item_variants_are_not_deleted
|
450
|
-
if line_items.
|
455
|
+
if line_items.any?{ |li| !li.variant || li.variant.paranoia_destroyed? }
|
451
456
|
errors.add(:base, Spree.t(:deleted_variants_present))
|
452
457
|
restart_checkout_flow
|
453
458
|
false
|
@@ -466,44 +471,12 @@ module Spree
|
|
466
471
|
end
|
467
472
|
end
|
468
473
|
|
469
|
-
def merge!(order, user = nil)
|
470
|
-
order.line_items.each do |other_order_line_item|
|
471
|
-
next unless other_order_line_item.currency == currency
|
472
|
-
|
473
|
-
# Compare the line items of the other order with mine.
|
474
|
-
# Make sure you allow any extensions to chime in on whether or
|
475
|
-
# not the extension-specific parts of the line item match
|
476
|
-
current_line_item = self.line_items.detect { |my_li|
|
477
|
-
my_li.variant == other_order_line_item.variant &&
|
478
|
-
self.line_item_comparison_hooks.all? { |hook|
|
479
|
-
self.send(hook, my_li, other_order_line_item.serializable_hash)
|
480
|
-
}
|
481
|
-
}
|
482
|
-
if current_line_item
|
483
|
-
current_line_item.quantity += other_order_line_item.quantity
|
484
|
-
current_line_item.save!
|
485
|
-
else
|
486
|
-
other_order_line_item.order_id = self.id
|
487
|
-
other_order_line_item.save!
|
488
|
-
end
|
489
|
-
end
|
490
|
-
|
491
|
-
self.associate_user!(user) if !self.user && !user.blank?
|
492
|
-
|
493
|
-
updater.update_item_count
|
494
|
-
updater.update_item_total
|
495
|
-
updater.persist_totals
|
496
|
-
|
497
|
-
# So that the destroy doesn't take out line items which may have been re-assigned
|
498
|
-
order.line_items.reload
|
499
|
-
order.destroy
|
500
|
-
end
|
501
|
-
|
502
474
|
def empty!
|
503
475
|
line_items.destroy_all
|
504
476
|
updater.update_item_count
|
505
477
|
adjustments.destroy_all
|
506
478
|
shipments.destroy_all
|
479
|
+
state_changes.destroy_all
|
507
480
|
|
508
481
|
update_totals
|
509
482
|
persist_totals
|
@@ -22,10 +22,10 @@ module Spree
|
|
22
22
|
# Update totals, then check if the order is eligible for any cart promotions.
|
23
23
|
# If we do not update first, then the item total will be wrong and ItemTotal
|
24
24
|
# promotion rules would not be triggered.
|
25
|
-
|
25
|
+
persist_totals
|
26
26
|
PromotionHandler::Cart.new(order).activate
|
27
27
|
order.ensure_updated_shipments
|
28
|
-
|
28
|
+
persist_totals
|
29
29
|
true
|
30
30
|
else
|
31
31
|
false
|
@@ -34,12 +34,12 @@ module Spree
|
|
34
34
|
|
35
35
|
private
|
36
36
|
def after_add_or_remove(line_item, options = {})
|
37
|
-
|
37
|
+
persist_totals
|
38
38
|
shipment = options[:shipment]
|
39
39
|
shipment.present? ? shipment.update_amounts : order.ensure_updated_shipments
|
40
40
|
PromotionHandler::Cart.new(order, line_item).activate
|
41
41
|
ItemAdjustments.new(line_item).update
|
42
|
-
|
42
|
+
persist_totals
|
43
43
|
line_item
|
44
44
|
end
|
45
45
|
|
@@ -61,10 +61,9 @@ module Spree
|
|
61
61
|
@updater ||= OrderUpdater.new(order)
|
62
62
|
end
|
63
63
|
|
64
|
-
def
|
64
|
+
def persist_totals
|
65
65
|
order_updater.update_item_count
|
66
66
|
order_updater.update
|
67
|
-
order.reload
|
68
67
|
end
|
69
68
|
|
70
69
|
def add_to_line_item(variant, quantity, options = {})
|
@@ -90,8 +89,8 @@ module Spree
|
|
90
89
|
line_item.quantity -= quantity
|
91
90
|
line_item.target_shipment= options[:shipment]
|
92
91
|
|
93
|
-
if line_item.quantity
|
94
|
-
|
92
|
+
if line_item.quantity.zero?
|
93
|
+
order.line_items.destroy(line_item)
|
95
94
|
else
|
96
95
|
line_item.save!
|
97
96
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Spree
|
2
|
+
class OrderMerger
|
3
|
+
attr_accessor :order
|
4
|
+
delegate :updater, to: :order
|
5
|
+
|
6
|
+
def initialize(order)
|
7
|
+
@order = order
|
8
|
+
end
|
9
|
+
|
10
|
+
def merge!(other_order, user = nil)
|
11
|
+
other_order.line_items.each do |other_order_line_item|
|
12
|
+
next unless other_order_line_item.currency == order.currency
|
13
|
+
|
14
|
+
current_line_item = find_matching_line_item(other_order_line_item)
|
15
|
+
handle_merge(current_line_item, other_order_line_item)
|
16
|
+
end
|
17
|
+
|
18
|
+
set_user(user)
|
19
|
+
persist_merge
|
20
|
+
|
21
|
+
# So that the destroy doesn't take out line items which may have been re-assigned
|
22
|
+
other_order.line_items.reload
|
23
|
+
other_order.destroy
|
24
|
+
end
|
25
|
+
|
26
|
+
# Compare the line item of the other order with mine.
|
27
|
+
# Make sure you allow any extensions to chime in on whether or
|
28
|
+
# not the extension-specific parts of the line item match
|
29
|
+
def find_matching_line_item(other_order_line_item)
|
30
|
+
order.line_items.detect do |my_li|
|
31
|
+
my_li.variant == other_order_line_item.variant &&
|
32
|
+
order.line_item_comparison_hooks.all? do |hook|
|
33
|
+
order.send(hook, my_li, other_order_line_item.serializable_hash)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def set_user(user = nil)
|
39
|
+
order.associate_user!(user) if !order.user && !user.blank?
|
40
|
+
end
|
41
|
+
|
42
|
+
# The idea is the end developer can choose to override the merge
|
43
|
+
# to their own choosing. Default is merge with errors.
|
44
|
+
def handle_merge(current_line_item, other_order_line_item)
|
45
|
+
if current_line_item
|
46
|
+
current_line_item.quantity += other_order_line_item.quantity
|
47
|
+
handle_error(current_line_item) unless current_line_item.save
|
48
|
+
else
|
49
|
+
other_order_line_item.order_id = order.id
|
50
|
+
handle_error(other_order_line_item) unless other_order_line_item.save
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Change the error messages as you choose.
|
55
|
+
def handle_error(line_item)
|
56
|
+
order.errors[:base] << line_item.errors.full_messages
|
57
|
+
end
|
58
|
+
|
59
|
+
def persist_merge
|
60
|
+
updater.update_item_count
|
61
|
+
updater.update_item_total
|
62
|
+
updater.persist_totals
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/app/models/spree/payment.rb
CHANGED
@@ -16,6 +16,7 @@ module Spree
|
|
16
16
|
has_many :capture_events, :class_name => 'Spree::PaymentCaptureEvent'
|
17
17
|
has_many :refunds, inverse_of: :payment
|
18
18
|
|
19
|
+
validates_presence_of :payment_method
|
19
20
|
before_validation :validate_source
|
20
21
|
before_create :set_unique_identifier
|
21
22
|
|
@@ -164,6 +165,10 @@ module Spree
|
|
164
165
|
amount - captured_amount
|
165
166
|
end
|
166
167
|
|
168
|
+
def editable?
|
169
|
+
checkout? || pending?
|
170
|
+
end
|
171
|
+
|
167
172
|
private
|
168
173
|
|
169
174
|
def validate_source
|
data/app/models/spree/product.rb
CHANGED
@@ -74,6 +74,7 @@ module Spree
|
|
74
74
|
after_create :build_variants_from_option_values_hash, if: :option_values_hash
|
75
75
|
|
76
76
|
after_destroy :punch_slug
|
77
|
+
after_restore :update_slug_history
|
77
78
|
|
78
79
|
after_initialize :ensure_master
|
79
80
|
|
@@ -263,7 +264,12 @@ module Spree
|
|
263
264
|
end
|
264
265
|
|
265
266
|
def punch_slug
|
266
|
-
|
267
|
+
# punch slug with date prefix to allow reuse of original
|
268
|
+
update_column :slug, "#{Time.now.to_i}_#{slug}"[0..254] unless frozen?
|
269
|
+
end
|
270
|
+
|
271
|
+
def update_slug_history
|
272
|
+
self.save!
|
267
273
|
end
|
268
274
|
|
269
275
|
def anything_changed?
|
@@ -29,22 +29,26 @@ module Spree
|
|
29
29
|
end
|
30
30
|
|
31
31
|
private
|
32
|
-
def promotions
|
33
|
-
promo_table = Promotion.arel_table
|
34
|
-
join_table = Arel::Table.new(:spree_orders_promotions)
|
35
32
|
|
36
|
-
|
37
|
-
|
38
|
-
|
33
|
+
def promotions
|
34
|
+
# AR cannot bind raw ASTs to prepared statements. There always must be a manager around.
|
35
|
+
# Also Postgresql requires an aliased table for `SELECT * FROM (subexpression) AS alias`.
|
36
|
+
# And Sqlite3 cannot work on outher parenthesis from `(left UNION right)`.
|
37
|
+
# So this construct makes both happy.
|
38
|
+
select = Arel::SelectManager.new(
|
39
|
+
Promotion,
|
40
|
+
Promotion.arel_table.create_table_alias(
|
41
|
+
order.promotions.active.union(Promotion.active.where(code: nil, path: nil)),
|
42
|
+
Promotion.table_name
|
43
|
+
),
|
44
|
+
)
|
45
|
+
select.project(Arel.star)
|
39
46
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
).or(join_table[:order_id].eq(order.id))
|
46
|
-
).distinct
|
47
|
-
end
|
47
|
+
Promotion.find_by_sql(
|
48
|
+
select,
|
49
|
+
order.promotions.bind_values
|
50
|
+
)
|
51
|
+
end
|
48
52
|
end
|
49
53
|
end
|
50
54
|
end
|
@@ -86,7 +86,7 @@ module Spree
|
|
86
86
|
}
|
87
87
|
|
88
88
|
# Check for applied adjustments.
|
89
|
-
discount = order.line_item_adjustments.promotion.detect(&detector)
|
89
|
+
discount = order.line_item_adjustments.promotion.eligible.detect(&detector)
|
90
90
|
discount ||= order.shipment_adjustments.promotion.detect(&detector)
|
91
91
|
discount ||= order.adjustments.promotion.detect(&detector)
|
92
92
|
|
@@ -5,16 +5,20 @@ module Spree
|
|
5
5
|
unit_count = line_item.inventory_units.size
|
6
6
|
return if unit_count >= line_item.quantity
|
7
7
|
quantity = line_item.quantity - unit_count
|
8
|
+
return if quantity.zero?
|
8
9
|
|
9
10
|
quantifier = Stock::Quantifier.new(line_item.variant)
|
10
11
|
|
11
|
-
|
12
|
-
variant = line_item.variant
|
13
|
-
display_name = %Q{#{variant.name}}
|
14
|
-
display_name += %Q{ (#{variant.options_text})} unless variant.options_text.blank?
|
12
|
+
return if quantifier.can_supply?(quantity)
|
15
13
|
|
16
|
-
|
17
|
-
|
14
|
+
variant = line_item.variant
|
15
|
+
display_name = "#{variant.name}"
|
16
|
+
display_name += " (#{variant.options_text})" unless variant.options_text.blank?
|
17
|
+
|
18
|
+
line_item.errors[:quantity] << Spree.t(
|
19
|
+
:selected_quantity_not_available,
|
20
|
+
item: display_name.inspect
|
21
|
+
)
|
18
22
|
end
|
19
23
|
end
|
20
24
|
end
|
@@ -8,7 +8,11 @@ module Spree
|
|
8
8
|
|
9
9
|
validates_presence_of :stock_location, :variant
|
10
10
|
validates_uniqueness_of :variant_id, scope: [:stock_location_id, :deleted_at]
|
11
|
-
|
11
|
+
|
12
|
+
validates_numericality_of :count_on_hand,
|
13
|
+
greater_than_or_equal_to: 0,
|
14
|
+
less_than_or_equal_to: 2**31 - 1,
|
15
|
+
only_integer: true, if: :verify_count_on_hand?
|
12
16
|
|
13
17
|
delegate :weight, :should_track_inventory?, to: :variant
|
14
18
|
|
@@ -6,7 +6,12 @@ module Spree
|
|
6
6
|
after_create :update_stock_item_quantity
|
7
7
|
|
8
8
|
validates :stock_item, presence: true
|
9
|
-
validates :quantity, presence: true
|
9
|
+
validates :quantity, presence: true, numericality: {
|
10
|
+
greater_than_or_equal_to: -2**31,
|
11
|
+
less_than_or_equal_to: 2**31-1,
|
12
|
+
only_integer: true,
|
13
|
+
allow_nil: true
|
14
|
+
}
|
10
15
|
|
11
16
|
scope :recent, -> { order('created_at DESC') }
|
12
17
|
|
@@ -79,7 +79,11 @@ module Spree
|
|
79
79
|
rates = self.match(order_tax_zone)
|
80
80
|
tax_categories = rates.map(&:tax_category)
|
81
81
|
relevant_items, non_relevant_items = items.partition { |item| tax_categories.include?(item.tax_category) }
|
82
|
-
|
82
|
+
|
83
|
+
if relevant_items.present?
|
84
|
+
Spree::Adjustment.where(adjustable: relevant_items).tax.destroy_all # using destroy_all to ensure adjustment destroy callback fires.
|
85
|
+
end
|
86
|
+
|
83
87
|
relevant_items.each do |item|
|
84
88
|
relevant_rates = rates.select { |rate| rate.tax_category == item.tax_category }
|
85
89
|
store_pre_tax_amount(item, relevant_rates)
|
data/app/models/spree/variant.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Spree
|
2
2
|
class Variant < Spree::Base
|
3
3
|
acts_as_paranoid
|
4
|
-
acts_as_list
|
4
|
+
acts_as_list scope: :product
|
5
5
|
|
6
6
|
include Spree::DefaultPrice
|
7
7
|
|
@@ -37,7 +37,6 @@ module Spree
|
|
37
37
|
validates_uniqueness_of :sku, allow_blank: true, conditions: -> { where(deleted_at: nil) }
|
38
38
|
|
39
39
|
after_create :create_stock_items
|
40
|
-
after_create :set_position
|
41
40
|
after_create :set_master_out_of_stock, unless: :is_master?
|
42
41
|
|
43
42
|
after_touch :clear_in_stock_cache
|
@@ -245,10 +244,6 @@ module Spree
|
|
245
244
|
end
|
246
245
|
end
|
247
246
|
|
248
|
-
def set_position
|
249
|
-
self.update_column(:position, product.variants.maximum(:position).to_i + 1)
|
250
|
-
end
|
251
|
-
|
252
247
|
def in_stock_cache_key
|
253
248
|
"variant-#{id}-in_stock"
|
254
249
|
end
|
data/config/locales/en.yml
CHANGED
@@ -842,6 +842,7 @@ en:
|
|
842
842
|
meta_title: Meta Title
|
843
843
|
metadata: Metadata
|
844
844
|
minimal_amount: Minimal Amount
|
845
|
+
missing_return_authorization: ! 'Missing Return Authorization for %{item_name}.'
|
845
846
|
month: Month
|
846
847
|
more: More
|
847
848
|
move_stock_between_locations: Move Stock Between Locations
|
@@ -979,7 +980,6 @@ en:
|
|
979
980
|
order_total: Order Total
|
980
981
|
order_updated: Order Updated
|
981
982
|
orders: Orders
|
982
|
-
other_items_in_other: Other Items in Order
|
983
983
|
out_of_stock: Out of Stock
|
984
984
|
overview: Overview
|
985
985
|
package_from: package from
|
@@ -0,0 +1,70 @@
|
|
1
|
+
class FixAdjustmentOrderId < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
say 'Populate order_id from adjustable_id where appropriate'
|
4
|
+
execute(<<-SQL.squish)
|
5
|
+
UPDATE
|
6
|
+
spree_adjustments
|
7
|
+
SET
|
8
|
+
order_id = adjustable_id
|
9
|
+
WHERE
|
10
|
+
adjustable_type = 'Spree::Order'
|
11
|
+
;
|
12
|
+
SQL
|
13
|
+
|
14
|
+
# Submitter of change does not care about MySQL, as it is not officially supported.
|
15
|
+
# Still spree officials decided to provide a working code path for MySQL users, hence
|
16
|
+
# submitter made a AR code path he could validate on PostgreSQL.
|
17
|
+
#
|
18
|
+
# Whoever runs a big enough MySQL installation where the AR solution hurts:
|
19
|
+
# Will have to write a better MySQL specific equivalent.
|
20
|
+
if Spree::Order.connection.adapter_name.eql?('MySQL')
|
21
|
+
Spree::Adjustment.where(adjustable_type: 'Spree::LineItem').find_each do |adjustment|
|
22
|
+
adjustment.update_columns(order_id: Spree::LineItem.find(adjustment.adjustable_id).order_id)
|
23
|
+
end
|
24
|
+
else
|
25
|
+
execute(<<-SQL.squish)
|
26
|
+
UPDATE
|
27
|
+
spree_adjustments
|
28
|
+
SET
|
29
|
+
order_id =
|
30
|
+
(SELECT order_id FROM spree_line_items WHERE spree_line_items.id = spree_adjustments.adjustable_id)
|
31
|
+
WHERE
|
32
|
+
adjustable_type = 'Spree::LineItem'
|
33
|
+
SQL
|
34
|
+
end
|
35
|
+
|
36
|
+
say 'Fix schema for spree_adjustments order_id column'
|
37
|
+
change_table :spree_adjustments do |t|
|
38
|
+
t.change :order_id, :integer, null: false
|
39
|
+
end
|
40
|
+
|
41
|
+
# Improved schema for postgresql, uncomment if you like it:
|
42
|
+
#
|
43
|
+
# # Negated Logical implication.
|
44
|
+
# #
|
45
|
+
# # When adjustable_type is 'Spree::Order' (p) the adjustable_id must be order_id (q).
|
46
|
+
# #
|
47
|
+
# # When adjustable_type is NOT 'Spree::Order' the adjustable id allowed to be any value (including of order_id in
|
48
|
+
# # case foreign keys match). XOR does not work here.
|
49
|
+
# #
|
50
|
+
# # Postgresql does not have an operator for logical implication. So we need to build the following truth table
|
51
|
+
# # via AND with OR:
|
52
|
+
# #
|
53
|
+
# # p q | CHECK = !(p -> q)
|
54
|
+
# # -----------
|
55
|
+
# # t t | t
|
56
|
+
# # t f | f
|
57
|
+
# # f t | t
|
58
|
+
# # f f | t
|
59
|
+
# #
|
60
|
+
# # According to de-morgans law the logical implication q -> p is equivalent to !p || q
|
61
|
+
# #
|
62
|
+
# execute(<<-SQL.squish)
|
63
|
+
# ALTER TABLE ONLY spree_adjustments
|
64
|
+
# ADD CONSTRAINT fk_spree_adjustments FOREIGN KEY (order_id)
|
65
|
+
# REFERENCES spree_orders(id) ON UPDATE RESTRICT ON DELETE RESTRICT,
|
66
|
+
# ADD CONSTRAINT check_spree_adjustments_order_id CHECK
|
67
|
+
# (adjustable_type <> 'Spree::Order' OR order_id = adjustable_id);
|
68
|
+
# SQL
|
69
|
+
end
|
70
|
+
end
|
data/lib/spree/core/engine.rb
CHANGED
@@ -101,6 +101,13 @@ module Spree
|
|
101
101
|
initializer "spree.core.checking_migrations" do |app|
|
102
102
|
Migrations.new(config, engine_name).check
|
103
103
|
end
|
104
|
+
|
105
|
+
config.to_prepare do
|
106
|
+
# Load application's model / class decorators
|
107
|
+
Dir.glob(File.join(File.dirname(__FILE__), '../../../app/**/*_decorator*.rb')) do |c|
|
108
|
+
Rails.configuration.cache_classes ? require(c) : load(c)
|
109
|
+
end
|
110
|
+
end
|
104
111
|
end
|
105
112
|
end
|
106
113
|
end
|
data/lib/spree/core/version.rb
CHANGED
@@ -17,6 +17,17 @@ FactoryGirl.define do
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
+
factory :order_with_line_item_quantity do
|
21
|
+
transient do
|
22
|
+
line_items_quantity 1
|
23
|
+
end
|
24
|
+
|
25
|
+
after(:create) do |order, evaluator|
|
26
|
+
create(:line_item, order: order, price: evaluator.line_items_price, quantity: evaluator.line_items_quantity)
|
27
|
+
order.line_items.reload # to ensure order.line_items is accessible after
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
20
31
|
factory :order_with_line_items do
|
21
32
|
bill_address
|
22
33
|
ship_address
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spree_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.4.
|
4
|
+
version: 2.4.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sean Schofield
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemerchant
|
@@ -232,14 +232,14 @@ dependencies:
|
|
232
232
|
requirements:
|
233
233
|
- - "~>"
|
234
234
|
- !ruby/object:Gem::Version
|
235
|
-
version: 2.0
|
235
|
+
version: 2.1.0
|
236
236
|
type: :runtime
|
237
237
|
prerelease: false
|
238
238
|
version_requirements: !ruby/object:Gem::Requirement
|
239
239
|
requirements:
|
240
240
|
- - "~>"
|
241
241
|
- !ruby/object:Gem::Version
|
242
|
-
version: 2.0
|
242
|
+
version: 2.1.0
|
243
243
|
- !ruby/object:Gem::Dependency
|
244
244
|
name: premailer-rails
|
245
245
|
requirement: !ruby/object:Gem::Requirement
|
@@ -258,16 +258,16 @@ dependencies:
|
|
258
258
|
name: rails
|
259
259
|
requirement: !ruby/object:Gem::Requirement
|
260
260
|
requirements:
|
261
|
-
- -
|
261
|
+
- - "~>"
|
262
262
|
- !ruby/object:Gem::Version
|
263
|
-
version: 4.1.
|
263
|
+
version: 4.1.11
|
264
264
|
type: :runtime
|
265
265
|
prerelease: false
|
266
266
|
version_requirements: !ruby/object:Gem::Requirement
|
267
267
|
requirements:
|
268
|
-
- -
|
268
|
+
- - "~>"
|
269
269
|
- !ruby/object:Gem::Version
|
270
|
-
version: 4.1.
|
270
|
+
version: 4.1.11
|
271
271
|
- !ruby/object:Gem::Dependency
|
272
272
|
name: ransack
|
273
273
|
requirement: !ruby/object:Gem::Requirement
|
@@ -385,6 +385,7 @@ files:
|
|
385
385
|
- app/models/concerns/spree/user_api_authentication.rb
|
386
386
|
- app/models/concerns/spree/user_payment_source.rb
|
387
387
|
- app/models/concerns/spree/user_reporting.rb
|
388
|
+
- app/models/friendly_id/slug_decorator.rb
|
388
389
|
- app/models/spree/ability.rb
|
389
390
|
- app/models/spree/address.rb
|
390
391
|
- app/models/spree/adjustment.rb
|
@@ -433,6 +434,7 @@ files:
|
|
433
434
|
- app/models/spree/order/payments.rb
|
434
435
|
- app/models/spree/order_contents.rb
|
435
436
|
- app/models/spree/order_inventory.rb
|
437
|
+
- app/models/spree/order_merger.rb
|
436
438
|
- app/models/spree/order_populator.rb
|
437
439
|
- app/models/spree/order_updater.rb
|
438
440
|
- app/models/spree/payment.rb
|
@@ -752,6 +754,9 @@ files:
|
|
752
754
|
- db/migrate/20141101231208_fix_adjustment_order_presence.rb
|
753
755
|
- db/migrate/20141105213646_update_classifications_positions.rb
|
754
756
|
- db/migrate/20141120135441_add_guest_token_index_to_spree_orders.rb
|
757
|
+
- db/migrate/20150515211137_fix_adjustment_order_id.rb
|
758
|
+
- db/migrate/20150522181728_add_deleted_at_to_friendly_id_slugs.rb
|
759
|
+
- db/migrate/20150707204155_enable_acts_as_paranoid_on_calculators.rb
|
755
760
|
- db/seeds.rb
|
756
761
|
- lib/generators/spree/custom_user/custom_user_generator.rb
|
757
762
|
- lib/generators/spree/custom_user/templates/authentication_helpers.rb.tt
|