spree_core 5.3.4 → 5.4.0.beta

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 (239) hide show
  1. checksums.yaml +4 -4
  2. data/app/finders/spree/orders/find_complete.rb +33 -2
  3. data/app/finders/spree/stores/find_default.rb +17 -0
  4. data/app/finders/spree/variants/visible_finder.rb +1 -0
  5. data/app/helpers/spree/addresses_helper.rb +1 -2
  6. data/app/helpers/spree/base_helper.rb +5 -4
  7. data/app/jobs/spree/api_key_touch_job.rb +9 -0
  8. data/app/models/concerns/spree/admin_user_methods.rb +32 -0
  9. data/app/models/concerns/spree/number_as_param.rb +5 -3
  10. data/app/models/concerns/spree/prefixed_id.rb +82 -0
  11. data/app/models/concerns/spree/product_scopes.rb +33 -18
  12. data/app/models/concerns/spree/publishable.rb +47 -47
  13. data/app/models/concerns/spree/{multi_store_resource.rb → store_scoped_resource.rb} +1 -10
  14. data/app/models/concerns/spree/stores/markets.rb +124 -0
  15. data/app/models/concerns/spree/user_methods.rb +7 -7
  16. data/app/models/concerns/spree/user_payment_source.rb +2 -0
  17. data/app/models/concerns/spree/user_roles.rb +1 -0
  18. data/app/models/spree/ability.rb +13 -0
  19. data/app/models/spree/address.rb +30 -0
  20. data/app/models/spree/adjustment.rb +2 -0
  21. data/app/models/spree/api_key.rb +47 -0
  22. data/app/models/spree/asset.rb +2 -0
  23. data/app/models/spree/authentication/strategies/base_strategy.rb +55 -0
  24. data/app/models/spree/authentication/strategies/email_password_strategy.rb +47 -0
  25. data/app/models/spree/base.rb +1 -0
  26. data/app/models/spree/calculator.rb +2 -0
  27. data/app/models/spree/country.rb +56 -0
  28. data/app/models/spree/coupon_code.rb +2 -0
  29. data/app/models/spree/credit_card.rb +2 -0
  30. data/app/models/spree/current.rb +9 -4
  31. data/app/models/spree/customer_group.rb +2 -0
  32. data/app/models/spree/customer_return.rb +2 -0
  33. data/app/models/spree/data_feed.rb +2 -0
  34. data/app/models/spree/digital.rb +2 -0
  35. data/app/models/spree/digital_link.rb +2 -0
  36. data/app/models/spree/export.rb +3 -2
  37. data/app/models/spree/fulfilment_changer.rb +8 -2
  38. data/app/models/spree/gateway/bogus.rb +60 -0
  39. data/app/models/spree/gateway_customer.rb +2 -0
  40. data/app/models/spree/gift_card.rb +2 -0
  41. data/app/models/spree/gift_card_batch.rb +2 -0
  42. data/app/models/spree/image.rb +18 -0
  43. data/app/models/spree/import.rb +5 -3
  44. data/app/models/spree/import_mapping.rb +2 -0
  45. data/app/models/spree/import_row.rb +2 -0
  46. data/app/models/spree/import_schemas/customers.rb +21 -0
  47. data/app/models/spree/imports/customers.rb +9 -0
  48. data/app/models/spree/integration.rb +2 -0
  49. data/app/models/spree/inventory_unit.rb +2 -0
  50. data/app/models/spree/invitation.rb +6 -6
  51. data/app/models/spree/legacy_admin_user.rb +31 -0
  52. data/app/models/spree/legacy_user.rb +19 -1
  53. data/app/models/spree/line_item.rb +15 -4
  54. data/app/models/spree/log_entry.rb +2 -0
  55. data/app/models/spree/market.rb +83 -0
  56. data/app/models/spree/market_country.rb +25 -0
  57. data/app/models/spree/metafield.rb +2 -0
  58. data/app/models/spree/metafield_definition.rb +2 -0
  59. data/app/models/spree/newsletter_subscriber.rb +2 -0
  60. data/app/models/spree/option_type.rb +2 -0
  61. data/app/models/spree/option_value.rb +2 -0
  62. data/app/models/spree/order/address_book.rb +2 -1
  63. data/app/models/spree/order.rb +73 -45
  64. data/app/models/spree/payment.rb +6 -1
  65. data/app/models/spree/payment_capture_event.rb +2 -0
  66. data/app/models/spree/payment_method.rb +59 -1
  67. data/app/models/spree/payment_session.rb +109 -0
  68. data/app/models/spree/payment_sessions/bogus.rb +4 -0
  69. data/app/models/spree/payment_setup_session.rb +79 -0
  70. data/app/models/spree/payment_source.rb +2 -0
  71. data/app/models/spree/permission_sets/default_customer.rb +19 -0
  72. data/app/models/spree/policy.rb +2 -0
  73. data/app/models/spree/post.rb +2 -0
  74. data/app/models/spree/post_category.rb +2 -0
  75. data/app/models/spree/price.rb +26 -2
  76. data/app/models/spree/price_list.rb +2 -0
  77. data/app/models/spree/price_rule.rb +2 -0
  78. data/app/models/spree/price_rules/market_rule.rb +19 -0
  79. data/app/models/spree/product.rb +41 -29
  80. data/app/models/spree/promotion/rules/country.rb +1 -1
  81. data/app/models/spree/promotion.rb +3 -1
  82. data/app/models/spree/promotion_action.rb +2 -0
  83. data/app/models/spree/promotion_category.rb +2 -0
  84. data/app/models/spree/promotion_rule.rb +2 -0
  85. data/app/models/spree/prototype.rb +2 -0
  86. data/app/models/spree/refund.rb +2 -0
  87. data/app/models/spree/refund_reason.rb +2 -0
  88. data/app/models/spree/reimbursement/credit.rb +2 -0
  89. data/app/models/spree/reimbursement.rb +2 -0
  90. data/app/models/spree/reimbursement_type.rb +2 -0
  91. data/app/models/spree/report.rb +3 -1
  92. data/app/models/spree/return_authorization.rb +2 -0
  93. data/app/models/spree/return_authorization_reason.rb +2 -0
  94. data/app/models/spree/return_item.rb +2 -0
  95. data/app/models/spree/role.rb +2 -0
  96. data/app/models/spree/shipment.rb +11 -1
  97. data/app/models/spree/shipping_category.rb +2 -0
  98. data/app/models/spree/shipping_method.rb +2 -0
  99. data/app/models/spree/shipping_method_category.rb +2 -0
  100. data/app/models/spree/shipping_rate.rb +2 -0
  101. data/app/models/spree/state_change.rb +2 -0
  102. data/app/models/spree/stock_item.rb +2 -0
  103. data/app/models/spree/stock_location.rb +2 -0
  104. data/app/models/spree/stock_movement.rb +2 -0
  105. data/app/models/spree/stock_transfer.rb +2 -1
  106. data/app/models/spree/store.rb +110 -179
  107. data/app/models/spree/store_credit.rb +2 -0
  108. data/app/models/spree/store_credit_category.rb +2 -0
  109. data/app/models/spree/store_credit_event.rb +2 -0
  110. data/app/models/spree/store_credit_type.rb +2 -0
  111. data/app/models/spree/store_product.rb +2 -0
  112. data/app/models/spree/tax_category.rb +2 -0
  113. data/app/models/spree/tax_rate.rb +2 -0
  114. data/app/models/spree/taxon.rb +4 -1
  115. data/app/models/spree/taxon_image.rb +8 -0
  116. data/app/models/spree/taxon_rule.rb +2 -0
  117. data/app/models/spree/taxonomy.rb +2 -0
  118. data/app/models/spree/user_identity.rb +81 -0
  119. data/app/models/spree/variant.rb +13 -3
  120. data/app/models/spree/webhook_delivery.rb +2 -0
  121. data/app/models/spree/webhook_endpoint.rb +2 -0
  122. data/app/models/spree/wished_item.rb +15 -0
  123. data/app/models/spree/wishlist.rb +2 -8
  124. data/app/models/spree/zone.rb +2 -6
  125. data/app/presenters/spree/filters/price_presenter.rb +1 -0
  126. data/app/presenters/spree/filters/price_range_presenter.rb +1 -0
  127. data/app/presenters/spree/filters/quantified_price_range_presenter.rb +1 -0
  128. data/app/presenters/spree/product_summary_presenter.rb +1 -0
  129. data/app/services/spree/addresses/helper.rb +22 -3
  130. data/app/services/spree/cart/associate.rb +19 -6
  131. data/app/services/spree/checkout/select_shipping_method.rb +13 -1
  132. data/app/services/spree/classifications/reposition.rb +5 -0
  133. data/app/services/spree/imports/row_processors/customer.rb +70 -0
  134. data/app/services/spree/orders/approve.rb +5 -3
  135. data/app/services/spree/orders/cancel.rb +9 -4
  136. data/app/services/spree/products/prepare_nested_attributes.rb +1 -1
  137. data/app/services/spree/sample_data/import_runner.rb +54 -0
  138. data/app/services/spree/sample_data/loader.rb +78 -0
  139. data/app/services/spree/seeds/admin_user.rb +2 -3
  140. data/app/services/spree/seeds/all.rb +1 -0
  141. data/app/services/spree/seeds/api_keys.rb +16 -0
  142. data/app/services/spree/seeds/stores.rb +2 -4
  143. data/app/sorters/spree/orders/sort.rb +4 -0
  144. data/app/subscribers/spree/product_metrics_subscriber.rb +4 -4
  145. data/config/brakeman.ignore +120 -0
  146. data/config/locales/en.yml +20 -1
  147. data/db/migrate/20250923141900_create_spree_user_identities.rb +17 -0
  148. data/db/migrate/20260123000000_create_spree_api_keys.rb +19 -0
  149. data/db/migrate/20260131000000_add_thumbnail_id_to_spree_variants_and_products.rb +9 -0
  150. data/db/migrate/20260213000000_create_spree_payment_sessions.rb +27 -0
  151. data/db/migrate/20260218000000_create_spree_payment_setup_sessions.rb +24 -0
  152. data/db/migrate/20260220000000_create_spree_markets.rb +29 -0
  153. data/db/sample_data/customers.csv +21 -0
  154. data/db/sample_data/metafield_definitions.rb +7 -0
  155. data/db/sample_data/orders.rb +131 -0
  156. data/db/sample_data/payment_methods.rb +17 -0
  157. data/db/sample_data/posts.rb +7 -0
  158. data/db/sample_data/products.csv +1083 -0
  159. data/db/sample_data/promotions.rb +8 -0
  160. data/db/sample_data/shipping_methods.rb +39 -0
  161. data/lib/generators/spree/authentication/devise/devise_generator.rb +2 -2
  162. data/lib/generators/spree/authentication/dummy/dummy_generator.rb +54 -0
  163. data/lib/generators/spree/authentication/dummy/templates/authentication_helpers.rb.tt +52 -0
  164. data/lib/generators/spree/authentication/dummy/templates/create_spree_admin_users.rb.tt +33 -0
  165. data/lib/generators/spree/dummy/dummy_generator.rb +1 -1
  166. data/lib/spree/core/configuration.rb +1 -0
  167. data/lib/spree/core/controller_helpers/common.rb +6 -0
  168. data/lib/spree/core/controller_helpers/currency.rb +5 -0
  169. data/lib/spree/core/controller_helpers/order.rb +5 -1
  170. data/lib/spree/core/controller_helpers/store.rb +1 -1
  171. data/lib/spree/core/dependencies.rb +1 -1
  172. data/lib/spree/core/engine.rb +17 -4
  173. data/lib/spree/core/pricing/context.rb +6 -3
  174. data/lib/spree/core/product_filters.rb +14 -0
  175. data/lib/spree/core/query_filters/comparable.rb +4 -0
  176. data/lib/spree/core/query_filters/text.rb +4 -0
  177. data/lib/spree/core/version.rb +1 -1
  178. data/lib/spree/core.rb +4 -4
  179. data/lib/spree/database_type_utilities.rb +7 -0
  180. data/lib/spree/events.rb +17 -10
  181. data/lib/spree/money.rb +2 -9
  182. data/lib/spree/permitted_attributes.rb +19 -7
  183. data/lib/spree/testing_support/capybara_config.rb +2 -2
  184. data/lib/spree/testing_support/common_rake.rb +15 -4
  185. data/lib/spree/testing_support/factories/api_key_factory.rb +19 -0
  186. data/lib/spree/testing_support/factories/custom_domain_factory.rb +7 -5
  187. data/lib/spree/testing_support/factories/import_factory.rb +12 -0
  188. data/lib/spree/testing_support/factories/market_factory.rb +35 -0
  189. data/lib/spree/testing_support/factories/order_factory.rb +3 -1
  190. data/lib/spree/testing_support/factories/payment_method_factory.rb +2 -0
  191. data/lib/spree/testing_support/factories/payment_session_factory.rb +47 -0
  192. data/lib/spree/testing_support/factories/payment_setup_session_factory.rb +31 -0
  193. data/lib/spree/testing_support/factories/price_rule_factory.rb +10 -0
  194. data/lib/spree/testing_support/factories/user_identity_factory.rb +15 -0
  195. data/lib/spree/testing_support/store.rb +3 -2
  196. data/lib/spree/webhooks.rb +7 -7
  197. data/lib/tasks/images.rake +20 -0
  198. data/lib/tasks/markets.rake +40 -0
  199. data/lib/tasks/sample_data.rake +15 -0
  200. data/spec/fixtures/files/customers_import.csv +4 -0
  201. metadata +99 -59
  202. data/LICENSE.md +0 -57
  203. data/app/finders/spree/stores/find_current.rb +0 -28
  204. data/app/models/spree/custom_domain.rb +0 -59
  205. data/app/serializers/spree/events/asset_serializer.rb +0 -22
  206. data/app/serializers/spree/events/base_serializer.rb +0 -61
  207. data/app/serializers/spree/events/customer_return_serializer.rb +0 -20
  208. data/app/serializers/spree/events/digital_link_serializer.rb +0 -20
  209. data/app/serializers/spree/events/digital_serializer.rb +0 -18
  210. data/app/serializers/spree/events/export_serializer.rb +0 -22
  211. data/app/serializers/spree/events/gift_card_batch_serializer.rb +0 -24
  212. data/app/serializers/spree/events/gift_card_serializer.rb +0 -29
  213. data/app/serializers/spree/events/image_serializer.rb +0 -9
  214. data/app/serializers/spree/events/import_row_serializer.rb +0 -23
  215. data/app/serializers/spree/events/import_serializer.rb +0 -24
  216. data/app/serializers/spree/events/invitation_serializer.rb +0 -28
  217. data/app/serializers/spree/events/line_item_serializer.rb +0 -31
  218. data/app/serializers/spree/events/newsletter_subscriber_serializer.rb +0 -21
  219. data/app/serializers/spree/events/order_serializer.rb +0 -39
  220. data/app/serializers/spree/events/payment_serializer.rb +0 -24
  221. data/app/serializers/spree/events/post_category_serializer.rb +0 -20
  222. data/app/serializers/spree/events/post_serializer.rb +0 -26
  223. data/app/serializers/spree/events/price_serializer.rb +0 -22
  224. data/app/serializers/spree/events/product_serializer.rb +0 -24
  225. data/app/serializers/spree/events/promotion_serializer.rb +0 -32
  226. data/app/serializers/spree/events/refund_serializer.rb +0 -23
  227. data/app/serializers/spree/events/reimbursement_serializer.rb +0 -22
  228. data/app/serializers/spree/events/report_serializer.rb +0 -23
  229. data/app/serializers/spree/events/return_authorization_serializer.rb +0 -22
  230. data/app/serializers/spree/events/return_item_serializer.rb +0 -27
  231. data/app/serializers/spree/events/shipment_serializer.rb +0 -24
  232. data/app/serializers/spree/events/stock_item_serializer.rb +0 -22
  233. data/app/serializers/spree/events/stock_movement_serializer.rb +0 -22
  234. data/app/serializers/spree/events/stock_transfer_serializer.rb +0 -22
  235. data/app/serializers/spree/events/store_credit_serializer.rb +0 -30
  236. data/app/serializers/spree/events/user_serializer.rb +0 -18
  237. data/app/serializers/spree/events/variant_serializer.rb +0 -34
  238. data/app/serializers/spree/events/wished_item_serializer.rb +0 -20
  239. data/app/serializers/spree/events/wishlist_serializer.rb +0 -22
