spree_core 5.5.4 → 5.6.0.rc1

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 (136) hide show
  1. checksums.yaml +4 -4
  2. data/app/helpers/spree/base_helper.rb +12 -2
  3. data/app/helpers/spree/currency_helper.rb +1 -4
  4. data/app/helpers/spree/locale_helper.rb +18 -13
  5. data/app/helpers/spree/localized_names_helper.rb +25 -0
  6. data/app/mailers/spree/admin_user_mailer.rb +71 -0
  7. data/app/mailers/spree/base_mailer.rb +73 -11
  8. data/app/mailers/spree/export_mailer.rb +7 -7
  9. data/app/mailers/spree/import_mailer.rb +19 -0
  10. data/app/mailers/spree/invitation_mailer.rb +16 -11
  11. data/app/mailers/spree/report_mailer.rb +6 -6
  12. data/app/mailers/spree/webhook_mailer.rb +7 -6
  13. data/app/models/concerns/spree/admin_user_methods.rb +44 -0
  14. data/app/models/concerns/spree/legacy_multi_store_support.rb +48 -0
  15. data/app/models/concerns/spree/presentation_translatable.rb +39 -0
  16. data/app/models/concerns/spree/product_scopes.rb +21 -3
  17. data/app/models/concerns/spree/single_store_resource.rb +5 -0
  18. data/app/models/concerns/spree/store_scoped_resource.rb +10 -0
  19. data/app/models/concerns/spree/stores/markets.rb +9 -1
  20. data/app/models/concerns/spree/stores/setup.rb +37 -23
  21. data/app/models/concerns/spree/translatable_resource.rb +95 -5
  22. data/app/models/concerns/spree/user_methods.rb +27 -2
  23. data/app/models/spree/ability.rb +5 -4
  24. data/app/models/spree/allowed_origin.rb +31 -0
  25. data/app/models/spree/category.rb +12 -2
  26. data/app/models/spree/channel/gating.rb +67 -0
  27. data/app/models/spree/channel.rb +1 -0
  28. data/app/models/spree/classification.rb +12 -0
  29. data/app/models/spree/country.rb +22 -1
  30. data/app/models/spree/credit_card.rb +29 -0
  31. data/app/models/spree/currency.rb +47 -0
  32. data/app/models/spree/current.rb +12 -1
  33. data/app/models/spree/customer_group.rb +1 -0
  34. data/app/models/spree/export.rb +19 -0
  35. data/app/models/spree/exports/coupon_codes.rb +1 -2
  36. data/app/models/spree/import.rb +84 -1
  37. data/app/models/spree/import_row.rb +7 -1
  38. data/app/models/spree/imports/product_translations.rb +6 -0
  39. data/app/models/spree/locale.rb +104 -0
  40. data/app/models/spree/option_type.rb +11 -13
  41. data/app/models/spree/option_value.rb +5 -17
  42. data/app/models/spree/order.rb +19 -2
  43. data/app/models/spree/payment_method.rb +6 -5
  44. data/app/models/spree/policy.rb +2 -1
  45. data/app/models/spree/product.rb +23 -2
  46. data/app/models/spree/promotion/rules/channel.rb +37 -0
  47. data/app/models/spree/promotion/rules/market.rb +37 -0
  48. data/app/models/spree/promotion.rb +5 -3
  49. data/app/models/spree/promotion_handler/promotion_duplicator.rb +1 -1
  50. data/app/models/spree/role_user.rb +4 -0
  51. data/app/models/spree/search_provider/meilisearch.rb +22 -9
  52. data/app/models/spree/setup_task.rb +12 -0
  53. data/app/models/spree/setup_tasks.rb +86 -0
  54. data/app/models/spree/shipment.rb +38 -1
  55. data/app/models/spree/shipment_handler.rb +1 -1
  56. data/app/models/spree/stock/availability_validator.rb +1 -1
  57. data/app/models/spree/stock/quantifier.rb +21 -1
  58. data/app/models/spree/stock_item.rb +2 -1
  59. data/app/models/spree/stock_location.rb +4 -1
  60. data/app/models/spree/store.rb +45 -9
  61. data/app/models/spree/store_payment_method.rb +5 -1
  62. data/app/models/spree/store_promotion.rb +4 -0
  63. data/app/models/spree/taxon.rb +112 -9
  64. data/app/models/spree/taxonomy.rb +1 -1
  65. data/app/models/spree/translations/batch.rb +104 -0
  66. data/app/models/spree/variant.rb +29 -2
  67. data/app/models/spree/webhook_delivery.rb +0 -22
  68. data/app/presenters/spree/data_feeds/google_presenter.rb +1 -28
  69. data/app/presenters/spree/search_provider/product_presenter.rb +3 -0
  70. data/app/services/spree/carts/complete.rb +3 -0
  71. data/app/services/spree/fulfillments/create.rb +259 -0
  72. data/app/services/spree/locales/set_fallback_locale_for_store.rb +7 -1
  73. data/app/services/spree/locales.rb +52 -0
  74. data/app/services/spree/products/prepare_nested_attributes.rb +40 -12
  75. data/app/services/spree/shipments/update.rb +1 -1
  76. data/app/services/spree/stock_reservations/reserve.rb +4 -1
  77. data/app/services/spree/taxons/add_products.rb +3 -0
  78. data/app/services/spree/taxons/remove_products.rb +3 -0
  79. data/app/subscribers/spree/admin_user_email_subscriber.rb +29 -0
  80. data/app/subscribers/spree/import_email_subscriber.rb +26 -0
  81. data/app/views/layouts/spree/base_mailer.html.erb +14 -17
  82. data/app/views/spree/admin_user_mailer/confirmation_email.html.erb +7 -0
  83. data/app/views/spree/admin_user_mailer/password_reset_email.html.erb +8 -0
  84. data/app/views/spree/export_mailer/export_done.html.erb +6 -14
  85. data/app/views/spree/import_mailer/import_done.html.erb +12 -0
  86. data/app/views/spree/invitation_mailer/invitation_accepted.html.erb +4 -12
  87. data/app/views/spree/invitation_mailer/invitation_email.html.erb +11 -24
  88. data/app/views/spree/report_mailer/report_done.html.erb +6 -14
  89. data/app/views/spree/shared/_base_mailer_footer.html.erb +15 -8
  90. data/app/views/spree/shared/_base_mailer_header.html.erb +7 -5
  91. data/app/views/spree/shared/_base_mailer_stylesheets.html.erb +211 -273
  92. data/app/views/spree/shared/_mailer_button.html.erb +10 -0
  93. data/app/views/spree/shared/_mailer_hero.html.erb +12 -0
  94. data/app/views/spree/shared/_purchased_items_styles.html.erb +112 -0
  95. data/app/views/spree/webhook_mailer/endpoint_disabled.html.erb +39 -14
  96. data/config/initializers/spree_store_setup_tasks.rb +23 -0
  97. data/config/locales/en.yml +42 -992
  98. data/db/migrate/20260613000001_add_store_id_to_spree_role_users.rb +10 -0
  99. data/db/migrate/20260626000001_add_store_id_to_spree_taxons.rb +11 -0
  100. data/db/migrate/20260627000001_add_products_count_to_spree_taxons.rb +6 -0
  101. data/db/migrate/20260628000001_add_store_id_to_spree_promotions.rb +10 -0
  102. data/db/migrate/20260628000002_add_store_id_to_spree_payment_methods.rb +11 -0
  103. data/db/migrate/20260630000001_add_preorder_fields_to_spree_variants.rb +7 -0
  104. data/db/migrate/20260707000001_add_fingerprint_to_spree_credit_cards.rb +39 -0
  105. data/db/migrate/20260710000001_add_import_id_status_index_to_spree_import_rows.rb +7 -0
  106. data/db/migrate/20260711000001_add_preferences_to_spree_exports.rb +7 -0
  107. data/db/sample_data/promotions.rb +1 -1
  108. data/lib/generators/spree/authentication/dummy/templates/create_spree_admin_users.rb.tt +0 -1
  109. data/lib/mobility/plugins/store_based_fallbacks.rb +7 -5
  110. data/lib/spree/core/configuration.rb +1 -0
  111. data/lib/spree/core/controller_helpers/locale.rb +4 -1
  112. data/lib/spree/core/controller_helpers/strong_parameters.rb +1 -0
  113. data/lib/spree/core/dependencies.rb +3 -0
  114. data/lib/spree/core/engine.rb +24 -0
  115. data/lib/spree/core/preferences/preferable.rb +6 -1
  116. data/lib/spree/core/previews/admin_user_preview.rb +22 -0
  117. data/lib/spree/core/previews/export_preview.rb +37 -0
  118. data/lib/spree/core/previews/invitation_preview.rb +47 -0
  119. data/lib/spree/core/previews/preview_data.rb +52 -0
  120. data/lib/spree/core/previews/report_preview.rb +40 -0
  121. data/lib/spree/core/previews/webhook_preview.rb +34 -0
  122. data/lib/spree/core/version.rb +1 -1
  123. data/lib/spree/core.rb +22 -1
  124. data/lib/spree/permitted_attributes.rb +5 -4
  125. data/lib/spree/testing_support/factories/export_factory.rb +4 -0
  126. data/lib/spree/testing_support/factories/payment_method_factory.rb +1 -9
  127. data/lib/spree/testing_support/factories/promotion_factory.rb +1 -9
  128. data/lib/spree/testing_support/factories/promotion_rule_factory.rb +24 -0
  129. data/lib/spree/translations.rb +113 -0
  130. data/lib/spree/upgrades/5_5_to_5_6/manifest.yml +59 -0
  131. data/lib/tasks/role_users.rake +21 -0
  132. data/lib/tasks/single_store_associations.rake +65 -0
  133. data/lib/tasks/taxons.rake +62 -1
  134. metadata +47 -6
  135. data/app/models/concerns/spree/webhook_payload_redaction.rb +0 -88
  136. data/app/models/spree/product/legacy_multi_store_support.rb +0 -40
