spree_core 5.3.6 → 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 (243) 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/jobs/spree/images/save_from_url_job.rb +23 -47
  9. data/app/models/concerns/spree/admin_user_methods.rb +32 -0
  10. data/app/models/concerns/spree/number_as_param.rb +5 -3
  11. data/app/models/concerns/spree/prefixed_id.rb +82 -0
  12. data/app/models/concerns/spree/product_scopes.rb +33 -18
  13. data/app/models/concerns/spree/publishable.rb +47 -47
  14. data/app/models/concerns/spree/{multi_store_resource.rb → store_scoped_resource.rb} +1 -10
  15. data/app/models/concerns/spree/stores/markets.rb +124 -0
  16. data/app/models/concerns/spree/user_methods.rb +7 -7
  17. data/app/models/concerns/spree/user_payment_source.rb +2 -0
  18. data/app/models/concerns/spree/user_roles.rb +1 -0
  19. data/app/models/spree/ability.rb +13 -0
  20. data/app/models/spree/address.rb +30 -0
  21. data/app/models/spree/adjustment.rb +2 -0
  22. data/app/models/spree/api_key.rb +47 -0
  23. data/app/models/spree/asset.rb +2 -0
  24. data/app/models/spree/authentication/strategies/base_strategy.rb +55 -0
  25. data/app/models/spree/authentication/strategies/email_password_strategy.rb +47 -0
  26. data/app/models/spree/base.rb +1 -0
  27. data/app/models/spree/calculator.rb +2 -0
  28. data/app/models/spree/country.rb +56 -0
  29. data/app/models/spree/coupon_code.rb +2 -0
  30. data/app/models/spree/credit_card.rb +2 -0
  31. data/app/models/spree/current.rb +9 -4
  32. data/app/models/spree/customer_group.rb +2 -0
  33. data/app/models/spree/customer_return.rb +2 -0
  34. data/app/models/spree/data_feed.rb +2 -0
  35. data/app/models/spree/digital.rb +2 -0
  36. data/app/models/spree/digital_link.rb +2 -0
  37. data/app/models/spree/export.rb +5 -4
  38. data/app/models/spree/fulfilment_changer.rb +8 -2
  39. data/app/models/spree/gateway/bogus.rb +60 -0
  40. data/app/models/spree/gateway_customer.rb +2 -0
  41. data/app/models/spree/gift_card.rb +2 -0
  42. data/app/models/spree/gift_card_batch.rb +2 -4
  43. data/app/models/spree/image.rb +18 -0
  44. data/app/models/spree/import.rb +5 -3
  45. data/app/models/spree/import_mapping.rb +2 -0
  46. data/app/models/spree/import_row.rb +2 -0
  47. data/app/models/spree/import_schemas/customers.rb +21 -0
  48. data/app/models/spree/imports/customers.rb +9 -0
  49. data/app/models/spree/integration.rb +2 -0
  50. data/app/models/spree/inventory_unit.rb +2 -0
  51. data/app/models/spree/invitation.rb +6 -6
  52. data/app/models/spree/legacy_admin_user.rb +31 -0
  53. data/app/models/spree/legacy_user.rb +19 -1
  54. data/app/models/spree/line_item.rb +15 -4
  55. data/app/models/spree/log_entry.rb +2 -0
  56. data/app/models/spree/market.rb +83 -0
  57. data/app/models/spree/market_country.rb +25 -0
  58. data/app/models/spree/metafield.rb +2 -0
  59. data/app/models/spree/metafield_definition.rb +2 -0
  60. data/app/models/spree/newsletter_subscriber.rb +2 -0
  61. data/app/models/spree/option_type.rb +2 -0
  62. data/app/models/spree/option_value.rb +2 -0
  63. data/app/models/spree/order/address_book.rb +2 -1
  64. data/app/models/spree/order.rb +75 -47
  65. data/app/models/spree/payment.rb +6 -1
  66. data/app/models/spree/payment_capture_event.rb +2 -0
  67. data/app/models/spree/payment_method.rb +59 -1
  68. data/app/models/spree/payment_session.rb +109 -0
  69. data/app/models/spree/payment_sessions/bogus.rb +4 -0
  70. data/app/models/spree/payment_setup_session.rb +79 -0
  71. data/app/models/spree/payment_source.rb +2 -0
  72. data/app/models/spree/permission_sets/default_customer.rb +19 -0
  73. data/app/models/spree/policy.rb +2 -0
  74. data/app/models/spree/post.rb +2 -0
  75. data/app/models/spree/post_category.rb +2 -0
  76. data/app/models/spree/price.rb +26 -2
  77. data/app/models/spree/price_list.rb +2 -0
  78. data/app/models/spree/price_rule.rb +2 -0
  79. data/app/models/spree/price_rules/market_rule.rb +19 -0
  80. data/app/models/spree/product.rb +41 -29
  81. data/app/models/spree/promotion/rules/country.rb +1 -1
  82. data/app/models/spree/promotion.rb +3 -1
  83. data/app/models/spree/promotion_action.rb +2 -0
  84. data/app/models/spree/promotion_category.rb +2 -0
  85. data/app/models/spree/promotion_rule.rb +2 -0
  86. data/app/models/spree/prototype.rb +2 -0
  87. data/app/models/spree/refund.rb +2 -4
  88. data/app/models/spree/refund_reason.rb +2 -0
  89. data/app/models/spree/reimbursement/credit.rb +2 -0
  90. data/app/models/spree/reimbursement.rb +2 -0
  91. data/app/models/spree/reimbursement_type.rb +2 -0
  92. data/app/models/spree/report.rb +3 -1
  93. data/app/models/spree/return_authorization.rb +2 -0
  94. data/app/models/spree/return_authorization_reason.rb +2 -0
  95. data/app/models/spree/return_item.rb +2 -0
  96. data/app/models/spree/role.rb +2 -0
  97. data/app/models/spree/shipment.rb +11 -1
  98. data/app/models/spree/shipping_category.rb +2 -0
  99. data/app/models/spree/shipping_method.rb +2 -0
  100. data/app/models/spree/shipping_method_category.rb +2 -0
  101. data/app/models/spree/shipping_rate.rb +2 -0
  102. data/app/models/spree/state_change.rb +2 -0
  103. data/app/models/spree/stock_item.rb +2 -0
  104. data/app/models/spree/stock_location.rb +2 -0
  105. data/app/models/spree/stock_movement.rb +2 -0
  106. data/app/models/spree/stock_transfer.rb +2 -1
  107. data/app/models/spree/store.rb +110 -179
  108. data/app/models/spree/store_credit.rb +2 -4
  109. data/app/models/spree/store_credit_category.rb +2 -0
  110. data/app/models/spree/store_credit_event.rb +2 -0
  111. data/app/models/spree/store_credit_type.rb +2 -0
  112. data/app/models/spree/store_product.rb +2 -0
  113. data/app/models/spree/tax_category.rb +2 -0
  114. data/app/models/spree/tax_rate.rb +2 -0
  115. data/app/models/spree/taxon.rb +4 -1
  116. data/app/models/spree/taxon_image.rb +8 -0
  117. data/app/models/spree/taxon_rule.rb +2 -0
  118. data/app/models/spree/taxonomy.rb +2 -0
  119. data/app/models/spree/user_identity.rb +81 -0
  120. data/app/models/spree/variant.rb +13 -3
  121. data/app/models/spree/webhook_delivery.rb +2 -0
  122. data/app/models/spree/webhook_endpoint.rb +2 -17
  123. data/app/models/spree/wished_item.rb +15 -0
  124. data/app/models/spree/wishlist.rb +2 -8
  125. data/app/models/spree/zone.rb +2 -6
  126. data/app/presenters/spree/filters/price_presenter.rb +1 -0
  127. data/app/presenters/spree/filters/price_range_presenter.rb +1 -0
  128. data/app/presenters/spree/filters/quantified_price_range_presenter.rb +1 -0
  129. data/app/presenters/spree/product_summary_presenter.rb +1 -0
  130. data/app/services/spree/addresses/helper.rb +22 -3
  131. data/app/services/spree/cart/associate.rb +19 -6
  132. data/app/services/spree/checkout/select_shipping_method.rb +13 -1
  133. data/app/services/spree/classifications/reposition.rb +5 -0
  134. data/app/services/spree/data_feeds/google/required_attributes.rb +8 -3
  135. data/app/services/spree/gift_cards/apply.rb +4 -5
  136. data/app/services/spree/imports/row_processors/customer.rb +70 -0
  137. data/app/services/spree/orders/approve.rb +5 -3
  138. data/app/services/spree/orders/cancel.rb +9 -4
  139. data/app/services/spree/products/prepare_nested_attributes.rb +1 -1
  140. data/app/services/spree/sample_data/import_runner.rb +54 -0
  141. data/app/services/spree/sample_data/loader.rb +78 -0
  142. data/app/services/spree/seeds/admin_user.rb +2 -3
  143. data/app/services/spree/seeds/all.rb +1 -0
  144. data/app/services/spree/seeds/api_keys.rb +16 -0
  145. data/app/services/spree/seeds/stores.rb +2 -4
  146. data/app/sorters/spree/orders/sort.rb +4 -0
  147. data/app/subscribers/spree/product_metrics_subscriber.rb +4 -4
  148. data/config/brakeman.ignore +120 -0
  149. data/config/locales/en.yml +20 -5
  150. data/db/migrate/20250923141900_create_spree_user_identities.rb +17 -0
  151. data/db/migrate/20260123000000_create_spree_api_keys.rb +19 -0
  152. data/db/migrate/20260131000000_add_thumbnail_id_to_spree_variants_and_products.rb +9 -0
  153. data/db/migrate/20260213000000_create_spree_payment_sessions.rb +27 -0
  154. data/db/migrate/20260218000000_create_spree_payment_setup_sessions.rb +24 -0
  155. data/db/migrate/20260220000000_create_spree_markets.rb +29 -0
  156. data/db/sample_data/customers.csv +21 -0
  157. data/db/sample_data/metafield_definitions.rb +7 -0
  158. data/db/sample_data/orders.rb +131 -0
  159. data/db/sample_data/payment_methods.rb +17 -0
  160. data/db/sample_data/posts.rb +7 -0
  161. data/db/sample_data/products.csv +1083 -0
  162. data/db/sample_data/promotions.rb +8 -0
  163. data/db/sample_data/shipping_methods.rb +39 -0
  164. data/lib/generators/spree/authentication/devise/devise_generator.rb +2 -2
  165. data/lib/generators/spree/authentication/dummy/dummy_generator.rb +54 -0
  166. data/lib/generators/spree/authentication/dummy/templates/authentication_helpers.rb.tt +52 -0
  167. data/lib/generators/spree/authentication/dummy/templates/create_spree_admin_users.rb.tt +33 -0
  168. data/lib/generators/spree/dummy/dummy_generator.rb +1 -1
  169. data/lib/spree/core/configuration.rb +1 -1
  170. data/lib/spree/core/controller_helpers/common.rb +6 -0
  171. data/lib/spree/core/controller_helpers/currency.rb +5 -0
  172. data/lib/spree/core/controller_helpers/order.rb +5 -1
  173. data/lib/spree/core/controller_helpers/store.rb +1 -1
  174. data/lib/spree/core/dependencies.rb +1 -1
  175. data/lib/spree/core/engine.rb +17 -4
  176. data/lib/spree/core/pricing/context.rb +6 -3
  177. data/lib/spree/core/product_filters.rb +14 -0
  178. data/lib/spree/core/query_filters/comparable.rb +4 -0
  179. data/lib/spree/core/query_filters/text.rb +4 -0
  180. data/lib/spree/core/version.rb +1 -1
  181. data/lib/spree/core.rb +4 -4
  182. data/lib/spree/database_type_utilities.rb +7 -0
  183. data/lib/spree/events.rb +17 -10
  184. data/lib/spree/money.rb +2 -9
  185. data/lib/spree/permitted_attributes.rb +19 -7
  186. data/lib/spree/testing_support/capybara_config.rb +2 -2
  187. data/lib/spree/testing_support/common_rake.rb +15 -4
  188. data/lib/spree/testing_support/factories/api_key_factory.rb +19 -0
  189. data/lib/spree/testing_support/factories/custom_domain_factory.rb +7 -5
  190. data/lib/spree/testing_support/factories/import_factory.rb +12 -0
  191. data/lib/spree/testing_support/factories/market_factory.rb +35 -0
  192. data/lib/spree/testing_support/factories/order_factory.rb +3 -1
  193. data/lib/spree/testing_support/factories/payment_method_factory.rb +2 -0
  194. data/lib/spree/testing_support/factories/payment_session_factory.rb +47 -0
  195. data/lib/spree/testing_support/factories/payment_setup_session_factory.rb +31 -0
  196. data/lib/spree/testing_support/factories/price_rule_factory.rb +10 -0
  197. data/lib/spree/testing_support/factories/user_identity_factory.rb +15 -0
  198. data/lib/spree/testing_support/store.rb +3 -2
  199. data/lib/spree/webhooks.rb +7 -7
  200. data/lib/tasks/images.rake +20 -0
  201. data/lib/tasks/markets.rake +40 -0
  202. data/lib/tasks/sample_data.rake +15 -0
  203. data/spec/fixtures/files/customers_import.csv +4 -0
  204. metadata +88 -63
  205. data/LICENSE.md +0 -57
  206. data/app/finders/spree/stores/find_current.rb +0 -28
  207. data/app/models/spree/custom_domain.rb +0 -59
  208. data/app/presenters/spree/csv/formula_sanitizer.rb +0 -28
  209. data/app/serializers/spree/events/asset_serializer.rb +0 -22
  210. data/app/serializers/spree/events/base_serializer.rb +0 -61
  211. data/app/serializers/spree/events/customer_return_serializer.rb +0 -20
  212. data/app/serializers/spree/events/digital_link_serializer.rb +0 -20
  213. data/app/serializers/spree/events/digital_serializer.rb +0 -18
  214. data/app/serializers/spree/events/export_serializer.rb +0 -22
  215. data/app/serializers/spree/events/gift_card_batch_serializer.rb +0 -24
  216. data/app/serializers/spree/events/gift_card_serializer.rb +0 -29
  217. data/app/serializers/spree/events/image_serializer.rb +0 -9
  218. data/app/serializers/spree/events/import_row_serializer.rb +0 -23
  219. data/app/serializers/spree/events/import_serializer.rb +0 -24
  220. data/app/serializers/spree/events/invitation_serializer.rb +0 -28
  221. data/app/serializers/spree/events/line_item_serializer.rb +0 -31
  222. data/app/serializers/spree/events/newsletter_subscriber_serializer.rb +0 -21
  223. data/app/serializers/spree/events/order_serializer.rb +0 -39
  224. data/app/serializers/spree/events/payment_serializer.rb +0 -24
  225. data/app/serializers/spree/events/post_category_serializer.rb +0 -20
  226. data/app/serializers/spree/events/post_serializer.rb +0 -26
  227. data/app/serializers/spree/events/price_serializer.rb +0 -22
  228. data/app/serializers/spree/events/product_serializer.rb +0 -24
  229. data/app/serializers/spree/events/promotion_serializer.rb +0 -32
  230. data/app/serializers/spree/events/refund_serializer.rb +0 -23
  231. data/app/serializers/spree/events/reimbursement_serializer.rb +0 -22
  232. data/app/serializers/spree/events/report_serializer.rb +0 -23
  233. data/app/serializers/spree/events/return_authorization_serializer.rb +0 -22
  234. data/app/serializers/spree/events/return_item_serializer.rb +0 -27
  235. data/app/serializers/spree/events/shipment_serializer.rb +0 -24
  236. data/app/serializers/spree/events/stock_item_serializer.rb +0 -22
  237. data/app/serializers/spree/events/stock_movement_serializer.rb +0 -22
  238. data/app/serializers/spree/events/stock_transfer_serializer.rb +0 -22
  239. data/app/serializers/spree/events/store_credit_serializer.rb +0 -30
  240. data/app/serializers/spree/events/user_serializer.rb +0 -18
  241. data/app/serializers/spree/events/variant_serializer.rb +0 -34
  242. data/app/serializers/spree/events/wished_item_serializer.rb +0 -20
  243. data/app/serializers/spree/events/wishlist_serializer.rb +0 -22
