solidus_core 3.2.3 → 3.2.5

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: dc968f634c0e31f7ad3d1928133d5d682df2669617eaca7abdc87379228d7e30
4
- data.tar.gz: a2e38014e3d24fe363651e7e27f5b8fa21b93105f1269e67adee3e20ec1665fa
3
+ metadata.gz: 1ca291cd7b979dea71a53e089ec1f5582fd29606135be6802668e6a249655295
4
+ data.tar.gz: 35c97c39d287f13bd2330fef96e59eefa5d82869e49563a32706b827087a936a
5
5
  SHA512:
6
- metadata.gz: 8fbc377c572b99bb42d055b1479f2be9c5bca450019f70bef38adf76a3bfd69057c90824150036c7ed1330d9052f3916f09a48a252b85f31c0719f33f5d52c43
7
- data.tar.gz: c57b6889ddf53bcf23fc1ed0012a9759ef72a031a72e1c8a8a838abfb8594b8f401bb17a973d17c37347aae44f37411181ab9a663e884659ebeb6122c06481c4
6
+ metadata.gz: dcd03d7fe00dade48a32ff5862579eed61115afe17e225e0378ea83fb1af3c502467dbef833619159742b2b7cef998e53d47cde357d6e2b57beb73daa80708f2
7
+ data.tar.gz: cea864acea70b4d18b208481ffa8d0587ce5bc721f2de5d83c653b2125e7dbf1e9da81ef0cb211180d48df93a53daaf813e5d8d7ecd9181c5c0f9de2efd239ba
@@ -16,10 +16,12 @@ module Spree
16
16
 
17
17
  # Returns `#prices` prioritized for being considered as default price
18
18
  #
19
+ # @deprecated
19
20
  # @return [ActiveRecord::Relation<Spree::Price>]
20
21
  def currently_valid_prices
21
22
  prices.currently_valid
22
23
  end
24
+ deprecate :currently_valid_prices, deprecator: Spree::Deprecation
23
25
 
24
26
  # Returns {#default_price} or builds it from {Spree::Variant.default_price_attributes}
25
27
  #
@@ -33,7 +35,7 @@ module Spree
33
35
  # Select from {#prices} the one to be considered as the default
34
36
  #
35
37
  # This method works with the in-memory association, so non-persisted prices
36
- # are taken into account. Discarded prices are also considered.
38
+ # are taken into account.
37
39
  #
38
40
  # A price is a candidate to be considered as the default when it meets
39
41
  # {Spree::Variant.default_price_attributes} criteria. When more than one candidate is
@@ -44,37 +46,11 @@ module Spree
44
46
  # @return [Spree::Price, nil]
45
47
  # @see Spree::Variant.default_price_attributes
46
48
  def default_price
47
- prioritized_default(
48
- prices_meeting_criteria_to_be_default(
49
- (prices + prices.with_discarded).uniq
50
- )
51
- )
49
+ price_selector.price_for_options(Spree::Config.default_pricing_options)
52
50
  end
53
51
 
54
52
  def has_default_price?
55
53
  default_price.present? && !default_price.discarded?
56
54
  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
79
55
  end
80
56
  end
@@ -113,7 +113,8 @@ module Spree
113
113
  def amount_for_adjustment_label
114
114
  ActiveSupport::NumberHelper::NumberToPercentageConverter.convert(
115
115
  amount * 100,
116
- locale: I18n.locale
116
+ locale: I18n.locale,
117
+ precision: nil
117
118
  )
118
119
  end
119
120
 
@@ -39,12 +39,29 @@ module Spree
39
39
  # @param [Spree::Variant::PricingOptions] price_options Pricing Options to abide by
40
40
  # @return [Spree::Price, nil] The most specific price for this set of pricing options.
41
41
  def price_for_options(price_options)