@@ -0,0 +1,8 @@
1
+ promotion = Spree::Promotion.where(
2
+ name: 'Free Shipping',
3
+ code: 'FREESHIP'
4
+ ).first_or_create! do |promo|
5
+ promo.stores = Spree::Store.all
6
+ end
7
+
8
+ Spree::Promotion::Actions::FreeShipping.where(promotion: promotion).first_or_create!
@@ -0,0 +1,39 @@
1
+ begin
2
+ north_america = Spree::Zone.find_by!(name: 'North America')
3
+ rescue ActiveRecord::RecordNotFound
4
+ puts "Couldn't find 'North America' zone. Did you run `rake db:seed` first?"
5
+ exit
6
+ end
7
+
8
+ europe_vat = Spree::Zone.find_by!(name: 'EU_VAT')
9
+ shipping_category = Spree::ShippingCategory.find_or_create_by!(name: 'Default')
10
+
11
+ shipping_methods = [
12
+ { name: 'UPS Ground (USD)', zones: [north_america], display_on: 'both', shipping_categories: [shipping_category] },
13
+ { name: 'UPS Two Day (USD)', zones: [north_america], display_on: 'both', shipping_categories: [shipping_category] },
14
+ { name: 'UPS One Day (USD)', zones: [north_america], display_on: 'both', shipping_categories: [shipping_category] },
15
+ { name: 'UPS Ground (EU)', zones: [europe_vat], display_on: 'both', shipping_categories: [shipping_category] },
16
+ { name: 'UPS Ground (EUR)', zones: [europe_vat], display_on: 'both', shipping_categories: [shipping_category] }
17
+ ]
18
+
19
+ shipping_methods.each do |attributes|
20
+ Spree::ShippingMethod.where(name: attributes[:name]).first_or_create! do |shipping_method|
21
+ shipping_method.calculator = Spree::Calculator::Shipping::FlatRate.create!
22
+ shipping_method.zones = attributes[:zones]
23
+ shipping_method.display_on = attributes[:display_on]
24
+ shipping_method.shipping_categories = attributes[:shipping_categories]
25
+ end
26
+ end
27
+
28
+ {
29
+ 'UPS Ground (USD)' => [5, 'USD'],
30
+ 'UPS Ground (EU)' => [5, 'USD'],
31
+ 'UPS One Day (USD)' => [15, 'USD'],
32
+ 'UPS Two Day (USD)' => [10, 'USD'],
33
+ 'UPS Ground (EUR)' => [8, 'EUR']
34
+ }.each do |shipping_method_name, (price, currency)|
35
+ shipping_method = Spree::ShippingMethod.find_by!(name: shipping_method_name)
36
+ shipping_method.calculator.preferences = { amount: price, currency: currency }
37
+ shipping_method.calculator.save!
38
+ shipping_method.save!
39
+ end
@@ -55,7 +55,7 @@ module Spree
55
55
  inject_into_file admin_user_class_file, after: "class #{Spree.admin_user_class.name} < ApplicationRecord\n" do