@@ -0,0 +1,16 @@
1
+ module Spree
2
+ module Seeds
3
+ class ApiKeys
4
+ prepend Spree::ServiceModule::Base
5
+
6
+ def call
7
+ store = Spree::Store.default
8
+ return unless store&.persisted?
9
+
10
+ unless store.api_keys.active.publishable.exists?
11
+ store.api_keys.create!(name: 'Default', key_type: 'publishable')
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -6,9 +6,7 @@ module Spree
6
6
  def call
7
7
  default_store = Spree::Store.default
8
8
 
9
- if default_store.persisted?
10
- default_store.update!(default_country: Spree::Country.find_by(iso: 'US') || Spree::Country.first)
11
- else
9
+ unless default_store.persisted?
12
10
  Spree::Store.new do |s|
13
11
  s.name = 'Shop'
14
12
  s.code = 'shop'
@@ -16,7 +14,7 @@ module Spree
16
14
  s.mail_from_address = 'no-reply@example.com'
17
15
  s.customer_support_email = 'support@example.com'
18
16
  s.default_currency = 'USD'
19
- s.default_country = Spree::Country.find_by(iso: 'US') || Spree::Country.first
17
+ s.default_country_iso = 'US'
20
18
  s.default_locale = I18n.locale
21
19
  end.save!
