spree_core 4.1.2 → 4.1.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b705f768f8ff59c9810f09dd3a99a68c2dc13811769a180069b9261009d9cdff
4
- data.tar.gz: a64dba1a7bf10999d6e588a9411e39172f25c93f9a26876719b1d6da5940bb0a
3
+ metadata.gz: f9abe56060f0568926e082bc13e3984b3819c23f5e5658b14ff58e44589a9e51
4
+ data.tar.gz: ca29391589cf6bf06c8f20bfb248be16fae419b3fb683255803f01a355f0ddac
5
5
  SHA512:
6
- metadata.gz: 0d49c78014b9a7899e754dbe299bb00b293939d7e25e5091cf3124a0951da7076303ce358da23e790f7efe626bce656b09d9cdf3a5a512cdefbff5cee739faa2
7
- data.tar.gz: 6dbe8cdd4dd58cb1f8a8c5e9bd6b1d34344e119f8df0839a4824d9f3fc809f1215def97bec41b47732d2530c48e63a0c5e5f808c027353b551eb169b004ba013
6
+ metadata.gz: e2aea90e9694d9b2ac45d23e7a5ea5fd07bc25a7ba93a614328f740857c8c10b6c6d644ff3bc258c3a600f3ae8836e6ad5b1d9473799ffc1c672e7878afd3ff3
7
+ data.tar.gz: 423b46182c0785e1915315afa475f0125f9d832fcab13ff34abc83f7628681d24d555cc6513b4338c8f282b40f833825b8015502b73162946f908e6535ad5b46
@@ -8,7 +8,8 @@ module Spree
8
8
  @skus = String(params.dig(:filter, :skus)).split(',')
9
9
  @price = String(params.dig(:filter, :price)).split(',').map(&:to_f)
10
10
  @currency = params[:currency] || current_currency
11
- @taxons = String(params.dig(:filter, :taxons)).split(',')
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)
@@ -29,12 +31,13 @@ module Spree
29
31
  products = include_discontinued(products)
30
32
  products = ordered(products)
31
33
 
32
- products
34
+ products.distinct
33
35
  end
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
@@ -81,14 +88,13 @@ module Spree
81
88
  def by_skus(products)
82
89
  return products unless skus?
83
90
 
84
- products.joins(:variants_including_master).distinct.where(spree_variants: { sku: skus })
91
+ products.joins(:variants_including_master).where(spree_variants: { sku: skus })
85
92
  end
86
93
 
87
94
  def by_price(products)
88
95
  return products unless price?
89
96
 
90
97
  products.joins(master: :default_price).
91
- distinct.
92
98
  where(
93
99
  spree_prices: {
94
100
  amount: price.min..price.max,
@@ -100,7 +106,20 @@ module Spree
100
106
  def by_taxons(products)
101
107
  return products unless taxons?
102
108
 
103
- products.joins(:taxons).distinct.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)
104
123
  end
105
124
 
106
125
  def by_name(products)
@@ -112,9 +131,11 @@ module Spree
112
131
  def by_options(products)
113
132
  return products unless options?
114
133
 
115
- options.map do |key, value|
116
- products.with_option_value(key, value)
117
- 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
+ )
118
139
  end
119
140
 
120
141
  def by_option_value_ids(products)
@@ -143,13 +164,25 @@ module Spree
143
164
 
144
165
  case sort_by
145
166
  when 'default'
146
- 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
147
174
  when 'newest-first'
148
175
  products.order(available_on: :desc)
149
176
  when 'price-high-to-low'
150
- 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)
151
181
  when 'price-low-to-high'
152
- 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)
153
186
  end
154
187
  end
155
188
 
@@ -160,6 +193,13 @@ module Spree
160
193
  def include_discontinued(products)
161
194
  discontinued ? products : products.available
162
195
  end
196
+
197
+ def taxon_ids(taxons_ids)
198
+ return if taxons_ids.nil? || taxons_ids.to_s.blank?
199
+
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)
202
+ end
163
203
  end
164
204
  end
