solidus_core 3.1.9 → 3.2.0.alpha
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/helpers/spree/products_helper.rb +1 -1
- data/app/models/concerns/spree/active_storage_adapter/attachment.rb +23 -10
- data/app/models/concerns/spree/active_storage_adapter.rb +1 -1
- data/app/models/concerns/spree/default_price.rb +28 -4
- data/app/models/concerns/spree/user_address_book.rb +11 -1
- data/app/models/spree/adjustment.rb +1 -0
- data/app/models/spree/carton.rb +1 -1
- data/app/models/spree/option_value.rb +9 -0
- data/app/models/spree/order.rb +68 -29
- data/app/models/spree/order_contents.rb +2 -1
- data/app/models/spree/order_inventory.rb +1 -1
- data/app/models/spree/order_merger.rb +2 -2
- data/app/models/spree/order_taxation.rb +6 -4
- data/app/models/spree/order_updater.rb +4 -3
- data/app/models/spree/payment_method.rb +11 -0
- data/app/models/spree/price.rb +1 -1
- data/app/models/spree/product/scopes.rb +21 -3
- data/app/models/spree/product.rb +1 -1
- data/app/models/spree/promotion/actions/create_adjustment.rb +4 -0
- data/app/models/spree/promotion/actions/create_item_adjustments.rb +5 -6
- data/app/models/spree/promotion/rules/product.rb +20 -8
- data/app/models/spree/promotion/rules/store.rb +4 -0
- data/app/models/spree/promotion/rules/taxon.rb +4 -0
- data/app/models/spree/promotion/rules/user.rb +4 -0
- data/app/models/spree/promotion.rb +34 -23
- data/app/models/spree/promotion_action.rb +4 -0
- data/app/models/spree/promotion_code.rb +8 -4
- data/app/models/spree/promotion_handler/cart.rb +26 -6
- data/app/models/spree/promotion_rule.rb +5 -0
- data/app/models/spree/reimbursement.rb +2 -2
- data/app/models/spree/return_item.rb +1 -2
- data/app/models/spree/stock/allocator/on_hand_first.rb +2 -2
- data/app/models/spree/stock/quantifier.rb +12 -8
- data/app/models/spree/stock/simple_coordinator.rb +2 -1
- data/app/models/spree/tax/item_tax.rb +3 -2
- data/app/models/spree/tax/order_tax.rb +3 -1
- data/app/models/spree/tax/tax_location.rb +4 -7
- data/app/models/spree/tax_rate.rb +2 -0
- data/app/models/spree/variant/price_selector.rb +1 -18
- data/app/models/spree/variant.rb +2 -2
- data/app/subscribers/spree/mailer_subscriber.rb +4 -0
- data/app/subscribers/spree/order_mailer_subscriber.rb +35 -0
- data/config/locales/en.yml +7 -253
- data/db/migrate/20201127212108_add_type_before_removal_to_spree_payment_methods.rb +7 -0
- data/db/migrate/20220317165036_set_promotions_with_any_policy_to_all_if_possible.rb +20 -0
- data/lib/generators/solidus/install/install_generator/bundler_context.rb +97 -0
- data/lib/generators/solidus/install/install_generator/install_frontend.rb +50 -0
- data/lib/generators/solidus/install/install_generator/support_solidus_frontend_extraction.rb +48 -0
- data/lib/generators/solidus/install/install_generator.rb +56 -49
- data/lib/generators/solidus/install/templates/config/initializers/spree.rb.tt +6 -16
- data/lib/generators/solidus/install/templates/vendor/assets/javascripts/spree/backend/all.js +2 -2
- data/lib/spree/app_configuration.rb +29 -3
- data/lib/spree/bus.rb +20 -0
- data/lib/spree/core/controller_helpers/auth.rb +9 -1
- data/lib/spree/core/controller_helpers/current_host.rb +1 -3
- data/lib/spree/core/controller_helpers/order.rb +10 -10
- data/lib/spree/core/controller_helpers/search.rb +1 -1
- data/lib/spree/core/engine.rb +33 -8
- data/lib/spree/core/state_machines/order.rb +1 -1
- data/lib/spree/core/stock_configuration.rb +18 -0
- data/lib/spree/core/validators/email.rb +3 -1
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +20 -0
- data/lib/spree/event/subscriber_registry.rb +4 -6
- data/lib/spree/event.rb +1 -1
- data/lib/spree/migrations.rb +1 -1
- data/lib/spree/permission_sets/default_customer.rb +8 -1
- data/lib/spree/permitted_attributes.rb +4 -4
- data/lib/spree/preferences/configuration.rb +34 -12
- data/lib/spree/preferences/preferable.rb +0 -5
- data/lib/spree/preferences/preferable_class_methods.rb +3 -3
- data/lib/spree/preferences/preference_differentiator.rb +2 -1
- data/lib/spree/preferences/static_model_preferences.rb +0 -2
- data/lib/spree/rails_compatibility.rb +99 -0
- data/lib/spree/testing_support/bus_helpers.rb +101 -0
- data/lib/spree/testing_support/common_rake.rb +47 -19
- data/lib/spree/testing_support/dummy_app/assets/javascripts/spree/backend/all.js +1 -1
- data/lib/spree/testing_support/dummy_app/assets/javascripts/spree/frontend/all.js +1 -1
- data/lib/spree/testing_support/dummy_app.rb +6 -2
- data/lib/spree/testing_support/factories/address_factory.rb +7 -2
- data/lib/spree/testing_support/factories/inventory_unit_factory.rb +1 -1
- data/lib/spree/testing_support/factories/order_factory.rb +8 -4
- data/lib/spree/testing_support/factories/product_factory.rb +4 -1
- data/lib/spree/testing_support/factories/store_credit_factory.rb +4 -4
- data/lib/spree/testing_support/factory_bot.rb +1 -1
- data/lib/spree/testing_support/order_walkthrough.rb +5 -4
- data/lib/spree/testing_support/silence_deprecations.rb +9 -0
- data/lib/tasks/payment_method.rake +29 -0
- data/lib/tasks/solidus/delete_prices_with_nil_amount.rake +2 -2
- data/lib/tasks/solidus/split_promotions_with_any_match_policy.rake +33 -0
- data/solidus_core.gemspec +6 -2
- metadata +71 -26
- data/lib/generators/solidus/install/templates/vendor/assets/javascripts/spree/frontend/all.js +0 -10
- data/lib/generators/solidus/install/templates/vendor/assets/stylesheets/spree/frontend/all.css +0 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b1b866f15d9df0394383e7f634858ee99f21ed214e8fae6928af514a6421ddbc
|
|
4
|
+
data.tar.gz: d2f5c689bf6debe86f5b9be575eea7640e496606f8933b85a1d2e7a2cb90123c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: df2acde7ab4aa4b01e3d5b187b6c47a911714c868237a1ba494095a43bdd07bac5082e2080d4aabc563576d502fecda0d28a94b9cef53db8e6c1e1c89a0cbc97
|
|
7
|
+
data.tar.gz: c183f6200f52b585a4ae391bd8b412c6a4f58e987fcc6ceb3cd1cf6835b92b1019f6077e4a13c75dbe6a4c0dd64c81fe7c4d8d3deeed2b8fbadc67ed74148cb5
|
|
@@ -68,7 +68,7 @@ module Spree
|
|
|
68
68
|
# @return [String] a cache invalidation key for products
|
|
69
69
|
def cache_key_for_products
|
|
70
70
|
count = @products.count
|
|
71
|
-
max_updated_at = (@products.maximum(:updated_at) || Date.today)
|
|
71
|
+
max_updated_at = Spree::RailsCompatibility.to_fs((@products.maximum(:updated_at) || Date.today), :number)
|
|
72
72
|
"#{I18n.locale}/#{current_pricing_options.cache_key}/spree/products/all-#{params[:page]}-#{max_updated_at}-#{count}"
|
|
73
73
|
end
|
|
74
74
|
end
|
|
@@ -4,14 +4,16 @@ require 'mini_magick'
|
|
|
4
4
|
|
|
5
5
|
module Spree
|
|
6
6
|
module ActiveStorageAdapter
|
|
7
|
-
#
|
|
7
|
+
# Decorates ActiveStorage attachment to add methods expected by Solidus'
|
|
8
8
|
# Paperclip-oriented attachment support.
|
|
9
9
|
class Attachment
|
|
10
10
|
delegate_missing_to :@attachment
|
|
11
11
|
|
|
12
|
+
attr_reader :attachment
|
|
13
|
+
|
|
12
14
|
def initialize(attachment, styles: {})
|
|
13
15
|
@attachment = attachment
|
|
14
|
-
@
|
|
16
|
+
@transformations = styles_to_transformations(styles)
|
|
15
17
|
end
|
|
16
18
|
|
|
17
19
|
def exists?
|
|
@@ -27,13 +29,13 @@ module Spree
|
|
|
27
29
|
end
|
|
28
30
|
|
|
29
31
|
def variant(style = nil)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
transformation = @transformations[style] || default_transformation(width, height)
|
|
33
|
+
|
|
34
|
+
@attachment.variant({
|
|
33
35
|
saver: {
|
|
34
36
|
strip: true
|
|
35
37
|
}
|
|
36
|
-
).processed
|
|
38
|
+
}.merge(transformation)).processed
|
|
37
39
|
end
|
|
38
40
|
|
|
39
41
|
def height
|
|
@@ -59,12 +61,23 @@ module Spree
|
|
|
59
61
|
@attachment.metadata
|
|
60
62
|
end
|
|
61
63
|
|
|
62
|
-
def
|
|
63
|
-
styles.transform_values
|
|
64
|
+
def styles_to_transformations(styles)
|
|
65
|
+
styles.transform_values(&method(:imagemagick_to_image_processing_definition))
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def imagemagick_to_image_processing_definition(definition)
|
|
69
|
+
width_height = definition.split('x').map(&:to_i)
|
|
70
|
+
|
|
71
|
+
case definition[-1].to_sym
|
|
72
|
+
when :^
|
|
73
|
+
{ resize_to_fill: width_height }
|
|
74
|
+
else
|
|
75
|
+
default_transformation(*width_height)
|
|
76
|
+
end
|
|
64
77
|
end
|
|
65
78
|
|
|
66
|
-
def
|
|
67
|
-
|
|
79
|
+
def default_transformation(width, height)
|
|
80
|
+
{ resize_to_limit: [width, height] }
|
|
68
81
|
end
|
|
69
82
|
end
|
|
70
83
|
end
|
|
@@ -10,7 +10,7 @@ module Spree
|
|
|
10
10
|
included do
|
|
11
11
|
next if Rails.gem_version >= Gem::Version.new('6.1.0.alpha')
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
raise <<~MESSAGE
|
|
14
14
|
Configuration Error: Solidus ActiveStorage attachment adpater requires Rails >= 6.1.0.
|
|
15
15
|
|
|
16
16
|
Spree::Config.image_attachment_module preference is set to #{Spree::Config.image_attachment_module}
|
|
@@ -16,12 +16,10 @@ module Spree
|
|
|
16
16
|
|
|
17
17
|
# Returns `#prices` prioritized for being considered as default price
|
|
18
18
|
#
|
|
19
|
-
# @deprecated
|
|
20
19
|
# @return [ActiveRecord::Relation<Spree::Price>]
|
|
21
20
|
def currently_valid_prices
|
|
22
21
|
prices.currently_valid
|
|
23
22
|
end
|
|
24
|
-
deprecate :currently_valid_prices, deprecator: Spree::Deprecation
|
|
25
23
|
|
|
26
24
|
# Returns {#default_price} or builds it from {Spree::Variant.default_price_attributes}
|
|
27
25
|
#
|
|
@@ -35,7 +33,7 @@ module Spree
|
|
|
35
33
|
# Select from {#prices} the one to be considered as the default
|
|
36
34
|
#
|
|
37
35
|
# This method works with the in-memory association, so non-persisted prices
|
|
38
|
-
# are taken into account.
|
|
36
|
+
# are taken into account. Discarded prices are also considered.
|
|
39
37
|
#
|
|
40
38
|
# A price is a candidate to be considered as the default when it meets
|
|
41
39
|
# {Spree::Variant.default_price_attributes} criteria. When more than one candidate is
|
|
@@ -46,11 +44,37 @@ module Spree
|
|
|
46
44
|
# @return [Spree::Price, nil]
|
|
47
45
|
# @see Spree::Variant.default_price_attributes
|
|
48
46
|
def default_price
|
|
49
|
-
|
|
47
|
+
prioritized_default(
|
|
48
|
+
prices_meeting_criteria_to_be_default(
|
|
49
|
+
(prices + prices.with_discarded).uniq
|
|
50
|
+
)
|
|
51
|
+
)
|
|
50
52
|
end
|
|
51
53
|
|
|
52
54
|
def has_default_price?
|
|
53
55
|
default_price.present? && !default_price.discarded?
|
|
54
56
|
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
def prices_meeting_criteria_to_be_default(prices)
|
|
61
|
+
criteria = self.class.default_price_attributes.transform_keys(&:to_s)
|
|
62
|
+
prices.select do |price|
|
|
63
|
+
contender = price.attributes.slice(*criteria.keys)
|
|
64
|
+
criteria == contender
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def prioritized_default(prices)
|
|
69
|
+
prices.min do |prev, succ|
|
|
70
|
+
contender_one, contender_two = [succ, prev].map do |item|
|
|
71
|
+
[
|
|
72
|
+
item.updated_at || Time.zone.now,
|
|
73
|
+
item.id || Float::INFINITY
|
|
74
|
+
]
|
|
75
|
+
end
|
|
76
|
+
contender_one <=> contender_two
|
|
77
|
+
end
|
|
78
|
+
end
|
|
55
79
|
end
|
|
56
80
|
end
|
|
@@ -37,6 +37,9 @@ module Spree
|
|
|
37
37
|
|
|
38
38
|
has_one :default_user_ship_address, ->{ default_shipping }, class_name: 'Spree::UserAddress', foreign_key: 'user_id'
|
|
39
39
|
has_one :ship_address, through: :default_user_ship_address, source: :address
|
|
40
|
+
|
|
41
|
+
accepts_nested_attributes_for :ship_address
|
|
42
|
+
accepts_nested_attributes_for :bill_address
|
|
40
43
|
end
|
|
41
44
|
|
|
42
45
|
# saves address in address book
|
|
@@ -104,12 +107,19 @@ module Spree
|
|
|
104
107
|
return new_address unless new_address.valid?
|
|
105
108
|
|
|
106
109
|
first_one = user_addresses.empty?
|
|
110
|
+
user_address = prepare_user_address(new_address)
|
|
107
111
|
|
|
108
112
|
if address_attributes[:id].present? && new_address.id != address_attributes[:id]
|
|
113
|
+
if ship_address&.id == address_attributes[:id].to_i
|
|
114
|
+
user_addresses.mark_default(user_address, address_type: :shipping)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
if bill_address&.id == address_attributes[:id].to_i
|
|
118
|
+
user_addresses.mark_default(user_address, address_type: :billing)
|
|
119
|
+
end
|
|
109
120
|
remove_from_address_book(address_attributes[:id])
|
|
110
121
|
end
|
|
111
122
|
|
|
112
|
-
user_address = prepare_user_address(new_address)
|
|
113
123
|
user_addresses.mark_default(user_address, address_type: address_type) if default || first_one
|
|
114
124
|
|
|
115
125
|
if persisted?
|
|
@@ -62,6 +62,7 @@ module Spree
|
|
|
62
62
|
.distinct
|
|
63
63
|
exclude_canceled ? result.merge(Spree::Order.not_canceled) : result
|
|
64
64
|
end
|
|
65
|
+
deprecate :in_completed_orders, "Please don't use this and rather go through Spree::Promotion#discounted_orders"
|
|
65
66
|
|
|
66
67
|
def finalize!
|
|
67
68
|
update!(finalized: true)
|
data/app/models/spree/carton.rb
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
module Spree
|
|
4
4
|
class OptionValue < Spree::Base
|
|
5
|
+
# TODO: Remove optional on Solidus v4.0. Don't forget adding a migration to
|
|
6
|
+
# enforce at the database layer
|
|
5
7
|
belongs_to :option_type, class_name: 'Spree::OptionType', inverse_of: :option_values, optional: true
|
|
6
8
|
acts_as_list scope: :option_type
|
|
7
9
|
|
|
@@ -13,7 +15,14 @@ module Spree
|
|
|
13
15
|
|
|
14
16
|
after_save :touch, if: :saved_changes?
|
|
15
17
|
after_touch :touch_all_variants
|
|
18
|
+
after_save do
|
|
19
|
+
Spree::Deprecation.warn <<~MSG if option_type.nil?
|
|
20
|
+
Having an option_value with no associated option_type will be deprecated
|
|
21
|
+
on Solidus v4.0
|
|
22
|
+
MSG
|
|
23
|
+
end
|
|
16
24
|
|
|
25
|
+
# TODO: Remove allow_nil once option_type is required on Solidus v4.0
|
|
17
26
|
delegate :name, :presentation, to: :option_type, prefix: :option_type, allow_nil: true
|
|
18
27
|
|
|
19
28
|
self.whitelisted_ransackable_attributes = %w[name presentation]
|
data/app/models/spree/order.rb
CHANGED
|
@@ -38,9 +38,21 @@ module Spree
|
|
|
38
38
|
class CannotRebuildShipments < StandardError; end
|
|
39
39
|
|
|
40
40
|
extend Spree::DisplayMoney
|
|
41
|
-
money_methods
|
|
42
|
-
:
|
|
43
|
-
:
|
|
41
|
+
money_methods(
|
|
42
|
+
:outstanding_balance,
|
|
43
|
+
:item_total,
|
|
44
|
+
:adjustment_total,
|
|
45
|
+
:included_tax_total,
|
|
46
|
+
:additional_tax_total,
|
|
47
|
+
:tax_total,
|
|
48
|
+
:shipment_total,
|
|
49
|
+
:total,
|
|
50
|
+
:order_total_after_store_credit,
|
|
51
|
+
:total_available_store_credit,
|
|
52
|
+
:item_total_before_tax,
|
|
53
|
+
:shipment_total_before_tax,
|
|
54
|
+
:item_total_excluding_vat
|
|
55
|
+
)
|
|
44
56
|
alias :display_ship_total :display_shipment_total
|
|
45
57
|
|
|
46
58
|
checkout_flow do
|
|
@@ -102,7 +114,7 @@ module Spree
|
|
|
102
114
|
# Returns
|
|
103
115
|
has_many :return_authorizations, dependent: :destroy, inverse_of: :order
|
|
104
116
|
has_many :return_items, through: :inventory_units
|
|
105
|
-
has_many :customer_returns, through: :return_items
|
|
117
|
+
has_many :customer_returns, -> { distinct }, through: :return_items
|
|
106
118
|
has_many :reimbursements, inverse_of: :order
|
|
107
119
|
has_many :refunds, through: :payments
|
|
108
120
|
|
|
@@ -195,6 +207,10 @@ module Spree
|
|
|
195
207
|
line_items.to_a.sum(&:total_before_tax)
|
|
196
208
|
end
|
|
197
209
|
|
|
210
|
+
def shipment_total_before_tax
|
|
211
|
+
shipments.to_a.sum(&:total_before_tax)
|
|
212
|
+
end
|
|
213
|
+
|
|
198
214
|
# Sum of all line item amounts pre-tax
|
|
199
215
|
def item_total_excluding_vat
|
|
200
216
|
line_items.to_a.sum(&:total_excluding_vat)
|
|
@@ -239,7 +255,7 @@ module Spree
|
|
|
239
255
|
ship_address
|
|
240
256
|
else
|
|
241
257
|
bill_address
|
|
242
|
-
end || store
|
|
258
|
+
end || store&.default_cart_tax_location
|
|
243
259
|
end
|
|
244
260
|
|
|
245
261
|
def updater
|
|
@@ -379,25 +395,16 @@ module Spree
|
|
|
379
395
|
Spree::CreditCard.where(id: credit_card_ids)
|
|
380
396
|
end
|
|
381
397
|
|
|
382
|
-
#
|
|
383
|
-
#
|
|
398
|
+
# TODO: Remove on Solidus 4.0
|
|
399
|
+
# @api private
|
|
384
400
|
def finalize!
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
shipment.finalize!
|
|
393
|
-
end
|
|
394
|
-
|
|
395
|
-
updater.update_shipment_state
|
|
396
|
-
save!
|
|
397
|
-
|
|
398
|
-
touch :completed_at
|
|
399
|
-
|
|
400
|
-
Spree::Event.fire 'order_finalized', order: self
|
|
401
|
+
Spree::Deprecation.warn <<~MSG
|
|
402
|
+
Calling `Spree::Order#finalize!` is discouraged. Instead, use
|
|
403
|
+
`Spree::Order#complete!`, which goes through all the needed safety
|
|
404
|
+
checks before finalizing an order. This method will be removed
|
|
405
|
+
altogether on Solidus 4.0.
|
|
406
|
+
MSG
|
|
407
|
+
finalize
|
|
401
408
|
end
|
|
402
409
|
|
|
403
410
|
def fulfill!
|
|
@@ -495,7 +502,8 @@ module Spree
|
|
|
495
502
|
end
|
|
496
503
|
|
|
497
504
|
def create_shipments_for_line_item(line_item)
|
|
498
|
-
units = Spree::
|
|
505
|
+
units = Spree::Config.stock.inventory_unit_builder_class.new(self).missing_units_for_line_item(line_item)
|
|
506
|
+
|
|
499
507
|
Spree::Config.stock.coordinator_class.new(self, units).shipments.each do |shipment|
|
|
500
508
|
shipments << shipment
|
|
501
509
|
end
|
|
@@ -526,7 +534,7 @@ module Spree
|
|
|
526
534
|
state: 'cart',
|
|
527
535
|
updated_at: Time.current
|
|
528
536
|
)
|
|
529
|
-
next
|
|
537
|
+
self.next
|
|
530
538
|
end
|
|
531
539
|
|
|
532
540
|
def refresh_shipment_rates
|
|
@@ -741,6 +749,27 @@ module Spree
|
|
|
741
749
|
end
|
|
742
750
|
end
|
|
743
751
|
|
|
752
|
+
# Finalizes an in progress order after checkout is complete.
|
|
753
|
+
# Called after transition to complete state when payments will have been processed
|
|
754
|
+
def finalize
|
|
755
|
+
# lock all adjustments (coupon promotions, etc.)
|
|
756
|
+
all_adjustments.each(&:finalize!)
|
|
757
|
+
|
|
758
|
+
# update payment and shipment(s) states, and save
|
|
759
|
+
updater.update_payment_state
|
|
760
|
+
shipments.each do |shipment|
|
|
761
|
+
shipment.update_state
|
|
762
|
+
shipment.finalize!
|
|
763
|
+
end
|
|
764
|
+
|
|
765
|
+
updater.update_shipment_state
|
|
766
|
+
save!
|
|
767
|
+
|
|
768
|
+
touch :completed_at
|
|
769
|
+
|
|
770
|
+
Spree::Bus.publish :order_finalized, order: self
|
|
771
|
+
end
|
|
772
|
+
|
|
744
773
|
def associate_store
|
|
745
774
|
self.store ||= Spree::Store.default
|
|
746
775
|
end
|
|
@@ -761,9 +790,12 @@ module Spree
|
|
|
761
790
|
|
|
762
791
|
def ensure_inventory_units
|
|
763
792
|
if has_checkout_step?("delivery")
|
|
764
|
-
inventory_validator = Spree::
|
|
793
|
+
inventory_validator = Spree::Config.stock.inventory_validator_class.new
|
|
794
|
+
|
|
795
|
+
errors = line_items.map { |line_item|
|
|
796
|
+
inventory_validator.validate(line_item)
|
|
797
|
+
}.compact
|
|
765
798
|
|
|
766
|
-
errors = line_items.map { |line_item| inventory_validator.validate(line_item) }.compact
|
|
767
799
|
raise InsufficientStock if errors.any?
|
|
768
800
|
end
|
|
769
801
|
end
|
|
@@ -781,8 +813,15 @@ module Spree
|
|
|
781
813
|
end
|
|
782
814
|
|
|
783
815
|
def validate_line_item_availability
|
|
784
|
-
availability_validator = Spree::
|
|
785
|
-
|
|
816
|
+
availability_validator = Spree::Config.stock.availability_validator_class.new
|
|
817
|
+
|
|
818
|
+
# NOTE: This code assumes that the availability validator will return
|
|
819
|
+
# true for success and false for failure. This is not normally the
|
|
820
|
+
# behaviour of validators, as the framework only cares about the
|
|
821
|
+
# population of the errors, not the return value of the validate method.
|
|
822
|
+
raise InsufficientStock unless line_items.all? { |line_item|
|
|
823
|
+
availability_validator.validate(line_item)
|
|
824
|
+
}
|
|
786
825
|
end
|
|
787
826
|
|
|
788
827
|
def ensure_line_items_present
|
|
@@ -42,8 +42,8 @@ module Spree
|
|
|
42
42
|
# If we do not update first, then the item total will be wrong and ItemTotal
|
|
43
43
|
# promotion rules would not be triggered.
|
|
44
44
|
reload_totals
|
|
45
|
-
PromotionHandler::Cart.new(order).activate
|
|
46
45
|
order.ensure_updated_shipments
|
|
46
|
+
PromotionHandler::Cart.new(order).activate
|
|
47
47
|
end
|
|
48
48
|
reload_totals
|
|
49
49
|
true
|
|
@@ -89,6 +89,7 @@ module Spree
|
|
|
89
89
|
line_item ||= order.line_items.new(
|
|
90
90
|
quantity: 0,
|
|
91
91
|
variant: variant,
|
|
92
|
+
adjustments: [],
|
|
92
93
|
)
|
|
93
94
|
|
|
94
95
|
line_item.quantity += quantity.to_i
|
|
@@ -62,7 +62,7 @@ module Spree
|
|
|
62
62
|
potential_shipments.detect do |shipment|
|
|
63
63
|
shipment.include?(variant)
|
|
64
64
|
end || potential_shipments.detect do |shipment|
|
|
65
|
-
stock_item =
|
|
65
|
+
stock_item = variant.stock_items.detect { |stock_item| stock_item.stock_location == shipment.stock_location }
|
|
66
66
|
if stock_item
|
|
67
67
|
stock_item.backorderable? || stock_item.count_on_hand >= quantity
|
|
68
68
|
end
|
|
@@ -115,8 +115,8 @@ module Spree
|
|
|
115
115
|
current_line_item.quantity += other_order_line_item.quantity
|
|
116
116
|
handle_error(current_line_item) unless current_line_item.save
|
|
117
117
|
else
|
|
118
|
-
order.line_items
|
|
119
|
-
handle_error(
|
|
118
|
+
new_line_item = order.line_items.build(other_order_line_item.attributes.except("id"))
|
|
119
|
+
handle_error(new_line_item) unless new_line_item.save
|
|
120
120
|
end
|
|
121
121
|
end
|
|
122
122
|
|
|
@@ -17,13 +17,15 @@ module Spree
|
|
|
17
17
|
|
|
18
18
|
# Apply taxes to the order.
|
|
19
19
|
#
|
|
20
|
-
# This method will create or update adjustments on all line
|
|
21
|
-
# shipments in the order to reflect the appropriate taxes passed
|
|
22
|
-
# will also remove any now inapplicable tax adjustments.
|
|
20
|
+
# This method will create or update adjustments on the order and all line
|
|
21
|
+
# items and shipments in the order to reflect the appropriate taxes passed
|
|
22
|
+
# in. It will also remove any now inapplicable tax adjustments.
|
|
23
23
|
#
|
|
24
24
|
# @param [Spree::Tax::OrderTax] taxes the taxes to apply to the order
|
|
25
25
|
# @return [void]
|
|
26
26
|
def apply(taxes)
|
|
27
|
+
update_adjustments(@order, taxes.order_taxes) if taxes.order_taxes
|
|
28
|
+
|
|
27
29
|
@order.line_items.each do |item|
|
|
28
30
|
taxed_items = taxes.line_item_taxes.select { |element| element.item_id == item.id }
|
|
29
31
|
update_adjustments(item, taxed_items)
|
|
@@ -70,7 +72,7 @@ module Spree
|
|
|
70
72
|
|
|
71
73
|
tax_adjustment ||= item.adjustments.new(
|
|
72
74
|
source: tax_item.tax_rate,
|
|
73
|
-
order_id: item.order_id,
|
|
75
|
+
order_id: item.is_a?(Spree::Order) ? item.id : item.order_id,
|
|
74
76
|
label: tax_item.label,
|
|
75
77
|
included: tax_item.included_in_price
|
|
76
78
|
)
|
|
@@ -26,7 +26,7 @@ module Spree
|
|
|
26
26
|
update_shipments
|
|
27
27
|
update_shipment_state
|
|
28
28
|
end
|
|
29
|
-
Spree::
|
|
29
|
+
Spree::Bus.publish :order_recalculated, order: order
|
|
30
30
|
persist_totals
|
|
31
31
|
end
|
|
32
32
|
end
|
|
@@ -157,10 +157,11 @@ module Spree
|
|
|
157
157
|
recalculate_adjustments
|
|
158
158
|
|
|
159
159
|
all_items = line_items + shipments
|
|
160
|
+
order_tax_adjustments = adjustments.select(&:eligible?).select(&:tax?)
|
|
160
161
|
|
|
161
162
|
order.adjustment_total = all_items.sum(&:adjustment_total) + adjustments.select(&:eligible?).sum(&:amount)
|
|
162
|
-
order.included_tax_total = all_items.sum(&:included_tax_total)
|
|
163
|
-
order.additional_tax_total = all_items.sum(&:additional_tax_total)
|
|
163
|
+
order.included_tax_total = all_items.sum(&:included_tax_total) + order_tax_adjustments.select(&:included?).sum(&:amount)
|
|
164
|
+
order.additional_tax_total = all_items.sum(&:additional_tax_total) + order_tax_adjustments.reject(&:included?).sum(&:amount)
|
|
164
165
|
|
|
165
166
|
order.promo_total = all_items.sum(&:promo_total) + adjustments.select(&:eligible?).select(&:promotion?).sum(&:amount)
|
|
166
167
|
|
|
@@ -13,6 +13,7 @@ module Spree
|
|
|
13
13
|
#
|
|
14
14
|
class PaymentMethod < Spree::Base
|
|
15
15
|
include Spree::Preferences::Persistable
|
|
16
|
+
class UnsupportedPaymentMethod < StandardError; end
|
|
16
17
|
|
|
17
18
|
preference :server, :string, default: 'test'
|
|
18
19
|
preference :test_mode, :boolean, default: true
|
|
@@ -60,6 +61,16 @@ module Spree
|
|
|
60
61
|
def model_name
|
|
61
62
|
ModelName.new(self, Spree)
|
|
62
63
|
end
|
|
64
|
+
|
|
65
|
+
def find_sti_class(type_name)
|
|
66
|
+
super(type_name)
|
|
67
|
+
rescue ActiveRecord::SubclassNotFound
|
|
68
|
+
raise UnsupportedPaymentMethod, "Found invalid payment type '#{type_name}'.\n"\
|
|
69
|
+
"This may happen after switching payment service provider, when payment methods "\
|
|
70
|
+
"reference old types that are not supported any more.\n"\
|
|
71
|
+
"If that is the case, consider running 'rake payment_method:deprecate_unsupported_payment_methods' "\
|
|
72
|
+
"to fix the issue."
|
|
73
|
+
end
|
|
63
74
|
end
|
|
64
75
|
|
|
65
76
|
# Represents the gateway of this payment method
|
data/app/models/spree/price.rb
CHANGED
|
@@ -194,13 +194,31 @@ module Spree
|
|
|
194
194
|
group("spree_products.id").joins(:taxons).where(Spree::Taxon.arel_table[:name].eq(name))
|
|
195
195
|
end
|
|
196
196
|
|
|
197
|
-
def self.
|
|
198
|
-
|
|
197
|
+
def self.with_all_variant_sku_cont(sku)
|
|
198
|
+
variant_table = Spree::Variant.arel_table
|
|
199
|
+
subquery = Spree::Variant.with_discarded.where(
|
|
200
|
+
variant_table[:sku].matches("%#{sku}%").and(
|
|
201
|
+
variant_table[:product_id].eq(arel_table[:id])
|
|
202
|
+
)
|
|
203
|
+
)
|
|
204
|
+
where(subquery.arel.exists)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def self.with_kept_variant_sku_cont(sku)
|
|
199
208
|
variant_table = Spree::Variant.arel_table
|
|
200
|
-
subquery = Spree::Variant.where(
|
|
209
|
+
subquery = Spree::Variant.where(
|
|
210
|
+
variant_table[:sku].matches("%#{sku}%").and(
|
|
211
|
+
variant_table[:product_id].eq(arel_table[:id])
|
|
212
|
+
)
|
|
213
|
+
)
|
|
201
214
|
where(subquery.arel.exists)
|
|
202
215
|
end
|
|
203
216
|
|
|
217
|
+
def self.with_variant_sku_cont(sku)
|
|
218
|
+
Spree::Deprecation.warn("use .with_kept_variant_sku_cont instead")
|
|
219
|
+
with_kept_variant_sku_cont(sku)
|
|
220
|
+
end
|
|
221
|
+
|
|
204
222
|
class << self
|
|
205
223
|
private
|
|
206
224
|
|
data/app/models/spree/product.rb
CHANGED
|
@@ -135,7 +135,7 @@ module Spree
|
|
|
135
135
|
self.whitelisted_ransackable_attributes = %w[name slug]
|
|
136
136
|
|
|
137
137
|
def self.ransackable_scopes(_auth_object = nil)
|
|
138
|
-
%i(with_discarded with_variant_sku_cont)
|
|
138
|
+
%i(with_discarded with_variant_sku_cont with_all_variant_sku_cont with_kept_variant_sku_cont)
|
|
139
139
|
end
|
|
140
140
|
|
|
141
141
|
# @return [Boolean] true if there are any variants
|
|
@@ -15,6 +15,10 @@ module Spree
|
|
|
15
15
|
before_destroy :remove_adjustments_from_incomplete_orders
|
|
16
16
|
before_discard :remove_adjustments_from_incomplete_orders
|
|
17
17
|
|
|
18
|
+
def preload_relations
|
|
19
|
+
[:calculator]
|
|
20
|
+
end
|
|
21
|
+
|
|
18
22
|
# Creates the adjustment related to a promotion for the order passed
|
|
19
23
|
# through options hash
|
|
20
24
|
#
|
|
@@ -15,6 +15,10 @@ module Spree
|
|
|
15
15
|
before_destroy :remove_adjustments_from_incomplete_orders
|
|
16
16
|
before_discard :remove_adjustments_from_incomplete_orders
|
|
17
17
|
|
|
18
|
+
def preload_relations
|
|
19
|
+
[:calculator]
|
|
20
|
+
end
|
|
21
|
+
|
|
18
22
|
def perform(payload = {})
|
|
19
23
|
order = payload[:order]
|
|
20
24
|
promotion = payload[:promotion]
|
|
@@ -83,13 +87,8 @@ module Spree
|
|
|
83
87
|
end
|
|
84
88
|
|
|
85
89
|
def line_items_to_adjust(promotion, order)
|
|
86
|
-
excluded_ids = adjustments.
|
|
87
|
-
where(adjustable_id: order.line_items.pluck(:id), adjustable_type: 'Spree::LineItem').
|
|
88
|
-
pluck(:adjustable_id).
|
|
89
|
-
to_set
|
|
90
|
-
|
|
91
90
|
order.line_items.select do |line_item|
|
|
92
|
-
|
|
91
|
+
line_item.adjustments.none? { |adjustment| adjustment.source == self } &&
|
|
93
92
|
promotion.line_item_actionable?(order, line_item)
|
|
94
93
|
end
|
|
95
94
|
end
|
|
@@ -12,6 +12,10 @@ module Spree
|
|
|
12
12
|
class_name: 'Spree::ProductPromotionRule'
|
|
13
13
|
has_many :products, class_name: 'Spree::Product', through: :product_promotion_rules
|
|
14
14
|
|
|
15
|
+
def preload_relations
|
|
16
|
+
[:products]
|
|
17
|
+
end
|
|
18
|
+
|
|
15
19
|
MATCH_POLICIES = %w(any all none)
|
|
16
20
|
|
|
17
21
|
validates_inclusion_of :preferred_match_policy, in: MATCH_POLICIES
|
|
@@ -31,17 +35,19 @@ module Spree
|
|
|
31
35
|
return true if eligible_products.empty?
|
|
32
36
|
|
|
33
37
|
case preferred_match_policy
|
|
34
|
-
when
|
|
35
|
-
unless eligible_products.all? { |product| order.
|
|
38
|
+
when "all"
|
|
39
|
+
unless eligible_products.all? { |product| order_products(order).include?(product) }
|
|
36
40
|
eligibility_errors.add(:base, eligibility_error_message(:missing_product), error_code: :missing_product)
|
|
37
41
|
end
|
|
38
|
-
when
|
|
39
|
-
unless order.
|
|
40
|
-
eligibility_errors.add(:base, eligibility_error_message(:no_applicable_products),
|
|
42
|
+
when "any"
|
|
43
|
+
unless order_products(order).any? { |product| eligible_products.include?(product) }
|
|
44
|
+
eligibility_errors.add(:base, eligibility_error_message(:no_applicable_products),
|
|
45
|
+
error_code: :no_applicable_products)
|
|
41
46
|
end
|
|
42
|
-
when
|
|
43
|
-
unless order.
|
|
44
|
-
eligibility_errors.add(:base, eligibility_error_message(:has_excluded_product),
|
|
47
|
+
when "none"
|
|
48
|
+
unless order_products(order).none? { |product| eligible_products.include?(product) }
|
|
49
|
+
eligibility_errors.add(:base, eligibility_error_message(:has_excluded_product),
|
|
50
|
+
error_code: :has_excluded_product)
|
|
45
51
|
end
|
|
46
52
|
else
|
|
47
53
|
raise "unexpected match policy: #{preferred_match_policy.inspect}"
|
|
@@ -68,6 +74,12 @@ module Spree
|
|
|
68
74
|
def product_ids_string=(product_ids)
|
|
69
75
|
self.product_ids = product_ids.to_s.split(',').map(&:strip)
|
|
70
76
|
end
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
|
|
80
|
+
def order_products(order)
|
|
81
|
+
order.line_items.map(&:variant).map(&:product)
|
|
82
|
+
end
|
|
71
83
|
end
|
|
72
84
|
end
|
|
73
85
|
end
|