solidus_core 3.1.9 → 3.2.0.alpha

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/app/helpers/spree/products_helper.rb +1 -1
  3. data/app/models/concerns/spree/active_storage_adapter/attachment.rb +23 -10
  4. data/app/models/concerns/spree/active_storage_adapter.rb +1 -1
  5. data/app/models/concerns/spree/default_price.rb +28 -4
  6. data/app/models/concerns/spree/user_address_book.rb +11 -1
  7. data/app/models/spree/adjustment.rb +1 -0
  8. data/app/models/spree/carton.rb +1 -1
  9. data/app/models/spree/option_value.rb +9 -0
  10. data/app/models/spree/order.rb +68 -29
  11. data/app/models/spree/order_contents.rb +2 -1
  12. data/app/models/spree/order_inventory.rb +1 -1
  13. data/app/models/spree/order_merger.rb +2 -2
  14. data/app/models/spree/order_taxation.rb +6 -4
  15. data/app/models/spree/order_updater.rb +4 -3
  16. data/app/models/spree/payment_method.rb +11 -0
  17. data/app/models/spree/price.rb +1 -1
  18. data/app/models/spree/product/scopes.rb +21 -3
  19. data/app/models/spree/product.rb +1 -1
  20. data/app/models/spree/promotion/actions/create_adjustment.rb +4 -0
  21. data/app/models/spree/promotion/actions/create_item_adjustments.rb +5 -6
  22. data/app/models/spree/promotion/rules/product.rb +20 -8
  23. data/app/models/spree/promotion/rules/store.rb +4 -0
  24. data/app/models/spree/promotion/rules/taxon.rb +4 -0
  25. data/app/models/spree/promotion/rules/user.rb +4 -0
  26. data/app/models/spree/promotion.rb +34 -23
  27. data/app/models/spree/promotion_action.rb +4 -0
  28. data/app/models/spree/promotion_code.rb +8 -4
  29. data/app/models/spree/promotion_handler/cart.rb +26 -6
  30. data/app/models/spree/promotion_rule.rb +5 -0
  31. data/app/models/spree/reimbursement.rb +2 -2
  32. data/app/models/spree/return_item.rb +1 -2
  33. data/app/models/spree/stock/allocator/on_hand_first.rb +2 -2
  34. data/app/models/spree/stock/quantifier.rb +12 -8
  35. data/app/models/spree/stock/simple_coordinator.rb +2 -1
  36. data/app/models/spree/tax/item_tax.rb +3 -2
  37. data/app/models/spree/tax/order_tax.rb +3 -1
  38. data/app/models/spree/tax/tax_location.rb +4 -7
  39. data/app/models/spree/tax_rate.rb +2 -0
  40. data/app/models/spree/variant/price_selector.rb +1 -18
  41. data/app/models/spree/variant.rb +2 -2
  42. data/app/subscribers/spree/mailer_subscriber.rb +4 -0
  43. data/app/subscribers/spree/order_mailer_subscriber.rb +35 -0
  44. data/config/locales/en.yml +7 -253
  45. data/db/migrate/20201127212108_add_type_before_removal_to_spree_payment_methods.rb +7 -0
  46. data/db/migrate/20220317165036_set_promotions_with_any_policy_to_all_if_possible.rb +20 -0
  47. data/lib/generators/solidus/install/install_generator/bundler_context.rb +97 -0
  48. data/lib/generators/solidus/install/install_generator/install_frontend.rb +50 -0
  49. data/lib/generators/solidus/install/install_generator/support_solidus_frontend_extraction.rb +48 -0
  50. data/lib/generators/solidus/install/install_generator.rb +56 -49
  51. data/lib/generators/solidus/install/templates/config/initializers/spree.rb.tt +6 -16
  52. data/lib/generators/solidus/install/templates/vendor/assets/javascripts/spree/backend/all.js +2 -2
  53. data/lib/spree/app_configuration.rb +29 -3
  54. data/lib/spree/bus.rb +20 -0
  55. data/lib/spree/core/controller_helpers/auth.rb +9 -1
  56. data/lib/spree/core/controller_helpers/current_host.rb +1 -3
  57. data/lib/spree/core/controller_helpers/order.rb +10 -10
  58. data/lib/spree/core/controller_helpers/search.rb +1 -1
  59. data/lib/spree/core/engine.rb +33 -8
  60. data/lib/spree/core/state_machines/order.rb +1 -1
  61. data/lib/spree/core/stock_configuration.rb +18 -0
  62. data/lib/spree/core/validators/email.rb +3 -1
  63. data/lib/spree/core/version.rb +1 -1
  64. data/lib/spree/core.rb +20 -0
  65. data/lib/spree/event/subscriber_registry.rb +4 -6
  66. data/lib/spree/event.rb +1 -1
  67. data/lib/spree/migrations.rb +1 -1
  68. data/lib/spree/permission_sets/default_customer.rb +8 -1
  69. data/lib/spree/permitted_attributes.rb +4 -4
  70. data/lib/spree/preferences/configuration.rb +34 -12
  71. data/lib/spree/preferences/preferable.rb +0 -5
  72. data/lib/spree/preferences/preferable_class_methods.rb +3 -3
  73. data/lib/spree/preferences/preference_differentiator.rb +2 -1
  74. data/lib/spree/preferences/static_model_preferences.rb +0 -2
  75. data/lib/spree/rails_compatibility.rb +99 -0
  76. data/lib/spree/testing_support/bus_helpers.rb +101 -0
  77. data/lib/spree/testing_support/common_rake.rb +47 -19
  78. data/lib/spree/testing_support/dummy_app/assets/javascripts/spree/backend/all.js +1 -1
  79. data/lib/spree/testing_support/dummy_app/assets/javascripts/spree/frontend/all.js +1 -1
  80. data/lib/spree/testing_support/dummy_app.rb +6 -2
  81. data/lib/spree/testing_support/factories/address_factory.rb +7 -2
  82. data/lib/spree/testing_support/factories/inventory_unit_factory.rb +1 -1
  83. data/lib/spree/testing_support/factories/order_factory.rb +8 -4
  84. data/lib/spree/testing_support/factories/product_factory.rb +4 -1
  85. data/lib/spree/testing_support/factories/store_credit_factory.rb +4 -4
  86. data/lib/spree/testing_support/factory_bot.rb +1 -1
  87. data/lib/spree/testing_support/order_walkthrough.rb +5 -4
  88. data/lib/spree/testing_support/silence_deprecations.rb +9 -0
  89. data/lib/tasks/payment_method.rake +29 -0
  90. data/lib/tasks/solidus/delete_prices_with_nil_amount.rake +2 -2
  91. data/lib/tasks/solidus/split_promotions_with_any_match_policy.rake +33 -0
  92. data/solidus_core.gemspec +6 -2
  93. metadata +71 -26
  94. data/lib/generators/solidus/install/templates/vendor/assets/javascripts/spree/frontend/all.js +0 -10
  95. data/lib/generators/solidus/install/templates/vendor/assets/stylesheets/spree/frontend/all.css +0 -9