@@ -1,88 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Spree
4
- # Keeps single-use credentials out of the persisted webhook delivery log.
5
- #
6
- # Some events must carry a live credential to their subscriber — a storefront
7
- # that owns its transactional emails needs the real password reset token to
8
- # build the email. Delivering it over TLS to a merchant-configured endpoint is
9
- # intended; keeping a readable copy in `spree_webhook_deliveries.payload` is
10
- # not, because that column is queryable and is served back through the Admin
11
- # API delivery log.
12
- #
13
- # Sensitive values are therefore replaced with {REDACTION_PLACEHOLDER} before
14
- # the record is written, and re-attached in memory at send time so the
15
- # outgoing request body is unchanged.
16
- module WebhookPayloadRedaction
17
- extend ActiveSupport::Concern
18
-
19
- # Payload keys under `data` whose values are live credentials.
20
- SENSITIVE_PAYLOAD_KEYS = %w[reset_token unsubscribe_token].freeze
21
-
22
- REDACTION_PLACEHOLDER = '[REDACTED]'
23
-
24
- # Splits a payload into the version safe to persist and the secrets held
25
- # back from it.
26
- #
27
- # @param payload [Hash] the full event payload
28
- # @return [Array(Hash, Hash)] redacted payload, and the extracted secrets
29
- # keyed as they appeared under `data`
30
- def self.split(payload)
31
- secrets = {}
32
-
33
- redacted = transform_data_hashes(payload) do |data|
34
- data.to_h do |key, value|
35
- if SENSITIVE_PAYLOAD_KEYS.include?(key.to_s) && value.present?
36
- secrets[secret_key_for(key)] = value
37
- [key, REDACTION_PLACEHOLDER]
38
- else
39
- [key, value]
40
- end
41
- end
42
- end
43
-
44
- secrets.empty? ? [payload, {}] : [redacted, secrets]
45
- end
46
-
47
- # Re-attaches previously extracted secrets to a redacted payload.
48
- #
49
- # @param payload [Hash] the redacted payload
50
- # @param secrets [Hash] secrets returned by {split}
51
- # @return [Hash] the payload as it should go over the wire
52
- def self.merge(payload, secrets)
53
- return payload if secrets.blank?
54
-
55
- transform_data_hashes(payload) do |data|
56
- data.to_h do |key, value|
57
- secret = secrets[secret_key_for(key)]
58
- [key, secret.presence || value]
59
- end
60
- end
61
- end
62
-
63
- # Applies +block+ to every `data` hash on the payload.
64
- #
65
- # Both key forms are visited rather than only the first match: a payload
66
- # carrying `:data` *and* `'data'` would otherwise leave one of them
67
- # unredacted.
68
- def self.transform_data_hashes(payload)
69
- return payload unless payload.is_a?(Hash)
70
-
71
- [:data, 'data'].reduce(payload) do |result, data_key|
72
- data = result[data_key]
73
- next result unless data.is_a?(Hash)
74
-
75
- result.merge(data_key => yield(data))
76
- end
77
- end
78
- private_class_method :transform_data_hashes
79
-
80
- # Secrets are keyed by name alone. They cross an ActiveJob serialization
81
- # boundary, which coerces symbol keys to strings, so the key form at split
82
- # time cannot be relied on to still match at merge time.
83
- def self.secret_key_for(key)
84
- key.to_s
85
- end
86
- private_class_method :secret_key_for
87
- end
88
- end
@@ -1,40 +0,0 @@
1
- module Spree
2
- class Product
3
- # Legacy multi-store support. In Spree 5.5+ the +Spree::ProductPublication+ model
4
- # handles the Product↔Store relation, so this module only provides a fallback
5
- # for legacy code that still references +Spree::Product#stores+.
6
- module LegacyMultiStoreSupport
7
- extend ActiveSupport::Concern
8
-
9
- included do
10
- def stores
11
- Spree::Deprecation.warn(
12
- "Spree::Product#stores is deprecated. Please use Spree::Product.store instead. If you want to continue using multiple stores please install spree_multi_store gem"
13
- )
14
- store ? [store] : []
15
- end
16
-
17
- def store_ids
18
- Spree::Deprecation.warn(
19
- "Spree::Product#store_ids is deprecated. Please use Spree::Product.store_id instead. If you want to continue using multiple stores please install spree_multi_store gem"
20
- )
21
- store_id ? [store_id] : []
22
- end
23
-
24
- def stores=(stores)
25
- Spree::Deprecation.warn(
26
- "Spree::Product#stores= is deprecated. Please use Spree::Product.store= instead. If you want to continue using multiple stores please install spree_multi_store gem"
27
- )
28
- self.store = Array(stores).compact.first
29
- end
30
-
31
- def store_ids=(store_ids)
32
- Spree::Deprecation.warn(
33
- "Spree::Product#store_ids= is deprecated. Please use Spree::Product.store_id= instead. If you want to continue using multiple stores please install spree_multi_store gem"
34
- )
35
- self.store_id = Array(store_ids).compact_blank.first
36
- end
37
- end
38
- end
39
- end
40
- end