56
56
  <<-RUBY
57
57
  # Spree modules
58
- include Spree::UserMethods
58
+ include Spree::AdminUserMethods
59
59
  RUBY
60
60
  end
61
61
  gsub_file admin_user_class_file, "< ApplicationRecord", "< Spree.base_class"
@@ -65,7 +65,7 @@ module Spree
65
65
  say "Could not locate admin user model file at #{admin_user_class_file}. Please add these lines manually:", :red
66
66
  say <<~RUBY
67
67
  # Spree modules
68
- include Spree::UserMethods
68
+ include Spree::AdminUserMethods
69
69
  RUBY
70
70
 
71
71
  say "Please replace < ApplicationRecord with < Spree.base_class in #{admin_user_class_file}"
@@ -0,0 +1,54 @@
1
+ require 'rails/generators'
2
+
3
+ module Spree
4
+ module Authentication
5
+ class DummyGenerator < Rails::Generators::Base
6
+ desc 'Set up a Spree installation with dummy authentication for testing. Creates a separate spree_admin_users table.'
7
+
8
+ def self.source_paths
9
+ paths = superclass.source_paths
10
+ paths << File.expand_path('templates', __dir__)
11
+ paths.flatten
12
+ end
13
+
14
+ def create_authentication_helpers
15
+ template 'authentication_helpers.rb.tt', 'lib/spree/authentication_helpers.rb'
16
+ end
17
+
18
+ def configure_authentication_helpers
19
+ file_action = File.exist?('config/initializers/spree.rb') ? :append_file : :create_file
20
+ send(file_action, 'config/initializers/spree.rb') do
21
+ <<~RUBY
22
+
23
+ Rails.application.config.to_prepare do
24
+ require_dependency 'spree/authentication_helpers'
25
+ end
26
+ RUBY
27
+ end
28
+ end
29
+
30
+ def create_admin_users_migration
31
+ # Use a fixed early timestamp (20210913) to ensure this migration runs BEFORE
32
+ # any Spree core migrations that reference spree_admin_users table.
33
+ # The earliest such migration is 20250122113708_add_first_and_last_name_to_spree_admin_class.rb
34
+ # We use a timestamp before the main Spree migration (20210914000000_spree_four_three.rb)
35
+ migration_file = File.join('db', 'migrate', '20210913000000_create_spree_admin_users.rb')
36
+
37
+ # Skip if migration already exists
38
+ return if File.exist?(migration_file) || migration_exists?('create_spree_admin_users')
39
+
40
+ template 'create_spree_admin_users.rb.tt', migration_file
41
+ end
42
+
43
+ private
44
+
45
+ def migration_exists?(name)
46
+ Dir.glob(File.join('db', 'migrate', "*_#{name}.rb")).any?
47
+ end
48
+
49
+ def migration_version
50
+ "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,52 @@
1
+ # Dummy authentication helpers for testing purposes.
2
+ # These provide stub implementations that don't require actual routes.
3
+ module Spree
4
+ module AuthenticationHelpers
5
+ def self.included(receiver)
6
+ receiver.helper_method(
7
+ :spree_current_user,
8
+ :spree_login_path,
9
+ :spree_signup_path,
10
+ :spree_logout_path,
11
+ :spree_forgot_password_path,
12
+ :spree_edit_password_path,
13
+ :spree_admin_login_path,
14
+ :spree_admin_logout_path
15
+ )
16
+ end
17
+
18
+ def spree_current_user
19
+ @spree_current_user
20
+ end
21
+
22
+ def spree_login_path(_opts = {})
23
+ '/login'
24
+ end
25
+
26
+ def spree_signup_path(_opts = {})
27
+ '/signup'
28
+ end
29
+
30
+ def spree_logout_path(_opts = {})
31
+ '/logout'
32
+ end
33
+
34
+ def spree_forgot_password_path(_opts = {})
35
+ '/forgot_password'
36
+ end
37
+
38
+ def spree_edit_password_path(_opts = {})
39
+ '/edit_password'
40
+ end
41
+
42
+ def spree_admin_login_path(_opts = {})
43
+ '/admin/login'
44
+ end
45
+
46
+ def spree_admin_logout_path(_opts = {})
47
+ '/admin/logout'
48
+ end
49
+ end
50
+ end
51
+
52
+ ApplicationController.include Spree::AuthenticationHelpers if defined?(ApplicationController)
@@ -0,0 +1,33 @@
1
+ class CreateSpreeAdminUsers < ActiveRecord::Migration<%= migration_version %>
2
+ def change
3
+ create_table :spree_admin_users do |t|
4
+ t.string :encrypted_password, limit: 128
5
+ t.string :password_salt, limit: 128
6
+ t.string :email
7
+ t.string :remember_token
8
+ t.string :persistence_token
9
+ t.string :reset_password_token
10
+ t.string :perishable_token
11
+ t.integer :sign_in_count, default: 0, null: false
12
+ t.integer :failed_attempts, default: 0, null: false
13
+ t.datetime :last_request_at
14
+ t.datetime :current_sign_in_at
15
+ t.datetime :last_sign_in_at
16
+ t.string :current_sign_in_ip
17
+ t.string :last_sign_in_ip
18
+ t.string :login
19
+ t.string :authentication_token
20
+ t.string :unlock_token
21
+ t.datetime :locked_at
22
+ t.datetime :remember_created_at
23
+ t.datetime :reset_password_sent_at
24
+ t.string :first_name
25
+ t.string :last_name
26
+ t.string :selected_locale
27
+
28
+ t.timestamps
29
+ end
30
+
31
+ add_index :spree_admin_users, :email, unique: true
32
+ end
33
+ end
@@ -4,7 +4,7 @@ require 'spree/core/version'
4
4
 