@@ -31,16 +31,6 @@ Spree.config do |config|
31
31
  # to a custom users role:
32
32
  # config.roles.assign_permissions :role_name, ['Spree::PermissionSets::CustomPermissionSet']
33
33
 
34
-
35
- # Frontend:
36
-
37
- # Custom logo for the frontend
38
- # config.logo = "logo/solidus.svg"
39
-
40
- # Template to use when rendering layout
41
- # config.layout = "spree/layouts/spree_application"
42
-
43
-
44
34
  # Admin:
45
35
 
46
36
  # Custom logo for the admin
@@ -62,12 +52,6 @@ Spree.config do |config|
62
52
  # )
63
53
  end
64
54
 
65
- <% if defined?(Spree::Frontend::Engine) -%>
66
- Spree::Frontend::Config.configure do |config|
67
- config.locale = 'en'
68
- end
69
- <% end -%>
70
-
71
55
  <% if defined?(Spree::Backend::Engine) -%>
72
56
  Spree::Backend::Config.configure do |config|
73
57
  config.locale = 'en'
@@ -80,6 +64,12 @@ Spree::Backend::Config.configure do |config|
80
64
  # 'icon-name',
81
65
  # url: 'https://solidus.io/'
82
66
  # )
67
+
68
+ # Custom frontend product path
69
+ #
70
+ # config.frontend_product_path = ->(template_context, product) {
71
+ # template_context.spree.product_path(product)
72
+ # }
83
73
  end
84
74
  <% end -%>
85
75
 
@@ -1,10 +1,10 @@
1
1
  // This is a manifest file that'll be compiled into including all the files listed below.
