spree_core 4.1.4 → 4.1.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 14259887630a60331633df140cfe4f7b9e94b9ecdf95342c5e8a31011dbfb807
4
- data.tar.gz: 2801ca34a2ad369726b829ea9e3decf00ae64c9fcc4cc673cf04e0dc0aa826c5
3
+ metadata.gz: 735a7c4cad6166518bb05cc45fcc5a2f303e1b4a11f5ec9ae1e17a6df5916142
4
+ data.tar.gz: a62c2b5fec62e7c9bf7971198f3805c573785c9e9768d88c61b3ae89b578c31d
5
5
  SHA512:
6
- metadata.gz: f644cd935bca9d371a3a558ffe76994143bc8af738ac9ff8621a778eef743d79339b3f5bda697e84a287c51e12e235bac989c500dd4923ca08f52a89ba8d80ac
7
- data.tar.gz: 62203be51964aa4ccd9ea69a5e5fd47ea7408c6028e257a5c30a7769de7178127aecef002305731f58d5e676bd209c15b776d182246f23dc07a4a0679801d5d3
6
+ metadata.gz: 25b68dc35a114eaa937dc25fc06576065d8b56baa23d4839cdfa401c08fb5f85638e65d924cba0f9f84b9585761eb3855cf938811c288578968aee2d0ef3e2bb
7
+ data.tar.gz: 67270a8f7d20847ddcced170c3ebb82b419d89ffff202905d4a9161b13cd526a954b67367bf925133822a0903e5a7a41e81f2f11e4abadf7d9b375b5bdf54793
@@ -9,6 +9,7 @@ module Spree
9
9
  @price = String(params.dig(:filter, :price)).split(',').map(&:to_f)
10
10
  @currency = params[:currency] || current_currency
11
11
  @taxons = taxon_ids(params.dig(:filter, :taxons))
12
+ @concat_taxons = taxon_ids(params.dig(:filter, :concat_taxons))
12
13
  @name = params.dig(:filter, :name)
13
14
  @options = params.dig(:filter, :options).try(:to_unsafe_hash)
14
15
  @option_value_ids = params.dig(:filter, :option_value_ids)
@@ -22,6 +23,7 @@ module Spree
22
23
  products = by_skus(products)
23
24
  products = by_price(products)
24
25
  products = by_taxons(products)
26
+ products = by_concat_taxons(products)
25
27
  products = by_name(products)
26
28
  products = by_options(products)
27
29
  products = by_option_value_ids(products)
@@ -34,7 +36,8 @@ module Spree
34
36
 
35
37
  private
36
38
 
37
- attr_reader :ids, :skus, :price, :currency, :taxons, :name, :options, :option_value_ids, :scope, :sort_by, :deleted, :discontinued
39
+ attr_reader :ids, :skus, :price, :currency, :taxons, :concat_taxons, :name, :options,
40
+ :option_value_ids, :scope, :sort_by, :deleted, :discontinued
38
41
 
39
42
  def ids?
40
43
  ids.present?
@@ -52,6 +55,10 @@ module Spree
52
55
  taxons.present?
53
56
  end
54
57
 
58
+ def concat_taxons?
59
+ concat_taxons.present?
60
+ end
61
+
55
62
  def name?
56
63
  name.present?
57
64
  end
@@ -99,7 +106,20 @@ module Spree
99
106
  def by_taxons(products)
100
107
  return products unless taxons?
101
108
 
102
- products.joins(:taxons).where(spree_taxons: { id: taxons })
109
+ products.joins(:classifications).where(Classification.table_name => { taxon_id: taxons })
110
+ end
111
+
112
+ def by_concat_taxons(products)
113
+ return products unless concat_taxons?
114
+
115
+ product_ids = Spree::Product.
116
+ joins(:classifications).
117
+ where(Classification.table_name => { taxon_id: concat_taxons }).
118
+ group("#{Spree::Product.table_name}.id").
119
+ having("COUNT(#{Spree::Product.table_name}.id) = ?", concat_taxons.length).
120
+ ids
121
+
122
+ products.where(id: product_ids)
103
123
  end
104
124
 
105
125
  def by_name(products)