42
- variant.currently_valid_prices.detect do |price|
42
+ sorted_prices_for(variant).detect do |price|
43
43
  (price.country_iso == price_options.desired_attributes[:country_iso] ||
44
44
  price.country_iso.nil?
45
45
  ) && price.currency == price_options.desired_attributes[:currency]
46
46
  end
47
47
  end
48
+
49
+ private
50
+
51
+ # Returns `#prices` prioritized for being considered as default price
52
+ #
53
+ # @return [Array<Spree::Price>]
54
+ def sorted_prices_for(variant)
55
+ variant.prices.select do |price|
56
+ variant.discarded? || price.kept?
57
+ end.sort_by do |price|
58
+ [
59
+ price.country_iso.nil? ? 0 : 1,
60
+ price.updated_at || Time.zone.now,
61
+ price.id || Float::INFINITY,
62
+ ]
63
+ end.reverse
64
+ end
48
65
  end
49
66
  end
50
67
  end
@@ -23,7 +23,6 @@ module Spree
23
23
  after_discard do
24
24
  stock_items.discard_all
25
25
  images.destroy_all
26
- prices.discard_all
27
26
  end
28
27
 
29
28
  attr_writer :rebuild_vat_prices
@@ -52,6 +51,7 @@ module Spree
52
51
  has_many :images, -> { order(:position) }, as: :viewable, dependent: :destroy, class_name: "Spree::Image"
53
52
 
54
53
  has_many :prices,
54
+ -> { with_discarded },
55
55
  class_name: 'Spree::Price',
56
56
  dependent: :destroy,
57
57
  inverse_of: :variant,
@@ -0,0 +1,11 @@
1
+ plugin_name = PAYMENT_METHODS.fetch(@selected_payment_method)
2
+ plugin_generator_name = "#{plugin_name}:install"
3
+
4
+ if bundler_context.dependencies[plugin_name]
5
+ say_status :skipping, "#{plugin_name} is already in the gemfile"
6
+ else
7
+ gem plugin_name
8
+ run_bundle
9
+ run "spring stop" if defined?(Spring)
10
+ generate "#{plugin_generator_name} --skip_migrations=true"
11
+ end
@@ -0,0 +1,11 @@
1
+ plugin_name = PAYMENT_METHODS.fetch(@selected_payment_method)
2
+ plugin_generator_name = "#{plugin_name}:install"
3
+
4
+ if bundler_context.dependencies[plugin_name]
5
+ say_status :skipping, "#{plugin_name} is already in the gemfile"
6
+ else
7
+ gem plugin_name, @selected_frontend == 'solidus_frontend' ? '< 1' : '>= 1.a'
8
+ run_bundle
9
+ run "spring stop" if defined?(Spring)
10
+ generate "#{plugin_generator_name} --skip_migrations=true"
11
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Solidus
4
- class InstallGenerator < Rails::Generators::Base
4
+ class InstallGenerator < Rails::Generators::AppBase
5
5
  # Bundler context during the install process.
6
6
  #
7
7
  # This class gives access to information about the bundler context in which
@@ -49,7 +49,7 @@ module Solidus
49
49
  end
50
50
 
51
51
  def initialize
52
- @dependencies = Bundler.locked_gems.dependencies
52
+ @dependencies = uncached_dependencies
53
53
  @injector = InjectorWithPathSupport
54
54
  end
55
55
 
@@ -92,6 +92,14 @@ module Solidus
92
92
  def solidus_dependency
93
93
  @dependencies['solidus']
94
94
  end
95
+
96
+ # We want to get the locked gems from `Bundler.definition.locked_gems`
97
+ # instead of `Bundler.locked_gems` so that the locked gems won't be
98
+ # memoized. See
99
+ # https://rubydoc.info/gems/bundler/2.3.22/Bundler.locked_gems.
100
+ def uncached_dependencies
101
+ Bundler.definition.locked_gems.dependencies
102
+ end
95
103
  end
96
104
  end