2
- // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
2
+ // Add new JavaScript code in separate files in this directory and they'll automatically
3
3
  // be included in the compiled file accessible from http://example.com/assets/application.js
4
4
  // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
5
5
  // the compiled file.
6
6
  //
7
- //= require jquery
7
+ //= require jquery3
8
8
  //= require rails-ujs
9
9
  //= require spree/backend
10
10
  //= require_tree .
@@ -21,7 +21,6 @@ require "spree/core/search/base"
21
21
  require "spree/core/search/variant"
22
22
  require 'spree/preferences/configuration'
23
23
  require 'spree/core/environment'
24
- require 'rails/gem_version'
25
24
 
26
25
  module Spree
27
26
  class AppConfiguration < Preferences::Configuration
@@ -61,6 +60,11 @@ module Spree
61
60
  # @return [Boolean] When false, customers must create an account to complete an order (default: +true+)
62
61
  preference :allow_guest_checkout, :boolean, default: true
63
62
 
63
+ # @!attribute [rw] allow_promotions_any_match_policy
64
+ # @return [Boolean] When false, admins cannot create promotions with an "any" match policy (default: +false+)
65
+ # Create individual, separate promotions for each of your rules instead.
66
+ preference :allow_promotions_any_match_policy, :boolean, default: false
67
+
64
68
  # @!attribute [rw] guest_token_cookie_options
65
69
  # @return [Hash] Add additional guest_token cookie options here (ie. domain or path)
66
70
  preference :guest_token_cookie_options, :hash, default: {}
@@ -146,6 +150,10 @@ module Spree
146
150
  # @return [String] Two-letter ISO code of a {Spree::Country} to assumed as the country of an unidentified customer (default: "US")
147
151
  preference :default_country_iso, :string, default: 'US'
148
152
 
153
+ # @!attribute [rw] default_email_regexp
154
+ # @return [Regexp] Regex to be used in email validations, for example in Spree::EmailValidator
155
+ preference :default_email_regexp, :regexp, default: URI::MailTo::EMAIL_REGEXP
156
+
149
157
  # @!attribute [rw] generate_api_key_for_all_roles
150
158
  # @return [Boolean] Allow generating api key automatically for user
151
159
  # at role_user creation for all roles. (default: +false+)
@@ -280,6 +288,13 @@ module Spree
280
288
  # @return [] Track on_hand values for variants / products. (default: true)
281
289
  preference :track_inventory_levels, :boolean, default: true
282
290
 
291
+ # @!attribute [rw] use_legacy_events
292
+ # Before v3.2, Solidus used a custom pub/sub implementation based on
293
+ # ActiveSupport::Notifications. Now, we internally use and recommend
294
+ # [Omnes](https://github.com/nebulab/omnes). This preference allows falling
295
+ # back to the old system.
296
+ # @return [Boolean]
297
+ versioned_preference :use_legacy_events, :boolean, initial_value: true, boundaries: { "3.2.0.alpha" => false }
283
298
 
284
299
  # Other configurations
285
300
 
@@ -482,7 +497,7 @@ module Spree
482
497
  # @!attribute [rw] image_attachment_module
483
498
  # @return [Module] a module that can be included into Spree::Image to allow attachments
484
499
  # Enumerable of images adhering to the present_image_class interface
485
- class_name_attribute :image_attachment_module, default: Rails.gem_version >= Gem::Version.new("6.1.0") ? "Spree::Image::ActiveStorageAttachment" : "Spree::Image::PaperclipAttachment"
500
+ class_name_attribute :image_attachment_module, default: 'Spree::Image::ActiveStorageAttachment'
486
501
 
487
502
  # @!attribute [rw] allowed_image_mime_types
488
503
  #
@@ -540,7 +555,18 @@ module Spree
540
555
  # @!attribute [rw] taxon_attachment_module
541
556
  # @return [Module] a module that can be included into Spree::Taxon to allow attachments
542
557
  # Enumerable of taxons adhering to the present_taxon_class interface
543
- class_name_attribute :taxon_attachment_module, default: Rails.gem_version >= Gem::Version.new("6.1.0") ? "Spree::Taxon::ActiveStorageAttachment" : "Spree::Taxon::PaperclipAttachment"
558
+ class_name_attribute :taxon_attachment_module, default: 'Spree::Taxon::ActiveStorageAttachment'
559
+
560
+ # Configures the absolute path that contains the Solidus engine
561
+ # migrations. This will be checked at app boot to confirm that all Solidus
562
+ # migrations are installed.
563
+ #
564
+ # @!attribute [rw] migration_path
565
+ # @return [Pathname] the configured path. (default: `Rails.root.join('db', 'migrate')`)
566
+ attr_writer :migration_path
567
+ def migration_path
568
+ @migration_path ||= ::Rails.root.join('db', 'migrate')
569
+ end
544
570
 
