solidus_core 2.11.10 → 3.3.1

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.
Files changed (252) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +6 -2
  3. data/app/assets/javascripts/spree.js.erb +0 -51
  4. data/app/controllers/spree/base_controller.rb +1 -1
  5. data/app/helpers/spree/base_helper.rb +1 -1
  6. data/app/helpers/spree/products_helper.rb +2 -2
  7. data/app/helpers/spree/store_helper.rb +0 -11
  8. data/app/mailers/spree/carton_mailer.rb +1 -5
  9. data/app/models/concerns/spree/active_storage_adapter/attachment.rb +30 -11
  10. data/app/models/concerns/spree/active_storage_adapter.rb +1 -1
  11. data/app/models/concerns/spree/adjustment_source.rb +0 -15
  12. data/app/models/concerns/spree/calculated_adjustments.rb +0 -18
  13. data/app/models/concerns/spree/default_price.rb +39 -10
  14. data/app/models/concerns/spree/ransackable_attributes.rb +24 -4
  15. data/app/models/concerns/spree/soft_deletable.rb +2 -4
  16. data/app/models/concerns/spree/user_address_book.rb +10 -37
  17. data/app/models/concerns/spree/user_methods.rb +38 -13
  18. data/app/models/spree/ability.rb +0 -37
  19. data/app/models/spree/address/name.rb +2 -20
  20. data/app/models/spree/address.rb +8 -186
  21. data/app/models/spree/adjustment.rb +7 -33
  22. data/app/models/spree/base.rb +0 -53
  23. data/app/models/spree/calculator/flat_fee.rb +21 -0
  24. data/app/models/spree/calculator/flexi_rate.rb +0 -5
  25. data/app/models/spree/calculator.rb +0 -7
  26. data/app/models/spree/carton.rb +1 -1
  27. data/app/models/spree/country.rb +2 -7
  28. data/app/models/spree/credit_card.rb +1 -28
  29. data/app/models/spree/customer_return.rb +5 -7
  30. data/app/models/spree/image/active_storage_attachment.rb +2 -7
  31. data/app/models/spree/image/paperclip_attachment.rb +2 -2
  32. data/app/models/spree/image.rb +0 -7
  33. data/app/models/spree/inventory_unit.rb +0 -21
  34. data/app/models/spree/line_item.rb +6 -49
  35. data/app/models/spree/log_entry.rb +74 -1
  36. data/app/models/spree/option_type.rb +1 -1
  37. data/app/models/spree/option_value.rb +10 -1
  38. data/app/models/spree/order/number_generator.rb +7 -1
  39. data/app/models/spree/order.rb +82 -170
  40. data/app/models/spree/order_cancellations.rb +4 -24
  41. data/app/models/spree/order_contents.rb +2 -1
  42. data/app/models/spree/order_inventory.rb +1 -1
  43. data/app/models/spree/order_merger.rb +2 -2
  44. data/app/models/spree/order_promotion.rb +1 -1
  45. data/app/models/spree/order_shipping.rb +6 -9
  46. data/app/models/spree/order_taxation.rb +6 -4
  47. data/app/models/spree/order_updater.rb +17 -16
  48. data/app/models/spree/payment/cancellation.rb +1 -1
  49. data/app/models/spree/payment/processing.rb +58 -55
  50. data/app/models/spree/payment.rb +0 -3
  51. data/app/models/spree/payment_create.rb +1 -13
  52. data/app/models/spree/payment_method/bogus_credit_card.rb +6 -7
  53. data/app/models/spree/payment_method/credit_card.rb +1 -3
  54. data/app/models/spree/payment_method/simple_bogus_credit_card.rb +8 -0
  55. data/app/models/spree/payment_method.rb +26 -110
  56. data/app/models/spree/price.rb +3 -3
  57. data/app/models/spree/product/scopes.rb +24 -33
  58. data/app/models/spree/product.rb +15 -42
  59. data/app/models/spree/product_property.rb +1 -1
  60. data/app/models/spree/promotion/actions/create_adjustment.rb +4 -3
  61. data/app/models/spree/promotion/actions/create_item_adjustments.rb +5 -9
  62. data/app/models/spree/promotion/actions/create_quantity_adjustments.rb +0 -3
  63. data/app/models/spree/promotion/actions/free_shipping.rb +1 -0
  64. data/app/models/spree/promotion/order_adjustments_recalculator.rb +92 -0
  65. data/app/models/spree/promotion/rules/item_total.rb +50 -6
  66. data/app/models/spree/promotion/rules/product.rb +20 -8
  67. data/app/models/spree/promotion/rules/store.rb +4 -0
  68. data/app/models/spree/promotion/rules/taxon.rb +6 -15
  69. data/app/models/spree/promotion/rules/user.rb +4 -0
  70. data/app/models/spree/promotion.rb +39 -32
  71. data/app/models/spree/promotion_action.rb +6 -9
  72. data/app/models/spree/promotion_code/batch_builder.rb +0 -14
  73. data/app/models/spree/promotion_code.rb +11 -7
  74. data/app/models/spree/promotion_handler/cart.rb +26 -6
  75. data/app/models/spree/promotion_rule.rb +5 -0
  76. data/app/models/spree/property.rb +1 -1
  77. data/app/models/spree/refund.rb +8 -52
  78. data/app/models/spree/reimbursement.rb +5 -43
  79. data/app/models/spree/reimbursement_performer.rb +2 -8
  80. data/app/models/spree/reimbursement_type/credit.rb +1 -4
  81. data/app/models/spree/reimbursement_type/reimbursement_helpers.rb +1 -2
  82. data/app/models/spree/reimbursement_type/store_credit.rb +1 -4
  83. data/app/models/spree/return_authorization.rb +2 -5
  84. data/app/models/spree/return_item.rb +4 -24
  85. data/app/models/spree/shipment.rb +3 -56
  86. data/app/models/spree/shipping_method.rb +0 -25
  87. data/app/models/spree/shipping_rate.rb +0 -2
  88. data/app/models/spree/shipping_rate_tax.rb +1 -1
  89. data/app/models/spree/state.rb +1 -5
  90. data/app/models/spree/stock/allocator/on_hand_first.rb +2 -2
  91. data/app/models/spree/stock/availability.rb +11 -3
  92. data/app/models/spree/stock/quantifier.rb +12 -8
  93. data/app/models/spree/stock/simple_coordinator.rb +8 -26
  94. data/app/models/spree/stock/splitter/base.rb +2 -7
  95. data/app/models/spree/stock_item.rb +2 -8
  96. data/app/models/spree/stock_location.rb +2 -2
  97. data/app/models/spree/stock_movement.rb +2 -2
  98. data/app/models/spree/store.rb +0 -12
  99. data/app/models/spree/store_credit.rb +14 -1
  100. data/app/models/spree/store_credit_category.rb +0 -32
  101. data/app/models/spree/store_credit_prioritizer.rb +17 -0
  102. data/app/models/spree/tax/item_tax.rb +3 -2
  103. data/app/models/spree/tax/order_tax.rb +3 -1
  104. data/app/models/spree/tax/tax_helpers.rb +2 -2
  105. data/app/models/spree/tax/tax_location.rb +4 -7
  106. data/app/models/spree/tax_calculator/default.rb +31 -0
  107. data/app/models/spree/tax_calculator/shipping_rate.rb +2 -13
  108. data/app/models/spree/tax_rate.rb +9 -27
  109. data/app/models/spree/taxon/active_storage_attachment.rb +2 -7
  110. data/app/models/spree/taxon/paperclip_attachment.rb +3 -8
  111. data/app/models/spree/taxon.rb +1 -12
  112. data/app/models/spree/taxonomy.rb +1 -1
  113. data/app/models/spree/user_address.rb +0 -5
  114. data/app/models/spree/user_last_url_storer/rules/authentication_rule.rb +1 -1
  115. data/app/models/spree/variant/price_selector.rb +34 -4
  116. data/app/models/spree/variant.rb +52 -66
  117. data/app/models/spree/zone.rb +1 -1
  118. data/app/subscribers/spree/mailer_subscriber.rb +4 -0
  119. data/app/subscribers/spree/order_mailer_subscriber.rb +35 -0
  120. data/config/i18n-tasks.yml +134 -0
  121. data/config/locales/en.yml +406 -263
  122. data/db/migrate/20180416083007_add_apply_to_all_to_variant_property_rule.rb +1 -1
  123. data/db/migrate/20201127212108_add_type_before_removal_to_spree_payment_methods.rb +7 -0
  124. data/db/migrate/20210312061050_change_column_null_on_prices.rb +7 -0
  125. data/db/migrate/20220317165036_set_promotions_with_any_policy_to_all_if_possible.rb +20 -0
  126. data/db/migrate/20220805202442_add_level_to_spree_tax_rates.rb +5 -0
  127. data/db/migrate/20221123152807_add_shipping_category_to_spree_variants.rb +5 -0
  128. data/db/seeds.rb +4 -1
  129. data/lib/generators/solidus/install/app_templates/authentication/custom.rb +21 -0
  130. data/lib/generators/solidus/install/app_templates/authentication/devise.rb +16 -0
  131. data/lib/generators/solidus/install/app_templates/authentication/existing.rb +10 -0
  132. data/lib/generators/solidus/install/app_templates/authentication/none.rb +1 -0
  133. data/lib/generators/solidus/install/app_templates/frontend/break_down_solidus_gem.rb +54 -0
  134. data/lib/generators/solidus/install/app_templates/frontend/classic.rb +16 -0
  135. data/lib/generators/solidus/install/app_templates/frontend/none.rb +2 -0
  136. data/lib/generators/solidus/install/app_templates/frontend/starter.rb +3 -0
  137. data/lib/generators/solidus/install/app_templates/payment_method/bolt.rb +13 -0
  138. data/lib/generators/solidus/install/app_templates/payment_method/none.rb +1 -0
  139. data/lib/generators/solidus/install/app_templates/payment_method/paypal.rb +10 -0
  140. data/lib/generators/solidus/install/install_generator.rb +247 -149
  141. data/lib/generators/solidus/install/templates/config/initializers/spree.rb.tt +15 -60
  142. data/lib/generators/solidus/install/templates/vendor/assets/javascripts/spree/backend/all.js +2 -2
  143. data/lib/generators/solidus/update/templates/config/initializers/new_solidus_defaults.rb.tt +30 -0
  144. data/lib/generators/solidus/update/update_generator.rb +112 -0
  145. data/lib/generators/spree/custom_user/custom_user_generator.rb +6 -4
  146. data/lib/generators/spree/custom_user/templates/authentication_helpers.rb.tt +2 -6
  147. data/lib/generators/spree/custom_user/templates/migration.rb.tt +7 -3
  148. data/lib/generators/spree/dummy/dummy_generator.rb +12 -9
  149. data/lib/generators/spree/dummy/templates/rails/application.rb.tt +0 -1
  150. data/lib/generators/spree/dummy/templates/rails/database.yml +81 -39
  151. data/lib/generators/spree/dummy/templates/rails/storage.yml +3 -0
  152. data/lib/generators/spree/dummy/templates/rails/test.rb +2 -0
  153. data/lib/spree/app_configuration.rb +134 -64
  154. data/lib/spree/bus.rb +20 -0
  155. data/lib/spree/core/class_constantizer.rb +2 -0
  156. data/lib/spree/core/controller_helpers/auth.rb +10 -15
  157. data/lib/spree/core/controller_helpers/current_host.rb +5 -3
  158. data/lib/spree/core/controller_helpers/order.rb +12 -32
  159. data/lib/spree/core/controller_helpers/payment_parameters.rb +0 -54
  160. data/lib/spree/core/controller_helpers/pricing.rb +0 -8
  161. data/lib/spree/core/controller_helpers/search.rb +1 -1
  162. data/lib/spree/core/controller_helpers/strong_parameters.rb +0 -4
  163. data/lib/spree/core/engine.rb +54 -50
  164. data/lib/spree/core/environment_extension.rb +0 -9
  165. data/lib/spree/core/product_filters.rb +1 -41
  166. data/lib/spree/core/role_configuration.rb +0 -14
  167. data/lib/spree/core/search/base.rb +18 -35
  168. data/lib/spree/core/state_machines/order.rb +2 -2
  169. data/lib/spree/core/state_machines.rb +2 -11
  170. data/lib/spree/core/stock_configuration.rb +18 -0
  171. data/lib/spree/core/validators/email.rb +5 -3
  172. data/lib/spree/core/version.rb +5 -1
  173. data/lib/spree/core/versioned_value.rb +75 -0
  174. data/lib/spree/core.rb +40 -11
  175. data/lib/spree/deprecation.rb +1 -1
  176. data/lib/spree/event/configuration.rb +0 -5
  177. data/lib/spree/event/subscriber.rb +0 -18
  178. data/lib/spree/event/subscriber_registry.rb +7 -7
  179. data/lib/spree/event.rb +1 -32
  180. data/lib/spree/i18n.rb +0 -22
  181. data/lib/spree/migrations.rb +13 -11
  182. data/lib/spree/money.rb +3 -18
  183. data/lib/spree/permission_sets/default_customer.rb +8 -1
  184. data/lib/spree/permitted_attributes.rb +17 -59
  185. data/lib/spree/preferences/configuration.rb +84 -0
  186. data/lib/spree/preferences/preferable.rb +13 -0
  187. data/lib/spree/preferences/preferable_class_methods.rb +37 -4
  188. data/lib/spree/preferences/preference_differentiator.rb +29 -0
  189. data/lib/spree/preferences/static_model_preferences.rb +25 -10
  190. data/lib/spree/rails_compatibility.rb +106 -0
  191. data/lib/spree/testing_support/blacklist_urls.rb +1 -1
  192. data/lib/spree/testing_support/bus_helpers.rb +101 -0
  193. data/lib/spree/testing_support/capybara_ext.rb +0 -30
  194. data/lib/spree/testing_support/common_rake.rb +71 -23
  195. data/lib/spree/testing_support/controller_requests.rb +0 -82
  196. data/lib/spree/testing_support/dummy_app/assets/javascripts/spree/backend/all.js +1 -1
  197. data/lib/spree/testing_support/dummy_app/assets/javascripts/spree/frontend/all.js +1 -1
  198. data/lib/spree/testing_support/dummy_app/database.yml +42 -22
  199. data/lib/spree/testing_support/dummy_app/migrations.rb +0 -3
  200. data/lib/spree/testing_support/dummy_app.rb +47 -34
  201. data/lib/spree/testing_support/factories/address_factory.rb +9 -6
  202. data/lib/spree/testing_support/factories/calculator_factory.rb +3 -0
  203. data/lib/spree/testing_support/factories/country_factory.rb +1 -2
  204. data/lib/spree/testing_support/factories/inventory_unit_factory.rb +1 -1
  205. data/lib/spree/testing_support/factories/order_factory.rb +8 -5
  206. data/lib/spree/testing_support/factories/product_factory.rb +4 -1
  207. data/lib/spree/testing_support/factories/promotion_factory.rb +28 -14
  208. data/lib/spree/testing_support/factories/refund_factory.rb +0 -1
  209. data/lib/spree/testing_support/factories/state_factory.rb +8 -2
  210. data/lib/spree/testing_support/factories/store_credit_factory.rb +4 -4
  211. data/lib/spree/testing_support/factories/user_factory.rb +6 -0
  212. data/lib/spree/testing_support/factory_bot.rb +2 -2
  213. data/lib/spree/testing_support/order_walkthrough.rb +6 -8
  214. data/lib/spree/testing_support/preferences.rb +0 -25
  215. data/lib/spree/testing_support/silence_deprecations.rb +9 -0
  216. data/lib/tasks/colorado_delivery_fee.rake +28 -0
  217. data/lib/tasks/payment_method.rake +29 -0
  218. data/lib/tasks/solidus/check_orders_with_invalid_email.rake +18 -0
  219. data/lib/tasks/solidus/delete_prices_with_nil_amount.rake +8 -0
  220. data/lib/tasks/solidus/split_promotions_with_any_match_policy.rake +33 -0
  221. data/solidus_core.gemspec +14 -7
  222. metadata +127 -78
  223. data/app/mailers/spree/test_mailer.rb +0 -13
  224. data/app/models/concerns/spree/user_payment_source.rb +0 -26
  225. data/app/models/spree/calculator/free_shipping.rb +0 -22
  226. data/app/models/spree/calculator/percent_per_item.rb +0 -51
  227. data/app/models/spree/calculator/price_sack.rb +0 -28
  228. data/app/models/spree/gateway/bogus.rb +0 -13
  229. data/app/models/spree/gateway/bogus_simple.rb +0 -13
  230. data/app/models/spree/gateway.rb +0 -14
  231. data/app/models/spree/order/checkout.rb +0 -244
  232. data/app/models/spree/order_capturing.rb +0 -50
  233. data/app/models/spree/promotion_handler/free_shipping.rb +0 -9
  234. data/app/models/spree/tax/shipping_rate_taxer.rb +0 -24
  235. data/lib/generators/solidus/install/templates/vendor/assets/javascripts/spree/frontend/all.js +0 -10
  236. data/lib/generators/solidus/install/templates/vendor/assets/stylesheets/spree/frontend/all.css +0 -9
  237. data/lib/generators/spree/install/install_generator.rb +0 -15
  238. data/lib/solidus/migrations/rename_gateways.rb +0 -41
  239. data/lib/spree/core/current_store.rb +0 -24
  240. data/lib/spree/paranoia_deprecations.rb +0 -41
  241. data/lib/spree/promo/environment.rb +0 -12
  242. data/lib/spree/testing_support/bar_ability.rb +0 -19
  243. data/lib/tasks/core.rake +0 -104
  244. data/lib/tasks/email.rake +0 -12
  245. data/lib/tasks/migrations/copy_order_bill_address_to_credit_card.rake +0 -119
  246. data/lib/tasks/migrations/migrate_address_names.rake +0 -158
  247. data/lib/tasks/migrations/migrate_default_billing_addresses_to_address_book.rake +0 -26
  248. data/lib/tasks/migrations/migrate_shipping_rate_taxes.rake +0 -22
  249. data/lib/tasks/migrations/migrate_user_addresses.rake +0 -34
  250. data/lib/tasks/migrations/rename_gateways.rake +0 -23
  251. data/lib/tasks/order_capturing.rake +0 -27
  252. data/lib/tasks/upgrade.rake +0 -13
