solidus_core 3.0.0.rc2 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of solidus_core might be problematic. Click here for more details.

Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/app/helpers/spree/base_helper.rb +1 -1
  3. data/app/helpers/spree/products_helper.rb +1 -1
  4. data/app/models/concerns/spree/active_storage_adapter/attachment.rb +11 -11
  5. data/app/models/concerns/spree/active_storage_adapter.rb +2 -0
  6. data/app/models/concerns/spree/default_price.rb +63 -10
  7. data/app/models/spree/adjustment.rb +6 -5
  8. data/app/models/spree/base.rb +0 -17
  9. data/app/models/spree/calculator.rb +4 -0
  10. data/app/models/spree/customer_return.rb +3 -2
  11. data/app/models/spree/image/active_storage_attachment.rb +11 -8
  12. data/app/models/spree/image/paperclip_attachment.rb +3 -3
  13. data/app/models/spree/line_item.rb +2 -2
  14. data/app/models/spree/order.rb +12 -7
  15. data/app/models/spree/payment_method/bogus_credit_card.rb +13 -9
  16. data/app/models/spree/payment_method/simple_bogus_credit_card.rb +4 -4
  17. data/app/models/spree/payment_method.rb +3 -0
  18. data/app/models/spree/price.rb +1 -1
  19. data/app/models/spree/product/scopes.rb +5 -5
  20. data/app/models/spree/product.rb +12 -1
  21. data/app/models/spree/promotion/rules/item_total.rb +50 -6
  22. data/app/models/spree/promotion.rb +2 -2
  23. data/app/models/spree/promotion_action.rb +3 -0
  24. data/app/models/spree/promotion_code.rb +1 -1
  25. data/app/models/spree/promotion_rule.rb +4 -0
  26. data/app/models/spree/return_item.rb +2 -3
  27. data/app/models/spree/shipping_rate_tax.rb +1 -1
  28. data/app/models/spree/stock/availability.rb +11 -3
  29. data/app/models/spree/stock/simple_coordinator.rb +6 -11
  30. data/app/models/spree/stock_location.rb +1 -1
  31. data/app/models/spree/store_credit.rb +6 -1
  32. data/app/models/spree/tax_calculator/shipping_rate.rb +1 -1
  33. data/app/models/spree/taxon/active_storage_attachment.rb +2 -2
  34. data/app/models/spree/taxon/paperclip_attachment.rb +3 -3
  35. data/app/models/spree/variant/price_selector.rb +16 -3
  36. data/app/models/spree/variant.rb +27 -17
  37. data/config/locales/en.yml +2 -0
  38. data/db/migrate/20210312061050_change_column_null_on_prices.rb +7 -0
  39. data/lib/generators/solidus/install/install_generator.rb +2 -2
  40. data/lib/generators/solidus/install/templates/config/initializers/spree.rb.tt +3 -1
  41. data/lib/generators/solidus/update/templates/config/initializers/new_solidus_defaults.rb.tt +30 -0
  42. data/lib/generators/solidus/update/update_generator.rb +112 -0
  43. data/lib/generators/spree/dummy/templates/rails/application.rb.tt +0 -1
  44. data/lib/generators/spree/dummy/templates/rails/database.yml +78 -35
  45. data/lib/spree/app_configuration.rb +70 -0
  46. data/lib/spree/core/engine.rb +10 -11
  47. data/lib/spree/core/product_filters.rb +1 -1
  48. data/lib/spree/core/search/base.rb +1 -1
  49. data/lib/spree/core/state_machines/order.rb +1 -1
  50. data/lib/spree/core/validators/email.rb +1 -1
  51. data/lib/spree/core/version.rb +5 -1
  52. data/lib/spree/core/versioned_value.rb +75 -0
  53. data/lib/spree/core.rb +17 -0
  54. data/lib/spree/deprecation.rb +1 -1
  55. data/lib/spree/permitted_attributes.rb +8 -2
  56. data/lib/spree/preferences/configuration.rb +62 -0
  57. data/lib/spree/preferences/persistable.rb +23 -0
  58. data/lib/spree/preferences/preferable.rb +8 -0
  59. data/lib/spree/preferences/preferable_class_methods.rb +5 -3
  60. data/lib/spree/preferences/preference_differentiator.rb +28 -0
  61. data/lib/spree/testing_support/dummy_app/database.yml +42 -22
  62. data/lib/spree/testing_support/dummy_app.rb +33 -17
  63. data/lib/spree/testing_support/fixtures/file.txt +1 -0
  64. data/lib/spree/testing_support.rb +1 -1
  65. data/lib/tasks/solidus/delete_prices_with_nil_amount.rake +8 -0
  66. data/solidus_core.gemspec +20 -0
  67. metadata +29 -8
  68. data/app/models/spree/tax/shipping_rate_taxer.rb +0 -24
  69. data/lib/tasks/migrations/migrate_address_names.rake +0 -158
  70. data/lib/tasks/migrations/migrate_default_billing_addresses_to_address_book.rake +0 -38
  71. data/lib/tasks/upgrade.rake +0 -13