545
571
  # Allows providing your own class instance for generating order numbers.
546
572
  #
data/lib/spree/bus.rb ADDED
@@ -0,0 +1,20 @@
1
+ require 'omnes'
2
+
3
+ module Spree
4
+ # Global [Omnes](https://github.com/nebulab/omnes) bus.
5
+ #
6
+ # This is used for internal events, while host applications are also able to
7
+ # use it.
8
+ #
9
+ # It has some modifications to support internal usage of the legacy event
10
+ # system {see Spree::AppConfiguration#use_legacy_events}.
11
+ Bus = Omnes::Bus.new
12
+ Bus.define_singleton_method(:publish) do |*args, **kwargs, &block|
13
+ if Spree::Config.use_legacy_events
14
+ Spree::Event.fire(*args, **kwargs, &block)
15
+ else
16
+ # Override caller_location to point to the actual event publisher
17
+ super(*args, **kwargs, caller_location: caller_locations(1)[0], &block)
18
+ end
19
+ end
20
+ end
@@ -18,6 +18,7 @@ module Spree
18
18
  included do
19
19
  before_action :set_guest_token
20
20
  helper_method :try_spree_current_user
21
+ helper_method :spree_current_user
21
22
 
22
23
  class_attribute :unauthorized_redirect
23
24
  self.unauthorized_redirect = -> do
@@ -32,7 +33,7 @@ module Spree
32
33
 
33
34
  # Needs to be overriden so that we use Spree's Ability rather than anyone else's.
34
35
  def current_ability
35
- @current_ability ||= Spree::Ability.new(try_spree_current_user)
36
+ @current_ability ||= Spree::Ability.new(spree_current_user)
36
37
  end
37
38
 
38
39
  def redirect_back_or_default(default)
@@ -53,6 +54,11 @@ module Spree
53
54
  Spree::UserLastUrlStorer.new(self).store_location
54
55
  end
55
56
 
57
+ # Auth extensions are expected to define it, otherwise it's a no-op
58
+ def spree_current_user
59
+ defined?(super) ? super : nil
60
+ end
61
+
56
62
  # proxy method to *possible* spree_current_user method
57
63
  # Authentication extensions (such as spree_auth_devise) are meant to provide spree_current_user
58
64
  def try_spree_current_user
@@ -65,6 +71,8 @@ module Spree
65
71
  current_spree_user
66
72
  end
67
73
  end
74
+
75
+ deprecate try_spree_current_user: :spree_current_user, deprecator: Spree::Deprecation
68
76
  end
69
77
  end
70
78
  end
@@ -7,9 +7,7 @@ module Spree
7
7
  extend ActiveSupport::Concern
8
8
 
9
9
  included do
10
- before_action do
11
- ActiveStorage::Current.host = request.base_url
12
- end
10
+ Spree::RailsCompatibility.active_storage_set_current(self)
13
11
  end
14
12
  end
15
13
  end
@@ -24,9 +24,9 @@ module Spree
24
24
 
25
25
  if should_build && (@current_order.nil? || @current_order.completed?)
26
26
  @current_order = Spree::Order.new(new_order_params)
27
- @current_order.user ||= try_spree_current_user
27
+ @current_order.user ||= spree_current_user
28
28
  # See issue https://github.com/spree/spree/issues/3346 for reasons why this line is here
29
- @current_order.created_by ||= try_spree_current_user
29
+ @current_order.created_by ||= spree_current_user
30
30
  @current_order.save! if should_create
31
31
  end
32
32
 
@@ -38,15 +38,15 @@ module Spree
38
38
 
39
39
  def associate_user
40
40
  @order ||= current_order
41
- if try_spree_current_user && @order
42
- @order.associate_user!(try_spree_current_user) if @order.user.blank? || @order.email.blank?
41
+ if spree_current_user && @order
42
+ @order.associate_user!(spree_current_user) if @order.user.blank? || @order.email.blank?
43
43
  end
44
44
  end
45
45
 
46
46
  def set_current_order