@@ -35,7 +35,9 @@ module Spree
35
35
  subscription = Spree::Event.subscribe(event_name) { |event| subscriber.send(event_action, event) }
36
36
 
37
37
  # deprecated mappings, to be removed when Solidus 2.10 is not supported anymore:
38
- subscriber.send("#{event_action}_handler=", subscription)
38
+ if subscriber.respond_to?("#{event_action}_handler=")
39
+ subscriber.send("#{event_action}_handler=", subscription)
40
+ end
39
41
 
40
42
  registry[subscriber.name][event_action] = subscription
41
43
  end
@@ -62,13 +64,11 @@ module Spree
62
64
  # Loading the files has the side effect of adding their module to the
63
65
  # list in Spree::Event.subscribers.
64
66
  def require_subscriber_files
65
- pattern = "app/subscribers/**/*_subscriber.rb"
67
+ require_dependency(
68
+ Spree::Core::Engine.root.join('app', 'subscribers', 'spree', 'mailer_subscriber.rb')
69
+ )
66
70
 
67
- # Load Solidus subscribers
68
- # rubocop:disable Rails/DynamicFindBy
69
- solidus_core_dir = Gem::Specification.find_by_name('solidus_core').gem_dir
70
- # rubocop:enable Rails/DynamicFindBy
71
- Dir.glob(File.join(solidus_core_dir, pattern)) { |c| require_dependency(c.to_s) }
71
+ pattern = "app/subscribers/**/*_subscriber.rb"
72
72
 