22
20
  end
@@ -1,6 +1,10 @@
1
1
  module Spree
2
2
  module Orders
3
3
  class Sort < ::Spree::BaseSorter
4
+ def initialize(*args)
5
+ Spree::Deprecation.warn('Spree::Orders::Sort is deprecated and will be removed in Spree 5.5.')
6
+ super
7
+ end
4
8
  end
5
9
  end
6
10
  end
@@ -13,16 +13,16 @@ module Spree
13
13
 
14
14
  def refresh_product_metrics(event)
15
15
  order_id = event.payload['id']
16
- store_id = event.payload['store_id']
17
- return unless order_id && store_id
16
+ return unless order_id
18
17
 
19
- order = Spree::Order.find_by(id: order_id)
18
+ order = Spree::Order.find_by_param(order_id)
20
19
  return unless order
20
+ return unless order.store_id
21
21
 
22
22
  product_ids = order.line_items.includes(:variant).map { |li| li.variant.product_id }.uniq
23
23
  return if product_ids.empty?
24
24
 
25
- jobs = product_ids.map { |product_id| Spree::Products::RefreshMetricsJob.new(product_id, store_id) }
25
+ jobs = product_ids.map { |product_id| Spree::Products::RefreshMetricsJob.new(product_id, order.store_id) }
26
26
  ActiveJob.perform_all_later(jobs)
