solidus_core 3.2.3 → 3.2.5

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