73
73
  # Load application subscribers, only when the flag is set to true:
74
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
@@ -29,20 +29,6 @@ module Spree
29
29
  end
30
30
  end
31
31
 
32
- # @deprecated Loads all Solidus' core and application's event subscribers files.
33
- # The latter are loaded automatically only when the preference
34
- # Spree::Config.events.autoload_subscribers is set to a truthy value.
35
- #
36
- # Files must be placed under the directory `app/subscribers` and their
37
- # name must end with `_subscriber.rb`.
38
- #
39
- # Loading the files has the side effect of adding their module to the
40
- # list in Spree::Event.subscribers.
41
- def require_subscriber_files
42
- Spree::Deprecation.warn("#{self}.require_subscriber_files is deprecated and will be removed in Solidus 3.0.", caller)
43
- subscriber_registry.send(:require_subscriber_files)
44
- end
45
-
46
32
  # Subscribe to an event with the given name. The provided block is executed
47
33
  # every time the subscribed event is fired.
48
34
  #
@@ -114,23 +100,6 @@ module Spree
114
100
  Spree::Config.events.adapter
115
101
  end
116
102
 
117
- # The suffix used for namespacing Solidus events, defaults to
118
- # `.spree`
119
- #
120
- # @see Spree::Event::Configuration#suffix
121
- def suffix
122
- Spree::Deprecation.warn "This method is deprecated and will be removed. Please use Event::Adapters::ActiveSupportNotifications#suffix"
123
- Spree::Config.events.suffix
124
- end
125
-
126
- # @deprecated
127
- # @!attribute [r] subscribers
128
- # @return [Array<Spree::Event::Subscriber>] A list of subscribers used to support class reloading for Spree::Event::Subscriber instances
129
- def subscribers
130
- Spree::Deprecation.warn("`#{self}.subscribers` is deprecated. Please use `#{self}.subscriber_registry` instead.", caller)
131
- Spree::Config.events.subscribers
132
- end
133
-
134
103
  # @!attribute [r] subscribers