@@ -372,6 +372,28 @@ module Spree
372
372
  # Spree::Wallet::DefaultPaymentBuilder.
373
373
  class_name_attribute :default_payment_builder_class, default: 'Spree::Wallet::DefaultPaymentBuilder'
374
374
 
375
+ # Allows providing your own class for managing the contents of an order.
376
+ #
377
+ # @!attribute [rw] order_contents_class
378
+ # @return [Class] a class with the same public interfaces as
379
+ # Spree::OrderContents.
380
+ class_name_attribute :order_contents_class, default: 'Spree::OrderContents'
381
+
382
+ # Allows providing your own class for shipping an order.
383
+ #
384
+ # @!attribute [rw] order_shipping_class
385
+ # @return [Class] a class with the same public interfaces as
386
+ # Spree::OrderShipping.
387
+ class_name_attribute :order_shipping_class, default: 'Spree::OrderShipping'
388
+
389
+ # Allows providing your own class for managing the inventory units of a
390
+ # completed order.
391
+ #
392
+ # @!attribute [rw] order_cancellations_class
393
+ # @return [Class] a class with the same public interfaces as
394
+ # Spree::OrderCancellations.
395
+ class_name_attribute :order_cancellations_class, default: 'Spree::OrderCancellations'
396
+
375
397
  # Allows providing your own class for canceling payments.
376
398
  #
377
399
  # @!attribute [rw] payment_canceller
@@ -445,6 +467,54 @@ module Spree
445
467
  # Enumerable of images adhering to the present_image_class interface
446
468
  class_name_attribute :image_attachment_module, default: 'Spree::Image::ActiveStorageAttachment'
447
469
 
470
+ # @!attribute [rw] allowed_image_mime_types
471
+ #
472
+ # Defines which MIME types are allowed for images
473
+ # `%w(image/jpeg image/jpg image/png image/gif).freeze` is the default.
474
+ #
475
+ # @return [Array]
476
+ class_name_attribute :allowed_image_mime_types, default: %w(image/jpeg image/jpg image/png image/gif).freeze
477
+
478
+ # @!attribute [rw] product_image_style_default
479
+ #
480
+ # Defines which style to default to when style is not provided
481
+ # :product is the default.
482
+ #
483
+ # @return [Symbol]
484
+ class_name_attribute :product_image_style_default, default: :product
485
+
486
+ # @!attribute [rw] product_image_styles
487
+ #
488
+ # Defines image styles/sizes hash for styles
489
+ # `{ mini: '48x48>',
490
+ # small: '400x400>',
491
+ # product: '680x680>',
492
+ # large: '1200x1200>' } is the default.
493
+ #
494
+ # @return [Hash]
495
+ class_name_attribute :product_image_styles, default: { mini: '48x48>',
496
+ small: '400x400>',
497
+ product: '680x680>',
498
+ large: '1200x1200>' }
499
+ # @!attribute [rw] taxon_image_style_default
500
+ #
501
+ # Defines which style to default to when style is not provided
502
+ # :mini is the default.
503
+ #
504
+ # @return [Symbol]
505
+ class_name_attribute :taxon_image_style_default, default: :mini
506
+
507
+ # @!attribute [rw] taxon_styles
508
+ #
509
+ # Defines taxon styles/sizes hash for styles
510
+ # `{ mini: '48x48>',
511
+ # small: '400x400>',
512
+ # product: '680x680>',
513
+ # large: '1200x1200>' } is the default.
514
+ #
515
+ # @return [Hash]
516
+ class_name_attribute :taxon_image_styles, default: { mini: '32x32>', normal: '128x128>' }
517
+
448
518
  # Allows switching attachment library for Taxon