@@ -111,9 +131,11 @@ module Spree
111
131
  def by_options(products)
112
132
  return products unless options?
113
133
 
114
- options.map do |key, value|
115
- products.with_option_value(key, value)
116
- end.inject(:&)
134
+ products.where(
135
+ id: options.map do |key, value|
136
+ products.with_option_value(key, value).ids
137
+ end.flatten.compact.uniq
138
+ )
117
139
  end
118
140
 
119
141
  def by_option_value_ids(products)
@@ -142,13 +164,25 @@ module Spree
142
164
 
143
165
  case sort_by
144
166
  when 'default'
145
- products
167
+ if taxons?
168
+ products.
169
+ select("#{Product.table_name}.*, #{Classification.table_name}.position").
170
+ order("#{Classification.table_name}.position" => :asc)
171
+ else
172
+ products
173
+ end
146
174
  when 'newest-first'
147
175
  products.order(available_on: :desc)
148
176
  when 'price-high-to-low'
149
- products.select('spree_products.*, spree_prices.amount').reorder('').send(:descend_by_master_price)
177
+ products.
178
+ select("#{Product.table_name}.*, #{Spree::Price.table_name}.amount").
179
+ reorder('').
180
+ send(:descend_by_master_price)
150
181
  when 'price-low-to-high'
151
- products.select('spree_products.*, spree_prices.amount').reorder('').send(:ascend_by_master_price)
182
+ products.
183
+ select("#{Product.table_name}.*, #{Spree::Price.table_name}.amount").
184
+ reorder('').
185
+ send(:ascend_by_master_price)
152
186
  end
153
187
  end
154
188
 
@@ -160,10 +194,11 @@ module Spree
160
194
  discontinued ? products : products.available
161
195
  end
162
196
 
163
- def taxon_ids(taxon_id)
164
- return unless (taxon = Spree::Taxon.find_by(id: taxon_id))
197
+ def taxon_ids(taxons_ids)
198
+ return if taxons_ids.nil? || taxons_ids.to_s.blank?
165
199
 
166
- taxon.self_and_descendants.ids.map(&:to_s)
200
+ taxons = Spree::Taxon.where(id: taxons_ids.to_s.split(','))
201
+ taxons.map(&:cached_self_and_descendants_ids).flatten.compact.uniq.map(&:to_s)
167
202
  end
168
203
  end
169
204
  end
@@ -111,7 +111,9 @@ module Spree
111
111
  # we should always try to render image of the default variant
112
112
  # same as it's done on PDP
113
113
  def default_image_for_product(product)
114
- if product.default_variant.images.any?
114
+ if product.images.any?
115
+ product.images.first
116
+ elsif product.default_variant.images.any?
115
117
  product.default_variant.images.first
116
118
  elsif product.variant_images.any?
117
119
  product.variant_images.first
@@ -67,7 +67,7 @@ module Spree
67
67
  cache_key_elements = common_product_cache_keys
68
68
  cache_key_elements += [
69
69
  product.cache_key_with_version,
70
- product.possible_promotions
70
+ product.possible_promotions.map(&:cache_key)
71
71
  ]
72
72
 
73
73
  cache_key_elements.compact.join('/')
@@ -79,8 +79,9 @@ module Spree
79
79
  string.slice(0..449) + '...'
80
80
  end
81
81
 
82
- def available_status(product) # will return a human readable string
83
- return Spree.t(:discontinued) if product.discontinued?
82
+ # will return a human readable string
83
+ def available_status(product)
84
+ return Spree.t(:discontinued) if product.discontinued?
84
85
  return Spree.t(:deleted) if product.deleted?
85
86
 
86
87
  if product.available?
@@ -116,16 +117,16 @@ module Spree
116
117
  def related_products
117
118
  return [] unless @product.respond_to?(:has_related_products?) && @product.has_related_products?(:related_products)
118
119
 
119
- @_related_products ||= @product.
120
- related_products.
121
- includes(
122
- :tax_category,
123
- master: [
124
- :prices,
125
- images: { attachment_attachment: :blob },
126
- ]
127
- ).
128
- limit(Spree::Config[:products_per_page])
120
+ @related_products ||= @product.
121
+ related_products.
122
+ includes(
123
+ :tax_category,
124
+ master: [
125
+ :prices,
126
+ images: { attachment_attachment: :blob },
127
+ ]
128
+ ).
129
+ limit(Spree::Config[:products_per_page])
129
130
  end