5
5
  module Spree
6
6
  class DummyGenerator < Rails::Generators::Base
7
- SPREE_GEMS = %w(spree_admin spree_storefront spree_api spree_emails).freeze
7
+ SPREE_GEMS = %w(spree_admin spree_api spree_emails).freeze
8
8
 
9
9
  desc 'Creates blank Rails application, installs Spree and all sample data'
10
10
 
@@ -40,6 +40,7 @@ module Spree
40
40
  preference :company, :boolean, default: false, deprecated: 'Use the company_field_enabled preference in the Spree::Store model' # Request company field for billing and shipping addr
41
41
  preference :currency, :string, default: 'USD', deprecated: true
42
42
  preference :credit_to_new_allocation, :boolean, default: false
43
+ preference :disable_migration_check, :boolean, default: false # when turned on disables the startup warning about missing engine migrations
43
44
  preference :disable_sku_validation, :boolean, default: false # when turned off disables the built-in SKU uniqueness validation
44
45
  preference :disable_store_presence_validation, :boolean, default: false # when turned off disables Store presence validation for Products and Payment Methods
45
46
  preference :events_log_enabled, :boolean, default: true # Log all Spree events to Rails logger
@@ -1,7 +1,13 @@
1
1
  module Spree
2
2
  module Core
3
3
  module ControllerHelpers