449
519
  #
450
520
  # `Spree::Taxon::ActiveStorageAttachment`
@@ -55,18 +55,17 @@ module Spree
55
55
  end
56
56
  end
57
57
 
58
- config.after_initialize do
59
- # Load in mailer previews for apps to use in development.
60
- # We need to make sure we call `Preview.all` before requiring our
61
- # previews, otherwise any previews the app attempts to add need to be
62
- # manually required.
63
- if Rails.env.development? || Rails.env.test?
64
- ActionMailer::Preview.all
58
+ # Load in mailer previews for apps to use in development.
59
+ initializer "spree.core.action_mailer.set_preview_path", after: "action_mailer.set_configs" do |app|
60
+ original_preview_path = app.config.action_mailer.preview_path
61
+ solidus_preview_path = Spree::Core::Engine.root.join 'lib/spree/mailer_previews'
65
62
 
66
- Dir[root.join("lib/spree/mailer_previews/**/*_preview.rb")].each do |file|
67
- require_dependency file
68
- end
69
- end
63
+ app.config.action_mailer.preview_path = "{#{original_preview_path},#{solidus_preview_path}}"
64
+ ActionMailer::Base.preview_path = app.config.action_mailer.preview_path
65
+ end
66
+
67
+ config.after_initialize do
68
+ Spree::Config.check_load_defaults_called('Spree::Config')
70
69
  end
71
70
  end
72
71
  end
@@ -61,7 +61,7 @@ module Spree
61
61
  scope = scope.or(new_scope)
62
62
  end
63
63
 
64
- Spree::Product.joins(master: :default_price).where(scope)
64
+ Spree::Product.joins(master: :prices).where(scope)
65
65
  end
66
66
 
67
67
  def self.format_price(amount)
@@ -51,7 +51,7 @@ module Spree
51
51
  # separate queries most of the time but opt for a join as soon as any
52
52
  # `where` constraints affecting joined tables are added to the search;
53
53
  # which is the case as soon as a taxon is added to the base scope.
54
- scope = scope.preload(master: :currently_valid_prices)
54
+ scope = scope.preload(master: :prices)
55
55
  scope = scope.preload(master: :images) if @properties[:include_images]
56
56
  scope
57
57
  end
@@ -73,7 +73,7 @@ module Spree
73
73
  end
74
74
 
75
75
  event :complete do
76
- transition to: :complete, from: :confirm
76
+ transition to: :complete, from: klass.checkout_steps.keys.last
77
77
  end
78
78
 
79
79
  if states[:payment]
@@ -16,7 +16,7 @@ module Spree
16
16
 
17
17
  def validate_each(record, attribute, value)
18
18
  unless EMAIL_REGEXP.match? value
19
- record.errors.add(attribute, :invalid, { value: value }.merge!(options))
19
+ record.errors.add(attribute, :invalid, **{ value: value }.merge!(options))
20
20
  end
21
21
  end
22
22
  end
@@ -1,12 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Spree
4
- VERSION = "3.0.0.rc2"
4
+ VERSION = "3.1.0"
5
5
 
6
6
  def self.solidus_version
7
7
  VERSION
8
8
  end
9
9
 
10
+ def self.previous_solidus_minor_version
11
+ '3.0'
12
+ end
13
+
10
14
  def self.solidus_gem_version
11
15
  Gem::Version.new(solidus_version)
12
16
  end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ module Core