130
131
 
131
132
  def product_available_in_currency?
@@ -145,7 +146,7 @@ module Spree
145
146
  end
146
147
 
147
148
  def variants_option_types_presenter(variants, product)
148
- @_variants_option_types_presenter ||= begin
149
+ @variants_option_types_presenter ||= begin
149
150
  option_types = Spree::Variants::OptionTypesFinder.new(variant_ids: variants.map(&:id)).execute
150
151
 
151
152
  Spree::Variants::OptionTypesPresenter.new(option_types, variants, product)
@@ -81,7 +81,7 @@ module Spree
81
81
  # SELECT COUNT(*) ...
82
82
  add_search_scope :in_taxon do |taxon|
83
83
  includes(:classifications).
84
- where('spree_products_taxons.taxon_id' => taxon.self_and_descendants.pluck(:id)).
84
+ where('spree_products_taxons.taxon_id' => taxon.cached_self_and_descendants_ids).
85
85
  order('spree_products_taxons.position ASC')
86
86
  end
87
87
 
@@ -221,7 +221,7 @@ module Spree
221
221
 
222
222
  # specifically avoid having an order for taxon search (conflicts with main order)
223
223
  def self.prepare_taxon_conditions(taxons)
224
- ids = taxons.map { |taxon| taxon.self_and_descendants.pluck(:id) }.flatten.uniq
224
+ ids = taxons.map(&:cached_self_and_descendants_ids).flatten.uniq
225
225
  joins(:classifications).where(Classification.table_name => { taxon_id: ids })
226
226
  end
227
227
  private_class_method :prepare_taxon_conditions
@@ -44,6 +44,7 @@ module Spree
44
44
  preference :company, :boolean, default: false # Request company field for billing and shipping addr
45
45
  preference :currency, :string, default: 'USD'
46
46
  preference :default_country_id, :integer
47
+ preference :disable_sku_validation, :boolean, default: false # when turned off disables the built-in SKU uniqueness validation
47
48
  preference :expedited_exchanges, :boolean, default: false # NOTE this requires payment profiles to be supported on your gateway of choice as well as a delayed job handler to be configured with activejob. kicks off an exchange shipment upon return authorization save. charge customer if they do not return items within timely manner.
48
49
  preference :expedited_exchanges_days_window, :integer, default: 14 # the amount of days the customer has to return their item after the expedited exchange is shipped in order to avoid being charged
49
50
  preference :layout, :string, default: 'spree/layouts/spree_application'
@@ -24,10 +24,9 @@ module Spree
24
24
  attribute :month, ActiveRecord::Type::Integer.new
25
25
  attribute :year, ActiveRecord::Type::Integer.new
26
26
 
27
- attr_reader :number
27
+ attr_reader :number, :verification_value
28
28
  attr_accessor :encrypted_data,
29
29
  :imported,
30
- :verification_value,
31
30
  :manual_entry
32
31
 
33
32
  with_options if: :require_card_numbers?, on: :create do
@@ -101,9 +100,11 @@ module Spree
101
100
  end
102
101
  end
103
102
 
103
+ def verification_value=(value)
104
+ @verification_value = value.to_s.gsub(/\s/, '')
105
+ end
106
+
104
107
  def set_last_digits
105
- number.to_s.gsub!(/\s/, '')
106
- verification_value.to_s.gsub!(/\s/, '')
107
108
  self.last_digits ||= number.to_s.length <= 4 ? number : number.to_s.slice(-4..-1)
108
109
  end
109
110
 
@@ -100,7 +100,7 @@ module Spree::Preferences::Preferable
100
100
  if value.is_a?(FalseClass) ||
101
101
  value.nil? ||
102
102
  value == 0 ||
103
- value =~ /^(f|false|0)$/i ||
103
+ value&.to_s =~ /^(f|false|0)$/i ||
104
104
  (value.respond_to?(:empty?) && value.empty?)