47
- if try_spree_current_user && current_order
48
- try_spree_current_user.orders.by_store(current_store).incomplete.where('id != ?', current_order.id).each do |order|
49
- current_order.merge!(order, try_spree_current_user)
47
+ if spree_current_user && current_order
48
+ spree_current_user.orders.by_store(current_store).incomplete.where('id != ?', current_order.id).each do |order|
49
+ current_order.merge!(order, spree_current_user)
50
50
  end
51
51
  end
52
52
  end
@@ -58,11 +58,11 @@ module Spree
58
58
  private
59
59
 
60
60
  def last_incomplete_order
61
- @last_incomplete_order ||= try_spree_current_user.last_incomplete_spree_order(store: current_store)
61
+ @last_incomplete_order ||= spree_current_user.last_incomplete_spree_order(store: current_store)
62
62
  end
63
63
 
64
64
  def current_order_params
65
- { currency: current_pricing_options.currency, guest_token: cookies.signed[:guest_token], store_id: current_store.id, user_id: try_spree_current_user.try(:id) }
65
+ { currency: current_pricing_options.currency, guest_token: cookies.signed[:guest_token], store_id: current_store.id, user_id: spree_current_user.try(:id) }
66
66
  end
67
67
 
68
68
  def new_order_params
@@ -76,7 +76,7 @@ module Spree
76
76
  order = Spree::Order.incomplete.lock(should_lock).find_by(current_order_params)
77
77
 
78
78
  # Find any incomplete orders for the current user
79
- if order.nil? && try_spree_current_user
79
+ if order.nil? && spree_current_user
80
80
  order = last_incomplete_order
81
81
  end
82
82
 
@@ -6,7 +6,7 @@ module Spree
6
6
  module Search
7
7
  def build_searcher(params)
8
8
  Spree::Config.searcher_class.new(params).tap do |searcher|
9
- searcher.current_user = try_spree_current_user
9
+ searcher.current_user = spree_current_user
10
10
  searcher.pricing_options = current_pricing_options
11
11
  end
12
12
  end
@@ -46,18 +46,33 @@ module Spree
46
46
  ]
47
47
  end
48
48
 
49
- initializer "spree.core.checking_migrations", before: :load_config_initializers do |_app|
49
+ initializer "spree.core.checking_migrations", after: :load_config_initializers do |_app|
50
50
  Migrations.new(config, engine_name).check
51
51
  end
52
52
 
53
- # Setup Event Subscribers
54
- initializer 'spree.core.initialize_subscribers' do |app|
55
- app.reloader.to_prepare do
56
- Spree::Event.activate_autoloadable_subscribers
57
- end
53
+ # Setup pub/sub
54
+ initializer 'spree.core.pub_sub' do |app|
55
+ if Spree::Config.use_legacy_events
56
+ app.reloader.to_prepare do
57
+ Spree::Event.activate_autoloadable_subscribers
58
+ end
59
+
60
+ app.reloader.before_class_unload do
61
+ Spree::Event.deactivate_all_subscribers
62
+ end
63
+ else
64
+ app.reloader.to_prepare do
65
+ Spree::Bus.clear
58
66
 
59
- app.reloader.before_class_unload do
60
- Spree::Event.deactivate_all_subscribers
67
+ %i[
68
+ order_finalized
69
+ order_recalculated
70
+ reimbursement_reimbursed
71
+ reimbursement_errored
72
+ ].each { |event_name| Spree::Bus.register(event_name) }
73
+
74
+ Spree::OrderMailerSubscriber.new.subscribe_to(Spree::Bus)
75
+ end
61
76
  end
62
77
  end
63
78
 
@@ -81,6 +96,16 @@ module Spree
81
96
  Spree::UsersController.protect_from_forgery with: :exception
82
97
  end
83
98
  end
99
+
100
+ config.after_initialize do
101
+ if Spree::Config.use_legacy_events && !ENV['CI']
102
+ Spree::Deprecation.warn <<~MSG
103
+ Your Solidus store is using the legacy event system. You're
104
+ encouraged to switch to the new event bus. After you're done, you
105
+ can remove the `use_legacy_events` setting from `spree.rb`.
106
+ MSG
107
+ end
108
+ end
84
109
  end
85
110
  end
86
111
  end
@@ -119,7 +119,7 @@ module Spree
119
119
  before_transition to: :complete, do: :process_payments_before_complete
120
120
  end