5
+ # Wrapper for a value that can be different depending on the Solidus version
6
+ #
7
+ # Some configuration defaults can be added or changed when a new Solidus
8
+ # version is released. This class encapsulates getting the correct value for a
9
+ # given Solidus version.
10
+ #
11
+ # The way it works is you provide an initial value in time, plus the version
12
+ # boundary where it got changed. Then you can fetch the value providing the
13
+ # desired Solidus version:
14
+ #
15
+ # @example
16
+ # value = VersionedValue.new(true, "3.0.0" => false)
17
+ # value.call("2.7.0") # => true
18
+ # value.call("3.0.0") # => false
19
+ # value.call("3.1.0") # => false
20
+ #
21
+ # Remember that you must provide the exact boundary when a value got changed,
22
+ # which could easily be during a pre-release:
23
+ #
24
+ # @example
25
+ # value = VersionedValue.new(true, "3.0.0" => false)
26
+ # value.call("3.0.0.alpha") # => true
27
+ #
28
+ # value = VersionedValue.new(true, "3.0.0.alpha" => false)
29
+ # value.call("3.0.0.alpha") # => false
30
+ #
31
+ # Multiple boundaries can also be provided:
32
+ #
33
+ # @example
34
+ # value = VersionedValue.new(0, "2.0.0" => 1, "3.0.0" => 2)
35
+ # value.call("1.0.0") # => 0
36
+ # value.call("2.1.0") # => 1
37
+ # value.call("3.0.0") # => 2
38
+ class VersionedValue
39
+ attr_reader :boundaries
40
+
41
+ # @param initial_value [Any]
42
+ # @param boundary [Hash<String, Any>] Map from version number to new value
43
+ def initialize(initial_value, boundaries = {})
44
+ @boundaries = Hash[
45
+ { '0' => initial_value }
46
+ .merge(boundaries)
47
+ .transform_keys { |version| to_gem_version(version) }
48
+ .sort
49
+ ]
50
+ end
51
+
52
+ # @param solidus_version [String]
53
+ def call(solidus_version = Spree.solidus_version)
54
+ solidus_version = to_gem_version(solidus_version)
55
+ boundaries.fetch(
56
+ boundaries
57
+ .keys
58
+ .reduce do |target, following|
59
+ if target <= solidus_version && solidus_version < following
60
+ target
61
+ else
62
+ following
63
+ end
64
+ end
65
+ )
66
+ end
67
+
68
+ private
69
+
70
+ def to_gem_version(string)
71
+ Gem::Version.new(string)
72
+ end
73
+ end
74
+ end
75
+ end
data/lib/spree/core.rb CHANGED
@@ -37,6 +37,16 @@ module Spree
37
37
  end
38
38
  end
39
39
 
40
+ # Load the same version defaults for all available Solidus components
41
+ #
42
+ # @see Spree::Preferences::Configuration#load_defaults
43
+ def self.load_defaults(version)
44
+ Spree::Config.load_defaults(version)
45
+ Spree::Frontend::Config.load_defaults(version) if defined?(Spree::Frontend::Config)
46
+ Spree::Backend::Config.load_defaults(version) if defined?(Spree::Backend::Config)
47
+ Spree::Api::Config.load_defaults(version) if defined?(Spree::Api::Config)
48
+ end
49
+
40
50
  # Used to configure Spree.
41
51
  #
42
52
  # Example:
@@ -52,6 +62,13 @@ module Spree
52
62
  end
53
63
 
54
64
  module Core
65
+ def self.has_install_generator_been_run?
66
+ (Rails.env.test? && Rails.application.class.name == 'DummyApp::Application') ||
67
+ Rails.application.paths['config/initializers'].paths.any? do |path|
68
+ File.exist?(path.join('spree.rb'))
69
+ end
70
+ end
71
+
55
72
  class GatewayError < RuntimeError; end
56
73
  end
57
74
  end
@@ -3,7 +3,7 @@
3
3
  require 'active_support/deprecation'
4
4
 
5
5
  module Spree
6
- Deprecation = ActiveSupport::Deprecation.new('3.0', 'Solidus')
6
+ Deprecation = ActiveSupport::Deprecation.new('4.0', 'Solidus')
7
7
 
8
8
  # This DeprecatedInstanceVariableProxy transforms instance variable to
9
9
  # deprecated instance variable.
@@ -51,7 +51,13 @@ module Spree
51
51
  :month, :year, :expiry, :first_name, :last_name, :name
52
52
  ]
53
53
 
54
- @@customer_return_attributes = [:stock_location_id, return_items_attributes: [:id, :inventory_unit_id, :return_authorization_id, :returned, :amount, :reception_status_event, :acceptance_status, :exchange_variant_id, :resellable]]
54
+ @@customer_return_attributes = [
55
+ :stock_location_id, return_items_attributes: [
56
+ :id, :inventory_unit_id, :return_authorization_id, :returned, :amount,
57
+ :reception_status_event, :acceptance_status, :exchange_variant_id,
58
+ :resellable, :return_reason_id
59
+ ]
60
+ ]
55
61
 