165
205
  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
@@ -136,6 +138,10 @@ module Spree
136
138
  [I18n.locale, current_currency]
137
139
  end
138
140
 
141
+ def maximum_quantity
142
+ Spree::DatabaseTypeUtilities.maximum_value_for(:integer)
143
+ end
144
+
139
145
  private
140
146
 
141
147
  def create_product_image_tag(image, product, options, style)
@@ -58,13 +58,8 @@ module Spree
58
58
  end
59
59
 
60
60
  def cache_key_for_products(products = @products, additional_cache_key = nil)
61
- ids = if products.is_a?(Array)
62
- products.map(&:id)
63
- else
64
- products.ids
65
- end.join('-')
66
61
  max_updated_at = (products.maximum(:updated_at) || Date.today).to_s(:number)
67
- products_cache_keys = "spree/products/#{ids}-#{params[:page]}-#{params[:sort_by]}-#{max_updated_at}-#{@taxon&.id}"
62
+ products_cache_keys = "spree/products/#{products.map(&:id).join('-')}-#{params[:page]}-#{params[:sort_by]}-#{max_updated_at}-#{@taxon&.id}"
68
63
  (common_product_cache_keys + [products_cache_keys] + [additional_cache_key]).compact.join('/')
69
64
  end
70
65
 
@@ -72,7 +67,7 @@ module Spree
72
67
  cache_key_elements = common_product_cache_keys
73
68
  cache_key_elements += [
74
69
  product.cache_key_with_version,
75
- product.possible_promotions
70
+ product.possible_promotions.map(&:cache_key)
76
71
  ]
77
72
 
78
73
  cache_key_elements.compact.join('/')
@@ -84,8 +79,9 @@ module Spree
84
79
  string.slice(0..449) + '...'
85
80
  end
86
81
 
87
- def available_status(product) # will return a human readable string
88
- 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?
89
85
  return Spree.t(:deleted) if product.deleted?
90
86
 
91
87
  if product.available?
@@ -121,16 +117,16 @@ module Spree
121
117
  def related_products
122
118
  return [] unless @product.respond_to?(:has_related_products?) && @product.has_related_products?(:related_products)
123
119
 
124
- @_related_products ||= @product.
125
- related_products.
126
- includes(
127
- :tax_category,
128
- master: [
129
- :prices,
130
- images: { attachment_attachment: :blob },
131
- ]
132
- ).
133
- 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])
134
130
  end
135
131
 
136
132
  def product_available_in_currency?
@@ -150,7 +146,7 @@ module Spree
150
146
  end
151
147
 
152
148
  def variants_option_types_presenter(variants, product)
153
- @_variants_option_types_presenter ||= begin
149
+ @variants_option_types_presenter ||= begin
154
150
  option_types = Spree::Variants::OptionTypesFinder.new(variant_ids: variants.map(&:id)).execute
155
151
 
156
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
@@ -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
 
@@ -17,7 +17,14 @@ module Spree
17
17
  before_validation :copy_tax_category
18
18
 
19
19
  validates :variant, :order, presence: true
20
- validates :quantity, numericality: { only_integer: true, message: Spree.t('validation.must_be_int') }
20
+
21
+ # numericality: :less_than_or_equal_to validation is due to the restriction at the database level
22
+ # https://github.com/spree/spree/issues/2695#issuecomment-143314161
23
+ validates :quantity, numericality: {
24
+ less_than_or_equal_to: DatabaseTypeUtilities.maximum_value_for(:integer),
25
+ only_integer: true, message: Spree.t('validation.must_be_int')
26
+ }
27
+
21
28
  validates :price, numericality: true
22
29
 
23
30
  validates_with Spree::Stock::AvailabilityValidator
@@ -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
@@ -102,6 +102,11 @@ module Spree
102
102
 
103
103
  self.whitelisted_ransackable_associations = %w[option_values product prices default_price]
104
104
  self.whitelisted_ransackable_attributes = %w[weight sku]