4
+ # @deprecated This module is deprecated and will be removed in Spree 5.5.
4
5
  module Common
6
+ def self.included(base)
7
+ Spree::Deprecation.warn(
8
+ 'Spree::Core::ControllerHelpers::Common is deprecated and will be removed in Spree 5.5.'
9
+ )
10
+ end
5
11
  end
6
12
  end
7
13
  end
@@ -39,8 +39,13 @@ module Spree
39
39
  end
40
40
 
41
41
  # Returns the list of supported currencies for all stores.
42
+ # @deprecated This method will be removed in Spree 5.5.
42
43
  # @return [Array<String>] the list of supported currencies, eg. `["USD", "EUR"]`
43
44
  def supported_currencies_for_all_stores
45
+ Spree::Deprecation.warn(
46
+ 'supported_currencies_for_all_stores is deprecated and will be removed in Spree 5.5.'
47
+ )
48
+
44
49
  @supported_currencies_for_all_stores ||= begin
45
50
  (
46
51
  Spree::Store.pluck(:supported_currencies).map { |c| c&.split(',') }.flatten + Spree::Store.pluck(:default_currency)
@@ -15,8 +15,12 @@ module Spree
15
15
  @order_token ||= cookies.signed[:token] || params[:order_token]
16
16
  end
17
17
 
18
- # Used in the link_to_cart helper.
18
+ # @deprecated Use `current_order` instead. This method will be removed in Spree 5.5.
19
19
  def simple_current_order
20
+ Spree::Deprecation.warn(
21
+ 'simple_current_order is deprecated and will be removed in Spree 5.5. Use current_order instead.'
22
+ )
23
+
20
24
  return @simple_current_order if @simple_current_order
21
25
 
22
26
  @simple_current_order = find_order_by_token_or_user
@@ -61,7 +61,7 @@ module Spree
61
61
 
62
62
  def current_tax_zone
63
63
  @current_tax_zone ||= begin
64
- zone = @current_order&.tax_zone || Spree::Zone.default_tax || current_store.checkout_zone
64
+ zone = @current_order&.tax_zone || Spree::Zone.default_tax
65
65
  Spree::Current.zone = zone
66
66
  zone
67
67
  end
@@ -100,7 +100,7 @@ module Spree
100
100
  cms_page_finder: nil, # LEGACY
101
101
  menu_finder: nil, # LEGACY
102
102
  current_order_finder: 'Spree::Orders::FindCurrent',
103
- current_store_finder: 'Spree::Stores::FindCurrent',
103
+ current_store_finder: 'Spree::Stores::FindDefault',
104
104
  completed_order_finder: 'Spree::Orders::FindComplete',
105
105
  credit_card_finder: 'Spree::CreditCards::Find',
106
106
  products_finder: 'Spree::Products::Find',
@@ -29,7 +29,9 @@ module Spree
29
29
  :analytics_events,
30
30
  :analytics_event_handlers,
31
31
  :integrations,
32
- :subscribers)
32
+ :subscribers,
33
+ :store_authentication_strategies,
34
+ :admin_authentication_strategies)
33
35
  SpreeCalculators = Struct.new(:shipping_methods, :tax_rates, :promotion_actions_create_adjustments, :promotion_actions_create_item_adjustments)