105
105
  false
106
106
  else
@@ -111,7 +111,7 @@ module Spree
111
111
 
112
112
  alias options product_option_types
113
113
 
114
- self.whitelisted_ransackable_associations = %w[stores variants_including_master master variants]
114
+ self.whitelisted_ransackable_associations = %w[taxons stores variants_including_master master variants]
115
115
  self.whitelisted_ransackable_attributes = %w[description name slug discontinue_on]
116
116
  self.whitelisted_ransackable_scopes = %w[not_discontinued]
117
117
 
@@ -341,7 +341,7 @@ module Spree
341
341
  price: master.price
342
342
  )
343
343
  end
344
- throw(:abort) unless save
344
+ save
345
345
  end
346
346
 
347
347
  def ensure_master
@@ -23,7 +23,7 @@ module Spree
23
23
  order = line_item.order
24
24
 
25
25
  # Prevent negative order totals
26
- amounts << order.amount - order.adjustments.sum(:amount).abs if order.adjustments.any?
26
+ amounts << order.amount - order.adjustments.eligible.sum(:amount).abs if order.adjustments.eligible.any?
27
27
 
28
28
  amounts.min * -1
29
29
  end
@@ -74,6 +74,12 @@ module Spree
74
74
  ancestor_chain + name.to_s
75
75
  end
76
76
 
77
+ def cached_self_and_descendants_ids
78
+ Rails.cache.fetch("#{cache_key_with_version}/descendant-ids") do
79
+ self_and_descendants.ids
80
+ end
81
+ end
82
+
77
83
  # awesome_nested_set sorts by :lft and :rgt. This call re-inserts the child
78
84
  # node so that its resulting position matches the observable 0-indexed position.
79
85
  # ** Note ** no :position column needed - a_n_s doesn't handle the reordering if
@@ -48,7 +48,8 @@ module Spree
48
48
  validates :cost_price
49
49
  validates :price
50
50
  end
51
- validates :sku, uniqueness: { conditions: -> { where(deleted_at: nil) }, case_sensitive: false }, allow_blank: true
51
+ validates :sku, uniqueness: { conditions: -> { where(deleted_at: nil) }, case_sensitive: false },
52
+ allow_blank: true, unless: :disable_sku_validation?
52
53
 
53
54
  after_create :create_stock_items
54
55
  after_create :set_master_out_of_stock, unless: :is_master?
@@ -102,6 +103,11 @@ module Spree
102
103
 
103
104
  self.whitelisted_ransackable_associations = %w[option_values product prices default_price]
104
105
  self.whitelisted_ransackable_attributes = %w[weight sku]
106
+ self.whitelisted_ransackable_scopes = %i(product_name_or_sku_cont)
107
+
108
+ def self.product_name_or_sku_cont(query)
109
+ joins(:product).where("#{Product.table_name}.name LIKE :query OR sku LIKE :query", query: "%#{query}%")
110
+ end
105
111
 
106
112
  def available?
107
113
  !discontinued? && product.available?
@@ -226,7 +232,11 @@ module Spree
226
232
  end
227
233
 
228
234
  def in_stock?
229
- Rails.cache.fetch(in_stock_cache_key) do
235
+ # Issue 10280
236
+ # Check if model responds to cache version and fall back to updated_at for older rails versions
237
+ # This makes sure a version is supplied when recyclable cache keys are disabled.
238
+ version = respond_to?(:cache_version) ? cache_version : updated_at.to_i
239
+ Rails.cache.fetch(in_stock_cache_key, version: version) do
230
240
  total_on_hand > 0
231
241
  end
232
242
  end
@@ -319,5 +329,9 @@ module Spree
319
329
  def clear_in_stock_cache
320
330
  Rails.cache.delete(in_stock_cache_key)
321
331
  end
332
+
333
+ def disable_sku_validation?
334
+ Spree::Config[:disable_sku_validation]
335
+ end
322
336
  end
323
337
  end
@@ -7,9 +7,7 @@ module Spree
7
7
  run :reload_order
8
8
  run :ensure_shipping_address
9
9
  run :ensure_line_items_present