121
121
 
122
- after_transition to: :complete, do: :finalize!
122
+ after_transition to: :complete, do: :finalize
123
123
  after_transition to: :resumed, do: :after_resume
124
124
  after_transition to: :canceled, do: :after_cancel
125
125
 
@@ -8,6 +8,9 @@ module Spree
8
8
  attr_writer :location_filter_class
9
9
  attr_writer :location_sorter_class
10
10
  attr_writer :allocator_class
11
+ attr_writer :inventory_unit_builder_class
12
+ attr_writer :availability_validator_class
13
+ attr_writer :inventory_validator_class
11
14
 
12
15
  def coordinator_class
13
16
  @coordinator_class ||= '::Spree::Stock::SimpleCoordinator'
@@ -33,6 +36,21 @@ module Spree
33
36
  @allocator_class ||= '::Spree::Stock::Allocator::OnHandFirst'
34
37
  @allocator_class.constantize
35
38
  end
39
+
40
+ def inventory_unit_builder_class
41
+ @inventory_unit_builder_class ||= '::Spree::Stock::InventoryUnitBuilder'
42
+ @inventory_unit_builder_class.constantize
43
+ end
44
+
45
+ def availability_validator_class
46
+ @availability_validator_class ||= '::Spree::Stock::AvailabilityValidator'
47
+ @availability_validator_class.constantize
48
+ end
49
+
50
+ def inventory_validator_class
51
+ @inventory_validator_class ||= '::Spree::Stock::InventoryValidator'
52
+ @inventory_validator_class.constantize
53
+ end
36
54
  end
37
55
  end
38
56
  end
@@ -13,9 +13,11 @@ module Spree
13
13
  #
14
14
  class EmailValidator < ActiveModel::EachValidator
15
15
  EMAIL_REGEXP = URI::MailTo::EMAIL_REGEXP
16
+ # Use Spree::Config.default_email_regexp instead
17
+ deprecate_constant :EMAIL_REGEXP
16
18
 
17
19
  def validate_each(record, attribute, value)
18
- unless EMAIL_REGEXP.match? value
20
+ unless Spree::Config.default_email_regexp.match? value
19
21
  record.errors.add(attribute, :invalid, **{ value: value }.merge!(options))
20
22
  end
21
23
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Spree
4
- VERSION = "3.1.9"
4
+ VERSION = "3.2.0.alpha"
5
5
 
6
6
  def self.solidus_version
7
7
  VERSION
data/lib/spree/core.rb CHANGED
@@ -21,6 +21,7 @@ require 'ransack'
21
21
  require 'state_machines-activerecord'
22
22
 
23
23
  require 'spree/deprecation'
24
+ require 'spree/rails_compatibility'
24
25
 
25
26
  # This is required because ActiveModel::Validations#invalid? conflicts with the
26
27
  # invalid state of a Payment. In the future this should be removed.
@@ -84,6 +85,24 @@ module Spree
84
85
  end
85
86
  end
86
87
 
88
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.7")
89
+ Spree::Deprecation.warn <<~HEREDOC
90
+ Ruby 2.5 & Ruby 2.6 (both EOL) are deprecated and will not be supported anymore from the next Solidus version.
91
+ Please, upgrade to a more recent Ruby version.
92
+ Read more on the release notes for different Ruby versions here:
93
+ https://www.ruby-lang.org/en/downloads/releases/
94
+ HEREDOC
95
+ end
96
+
97
+ if Gem::Version.new(Rails.version) < Gem::Version.new('6.0')
98
+ Spree::Deprecation.warn <<~HEREDOC
99
+ Rails 5.2 (EOL) is deprecated and will not be supported anymore from the next Solidus version.
100
+ Please, upgrade to a more recent Rails version.
101
+ Read more on upgrading from Rails 5.2 to Rails 6.0 here:
102
+ https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#upgrading-from-rails-5-2-to-rails-6-0
103
+ HEREDOC
104
+ end
105
+
87
106
  require 'spree/core/version'
88
107
 
89
108
  require 'spree/core/active_merchant_dependencies'
@@ -95,6 +114,7 @@ require 'spree/core/environment'
95
114
  require 'spree/migrations'
96
115
  require 'spree/migration_helpers'
97
116
  require 'spree/event'
117
+ require 'spree/bus'
98
118
  require 'spree/core/engine'
99
119
 
100
120
  require 'spree/i18n'