135
104
  # @return <Spree::Event::SubscriberRegistry> The registry for supporting class reloading for Spree::Event::Subscriber instances
136
105
  def subscriber_registry
data/lib/spree/i18n.rb CHANGED
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'i18n'
4
- require 'active_support/core_ext/array/extract_options'
5
- require 'action_view'
6
4
 
7
5
  module Spree
8
6
  def self.i18n_available_locales
@@ -11,29 +9,9 @@ module Spree
11
9
  end
12
10
  end
13
11
 
14
- class TranslationHelperWrapper # :nodoc:
15
- include ActionView::Helpers::TranslationHelper
16
- end
17
-
18
12
  # This value is used as a count for the pluralization helpers related to I18n
19
13
  # ex: Spree::Order.model_name.human(count: Spree::I18N_GENERIC_PLURAL)
20
14
  # Related to Solidus issue #1164, this is needed to avoid problems with
21
15
  # some pluralization calculators
22
16
  I18N_GENERIC_PLURAL = 2.1
23
-
24
- class << self
25
- # Add spree namespace and delegate to Rails TranslationHelper for some nice
26
- # extra functionality. e.g return reasonable strings for missing translations
27
-
28
- def translate(key, options = {})
29
- Spree::Deprecation.warn <<-WARN.squish
30
- Spree.t & Spree.translate have been deprecated.
31
- Instead use I18n.t('spree.your_translation_key')
32
- WARN
33
- options[:scope] = [:spree, *options[:scope]]
34
- TranslationHelperWrapper.new.translate(key, **options)
35
- end
36
-
37
- alias_method :t, :translate
38
- end
39
17
  end
