solidus_core 3.0.2 → 3.1.3
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.
Potentially problematic release.
This version of solidus_core might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/app/helpers/spree/base_helper.rb +1 -1
- data/app/helpers/spree/products_helper.rb +1 -1
- data/app/models/concerns/spree/default_price.rb +63 -10
- data/app/models/spree/adjustment.rb +6 -5
- data/app/models/spree/customer_return.rb +3 -2
- data/app/models/spree/image/active_storage_attachment.rb +2 -7
- data/app/models/spree/image/paperclip_attachment.rb +2 -2
- data/app/models/spree/line_item.rb +2 -2
- data/app/models/spree/order.rb +11 -6
- data/app/models/spree/price.rb +1 -1
- data/app/models/spree/product/scopes.rb +5 -5
- data/app/models/spree/product.rb +12 -0
- data/app/models/spree/promotion/rules/item_total.rb +50 -6
- data/app/models/spree/promotion.rb +2 -2
- data/app/models/spree/promotion_code.rb +1 -1
- data/app/models/spree/shipping_rate_tax.rb +1 -1
- data/app/models/spree/stock/availability.rb +11 -3
- data/app/models/spree/stock/simple_coordinator.rb +0 -10
- data/app/models/spree/stock_location.rb +1 -1
- data/app/models/spree/store_credit.rb +6 -1
- data/app/models/spree/tax_calculator/shipping_rate.rb +1 -1
- data/app/models/spree/taxon/active_storage_attachment.rb +2 -2
- data/app/models/spree/taxon/paperclip_attachment.rb +3 -3
- data/app/models/spree/variant/price_selector.rb +16 -3
- data/app/models/spree/variant.rb +26 -16
- data/config/locales/en.yml +2 -0
- data/db/migrate/20210312061050_change_column_null_on_prices.rb +7 -0
- data/lib/generators/solidus/install/install_generator.rb +1 -1
- data/lib/generators/solidus/install/templates/config/initializers/spree.rb.tt +3 -1
- data/lib/generators/solidus/update/templates/config/initializers/new_solidus_defaults.rb.tt +30 -0
- data/lib/generators/solidus/update/update_generator.rb +112 -0
- data/lib/generators/spree/dummy/templates/rails/application.rb.tt +0 -1
- data/lib/generators/spree/dummy/templates/rails/database.yml +78 -35
- data/lib/spree/app_configuration.rb +62 -0
- data/lib/spree/core/engine.rb +16 -9
- data/lib/spree/core/product_filters.rb +1 -1
- data/lib/spree/core/search/base.rb +1 -1
- data/lib/spree/core/state_machines/order.rb +1 -1
- data/lib/spree/core/version.rb +5 -1
- data/lib/spree/core/versioned_value.rb +75 -0
- data/lib/spree/core.rb +28 -0
- data/lib/spree/permitted_attributes.rb +1 -1
- data/lib/spree/preferences/configuration.rb +62 -0
- data/lib/spree/preferences/preferable.rb +8 -0
- data/lib/spree/preferences/preferable_class_methods.rb +37 -4
- data/lib/spree/preferences/preference_differentiator.rb +28 -0
- data/lib/spree/testing_support/dummy_app/database.yml +42 -22
- data/lib/spree/testing_support/dummy_app.rb +33 -18
- data/lib/tasks/solidus/delete_prices_with_nil_amount.rake +8 -0
- data/solidus_core.gemspec +6 -1
- metadata +17 -8
- data/app/models/spree/tax/shipping_rate_taxer.rb +0 -24
- data/lib/tasks/upgrade.rake +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 25d076da4eef33c845f1da39a5bb6e7b6164c98372bc59f1d9cd441fc182576a
|
4
|
+
data.tar.gz: f4b6369b678db721bd71e67323468e376e6ab59bfb67cb766cbc05927a42cc7c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5eec6a669e66e4fb3c2a492844ff0e73c60e06b14b959f9ea868995e2f5e766f1a6493da85ef3494e726e0ddbbc483dc93b524d4a07be31305edde61fe917d24
|
7
|
+
data.tar.gz: aae29e7ece97dde8df64e368e2bddf5c9bd95cc5118a345d343d8625234355e15b9edf055f9aac7bca2d048235cff6b77de4cfcbd7ae81b544769924d7aa4c89
|
@@ -130,7 +130,7 @@ module Spree
|
|
130
130
|
end
|
131
131
|
|
132
132
|
def display_price(product_or_variant)
|
133
|
-
product_or_variant.
|
133
|
+
product_or_variant.price_for_options(current_pricing_options)&.money&.to_html
|
134
134
|
end
|
135
135
|
|
136
136
|
def pretty_time(time, format = :long)
|
@@ -38,7 +38,7 @@ module Spree
|
|
38
38
|
.with_prices(current_pricing_options)
|
39
39
|
.all? { |variant_with_prices| variant_with_prices.price_same_as_master?(current_pricing_options) }
|
40
40
|
|
41
|
-
variant.
|
41
|
+
variant.price_for_options(current_pricing_options)&.money&.to_html
|
42
42
|
end
|
43
43
|
|
44
44
|
# Converts line breaks in product description into <p> tags.
|
@@ -5,23 +5,76 @@ module Spree
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
7
|
included do
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
delegate :display_price, :display_amount, :price, to: :default_price, allow_nil: true
|
9
|
+
delegate :price=, to: :default_price_or_build
|
10
|
+
|
11
|
+
# @see Spree::Variant::PricingOptions.default_price_attributes
|
12
|
+
def self.default_price_attributes
|
13
|
+
Spree::Config.default_pricing_options.desired_attributes
|
14
|
+
end
|
14
15
|
end
|
15
16
|
|
16
|
-
|
17
|
-
|
17
|
+
# Returns `#prices` prioritized for being considered as default price
|
18
|
+
#
|
19
|
+
# @return [ActiveRecord::Relation<Spree::Price>]
|
20
|
+
def currently_valid_prices
|
21
|
+
prices.currently_valid
|
18
22
|
end
|
19
23
|
|
20
|
-
|
21
|
-
|
24
|
+
# Returns {#default_price} or builds it from {Spree::Variant.default_price_attributes}
|
25
|
+
#
|
26
|
+
# @return [Spree::Price, nil]
|
27
|
+
# @see Spree::Variant.default_price_attributes
|
28
|
+
def default_price_or_build
|
29
|
+
default_price ||
|
30
|
+
prices.build(self.class.default_price_attributes)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Select from {#prices} the one to be considered as the default
|
34
|
+
#
|
35
|
+
# This method works with the in-memory association, so non-persisted prices
|
36
|
+
# are taken into account. Discarded prices are also considered.
|
37
|
+
#
|
38
|
+
# A price is a candidate to be considered as the default when it meets
|
39
|
+
# {Spree::Variant.default_price_attributes} criteria. When more than one candidate is
|
40
|
+
# found, non-persisted records take preference. When more than one persisted
|
41
|
+
# candidate exists, the one most recently updated is taken or, in case of
|
42
|
+
# race condition, the one with higher id.
|
43
|
+
#
|
44
|
+
# @return [Spree::Price, nil]
|
45
|
+
# @see Spree::Variant.default_price_attributes
|
46
|
+
def default_price
|
47
|
+
prioritized_default(
|
48
|
+
prices_meeting_criteria_to_be_default(
|
49
|
+
(prices + prices.with_discarded).uniq
|
50
|
+
)
|
51
|
+
)
|
52
|
+
end
|
22
53
|
|
23
54
|
def has_default_price?
|
24
55
|
default_price.present? && !default_price.discarded?
|
25
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
|
26
79
|
end
|
27
80
|
end
|
@@ -55,11 +55,12 @@ module Spree
|
|
55
55
|
#
|
56
56
|
# @param excluded_orders [Array<Spree::Order>] Orders to exclude from query
|
57
57
|
# @return [ActiveRecord::Relation] Scoped Adjustments
|
58
|
-
def self.in_completed_orders(excluded_orders: [])
|
59
|
-
joins(:order)
|
60
|
-
|
61
|
-
|
62
|
-
|
58
|
+
def self.in_completed_orders(excluded_orders: [], exclude_canceled: false)
|
59
|
+
result = joins(:order)
|
60
|
+
.merge(Spree::Order.complete)
|
61
|
+
.where.not(spree_orders: { id: excluded_orders })
|
62
|
+
.distinct
|
63
|
+
exclude_canceled ? result.merge(Spree::Order.not_canceled) : result
|
63
64
|
end
|
64
65
|
|
65
66
|
def finalize!
|
@@ -40,7 +40,8 @@ module Spree
|
|
40
40
|
# Temporarily tie a customer_return to one order
|
41
41
|
def order
|
42
42
|
return nil if return_items.blank?
|
43
|
-
|
43
|
+
|
44
|
+
return_items.first.inventory_unit&.order
|
44
45
|
end
|
45
46
|
|
46
47
|
def fully_reimbursed?
|
@@ -65,7 +66,7 @@ module Spree
|
|
65
66
|
end
|
66
67
|
|
67
68
|
def return_items_belong_to_same_order
|
68
|
-
if return_items.reject{ |return_item| return_item.inventory_unit
|
69
|
+
if return_items.reject{ |return_item| return_item.inventory_unit&.order_id == order_id }.any?
|
69
70
|
errors.add(:base, I18n.t('spree.return_items_cannot_be_associated_with_multiple_orders'))
|
70
71
|
end
|
71
72
|
end
|
@@ -12,13 +12,8 @@ module Spree::Image::ActiveStorageAttachment
|
|
12
12
|
validate :supported_content_type
|
13
13
|
|
14
14
|
has_attachment :attachment,
|
15
|
-
styles:
|
16
|
-
|
17
|
-
small: '400x400>',
|
18
|
-
product: '680x680>',
|
19
|
-
large: '1200x1200>'
|
20
|
-
},
|
21
|
-
default_style: :product
|
15
|
+
styles: Spree::Config.product_image_styles,
|
16
|
+
default_style: Spree::Config.product_image_style_default
|
22
17
|
|
23
18
|
def supported_content_type
|
24
19
|
unless attachment.content_type.in?(Spree::Config.allowed_image_mime_types)
|
@@ -7,8 +7,8 @@ module Spree::Image::PaperclipAttachment
|
|
7
7
|
validate :no_attachment_errors
|
8
8
|
|
9
9
|
has_attached_file :attachment,
|
10
|
-
styles:
|
11
|
-
default_style:
|
10
|
+
styles: Spree::Config.product_image_styles,
|
11
|
+
default_style: Spree::Config.product_image_style_default,
|
12
12
|
default_url: 'noimage/:style.png',
|
13
13
|
url: '/spree/products/:id/:style/:basename.:extension',
|
14
14
|
path: ':rails_root/public/spree/products/:id/:style/:basename.:extension',
|
@@ -123,7 +123,7 @@ module Spree
|
|
123
123
|
# a price for this line item, even if there is no existing price
|
124
124
|
# for the associated line item in the order currency.
|
125
125
|
unless options.key?(:price) || options.key?('price')
|
126
|
-
self.money_price = variant.
|
126
|
+
self.money_price = variant.price_for_options(pricing_options)&.money
|
127
127
|
end
|
128
128
|
end
|
129
129
|
|
@@ -149,7 +149,7 @@ module Spree
|
|
149
149
|
# Set price, cost_price and currency.
|
150
150
|
def set_pricing_attributes
|
151
151
|
self.cost_price ||= variant.cost_price
|
152
|
-
self.money_price = variant.
|
152
|
+
self.money_price = variant.price_for_options(pricing_options)&.money if price.nil?
|
153
153
|
true
|
154
154
|
end
|
155
155
|
|
data/app/models/spree/order.rb
CHANGED
@@ -51,7 +51,7 @@ module Spree
|
|
51
51
|
end
|
52
52
|
|
53
53
|
self.whitelisted_ransackable_associations = %w[shipments user order_promotions promotions bill_address ship_address line_items]
|
54
|
-
self.whitelisted_ransackable_attributes = %w[
|
54
|
+
self.whitelisted_ransackable_attributes = %w[completed_at created_at email number state payment_state shipment_state total store_id]
|
55
55
|
|
56
56
|
attr_reader :coupon_code
|
57
57
|
attr_accessor :temporary_address
|
@@ -128,7 +128,7 @@ module Spree
|
|
128
128
|
before_create :create_token
|
129
129
|
before_create :link_by_email
|
130
130
|
|
131
|
-
validates :email, presence: true, if: :
|
131
|
+
validates :email, presence: true, if: :email_required?
|
132
132
|
validates :email, 'spree/email' => true, allow_blank: true
|
133
133
|
validates :guest_token, presence: { allow_nil: true }
|
134
134
|
validates :number, presence: true, uniqueness: { allow_blank: true, case_sensitive: true }
|
@@ -269,15 +269,15 @@ module Spree
|
|
269
269
|
end
|
270
270
|
|
271
271
|
def contents
|
272
|
-
@contents ||= Spree::
|
272
|
+
@contents ||= Spree::Config.order_contents_class.new(self)
|
273
273
|
end
|
274
274
|
|
275
275
|
def shipping
|
276
|
-
@shipping ||= Spree::
|
276
|
+
@shipping ||= Spree::Config.order_shipping_class.new(self)
|
277
277
|
end
|
278
278
|
|
279
279
|
def cancellations
|
280
|
-
@cancellations ||= Spree::
|
280
|
+
@cancellations ||= Spree::Config.order_cancellations_class.new(self)
|
281
281
|
end
|
282
282
|
|
283
283
|
# Associates the specified user with the order.
|
@@ -750,10 +750,15 @@ module Spree
|
|
750
750
|
end
|
751
751
|
|
752
752
|
# Determine if email is required (we don't want validation errors before we hit the checkout)
|
753
|
-
def
|
753
|
+
def email_required?
|
754
754
|
true unless new_record? || ['cart', 'address'].include?(state)
|
755
755
|
end
|
756
756
|
|
757
|
+
def require_email
|
758
|
+
Spree::Deprecation.warn "Use email_required? instead", caller(1)
|
759
|
+
email_required?
|
760
|
+
end
|
761
|
+
|
757
762
|
def ensure_inventory_units
|
758
763
|
if has_checkout_step?("delivery")
|
759
764
|
inventory_validator = Spree::Stock::InventoryValidator.new
|
data/app/models/spree/price.rb
CHANGED
@@ -29,25 +29,25 @@ module Spree
|
|
29
29
|
scope :descend_by_name, -> { order(name: :desc) }
|
30
30
|
|
31
31
|
add_search_scope :ascend_by_master_price do
|
32
|
-
joins(master: :
|
32
|
+
joins(master: :prices).select('spree_products.* , spree_prices.amount')
|
33
33
|
.order(Spree::Price.arel_table[:amount].asc)
|
34
34
|
end
|
35
35
|
|
36
36
|
add_search_scope :descend_by_master_price do
|
37
|
-
joins(master: :
|
37
|
+
joins(master: :prices).select('spree_products.* , spree_prices.amount')
|
38
38
|
.order(Spree::Price.arel_table[:amount].desc)
|
39
39
|
end
|
40
40
|
|
41
41
|
add_search_scope :price_between do |low, high|
|
42
|
-
joins(master: :
|
42
|
+
joins(master: :prices).where(Price.table_name => { amount: low..high })
|
43
43
|
end
|
44
44
|
|
45
45
|
add_search_scope :master_price_lte do |price|
|
46
|
-
joins(master: :
|
46
|
+
joins(master: :prices).where("#{price_table_name}.amount <= ?", price)
|
47
47
|
end
|
48
48
|
|
49
49
|
add_search_scope :master_price_gte do |price|
|
50
|
-
joins(master: :
|
50
|
+
joins(master: :prices).where("#{price_table_name}.amount >= ?", price)
|
51
51
|
end
|
52
52
|
|
53
53
|
# This scope selects products in taxon AND all its descendants
|
data/app/models/spree/product.rb
CHANGED
@@ -60,6 +60,17 @@ module Spree
|
|
60
60
|
has_many :line_items, through: :variants_including_master
|
61
61
|
has_many :orders, through: :line_items
|
62
62
|
|
63
|
+
scope :sort_by_master_default_price_amount_asc, -> {
|
64
|
+
with_default_price.order('spree_prices.amount ASC')
|
65
|
+
}
|
66
|
+
scope :sort_by_master_default_price_amount_desc, -> {
|
67
|
+
with_default_price.order('spree_prices.amount DESC')
|
68
|
+
}
|
69
|
+
scope :with_default_price, -> {
|
70
|
+
left_joins(master: :prices)
|
71
|
+
.where(master: { spree_prices: Spree::Config.default_pricing_options.desired_attributes })
|
72
|
+
}
|
73
|
+
|
63
74
|
def find_or_build_master
|
64
75
|
master || build_master
|
65
76
|
end
|
@@ -84,6 +95,7 @@ module Spree
|
|
84
95
|
:has_default_price?,
|
85
96
|
:images,
|
86
97
|
:price_for,
|
98
|
+
:price_for_options,
|
87
99
|
:rebuild_vat_prices=,
|
88
100
|
to: :find_or_build_master
|
89
101
|
|
@@ -5,12 +5,38 @@ module Spree
|
|
5
5
|
module Rules
|
6
6
|
# A rule to apply to an order greater than (or greater than or equal to)
|
7
7
|
# a specific amount
|
8
|
+
#
|
9
|
+
# To add extra operators please override `self.operators_map` or any other helper method.
|
10
|
+
# To customize the error message you can also override `ineligible_message`.
|
8
11
|
class ItemTotal < PromotionRule
|
12
|
+
include ActiveSupport::Deprecation::DeprecatedConstantAccessor
|
13
|
+
|
9
14
|
preference :amount, :decimal, default: 100.00
|
10
15
|
preference :currency, :string, default: ->{ Spree::Config[:currency] }
|
11
|
-
preference :operator, :string, default: '
|
16
|
+
preference :operator, :string, default: 'gt'
|
17
|
+
|
18
|
+
# The list of allowed operators names mapped to their symbols.
|
19
|
+
def self.operators_map
|
20
|
+
{
|
21
|
+
gte: :>=,
|
22
|
+
gt: :>,
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.operator_options
|
27
|
+
operators_map.map do |name, _method|
|
28
|
+
[I18n.t(name, scope: 'spree.item_total_rule.operators'), name]
|
29
|
+
end
|
30
|
+
end
|
12
31
|
|
13
|
-
|
32
|
+
# @deprecated
|
33
|
+
OPERATORS = operators_map.keys.map(&:to_s)
|
34
|
+
deprecate_constant(
|
35
|
+
:OPERATORS,
|
36
|
+
:operators_map,
|
37
|
+
message: "OPERATORS is deprecated! Use `operators_map.keys.map(&:to_s)` instead.",
|
38
|
+
deprecator: Spree::Deprecation,
|
39
|
+
)
|
14
40
|
|
15
41
|
def applicable?(promotable)
|
16
42
|
promotable.is_a?(Spree::Order)
|
@@ -18,8 +44,8 @@ module Spree
|
|
18
44
|
|
19
45
|
def eligible?(order, _options = {})
|
20
46
|
return false unless order.currency == preferred_currency
|
21
|
-
|
22
|
-
unless
|
47
|
+
|
48
|
+
unless total_for_order(order).send(operator, threshold)
|
23
49
|
eligibility_errors.add(:base, ineligible_message, error_code: ineligible_error_code)
|
24
50
|
end
|
25
51
|
|
@@ -28,15 +54,33 @@ module Spree
|
|
28
54
|
|
29
55
|
private
|
30
56
|
|
57
|
+
def operator
|
58
|
+
self.class.operators_map.fetch(
|
59
|
+
preferred_operator.to_sym,
|
60
|
+
preferred_operator_default,
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
def total_for_order(order)
|
65
|
+
order.item_total
|
66
|
+
end
|
67
|
+
|
68
|
+
def threshold
|
69
|
+
BigDecimal(preferred_amount.to_s)
|
70
|
+
end
|
71
|
+
|
31
72
|
def formatted_amount
|
32
73
|
Spree::Money.new(preferred_amount, currency: preferred_currency).to_s
|
33
74
|
end
|
34
75
|
|
35
76
|
def ineligible_message
|
36
|
-
|
77
|
+
case preferred_operator.to_s
|
78
|
+
when 'gte'
|
37
79
|
eligibility_error_message(:item_total_less_than, amount: formatted_amount)
|
38
|
-
|
80
|
+
when 'gt'
|
39
81
|
eligibility_error_message(:item_total_less_than_or_equal, amount: formatted_amount)
|
82
|
+
else
|
83
|
+
eligibility_error_message(:item_total_doesnt_match_with_operator, amount: formatted_amount, operator: preferred_operator)
|
40
84
|
end
|
41
85
|
end
|
42
86
|
|
@@ -47,7 +47,7 @@ module Spree
|
|
47
47
|
where(table[:expires_at].eq(nil).or(table[:expires_at].gt(time)))
|
48
48
|
end
|
49
49
|
scope :has_actions, -> do
|
50
|
-
joins(:promotion_actions)
|
50
|
+
joins(:promotion_actions).distinct
|
51
51
|
end
|
52
52
|
scope :applied, -> { joins(:order_promotions).distinct }
|
53
53
|
|
@@ -192,7 +192,7 @@ module Spree
|
|
192
192
|
def usage_count(excluded_orders: [])
|
193
193
|
Spree::Adjustment.promotion.
|
194
194
|
eligible.
|
195
|
-
in_completed_orders(excluded_orders: excluded_orders).
|
195
|
+
in_completed_orders(excluded_orders: excluded_orders, exclude_canceled: true).
|
196
196
|
where(source_id: actions).
|
197
197
|
count(:order_id)
|
198
198
|
end
|
@@ -30,7 +30,7 @@ class Spree::PromotionCode < Spree::Base
|
|
30
30
|
def usage_count(excluded_orders: [])
|
31
31
|
adjustments.
|
32
32
|
eligible.
|
33
|
-
in_completed_orders(excluded_orders: excluded_orders).
|
33
|
+
in_completed_orders(excluded_orders: excluded_orders, exclude_canceled: true).
|
34
34
|
count(:order_id)
|
35
35
|
end
|
36
36
|
|
@@ -5,7 +5,7 @@ module Spree
|
|
5
5
|
# @attr [Spree::ShippingRate] shipping_rate The shipping rate to be taxed
|
6
6
|
# @attr [Spree::TaxRate] tax_rate The tax rate used to calculate the tax amount
|
7
7
|
# @since 1.3.0
|
8
|
-
# @see Spree::
|
8
|
+
# @see Spree::Stock::Estimator
|
9
9
|
class ShippingRateTax < Spree::Base
|
10
10
|
belongs_to :shipping_rate, class_name: "Spree::ShippingRate", optional: true
|
11
11
|
belongs_to :tax_rate, class_name: "Spree::TaxRate", optional: true
|
@@ -19,7 +19,7 @@ module Spree
|
|
19
19
|
# Get the on_hand stock quantities
|
20
20
|
# @return [Hash<Integer=>Spree::StockQuantities>] A map of stock_location_ids to the stock quantities available in that location
|
21
21
|
def on_hand_by_stock_location_id
|
22
|
-
counts_on_hand.to_a.group_by do |(_, stock_location_id), _|
|
22
|
+
quantities_by_location_id = counts_on_hand.to_a.group_by do |(_, stock_location_id), _|
|
23
23
|
stock_location_id
|
24
24
|
end.transform_values do |values|
|
25
25
|
Spree::StockQuantities.new(
|
@@ -31,12 +31,13 @@ module Spree
|
|
31
31
|
end.to_h
|
32
32
|
)
|
33
33
|
end
|
34
|
+
restore_location_order(quantities_by_location_id)
|
34
35
|
end
|
35
36
|
|
36
|
-
# Get the
|
37
|
+
# Get the backorderable stock quantities
|
37
38
|
# @return [Hash<Integer=>Spree::StockQuantities>] A map of stock_location_ids to the stock quantities available in that location
|
38
39
|
def backorderable_by_stock_location_id
|
39
|
-
backorderables.group_by(&:second).transform_values do |variant_ids|
|
40
|
+
quantities_by_location_id = backorderables.group_by(&:second).transform_values do |variant_ids|
|
40
41
|
Spree::StockQuantities.new(
|
41
42
|
variant_ids.map do |variant_id, _|
|
42
43
|
variant = @variant_map[variant_id]
|
@@ -44,6 +45,7 @@ module Spree
|
|
44
45
|
end.to_h
|
45
46
|
)
|
46
47
|
end
|
48
|
+
restore_location_order(quantities_by_location_id)
|
47
49
|
end
|
48
50
|
|
49
51
|
private
|
@@ -67,6 +69,12 @@ module Spree
|
|
67
69
|
where(variant_id: @variants).
|
68
70
|
where(stock_location_id: @stock_locations)
|
69
71
|
end
|
72
|
+
|
73
|
+
def restore_location_order(quantities_by_location_id)
|
74
|
+
sorted_location_ids = @stock_locations.map(&:id)
|
75
|
+
|
76
|
+
quantities_by_location_id.sort_by { |key, _value| sorted_location_ids.index(key) }.to_h
|
77
|
+
end
|
70
78
|
end
|
71
79
|
end
|
72
80
|
end
|
@@ -92,16 +92,6 @@ module Spree
|
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
95
|
-
def sort_availability(availability)
|
96
|
-
sorted_availability = availability.sort_by do |stock_location_id, _|
|
97
|
-
@stock_locations.find_index do |stock_location|
|
98
|
-
stock_location.id == stock_location_id
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
Hash[sorted_availability]
|
103
|
-
end
|
104
|
-
|
105
95
|
def get_units(quantities)
|
106
96
|
# Change our raw quantities back into inventory units
|
107
97
|
quantities.flat_map do |variant, quantity|
|
@@ -26,7 +26,7 @@ module Spree
|
|
26
26
|
validates_uniqueness_of :code, allow_blank: true, case_sensitive: false
|
27
27
|
|
28
28
|
scope :active, -> { where(active: true) }
|
29
|
-
scope :order_default, -> { order(default: :desc,
|
29
|
+
scope :order_default, -> { order(default: :desc, position: :asc) }
|
30
30
|
|
31
31
|
after_create :create_stock_items, if: :propagate_all_variants?
|
32
32
|
after_save :ensure_one_default
|
@@ -150,7 +150,12 @@ class Spree::StoreCredit < Spree::PaymentSource
|
|
150
150
|
end
|
151
151
|
|
152
152
|
def generate_authorization_code
|
153
|
-
|
153
|
+
[
|
154
|
+
id,
|
155
|
+
'SC',
|
156
|
+
Time.current.utc.strftime('%Y%m%d%H%M%S%6N'),
|
157
|
+
SecureRandom.uuid
|
158
|
+
].join('-')
|
154
159
|
end
|
155
160
|
|
156
161
|
def editable?
|
@@ -6,8 +6,8 @@ module Spree::Taxon::ActiveStorageAttachment
|
|
6
6
|
|
7
7
|
included do
|
8
8
|
has_attachment :icon,
|
9
|
-
styles:
|
10
|
-
default_style:
|
9
|
+
styles: Spree::Config.taxon_image_styles,
|
10
|
+
default_style: Spree::Config.taxon_image_style_default
|
11
11
|
validate :icon_is_an_image
|
12
12
|
end
|
13
13
|
end
|
@@ -5,14 +5,14 @@ module Spree::Taxon::PaperclipAttachment
|
|
5
5
|
|
6
6
|
included do
|
7
7
|
has_attached_file :icon,
|
8
|
-
styles:
|
9
|
-
default_style:
|
8
|
+
styles: Spree::Config.taxon_image_styles,
|
9
|
+
default_style: Spree::Config.taxon_image_style_default,
|
10
10
|
url: '/spree/taxons/:id/:style/:basename.:extension',
|
11
11
|
path: ':rails_root/public/spree/taxons/:id/:style/:basename.:extension',
|
12
12
|
default_url: '/assets/default_taxon.png'
|
13
13
|
|
14
14
|
validates_attachment :icon,
|
15
|
-
content_type: { content_type:
|
15
|
+
content_type: { content_type: Spree::Config.allowed_image_mime_types }
|
16
16
|
end
|
17
17
|
|
18
18
|
def icon_present?
|
@@ -26,11 +26,24 @@ module Spree
|
|
26
26
|
# @param [Spree::Variant::PricingOptions] price_options Pricing Options to abide by
|
27
27
|
# @return [Spree::Money, nil] The most specific price for this set of pricing options.
|
28
28
|
def price_for(price_options)
|
29
|
+
Spree::Deprecation.warn(
|
30
|
+
"price_for is deprecated and will be removed. The price_for method
|
31
|
+
should return a Spree::Price as described. Please use
|
32
|
+
#price_for_options and adjust your frontend code to explicitly call
|
33
|
+
&.money where required"
|
34
|
+
)
|
35
|
+
price_for_options(price_options)&.money
|
36
|
+
end
|
37
|
+
|
38
|
+
# The variant's Spree::Price record, given a set of pricing options
|
39
|
+
# @param [Spree::Variant::PricingOptions] price_options Pricing Options to abide by
|
40
|
+
# @return [Spree::Price, nil] The most specific price for this set of pricing options.
|
41
|
+
def price_for_options(price_options)
|
29
42
|
variant.currently_valid_prices.detect do |price|
|
30
|
-
(
|
31
|
-
|
43
|
+
(price.country_iso == price_options.desired_attributes[:country_iso] ||
|
44
|
+
price.country_iso.nil?
|
32
45
|
) && price.currency == price_options.desired_attributes[:currency]
|
33
|
-
end
|
46
|
+
end
|
34
47
|
end
|
35
48
|
end
|
36
49
|
end
|