@@ -64,13 +64,11 @@ module Spree
64
64
  # Loading the files has the side effect of adding their module to the
65
65
  # list in Spree::Event.subscribers.
66
66
  def require_subscriber_files
67
- pattern = "app/subscribers/**/*_subscriber.rb"
67
+ require_dependency(
68
+ Spree::Core::Engine.root.join('app', 'subscribers', 'spree', 'mailer_subscriber.rb')
69
+ )
68
70
 
69
- # Load Solidus subscribers
70
- # rubocop:disable Rails/DynamicFindBy
71
- solidus_core_dir = Gem::Specification.find_by_name('solidus_core').gem_dir
72
- # rubocop:enable Rails/DynamicFindBy
73
- Dir.glob(File.join(solidus_core_dir, pattern)) { |c| require_dependency(c.to_s) }
71
+ pattern = "app/subscribers/**/*_subscriber.rb"
74
72
 
75
73
  # Load application subscribers, only when the flag is set to true:
76
74
  if Spree::Config.events.autoload_subscribers
data/lib/spree/event.rb CHANGED
@@ -21,7 +21,7 @@ module Spree
21
21
  #
22
22
  # @example Trigger an event named 'order_finalized'
23
23
  # Spree::Event.fire 'order_finalized', order: @order do
24
- # @order.finalize!
24
+ # @order.complete!
25
25
  # end
26
26
  def fire(event_name, opts = {})
27
27
  adapter.fire normalize_name(event_name), opts do
@@ -66,7 +66,7 @@ module Spree
66
66
  end
67
67
 
68
68
  def app_dir
69
- "#{Rails.root}/db/migrate"
69
+ Spree::Config.migration_path
70
70
  end
71
71
 
72
72
  def engine_dir
@@ -7,7 +7,14 @@ module Spree
7
7
  can :read, Country
8
8
  can :read, OptionType
9
9
  can :read, OptionValue
10
- can :create, Order
10
+ can :create, Order do |order, token|
11
+ # same user, or both nil
12
+ order.user == user ||
13
+ # guest checkout order
14
+ order.email.present? ||
15
+ # via API, just like with show and update
16
+ (order.guest_token.present? && token == order.guest_token)
17
+ end
11
18
  can [:show, :update], Order, Order.where(user: user) do |order, token|
12
19
  order.user == user || (order.guest_token.present? && token == order.guest_token)
13
20
  end
@@ -65,10 +65,10 @@ module Spree
65
65
 
66
66
  @@line_item_attributes = [:id, :variant_id, :quantity]
67
67
 
68
- @@option_type_attributes = [:name, :presentation, :option_values_attributes]
69
-
70
68
  @@option_value_attributes = [:name, :presentation]
71
69
 
70
+ @@option_type_attributes = [:name, :presentation, option_values_attributes: option_value_attributes]
71
+
72
72
  @@payment_attributes = [:amount, :payment_method_id, :payment_method]
73
73
 
74
74
  @@product_properties_attributes = [:property_name, :value, :position]
@@ -131,8 +131,8 @@ module Spree
131
131
  @@variant_attributes = [
132
132
  :name, :presentation, :cost_price, :lock_version,
133
133
  :position, :track_inventory,
134
- :product_id, :product, :option_values_attributes, :price,
135
- :weight, :height, :width, :depth, :sku, :cost_currency, option_value_ids: [], options: [:name, :value]
134
+ :product_id, :product, :price,
135
+ :weight, :height, :width, :depth, :sku, :cost_currency, :tax_category_id, option_value_ids: [], options: [:name, :value]
136
136
  ]
137
137
 