@@ -23,16 +23,18 @@ module Spree
23
23
  # Shouldn't run on test mode because migrations inside engine don't have
24
24
  # engine name on the file name
25
25
  def check
26
- if File.directory?(app_dir)
27
- unless missing_migrations.empty?
28
- puts "[#{engine_name.capitalize} WARNING] Missing migrations."
29
- missing_migrations.each do |migration|
30
- puts "[#{engine_name.capitalize} WARNING] #{migration} from #{engine_name} is missing."
31
- end
32
- puts "[#{engine_name.capitalize} WARNING] Run `bundle exec rake railties:install:migrations` to get them.\n\n"
33
- true
34
- end
35
- end
26
+ return unless File.directory?(app_dir)
27
+ return if missing_migrations.empty?
28
+ return if ENV['SOLIDUS_SKIP_MIGRATIONS_CHECK']
29
+
30
+ prefix = "[WARNING #{engine_name.capitalize}]"
31
+ warn <<~WARN
32
+ #{prefix} Missing migrations.
33
+ #{missing_migrations.map {|m| "#{prefix} - #{m}"}.join("\n")}
34
+ #{prefix}
35
+ #{prefix} Run `bin/rails railties:install:migrations` to get them.
36
+ #{prefix} You can silence this warning by setting the `SOLIDUS_SKIP_MIGRATIONS_CHECK` environment variable.
37
+ WARN
36
38
  end
37
39
 
38
40
  def missing_migrations
@@ -66,7 +68,7 @@ module Spree
66
68
  end
67
69
 
68
70
  def app_dir