34
36
  PromoEnvironment = Struct.new(:rules, :actions)
35
37
  PricingEnvironment = Struct.new(:rules)
@@ -166,6 +168,7 @@ module Spree
166
168
 
167
169
  Rails.application.config.spree.pricing.rules.concat [
168
170
  Spree::PriceRules::ZoneRule,
171
+ Spree::PriceRules::MarketRule,
169
172
  Spree::PriceRules::UserRule,
170
173
  Spree::PriceRules::CustomerGroupRule,
171
174
  Spree::PriceRules::VolumeRule
@@ -192,6 +195,7 @@ module Spree
192
195
 
193
196
  Rails.application.config.spree.import_types = [
194
197
  Spree::Imports::Products,
198
+ Spree::Imports::Customers,
195
199
  ]
196
200
 
197
201
  Rails.application.config.spree.taxon_rules = [
@@ -228,7 +232,6 @@ module Spree
228
232
  Spree::Address,
229
233
  Spree::Asset,
230
234
  Spree::CreditCard,
231
- Spree::CustomDomain,
232
235
  Spree::CustomerReturn,
233
236
  Spree::GiftCard,
234
237
  Spree::Image,
@@ -304,6 +307,14 @@ module Spree
304
307
  Spree::InvitationEmailSubscriber,
305
308
  Spree::ProductMetricsSubscriber
306
309
  ]
310
+
311
+ # Pre-load authentication strategy classes to avoid reflection at request time
312
+ Rails.application.config.spree.store_authentication_strategies = {
313
+ email: Spree::Authentication::Strategies::EmailPasswordStrategy
314
+ }
315
+ Rails.application.config.spree.admin_authentication_strategies = {
316
+ email: Spree::Authentication::Strategies::EmailPasswordStrategy
317
+ }
307
318
  end
308
319
 
309
320
  initializer 'spree.promo.register.promotions.actions' do |app|
@@ -322,8 +333,10 @@ module Spree
322
333
  ]
323
334
  end
324
335
 
325
- initializer 'spree.core.checking_migrations' do
326
- Migrations.new(config, engine_name).check unless Rails.env.test?
336
+ initializer 'spree.core.checking_migrations' do |app|
337
+ app.config.after_initialize do
338
+ Migrations.new(config, engine_name).check unless Rails.env.test? || Spree::Config.disable_migration_check
339
+ end
327
340
  end
328
341
 
329
342
  initializer 'spree.core.assets' do |app|
@@ -1,22 +1,24 @@
1
1
  module Spree
2
2
  module Pricing
3
3
  class Context
4
- attr_reader :variant, :currency, :store, :zone, :user, :quantity, :date, :order
4
+ attr_reader :variant, :currency, :store, :zone, :market, :user, :quantity, :date, :order
5
5
 
6
6
  # Initializes the context
7
7
  # @param variant [Spree::Variant]
8
8
  # @param currency [String]
9
9
  # @param store [Spree::Store]
10
10
  # @param zone [Spree::Zone]
11
+ # @param market [Spree::Market]
11
12
  # @param user [Spree::User]
12
13
  # @param quantity [Integer]
13
14
  # @param date [Time]
14
15
  # @param order [Spree::Order]