10
- run :move_order_to_delivery_state
11
- run :generate_shipping_rates
12
- run :return_shipments
10
+ run :generate_or_return_shipping_rates
13
11
  end
14
12
 
15
13
  private
@@ -31,6 +29,11 @@ module Spree
31
29
  success(order: order)
32
30
  end
33
31
 
32
+ def generate_or_return_shipping_rates(order:)
33
+ generate_shipping_rates(order: order) if order.shipments.empty?
34
+ return_shipments(order: order)
35
+ end
36
+
34
37
  def generate_shipping_rates(order:)
35
38
  ApplicationRecord.transaction do
36
39
  order.create_proposed_shipments
@@ -42,13 +45,7 @@ module Spree
42
45
  end
43
46
 
44
47
  def return_shipments(order:)
45
- success(order.shipments.includes([shipping_rates: :shipping_method]))
46
- end
47
-
48
- def move_order_to_delivery_state(order:)
49
- Spree::Dependencies.checkout_next_service.constantize.call(order: order) until order.state == 'delivery'
50
-
51
- success(order: order)
48
+ success(order.reload.shipments.includes([shipping_rates: :shipping_method]))
52
49
  end
53
50
  end
54
51
  end
@@ -138,7 +138,7 @@ end
138
138
  end
139
139
 
140
140
  def gemfile_path
141
- core_gems = ['spree/core', 'spree/api', 'spree/backend', 'spree/frontend']
141
+ core_gems = ['spree/core', 'spree/api', 'spree/backend', 'spree/frontend', 'spree/sample']
142
142
 
143
143
  if core_gems.include?(lib_name)
144
144
  '../../../../../Gemfile'
@@ -26,5 +26,6 @@ Spree.dependencies do |dependencies|
26
26
  # dependencies.cart_add_item_service = 'MyNewAwesomeService'
27
27
  end
28
28
 
29
+ # Spree::Api::Dependencies.storefront_cart_serializer = 'MyRailsApp::CartSerializer'
29
30
 
30
31
  Spree.user_class = <%= (options[:user_class].blank? ? 'Spree::LegacyUser' : options[:user_class]).inspect %>
@@ -1,5 +1,5 @@
1
1
  module Spree
2
2
  def self.version
3
- '4.1.4'
3
+ '4.1.9'
4
4
  end
5
5
  end
@@ -6,17 +6,23 @@ Gem::Specification.new do |s|
6
6
  s.platform = Gem::Platform::RUBY
7
7
  s.name = 'spree_core'
8
8
  s.version = Spree.version
9
+ s.author = 'Sean Schofield'
10
+ s.email = 'sean@spreecommerce.com'
9
11
  s.summary = 'The bare bones necessary for Spree.'
10
12
  s.description = 'The bare bones necessary for Spree.'
13
+ s.homepage = 'http://spreecommerce.org'
14
+ s.license = 'BSD-3-Clause'
15
+
16
+ s.metadata = {
17
+ "bug_tracker_uri" => "https://github.com/spree/spree/issues",
18
+ "changelog_uri" => "https://github.com/spree/spree/releases/tag/v#{s.version}",
19
+ "documentation_uri" => "https://guides.spreecommerce.org/",
20
+ "source_code_uri" => "https://github.com/spree/spree/tree/v#{s.version}",
21
+ }
11
22
 
12
23
  s.required_ruby_version = '>= 2.5.0'
13
24
  s.required_rubygems_version = '>= 1.8.23'
14
25
 
15
- s.author = 'Sean Schofield'
16
- s.email = 'sean@spreecommerce.com'
17
- s.homepage = 'http://spreecommerce.org'
18
- s.license = 'BSD-3-Clause'
19
-
20
26
  s.files = `git ls-files`.split("\n").reject { |f| f.match(/^spec/) && !f.match(/^spec\/fixtures/) }
21
27
  s.require_path = 'lib'
22
28
 
@@ -28,7 +34,7 @@ Gem::Specification.new do |s|
28
34
  s.add_dependency 'ffaker', '~> 2.9'
29
35
  s.add_dependency 'friendly_id', '>= 5.2.1', '< 5.4.0'