56
62
  @@image_attributes = [:alt, :attachment, :position, :viewable_type, :viewable_id]
57
63
 
@@ -68,7 +74,7 @@ module Spree
68
74
  @@product_properties_attributes = [:property_name, :value, :position]
69
75
 
70
76
  @@product_attributes = [
71
- :name, :description, :available_on, :discontinue_on, :permalink, :meta_description,
77
+ :name, :description, :available_on, :discontinue_on, :meta_description,
72
78
  :meta_keywords, :price, :sku, :deleted_at,
73
79
  :option_values_hash, :weight, :height, :width, :depth,
74
80
  :shipping_category_id, :tax_category_id,
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'spree/core/versioned_value'
3
4
  require 'spree/preferences/preferable'
4
5
 
5
6
  module Spree::Preferences
@@ -29,6 +30,44 @@ module Spree::Preferences
29
30
  class Configuration
30
31
  include Spree::Preferences::Preferable
31
32
 
33
+ # @!attribute [r] loaded_defaults
34
+ # @return [String]
35
+ # Some configuration defaults can be added or changed when a new Solidus
36
+ # version is released. Setting this to an older Solidus version allows keeping
37
+ # backward compatibility until the application code is updated to the new
38
+ # defaults. Set via {#load_defaults}
39
+ attr_reader :loaded_defaults
40
+
41
+ attr_reader :load_defaults_called
42
+
43
+ def initialize
44
+ @loaded_defaults = Spree.solidus_version
45
+ @load_defaults_called = false
46
+ end
47
+
48
+ # @param [String] Solidus version from which take defaults when not
49
+ # overriden.
50
+ # @see #load_defaults
51
+ def load_defaults(version)
52
+ @loaded_defaults = version
53
+ @load_defaults_called = true
54
+ reset
55
+ end
56
+
57
+ def check_load_defaults_called(instance_constant_name = nil)
58
+ return if load_defaults_called || !Spree::Core.has_install_generator_been_run?
59
+
60
+ target_name = instance_constant_name || "#{self.class.name}.new"
61
+ Spree::Deprecation.warn <<~MSG
62
+ It's recommended that you explicitly load the default configuration for
63
+ your current Solidus version. You can do it by adding the following call
64
+ to your Solidus initializer within the #{target_name} block:
65
+
66
+ config.load_defaults('#{Spree.solidus_version}')
67
+
68
+ MSG
69
+ end
70
+
32
71
  # @yield [config] Yields this configuration object to a block
33
72
  def configure
34
73
  yield(self)
@@ -79,6 +118,23 @@ module Spree::Preferences
79
118
  end
80
119
  end
81
120
 
121
+ # Generates a different preference default depending on {#version_defaults}
122
+ #
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`:
126
+ #
127
+ # @example
128
+ # preference :foo, :boolean, default: by_version(true, "3.0.0.alpha" => false)
129
+ #
130
+ # @see #loaded_defaults
131
+ # @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
136
+ end
137
+
82
138
  def self.preference(name, type, options = {})
83
139
  super
84
140
  alias_method name.to_s, "preferred_#{name}"
@@ -103,5 +159,11 @@ module Spree::Preferences
103
159
  class_name
104
160
  end
105
161
  end
162
+
163
+ private
164
+
165
+ def context_for_default
166
+ [loaded_defaults]
167
+ end
106
168
  end
107
169
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ module Preferences
5
+ module Persistable
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ include Spree::Preferences::Preferable
10
+ serialize :preferences, Hash
11
+ after_initialize :initialize_preference_defaults
12
+ end
13
+
14
+ private
15
+
16
+ def initialize_preference_defaults
17
+ if has_attribute?(:preferences)
18
+ self.preferences = default_preferences.merge(preferences)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -11,6 +11,10 @@ module Spree
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
13
  #
14
+ # It may also define a `#context_for_default` method. It should return an
15
+ # array with the arguments to be provided to a proc used as the `default:`
16
+ # keyword for a preference.
17
+ #
14
18
  # The generated writer method performs typecasting before assignment into the
15
19
  # preferences object.
16
20
  #
@@ -176,6 +180,10 @@ module Spree
176
180
  value
177
181
  end
178
182
  end
183
+
184
+ def context_for_default
185
+ [].freeze
186
+ end
179
187
  end
180
188
  end
181
189
  end