15
- def initialize(variant: nil, currency:, store: nil, zone: nil, user: nil, quantity: nil, date: nil, order: nil)
16
+ def initialize(variant: nil, currency:, store: nil, zone: nil, market: nil, user: nil, quantity: nil, date: nil, order: nil)
16
17
  @variant = variant
17
18
  @currency = currency
18
19
  @store = store || Spree::Current.store
19
20
  @zone = zone || Spree::Current.zone
21
+ @market = market || Spree::Current.market
20
22
  @user = user
21
23
  @quantity = quantity
22
24
  @date = date || Time.current
@@ -36,7 +38,7 @@ module Spree
36
38
  variant: variant,
37
39
  currency: order.currency,
38
40
  store: order.store,
39
- zone: order.tax_zone || order.store.checkout_zone,
41
+ zone: order.tax_zone || Spree::Zone.default_tax,
40
42
  user: order.user,
41
43
  quantity: quantity || order.line_items.find_by(variant: variant)&.quantity,
42
44
  order: order
@@ -53,6 +55,7 @@ module Spree
53
55
  currency,
54
56
  store&.id,
55
57
  zone&.id,
58
+ market&.id,
56
59
  user&.id,
57
60
  quantity,
58
61
  date&.to_i
@@ -42,7 +42,16 @@ module Spree
42
42
  # or taxons), eg see the taxon model/controller.
43
43
 
44
44
  # See specific filters below for concrete examples.
45
+ # @deprecated This module is deprecated and will be removed in Spree 5.5.
46
+ # Use Spree::Api::V3::FiltersAggregator instead.
45
47
  module ProductFilters
48
+ def self.deprecated_warning
49
+ Spree::Deprecation.warn(
50
+ 'Spree::Core::ProductFilters is deprecated and will be removed in Spree 5.5. ' \
51
+ 'Please use Spree::Api::V3::FiltersAggregator instead.'
52
+ )
53
+ end
54
+
46
55
  # Example: filtering by price
47
56
  # The named scope just maps incoming labels onto their conditions, and builds the conjunction
48
57
  # 'price' is in the base scope's context (ie, "select foo from products where ...") so
@@ -66,6 +75,7 @@ module Spree
66
75
  end
67
76
 
68
77
  def self.price_filter
78
+ deprecated_warning
69
79
  v = Spree::Price.arel_table
