spree_core 4.1.2 → 4.1.7

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: 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.