27
27
  end
28
28
  end
@@ -0,0 +1,120 @@
1
+ {
2
+ "ignored_warnings": [
3
+ {
4
+ "warning_type": "SQL Injection",
5
+ "warning_code": 0,
6
+ "fingerprint": "05bad36b6a70ef61186c5f7152922a518714d5ac67766cebae0c35d0503e8d1a",
7
+ "check_name": "SQL",
8
+ "message": "Possible SQL injection",
9
+ "file": "lib/spree/testing_support/capybara_ext.rb",
10
+ "line": 16,
11
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
12
+ "code": "first(\".icon-#{type}\")",
13
+ "render_path": null,
14
+ "location": {
15
+ "type": "method",
16
+ "class": "CapybaraExt",
17
+ "method": "click_icon"
18
+ },
19
+ "user_input": "type",
20
+ "confidence": "Medium",
21
+ "cwe_id": [
22
+ 89
23
+ ],
24
+ "note": "False positive: this is a Capybara CSS selector, not a SQL query"
25
+ },
26
+ {
27
+ "warning_type": "SQL Injection",
28
+ "warning_code": 0,
29
+ "fingerprint": "0e3bd8868fcc07adb95a529b67bc5729a239a89bda61e44fb8a117930ac22281",
30
+ "check_name": "SQL",
31
+ "message": "Possible SQL injection",
32
+ "file": "app/finders/spree/products/find.rb",
33
+ "line": 349,
34
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
35
+ "code": "scope.joins(:variants_including_master => :prices).select(\"#{Spree::Product.table_name}.* , min(#{Spree::Price.table_name}.amount)\").where(Spree::Price.table_name => ({ :currency => currency })).where.not(Spree::Price.table_name => ({ :amount => nil })).order(\"min(#{Spree::Price.table_name}.amount) #{sort_order}\")",
36
+ "render_path": null,
37
+ "location": {
38
+ "type": "method",
39
+ "class": "Spree::Products::Find",
40
+ "method": "order_by_price"
41
+ },
42
+ "user_input": "sort_order",
43
+ "confidence": "Weak",
44
+ "cwe_id": [
45
+ 89
46
+ ],
47
+ "note": "Safe: sort_order is hardcoded as :desc or :asc at the call site, never from user input"
48
+ },
49
+ {
50
+ "warning_type": "SQL Injection",
51
+ "warning_code": 0,
52
+ "fingerprint": "1365b154e2a8020d32c58a32394892212c8c575676ab0e6c51a379b1485ca38c",
53
+ "check_name": "SQL",
54
+ "message": "Possible SQL injection",
55
+ "file": "app/sorters/spree/products/sort.rb",
56
+ "line": 44,
57
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
58
+ "code": "scope.joins(:master).select(\"#{(\"\" or \"#{Spree::Product.table_name}.*, \")}#{Spree::Variant.table_name}.sku\").order(\"#{Spree::Variant.table_name}.sku #{sort_by?(\"sku\")[1]}\")",
59
+ "render_path": null,
60
+ "location": {
61
+ "type": "method",
62
+ "class": "Spree::Products::Sort",
63
+ "method": "by_sku"
64
+ },
65
+ "user_input": "sort_by?(\"sku\")[1]",
66
+ "confidence": "Weak",
67
+ "cwe_id": [
68
+ 89
69
+ ],
70
+ "note": "Safe: sort direction comes from BaseSorter#order_direction which only returns :desc or :asc"
71
+ },
72
+ {
73
+ "warning_type": "SQL Injection",
74
+ "warning_code": 0,
75
+ "fingerprint": "3f8922e178006ab8f050ffd2636a2aa96241b5d754b4e019e9a1285feae4e57c",
76
+ "check_name": "SQL",
77
+ "message": "Possible SQL injection",
78
+ "file": "app/sorters/spree/classifications/sort.rb",
79
+ "line": 59,
80
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
81
+ "code": "scope.joins(:product => ({ :variants_including_master => :prices })).select(\"#{Spree::Classification.table_name}.*, min(#{Spree::Price.table_name}.amount)\").distinct.where(:spree_prices => ({ :currency => currency })).order(\"min(#{Spree::Price.table_name}.amount) #{sort_by?(\"price\")[1]}\")",
82
+ "render_path": null,
83
+ "location": {
84
+ "type": "method",
85
+ "class": "Spree::Classifications::Sort",
86
+ "method": "by_price"
87
+ },
88
+ "user_input": "sort_by?(\"price\")[1]",
89
+ "confidence": "Weak",
90
+ "cwe_id": [
91
+ 89
92
+ ],
93
+ "note": "Safe: sort direction comes from BaseSorter#order_direction which only returns :desc or :asc"
94
+ },
95
+ {
96
+ "warning_type": "SQL Injection",
97
+ "warning_code": 0,
98
+ "fingerprint": "9d14b5b042473e45257286b5342318871ebe0c907ddbb3808151b5efb3281b36",
99
+ "check_name": "SQL",
100
+ "message": "Possible SQL injection",
101
+ "file": "app/sorters/spree/products/sort.rb",
102
+ "line": 30,
103
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
104
+ "code": "scope.joins(:variants_including_master => :prices).select(\"#{Spree::Product.table_name}.*, #{Spree::Price.table_name}.amount\").distinct.where(:\"#{Spree::Price.table_name}.currency\" => currency).order(\"#{Spree::Price.table_name}.amount #{sort_by?(\"price\")[1]}\")",
105
+ "render_path": null,
106
+ "location": {
107
+ "type": "method",
108
+ "class": "Spree::Products::Sort",
109
+ "method": "by_price"
110
+ },
111
+ "user_input": "sort_by?(\"price\")[1]",
112
+ "confidence": "Weak",
113
+ "cwe_id": [
114
+ 89
115
+ ],
116
+ "note": "Safe: sort direction comes from BaseSorter#order_direction which only returns :desc or :asc"
117
+ }
118
+ ],
119
+ "brakeman_version": "8.0.2"
120
+ }
@@ -292,6 +292,10 @@ en:
292
292
  attributes:
293
293
  currency:
294
294
  must_match_order_currency: Must match order currency
295
+ spree/market_country:
296
+ attributes:
297
+ country:
298
+ not_in_shipping_zone: is not covered by any shipping zone. Please set up a shipping zone first.
295
299
  spree/payment:
296
300
  attributes:
297
301
  amount:
@@ -361,10 +365,6 @@ en:
361
365
  cannot_destroy_if_attached_to_line_items: Cannot delete Variants that are added to placed Orders. In such cases, please discontinue them.
362
366
  must_supply_price_for_variant_or_master: Must supply price for variant or master price for product.
363
367
  no_master_variant_found_to_infer_price: No master variant found to infer price
364
- spree/webhook_endpoint:
365
- attributes:
366
- url:
367
- internal_address_not_allowed: must not point to an internal or private network address
368
368
  spree/wished_item:
369
369
  attributes:
370
370
  variant:
@@ -726,6 +726,8 @@ en:
726
726
  adjustment_total: Adjustment Total
727
727
  adjustments: Adjustments
728
728
  adjustments_deleted: Adjustments Deleted
729
+ admin_locale: Admin locale
730
+ admin_locale_help: The language used for the admin dashboard. If not set, defaults to the application locale.
729
731
  administration: Administration
730
732
  advertise: Advertise
731
733
  agree_to_privacy_policy: Agree to Privacy Policy
@@ -749,9 +751,12 @@ en:
749
751
  and_n_more:
750
752
  one: "...and %{count} more"
751
753
  other: "...and %{count} more"
752
- api_keys: API keys
754
+ api_key: API Key
755
+ api_keys: API Keys
753
756
  apis:
757
+ admin: Admin API
754
758
  platform: Platform API
759
+ store: Store API
755
760
  storefront: Storefront API
756
761
  applied_to: Applied to
757
762
  apply: Apply
@@ -951,6 +956,7 @@ en:
951
956
  credits: Credits
952
957
  currencies: Currencies
953
958
  currency: Currency
959
+ currency_not_supported_by_store: is not supported by this store
954
960
  currency_settings: Currency Settings
955
961
  current: Current
956
962
  current_password: Current password
@@ -1357,6 +1363,9 @@ en:
1357
1363
  manual_adjustments: Manual Adjustments
1358
1364
  manual_intervention_required: Manual intervention required
1359
1365
  mark_as_default: Mark as default
1366
+ market: Market
1367
+ market_ids: Markets
1368
+ markets: Markets
1360
1369
  master: Master
1361
1370
  master_price: Master Price
1362
1371
  master_sku: Master SKU