70
80
  conds = [[Spree.t(:under_price, price: format_price(10)), v[:amount].lteq(10)],
71
81
  ["#{format_price(10)} - #{format_price(15)}", v[:amount].between(10..15)],
@@ -107,6 +117,7 @@ module Spree
107
117
  end
108
118
 
109
119
  def self.brand_filter
120
+ deprecated_warning
110
121
  brand_property = Spree::Property.find_by(name: 'brand')
111
122
  brands = brand_property ? Spree::ProductProperty.where(property_id: brand_property.id).pluck(:value).uniq.map(&:to_s) : []
112
123
 
@@ -148,6 +159,7 @@ module Spree
148
159
  end
149
160
 
150
161
  def self.selective_brand_filter(taxon = nil)
162
+ deprecated_warning
151
163
  taxon ||= Spree::Taxonomy.first.root
152
164
  brand_property = Spree::Property.find_by(name: 'brand')
153
165
  scope = Spree::ProductProperty.where(property: brand_property).
@@ -174,6 +186,7 @@ module Spree
174
186
  # This scope selects products in any of the active taxons or their children.
175
187
  #
176
188
  def self.taxons_below(taxon)
189
+ deprecated_warning
177
190
  return Spree::Core::ProductFilters.all_taxons if taxon.nil?
178
191
 
179
192
  {
@@ -191,6 +204,7 @@ module Spree
191
204
  #
192
205
  # idea: expand the format to allow nesting of labels?
193
206
  def self.all_taxons
207
+ deprecated_warning
194
208
  taxons = Spree::Taxonomy.all.map { |t| [t.root] + t.root.descendants }.flatten
195
209
  {
196
210
  name: 'All taxons',
@@ -1,8 +1,12 @@
1
1
  module Spree
2
2
  module Core
3
3
  module QueryFilters
4
+ # @deprecated This class is deprecated and will be removed in Spree 5.5.
4
5
  class Comparable
5
6
  def initialize(attribute:)
7
+ Spree::Deprecation.warn(
8
+ "#{self.class.name} is deprecated and will be removed in Spree 5.5."
9
+ )
6
10
  @attribute = attribute
7
11
  end
8
12
 
@@ -1,8 +1,12 @@
1
1
  module Spree
2
2
  module Core
3
3
  module QueryFilters
4
+ # @deprecated This class is deprecated and will be removed in Spree 5.5.
4
5
  class Text
5
6
  def initialize(attribute:)
7
+ Spree::Deprecation.warn(
8
+ 'Spree::Core::QueryFilters::Text is deprecated and will be removed in Spree 5.5.'
9
+ )
6
10
  @attribute = attribute
7
11
  end
8
12
 
@@ -1,5 +1,5 @@
1
1
  module Spree
2
- VERSION = '5.3.4'.freeze
2
+ VERSION = '5.4.0.beta'.freeze
3
3
 
4
4
  def self.version
5
5
  VERSION
data/lib/spree/core.rb CHANGED
@@ -18,6 +18,7 @@ require 'awesome_nested_set'
18
18
  require 'cancan'
19
19
  require 'countries/global'
20
20
  require 'friendly_id'
21
+ require 'jwt'
21
22
  require 'monetize'
22
23
  require 'mobility'
23
24
  require 'name_of_person'
@@ -25,12 +26,12 @@ require 'paranoia'
25
26
  require 'ransack'
26
27
  require 'state_machines-activerecord'
27
28
  require 'active_storage_validations'
28
- require 'request_store'
29
29
  require 'wannabe_bool'
30
30
  require 'geocoder'
31
31
  require 'oembed'
32
32
  require 'safely_block'
33
33
  require 'ar_lazy_preload'
34
+ require 'sqids'
34
35
 
35
36
  # This is required because ActiveModel::Validations#invalid? conflicts with the
36
37
  # invalid state of a Payment. In the future this should be removed.
@@ -60,8 +61,6 @@ module Spree
60
61
  end
61
62
 
62
63
  def self.admin_user_class(constantize: true)
63
- @@admin_user_class ||= @@user_class
64
-
65
64
  if @@admin_user_class.is_a?(Class)
66
65
  raise 'Spree.admin_user_class MUST be a String or Symbol object, not a Class object.'
67
66
  elsif @@admin_user_class.is_a?(String) || @@admin_user_class.is_a?(Symbol)
@@ -109,7 +108,8 @@ module Spree
109
108
  themes: :default,
110
109
  addresses: :default,
111
110
  gift_cards: :default,
112
- webhooks: :default
111
+ webhooks: :default,
112
+ api_keys: :default
113
113
  )
114
114
  end
115
115
 
@@ -1,9 +1,16 @@
1
1
  module Spree
2
+ # @deprecated Use the integer constant directly instead, eg. `2_147_483_647` for 4-byte signed integer max.
3
+ # This module will be removed in Spree 5.5.
2
4
  module DatabaseTypeUtilities
3
5
  # Maximum value for a 4-byte signed integer (default database integer type)
4
6
  INTEGER_MAX = (2**31) - 1
5
7
 
6
8
  def self.maximum_value_for(data_type)
9
+ Spree::Deprecation.warn(
10
+ 'Spree::DatabaseTypeUtilities.maximum_value_for is deprecated and will be removed in Spree 5.5. ' \
11
+ 'Use the integer constant directly instead, eg. 2_147_483_647 for 4-byte signed integer max.'
12
+ )
13
+
7
14
  case data_type
8
15
  when :integer
9
16
  INTEGER_MAX
data/lib/spree/events.rb CHANGED
@@ -177,10 +177,11 @@ module Spree
177
177
  # Check if events are enabled
178
178
  #
179
179
  # Events can be temporarily disabled using Spree::Events.disable { ... }
180
+ # or globally with Spree::Events.disable!
180
181
  #
181
182
  # @return [Boolean]
182
183
  def enabled?
183
- !RequestStore.store[:spree_events_disabled]
184
+ !@globally_disabled && !Thread.current[:spree_events_disabled]
184
185
  end
185
186
 
186
187
  # Temporarily disable events within a block
@@ -195,18 +196,21 @@ module Spree
195
196
  # end
196
197
  #
197
198
  def disable
198
- previous = RequestStore.store[:spree_events_disabled]
199
- RequestStore.store[:spree_events_disabled] = true
199
+ previous = Thread.current[:spree_events_disabled]
200
+ Thread.current[:spree_events_disabled] = true
200
201
  yield
201
202
  ensure
202
- RequestStore.store[:spree_events_disabled] = previous
203
+ Thread.current[:spree_events_disabled] = previous
203
204
  end
204
205
 
205
206
  # Globally disable events
206
- # Useful for testing to disable events for the entire test suite
207
+ #
208
+ # Uses a class-level flag that is not affected by per-request cleanup.
209
+ # Useful for disabling events for the entire test suite.
210
+ #
207
211
  # @return [void]
208
212
  def disable!
209
- RequestStore.store[:spree_events_disabled] = true
213
+ @globally_disabled = true
210
214
  end
211
215
 
212
216
  # Temporarily enable events within a block
@@ -222,18 +226,21 @@ module Spree
222
226
  # end
223
227
  #
224
228
  def enable
225
- previous = RequestStore.store[:spree_events_disabled]
226
- RequestStore.store[:spree_events_disabled] = false
229
+ previous_global = @globally_disabled
230
+ previous_thread = Thread.current[:spree_events_disabled]
231
+ @globally_disabled = false
232
+ Thread.current[:spree_events_disabled] = false
227
233
  yield
228
234
  ensure
229
- RequestStore.store[:spree_events_disabled] = previous
235
+ @globally_disabled = previous_global
236
+ Thread.current[:spree_events_disabled] = previous_thread
230
237
  end
231
238
 
232
239
  # Globally enable events
233
240
  # Useful for testing
234
241
  # @return [void]
235
242
  def enable!
236
- RequestStore.store[:spree_events_disabled] = false
243
+ @globally_disabled = false
237
244
  end
238
245
  end
239
246
  end
data/lib/spree/money.rb CHANGED
@@ -51,17 +51,10 @@ module Spree
51
51
  # 1) prevent blank, breaking spaces
52
52
  # 2) prevent escaping of HTML character entities
53
53
  def to_html(opts = { html: true })
54
- # html option is deprecated and we need to fallback to html_wrap
55
- opts[:html_wrap] = opts[:html]
56
54
  opts.delete(:html)
57
55
 
58
- output = money.format(options.merge(opts))
59
- if opts[:html_wrap]
60
- output.gsub!(/<\/?[^>]*>/, '') # we don't want wrap every element in span
61
- output = output.sub(' ', '&nbsp;').html_safe
62
- end
63
-
64
- output
56
+ output = money.format(options.merge(opts).merge(html_wrap: false))
57
+ output.sub(' ', '&nbsp;').html_safe
65
58
  end
66
59
 
67
60
  def as_json(*)