69
- "#{Rails.root}/db/migrate"
71
+ Spree::Config.migration_path
70
72
  end
71
73
 
72
74
  def engine_dir
data/lib/spree/money.rb CHANGED
@@ -6,7 +6,6 @@ module Spree
6
6
  class Money
7
7
  include Comparable
8
8
  DifferentCurrencyError = Class.new(StandardError)
9
- RUBY_NUMERIC_STRING = /\A-?\d+(\.\d+)?\z/
10
9
 
11
10
  class <<self
12
11
  attr_accessor :default_formatting_rules
@@ -37,15 +36,8 @@ module Spree
37
36
  @money = amount
38
37
  else
39
38
  currency = (options[:currency] || Spree::Config[:currency])
40
- if amount.to_s =~ RUBY_NUMERIC_STRING
41
- @money = Monetize.from_string(amount, currency)
42
- else
43
- @money = Spree::Money.parse_to_money(amount, currency)
44
- Spree::Deprecation.warn <<-WARN.squish, caller
45
- Spree::Money was initialized with #{amount.inspect}, which will not be supported in the future.
46
- Instead use Spree::Money.new(#{@money.to_s.inspect}, options) or Spree::Money.parse(#{amount.inspect})
47
- WARN
48
- end
39
+
40
+ @money = Monetize.from_string(amount, currency)
49
41
  end
50
42
  @options = Spree::Money.default_formatting_rules.merge(options)
51
43
  end
@@ -80,14 +72,7 @@ module Spree
80
72
  def to_html(options = { html_wrap: true })
81
73
  output = format(options)
82
74
  # Maintain compatibility by checking html option renamed to html_wrap.
83
- if options[:html] || options[:html] == false
84
- Spree::Deprecation.warn <<-WARN.squish, caller
85
- Spree::Money#to_html called with Spree::Money#to_html(html: #{options[:html].inspect}),
86
- which will not be supported in the future.
87
- Instead use :html_wrap e.g. Spree::Money#to_html(html_wrap: #{options[:html].inspect})
88
- WARN
89
- end
90
- if options[:html_wrap] || options[:html]
75
+ if options[:html_wrap]
91
76
  output = output.html_safe
92
77
  end
93
78
  output
@@ -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
@@ -39,8 +39,7 @@ module Spree
39
39
  mattr_reader(*ATTRIBUTES)
40
40
 
41
41
  @@address_attributes = [
42
- :id, :name, :firstname, :lastname, :first_name, :last_name,
43
- :address1, :address2, :city, :country_id, :state_id,
42
+ :id, :name, :address1, :address2, :city, :country_id, :state_id,
44
43
  :zipcode, :phone, :state_name, :country_iso, :alternative_phone, :company,
45
44
  country: [:iso, :name, :iso3, :iso_name],
46
45
  state: [:name, :abbr]
@@ -52,7 +51,13 @@ module Spree
52
51
  :month, :year, :expiry, :first_name, :last_name, :name
53
52
  ]
54
53
 
55
- @@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
+ ]
56
61
 
57
62
  @@image_attributes = [:alt, :attachment, :position, :viewable_type, :viewable_id]
58
63
 
@@ -60,16 +65,16 @@ module Spree
60
65
 
61
66
  @@line_item_attributes = [:id, :variant_id, :quantity]
62
67
 
63
- @@option_type_attributes = [:name, :presentation, :option_values_attributes]
64
-
65
68
  @@option_value_attributes = [:name, :presentation]
66
69
 
70
+ @@option_type_attributes = [:name, :presentation, option_values_attributes: option_value_attributes]
71
+
67
72
  @@payment_attributes = [:amount, :payment_method_id, :payment_method]
68
73
 
69
74
  @@product_properties_attributes = [:property_name, :value, :position]
70
75
 
71
76
  @@product_attributes = [
72
- :name, :description, :available_on, :discontinue_on, :permalink, :meta_description,
77
+ :name, :description, :available_on, :discontinue_on, :meta_description,
73
78
  :meta_keywords, :price, :sku, :deleted_at,
74
79
  :option_values_hash, :weight, :height, :width, :depth,
75
80
  :shipping_category_id, :tax_category_id,
@@ -90,7 +95,7 @@ module Spree
90
95
  :number, :month, :year, :expiry, :verification_value,
91
96
  :first_name, :last_name, :cc_type, :gateway_customer_profile_id,
92
97
  :gateway_payment_profile_id, :last_digits, :name, :encrypted_data,
93
- :existing_card_id, :wallet_payment_source_id, address_attributes: address_attributes
98
+ :wallet_payment_source_id, address_attributes: address_attributes
94
99
  ]
95
100
 
96
101
  @@stock_item_attributes = [:variant, :stock_location, :backorderable, :variant_id]
@@ -126,8 +131,11 @@ module Spree
126
131
  @@variant_attributes = [
127
132
  :name, :presentation, :cost_price, :lock_version,
128
133
  :position, :track_inventory,
129
- :product_id, :product, :option_values_attributes, :price,
130
- :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,
136
+ :tax_category_id, :shipping_category_id,
137
+ option_value_ids: [],
138
+ options: [:name, :value]
131
139
  ]