@@ -1405,6 +1414,7 @@ en:
1405
1414
  new: New
1406
1415
  new_address: New address
1407
1416
  new_adjustment: New Adjustment
1417
+ new_api_key: New API Key
1408
1418
  new_balance: New balance
1409
1419
  new_billing_address: New Billing Address
1410
1420
  new_country: New Country
@@ -1532,6 +1542,7 @@ en:
1532
1542
  notify_me_when_available: Notify me when available
1533
1543
  num_orders: "# Orders"
1534
1544
  number: Number
1545
+ oauth_applications: OAuth Applications
1535
1546
  ok: OK
1536
1547
  on_hand: On Hand
1537
1548
  only_active_products_can_be_added_to_cart: Draft and archived products cannot be added to cart, please mark the product as active before.
@@ -1761,6 +1772,9 @@ en:
1761
1772
  customer_group_rule:
1762
1773
  description: Apply pricing to specific customer groups
1763
1774
  name: Customer Group
1775
+ market_rule:
1776
+ description: Apply pricing based on the market
1777
+ name: Market
1764
1778
  user_rule:
1765
1779
  description: Apply pricing to specific customers
1766
1780
  name: User
@@ -2031,6 +2045,7 @@ en:
2031
2045
  select_an_option: Select an option
2032
2046
  select_existing_address: Select existing address
2033
2047
  select_from_prototype: Select From Prototype
2048
+ select_key_type: Select key type
2034
2049
  select_stock: Select stock
2035
2050
  select_stores: Select Store(s)
2036
2051
  select_user: Select customer