30
36
  s.add_dependency 'highline', '~> 2.0.0' # Necessary for the install generator
31
- s.add_dependency 'kaminari', '>= 1.0.1', '< 1.2.0'
37
+ s.add_dependency 'kaminari', '~> 1.2.1'
32
38
  s.add_dependency 'money', '~> 6.13'
33
39
  s.add_dependency 'monetize', '~> 1.9'
34
40
  s.add_dependency 'paranoia', '~> 2.4.2'
@@ -39,7 +45,7 @@ Gem::Specification.new do |s|
39
45
  s.add_dependency 'state_machines-activerecord', '~> 0.6'
40
46
  s.add_dependency 'state_machines-activemodel', '~> 0.7'
41
47
  s.add_dependency 'stringex'
42
- s.add_dependency 'twitter_cldr', '>= 4.3', '< 6.0'
48
+ s.add_dependency 'twitter_cldr', '>= 4.3', '< 7.0'
43
49
  s.add_dependency 'sprockets', '~> 3.7'
44
50
  s.add_dependency 'sprockets-rails'
45
51
  s.add_dependency 'mini_magick', '>= 4.9.4', '< 4.11.0'
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: 4.1.4
4
+ version: 4.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Schofield
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-07 00:00:00.000000000 Z
11
+ date: 2020-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemerchant
@@ -144,22 +144,16 @@ dependencies:
144
144
  name: kaminari
145
145
  requirement: !ruby/object:Gem::Requirement
146
146
  requirements:
147
- - - ">="
148
- - !ruby/object:Gem::Version
149
- version: 1.0.1
150
- - - "<"
147
+ - - "~>"
151
148
  - !ruby/object:Gem::Version
152
- version: 1.2.0
149
+ version: 1.2.1
153
150
  type: :runtime
154
151
  prerelease: false
155
152
  version_requirements: !ruby/object:Gem::Requirement
156
153
  requirements:
157
- - - ">="
158
- - !ruby/object:Gem::Version
159
- version: 1.0.1
160
- - - "<"
154
+ - - "~>"
161
155
  - !ruby/object:Gem::Version
162
- version: 1.2.0
156
+ version: 1.2.1
163
157
  - !ruby/object:Gem::Dependency
164
158
  name: money
165
159
  requirement: !ruby/object:Gem::Requirement
@@ -309,7 +303,7 @@ dependencies:
309
303
  version: '4.3'
310
304
  - - "<"
311
305
  - !ruby/object:Gem::Version
312
- version: '6.0'
306
+ version: '7.0'
313
307
  type: :runtime
314
308
  prerelease: false
315
309
  version_requirements: !ruby/object:Gem::Requirement
@@ -319,7 +313,7 @@ dependencies:
319
313
  version: '4.3'
320
314
  - - "<"
321
315
  - !ruby/object:Gem::Version
322
- version: '6.0'
316
+ version: '7.0'
323
317
  - !ruby/object:Gem::Dependency
324
318
  name: sprockets
325
319
  requirement: !ruby/object:Gem::Requirement
@@ -1089,8 +1083,12 @@ files:
1089
1083
  homepage: http://spreecommerce.org
1090
1084
  licenses:
1091
1085
  - BSD-3-Clause
1092
- metadata: {}
1093
- post_install_message:
1086
+ metadata:
1087
+ bug_tracker_uri: https://github.com/spree/spree/issues
1088
+ changelog_uri: https://github.com/spree/spree/releases/tag/v4.1.9
1089
+ documentation_uri: https://guides.spreecommerce.org/
1090
+ source_code_uri: https://github.com/spree/spree/tree/v4.1.9
1091
+ post_install_message:
1094
1092
  rdoc_options: []
1095
1093
  require_paths:
1096
1094
  - lib
@@ -1105,8 +1103,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1105
1103
  - !ruby/object:Gem::Version
1106
1104
  version: 1.8.23
1107
1105
  requirements: []
1108
- rubygems_version: 3.0.6
1109
- signing_key:
1106
+ rubygems_version: 3.1.2
1107
+ signing_key:
1110
1108
  specification_version: 4
1111
1109
  summary: The bare bones necessary for Spree.
1112
1110
  test_files: []