105
+ self.whitelisted_ransackable_scopes = %i(product_name_or_sku_cont)
106
+
107
+ def self.product_name_or_sku_cont(query)
108
+ joins(:product).where("#{Product.table_name}.name LIKE :query OR sku LIKE :query", query: "%#{query}%")
109
+ end
105
110
 
106
111
  def available?
107
112
  !discontinued? && product.available?
@@ -71,8 +71,8 @@ module Spree
71
71
  end
72
72
 
73
73
  def kind
74
- if kind?
75
- super
74
+ if self[:kind].present?
75
+ self[:kind]
76
76
  else
77
77
  not_nil_scope = members.where.not(zoneable_type: nil)
78
78
  zone_type = not_nil_scope.order('created_at ASC').pluck(:zoneable_type).last
@@ -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'
@@ -93,6 +93,7 @@ require 'spree/money'
93
93
  require 'spree/permitted_attributes'
94
94
  require 'spree/service_module'
95
95
  require 'spree/dependencies_helper'
96
+ require 'spree/database_type_utilities'
96
97
 
97
98
  require 'spree/core/importer'
98
99
  require 'spree/core/query_filters'
@@ -1,5 +1,5 @@
1
1
  module Spree
2
2
  def self.version
3
- '4.1.2'
3
+ '4.1.7'
4
4
  end
5
5
  end
@@ -0,0 +1,12 @@
1
+ module Spree
2
+ module DatabaseTypeUtilities
3
+ def self.maximum_value_for(data_type)
4
+ case data_type
5
+ when :integer
6
+ ActiveModel::Type::Integer.new.instance_eval { range.max }
7
+ else
8
+ raise ArgumentError, 'Currently only :integer argument is acceptable'
9
+ end
10
+ end
11
+ end
12
+ end
@@ -28,7 +28,7 @@ Gem::Specification.new do |s|
28
28
  s.add_dependency 'ffaker', '~> 2.9'
29
29
  s.add_dependency 'friendly_id', '>= 5.2.1', '< 5.4.0'
30
30
  s.add_dependency 'highline', '~> 2.0.0' # Necessary for the install generator
31
- s.add_dependency 'kaminari', '>= 1.0.1', '< 1.2.0'
31
+ s.add_dependency 'kaminari', '~> 1.2.1'
32
32
  s.add_dependency 'money', '~> 6.13'
33
33
  s.add_dependency 'monetize', '~> 1.9'
34
34
  s.add_dependency 'paranoia', '~> 2.4.2'
@@ -39,7 +39,7 @@ Gem::Specification.new do |s|
39
39
  s.add_dependency 'state_machines-activerecord', '~> 0.6'
40
40
  s.add_dependency 'state_machines-activemodel', '~> 0.7'
41
41
  s.add_dependency 'stringex'
42
- s.add_dependency 'twitter_cldr', '>= 4.3', '< 6.0'
42
+ s.add_dependency 'twitter_cldr', '>= 4.3', '< 7.0'
43
43
  s.add_dependency 'sprockets', '~> 3.7'
44
44
  s.add_dependency 'sprockets-rails'
45
45
  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.2
4
+ version: 4.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Schofield
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-27 00:00:00.000000000 Z
11
+ date: 2020-06-08 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
@@ -997,6 +991,7 @@ files:
997
991
  - lib/spree/core/search/base.rb
998
992
  - lib/spree/core/token_generator.rb
999
993
  - lib/spree/core/version.rb
994
+ - lib/spree/database_type_utilities.rb
1000
995
  - lib/spree/dependencies_helper.rb
1001
996
  - lib/spree/i18n.rb
1002
997
  - lib/spree/i18n/base.rb
@@ -1104,7 +1099,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1104
1099
  - !ruby/object:Gem::Version
1105
1100
  version: 1.8.23
1106
1101
  requirements: []
1107
- rubygems_version: 3.0.6
1102
+ rubygems_version: 3.1.2
1108
1103
  signing_key:
1109
1104
  specification_version: 4
1110
1105
  summary: The bare bones necessary for Spree.