132
140
 
133
141
  @@checkout_address_attributes = [
@@ -143,61 +151,11 @@ module Spree
143
151
  ]
144
152
 
145
153
  @@checkout_payment_attributes = [
146
- :coupon_code,
147
154
  payments_attributes: payment_attributes + [
148
155
  source_attributes: source_attributes
149
156
  ]
150
157
  ]
151
158
 
152
159
  @@checkout_confirm_attributes = []
153
-
154
- def self.checkout_attributes
155
- Spree::Deprecation.warn <<-WARN.squish, caller
156
- checkout_attributes is deprecated, please use the permitted
157
- attributes set for the specific step that needs to be updated.
158
-
159
- E.g. permitted_checkout_address_attributes
160
- WARN
161
-
162
- CheckoutAdditionalAttributes.new(
163
- checkout_address_attributes +
164
- checkout_delivery_attributes +
165
- checkout_payment_attributes +
166
- checkout_confirm_attributes
167
- )
168
- end
169
- end
170
-
171
- class CheckoutAdditionalAttributes < Array
172
- def <<(*attributes)
173
- super
174
-
175
- inject_attributes_to_all_steps(attributes, :<<)
176
- end
177
-
178
- def push(*attributes)
179
- super
180
-
181
- inject_attributes_to_all_steps(attributes, :push)
182
- end
183
- alias append push
184
-
185
- def prepend(*attributes)
186
- super
187
-
188
- inject_attributes_to_all_steps(attributes, :prepend)
189
- end
190
- alias unshift prepend
191
-
192
- private
193
-
194
- def inject_attributes_to_all_steps(attributes, method_name)
195
- attributes.each do |attribute|
196
- PermittedAttributes.checkout_address_attributes.send(method_name, attribute)
197
- PermittedAttributes.checkout_delivery_attributes.send(method_name, attribute)
198
- PermittedAttributes.checkout_payment_attributes.send(method_name, attribute)
199
- PermittedAttributes.checkout_confirm_attributes.send(method_name, attribute)
200
- end
201
- end
202
160
  end
203
161
  end
@@ -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,45 @@ 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
+ # @api private
42
+ attr_reader :load_defaults_called
43
+
44
+ def initialize
45
+ @loaded_defaults = Spree.solidus_version
46
+ @load_defaults_called = false
47
+ end
48
+
49
+ # @param [String] Solidus version from which take defaults when preferences
50
+ # are not overriden by the user.
51
+ # @see #loaded_defaults
52
+ def load_defaults(version)
53
+ @loaded_defaults = version
54
+ @load_defaults_called = true
55
+ reset
56
+ end
57
+
58
+ def check_load_defaults_called(instance_constant_name = nil)
59
+ return if load_defaults_called || !Spree::Core.has_install_generator_been_run?
60
+
61
+ target_name = instance_constant_name || "#{self.class.name}.new"
62
+ Spree::Deprecation.warn <<~MSG
63
+ It's recommended that you explicitly load the default configuration for
64
+ your current Solidus version. You can do it by adding the following call
65
+ to your Solidus initializer within the #{target_name} block:
66
+
67
+ config.load_defaults('#{Spree.solidus_version}')
68
+
69
+ MSG
70
+ end
71
+
32
72
  # @yield [config] Yields this configuration object to a block
33
73
  def configure
34
74
  yield(self)
@@ -79,6 +119,37 @@ module Spree::Preferences
79
119
  end
80
120
  end
81
121
 
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}
130
+ #
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`:
135
+ #
136
+ # @example
137
+ # versioned_preference :foo, :boolean, initial_value: true, boundaries: { "3.0.0.alpha" => false }
138
+ #
139
+ # @see .preference
140
+ # @see #loaded_defaults
141
+ # @see Spree::Core::VersionedValue
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
+ )
151
+ end
152
+
82
153
  def self.preference(name, type, options = {})
83
154
  super
84
155
  alias_method name.to_s, "preferred_#{name}"
@@ -103,5 +174,18 @@ module Spree::Preferences
103
174
  class_name
104
175
  end
105
176
  end
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
+
185
+ private
186
+
187
+ def context_for_default
188
+ [loaded_defaults]
189
+ end
106
190
  end
107
191
  end
@@ -10,6 +10,13 @@ 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
+ #
17
+ # It may also define a `#context_for_default` method. It should return an
18
+ # array with the arguments to be provided to a proc used as the `default:`
19
+ # keyword for a preference.
13
20
  #
14
21
  # The generated writer method performs typecasting before assignment into the
15
22
  # preferences object.
@@ -107,6 +114,8 @@ module Spree
107
114
  end
108
115
 
109
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.
110
119
  def default_preferences