@@ -0,0 +1,17 @@
1
+ class CreateSpreeUserIdentities < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :spree_user_identities do |t|
4
+ t.references :user, polymorphic: true, null: false, index: true
5
+ t.string :provider, null: false
6
+ t.string :uid, null: false
7
+ t.json :info
8
+ t.string :access_token
9
+ t.string :refresh_token
10
+ t.datetime :expires_at
11
+
12
+ t.timestamps
13
+ end
14
+
15
+ add_index :spree_user_identities, [:provider, :uid, :user_type], unique: true, name: 'index_spree_user_identities_on_provider_uid_user_type'
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ class CreateSpreeApiKeys < ActiveRecord::Migration[7.2]
2
+ def change
3
+ create_table :spree_api_keys do |t|
4
+ t.string :name, null: false
5
+ t.string :key_type, null: false
6
+ t.string :token, null: false
7
+ t.references :store, null: false, index: true
8
+ t.references :created_by, null: true, polymorphic: true, index: true
9
+ t.datetime :last_used_at
10
+ t.datetime :revoked_at
11
+ t.references :revoked_by, null: true, polymorphic: true, index: true
12
+ t.timestamps
13
+ end
14
+
15
+ add_index :spree_api_keys, :token, unique: true
16
+ add_index :spree_api_keys, :key_type
17
+ add_index :spree_api_keys, [:store_id, :key_type]
18
+ end
19
+ end
@@ -0,0 +1,9 @@
1
+ class AddThumbnailIdToSpreeVariantsAndProducts < ActiveRecord::Migration[7.2]
2
+ def change
3
+ add_column :spree_variants, :thumbnail_id, :bigint, if_not_exists: true
4
+ add_column :spree_products, :thumbnail_id, :bigint, if_not_exists: true
5
+
6
+ add_index :spree_variants, :thumbnail_id, if_not_exists: true
7
+ add_index :spree_products, :thumbnail_id, if_not_exists: true
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ class CreateSpreePaymentSessions < ActiveRecord::Migration[7.2]
2
+ def change
3
+ create_table :spree_payment_sessions do |t|
4
+ t.string :type, null: false, index: true
5
+ t.references :order, null: false, index: true
6
+ t.references :payment_method, null: false, index: true
7
+ t.references :customer, index: true
8
+ t.decimal :amount, precision: 10, scale: 2, null: false
9
+ t.string :currency, null: false
10
+ t.string :status, null: false, index: true
11
+ t.string :external_id, null: false
12
+ if t.respond_to? :jsonb
13
+ t.jsonb :external_data
14
+ else
15
+ t.json :external_data
16
+ end
17
+ t.datetime :expires_at, index: true
18
+ t.string :customer_external_id
19
+ t.datetime :deleted_at, index: true
20
+ t.timestamps
21
+ end
22
+
23
+ add_index :spree_payment_sessions, [:order_id, :payment_method_id, :external_id],
24
+ unique: true, name: 'idx_payment_sessions_order_method_external'
25
+ add_index :spree_payment_sessions, :external_id
26
+ end
27
+ end
@@ -0,0 +1,24 @@
1
+ class CreateSpreePaymentSetupSessions < ActiveRecord::Migration[7.2]
2
+ def change
3
+ create_table :spree_payment_setup_sessions do |t|
4
+ t.references :customer, index: true
5
+ t.references :payment_method, null: false, index: true
6
+ t.references :payment_source, polymorphic: true, index: { name: 'idx_spree_pss_on_payment_source' }
7
+ t.string :status, null: false
8
+ t.string :external_id
9
+ t.string :external_client_secret
10
+ if t.respond_to? :jsonb
11
+ t.jsonb :external_data
12
+ else
13
+ t.json :external_data
14
+ end
15
+ t.datetime :deleted_at, index: true
16
+ t.timestamps
17
+ end
18
+
19
+ add_index :spree_payment_setup_sessions, :status
20
+ add_index :spree_payment_setup_sessions, [:external_id, :payment_method_id],
21
+ unique: true,
22
+ name: 'idx_spree_pss_unique_external_id_per_pm'
23
+ end
24
+ end
@@ -0,0 +1,29 @@
1
+ class CreateSpreeMarkets < ActiveRecord::Migration[7.2]
2
+ def change
3
+ create_table :spree_markets do |t|
4
+ t.references :store, null: false, foreign_key: false, index: true
5
+ t.string :name, null: false
6
+ t.string :currency, null: false
7
+ t.string :default_locale, null: false
8
+ t.string :supported_locales
9
+ t.boolean :tax_inclusive, null: false, default: false
10
+ t.boolean :default, null: false, default: false
11
+ t.integer :position, null: false, default: 0
12
+ t.timestamps
13
+ t.datetime :deleted_at
14
+ end
15
+
16
+ add_index :spree_markets, [:store_id, :name], unique: true, where: 'deleted_at IS NULL'
17
+ add_index :spree_markets, [:store_id, :default], where: 'deleted_at IS NULL'
18
+ add_index :spree_markets, [:store_id, :position]
19
+ add_index :spree_markets, :deleted_at
20
+
21
+ create_table :spree_market_countries do |t|
22
+ t.references :market, null: false, foreign_key: false
23
+ t.references :country, null: false, foreign_key: false
24
+ t.timestamps
25
+ end
26
+
27
+ add_index :spree_market_countries, [:market_id, :country_id], unique: true
28
+ end
29
+ end
@@ -0,0 +1,21 @@
1
+ email,first_name,last_name,phone,accepts_email_marketing,tags,company,address1,address2,city,province_code,country_code,zip
2
+ sarah.johnson@example.com,Sarah,Johnson,555-0142,yes,"VIP, Returning",,742 Evergreen Terrace,,Springfield,IL,US,62704
3
+ michael.chen@example.com,Michael,Chen,555-0198,yes,Newsletter,,1024 Market Street,Apt 3B,San Francisco,CA,US,94103
4
+ emily.rodriguez@example.com,Emily,Rodriguez,555-0231,no,,,305 Coral Way,,Miami,FL,US,33145
5
+ james.patel@example.com,James,Patel,555-0317,yes,Wholesale,Patel Trading Co.,89 Commerce Drive,Suite 200,Austin,TX,US,78701
6
+ olivia.thompson@example.com,Olivia,Thompson,555-0284,yes,"VIP, Newsletter",,2200 Westlake Avenue,Unit 14,Seattle,WA,US,98101
7
+ william.davis@example.com,William,Davis,555-0156,no,,,456 Oak Boulevard,,Brooklyn,NY,US,11201
8
+ sophia.martinez@example.com,Sophia,Martinez,555-0423,yes,Returning,,1587 Beacon Street,Apt 7,Boston,MA,US,02134
9
+ daniel.wright@example.com,Daniel,Wright,555-0367,yes,"Wholesale, VIP",Wright & Sons LLC,3300 Industrial Parkway,,Denver,CO,US,80205
10
+ charlotte.harris@example.com,Charlotte,Harris,+44 20 7946 0958,yes,Newsletter,,18 Kensington High Street,Flat 2,London,,GB,W8 5NP
11
+ alexander.kim@example.com,Alexander,Kim,555-0512,no,,,910 Magnolia Drive,,Houston,TX,US,77002
12
+ emma.wilson@example.com,Emma,Wilson,+1 416-555-0173,yes,Returning,,250 Queen Street West,Suite 1100,Toronto,ON,CA,M5V 1Z4
13
+ noah.taylor@example.com,Noah,Taylor,555-0289,yes,,,1445 Pearl Street,,Boulder,CO,US,80302
14
+ isabella.anderson@example.com,Isabella,Anderson,555-0634,no,VIP,,78 Fifth Avenue,Floor 3,New York,NY,US,10011
15
+ liam.murphy@example.com,Liam,Murphy,+49 30 12345678,yes,Newsletter,Murphy Imports GmbH,Friedrichstrasse 43,,Berlin,,DE,10117
16
+ ava.clark@example.com,Ava,Clark,555-0471,yes,"Returning, Newsletter",,2901 Wilshire Boulevard,,Los Angeles,CA,US,90010
17
+ ethan.brown@example.com,Ethan,Brown,555-0193,no,,,614 Congress Avenue,Apt 22,Austin,TX,US,78701
18
+ mia.scott@example.com,Mia,Scott,+1 604-555-0248,yes,Wholesale,Pacific Coast Supplies,800 Robson Street,Unit 305,Vancouver,BC,CA,V6Z 3B7
19
+ benjamin.lee@example.com,Benjamin,Lee,555-0385,yes,"VIP, Wholesale",Lee Electronics Inc.,155 North Wacker Drive,Suite 4200,Chicago,IL,US,60606
20
+ harper.white@example.com,Harper,White,+44 161 496 0321,no,,,42 Deansgate,Flat 8,Manchester,,GB,M3 2EG
21
+ lucas.garcia@example.com,Lucas,Garcia,555-0547,yes,Returning,,3720 Spruce Street,,Philadelphia,PA,US,19104
@@ -0,0 +1,7 @@
1
+ %w[manufacturer material fit].each do |key|
2
+ Spree::MetafieldDefinition.find_or_create_by!(
3
+ namespace: 'properties',
4
+ key: key,
5
+ resource_type: 'Spree::Product'
6
+ )
7
+ end
@@ -0,0 +1,131 @@
1
+ store = Spree::Store.default
2
+
3
+ # Find products created by the product import
4
+ product_1 = Spree::Product.find_by(name: 'Denim Shirt')
5
+ product_2 = Spree::Product.find_by(name: 'Checked Shirt')
6
+
7
+ unless product_1 && product_2
8
+ puts ' Skipping orders: required products not found'
9
+ return
10
+ end
11
+
12
+ # Build addresses for orders
13
+ us = Spree::Country.find_by!(iso: 'US')
14
+ ny = us.states.find_by(abbr: 'NY')
15
+
16
+ billing_address = Spree::Address.find_or_create_by!(
17
+ firstname: 'John',
18
+ lastname: 'Doe',
19
+ address1: '7735 Old Georgetown Rd',
20
+ city: 'Bethesda',
21
+ state: ny,
22
+ zipcode: '20814',
23
+ country: us,
24
+ phone: '555-0199'
25
+ )
26
+
27
+ shipping_address = Spree::Address.find_or_create_by!(
28
+ firstname: 'John',
29
+ lastname: 'Doe',
30
+ address1: '1600 Pennsylvania Ave NW',
31
+ city: 'Washington',
32
+ state: ny,
33
+ zipcode: '20500',
34
+ country: us,
35
+ phone: '555-0199'
36
+ )
37
+
38
+ # Create orders
39
+ orders = []
40
+
41
+ orders << store.orders.where(
42
+ number: 'R123456789',
43
+ email: 'spree@example.com',
44
+ currency: 'USD'
45
+ ).first_or_create! do |order|
46
+ order.item_total = product_1.default_variant.amount_in(order.currency)
47
+ order.adjustment_total = product_1.default_variant.amount_in(order.currency)
48
+ order.total = product_1.default_variant.amount_in(order.currency) * 2
49
+ end
50
+
51
+ orders << store.orders.where(
52
+ number: 'R987654321',
53
+ email: 'spree@example.com',
54
+ currency: 'USD'
55
+ ).first_or_create! do |order|
56
+ order.item_total = product_2.default_variant.amount_in(order.currency)
57
+ order.adjustment_total = product_2.default_variant.amount_in(order.currency)
58
+ order.total = product_2.default_variant.amount_in(order.currency) * 2
59
+ order.shipping_address = shipping_address
60
+ order.billing_address = billing_address
61
+ end
62
+
63
+ unless orders[0].line_items.any?
64
+ orders[0].line_items.new(
65
+ variant: product_1.default_variant,
66
+ quantity: 1,
67
+ price: product_1.default_variant.amount_in(orders[0].currency)
68
+ ).save!
69
+ end
70
+
71
+ unless orders[1].line_items.any?
72
+ orders[1].line_items.new(
73
+ variant: product_2.default_variant,
74
+ quantity: 1,
75
+ price: product_2.default_variant.amount_in(orders[1].currency)
76
+ ).save!
77
+ end
78
+
79
+ orders.each(&:create_proposed_shipments)
80
+
81
+ Spree::Order.where(id: orders.map(&:id)).update_all(state: :complete, completed_at: Time.current - 1.day)
82
+
83
+ # Adjustments (tax)
84
+ tax_rate = Spree::TaxRate.find_by(name: 'California')
85
+
86
+ if tax_rate
87
+ orders.each do |order|
88
+ order.all_adjustments.where(
89
+ adjustable: order,
90
+ source: tax_rate,
91
+ label: 'Tax',
92
+ state: 'open',
93
+ mandatory: true
94
+ ).first_or_create! do |adj|
95
+ adj.amount = 0
96
+ end
97
+ end
98
+ end
99
+
100
+ # Payments
101
+ method = Spree::PaymentMethod.where(name: 'Credit Card', active: true).first
102
+
103
+ if method
104
+ Spree::Gateway.class_eval do
105
+ def self.current
106
+ Spree::Gateway::Bogus.new
107
+ end
108
+ end
109
+
110
+ credit_card = Spree::CreditCard.find_or_initialize_by(gateway_customer_profile_id: 'BGS-1234')
111
+ credit_card.cc_type = 'visa'
112
+ credit_card.month = 12
113
+ credit_card.year = 2.years.from_now.year
114
+ credit_card.last_digits = '1111'
115
+ credit_card.name = 'Sean Schofield'
116
+ credit_card.save!
117
+
118
+ orders.each do |order|
119
+ order.update_with_updater!
120
+ payment = order.payments.where(
121
+ amount: BigDecimal(order.total, 4),
122
+ source: credit_card.clone,
123
+ payment_method: method
124
+ ).first_or_create!
125
+ payment.update_columns(state: 'pending', response_code: '12345')
126
+ end
127
+ end
128
+
129
+ # Reimbursement
130
+ first_complete_order = Spree::Order.complete.first
131
+ Spree::Reimbursement.create(order: first_complete_order) if first_complete_order
@@ -0,0 +1,17 @@
1
+ cc_payment_method = Spree::Gateway::Bogus.where(
2
+ name: 'Credit Card',
3
+ description: 'Bogus payment gateway.',
4
+ active: true
5
+ ).first_or_initialize
6
+
7
+ cc_payment_method.stores = Spree::Store.all
8
+ cc_payment_method.save!
9
+
10
+ check_payment_method = Spree::PaymentMethod::Check.where(
11
+ name: 'Check',
12
+ description: 'Pay by check.',
13
+ active: true
14
+ ).first_or_initialize
15
+
16
+ check_payment_method.stores = Spree::Store.all
17
+ check_payment_method.save!
@@ -0,0 +1,7 @@
1
+ store = Spree::Store.default
2
+
3
+ store.posts.where(title: 'Hello World').first_or_create!(
4
+ content: 'This is a test post',
5
+ published_at: Time.current,
6
+ author: Spree.admin_user_class.first
7
+ )