97
105
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Solidus
4
- class InstallGenerator < Rails::Generators::Base
4
+ class InstallGenerator < Rails::Generators::AppBase
5
5
  class InstallFrontend
6
6
  attr_reader :bundler_context,
7
7
  :generator_context
@@ -17,27 +17,18 @@ module Solidus
17
17
  install_solidus_frontend
18
18
  when 'solidus_starter_frontend'
19
19
  install_solidus_starter_frontend
20
+ else
21
+ install_custom_frontend
20
22
  end
21
23
  end
22
24
 
23
25
  private
24
26
 
25
- def bundle_command(command)
26
- @generator_context.say_status :run, "bundle #{command}"
27
- bundle_path = Gem.bin_path("bundler", "bundle")
28
-
29
- BundlerContext.bundle_cleanly do
30
- system(
31
- Gem.ruby,
32
- bundle_path,
33
- *command.shellsplit,
34
- )
35
- end
36
- end
37
-
38
27
  def install_solidus_frontend
39
28
  unless @bundler_context.component_in_gemfile?(:frontend)
40
- bundle_command 'add solidus_frontend'
29
+ # `Rails::Generator::AppBase#bundle_command` is protected so have to `send` it.
30
+ # See https://api.rubyonrails.org/v3.2.16/classes/Rails/Generators/AppBase.html#method-i-run_bundle
31
+ @generator_context.send :bundle_command, 'add solidus_frontend'
41
32
  end
42
33
 
43
34
  # Solidus bolt will be handled in the installer as a payment method.
@@ -51,9 +42,20 @@ module Solidus
51
42
  end
52
43
 
53
44
  def install_solidus_starter_frontend
54
- @bundler_context.remove(['solidus_frontend']) if @bundler_context.component_in_gemfile?(:frontend)
45
+ remove_solidus_frontend
55
46
  @generator_context.apply "https://raw.githubusercontent.com/solidusio/solidus_starter_frontend/v3.2/template.rb"
56
47
  end
48
+
49
+ def install_custom_frontend
50
+ remove_solidus_frontend
51
+ @generator_context.apply ENV['FRONTEND'] or abort("Frontend installation failed.")
52
+ end
53
+
54
+ def remove_solidus_frontend
55
+ return unless @bundler_context.component_in_gemfile?(:frontend)
56
+
57
+ @bundler_context.remove(['solidus_frontend'])
58
+ end
57
59
  end
58
60
  end
59
61
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Solidus
4
- class InstallGenerator < Rails::Generators::Base
4
+ class InstallGenerator < Rails::Generators::AppBase
5
5
  # Helper for extracting solidus_frontend from solidus meta-gem
6
6
  #
7
7
  # We're recommending users use newer solidus_starter_frontend. However,
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'rails/generators'
4
+ require 'rails/generators/app_base'
4
5
  require 'rails/version'
5
6
  require_relative 'install_generator/bundler_context'
6
7
  require_relative 'install_generator/support_solidus_frontend_extraction'
@@ -8,7 +9,9 @@ require_relative 'install_generator/install_frontend'
8
9
 
9
10
  module Solidus
10
11
  # @private
11
- class InstallGenerator < Rails::Generators::Base
12
+ class InstallGenerator < Rails::Generators::AppBase
13
+ argument :app_path, type: :string, default: Rails.root
14
+
12
15
  CORE_MOUNT_ROUTE = "mount Spree::Core::Engine"
13
16
 
14
17
  LEGACY_FRONTEND = 'solidus_frontend'
@@ -123,14 +126,9 @@ module Solidus
123
126
  end
124
127
  end
125
128
 