111
120
  Hash[
112
121
  defined_preferences.map do |preference|
@@ -176,6 +185,10 @@ module Spree
176
185
  value
177
186
  end
178
187
  end
188
+
189
+ def context_for_default
190
+ [].freeze
191
+ end
179
192
  end
180
193
  end
181
194
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'spree/deprecation'
3
4
  require 'spree/encryptor'
4
5
 
5
6
  module Spree::Preferences
@@ -26,8 +27,38 @@ module Spree::Preferences
26
27
  options[:default] = preference_encryptor.encrypt(options[:default])
27
28
  end
28
29
 
29
- default = options[:default]
30
- default = ->{ options[:default] } unless default.is_a?(Proc)
30
+ default = begin
31
+ given = options[:default]
32
+ if ancestors.include?(Spree::Preferences::Configuration) &&
33
+ given.is_a?(Proc) &&
34
+ given.lambda? &&
35
+ given.arity.zero?
36
+ Spree::Deprecation.warn <<~MSG
37
+ The arity of a proc given as the default for a preference
38
+ has changed from 0 to 1 on Solidus 3.1. The Solidus
39
+ version for the loaded preference defaults is given as the
40
+ proc's argument from this point on.
41
+
42
+ If you don't need to return a different default value
43
+ depending on the loaded Solidus version, you can change
44
+ the proc so that it doesn't have lambda semantics (lambdas
45
+ raise when extra arguments are supplied, while raw procs
46
+ don't). E.g.:
47
+
48
+ preference :foo, :string, default: proc { true }
49
+
50
+ If you want to branch on the provided Solidus version, you can do like the following:
51
+
52
+ versioned_preference :foo, :string, initial_value: true, boundaries: { "3.2.0" => false }
53
+
54
+ MSG
55
+ ->(_default_context) { given.call }
56
+ elsif given.is_a?(Proc)
57
+ given
58
+ else
59
+ proc { given }
60
+ end
61
+ end
31
62
 
32
63
  # The defined preferences on a class are all those defined directly on
33
64
  # that class as well as those defined on ancestors.
@@ -44,7 +75,7 @@ module Spree::Preferences
44
75
  # is a pending preference before going to default
45
76
  define_method preference_getter_method(name) do
46
77
  value = preferences.fetch(name) do
47
- default.call
78
+ instance_exec(*context_for_default, &default)
48
79
  end
49
80
  value = preference_encryptor.decrypt(value) if preference_encryptor.present?
50
81
  value
@@ -60,7 +91,9 @@ module Spree::Preferences
60
91
  preferences_will_change! if respond_to?(:preferences_will_change!)
61
92
  end
62
93
 
63
- define_method preference_default_getter_method(name), &default
94
+ define_method preference_default_getter_method(name) do
95
+ instance_exec(*context_for_default, &default)
96
+ end
64
97
 
65
98
  define_method preference_type_getter_method(name) do
66
99
  type
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ module Preferences
5
+ class PreferenceDifferentiator
6
+ attr_reader :config_class
7
+
8
+ def initialize(config_class)
9
+ @config_class = config_class
10
+ end
11
+
12
+ def call(from:, to:)
13
+ preferences_from = config_class.new.load_defaults(from)
14
+ preferences_to = config_class.new.load_defaults(to)
15
+ config_class.versioned_preferences.reduce({}) do |changes, pref_key|
16
+ value_from = preferences_from[pref_key]
17
+ value_to = preferences_to[pref_key]
18
+ if value_from == value_to
19
+ changes
20
+ else
21
+ changes.merge(
22
+ pref_key => { from: value_from, to: value_to }
23
+ )
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -7,13 +7,8 @@ module Spree
7
7
  attr_reader :preferences
8
8
 
9
9
  def initialize(klass, hash)
10
- hash = hash.symbolize_keys
11
- hash.keys.each do |key|
12
- if !klass.defined_preferences.include?(key)
13
- raise "Preference #{key.inspect} is not defined on #{klass}"
14
- end
15
- end
16
- @preferences = hash
10
+ @klass = klass
11
+ @preferences = hash.symbolize_keys
17
12
  end
18
13
 
19
14
  def fetch(key, &block)
@@ -27,6 +22,8 @@ module Spree
27
22
  def to_hash
28
23
  @preferences.deep_dup
29
24
  end
25
+
26
+ delegate :keys, to: :@preferences
30
27
  end
31
28
 
32
29
  def initialize
@@ -36,14 +33,32 @@ module Spree
36
33
  end
37
34
 
38
35
  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
- @store[klass.to_s][name] = Definition.new(klass, preferences)
36
+ @store[klass.to_s][name] = Definition.new(klass.to_s, preferences)
42
37
  end
43
38
 
44
39
  def for_class(klass)
45
40
  @store[klass.to_s]
46
41
  end
42
+
43
+ def validate!
44
+ @store.keys.map(&:constantize).each do |klass|
45
+ validate_for_class!(klass)
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ def validate_for_class!(klass)
52
+ for_class(klass).each do |name, preferences|
53
+ klass_keys = klass.defined_preferences.map(&:to_s)
54
+ extra_keys = preferences.keys.map(&:to_s) - klass_keys
55
+ next if extra_keys.empty?
56
+
57
+ raise \
58
+ "Unexpected keys found for #{klass} under #{name}: #{extra_keys.sort.join(', ')} " \
59
+ "(expected keys: #{klass_keys.sort.join(', ')})"
60
+ end
61
+ end
47
62
  end
48
63
  end
49
64
  end