138
138
  @@checkout_address_attributes = [
@@ -38,6 +38,7 @@ module Spree::Preferences
38
38
  # defaults. Set via {#load_defaults}
39
39
  attr_reader :loaded_defaults
40
40
 
41
+ # @api private
41
42
  attr_reader :load_defaults_called
42
43
 
43
44
  def initialize
@@ -45,9 +46,9 @@ module Spree::Preferences
45
46
  @load_defaults_called = false
46
47
  end
47
48
 
48
- # @param [String] Solidus version from which take defaults when not
49
- # overriden.
50
- # @see #load_defaults
49
+ # @param [String] Solidus version from which take defaults when preferences
50
+ # are not overriden by the user.
51
+ # @see #loaded_defaults
51
52
  def load_defaults(version)
52
53
  @loaded_defaults = version
53
54
  @load_defaults_called = true
@@ -118,21 +119,35 @@ module Spree::Preferences
118
119
  end
119
120
  end
120
121
 
121
- # Generates a different preference default depending on {#version_defaults}
122
+ def self.inherited(klass)
123
+ klass.instance_variable_set(:@versioned_preferences, [])
124
+ class << klass
125
+ attr_reader :versioned_preferences
126
+ end
127
+ end
128
+
129
+ # Adds a preference with different default depending on {#loaded_defaults}
122
130
  #
123
- # This method is meant to be used in the `default:` keyword argument for
124
- # {.preference}. For instance, in the example, `foo`'s default was `true`
125
- # until version 3.0.0.alpha, when it became `false`:
131
+ # This method is a specialized version of {.preference} that generates a
132
+ # different default value for different Solidus versions. For instance, in
133
+ # the example, `foo`'s default was `true` until version 3.0.0.alpha, when it
134
+ # became `false`:
126
135
  #
127
136
  # @example
128
- # preference :foo, :boolean, default: by_version(true, "3.0.0.alpha" => false)
137
+ # versioned_preference :foo, :boolean, initial_value: true, boundaries: { "3.0.0.alpha" => false }
129
138
  #
139
+ # @see .preference
130
140
  # @see #loaded_defaults
131
141
  # @see Spree::Core::VersionedValue
132
- def self.by_version(*args)
133
- proc do |loaded_defaults|
134
- Spree::Core::VersionedValue.new(*args).call(loaded_defaults)
135
- end
142
+ def self.versioned_preference(name, type, initial_value:, boundaries:, **options)
143
+ @versioned_preferences << name
144
+ preference(
145
+ name,
146
+ type,
147
+ options.merge(
148
+ default: by_version(initial_value, boundaries)
149
+ )
150
+ )
136
151
  end
137
152
 
138
153
  def self.preference(name, type, options = {})
@@ -160,6 +175,13 @@ module Spree::Preferences
160
175
  end
161
176
  end
162
177
 
178
+ def self.by_version(*args)
179
+ proc do |loaded_defaults|
180
+ Spree::Core::VersionedValue.new(*args).call(loaded_defaults)
181
+ end
182
+ end
183
+ private_class_method :by_version
184
+
163
185
  private
164
186
 
165
187
  def context_for_default
@@ -10,9 +10,6 @@ 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.
16
13
  #
17
14
  # It may also define a `#context_for_default` method. It should return an
18
15
  # array with the arguments to be provided to a proc used as the `default:`
@@ -114,8 +111,6 @@ module Spree
114
111
  end
115
112
 
116
113
  # @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.
119
114
  def default_preferences
120
115
  Hash[
121
116
  defined_preferences.map do |preference|
@@ -49,7 +49,7 @@ module Spree::Preferences
49
49
 
50
50
  If you want to branch on the provided Solidus version, you can do like the following:
51
51
 
52
- preference :foo, :string, default: by_version(true, "3.2.0" => false)
52
+ versioned_preference :foo, :string, initial_value: true, boundaries: { "3.2.0" => false }
53
53
 
54
54
  MSG
55
55
  ->(_default_context) { given.call }
@@ -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
- instance_exec(*context_for_default, &default)
78
+ default.call(*context_for_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
- instance_exec(*context_for_default, &default)
95
+ default.call(*context_for_default)
96
96
  end
97
97
 
98
98
  define_method preference_type_getter_method(name) do
@@ -12,7 +12,8 @@ module Spree
12
12
  def call(from:, to:)
13
13
  preferences_from = config_class.new.load_defaults(from)
14
14
  preferences_to = config_class.new.load_defaults(to)
15
- preferences_from.reduce({}) do |changes, (pref_key, value_from)|
15
+ config_class.versioned_preferences.reduce({}) do |changes, pref_key|
16
+ value_from = preferences_from[pref_key]
16
17
  value_to = preferences_to[pref_key]
17
18
  if value_from == value_to
18
19
  changes
@@ -36,8 +36,6 @@ module Spree
36
36
  end
37
37
 
38
38
  def add(klass, name, preferences)
39
- # We use class name instead of class to allow reloading in dev
40
- raise "Static model preference '#{name}' on #{klass} is already defined" if @store[klass.to_s][name]
41
39
  @store[klass.to_s][name] = Definition.new(klass, preferences)
42
40
  end
43
41