126
- def plugin_install_preparation
127
- @plugins_to_be_installed = []
128
- @plugin_generators_to_run = []
129
- end
130
-
131
- def install_auth_plugin
132
- with_authentication = options[:with_authentication]
133
- with_authentication.nil? and with_authentication = (options[:auto_accept] || !no?("
129
+ def select_auth_plugin
130
+ @with_authentication = options[:with_authentication]
131
+ @with_authentication.nil? and @with_authentication = (options[:auto_accept] || !no?("
134
132
  Solidus has a default authentication extension that uses Devise.
135
133
  You can find more info at https://github.com/solidusio/solidus_auth_devise.
136
134
 
@@ -138,31 +136,19 @@ module Solidus
138
136
  solidus_starter_frontend as your storefront in a later step.
139
137
 
140
138
  Would you like to install it? (Y/n)"))
141
-
142
- if with_authentication
143
- @plugins_to_be_installed << 'solidus_auth_devise'
144
- @plugin_generators_to_run << 'solidus:auth:install'
145
- end
146
139
  end
147
140
 
148
- def install_payment_method
141
+ def select_payment_method
149
142
  say_status :warning, set_color(
150
143
  "Selecting a payment along with `solidus_starter_frontend` might require manual integration.",
151
144
  :yellow
152
145
  ), :yellow
153
146
 
154
- name = options[:payment_method]
155
- name ||= PAYMENT_METHODS.keys.first if options[:auto_accept]
156
- name ||= ask("
147
+ @selected_payment_method = options[:payment_method]
148
+ @selected_payment_method ||= PAYMENT_METHODS.keys.first if options[:auto_accept]
149
+ @selected_payment_method ||= ask("
157
150
  You can select a payment method to be included in the installation process.
158
151
  Please select a payment method name:", limited_to: PAYMENT_METHODS.keys, default: PAYMENT_METHODS.keys.first)
159
-
160
- gem_name = PAYMENT_METHODS.fetch(name)
161
-
162
- if gem_name
163
- @plugins_to_be_installed << gem_name
164
- @plugin_generators_to_run << "#{gem_name}:install"
165
- end
166
152
  end
167
153
 
168
154
  def include_seed_data
@@ -184,32 +170,35 @@ module Solidus
184
170
  end
185
171
 
186
172
  def install_frontend
187
- return if options[:frontend] == 'none'
188
-
189
- bundler_context = BundlerContext.new
173
+ @selected_frontend = detect_frontend_to_install
190
174
 
191
- frontend = detect_frontend_to_install(bundler_context)
175
+ if @selected_frontend == 'none'
176
+ support_solidus_frontend_extraction
177
+ else
178
+ support_solidus_frontend_extraction unless @selected_frontend == LEGACY_FRONTEND
192
179
 
193
- support_solidus_frontend_extraction(bundler_context) unless frontend == LEGACY_FRONTEND
180
+ say_status :installing, @selected_frontend
194
181
 
195
- say_status :installing, frontend
182
+ InstallFrontend
183
+ .new(bundler_context: bundler_context, generator_context: self)
184
+ .call(@selected_frontend)
196
185
 
197
- InstallFrontend
198
- .new(bundler_context: bundler_context, generator_context: self)
199
- .call(frontend)
186
+ # The DEFAULT_FRONTEND installation makes changes to the
187
+ # bundle without updating the bundler context. As such, we need to
188
+ # reset the bundler context to get the latest dependencies from the
189
+ # context.
190
+ reset_bundler_context if @selected_frontend == DEFAULT_FRONTEND
191
+ end
200
192
  end
201
193
 
202
- def run_bundle_install_if_needed_by_plugins
203
- @plugins_to_be_installed.each do |plugin_name|
204
- gem plugin_name
205
- end
194
+ def install_authentication_plugin
195
+ return unless @with_authentication
206
196
 
207
- BundlerContext.bundle_cleanly { run "bundle install" } if @plugins_to_be_installed.any?
208
- run "spring stop" if defined?(Spring)
197
+ install_plugin(plugin_name: 'solidus_auth_devise', plugin_generator_name: 'solidus:auth:install')
198
+ end
209
199
 
210
- @plugin_generators_to_run.each do |plugin_generator_name|
211
- generate "#{plugin_generator_name} --skip_migrations=true"
212
- end
200
+ def install_payment_method
201
+ apply_template_for :payment_method, @selected_payment_method
213
202
  end
214
203
 
215
204
  def run_migrations
@@ -280,7 +269,21 @@ module Solidus
280
269
 
281
270
  private
282
271
 
283
- def detect_frontend_to_install(bundler_context)
272
+ def apply_template_for(topic, selected)
273
+ template_path = Dir["#{__dir__}/app_templates/#{topic}/*.rb"].find do |path|
274
+ File.basename(path, '.rb') == selected
275
+ end
276
+
277
+ unless template_path
278
+ say_status :warning, "Unknown #{topic}: #{selected.inspect}, attempting to run it with `rails app:template`"
279
+ template_path = selected
280
+ end
281
+
282
+ say_status :installing, "[#{topic}] #{selected}", :blue
283
+ apply template_path
284
+ end
285
+
286
+ def detect_frontend_to_install
284
287
  ENV['FRONTEND'] ||
285
288
  options[:frontend] ||
286
289
  (bundler_context.component_in_gemfile?(:frontend) && LEGACY_FRONTEND) ||
@@ -294,12 +297,32 @@ module Solidus
294
297
  MSG
295
298
  end
296
299
 
297
- def support_solidus_frontend_extraction(bundler_context)
300
+ def support_solidus_frontend_extraction
298
301
  say_status "break down", "solidus"
299
302
 
300
303
  SupportSolidusFrontendExtraction.
301
304
  new(bundler_context: bundler_context).
302
305
  call
303
306
  end
307
+
308
+ def install_plugin(plugin_name:, plugin_generator_name:)
309
+ if bundler_context.dependencies[plugin_name]
310
+ say_status :skipping, "#{plugin_name} is already in the gemfile"
311
+ return
312
+ end
313
+
314
+ gem plugin_name
315
+ run_bundle
316
+ run "spring stop" if defined?(Spring)
317
+ generate "#{plugin_generator_name} --skip_migrations=true"
318
+ end
319
+
320
+ def bundler_context
321
+ @bundler_context ||= BundlerContext.new
322
+ end
323
+
324
+ def reset_bundler_context
325
+ @bundler_context = nil
326
+ end
304
327
  end
305
328
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Spree
4
- VERSION = "3.2.3"
4
+ VERSION = "3.2.5"
5
5
 
6
6
  def self.solidus_version
7
7
  VERSION
data/lib/spree/core.rb CHANGED
@@ -14,7 +14,6 @@ require 'awesome_nested_set'
14
14
  require 'cancan'
15
15
  require 'friendly_id'
16
16
  require 'kaminari/activerecord'
17
- require 'mail'
18
17
  require 'monetize'
19
18
  require 'paperclip'
20
19
  require 'ransack'
@@ -10,6 +10,9 @@ module Spree
10
10
  #
11
11
  # A class including Preferable must implement #preferences which should return
12
12
  # an object responding to .fetch(key), []=(key, val), and .delete(key).
13
+ # If #preferences is initialized with `default_preferences` and one of the
14
+ # preferences is another preference, it will cause a stack level too deep error.
15
+ # To avoid it do not memoize #preferences.
13
16
  #
14
17
  # It may also define a `#context_for_default` method. It should return an
15
18
  # array with the arguments to be provided to a proc used as the `default:`
@@ -111,6 +114,8 @@ module Spree
111
114
  end
112
115
 
113
116
  # @return [Hash{Symbol => Object}] Default for all preferences defined on this class
117
+ # This may raise an infinite loop error if any of the defaults are
118
+ # dependent on other preferences defaults.
114
119
  def default_preferences
115
120
  Hash[
116
121
  defined_preferences.map do |preference|
@@ -75,7 +75,7 @@ module Spree::Preferences
75
75
  # is a pending preference before going to default
76
76
  define_method preference_getter_method(name) do
77
77
  value = preferences.fetch(name) do
78
- default.call(*context_for_default)
78
+ instance_exec(*context_for_default, &default)
79
79
  end
80
80
  value = preference_encryptor.decrypt(value) if preference_encryptor.present?
81
81
  value
@@ -92,7 +92,7 @@ module Spree::Preferences
92
92
  end
93
93
 
94
94
  define_method preference_default_getter_method(name) do
95
- default.call(*context_for_default)
95
+ instance_exec(*context_for_default, &default)
96
96
  end
97
97
 
98
98
  define_method preference_type_getter_method(name) do
@@ -1,9 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- unless defined?(Solidus::InstallGenerator)
4
- require 'generators/solidus/install/install_generator'
5
- end
6
-
7
3
  require 'generators/spree/dummy/dummy_generator'
8
4
 
9
5
  class CommonRakeTasks
@@ -17,8 +13,31 @@ class CommonRakeTasks
17
13
 
18
14
  force_rails_environment_to_test
19
15
 
20
- Spree::DummyGenerator.start ["--lib_name=#{ENV['LIB_NAME']}", "--quiet"]
21
- Solidus::InstallGenerator.start ["--lib_name=#{ENV['LIB_NAME']}", "--auto-accept", "--with-authentication=false", "--payment-method=none", "--migrate=false", "--seed=false", "--sample=false", "--quiet", "--user_class=#{args[:user_class]}"]
16
+ Spree::DummyGenerator.start [
17
+ "--lib-name=#{ENV['LIB_NAME']}",
18
+ "--quiet",
19
+ ]
20
+
21
+ # While the dummy app is generated the current directory
22
+ # within ruby is changed to that of the dummy app.
23
+ sh({
24
+ 'SKIP_SOLIDUS_BOLT' => '1',
25
+ 'FRONTEND' => 'solidus_frontend',
26
+ }, [
27
+ 'bin/rails',
28
+ 'generate',
29
+ 'solidus:install',
30
+ Dir.pwd, # use the current dir as Rails.root
31
+ "--lib-name=#{ENV['LIB_NAME']}",
32
+ "--auto-accept",
33
+ "--with-authentication=false",
34
+ "--payment-method=none",
35
+ "--migrate=false",
36
+ "--seed=false",
37
+ "--sample=false",
38
+ "--user-class=#{args[:user_class]}",
39
+ "--quiet",
40
+ ].shelljoin)
22
41
 
23
42
  puts "Setting up dummy database..."
24
43
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solidus_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.3
4
+ version: 3.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Solidus Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-03 00:00:00.000000000 Z
11
+ date: 2022-12-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionmailer
@@ -764,6 +764,9 @@ files:
764
764
  - db/migrate/20210312061050_change_column_null_on_prices.rb
765
765
  - db/migrate/20220317165036_set_promotions_with_any_policy_to_all_if_possible.rb
766
766
  - db/seeds.rb
767
+ - lib/generators/solidus/install/app_templates/payment_method/bolt.rb
768
+ - lib/generators/solidus/install/app_templates/payment_method/none.rb
769
+ - lib/generators/solidus/install/app_templates/payment_method/paypal.rb
767
770
  - lib/generators/solidus/install/install_generator.rb
768
771
  - lib/generators/solidus/install/install_generator/bundler_context.rb
769
772
  - lib/generators/solidus/install/install_generator/install_frontend.rb
@@ -1020,7 +1023,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1020
1023
  - !ruby/object:Gem::Version
1021
1024
  version: 1.8.23
1022
1025
  requirements: []
1023
- rubygems_version: 3.3.19
1026
+ rubygems_version: 3.3.26
1024
1027
  signing_key:
1025
1028
  specification_version: 4
1026
1029
  summary: Essential models, mailers, and classes for the Solidus e-commerce project.