spree_core 5.6.1 → 6.0.0.beta2

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 (1602) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +30 -0
  3. data/README.md +2 -3
  4. data/app/finders/spree/line_items/find_by_variant.rb +5 -3
  5. data/app/finders/spree/sellers/panel_url.rb +47 -0
  6. data/app/finders/spree/stores/dashboard_url.rb +76 -0
  7. data/app/helpers/spree/images_helper.rb +1 -1
  8. data/app/jobs/spree/carts/reap_expired_job.rb +43 -0
  9. data/app/jobs/spree/collections/regenerate_time_based_job.rb +18 -0
  10. data/app/jobs/spree/data_requests/process_job.rb +42 -0
  11. data/app/jobs/spree/events/subscriber_job.rb +1 -1
  12. data/app/jobs/spree/images/migrate_product_media_job.rb +80 -0
  13. data/app/jobs/spree/images/save_from_url_job.rb +70 -13
  14. data/app/jobs/spree/imports/create_categories_job.rb +23 -14
  15. data/app/jobs/spree/imports/create_rows_job.rb +3 -62
  16. data/app/jobs/spree/imports/process_group_job.rb +1 -1
  17. data/app/jobs/spree/imports/process_job.rb +164 -0
  18. data/app/jobs/spree/imports/process_rows_job.rb +4 -71
  19. data/app/jobs/spree/orders/finalize_stale_drafts_job.rb +29 -0
  20. data/app/jobs/spree/payments/handle_webhook_job.rb +1 -1
  21. data/app/jobs/spree/price_lists/sync_currencies_job.rb +42 -0
  22. data/app/jobs/spree/product_types/apply_to_products_job.rb +74 -0
  23. data/app/jobs/spree/products/auto_match_collections_job.rb +14 -0
  24. data/app/jobs/spree/products/auto_match_taxons_job.rb +6 -7
  25. data/app/jobs/spree/products/refresh_metrics_job.rb +1 -1
  26. data/app/jobs/spree/products/touch_categories_job.rb +15 -0
  27. data/app/jobs/spree/products/touch_taxons_job.rb +7 -6
  28. data/app/jobs/spree/sample_data/load_job.rb +13 -0
  29. data/app/jobs/spree/seller_payouts/sweep_due_job.rb +57 -0
  30. data/app/jobs/spree/seller_payouts/sweep_seller_job.rb +70 -0
  31. data/app/jobs/spree/seller_transfers/execute_pending_due_job.rb +56 -0
  32. data/app/jobs/spree/seller_transfers/execute_pending_job.rb +52 -0
  33. data/app/jobs/spree/shipping_labels/store_file_job.rb +17 -0
  34. data/app/jobs/spree/stock_locations/stock_items/create_job.rb +7 -5
  35. data/app/jobs/spree/stock_locations/stock_levels/create_job.rb +13 -0
  36. data/app/jobs/spree/stock_reservations/expire_job.rb +1 -1
  37. data/app/jobs/spree/tax_identifiers/validate_job.rb +14 -0
  38. data/app/jobs/spree/variants/remove_line_item_job.rb +29 -1
  39. data/app/mailers/spree/admin_user_mailer.rb +6 -35
  40. data/app/mailers/spree/base_mailer.rb +1 -20
  41. data/app/mailers/spree/invitation_mailer.rb +1 -1
  42. data/app/mailers/spree/seller_user_mailer.rb +47 -0
  43. data/app/models/concerns/spree/account_lockout.rb +38 -0
  44. data/app/models/concerns/spree/acted_by.rb +210 -0
  45. data/app/models/concerns/spree/actor.rb +51 -0
  46. data/app/models/concerns/spree/admin_user_methods.rb +53 -42
  47. data/app/models/concerns/spree/calculated_adjustments.rb +8 -14
  48. data/app/models/concerns/spree/calculator/currency_amounts.rb +43 -0
  49. data/app/models/concerns/spree/capture_method.rb +33 -0
  50. data/app/models/concerns/spree/custom_field_filterable.rb +163 -0
  51. data/app/models/concerns/spree/customer_methods.rb +421 -0
  52. data/app/models/concerns/spree/deprecated_customer_alias.rb +22 -0
  53. data/app/models/concerns/spree/derived_number.rb +66 -0
  54. data/app/models/concerns/spree/has_address_book.rb +89 -0
  55. data/app/models/concerns/spree/has_custom_fields.rb +360 -0
  56. data/app/models/concerns/spree/has_external_references.rb +95 -0
  57. data/app/models/concerns/spree/has_iso_geography.rb +71 -0
  58. data/app/models/concerns/spree/has_library_media.rb +94 -0
  59. data/app/models/concerns/spree/has_list_position.rb +15 -0
  60. data/app/models/concerns/spree/has_number.rb +139 -0
  61. data/app/models/concerns/spree/has_status.rb +76 -0
  62. data/app/models/concerns/spree/has_tracking_carrier.rb +18 -0
  63. data/app/models/concerns/spree/instruments_gateway_calls.rb +20 -0
  64. data/app/models/concerns/spree/integration_backed_provider.rb +89 -0
  65. data/app/models/concerns/spree/integrations_concern.rb +15 -2
  66. data/app/models/concerns/spree/label_translatable.rb +37 -0
  67. data/app/models/concerns/spree/marketplace/order_group.rb +35 -0
  68. data/app/models/concerns/spree/metadata.rb +18 -22
  69. data/app/models/concerns/spree/named_type.rb +11 -1
  70. data/app/models/concerns/spree/parameterizable_name.rb +5 -5
  71. data/app/models/concerns/spree/password_policy.rb +37 -0
  72. data/app/models/concerns/spree/payment_session_transitions.rb +93 -0
  73. data/app/models/concerns/spree/payment_source_concern.rb +1 -1
  74. data/app/models/concerns/spree/personal_data_matching.rb +120 -0
  75. data/app/models/concerns/spree/preference_schema.rb +120 -19
  76. data/app/models/concerns/spree/prefixed_id.rb +25 -3
  77. data/app/models/concerns/spree/presentation_translatable.rb +4 -37
  78. data/app/models/concerns/spree/product_scopes.rb +51 -191
  79. data/app/models/concerns/spree/provider_failure_policy.rb +44 -0
  80. data/app/models/concerns/spree/publishable.rb +7 -7
  81. data/app/models/concerns/spree/purchase/addresses.rb +258 -0
  82. data/app/models/concerns/spree/purchase/channel.rb +19 -0
  83. data/app/models/concerns/spree/purchase/checkout_steps.rb +68 -0
  84. data/app/models/concerns/spree/purchase/company.rb +96 -0
  85. data/app/models/concerns/spree/purchase/currency.rb +29 -0
  86. data/app/models/concerns/spree/purchase/digital_items.rb +60 -0
  87. data/app/models/concerns/spree/purchase/freight.rb +52 -0
  88. data/app/models/concerns/spree/purchase/gift_cards.rb +70 -0
  89. data/app/models/concerns/spree/purchase/lifecycle.rb +53 -0
  90. data/app/models/concerns/spree/purchase/line_item_currencies.rb +38 -0
  91. data/app/models/concerns/spree/purchase/line_item_lookup.rb +25 -0
  92. data/app/models/concerns/spree/purchase/locale.rb +30 -0
  93. data/app/models/concerns/spree/purchase/market.rb +29 -0
  94. data/app/models/concerns/spree/purchase/payment_processing.rb +93 -0
  95. data/app/models/concerns/spree/purchase/purchase_order.rb +94 -0
  96. data/app/models/concerns/spree/purchase/quantity_rules.rb +136 -0
  97. data/app/models/concerns/spree/purchase/store_credits.rb +100 -0
  98. data/app/models/concerns/spree/purchase/taxation.rb +146 -0
  99. data/app/models/concerns/spree/purchase/totals.rb +116 -0
  100. data/app/models/concerns/spree/purchase/validations.rb +45 -0
  101. data/app/models/concerns/spree/receivable.rb +103 -0
  102. data/app/models/concerns/spree/receivable_item.rb +78 -0
  103. data/app/models/concerns/spree/refund_methods.rb +19 -0
  104. data/app/models/concerns/spree/sanitizable_rich_text.rb +109 -0
  105. data/app/models/concerns/spree/search_indexable.rb +5 -2
  106. data/app/models/concerns/spree/single_store_resource.rb +3 -1
  107. data/app/models/concerns/spree/store_data_sources.rb +75 -0
  108. data/app/models/concerns/spree/store_preferences.rb +49 -0
  109. data/app/models/concerns/spree/stores/markets.rb +75 -28
  110. data/app/models/concerns/spree/stores/setup.rb +10 -0
  111. data/app/models/concerns/spree/translatable_resource.rb +25 -6
  112. data/app/models/concerns/spree/typed_adjustment_line.rb +55 -0
  113. data/app/models/concerns/spree/user_address.rb +13 -3
  114. data/app/models/concerns/spree/user_management.rb +18 -6
  115. data/app/models/concerns/spree/user_methods.rb +5 -330
  116. data/app/models/concerns/spree/user_payment_source.rb +1 -1
  117. data/app/models/concerns/spree/user_roles.rb +18 -11
  118. data/app/models/concerns/spree/validates_store_uniqueness.rb +53 -0
  119. data/app/models/concerns/spree/vat_price_calculation.rb +58 -6
  120. data/app/models/concerns/spree/webhook_payload_redaction.rb +1 -1
  121. data/app/models/spree/ability.rb +147 -43
  122. data/app/models/spree/address.rb +387 -118
  123. data/app/models/spree/adjusters/base.rb +26 -0
  124. data/app/models/spree/adjusters/largest_remainder.rb +24 -0
  125. data/app/models/spree/adjusters/promotion.rb +253 -0
  126. data/app/models/spree/admin_user.rb +26 -0
  127. data/app/models/spree/allowed_origin.rb +1 -1
  128. data/app/models/spree/api_key.rb +34 -31
  129. data/app/models/spree/asset.rb +14 -211
  130. data/app/models/spree/authentication/strategies/base_strategy.rb +54 -3
  131. data/app/models/spree/authentication/strategies/email_password_strategy.rb +11 -3
  132. data/app/models/spree/authentication/strategies/oidc_strategy.rb +330 -0
  133. data/app/models/spree/authentication/strategy_registry.rb +83 -0
  134. data/app/models/spree/base.rb +83 -12
  135. data/app/models/spree/base_analytics_event_handler.rb +1 -1
  136. data/app/models/spree/calculator/shipping/digital_delivery.rb +5 -2
  137. data/app/models/spree/calculator/shipping/flat_rate.rb +10 -5
  138. data/app/models/spree/calculator/shipping/flexi_rate.rb +6 -0
  139. data/app/models/spree/calculator/shipping/per_item.rb +8 -3
  140. data/app/models/spree/calculator/shipping/price_sack.rb +6 -0
  141. data/app/models/spree/calculator/tiered_flat_rate.rb +5 -1
  142. data/app/models/spree/calculator.rb +10 -0
  143. data/app/models/spree/cart.rb +285 -0
  144. data/app/models/spree/carts/item_warning.rb +28 -0
  145. data/app/models/spree/carts/resolved_item.rb +37 -0
  146. data/app/models/spree/catalog.rb +503 -0
  147. data/app/models/spree/catalog_assignment.rb +41 -0
  148. data/app/models/spree/catalog_order_minimum.rb +26 -0
  149. data/app/models/spree/catalog_price.rb +100 -0
  150. data/app/models/spree/catalog_price_tier.rb +36 -0
  151. data/app/models/spree/catalog_product.rb +23 -0
  152. data/app/models/spree/catalog_quantity_rule.rb +46 -0
  153. data/app/models/spree/catalogs/product_term.rb +43 -0
  154. data/app/models/spree/category.rb +430 -12
  155. data/app/models/spree/channel/gating.rb +1 -2
  156. data/app/models/spree/channel.rb +38 -4
  157. data/app/models/spree/channel_stock_location.rb +8 -0
  158. data/app/models/spree/claim.rb +69 -0
  159. data/app/models/spree/claim_line_item.rb +46 -0
  160. data/app/models/spree/claim_reason.rb +24 -0
  161. data/app/models/spree/classification.rb +7 -49
  162. data/app/models/spree/collection.rb +269 -0
  163. data/app/models/spree/collection_rule.rb +58 -0
  164. data/app/models/spree/collection_rules/available_on.rb +21 -0
  165. data/app/models/spree/collection_rules/sale.rb +18 -0
  166. data/app/models/spree/collection_rules/tag.rb +21 -0
  167. data/app/models/spree/commission_line.rb +85 -0
  168. data/app/models/spree/commission_rate.rb +370 -0
  169. data/app/models/spree/commission_rate_value.rb +47 -0
  170. data/app/models/spree/commission_rule.rb +77 -0
  171. data/app/models/spree/commission_rule_product.rb +19 -0
  172. data/app/models/spree/commission_rules/category_rule.rb +33 -0
  173. data/app/models/spree/commission_rules/item_total_rule.rb +31 -0
  174. data/app/models/spree/commission_rules/product_rule.rb +55 -0
  175. data/app/models/spree/commission_rules/seller_rule.rb +33 -0
  176. data/app/models/spree/commission_tax.rb +51 -0
  177. data/app/models/spree/commissions/context.rb +71 -0
  178. data/app/models/spree/company.rb +347 -0
  179. data/app/models/spree/company_invitation.rb +81 -0
  180. data/app/models/spree/company_membership.rb +25 -0
  181. data/app/models/spree/consent_record.rb +125 -0
  182. data/app/models/spree/country.rb +128 -52
  183. data/app/models/spree/coupon_code.rb +18 -5
  184. data/app/models/spree/credit_card.rb +10 -9
  185. data/app/models/spree/current.rb +152 -18
  186. data/app/models/spree/custom_field.rb +160 -7
  187. data/app/models/spree/custom_field_definition/search_capabilities.rb +98 -0
  188. data/app/models/spree/custom_field_definition.rb +219 -5
  189. data/app/models/spree/custom_fields/boolean.rb +15 -0
  190. data/app/models/spree/custom_fields/json.rb +38 -0
  191. data/app/models/spree/custom_fields/long_text.rb +11 -0
  192. data/app/models/spree/custom_fields/number.rb +23 -0
  193. data/app/models/spree/custom_fields/rich_text.rb +23 -0
  194. data/app/models/spree/custom_fields/short_text.rb +15 -0
  195. data/app/models/spree/customer.rb +34 -0
  196. data/app/models/spree/customer_group.rb +12 -12
  197. data/app/models/spree/customer_group_user.rb +6 -4
  198. data/app/models/spree/data_feed.rb +1 -1
  199. data/app/models/spree/data_request.rb +98 -0
  200. data/app/models/spree/delivery.rb +169 -0
  201. data/app/models/spree/delivery_method.rb +566 -0
  202. data/app/models/spree/delivery_method_rule.rb +55 -0
  203. data/app/models/spree/delivery_method_rule_product.rb +8 -0
  204. data/app/models/spree/delivery_method_rules/channel_rule.rb +41 -0
  205. data/app/models/spree/delivery_method_rules/company_rule.rb +24 -0
  206. data/app/models/spree/delivery_method_rules/excluded_products_rule.rb +48 -0
  207. data/app/models/spree/delivery_method_rules/item_total_rule.rb +19 -0
  208. data/app/models/spree/delivery_method_rules/volume_rule.rb +35 -0
  209. data/app/models/spree/delivery_method_rules/weight_rule.rb +19 -0
  210. data/app/models/spree/delivery_method_service.rb +24 -0
  211. data/app/models/spree/delivery_method_stock_location.rb +11 -0
  212. data/app/models/spree/delivery_origin_group.rb +73 -0
  213. data/app/models/spree/delivery_origin_group_location.rb +9 -0
  214. data/app/models/spree/delivery_profile.rb +141 -0
  215. data/app/models/spree/delivery_profiles/digital.rb +20 -0
  216. data/app/models/spree/delivery_profiles/shipping.rb +12 -0
  217. data/app/models/spree/delivery_rate.rb +164 -0
  218. data/app/models/spree/delivery_rate_provider/base.rb +120 -0
  219. data/app/models/spree/delivery_rate_provider/estimate.rb +44 -0
  220. data/app/models/spree/delivery_rate_provider/freight.rb +41 -0
  221. data/app/models/spree/delivery_rate_provider/internal.rb +28 -0
  222. data/app/models/spree/delivery_rate_provider/service_catalog.rb +48 -0
  223. data/app/models/spree/delivery_zone.rb +64 -0
  224. data/app/models/spree/delivery_zone_member.rb +98 -0
  225. data/app/models/spree/digital.rb +12 -16
  226. data/app/models/spree/digital_asset.rb +144 -0
  227. data/app/models/spree/digital_asset_provider/base.rb +95 -0
  228. data/app/models/spree/digital_asset_provider/file.rb +20 -0
  229. data/app/models/spree/digital_delivery.rb +28 -0
  230. data/app/models/spree/digital_link.rb +31 -11
  231. data/app/models/spree/discount.rb +51 -0
  232. data/app/models/spree/event.rb +6 -6
  233. data/app/models/spree/exchange.rb +50 -44
  234. data/app/models/spree/exchange_line_item.rb +52 -0
  235. data/app/models/spree/export.rb +128 -21
  236. data/app/models/spree/exports/customers.rb +2 -2
  237. data/app/models/spree/exports/gift_cards.rb +2 -2
  238. data/app/models/spree/exports/newsletter_subscribers.rb +2 -2
  239. data/app/models/spree/exports/orders.rb +35 -5
  240. data/app/models/spree/exports/price_list_prices.rb +107 -0
  241. data/app/models/spree/exports/products.rb +4 -4
  242. data/app/models/spree/exports/purchase_orders.rb +39 -0
  243. data/app/models/spree/exports/report.rb +95 -0
  244. data/app/models/spree/external_reference.rb +77 -0
  245. data/app/models/spree/external_video.rb +117 -0
  246. data/app/models/spree/fee.rb +40 -0
  247. data/app/models/spree/freight_summary/line.rb +257 -0
  248. data/app/models/spree/freight_summary.rb +180 -0
  249. data/app/models/spree/fulfillment/custom_events.rb +96 -0
  250. data/app/models/spree/fulfillment.rb +973 -0
  251. data/app/models/spree/fulfillment_changer.rb +170 -0
  252. data/app/models/spree/fulfillment_item.rb +148 -0
  253. data/app/models/spree/fulfillment_provider/base.rb +130 -0
  254. data/app/models/spree/fulfillment_provider/digital.rb +44 -0
  255. data/app/models/spree/fulfillment_provider/manual.rb +15 -0
  256. data/app/models/spree/fulfillment_provider/pickup.rb +38 -0
  257. data/app/models/spree/fulfillment_provider/pickup_point.rb +24 -0
  258. data/app/models/spree/fulfilment_changer.rb +3 -164
  259. data/app/models/spree/gateway/bogus.rb +5 -4
  260. data/app/models/spree/gateway/custom_payment_source_method.rb +5 -5
  261. data/app/models/spree/gateway.rb +2 -2
  262. data/app/models/spree/gateway_customer.rb +12 -4
  263. data/app/models/spree/gift_card.rb +140 -48
  264. data/app/models/spree/gift_card_batch.rb +2 -2
  265. data/app/models/spree/import.rb +136 -98
  266. data/app/models/spree/import_mapping.rb +1 -1
  267. data/app/models/spree/import_row.rb +35 -31
  268. data/app/models/spree/import_schemas/price_list_prices.rb +13 -0
  269. data/app/models/spree/import_schemas/products.rb +8 -1
  270. data/app/models/spree/import_schemas/purchase_orders.rb +19 -0
  271. data/app/models/spree/imports/price_list_prices.rb +72 -0
  272. data/app/models/spree/imports/purchase_orders.rb +28 -0
  273. data/app/models/spree/integration.rb +128 -5
  274. data/app/models/spree/inventory_provider/base.rb +30 -0
  275. data/app/models/spree/inventory_provider/internal.rb +22 -0
  276. data/app/models/spree/inventory_unit.rb +3 -139
  277. data/app/models/spree/invitation.rb +53 -47
  278. data/app/models/spree/label_purchase.rb +29 -0
  279. data/app/models/spree/line_item.rb +240 -106
  280. data/app/models/spree/market.rb +106 -15
  281. data/app/models/spree/market_country.rb +10 -5
  282. data/app/models/spree/media.rb +497 -0
  283. data/app/models/spree/media_usage_reference.rb +27 -0
  284. data/app/models/spree/metafield.rb +14 -102
  285. data/app/models/spree/metafield_definition.rb +11 -128
  286. data/app/models/spree/metafields.rb +32 -0
  287. data/app/models/spree/newsletter_subscriber.rb +10 -9
  288. data/app/models/spree/number_generators/base.rb +56 -0
  289. data/app/models/spree/number_generators/random.rb +23 -0
  290. data/app/models/spree/number_generators/sequential.rb +88 -0
  291. data/app/models/spree/number_sequence.rb +86 -0
  292. data/app/models/spree/option_type.rb +18 -32
  293. data/app/models/spree/option_type_product_type.rb +8 -0
  294. data/app/models/spree/option_value.rb +19 -13
  295. data/app/models/spree/option_value_variant.rb +0 -1
  296. data/app/models/spree/order.rb +681 -576
  297. data/app/models/spree/order_cancellation_reason.rb +25 -0
  298. data/app/models/spree/order_group.rb +244 -0
  299. data/app/models/spree/order_inventory.rb +42 -33
  300. data/app/models/spree/order_merger.rb +11 -6
  301. data/app/models/spree/order_promotion.rb +32 -6
  302. data/app/models/spree/order_routing/has_strategy_preference.rb +1 -2
  303. data/app/models/spree/order_routing/rules/minimize_splits.rb +6 -6
  304. data/app/models/spree/order_routing/strategy/rules.rb +12 -8
  305. data/app/models/spree/order_routing_rule.rb +5 -15
  306. data/app/models/spree/order_updater.rb +131 -163
  307. data/app/models/spree/package_type.rb +191 -0
  308. data/app/models/spree/payment/custom_events.rb +52 -5
  309. data/app/models/spree/payment/gateway_options.rb +20 -5
  310. data/app/models/spree/payment/processing.rb +95 -116
  311. data/app/models/spree/payment.rb +299 -123
  312. data/app/models/spree/payment_method/check.rb +4 -3
  313. data/app/models/spree/payment_method/session_instrumentation.rb +34 -0
  314. data/app/models/spree/payment_method/store_credit.rb +4 -2
  315. data/app/models/spree/payment_method.rb +106 -9
  316. data/app/models/spree/payment_session.rb +150 -53
  317. data/app/models/spree/payment_setup_session.rb +4 -37
  318. data/app/models/spree/payment_source.rb +5 -4
  319. data/app/models/spree/payment_split.rb +90 -0
  320. data/app/models/spree/payout_provider/base.rb +218 -0
  321. data/app/models/spree/payout_provider/system.rb +36 -0
  322. data/app/models/spree/permission_sets.rb +17 -0
  323. data/app/models/spree/pickup_point_option.rb +28 -0
  324. data/app/models/spree/pickup_point_provider/base.rb +24 -0
  325. data/app/models/spree/policy.rb +12 -11
  326. data/app/models/spree/price.rb +91 -5
  327. data/app/models/spree/price_adjustment_tier.rb +63 -0
  328. data/app/models/spree/price_history.rb +1 -1
  329. data/app/models/spree/price_list.rb +266 -142
  330. data/app/models/spree/price_rule.rb +51 -7
  331. data/app/models/spree/price_rules/channel_rule.rb +3 -0
  332. data/app/models/spree/price_rules/customer_group_rule.rb +10 -1
  333. data/app/models/spree/price_rules/market_rule.rb +6 -0
  334. data/app/models/spree/price_rules/user_rule.rb +12 -3
  335. data/app/models/spree/price_rules/volume_rule.rb +6 -0
  336. data/app/models/spree/price_rules/zone_rule.rb +5 -13
  337. data/app/models/spree/pricing_provider/base.rb +51 -0
  338. data/app/models/spree/pricing_provider/internal.rb +277 -0
  339. data/app/models/spree/pricing_provider.rb +28 -0
  340. data/app/models/spree/product.rb +528 -544
  341. data/app/models/spree/product_category.rb +65 -0
  342. data/app/models/spree/product_collection.rb +20 -0
  343. data/app/models/spree/product_option_type.rb +0 -1
  344. data/app/models/spree/product_promotion_rule.rb +0 -1
  345. data/app/models/spree/product_publication.rb +0 -1
  346. data/app/models/spree/product_submission.rb +72 -0
  347. data/app/models/spree/product_type.rb +116 -0
  348. data/app/models/spree/product_type_category.rb +8 -0
  349. data/app/models/spree/product_type_custom_field_definition.rb +39 -0
  350. data/app/models/spree/promotion/actions/create_adjustment.rb +9 -7
  351. data/app/models/spree/promotion/actions/create_item_adjustments.rb +11 -16
  352. data/app/models/spree/promotion/actions/create_line_items.rb +19 -8
  353. data/app/models/spree/promotion/actions/free_shipping.rb +12 -18
  354. data/app/models/spree/promotion/rules/category.rb +181 -0
  355. data/app/models/spree/promotion/rules/channel.rb +3 -3
  356. data/app/models/spree/promotion/rules/country.rb +43 -17
  357. data/app/models/spree/promotion/rules/currency.rb +2 -2
  358. data/app/models/spree/promotion/rules/customer_group.rb +13 -5
  359. data/app/models/spree/promotion/rules/first_order.rb +3 -3
  360. data/app/models/spree/promotion/rules/item_total.rb +2 -2
  361. data/app/models/spree/promotion/rules/market.rb +3 -3
  362. data/app/models/spree/promotion/rules/one_use_per_user.rb +4 -4
  363. data/app/models/spree/promotion/rules/option_value.rb +34 -11
  364. data/app/models/spree/promotion/rules/product.rb +3 -5
  365. data/app/models/spree/promotion/rules/taxon.rb +10 -131
  366. data/app/models/spree/promotion/rules/user.rb +14 -22
  367. data/app/models/spree/promotion/rules/user_logged_in.rb +3 -3
  368. data/app/models/spree/promotion.rb +59 -21
  369. data/app/models/spree/promotion_action.rb +52 -11
  370. data/app/models/spree/promotion_action_line_item.rb +1 -1
  371. data/app/models/spree/promotion_handler/coupon.rb +44 -16
  372. data/app/models/spree/promotion_handler/free_shipping.rb +1 -1
  373. data/app/models/spree/promotion_handler/promotion_duplicator.rb +1 -1
  374. data/app/models/spree/promotion_rule.rb +2 -9
  375. data/app/models/spree/promotion_rule_category.rb +22 -0
  376. data/app/models/spree/promotion_rule_taxon.rb +7 -6
  377. data/app/models/spree/promotion_rule_user.rb +2 -2
  378. data/app/models/spree/prototype.rb +3 -13
  379. data/app/models/spree/purchase_order.rb +95 -0
  380. data/app/models/spree/purchase_order_item.rb +40 -0
  381. data/app/models/spree/quantity_rule.rb +114 -0
  382. data/app/models/spree/refresh_token.rb +20 -2
  383. data/app/models/spree/refund.rb +96 -42
  384. data/app/models/spree/refund_reason.rb +32 -11
  385. data/app/models/spree/return.rb +151 -0
  386. data/app/models/spree/return_authorization_reason.rb +11 -6
  387. data/app/models/spree/return_line_item.rb +42 -0
  388. data/app/models/spree/return_reason.rb +26 -0
  389. data/app/models/spree/rich_text_sanitizer.rb +99 -0
  390. data/app/models/spree/role.rb +179 -4
  391. data/app/models/spree/role_user.rb +5 -21
  392. data/app/models/spree/saved_report.rb +56 -0
  393. data/app/models/spree/search_provider/base.rb +8 -2
  394. data/app/models/spree/search_provider/database.rb +73 -22
  395. data/app/models/spree/search_provider.rb +29 -0
  396. data/app/models/spree/seller.rb +475 -0
  397. data/app/models/spree/seller_balance.rb +86 -0
  398. data/app/models/spree/seller_payout.rb +116 -0
  399. data/app/models/spree/seller_requirement.rb +274 -0
  400. data/app/models/spree/seller_requirement_custom_field.rb +38 -0
  401. data/app/models/spree/seller_requirement_status.rb +144 -0
  402. data/app/models/spree/seller_requirement_submission.rb +91 -0
  403. data/app/models/spree/seller_requirements/accept_terms.rb +104 -0
  404. data/app/models/spree/seller_requirements/attestation.rb +22 -0
  405. data/app/models/spree/seller_requirements/billing_address.rb +13 -0
  406. data/app/models/spree/seller_requirements/complete_profile.rb +26 -0
  407. data/app/models/spree/seller_requirements/delivery_method.rb +20 -0
  408. data/app/models/spree/seller_requirements/document.rb +62 -0
  409. data/app/models/spree/seller_requirements/minimum_products.rb +20 -0
  410. data/app/models/spree/seller_requirements/operator_review.rb +23 -0
  411. data/app/models/spree/seller_requirements/package_type.rb +40 -0
  412. data/app/models/spree/seller_requirements/payout_account.rb +55 -0
  413. data/app/models/spree/seller_requirements/policy.rb +43 -0
  414. data/app/models/spree/seller_requirements/required_custom_fields.rb +56 -0
  415. data/app/models/spree/seller_requirements/returns_address.rb +19 -0
  416. data/app/models/spree/seller_transfer.rb +166 -0
  417. data/app/models/spree/setup_tasks.rb +3 -6
  418. data/app/models/spree/shipment.rb +3 -560
  419. data/app/models/spree/shipping_calculator.rb +7 -0
  420. data/app/models/spree/shipping_document.rb +32 -0
  421. data/app/models/spree/shipping_label.rb +146 -0
  422. data/app/models/spree/shipping_method.rb +3 -146
  423. data/app/models/spree/shipping_rate.rb +3 -97
  424. data/app/models/spree/state.rb +57 -23
  425. data/app/models/spree/stock/availability_validator.rb +1 -1
  426. data/app/models/spree/stock/content_item.rb +1 -0
  427. data/app/models/spree/stock/coordinator.rb +69 -9
  428. data/app/models/spree/stock/estimator.rb +198 -33
  429. data/app/models/spree/stock/inventory_unit_builder.rb +6 -1
  430. data/app/models/spree/stock/package.rb +145 -14
  431. data/app/models/spree/stock/packer.rb +20 -3
  432. data/app/models/spree/stock/prioritizer.rb +27 -4
  433. data/app/models/spree/stock/quantifier.rb +63 -38
  434. data/app/models/spree/stock/splitter/base.rb +3 -1
  435. data/app/models/spree/stock/splitter/delivery_profile.rb +41 -0
  436. data/app/models/spree/stock_item.rb +3 -147
  437. data/app/models/spree/stock_level/custom_events.rb +48 -0
  438. data/app/models/spree/stock_level.rb +305 -0
  439. data/app/models/spree/stock_location.rb +165 -87
  440. data/app/models/spree/stock_movement/custom_events.rb +1 -1
  441. data/app/models/spree/stock_movement.rb +166 -22
  442. data/app/models/spree/stock_receipt.rb +61 -0
  443. data/app/models/spree/stock_receipt_item.rb +35 -0
  444. data/app/models/spree/stock_reservation.rb +114 -11
  445. data/app/models/spree/stock_transfer.rb +84 -59
  446. data/app/models/spree/stock_transfer_item.rb +25 -0
  447. data/app/models/spree/store.rb +431 -107
  448. data/app/models/spree/store_credit.rb +88 -21
  449. data/app/models/spree/store_credit_category.rb +21 -28
  450. data/app/models/spree/store_credit_event.rb +1 -1
  451. data/app/models/spree/store_credit_type.rb +10 -2
  452. data/app/models/spree/store_payment_method.rb +0 -1
  453. data/app/models/spree/store_product.rb +2 -2
  454. data/app/models/spree/store_promotion.rb +0 -1
  455. data/app/models/spree/storefront/access_denied.rb +22 -0
  456. data/app/models/spree/storefront/access_policy.rb +180 -0
  457. data/app/models/spree/subscriber.rb +6 -6
  458. data/app/models/spree/supplier.rb +76 -0
  459. data/app/models/spree/tax_category.rb +15 -5
  460. data/app/models/spree/tax_exemption/item_override.rb +22 -0
  461. data/app/models/spree/tax_exemption.rb +81 -0
  462. data/app/models/spree/tax_exemption_certificate.rb +95 -0
  463. data/app/models/spree/tax_identifier.rb +209 -0
  464. data/app/models/spree/tax_identifiers/validation_result.rb +41 -0
  465. data/app/models/spree/tax_identifiers/validator/base.rb +53 -0
  466. data/app/models/spree/tax_identifiers/validator/eu_vat.rb +76 -0
  467. data/app/models/spree/tax_line.rb +79 -0
  468. data/app/models/spree/tax_provider/base.rb +150 -0
  469. data/app/models/spree/tax_provider/internal.rb +227 -0
  470. data/app/models/spree/tax_rate.rb +63 -100
  471. data/app/models/spree/taxon.rb +13 -514
  472. data/app/models/spree/taxon_rule.rb +8 -9
  473. data/app/models/spree/taxonomy.rb +8 -42
  474. data/app/models/spree/user_identity.rb +2 -2
  475. data/app/models/spree/variant.rb +629 -150
  476. data/app/models/spree/variant_media.rb +6 -7
  477. data/app/models/spree/webhook_endpoint.rb +2 -1
  478. data/app/models/spree/wished_item.rb +3 -31
  479. data/app/models/spree/wishlist.rb +17 -10
  480. data/app/models/spree/wishlist_item/custom_events.rb +42 -0
  481. data/app/models/spree/wishlist_item.rb +37 -0
  482. data/app/models/spree/zone.rb +24 -182
  483. data/app/models/spree/zone_member.rb +5 -8
  484. data/app/presenters/spree/csv/custom_fields_helper.rb +25 -0
  485. data/app/presenters/spree/csv/customer_presenter.rb +7 -6
  486. data/app/presenters/spree/csv/gift_card_presenter.rb +9 -8
  487. data/app/presenters/spree/csv/newsletter_subscriber_presenter.rb +7 -6
  488. data/app/presenters/spree/csv/order_line_item_presenter.rb +53 -21
  489. data/app/presenters/spree/csv/price_list_price_presenter.rb +41 -0
  490. data/app/presenters/spree/csv/product_variant_presenter.rb +22 -21
  491. data/app/presenters/spree/csv/purchase_order_item_presenter.rb +50 -0
  492. data/app/presenters/spree/data_feeds/google_presenter.rb +24 -10
  493. data/app/presenters/spree/filters/options_presenter.rb +2 -2
  494. data/app/services/spree/addresses/create.rb +70 -27
  495. data/app/services/spree/addresses/helper.rb +17 -54
  496. data/app/services/spree/addresses/update.rb +53 -31
  497. data/app/services/spree/carts/associate.rb +46 -0
  498. data/app/services/spree/carts/check_availability.rb +72 -0
  499. data/app/services/spree/carts/create.rb +7 -1
  500. data/app/services/spree/carts/destroy.rb +71 -0
  501. data/app/services/spree/carts/empty.rb +42 -0
  502. data/app/services/spree/carts/partition_by_seller.rb +71 -0
  503. data/app/services/spree/carts/price_items.rb +119 -0
  504. data/app/services/spree/carts/remove_item.rb +42 -0
  505. data/app/services/spree/carts/remove_line_item.rb +42 -0
  506. data/app/services/spree/carts/remove_out_of_stock_items.rb +104 -0
  507. data/app/services/spree/carts/set_quantity.rb +39 -0
  508. data/app/services/spree/carts/split_by_seller.rb +475 -0
  509. data/app/services/spree/carts/update.rb +157 -51
  510. data/app/services/spree/catalogs/resolve_prices.rb +192 -0
  511. data/app/services/spree/catalogs/resolve_quantity_rules.rb +115 -0
  512. data/app/services/spree/catalogs/set_assignments.rb +59 -0
  513. data/app/services/spree/catalogs/set_order_minimums.rb +44 -0
  514. data/app/services/spree/catalogs/set_product_terms.rb +83 -0
  515. data/app/services/spree/categories/add_products.rb +51 -0
  516. data/app/services/spree/categories/remove_products.rb +72 -0
  517. data/app/services/spree/checkout/add_store_credit.rb +11 -79
  518. data/app/services/spree/checkout/advance.rb +38 -38
  519. data/app/services/spree/checkout/remove_store_credit.rb +7 -12
  520. data/app/services/spree/collections/add_products.rb +42 -0
  521. data/app/services/spree/collections/regenerate_products.rb +67 -0
  522. data/app/services/spree/collections/remove_products.rb +65 -0
  523. data/app/services/spree/commissions/calculate_line.rb +132 -0
  524. data/app/services/spree/commissions/commission_order.rb +185 -0
  525. data/app/services/spree/commissions/resolve_rate.rb +114 -0
  526. data/app/services/spree/commissions/resolve_tax_rate.rb +78 -0
  527. data/app/services/spree/companies/add_member.rb +38 -0
  528. data/app/services/spree/company_invitations/accept.rb +60 -0
  529. data/app/services/spree/coupon_codes/coupon_codes_handler.rb +14 -2
  530. data/app/services/spree/customers/data_export.rb +372 -0
  531. data/app/services/spree/data_requests/create.rb +77 -0
  532. data/app/services/spree/deliveries/create.rb +56 -0
  533. data/app/services/spree/deliveries/destroy.rb +39 -0
  534. data/app/services/spree/deliveries/upsert_primary.rb +43 -0
  535. data/app/services/spree/fulfillments/recalculate_delivery.rb +62 -0
  536. data/app/services/spree/fulfillments/stand_down_provider.rb +47 -0
  537. data/app/services/spree/imports/row_processors/customer.rb +8 -8
  538. data/app/services/spree/imports/row_processors/price_list_price.rb +164 -0
  539. data/app/services/spree/imports/row_processors/product_variant.rb +193 -57
  540. data/app/services/spree/imports/row_processors/purchase_order.rb +157 -0
  541. data/app/services/spree/media/destroy.rb +88 -0
  542. data/app/services/spree/media/usage.rb +175 -0
  543. data/app/services/spree/newsletter/link_user.rb +4 -3
  544. data/app/services/spree/newsletter/subscribe.rb +3 -3
  545. data/app/services/spree/newsletter/verify.rb +6 -2
  546. data/app/services/spree/order_groups/allocate_payments.rb +101 -0
  547. data/app/services/spree/orders/approve.rb +11 -24
  548. data/app/services/spree/orders/build_fulfillments.rb +29 -0
  549. data/app/services/spree/orders/create.rb +38 -17
  550. data/app/services/spree/orders/create_from_cart.rb +88 -0
  551. data/app/services/spree/orders/create_user_account.rb +14 -67
  552. data/app/services/spree/orders/discounts/create.rb +84 -0
  553. data/app/services/spree/orders/discounts/destroy.rb +25 -0
  554. data/app/services/spree/orders/discounts/update.rb +29 -0
  555. data/app/services/spree/orders/fees/create.rb +28 -0
  556. data/app/services/spree/orders/fees/destroy.rb +22 -0
  557. data/app/services/spree/orders/fees/update.rb +25 -0
  558. data/app/services/spree/orders/remove_item.rb +13 -0
  559. data/app/services/spree/orders/remove_line_item.rb +13 -0
  560. data/app/services/spree/orders/update.rb +56 -11
  561. data/app/services/spree/orders/update_item.rb +105 -0
  562. data/app/services/spree/orders/update_statuses.rb +109 -0
  563. data/app/services/spree/payments/create.rb +31 -5
  564. data/app/services/spree/prices/bulk_upsert.rb +156 -30
  565. data/app/services/spree/product_submissions/close.rb +46 -0
  566. data/app/services/spree/product_types/apply_to_products.rb +167 -0
  567. data/app/services/spree/products/auto_match_collections.rb +75 -0
  568. data/app/services/spree/products/auto_match_taxons.rb +7 -54
  569. data/app/services/spree/products/duplicator.rb +16 -22
  570. data/app/services/spree/products/for_context.rb +54 -0
  571. data/app/services/spree/products/select_buy_box.rb +98 -0
  572. data/app/services/spree/purchases/amount_due_at_checkout.rb +33 -0
  573. data/app/services/spree/returns/eligibility_validator.rb +53 -0
  574. data/app/services/spree/sample_data/helper.rb +3 -3
  575. data/app/services/spree/sample_data/import_builder.rb +8 -4
  576. data/app/services/spree/sample_data/import_runner.rb +7 -4
  577. data/app/services/spree/sample_data/loader.rb +15 -6
  578. data/app/services/spree/search_provider/custom_field_schema.rb +153 -0
  579. data/app/services/spree/seeds/admin_user.rb +72 -12
  580. data/app/services/spree/seeds/all.rb +24 -13
  581. data/app/services/spree/seeds/commission_rates.rb +53 -0
  582. data/app/services/spree/seeds/digital_delivery.rb +18 -8
  583. data/app/services/spree/seeds/product_types.rb +23 -0
  584. data/app/services/spree/seeds/returns_environment.rb +44 -16
  585. data/app/services/spree/seeds/roles.rb +6 -1
  586. data/app/services/spree/seeds/saved_reports.rb +107 -0
  587. data/app/services/spree/seeds/seller_requirements.rb +19 -0
  588. data/app/services/spree/seeds/stores.rb +1 -1
  589. data/app/services/spree/seeds/tax_categories.rb +9 -2
  590. data/app/services/spree/sellers/requirements.rb +129 -0
  591. data/app/services/spree/shipments/update.rb +4 -33
  592. data/app/services/spree/shipping_labels/confirm_refund.rb +47 -0
  593. data/app/services/spree/shipping_labels/store_file.rb +68 -0
  594. data/app/services/spree/stock_levels/bulk_upsert.rb +67 -0
  595. data/app/services/spree/stock_levels/correct.rb +69 -0
  596. data/app/services/spree/stock_levels/recount.rb +103 -0
  597. data/app/services/spree/stock_locations/stock_items/create.rb +8 -13
  598. data/app/services/spree/stock_locations/stock_levels/create.rb +25 -0
  599. data/app/services/spree/stock_reservations/extend.rb +9 -5
  600. data/app/services/spree/stock_reservations/release.rb +4 -3
  601. data/app/services/spree/stock_reservations/reserve.rb +43 -32
  602. data/app/services/spree/store_credits/apply.rb +93 -0
  603. data/app/services/spree/store_credits/remove.rb +17 -0
  604. data/app/services/spree/stores/provision_defaults.rb +269 -0
  605. data/app/services/spree/tax/resolve_exemptions.rb +44 -0
  606. data/app/services/spree/tax/unusable_exemption_error.rb +8 -0
  607. data/app/services/spree/tax_identifiers/validate.rb +77 -0
  608. data/app/services/spree/taxons/add_products.rb +6 -39
  609. data/app/services/spree/taxons/regenerate_products.rb +8 -53
  610. data/app/services/spree/taxons/remove_products.rb +6 -60
  611. data/app/services/spree/variants/remove_line_items.rb +6 -1
  612. data/app/subscribers/spree/event_log_subscriber.rb +1 -1
  613. data/app/subscribers/spree/order_commission_subscriber.rb +23 -0
  614. data/app/subscribers/spree/order_placed_subscriber.rb +58 -0
  615. data/app/subscribers/spree/order_status_subscriber.rb +82 -0
  616. data/app/subscribers/spree/payment_split_subscriber.rb +71 -0
  617. data/app/subscribers/spree/product_metrics_subscriber.rb +2 -2
  618. data/app/subscribers/spree/seller_onboarding_subscriber.rb +32 -0
  619. data/app/subscribers/spree/seller_transfer_reversal_subscriber.rb +26 -0
  620. data/app/subscribers/spree/seller_transfer_subscriber.rb +26 -0
  621. data/app/subscribers/spree/seller_user_email_subscriber.rb +27 -0
  622. data/app/subscribers/spree/tax_identifier_validation_subscriber.rb +26 -0
  623. data/app/validators/spree/addresses/phone_validator.rb +2 -2
  624. data/app/validators/spree/attachment_content_type_validator.rb +183 -0
  625. data/app/validators/spree/password_length_validator.rb +23 -0
  626. data/app/views/spree/seller_user_mailer/password_reset_email.html.erb +8 -0
  627. data/app/views/spree/shared/_purchased_items_styles.html.erb +7 -0
  628. data/app/workflows/spree/carts/add_item.rb +234 -0
  629. data/app/workflows/spree/carts/complete.rb +516 -0
  630. data/app/workflows/spree/carts/merge.rb +90 -0
  631. data/app/workflows/spree/carts/recalculate.rb +54 -0
  632. data/app/workflows/spree/carts/recalculate_totals.rb +233 -0
  633. data/app/workflows/spree/carts/upsert_items.rb +368 -0
  634. data/app/workflows/spree/catalogs/activate.rb +51 -0
  635. data/app/workflows/spree/catalogs/create.rb +83 -0
  636. data/app/workflows/spree/catalogs/deactivate.rb +35 -0
  637. data/app/workflows/spree/catalogs/set_price_list.rb +130 -0
  638. data/app/workflows/spree/catalogs/update.rb +85 -0
  639. data/app/workflows/spree/claims/approve.rb +38 -0
  640. data/app/workflows/spree/claims/cancel.rb +37 -0
  641. data/app/workflows/spree/claims/create.rb +82 -0
  642. data/app/workflows/spree/claims/deny.rb +35 -0
  643. data/app/workflows/spree/claims/resolve.rb +166 -0
  644. data/app/workflows/spree/customers/anonymize.rb +502 -0
  645. data/app/workflows/spree/customers/create.rb +247 -0
  646. data/app/workflows/spree/data_requests/fulfill.rb +165 -0
  647. data/app/workflows/spree/deliveries/update_tracking.rb +96 -0
  648. data/app/workflows/spree/exchanges/approve.rb +38 -0
  649. data/app/workflows/spree/exchanges/cancel.rb +40 -0
  650. data/app/workflows/spree/exchanges/create.rb +90 -0
  651. data/app/workflows/spree/exchanges/fulfill.rb +146 -0
  652. data/app/workflows/spree/exchanges/receive.rb +86 -0
  653. data/app/workflows/spree/fulfillments/cancel.rb +87 -0
  654. data/app/workflows/spree/fulfillments/create.rb +346 -0
  655. data/app/workflows/spree/fulfillments/fulfill.rb +354 -0
  656. data/app/workflows/spree/fulfillments/mark_delivered.rb +67 -0
  657. data/app/workflows/spree/fulfillments/purchase_label.rb +40 -0
  658. data/app/workflows/spree/fulfillments/update.rb +123 -0
  659. data/app/workflows/spree/gift_cards/apply.rb +235 -0
  660. data/app/workflows/spree/gift_cards/cancel.rb +43 -0
  661. data/app/workflows/spree/gift_cards/redeem.rb +59 -0
  662. data/app/workflows/spree/gift_cards/remove.rb +78 -0
  663. data/app/workflows/spree/imports/complete.rb +45 -0
  664. data/app/workflows/spree/imports/complete_mapping.rb +50 -0
  665. data/app/workflows/spree/imports/retry_failed_rows.rb +46 -0
  666. data/app/workflows/spree/imports/start_mapping.rb +48 -0
  667. data/app/workflows/spree/imports/start_processing.rb +36 -0
  668. data/app/workflows/spree/invitations/accept.rb +50 -0
  669. data/app/workflows/spree/orders/add_item.rb +12 -0
  670. data/app/workflows/spree/orders/cancel.rb +261 -0
  671. data/app/workflows/spree/orders/complete.rb +169 -0
  672. data/app/workflows/spree/orders/recalculate.rb +11 -0
  673. data/app/workflows/spree/orders/recalculate_totals.rb +12 -0
  674. data/app/workflows/spree/orders/upsert_items.rb +28 -0
  675. data/app/workflows/spree/payment_sessions/complete.rb +44 -0
  676. data/app/workflows/spree/payments/capture.rb +109 -0
  677. data/app/workflows/spree/payments/handle_webhook.rb +100 -0
  678. data/app/workflows/spree/payments/process.rb +73 -0
  679. data/app/workflows/spree/payments/void.rb +72 -0
  680. data/app/workflows/spree/price_lists/activate.rb +49 -0
  681. data/app/workflows/spree/price_lists/create.rb +57 -0
  682. data/app/workflows/spree/price_lists/deactivate.rb +30 -0
  683. data/app/workflows/spree/price_lists/update.rb +117 -0
  684. data/app/workflows/spree/products/activate.rb +33 -0
  685. data/app/workflows/spree/products/approve.rb +52 -0
  686. data/app/workflows/spree/products/archive.rb +44 -0
  687. data/app/workflows/spree/products/create.rb +82 -0
  688. data/app/workflows/spree/products/destroy.rb +35 -0
  689. data/app/workflows/spree/products/draft.rb +49 -0
  690. data/app/workflows/spree/products/nested_attributes.rb +242 -0
  691. data/app/workflows/spree/products/propose.rb +62 -0
  692. data/app/workflows/spree/products/reject.rb +54 -0
  693. data/app/workflows/spree/products/update.rb +83 -0
  694. data/app/workflows/spree/purchase_orders/cancel.rb +57 -0
  695. data/app/workflows/spree/purchase_orders/close.rb +57 -0
  696. data/app/workflows/spree/purchase_orders/create.rb +68 -0
  697. data/app/workflows/spree/purchase_orders/mark_draft.rb +49 -0
  698. data/app/workflows/spree/purchase_orders/mark_ordered.rb +50 -0
  699. data/app/workflows/spree/purchase_orders/receive.rb +65 -0
  700. data/app/workflows/spree/purchase_orders/update.rb +56 -0
  701. data/app/workflows/spree/receivables/incoming_counter.rb +50 -0
  702. data/app/workflows/spree/refunds/create.rb +136 -0
  703. data/app/workflows/spree/refunds/order_payments.rb +129 -0
  704. data/app/workflows/spree/returns/approve.rb +47 -0
  705. data/app/workflows/spree/returns/cancel.rb +52 -0
  706. data/app/workflows/spree/returns/create.rb +135 -0
  707. data/app/workflows/spree/returns/purchase_label.rb +32 -0
  708. data/app/workflows/spree/returns/receive.rb +94 -0
  709. data/app/workflows/spree/returns/refund.rb +134 -0
  710. data/app/workflows/spree/seller_payouts/complete.rb +80 -0
  711. data/app/workflows/spree/seller_payouts/sweep.rb +192 -0
  712. data/app/workflows/spree/seller_requirement_submissions/accept.rb +40 -0
  713. data/app/workflows/spree/seller_requirement_submissions/create.rb +104 -0
  714. data/app/workflows/spree/seller_requirement_submissions/reject.rb +45 -0
  715. data/app/workflows/spree/seller_requirement_submissions/reviewable.rb +19 -0
  716. data/app/workflows/spree/seller_requirement_submissions/waive.rb +64 -0
  717. data/app/workflows/spree/seller_transfers/create.rb +131 -0
  718. data/app/workflows/spree/seller_transfers/reverse.rb +241 -0
  719. data/app/workflows/spree/sellers/approve.rb +88 -0
  720. data/app/workflows/spree/sellers/create.rb +72 -0
  721. data/app/workflows/spree/sellers/invite.rb +61 -0
  722. data/app/workflows/spree/sellers/reject.rb +52 -0
  723. data/app/workflows/spree/sellers/reopen_onboarding.rb +55 -0
  724. data/app/workflows/spree/sellers/start_onboarding.rb +46 -0
  725. data/app/workflows/spree/sellers/submit_for_review.rb +76 -0
  726. data/app/workflows/spree/sellers/suspend.rb +55 -0
  727. data/app/workflows/spree/shipping_labels/purchase.rb +154 -0
  728. data/app/workflows/spree/shipping_labels/record.rb +102 -0
  729. data/app/workflows/spree/shipping_labels/refund.rb +77 -0
  730. data/app/workflows/spree/stock_receipts/recording.rb +165 -0
  731. data/app/workflows/spree/stock_transfers/cancel.rb +103 -0
  732. data/app/workflows/spree/stock_transfers/close.rb +56 -0
  733. data/app/workflows/spree/stock_transfers/create.rb +63 -0
  734. data/app/workflows/spree/stock_transfers/mark_draft.rb +41 -0
  735. data/app/workflows/spree/stock_transfers/mark_in_transit.rb +91 -0
  736. data/app/workflows/spree/stock_transfers/mark_ready.rb +36 -0
  737. data/app/workflows/spree/stock_transfers/receive.rb +62 -0
  738. data/app/workflows/spree/stock_transfers/update.rb +55 -0
  739. data/app/workflows/spree/tax_exemption_certificates/verify.rb +48 -0
  740. data/app/workflows/spree/variants/create.rb +66 -0
  741. data/app/workflows/spree/variants/nested_attributes.rb +90 -0
  742. data/app/workflows/spree/variants/update.rb +55 -0
  743. data/config/brakeman.ignore +79 -79
  744. data/config/i18n-tasks.yml +4 -3
  745. data/config/initializers/mobility.rb +0 -4
  746. data/config/initializers/spree_store_setup_tasks.rb +4 -0
  747. data/config/locales/en.yml +952 -189
  748. data/config/routes.rb +11 -4
  749. data/db/migrate/20220201103922_add_first_name_and_last_name_to_spree_users.rb +7 -5
  750. data/db/migrate/20221215151408_add_selected_locale_to_spree_users.rb +6 -4
  751. data/db/migrate/20250127151258_add_phone_to_spree_users.rb +3 -1
  752. data/db/migrate/20250207084000_add_accepts_email_marketing_field_to_spree_users_table.rb +4 -2
  753. data/db/migrate/20250410061306_create_spree_invitations.rb +1 -1
  754. data/db/migrate/20250605131334_add_missing_fields_to_users.rb +24 -20
  755. data/db/migrate/20260315100000_add_product_media_support.rb +4 -1
  756. data/db/migrate/20260613000001_add_store_id_to_spree_role_users.rb +6 -3
  757. data/db/migrate/20260630000001_add_default_variant_id_to_spree_products.rb +9 -0
  758. data/db/migrate/20260708160054_create_spree_collections.rb +69 -0
  759. data/db/migrate/20260710000001_rename_taxons_to_categories.rb +28 -0
  760. data/db/migrate/20260727000001_add_unique_country_abbr_index_to_spree_states.rb +27 -4
  761. data/db/migrate/20260728000000_create_spree_customers_and_admin_users.rb +59 -0
  762. data/db/migrate/20260728000001_rename_prototypes_to_product_types.rb +59 -0
  763. data/db/migrate/20260728000002_create_spree_delivery_zones.rb +29 -0
  764. data/db/migrate/20260728000003_create_spree_carts.rb +58 -0
  765. data/db/migrate/20260728000003_rename_user_id_to_customer_id.rb +30 -0
  766. data/db/migrate/20260728000004_rename_shipping_to_fulfillment_and_delivery.rb +83 -0
  767. data/db/migrate/20260728000005_add_fulfillment_type_columns.rb +33 -0
  768. data/db/migrate/20260729000001_create_typed_adjustment_tables.rb +87 -0
  769. data/db/migrate/20260729100001_add_checkout_columns_to_spree_carts.rb +15 -0
  770. data/db/migrate/20260729100002_relax_owner_null_constraints.rb +7 -0
  771. data/db/migrate/20260729120001_rename_order_totals_to_standard_names.rb +7 -0
  772. data/db/migrate/20260729130001_create_spree_delivery_method_rules.rb +19 -0
  773. data/db/migrate/20260729140001_add_coupon_code_to_spree_orders.rb +6 -0
  774. data/db/migrate/20260729150001_add_store_to_delivery_methods_and_stock_locations.rb +6 -0
  775. data/db/migrate/20260802190001_create_spree_returns.rb +49 -0
  776. data/db/migrate/20260802210001_create_spree_exchanges_and_claims.rb +80 -0
  777. data/db/migrate/20260805100001_rename_return_authorization_reasons_to_return_reasons.rb +109 -0
  778. data/db/migrate/20260806000001_add_store_id_to_spree_tax_rates_and_categories.rb +16 -0
  779. data/db/migrate/20260806000001_create_spree_delivery_method_rule_products.rb +22 -0
  780. data/db/migrate/20260806000002_add_treatment_columns_to_spree_tax_lines.rb +19 -0
  781. data/db/migrate/20260806000003_create_spree_tax_identifiers.rb +41 -0
  782. data/db/migrate/20260806000004_add_tax_provider_to_spree_markets.rb +9 -0
  783. data/db/migrate/20260806000005_add_country_and_state_to_spree_tax_rates.rb +20 -0
  784. data/db/migrate/20260806100001_create_spree_product_type_custom_field_definitions.rb +17 -0
  785. data/db/migrate/20260806120001_add_rate_provider_to_delivery_methods.rb +7 -0
  786. data/db/migrate/20260806120002_add_carrier_columns_to_delivery_rates.rb +13 -0
  787. data/db/migrate/20260806130001_add_unique_store_type_index_to_spree_integrations.rb +9 -0
  788. data/db/migrate/20260807000001_add_permissions_to_spree_roles.rb +14 -0
  789. data/db/migrate/20260807000001_create_spree_companies.rb +66 -0
  790. data/db/migrate/20260807000003_create_spree_tax_exemption_certificates.rb +31 -0
  791. data/db/migrate/20260807120001_remove_claim_type_from_spree_claims.rb +5 -0
  792. data/db/migrate/20260807130001_add_country_state_codes_to_consumers.rb +28 -0
  793. data/db/migrate/20260807150001_reindex_spree_categories_by_store.rb +42 -0
  794. data/db/migrate/20260809000001_rename_metafields_to_custom_fields.rb +126 -0
  795. data/db/migrate/20260809100001_support_multi_rate_delivery_methods.rb +35 -0
  796. data/db/migrate/20260809120001_consolidate_metadata_columns.rb +120 -0
  797. data/db/migrate/20260809150001_promote_shipping_categories_to_delivery_profiles.rb +153 -0
  798. data/db/migrate/20260809170001_create_spree_channel_stock_locations.rb +17 -0
  799. data/db/migrate/20260809200001_add_rich_text_columns_for_action_text_removal.rb +11 -0
  800. data/db/migrate/20260810000001_rename_digitals_to_digital_assets.rb +38 -0
  801. data/db/migrate/20260811000001_add_delivery_tracking_to_fulfillments.rb +17 -0
  802. data/db/migrate/20260812000001_add_provider_type_to_spree_digital_assets.rb +7 -0
  803. data/db/migrate/20260812000002_add_metadata_to_spree_digital_assets.rb +11 -0
  804. data/db/migrate/20260813000001_create_spree_number_sequences.rb +13 -0
  805. data/db/migrate/20260813120001_add_setup_token_to_spree_stores.rb +11 -0
  806. data/db/migrate/20260813130001_add_capture_method_to_payment_methods.rb +17 -0
  807. data/db/migrate/20260813130001_add_unique_indexes_to_spree_data_feeds.rb +10 -0
  808. data/db/migrate/20260814000001_add_customs_fields_to_spree_variants.rb +7 -0
  809. data/db/migrate/20260814000001_rename_stock_items_to_stock_levels.rb +72 -0
  810. data/db/migrate/20260814000002_add_typed_stock_movements.rb +25 -0
  811. data/db/migrate/20260815000001_add_audience_to_spree_refresh_tokens.rb +14 -0
  812. data/db/migrate/20260815000002_add_resource_to_spree_roles.rb +190 -0
  813. data/db/migrate/20260816000001_create_spree_sellers.rb +59 -0
  814. data/db/migrate/20260816000002_add_seller_to_spree_products.rb +10 -0
  815. data/db/migrate/20260816210001_create_spree_commission_rates.rb +229 -0
  816. data/db/migrate/20260816210002_create_spree_commission_lines.rb +72 -0
  817. data/db/migrate/20260817000001_add_seller_to_spree_line_items.rb +15 -0
  818. data/db/migrate/20260817000002_add_seller_and_delivery_profile_to_spree_variants.rb +17 -0
  819. data/db/migrate/20260818000001_create_spree_external_references.rb +33 -0
  820. data/db/migrate/20260818000001_create_spree_seller_requirements.rb +60 -0
  821. data/db/migrate/20260818000001_rename_spree_payments_state_to_status.rb +5 -0
  822. data/db/migrate/20260818000002_add_price_source_to_spree_line_items.rb +9 -0
  823. data/db/migrate/20260818090001_rename_assets_to_media.rb +10 -0
  824. data/db/migrate/20260819000001_create_spree_seller_requirement_custom_fields.rb +15 -0
  825. data/db/migrate/20260819000001_replace_payment_method_display_on_with_storefront_visible.rb +25 -0
  826. data/db/migrate/20260819000002_rename_spree_gift_cards_state_to_status.rb +5 -0
  827. data/db/migrate/20260820000001_add_seller_business_identity_and_stock_locations.rb +17 -0
  828. data/db/migrate/20260820000001_create_spree_order_groups.rb +33 -0
  829. data/db/migrate/20260820000002_add_order_group_to_spree_orders_and_payments.rb +14 -0
  830. data/db/migrate/20260820000003_create_spree_payment_splits.rb +21 -0
  831. data/db/migrate/20260820000004_add_order_to_spree_refunds.rb +32 -0
  832. data/db/migrate/20260821000001_add_claimed_amount_to_spree_payment_splits.rb +14 -0
  833. data/db/migrate/20260822000001_create_spree_seller_transfers.rb +94 -0
  834. data/db/migrate/20260822000002_create_spree_seller_payouts.rb +48 -0
  835. data/db/migrate/20260822000003_add_payout_account_to_spree_sellers.rb +11 -0
  836. data/db/migrate/20260824000001_add_store_to_spree_media.rb +16 -0
  837. data/db/migrate/20260825000001_create_spree_catalogs.rb +40 -0
  838. data/db/migrate/20260826000001_add_owner_to_spree_addresses.rb +30 -0
  839. data/db/migrate/20260826000002_create_spree_product_submissions.rb +28 -0
  840. data/db/migrate/20260827000001_add_seller_to_spree_exports.rb +5 -0
  841. data/db/migrate/20260828100001_unify_import_and_export_tenancy.rb +79 -0
  842. data/db/migrate/20260830000001_add_catalog_to_spree_price_lists.rb +47 -0
  843. data/db/migrate/20260830000002_add_po_number_to_purchases.rb +16 -0
  844. data/db/migrate/20260830000002_add_price_adjustment_to_spree_price_lists.rb +14 -0
  845. data/db/migrate/20260831000001_add_description_to_spree_catalogs.rb +7 -0
  846. data/db/migrate/20260831000002_add_quantity_rules_to_spree_variants.rb +18 -0
  847. data/db/migrate/20260831000003_create_spree_catalog_terms.rb +35 -0
  848. data/db/migrate/20260831100001_create_spree_package_types.rb +38 -0
  849. data/db/migrate/20260831100002_add_carton_details_to_spree_variants.rb +10 -0
  850. data/db/migrate/20260831100003_add_unpriced_to_spree_delivery_rates.rb +8 -0
  851. data/db/migrate/20260901000001_add_seller_to_spree_delivery_methods.rb +11 -0
  852. data/db/migrate/20260902000001_add_store_and_filter_key_to_custom_field_definitions.rb +143 -0
  853. data/db/migrate/20260902000002_add_eu_legal_compliance.rb +68 -0
  854. data/db/migrate/20260902000002_replace_order_cancellation_tables_with_cancel_columns.rb +88 -0
  855. data/db/migrate/20260902100001_rename_wished_items_to_wishlist_items.rb +8 -0
  856. data/db/migrate/20260902100002_rename_promo_total_to_discount_total.rb +9 -0
  857. data/db/migrate/20260902100003_rename_address_name_and_postal_code_columns.rb +24 -0
  858. data/db/migrate/20260902100004_rename_option_presentation_to_label.rb +13 -0
  859. data/db/migrate/20260903000001_create_spree_shipping_labels_and_deliveries.rb +73 -0
  860. data/db/migrate/20260903120000_create_spree_saved_reports.rb +57 -0
  861. data/db/migrate/20260904000001_add_returns_enabled_to_stock_locations.rb +14 -0
  862. data/db/migrate/20260906000001_add_commission_total_to_orders.rb +22 -0
  863. data/db/migrate/20260907000001_add_inventory_operations.rb +113 -0
  864. data/db/migrate/20260907000001_add_min_quantity_to_spree_prices.rb +28 -0
  865. data/db/migrate/20260907000002_create_spree_price_adjustment_tiers.rb +19 -0
  866. data/db/migrate/20260908000001_add_seller_to_spree_package_types.rb +78 -0
  867. data/db/migrate/20260910000001_add_stock_receipts.rb +44 -0
  868. data/db/migrate/20260910000002_add_counters_to_spree_stock_levels.rb +6 -0
  869. data/db/migrate/20260910120000_index_reporting_time_columns.rb +12 -0
  870. data/db/migrate/20260912120000_index_reporting_lifetime_and_promotion_columns.rb +19 -0
  871. data/db/migrate/20260914000001_add_settlement_to_spree_seller_transfers.rb +18 -0
  872. data/db/migrate/20260914230000_add_store_to_spree_option_types.rb +46 -0
  873. data/db/migrate/20260916000001_order_operation_actors_polymorphic.rb +30 -0
  874. data/db/sample_data/collections.rb +58 -0
  875. data/db/sample_data/custom_field_definitions.rb +9 -0
  876. data/db/sample_data/digital_products.rb +26 -0
  877. data/db/sample_data/fulfillment.rb +88 -0
  878. data/db/sample_data/options.rb +25 -1
  879. data/db/sample_data/orders.rb +53 -30
  880. data/db/sample_data/payment_methods.rb +2 -2
  881. data/db/sample_data/price_list_prices.csv +25 -0
  882. data/db/sample_data/product_type_categories.rb +27 -0
  883. data/db/sample_data/product_types.rb +83 -0
  884. data/db/sample_data/products.csv +39 -38
  885. data/db/sample_data/wholesale.rb +42 -3
  886. data/lib/generators/spree/api_resource/api_resource_generator.rb +64 -6
  887. data/lib/generators/spree/api_resource/templates/admin_controller.rb.tt +5 -0
  888. data/lib/generators/spree/api_resource/templates/admin_controller_spec.rb.tt +3 -0
  889. data/lib/generators/spree/api_resource/templates/store_controller_spec.rb.tt +4 -1
  890. data/lib/generators/spree/authentication/dummy/templates/create_spree_admin_users.rb.tt +1 -0
  891. data/lib/generators/spree/controller_decorator/controller_decorator_generator.rb +4 -4
  892. data/lib/generators/spree/dummy/dummy_generator.rb +5 -12
  893. data/lib/generators/spree/dummy/templates/rails/test.rb +5 -0
  894. data/lib/generators/spree/model/model_generator.rb +46 -7
  895. data/lib/generators/spree/model/templates/create_table_migration.rb.tt +9 -0
  896. data/lib/generators/spree/model/templates/model.rb.tt +17 -7
  897. data/lib/spree/category_permalink_deduplicator.rb +328 -0
  898. data/lib/spree/checkout/default_requirements.rb +134 -0
  899. data/lib/spree/checkout/registry.rb +164 -0
  900. data/lib/spree/checkout/requirement.rb +49 -0
  901. data/lib/spree/checkout/requirements.rb +61 -0
  902. data/lib/spree/checkout/step.rb +52 -0
  903. data/lib/spree/core/configuration.rb +112 -63
  904. data/lib/spree/core/controller_helpers/store.rb +8 -9
  905. data/lib/spree/core/dependencies.rb +324 -71
  906. data/lib/spree/core/dependencies_helper.rb +4 -0
  907. data/lib/spree/core/engine.rb +360 -75
  908. data/lib/spree/core/number_generator.rb +37 -33
  909. data/lib/spree/core/permission_configuration.rb +183 -91
  910. data/lib/spree/core/permissions/default_catalog.rb +236 -0
  911. data/lib/spree/core/permissions/entry.rb +15 -0
  912. data/lib/spree/core/permissions/scope.rb +76 -0
  913. data/lib/spree/core/preferences/masking.rb +24 -2
  914. data/lib/spree/core/preferences/preferable.rb +52 -2
  915. data/lib/spree/core/preferences/preferable_class_methods.rb +41 -2
  916. data/lib/spree/core/preferences/runtime_configuration.rb +142 -9
  917. data/lib/spree/core/previews/admin_user_preview.rb +0 -8
  918. data/lib/spree/core/previews/invitation_preview.rb +1 -1
  919. data/lib/spree/core/previews/preview_data.rb +2 -2
  920. data/lib/spree/core/previews/seller_user_preview.rb +14 -0
  921. data/lib/spree/core/pricing/context.rb +28 -8
  922. data/lib/spree/core/pricing/price_resolution.rb +150 -0
  923. data/lib/spree/core/pricing/resolver.rb +17 -107
  924. data/lib/spree/core/ransack_configuration.rb +3 -3
  925. data/lib/spree/core/routes.rb +4 -6
  926. data/lib/spree/core/version.rb +1 -1
  927. data/lib/spree/core.rb +446 -59
  928. data/lib/spree/events/adapters/base.rb +42 -15
  929. data/lib/spree/hooks.rb +146 -0
  930. data/lib/spree/iso_data.rb +188 -0
  931. data/lib/spree/measurement.rb +113 -0
  932. data/lib/spree/money.rb +70 -0
  933. data/lib/spree/number_generators/registry.rb +80 -0
  934. data/lib/spree/reporting/adapters/base.rb +71 -0
  935. data/lib/spree/reporting/adapters/live.rb +677 -0
  936. data/lib/spree/reporting/counter_result.rb +19 -0
  937. data/lib/spree/reporting/counters.rb +33 -0
  938. data/lib/spree/reporting/default_vocabulary.rb +705 -0
  939. data/lib/spree/reporting/hydration.rb +64 -0
  940. data/lib/spree/reporting/query.rb +487 -0
  941. data/lib/spree/reporting/registry.rb +294 -0
  942. data/lib/spree/reporting/result.rb +10 -0
  943. data/lib/spree/reporting/schema.rb +124 -0
  944. data/lib/spree/reporting.rb +49 -0
  945. data/lib/spree/service_module.rb +6 -0
  946. data/lib/spree/store_scope_guard.rb +180 -0
  947. data/lib/spree/testing_support/action_text.rb +33 -0
  948. data/lib/spree/testing_support/common_rake.rb +4 -66
  949. data/lib/spree/testing_support/country_pool.rb +50 -0
  950. data/lib/spree/testing_support/extension_rake.rb +2 -6
  951. data/lib/spree/testing_support/factories/address_factory.rb +45 -15
  952. data/lib/spree/testing_support/factories/api_key_factory.rb +1 -1
  953. data/lib/spree/testing_support/factories/calculator_factory.rb +0 -3
  954. data/lib/spree/testing_support/factories/cart_factory.rb +60 -0
  955. data/lib/spree/testing_support/factories/catalog_factory.rb +37 -0
  956. data/lib/spree/testing_support/factories/category_factory.rb +21 -0
  957. data/lib/spree/testing_support/factories/claim_factory.rb +33 -0
  958. data/lib/spree/testing_support/factories/classification_factory.rb +3 -2
  959. data/lib/spree/testing_support/factories/collection_factory.rb +25 -0
  960. data/lib/spree/testing_support/factories/collection_rule_factory.rb +47 -0
  961. data/lib/spree/testing_support/factories/commission_rate_factory.rb +75 -0
  962. data/lib/spree/testing_support/factories/company_factory.rb +31 -0
  963. data/lib/spree/testing_support/factories/consent_record_factory.rb +10 -0
  964. data/lib/spree/testing_support/factories/country_factory.rb +28 -9
  965. data/lib/spree/testing_support/factories/custom_field_definition_factory.rb +79 -0
  966. data/lib/spree/testing_support/factories/custom_field_factory.rb +64 -0
  967. data/lib/spree/testing_support/factories/customer_group_user_factory.rb +1 -1
  968. data/lib/spree/testing_support/factories/data_request_factory.rb +17 -0
  969. data/lib/spree/testing_support/factories/delivery_factory.rb +13 -0
  970. data/lib/spree/testing_support/factories/delivery_method_factory.rb +47 -0
  971. data/lib/spree/testing_support/factories/delivery_origin_group_factory.rb +5 -0
  972. data/lib/spree/testing_support/factories/delivery_profile_factory.rb +9 -0
  973. data/lib/spree/testing_support/factories/delivery_rate_factory.rb +7 -0
  974. data/lib/spree/testing_support/factories/delivery_zone_factory.rb +34 -0
  975. data/lib/spree/testing_support/factories/digital_asset_factory.rb +13 -0
  976. data/lib/spree/testing_support/factories/digital_link_factory.rb +1 -1
  977. data/lib/spree/testing_support/factories/discount_factory.rb +9 -0
  978. data/lib/spree/testing_support/factories/exchange_factory.rb +50 -0
  979. data/lib/spree/testing_support/factories/external_reference_factory.rb +8 -0
  980. data/lib/spree/testing_support/factories/fee_factory.rb +8 -0
  981. data/lib/spree/testing_support/factories/fulfillment_factory.rb +32 -0
  982. data/lib/spree/testing_support/factories/fulfillment_item_factory.rb +17 -0
  983. data/lib/spree/testing_support/factories/gateway_customer_factory.rb +1 -1
  984. data/lib/spree/testing_support/factories/gift_card_factory.rb +2 -2
  985. data/lib/spree/testing_support/factories/import_factory.rb +33 -1
  986. data/lib/spree/testing_support/factories/line_item_factory.rb +10 -5
  987. data/lib/spree/testing_support/factories/market_factory.rb +5 -12
  988. data/lib/spree/testing_support/factories/media_factory.rb +36 -0
  989. data/lib/spree/testing_support/factories/newsletter_subscriber_factory.rb +1 -1
  990. data/lib/spree/testing_support/factories/number_sequence_factory.rb +7 -0
  991. data/lib/spree/testing_support/factories/options_factory.rb +5 -5
  992. data/lib/spree/testing_support/factories/order_factory.rb +39 -23
  993. data/lib/spree/testing_support/factories/order_group_factory.rb +29 -0
  994. data/lib/spree/testing_support/factories/package_type_factory.rb +36 -0
  995. data/lib/spree/testing_support/factories/payment_factory.rb +7 -7
  996. data/lib/spree/testing_support/factories/payment_method_factory.rb +5 -5
  997. data/lib/spree/testing_support/factories/payment_session_factory.rb +10 -6
  998. data/lib/spree/testing_support/factories/payment_setup_session_factory.rb +2 -2
  999. data/lib/spree/testing_support/factories/payment_split_factory.rb +10 -0
  1000. data/lib/spree/testing_support/factories/price_adjustment_tier_factory.rb +7 -0
  1001. data/lib/spree/testing_support/factories/price_factory.rb +6 -0
  1002. data/lib/spree/testing_support/factories/price_rule_factory.rb +0 -10
  1003. data/lib/spree/testing_support/factories/product_collection_factory.rb +8 -0
  1004. data/lib/spree/testing_support/factories/product_factory.rb +35 -7
  1005. data/lib/spree/testing_support/factories/product_type_custom_field_definition_factory.rb +10 -0
  1006. data/lib/spree/testing_support/factories/product_type_factory.rb +12 -0
  1007. data/lib/spree/testing_support/factories/promotion_factory.rb +4 -0
  1008. data/lib/spree/testing_support/factories/promotion_rule_factory.rb +1 -1
  1009. data/lib/spree/testing_support/factories/purchase_order_factory.rb +49 -0
  1010. data/lib/spree/testing_support/factories/refresh_token_factory.rb +2 -0
  1011. data/lib/spree/testing_support/factories/refund_factory.rb +1 -2
  1012. data/lib/spree/testing_support/factories/return_factory.rb +52 -0
  1013. data/lib/spree/testing_support/factories/return_reason_factory.rb +19 -0
  1014. data/lib/spree/testing_support/factories/role_factory.rb +1 -0
  1015. data/lib/spree/testing_support/factories/saved_report_factory.rb +7 -0
  1016. data/lib/spree/testing_support/factories/seller_factory.rb +34 -0
  1017. data/lib/spree/testing_support/factories/seller_payout_factory.rb +14 -0
  1018. data/lib/spree/testing_support/factories/seller_requirement_factory.rb +61 -0
  1019. data/lib/spree/testing_support/factories/seller_requirement_submission_factory.rb +32 -0
  1020. data/lib/spree/testing_support/factories/seller_transfer_factory.rb +21 -0
  1021. data/lib/spree/testing_support/factories/shipping_label_factory.rb +44 -0
  1022. data/lib/spree/testing_support/factories/state_factory.rb +18 -5
  1023. data/lib/spree/testing_support/factories/stock_level_factory.rb +24 -0
  1024. data/lib/spree/testing_support/factories/stock_location_factory.rb +12 -6
  1025. data/lib/spree/testing_support/factories/stock_movement_factory.rb +20 -3
  1026. data/lib/spree/testing_support/factories/stock_receipt_factory.rb +37 -0
  1027. data/lib/spree/testing_support/factories/stock_reservation_factory.rb +11 -8
  1028. data/lib/spree/testing_support/factories/stock_transfer_factory.rb +53 -6
  1029. data/lib/spree/testing_support/factories/store_credit_factory.rb +1 -3
  1030. data/lib/spree/testing_support/factories/supplier_factory.rb +17 -0
  1031. data/lib/spree/testing_support/factories/tax_exemption_certificate_factory.rb +18 -0
  1032. data/lib/spree/testing_support/factories/tax_identifier_factory.rb +33 -0
  1033. data/lib/spree/testing_support/factories/tax_line_factory.rb +19 -0
  1034. data/lib/spree/testing_support/factories/tax_rate_factory.rb +5 -2
  1035. data/lib/spree/testing_support/factories/taxon_factory.rb +6 -23
  1036. data/lib/spree/testing_support/factories/taxonomy_factory.rb +8 -0
  1037. data/lib/spree/testing_support/factories/user_factory.rb +8 -13
  1038. data/lib/spree/testing_support/factories/variant_factory.rb +1 -1
  1039. data/lib/spree/testing_support/factories/wishlist_factory.rb +1 -1
  1040. data/lib/spree/testing_support/factories/wishlist_item_factory.rb +10 -0
  1041. data/lib/spree/testing_support/factories/zone_factory.rb +2 -25
  1042. data/lib/spree/testing_support/factories/zone_member_factory.rb +2 -1
  1043. data/lib/spree/testing_support/factories.rb +1 -6
  1044. data/lib/spree/testing_support/imports.rb +16 -0
  1045. data/lib/spree/testing_support/label_provider.rb +49 -0
  1046. data/lib/spree/testing_support/lifecycle_events.rb +6 -1
  1047. data/lib/spree/testing_support/metadata.rb +38 -36
  1048. data/lib/spree/testing_support/order_walkthrough.rb +46 -36
  1049. data/lib/spree/testing_support/preferences.rb +39 -0
  1050. data/lib/spree/testing_support/purchase_order.rb +111 -0
  1051. data/lib/spree/testing_support/store.rb +6 -2
  1052. data/lib/spree/testing_support/tax_identifier_validators.rb +68 -0
  1053. data/lib/spree/translations.rb +139 -5
  1054. data/lib/spree/upgrades/5_4_to_5_5/manifest.yml +1 -1
  1055. data/lib/spree/upgrades/5_5_to_5_6/manifest.yml +17 -9
  1056. data/lib/spree/upgrades/5_6_to_6_0/manifest.yml +683 -0
  1057. data/lib/spree/validators.rb +74 -0
  1058. data/lib/spree/workflow.rb +335 -0
  1059. data/lib/tasks/backfill_actor_types.rake +35 -0
  1060. data/lib/tasks/backfill_custom_field_definition_stores.rake +82 -0
  1061. data/lib/tasks/backfill_import_export_tenancy.rake +93 -0
  1062. data/lib/tasks/backfill_library_media_placements.rake +29 -0
  1063. data/lib/tasks/backfill_media_store_ids.rake +70 -0
  1064. data/lib/tasks/backfill_reason_store_ids.rake +28 -0
  1065. data/lib/tasks/capture_methods_migration.rake +30 -0
  1066. data/lib/tasks/carts_migration.rake +113 -0
  1067. data/lib/tasks/categories_and_collections.rake +188 -0
  1068. data/lib/tasks/cli.rake +22 -3
  1069. data/lib/tasks/consolidate_metadata.rake +73 -0
  1070. data/lib/tasks/core.rake +1 -11
  1071. data/lib/tasks/deliveries_migration.rake +52 -0
  1072. data/lib/tasks/delivery_method_rules_migration.rake +51 -0
  1073. data/lib/tasks/delivery_migration.rake +213 -0
  1074. data/lib/tasks/delivery_profiles_migration.rake +109 -0
  1075. data/lib/tasks/fold_store_credit_categories.rake +40 -0
  1076. data/lib/tasks/fulfillment_statuses_migration.rake +59 -0
  1077. data/lib/tasks/inventory_operations_migration.rake +223 -0
  1078. data/lib/tasks/markets.rake +7 -2
  1079. data/lib/tasks/media.rake +2 -2
  1080. data/lib/tasks/media_class_rename.rake +56 -0
  1081. data/lib/tasks/migrate_country_state_codes.rake +228 -0
  1082. data/lib/tasks/migrate_promotion_option_value_rules.rake +124 -0
  1083. data/lib/tasks/migrate_returns.rake +322 -0
  1084. data/lib/tasks/migrate_rich_text_to_columns.rake +128 -0
  1085. data/lib/tasks/migrate_users_to_customers.rake +161 -0
  1086. data/lib/tasks/order_coupon_code_backfill.rake +32 -0
  1087. data/lib/tasks/order_market_backfill.rake +27 -0
  1088. data/lib/tasks/package_types.rake +62 -0
  1089. data/lib/tasks/price_history.rake +49 -6
  1090. data/lib/tasks/products.rake +21 -2
  1091. data/lib/tasks/remove_master_variant.rake +58 -0
  1092. data/lib/tasks/rich_text.rake +44 -0
  1093. data/lib/tasks/seller_sample_data.rake +142 -0
  1094. data/lib/tasks/setup.rake +18 -0
  1095. data/lib/tasks/single_store_associations.rake +11 -0
  1096. data/lib/tasks/stock.rake +15 -0
  1097. data/lib/tasks/store_binding_migration.rake +33 -0
  1098. data/lib/tasks/store_settings.rake +105 -0
  1099. data/lib/tasks/tax_zones_migration.rake +147 -0
  1100. data/lib/tasks/taxons.rake +9 -10
  1101. data/lib/tasks/typed_adjustments_migration.rake +189 -0
  1102. data/lib/tasks/typed_stock_movements_migration.rake +250 -0
  1103. data/lib/tasks/upgrade.rake +13 -8
  1104. data/spec/fixtures/files/eu_vat_numbers.txt +56 -0
  1105. data/spec/fixtures/files/price_list_prices_import.csv +4 -0
  1106. data/spec/fixtures/files/products_import.csv +1 -1
  1107. data/spec/fixtures/tiny-video.mp4 +0 -0
  1108. metadata +798 -546
  1109. data/app/assets/config/spree_core_manifest.js +0 -4
  1110. data/app/assets/images/google_on_white_hdpi.png +0 -0
  1111. data/app/assets/images/logo.png +0 -0
  1112. data/app/assets/images/payment_icons/ach.svg +0 -1
  1113. data/app/assets/images/payment_icons/achdirectdebit.svg +0 -1
  1114. data/app/assets/images/payment_icons/ada.svg +0 -1
  1115. data/app/assets/images/payment_icons/adyen.svg +0 -1
  1116. data/app/assets/images/payment_icons/affinbank.svg +0 -1
  1117. data/app/assets/images/payment_icons/affirm.svg +0 -1
  1118. data/app/assets/images/payment_icons/afterpay.svg +0 -1
  1119. data/app/assets/images/payment_icons/airtel_money.svg +0 -1
  1120. data/app/assets/images/payment_icons/airteltigo_mobile_money.svg +0 -1
  1121. data/app/assets/images/payment_icons/alandsbanken.svg +0 -1
  1122. data/app/assets/images/payment_icons/alipay.svg +0 -1
  1123. data/app/assets/images/payment_icons/alipay_hk.svg +0 -1
  1124. data/app/assets/images/payment_icons/alliancebank.svg +0 -1
  1125. data/app/assets/images/payment_icons/alma.svg +0 -1
  1126. data/app/assets/images/payment_icons/amazon.svg +0 -1
  1127. data/app/assets/images/payment_icons/ambank.svg +0 -1
  1128. data/app/assets/images/payment_icons/american_express.svg +0 -1
  1129. data/app/assets/images/payment_icons/apecoin.svg +0 -1
  1130. data/app/assets/images/payment_icons/apple_pay.svg +0 -1
  1131. data/app/assets/images/payment_icons/arbitrum.svg +0 -1
  1132. data/app/assets/images/payment_icons/atome.svg +0 -1
  1133. data/app/assets/images/payment_icons/authorizenet.svg +0 -1
  1134. data/app/assets/images/payment_icons/avalanche.svg +0 -1
  1135. data/app/assets/images/payment_icons/bacs.svg +0 -1
  1136. data/app/assets/images/payment_icons/bancontact.svg +0 -1
  1137. data/app/assets/images/payment_icons/bangkokbank.svg +0 -1
  1138. data/app/assets/images/payment_icons/bankislam.svg +0 -1
  1139. data/app/assets/images/payment_icons/bankmuamalat.svg +0 -1
  1140. data/app/assets/images/payment_icons/bankofamerica.svg +0 -1
  1141. data/app/assets/images/payment_icons/bankrakyat.svg +0 -1
  1142. data/app/assets/images/payment_icons/banktransfer.svg +0 -1
  1143. data/app/assets/images/payment_icons/base.svg +0 -1
  1144. data/app/assets/images/payment_icons/becs.svg +0 -1
  1145. data/app/assets/images/payment_icons/benefit.svg +0 -1
  1146. data/app/assets/images/payment_icons/billie.svg +0 -1
  1147. data/app/assets/images/payment_icons/bitcoin.svg +0 -1
  1148. data/app/assets/images/payment_icons/bitcoin_cash.svg +0 -1
  1149. data/app/assets/images/payment_icons/bizum.svg +0 -1
  1150. data/app/assets/images/payment_icons/blik.svg +0 -1
  1151. data/app/assets/images/payment_icons/bnbchain.svg +0 -1
  1152. data/app/assets/images/payment_icons/bogus.svg +0 -1
  1153. data/app/assets/images/payment_icons/bogus_app_coin.svg +0 -1
  1154. data/app/assets/images/payment_icons/boleto.svg +0 -1
  1155. data/app/assets/images/payment_icons/boost.svg +0 -1
  1156. data/app/assets/images/payment_icons/braintree.svg +0 -1
  1157. data/app/assets/images/payment_icons/buckaroopaybybank.svg +0 -1
  1158. data/app/assets/images/payment_icons/busd.svg +0 -1
  1159. data/app/assets/images/payment_icons/cartes_bancaires.svg +0 -1
  1160. data/app/assets/images/payment_icons/cash.svg +0 -1
  1161. data/app/assets/images/payment_icons/cashappafterpay.svg +0 -1
  1162. data/app/assets/images/payment_icons/cashapppay.svg +0 -1
  1163. data/app/assets/images/payment_icons/checkout_finance.svg +0 -1
  1164. data/app/assets/images/payment_icons/chinabank.svg +0 -1
  1165. data/app/assets/images/payment_icons/clearpay.svg +0 -1
  1166. data/app/assets/images/payment_icons/collector_bank.svg +0 -1
  1167. data/app/assets/images/payment_icons/dai.svg +0 -1
  1168. data/app/assets/images/payment_icons/dana.svg +0 -1
  1169. data/app/assets/images/payment_icons/dankort.svg +0 -1
  1170. data/app/assets/images/payment_icons/danske_bank.svg +0 -1
  1171. data/app/assets/images/payment_icons/deutschebank.svg +0 -1
  1172. data/app/assets/images/payment_icons/diners_club.svg +0 -1
  1173. data/app/assets/images/payment_icons/directbanktransferlatinamerica.svg +0 -1
  1174. data/app/assets/images/payment_icons/discover.svg +0 -1
  1175. data/app/assets/images/payment_icons/dogecoin.svg +0 -1
  1176. data/app/assets/images/payment_icons/duitnow.svg +0 -1
  1177. data/app/assets/images/payment_icons/eft_secure.svg +0 -1
  1178. data/app/assets/images/payment_icons/eftpos_au.svg +0 -1
  1179. data/app/assets/images/payment_icons/eftposau.svg +0 -1
  1180. data/app/assets/images/payment_icons/elo.svg +0 -1
  1181. data/app/assets/images/payment_icons/eos.svg +0 -1
  1182. data/app/assets/images/payment_icons/eps.svg +0 -1
  1183. data/app/assets/images/payment_icons/ethereum.svg +0 -1
  1184. data/app/assets/images/payment_icons/eurobonuscheckout.svg +0 -1
  1185. data/app/assets/images/payment_icons/ezcash.svg +0 -1
  1186. data/app/assets/images/payment_icons/fantom.svg +0 -1
  1187. data/app/assets/images/payment_icons/fpx.svg +0 -1
  1188. data/app/assets/images/payment_icons/gcash.svg +0 -1
  1189. data/app/assets/images/payment_icons/generic.svg +0 -1
  1190. data/app/assets/images/payment_icons/genericbank.svg +0 -1
  1191. data/app/assets/images/payment_icons/gift-card.svg +0 -1
  1192. data/app/assets/images/payment_icons/giropay.svg +0 -1
  1193. data/app/assets/images/payment_icons/glbepaypal.svg +0 -1
  1194. data/app/assets/images/payment_icons/gmobanktransfer.svg +0 -1
  1195. data/app/assets/images/payment_icons/gnosis.svg +0 -1
  1196. data/app/assets/images/payment_icons/google_pay.svg +0 -1
  1197. data/app/assets/images/payment_icons/google_wallet.svg +0 -1
  1198. data/app/assets/images/payment_icons/gopay.svg +0 -1
  1199. data/app/assets/images/payment_icons/grabpay.svg +0 -1
  1200. data/app/assets/images/payment_icons/gusd.svg +0 -1
  1201. data/app/assets/images/payment_icons/handelsbanken.svg +0 -1
  1202. data/app/assets/images/payment_icons/hongleongbank.svg +0 -1
  1203. data/app/assets/images/payment_icons/hypercard.svg +0 -1
  1204. data/app/assets/images/payment_icons/hypercash.svg +0 -1
  1205. data/app/assets/images/payment_icons/ideal.svg +0 -1
  1206. data/app/assets/images/payment_icons/in3viaideal.svg +0 -1
  1207. data/app/assets/images/payment_icons/inbank.svg +0 -1
  1208. data/app/assets/images/payment_icons/jcb.svg +0 -1
  1209. data/app/assets/images/payment_icons/kakao_pay.svg +0 -1
  1210. data/app/assets/images/payment_icons/kasikornbank.svg +0 -1
  1211. data/app/assets/images/payment_icons/klarna-pay-later.svg +0 -1
  1212. data/app/assets/images/payment_icons/klarna-pay-now.svg +0 -1
  1213. data/app/assets/images/payment_icons/klarna-slice-it.svg +0 -1
  1214. data/app/assets/images/payment_icons/klarna.svg +0 -1
  1215. data/app/assets/images/payment_icons/knet.svg +0 -1
  1216. data/app/assets/images/payment_icons/krungthaibank.svg +0 -1
  1217. data/app/assets/images/payment_icons/landbank.svg +0 -1
  1218. data/app/assets/images/payment_icons/laybuybyklarna.svg +0 -1
  1219. data/app/assets/images/payment_icons/litecoin.svg +0 -1
  1220. data/app/assets/images/payment_icons/lunchcheck.svg +0 -1
  1221. data/app/assets/images/payment_icons/mach.svg +0 -1
  1222. data/app/assets/images/payment_icons/mada.svg +0 -1
  1223. data/app/assets/images/payment_icons/maestro.svg +0 -1
  1224. data/app/assets/images/payment_icons/master.svg +0 -1
  1225. data/app/assets/images/payment_icons/mayabank.svg +0 -1
  1226. data/app/assets/images/payment_icons/maybank.svg +0 -1
  1227. data/app/assets/images/payment_icons/maybankm2u.svg +0 -1
  1228. data/app/assets/images/payment_icons/maybankqrpay.svg +0 -1
  1229. data/app/assets/images/payment_icons/mbway.svg +0 -1
  1230. data/app/assets/images/payment_icons/mcash.svg +0 -1
  1231. data/app/assets/images/payment_icons/medicinosbankas.svg +0 -1
  1232. data/app/assets/images/payment_icons/mercadopago.svg +0 -1
  1233. data/app/assets/images/payment_icons/metrobank.svg +0 -1
  1234. data/app/assets/images/payment_icons/mobilepay.svg +0 -1
  1235. data/app/assets/images/payment_icons/momopay.svg +0 -1
  1236. data/app/assets/images/payment_icons/monero.svg +0 -1
  1237. data/app/assets/images/payment_icons/mtn_mobile_money.svg +0 -1
  1238. data/app/assets/images/payment_icons/mybank.svg +0 -1
  1239. data/app/assets/images/payment_icons/naver_pay.svg +0 -1
  1240. data/app/assets/images/payment_icons/nelo.svg +0 -1
  1241. data/app/assets/images/payment_icons/netbanking.svg +0 -1
  1242. data/app/assets/images/payment_icons/novalnetdirectdebitach.svg +0 -1
  1243. data/app/assets/images/payment_icons/nubank.svg +0 -1
  1244. data/app/assets/images/payment_icons/ocbcbank.svg +0 -1
  1245. data/app/assets/images/payment_icons/offlinebanktransferlatinamerica.svg +0 -1
  1246. data/app/assets/images/payment_icons/ola_money.svg +0 -1
  1247. data/app/assets/images/payment_icons/oney.svg +0 -1
  1248. data/app/assets/images/payment_icons/onlinebanking.svg +0 -1
  1249. data/app/assets/images/payment_icons/onlinebanktransfer.svg +0 -1
  1250. data/app/assets/images/payment_icons/orangemobilemoney.svg +0 -1
  1251. data/app/assets/images/payment_icons/otpbank.svg +0 -1
  1252. data/app/assets/images/payment_icons/oxxo.svg +0 -1
  1253. data/app/assets/images/payment_icons/paybybank.svg +0 -1
  1254. data/app/assets/images/payment_icons/paybybankmollie.svg +0 -1
  1255. data/app/assets/images/payment_icons/paybybankus.svg +0 -1
  1256. data/app/assets/images/payment_icons/paycash.svg +0 -1
  1257. data/app/assets/images/payment_icons/payco.svg +0 -1
  1258. data/app/assets/images/payment_icons/payeverpaybybank.svg +0 -1
  1259. data/app/assets/images/payment_icons/payme.svg +0 -1
  1260. data/app/assets/images/payment_icons/paynow.svg +0 -1
  1261. data/app/assets/images/payment_icons/paynowmbank.svg +0 -1
  1262. data/app/assets/images/payment_icons/paypal.svg +0 -1
  1263. data/app/assets/images/payment_icons/paypo.svg +0 -1
  1264. data/app/assets/images/payment_icons/payrexxbanktransfer.svg +0 -1
  1265. data/app/assets/images/payment_icons/payrexxpaybybank.svg +0 -1
  1266. data/app/assets/images/payment_icons/paysafecash.svg +0 -1
  1267. data/app/assets/images/payment_icons/pix.svg +0 -1
  1268. data/app/assets/images/payment_icons/polygon.svg +0 -1
  1269. data/app/assets/images/payment_icons/przelewy24.svg +0 -1
  1270. data/app/assets/images/payment_icons/publicbank.svg +0 -1
  1271. data/app/assets/images/payment_icons/publicbank_pbe.svg +0 -1
  1272. data/app/assets/images/payment_icons/qr_promptpay.svg +0 -1
  1273. data/app/assets/images/payment_icons/rabobank.svg +0 -1
  1274. data/app/assets/images/payment_icons/revolut.svg +0 -1
  1275. data/app/assets/images/payment_icons/rhbbank.svg +0 -1
  1276. data/app/assets/images/payment_icons/riverty.svg +0 -1
  1277. data/app/assets/images/payment_icons/safetypaybanktransfer.svg +0 -1
  1278. data/app/assets/images/payment_icons/samsung_pay.svg +0 -1
  1279. data/app/assets/images/payment_icons/satispay.svg +0 -1
  1280. data/app/assets/images/payment_icons/scalapay.svg +0 -1
  1281. data/app/assets/images/payment_icons/scotiabank.svg +0 -1
  1282. data/app/assets/images/payment_icons/seabankid.svg +0 -1
  1283. data/app/assets/images/payment_icons/seabankph.svg +0 -1
  1284. data/app/assets/images/payment_icons/sepa_bank_transfer.svg +0 -1
  1285. data/app/assets/images/payment_icons/sepadebit.svg +0 -22
  1286. data/app/assets/images/payment_icons/sepadirectdebit.svg +0 -1
  1287. data/app/assets/images/payment_icons/seveneleven.svg +0 -1
  1288. data/app/assets/images/payment_icons/shib.svg +0 -1
  1289. data/app/assets/images/payment_icons/shopcash.svg +0 -1
  1290. data/app/assets/images/payment_icons/siauliubankas.svg +0 -1
  1291. data/app/assets/images/payment_icons/skeps.svg +0 -1
  1292. data/app/assets/images/payment_icons/snap_checkout.svg +0 -1
  1293. data/app/assets/images/payment_icons/sofort.svg +0 -1
  1294. data/app/assets/images/payment_icons/softbank.svg +0 -1
  1295. data/app/assets/images/payment_icons/spei.svg +0 -1
  1296. data/app/assets/images/payment_icons/storecredit.svg +0 -1
  1297. data/app/assets/images/payment_icons/stripe.svg +0 -1
  1298. data/app/assets/images/payment_icons/sveacheckout.svg +0 -1
  1299. data/app/assets/images/payment_icons/swedbank.svg +0 -1
  1300. data/app/assets/images/payment_icons/swish.svg +0 -1
  1301. data/app/assets/images/payment_icons/tbibank.svg +0 -1
  1302. data/app/assets/images/payment_icons/thanachartbank.svg +0 -1
  1303. data/app/assets/images/payment_icons/tnmmoney.svg +0 -1
  1304. data/app/assets/images/payment_icons/touchngo.svg +0 -1
  1305. data/app/assets/images/payment_icons/trustly.svg +0 -1
  1306. data/app/assets/images/payment_icons/twint.svg +0 -1
  1307. data/app/assets/images/payment_icons/uaevisa.svg +0 -1
  1308. data/app/assets/images/payment_icons/unionpay.svg +0 -1
  1309. data/app/assets/images/payment_icons/unzerbanktransfer.svg +0 -1
  1310. data/app/assets/images/payment_icons/upi.svg +0 -1
  1311. data/app/assets/images/payment_icons/usbank.svg +0 -1
  1312. data/app/assets/images/payment_icons/usdc.svg +0 -1
  1313. data/app/assets/images/payment_icons/usdt.svg +0 -1
  1314. data/app/assets/images/payment_icons/venmo.svg +0 -1
  1315. data/app/assets/images/payment_icons/vipps.svg +0 -1
  1316. data/app/assets/images/payment_icons/visa.svg +0 -1
  1317. data/app/assets/images/payment_icons/volksbank.svg +0 -1
  1318. data/app/assets/images/payment_icons/waavepaybybank.svg +0 -1
  1319. data/app/assets/images/payment_icons/walley.svg +0 -1
  1320. data/app/assets/images/payment_icons/wbtc.svg +0 -1
  1321. data/app/assets/images/payment_icons/wechatpay.svg +0 -1
  1322. data/app/assets/images/payment_icons/whishcheckout.svg +0 -1
  1323. data/app/assets/images/payment_icons/wingbank.svg +0 -1
  1324. data/app/assets/images/payment_icons/xrp.svg +0 -1
  1325. data/app/assets/images/payment_icons/zip.svg +0 -1
  1326. data/app/controllers/spree/base_controller.rb +0 -11
  1327. data/app/finders/concerns/spree/product_filterable.rb +0 -9
  1328. data/app/finders/spree/addresses/find.rb +0 -27
  1329. data/app/finders/spree/base_finder.rb +0 -14
  1330. data/app/finders/spree/countries/find.rb +0 -31
  1331. data/app/finders/spree/credit_cards/find.rb +0 -12
  1332. data/app/finders/spree/option_values/find_available.rb +0 -28
  1333. data/app/finders/spree/orders/find_complete.rb +0 -114
  1334. data/app/finders/spree/orders/find_current.rb +0 -24
  1335. data/app/finders/spree/orders/finder_helper.rb +0 -17
  1336. data/app/finders/spree/products/find.rb +0 -328
  1337. data/app/finders/spree/taxons/find.rb +0 -99
  1338. data/app/finders/spree/variants/find.rb +0 -30
  1339. data/app/finders/spree/variants/option_types_finder.rb +0 -21
  1340. data/app/helpers/spree/addresses_helper.rb +0 -97
  1341. data/app/helpers/spree/base_helper.rb +0 -132
  1342. data/app/helpers/spree/currency_helper.rb +0 -46
  1343. data/app/helpers/spree/integrations_helper.rb +0 -15
  1344. data/app/helpers/spree/locale_helper.rb +0 -44
  1345. data/app/helpers/spree/localized_names_helper.rb +0 -25
  1346. data/app/helpers/spree/products_helper.rb +0 -147
  1347. data/app/helpers/spree/shipment_helper.rb +0 -12
  1348. data/app/javascript/spree/core/controllers/address_autocomplete_controller.js +0 -230
  1349. data/app/javascript/spree/core/controllers/address_form_controller.js +0 -98
  1350. data/app/javascript/spree/core/controllers/disable_submit_button_controller.js +0 -19
  1351. data/app/javascript/spree/core/controllers/enable_button_controller.js +0 -29
  1352. data/app/javascript/spree/core/helpers/address_autocomplete/google_places_suggestions_provider.js +0 -161
  1353. data/app/javascript/spree/core/helpers/debounce.js +0 -9
  1354. data/app/javascript/spree/core/helpers/scroll_lock.js +0 -25
  1355. data/app/jobs/spree/media/migrate_product_assets_job.rb +0 -83
  1356. data/app/jobs/spree/reports/generate_job.rb +0 -23
  1357. data/app/mailers/spree/report_mailer.rb +0 -20
  1358. data/app/models/concerns/spree/adjustment_source.rb +0 -58
  1359. data/app/models/concerns/spree/default_price.rb +0 -138
  1360. data/app/models/concerns/spree/display_on.rb +0 -50
  1361. data/app/models/concerns/spree/image_methods.rb +0 -40
  1362. data/app/models/concerns/spree/legacy_multi_store_support.rb +0 -48
  1363. data/app/models/concerns/spree/metafield_filterable.rb +0 -162
  1364. data/app/models/concerns/spree/metafields.rb +0 -256
  1365. data/app/models/concerns/spree/number_as_param.rb +0 -13
  1366. data/app/models/concerns/spree/store_scoped_resource.rb +0 -37
  1367. data/app/models/concerns/spree/unique_name.rb +0 -12
  1368. data/app/models/spree/adjustable/adjuster/base.rb +0 -25
  1369. data/app/models/spree/adjustable/adjuster/promotion.rb +0 -41
  1370. data/app/models/spree/adjustable/adjuster/tax.rb +0 -26
  1371. data/app/models/spree/adjustable/adjustments_updater.rb +0 -74
  1372. data/app/models/spree/adjustable/promotion_accumulator.rb +0 -78
  1373. data/app/models/spree/adjustment.rb +0 -130
  1374. data/app/models/spree/asset/support/active_storage.rb +0 -26
  1375. data/app/models/spree/calculator/default_tax.rb +0 -87
  1376. data/app/models/spree/calculator/returns/default_refund_amount.rb +0 -40
  1377. data/app/models/spree/checkout/default_requirements.rb +0 -51
  1378. data/app/models/spree/checkout/registry.rb +0 -112
  1379. data/app/models/spree/checkout/requirement.rb +0 -49
  1380. data/app/models/spree/checkout/requirements.rb +0 -56
  1381. data/app/models/spree/checkout/step.rb +0 -52
  1382. data/app/models/spree/customer_return.rb +0 -94
  1383. data/app/models/spree/image/configuration/active_storage.rb +0 -11
  1384. data/app/models/spree/image.rb +0 -6
  1385. data/app/models/spree/legacy_admin_user.rb +0 -31
  1386. data/app/models/spree/legacy_user.rb +0 -33
  1387. data/app/models/spree/log_entry.rb +0 -30
  1388. data/app/models/spree/metafield_definition/search_capabilities.rb +0 -104
  1389. data/app/models/spree/metafields/boolean.rb +0 -15
  1390. data/app/models/spree/metafields/json.rb +0 -37
  1391. data/app/models/spree/metafields/long_text.rb +0 -11
  1392. data/app/models/spree/metafields/number.rb +0 -23
  1393. data/app/models/spree/metafields/rich_text.rb +0 -18
  1394. data/app/models/spree/metafields/short_text.rb +0 -15
  1395. data/app/models/spree/option_type_prototype.rb +0 -9
  1396. data/app/models/spree/order/address_book.rb +0 -100
  1397. data/app/models/spree/order/checkout.rb +0 -350
  1398. data/app/models/spree/order/currency_updater.rb +0 -37
  1399. data/app/models/spree/order/digital.rb +0 -60
  1400. data/app/models/spree/order/gift_card.rb +0 -71
  1401. data/app/models/spree/order/payments.rb +0 -64
  1402. data/app/models/spree/order/store_credit.rb +0 -110
  1403. data/app/models/spree/order/webhooks.rb +0 -19
  1404. data/app/models/spree/order_approval.rb +0 -19
  1405. data/app/models/spree/order_cancellation.rb +0 -19
  1406. data/app/models/spree/order_contents.rb +0 -31
  1407. data/app/models/spree/order_routing/strategy/legacy.rb +0 -33
  1408. data/app/models/spree/payment/webhooks.rb +0 -15
  1409. data/app/models/spree/permission_sets/base.rb +0 -81
  1410. data/app/models/spree/permission_sets/configuration_management.rb +0 -64
  1411. data/app/models/spree/permission_sets/dashboard_display.rb +0 -17
  1412. data/app/models/spree/permission_sets/default_customer.rb +0 -83
  1413. data/app/models/spree/permission_sets/order_display.rb +0 -27
  1414. data/app/models/spree/permission_sets/order_management.rb +0 -33
  1415. data/app/models/spree/permission_sets/product_display.rb +0 -27
  1416. data/app/models/spree/permission_sets/product_management.rb +0 -28
  1417. data/app/models/spree/permission_sets/promotion_management.rb +0 -22
  1418. data/app/models/spree/permission_sets/role_management.rb +0 -21
  1419. data/app/models/spree/permission_sets/stock_display.rb +0 -19
  1420. data/app/models/spree/permission_sets/stock_management.rb +0 -19
  1421. data/app/models/spree/permission_sets/super_user.rb +0 -28
  1422. data/app/models/spree/permission_sets/user_display.rb +0 -19
  1423. data/app/models/spree/permission_sets/user_management.rb +0 -20
  1424. data/app/models/spree/product/webhooks.rb +0 -17
  1425. data/app/models/spree/prototype_taxon.rb +0 -9
  1426. data/app/models/spree/reimbursement/credit.rb +0 -27
  1427. data/app/models/spree/reimbursement/reimbursement_type_engine.rb +0 -44
  1428. data/app/models/spree/reimbursement/reimbursement_type_validator.rb +0 -15
  1429. data/app/models/spree/reimbursement.rb +0 -167
  1430. data/app/models/spree/reimbursement_performer.rb +0 -34
  1431. data/app/models/spree/reimbursement_tax_calculator.rb +0 -37
  1432. data/app/models/spree/reimbursement_type/credit.rb +0 -13
  1433. data/app/models/spree/reimbursement_type/exchange.rb +0 -9
  1434. data/app/models/spree/reimbursement_type/original_payment.rb +0 -13
  1435. data/app/models/spree/reimbursement_type/reimbursement_helpers.rb +0 -64
  1436. data/app/models/spree/reimbursement_type/store_credit.rb +0 -20
  1437. data/app/models/spree/reimbursement_type.rb +0 -22
  1438. data/app/models/spree/report.rb +0 -140
  1439. data/app/models/spree/report_line_item.rb +0 -27
  1440. data/app/models/spree/report_line_items/products_performance.rb +0 -76
  1441. data/app/models/spree/report_line_items/sales_total.rb +0 -49
  1442. data/app/models/spree/reports/products_performance.rb +0 -44
  1443. data/app/models/spree/reports/sales_total.rb +0 -18
  1444. data/app/models/spree/return_authorization.rb +0 -109
  1445. data/app/models/spree/return_item/eligibility_validator/base_validator.rb +0 -24
  1446. data/app/models/spree/return_item/eligibility_validator/default.rb +0 -30
  1447. data/app/models/spree/return_item/eligibility_validator/inventory_shipped.rb +0 -16
  1448. data/app/models/spree/return_item/eligibility_validator/no_reimbursements.rb +0 -16
  1449. data/app/models/spree/return_item/eligibility_validator/order_completed.rb +0 -16
  1450. data/app/models/spree/return_item/eligibility_validator/rma_required.rb +0 -16
  1451. data/app/models/spree/return_item/eligibility_validator/time_since_purchase.rb +0 -16
  1452. data/app/models/spree/return_item/exchange_variant_eligibility/same_option_value.rb +0 -34
  1453. data/app/models/spree/return_item/exchange_variant_eligibility/same_product.rb +0 -9
  1454. data/app/models/spree/return_item.rb +0 -287
  1455. data/app/models/spree/returns_calculator.rb +0 -7
  1456. data/app/models/spree/search_provider/meilisearch.rb +0 -551
  1457. data/app/models/spree/shipment/custom_events.rb +0 -47
  1458. data/app/models/spree/shipment/webhooks.rb +0 -11
  1459. data/app/models/spree/shipment_handler.rb +0 -38
  1460. data/app/models/spree/shipping_category.rb +0 -25
  1461. data/app/models/spree/shipping_method_category.rb +0 -8
  1462. data/app/models/spree/shipping_method_zone.rb +0 -8
  1463. data/app/models/spree/state_change.rb +0 -12
  1464. data/app/models/spree/stock/splitter/digital.rb +0 -35
  1465. data/app/models/spree/stock/splitter/shipping_category.rb +0 -31
  1466. data/app/models/spree/stock_item/webhooks.rb +0 -6
  1467. data/app/models/spree/stock_movement/webhooks.rb +0 -6
  1468. data/app/models/spree/variant/webhooks.rb +0 -6
  1469. data/app/presenters/spree/csv/metafields_helper.rb +0 -17
  1470. data/app/presenters/spree/search_provider/product_presenter.rb +0 -158
  1471. data/app/presenters/spree/variant_presenter.rb +0 -81
  1472. data/app/presenters/spree/variants/option_types_presenter.rb +0 -87
  1473. data/app/services/spree/account/addresses/create.rb +0 -8
  1474. data/app/services/spree/account/addresses/update.rb +0 -8
  1475. data/app/services/spree/account/create.rb +0 -17
  1476. data/app/services/spree/account/update.rb +0 -15
  1477. data/app/services/spree/cart/add_item.rb +0 -63
  1478. data/app/services/spree/cart/associate.rb +0 -29
  1479. data/app/services/spree/cart/change_currency.rb +0 -27
  1480. data/app/services/spree/cart/create.rb +0 -26
  1481. data/app/services/spree/cart/destroy.rb +0 -50
  1482. data/app/services/spree/cart/empty.rb +0 -38
  1483. data/app/services/spree/cart/estimate_shipping_rates.rb +0 -39
  1484. data/app/services/spree/cart/recalculate.rb +0 -35
  1485. data/app/services/spree/cart/remove_item.rb +0 -39
  1486. data/app/services/spree/cart/remove_line_item.rb +0 -28
  1487. data/app/services/spree/cart/remove_out_of_stock_items.rb +0 -65
  1488. data/app/services/spree/cart/set_quantity.rb +0 -32
  1489. data/app/services/spree/cart/update.rb +0 -37
  1490. data/app/services/spree/carts/complete.rb +0 -50
  1491. data/app/services/spree/carts/upsert_items.rb +0 -76
  1492. data/app/services/spree/checkout/complete.rb +0 -23
  1493. data/app/services/spree/checkout/get_shipping_rates.rb +0 -52
  1494. data/app/services/spree/checkout/next.rb +0 -13
  1495. data/app/services/spree/checkout/select_shipping_method.rb +0 -63
  1496. data/app/services/spree/checkout/update.rb +0 -72
  1497. data/app/services/spree/credit_cards/destroy.rb +0 -25
  1498. data/app/services/spree/fulfillments/create.rb +0 -259
  1499. data/app/services/spree/gift_cards/apply.rb +0 -78
  1500. data/app/services/spree/gift_cards/redeem.rb +0 -17
  1501. data/app/services/spree/gift_cards/remove.rb +0 -39
  1502. data/app/services/spree/line_items/create.rb +0 -20
  1503. data/app/services/spree/line_items/destroy.rb +0 -18
  1504. data/app/services/spree/line_items/helper.rb +0 -11
  1505. data/app/services/spree/line_items/update.rb +0 -17
  1506. data/app/services/spree/orders/build_shipments.rb +0 -29
  1507. data/app/services/spree/orders/cancel.rb +0 -54
  1508. data/app/services/spree/orders/complete.rb +0 -53
  1509. data/app/services/spree/orders/update_contact_information.rb +0 -19
  1510. data/app/services/spree/orders/upsert_items.rb +0 -70
  1511. data/app/services/spree/payments/handle_webhook.rb +0 -57
  1512. data/app/services/spree/search_provider/metafield_schema.rb +0 -144
  1513. data/app/services/spree/seeds/countries.rb +0 -35
  1514. data/app/services/spree/seeds/default_reimbursement_types.rb +0 -12
  1515. data/app/services/spree/seeds/shipping_categories.rb +0 -12
  1516. data/app/services/spree/seeds/states.rb +0 -82
  1517. data/app/services/spree/seeds/stock_locations.rb +0 -18
  1518. data/app/services/spree/seeds/store_credit_categories.rb +0 -14
  1519. data/app/services/spree/seeds/zones.rb +0 -52
  1520. data/app/services/spree/shipments/add_item.rb +0 -32
  1521. data/app/services/spree/shipments/change_state.rb +0 -14
  1522. data/app/services/spree/shipments/create.rb +0 -48
  1523. data/app/services/spree/shipments/helper.rb +0 -23
  1524. data/app/services/spree/shipments/remove_item.rb +0 -55
  1525. data/app/services/spree/stores/settings_defaults_by_country.rb +0 -38
  1526. data/app/services/spree/themes/duplicator.rb +0 -40
  1527. data/app/sorters/spree/base_sorter.rb +0 -47
  1528. data/app/sorters/spree/classifications/sort.rb +0 -68
  1529. data/app/sorters/spree/products/sort.rb +0 -73
  1530. data/app/subscribers/spree/report_subscriber.rb +0 -26
  1531. data/app/views/spree/addresses/_form.html.erb +0 -59
  1532. data/app/views/spree/addresses/_suggestions_box.erb +0 -14
  1533. data/app/views/spree/admin_user_mailer/confirmation_email.html.erb +0 -7
  1534. data/app/views/spree/report_mailer/report_done.html.erb +0 -7
  1535. data/app/views/spree/shared/_google_places_api_loader.html.erb +0 -7
  1536. data/app/views/spree/shared/_mailer_line_item.html.erb +0 -12
  1537. data/app/views/spree/shared/_payment.html.erb +0 -52
  1538. data/config/importmap.rb +0 -15
  1539. data/config/initializers/carmen.rb +0 -23
  1540. data/config/initializers/rails61_fixes.rb +0 -1
  1541. data/db/migrate/20250120152208_add_default_locale_to_action_text_rich_texts.rb +0 -7
  1542. data/db/migrate/20250122113708_add_first_and_last_name_to_spree_admin_class.rb +0 -9
  1543. data/db/migrate/20250204162453_create_spree_reports.rb +0 -13
  1544. data/db/migrate/20250217171018_create_action_text_video_embeds.rb +0 -11
  1545. data/db/migrate/20250508060800_add_selected_locale_to_spree_admin_users.rb +0 -8
  1546. data/db/migrate/20260429000001_create_spree_order_cancellations.rb +0 -25
  1547. data/db/migrate/20260429000002_create_spree_order_approvals.rb +0 -22
  1548. data/db/sample_data/markets.rb +0 -64
  1549. data/db/sample_data/metafield_definitions.rb +0 -7
  1550. data/db/sample_data/shipping_methods.rb +0 -61
  1551. data/lib/generators/spree/authentication/custom/custom_generator.rb +0 -49
  1552. data/lib/generators/spree/authentication/custom/templates/authentication_helpers.rb.tt +0 -50
  1553. data/lib/generators/spree/authentication/devise/devise_generator.rb +0 -84
  1554. data/lib/generators/spree/authentication/devise/templates/authentication_helpers.rb.tt +0 -50
  1555. data/lib/generators/spree/dummy/templates/app/assets/config/manifest.js +0 -0
  1556. data/lib/spree/core/components.rb +0 -31
  1557. data/lib/spree/core/controller_helpers/auth.rb +0 -52
  1558. data/lib/spree/core/controller_helpers/currency.rb +0 -59
  1559. data/lib/spree/core/controller_helpers/locale.rb +0 -99
  1560. data/lib/spree/core/controller_helpers/order.rb +0 -172
  1561. data/lib/spree/core/controller_helpers/strong_parameters.rb +0 -48
  1562. data/lib/spree/core/controller_helpers/turbo.rb +0 -19
  1563. data/lib/spree/core/partials.rb +0 -42
  1564. data/lib/spree/core/previews/report_preview.rb +0 -40
  1565. data/lib/spree/permitted_attributes.rb +0 -337
  1566. data/lib/spree/testing_support/authorization_helpers.rb +0 -72
  1567. data/lib/spree/testing_support/caching.rb +0 -47
  1568. data/lib/spree/testing_support/capybara_config.rb +0 -45
  1569. data/lib/spree/testing_support/capybara_ext.rb +0 -83
  1570. data/lib/spree/testing_support/controller_requests.rb +0 -11
  1571. data/lib/spree/testing_support/factories/adjustment_factory.rb +0 -28
  1572. data/lib/spree/testing_support/factories/asset_factory.rb +0 -12
  1573. data/lib/spree/testing_support/factories/customer_return_factory.rb +0 -36
  1574. data/lib/spree/testing_support/factories/digital_factory.rb +0 -10
  1575. data/lib/spree/testing_support/factories/image_factory.rb +0 -11
  1576. data/lib/spree/testing_support/factories/inventory_unit_factory.rb +0 -18
  1577. data/lib/spree/testing_support/factories/log_entry_factory.rb +0 -6
  1578. data/lib/spree/testing_support/factories/metafield_definition_factory.rb +0 -82
  1579. data/lib/spree/testing_support/factories/metafield_factory.rb +0 -68
  1580. data/lib/spree/testing_support/factories/prototype_factory.rb +0 -9
  1581. data/lib/spree/testing_support/factories/reimbursement_credit_factory.rb +0 -7
  1582. data/lib/spree/testing_support/factories/reimbursement_factory.rb +0 -16
  1583. data/lib/spree/testing_support/factories/reimbursement_type_factory.rb +0 -7
  1584. data/lib/spree/testing_support/factories/report_factory.rb +0 -33
  1585. data/lib/spree/testing_support/factories/return_authorization_factory.rb +0 -21
  1586. data/lib/spree/testing_support/factories/return_item_factory.rb +0 -14
  1587. data/lib/spree/testing_support/factories/shipment_factory.rb +0 -21
  1588. data/lib/spree/testing_support/factories/shipping_category_factory.rb +0 -9
  1589. data/lib/spree/testing_support/factories/shipping_method_factory.rb +0 -31
  1590. data/lib/spree/testing_support/factories/shipping_rate_factory.rb +0 -7
  1591. data/lib/spree/testing_support/factories/state_change_factory.rb +0 -8
  1592. data/lib/spree/testing_support/factories/stock_item_factory.rb +0 -22
  1593. data/lib/spree/testing_support/factories/store_credit_category_factory.rb +0 -9
  1594. data/lib/spree/testing_support/factories/store_credit_type_factory.rb +0 -16
  1595. data/lib/spree/testing_support/factories/wished_variant_factory.rb +0 -6
  1596. data/lib/spree/webhooks.rb +0 -22
  1597. data/lib/tasks/role_users.rake +0 -21
  1598. data/vendor/javascript/@rails--request.js.js +0 -4
  1599. data/vendor/javascript/@stimulus-components--auto-submit.js +0 -4
  1600. data/vendor/javascript/stimulus-reveal-controller.js +0 -4
  1601. data/vendor/javascript/stimulus-textarea-autogrow.js +0 -4
  1602. data/vendor/javascript/tailwindcss-stimulus-components.js +0 -4
@@ -0,0 +1,503 @@
1
+ module Spree
2
+ # A product assortment with an optional pricing override, shown to a
3
+ # specific audience — a B2B tier, a VIP group, a regional selection.
4
+ #
5
+ # Who sees it is a {Spree::CatalogAssignment} (CustomerGroup or Company —
6
+ # where it covers the node's subtree).
7
+ #
8
+ # **The two audiences do not combine.** A buyer is matched by one of them,
9
+ # in the order {.for_context} walks: the company subtree if any of its
10
+ # nodes carry a catalog, otherwise the customer's groups, otherwise the
11
+ # channel's default catalog. So a company buyer never picks up their
12
+ # customer group's catalogs — the nearer agreement answers on its own, and
13
+ # trade tiers for company buyers are expressed by assigning the tier
14
+ # catalog to those companies or divisions rather than to a group.
15
+ #
16
+ # Within whichever audience answered, visibility is the union of its
17
+ # catalogs' assortments; pricing walks the assigning nodes nearest first and
18
+ # within one node charges the best price any of its catalogs gives
19
+ # (docs/plans/6.0-b2b-companies-and-catalogs.md).
20
+ class Catalog < Spree.base_class
21
+ has_prefix_id :cat
22
+
23
+ include Spree::SingleStoreResource
24
+ include Spree::HasListPosition
25
+ include Spree::HasCustomFields
26
+ include Spree::Metadata
27
+
28
+ publishes_lifecycle_events
29
+
30
+ acts_as_list scope: :store_id
31
+
32
+ # Born inactive: an agreement goes live through Catalogs::Activate, which
33
+ # is where the checks and the notifications hang — the same shape a price
34
+ # list uses (docs/plans/6.0-catalog-agreement-rework.md).
35
+ attribute :active, :boolean, default: false
36
+
37
+ belongs_to :store, class_name: 'Spree::Store', inverse_of: :catalogs
38
+ # The owned list, or nil for an assortment-only catalog priced at base.
39
+ # The FK lives on the list: a list is standalone or owned by exactly one
40
+ # catalog.
41
+ #
42
+ # Destroyed with the catalog rather than released, because an owned list
43
+ # carries no rules of its own — released, it would match every shopper in
44
+ # the store. The list is paranoid, so this is a soft delete.
45
+ has_one :price_list, class_name: 'Spree::PriceList', inverse_of: :catalog, dependent: :destroy
46
+
47
+ has_many :catalog_products, class_name: 'Spree::CatalogProduct', dependent: :destroy,
48
+ inverse_of: :catalog
49
+ has_many :products, through: :catalog_products, class_name: 'Spree::Product'
50
+ has_many :catalog_assignments, class_name: 'Spree::CatalogAssignment', dependent: :destroy,
51
+ inverse_of: :catalog
52
+
53
+ # Commercial terms — typed per grain rather than one rules table, because
54
+ # quantity rules are read on the add-to-cart path and want an indexed
55
+ # lookup, while minimums want DB-enforced per-currency uniqueness.
56
+ has_many :quantity_rules, class_name: 'Spree::CatalogQuantityRule', dependent: :destroy,
57
+ inverse_of: :catalog
58
+ has_many :order_minimums, class_name: 'Spree::CatalogOrderMinimum', dependent: :destroy,
59
+ inverse_of: :catalog
60
+
61
+ validates :name, presence: true
62
+ validates :minimum_order_quantity, numericality: { only_integer: true, greater_than: 0, allow_nil: true }
63
+ validates :order_multiple, numericality: { only_integer: true, greater_than: 0, allow_nil: true }
64
+ validate :price_list_in_same_store
65
+ validate :price_list_not_owned_elsewhere
66
+ validate :pending_price_list_is_valid
67
+
68
+ # The binding is applied inside the save, never on assignment: writing a
69
+ # has_one on a persisted record updates the child immediately, so a
70
+ # rejected save would already have re-homed the list — or, detaching,
71
+ # released it to store-wide rule matching, which is the leak this design
72
+ # exists to close. After rather than before, so a newly created catalog
73
+ # has an id for the child to point at; still inside the save transaction,
74
+ # so a later failure takes the binding down with it.
75
+ after_save :apply_pending_price_list
76
+
77
+ # Request-scoped catalog memoization must not keep a set that a write
78
+ # in the same request has already superseded. Destroying a catalog also
79
+ # releases its list through `dependent: :nullify`, which is an
80
+ # `update_all` and so never runs PriceList's own callback — without this
81
+ # the released list stays missing from the request's matching set, and
82
+ # anything priced later in that request misses it.
83
+ after_commit -> { Spree::Current.reset_catalog_memos }
84
+
85
+ scope :active, -> { where(active: true) }
86
+ scope :by_position, -> { ordered }
87
+
88
+ self.whitelisted_ransackable_attributes = %w[name active]
89
+
90
+ # The catalogs that apply to a purchase node, nearest node first: the
91
+ # node's own assignments before its parent's, catalog position breaking
92
+ # ties within a node. A parent's assignment covers the whole subtree, so a
93
+ # branch adds its own extra catalog without re-assigning the shared one.
94
+ #
95
+ # Always call this through the store — +current_store.catalogs.for_company+
96
+ # — so the tenant comes from the caller rather than from the argument.
97
+ #
98
+ # @param company [Spree::Company, nil]
99
+ # @return [Array<Spree::Catalog>]
100
+ def self.for_company(company)
101
+ groups_for_company(company).flatten
102
+ end
103
+
104
+ # The same catalogs, grouped by the node that assigns them, nearest first.
105
+ # Only pricing needs the boundaries: catalogs sharing a node rank equally
106
+ # and the best price among them wins, while a nearer node outranks a
107
+ # further one. Everything else takes the flat {.for_company}.
108
+ #
109
+ # @param company [Spree::Company, nil]
110
+ # @return [Array<Array<Spree::Catalog>>]
111
+ def self.groups_for_company(company)
112
+ return [] if company.nil?
113
+
114
+ nodes = company.self_and_ancestors
115
+ # Constrained to the receiving relation as well as the company's nodes:
116
+ # the assignment validates same-store on write, but a read that trusts
117
+ # the write path would hand another tenant's catalog to this buyer if a
118
+ # row ever arrived past it (raw SQL, an import, a bypass).
119
+ assignments = Spree::CatalogAssignment.
120
+ where(assignable_type: 'Spree::Company', assignable_id: nodes.map(&:id)).
121
+ where(catalog_id: all.select(:id)).
122
+ includes(:catalog).
123
+ group_by(&:assignable_id)
124
+
125
+ # A catalog assigned to a node and to an ancestor answers from the nearer.
126
+ seen = Set.new
127
+
128
+ nodes.filter_map do |node|
129
+ group = Array(assignments[node.id]).map(&:catalog).
130
+ select { |catalog| catalog.active? && seen.add?(catalog.id) }.
131
+ sort_by { |catalog| catalog.position.to_i }
132
+ group.presence
133
+ end
134
+ end
135
+
136
+ # The catalogs assigned to any of the given customer groups, by position.
137
+ #
138
+ # Always call this through the store —
139
+ # +current_store.catalogs.for_customer_groups+ — so the tenant comes from
140
+ # the caller rather than from the argument.
141
+ #
142
+ # @param customer_groups [Enumerable<Spree::CustomerGroup>]
143
+ # @return [Array<Spree::Catalog>]
144
+ def self.for_customer_groups(customer_groups)
145
+ ids = Array(customer_groups).map(&:id)
146
+ return [] if ids.empty?
147
+
148
+ Spree::CatalogAssignment.
149
+ where(assignable_type: 'Spree::CustomerGroup', assignable_id: ids).
150
+ where(catalog_id: all.select(:id)).
151
+ includes(:catalog).
152
+ map(&:catalog).select(&:active?).sort_by { |catalog| catalog.position.to_i }.uniq
153
+ end
154
+
155
+ # Catalogs that apply to a buyer: the company subtree, or failing that
156
+ # the customer's groups, or failing that the channel's default catalog —
157
+ # the one resolution chain both visibility
158
+ # ({Spree::Products::ForContext}) and pricing use. Pricing asks it once
159
+ # per request buyer via {Spree::Current#catalogs_for}.
160
+ #
161
+ # The steps are alternatives, not layers: the first one that finds a
162
+ # catalog answers, and the rest are not consulted. A buyer whose company
163
+ # has an agreement is on that agreement, so their customer group's
164
+ # catalogs are deliberately out of the picture (see the class comment).
165
+ #
166
+ # @param store [Spree::Store, nil]
167
+ # @param company [Spree::Company, nil]
168
+ # @param user [Object, nil]
169
+ # @param channel [Spree::Channel, nil]
170
+ # @return [Array<Spree::Catalog>]
171
+ def self.for_context(store:, company: nil, user: nil, channel: nil)
172
+ groups_for_context(store: store, company: company, user: user, channel: channel).flatten
173
+ end
174
+
175
+ # The same resolution, grouped by precedence rank ({.groups_for_company}).
176
+ # Only the company axis has more than one rank.
177
+ #
178
+ # @return [Array<Array<Spree::Catalog>>]
179
+ def self.groups_for_context(store:, company: nil, user: nil, channel: nil)
180
+ return [] if store.nil?
181
+
182
+ groups = store.catalogs.groups_for_company(company)
183
+
184
+ # Only when the company axis found nothing: a buyer purchasing for a
185
+ # company is on that company's agreement, and adding their personal
186
+ # segment's catalogs on top would price one buyer under two agreements
187
+ # at once.
188
+ if groups.empty? && user
189
+ customer_groups = user.try(:customer_groups)&.where(store_id: store.id) || []
190
+ groups = [store.catalogs.for_customer_groups(customer_groups).presence].compact
191
+ end
192
+
193
+ groups = [[channel&.default_catalog].compact.select(&:active?).presence].compact if groups.empty?
194
+
195
+ catalogs = groups.flatten
196
+ # Pricing reads each catalog's price list, and the list's contextual
197
+ # rules decide whether it applies to the quantity being bought; without
198
+ # this the walk is one query per catalog again, plus one per list.
199
+ if catalogs.any?
200
+ ActiveRecord::Associations::Preloader.new(
201
+ records: catalogs, associations: { price_list: [:price_rules, :price_adjustment_tiers] }
202
+ ).call
203
+ end
204
+ groups
205
+ end
206
+
207
+ # The catalogs applying to a buyer, resolving the company for them when
208
+ # the caller does not already know it, and reusing the request's memoized
209
+ # set where the store being asked about is the one being served.
210
+ #
211
+ # The single entry point for "what are this buyer's catalogs": visibility,
212
+ # pricing and quantity terms must answer from the same set, and a caller
213
+ # that resolved the company differently — or not at all — would show a
214
+ # storefront one agreement's prices under another's rules.
215
+ #
216
+ # @param store [Spree::Store, nil]
217
+ # @param customer [Object, nil]
218
+ # @param company [Spree::Company, nil] the purchase node; defaults to the
219
+ # customer's sole standing within the store
220
+ # @param channel [Spree::Channel, nil]
221
+ # @return [Array<Spree::Catalog>]
222
+ def self.for_buyer(store:, customer: nil, company: nil, channel: nil)
223
+ groups_for_buyer(store: store, customer: customer, company: company, channel: channel).flatten
224
+ end
225
+
226
+ # {.for_buyer}, grouped by precedence rank. What pricing walks.
227
+ #
228
+ # @return [Array<Array<Spree::Catalog>>]
229
+ def self.groups_for_buyer(store:, customer: nil, company: nil, channel: nil)
230
+ return [] if store.nil?
231
+
232
+ if store == Spree::Current.store
233
+ company ||= Spree::Current.standing_company_for(customer)
234
+ channel ||= Spree::Current.channel
235
+ Spree::Current.catalog_groups_for(company: company, user: customer, channel: channel)
236
+ else
237
+ company ||= Spree::Company.sole_standing_for(store: store, customer: customer)
238
+ groups_for_context(store: store, company: company, user: customer, channel: channel)
239
+ end
240
+ end
241
+
242
+ # How this agreement prices, as one word. The same three the dashboard
243
+ # offers when setting it up: `base` is no list at all — the buyer pays the
244
+ # shop price and the catalog only decides what they see — while
245
+ # `automatic` derives from base prices by a percentage and `fixed` holds
246
+ # amounts a merchant entered (docs/plans/6.0-catalog-agreement-rework.md).
247
+ #
248
+ # Read from the list rather than stored: it is the same question
249
+ # `automatic_pricing?` already answers, and a column would be a second
250
+ # copy to keep in step.
251
+ #
252
+ # @return [String] one of `base`, `automatic`, `fixed`
253
+ def pricing_strategy
254
+ return 'base' if price_list.nil?
255
+
256
+ price_list.automatic_pricing? ? 'automatic' : 'fixed'
257
+ end
258
+
259
+ # Assigning the association goes through a deferral, so the binding lands
260
+ # in the save rather than on assignment.
261
+ def price_list=(list)
262
+ @pending_price_list = list
263
+ end
264
+
265
+ # Reads back an assigned-but-unsaved binding, so callers see what they
266
+ # set rather than what is still on disk.
267
+ def price_list
268
+ return @pending_price_list if defined?(@pending_price_list)
269
+
270
+ super
271
+ end
272
+
273
+ # Adds products to the assortment, appending to the manual order and
274
+ # skipping ones already present. Written in one statement, so importing a
275
+ # whole price list is a single insert rather than a row per product.
276
+ #
277
+ # @param product_ids [Array<Integer>] raw product PKs
278
+ # @return [Integer] how many were added
279
+ def add_products(product_ids)
280
+ return 0 if product_ids.blank?
281
+
282
+ # Scoped to this store's products, so an id from another tenant adds
283
+ # nothing rather than being inserted past the row-level validation the
284
+ # bulk write skips.
285
+ allowed_ids = store.products.where(id: product_ids).ids.to_set
286
+ taken_ids = catalog_products.pluck(:product_id).to_set
287
+
288
+ new_ids = product_ids.uniq.select { |id| allowed_ids.include?(id) && !taken_ids.include?(id) }
289
+ return 0 if new_ids.empty?
290
+
291
+ now = Time.current
292
+
293
+ rows = new_ids.map do |product_id|
294
+ {
295
+ catalog_id: id,
296
+ product_id: product_id,
297
+ created_at: now,
298
+ updated_at: now
299
+ }
300
+ end
301
+
302
+ # :skip keeps a concurrent add from raising on the unique
303
+ # (catalog_id, product_id) index.
304
+ opts = { on_duplicate: :skip }
305
+ # MySQL infers the conflict target from the table's unique constraints
306
+ # and rejects an explicit +unique_by+; PostgreSQL/SQLite require it.
307
+ opts[:unique_by] = %i[catalog_id product_id] unless mysql_adapter?
308
+
309
+ # Both memberships move together: a half-applied add is the drift this
310
+ # sync exists to prevent, leaving the spreadsheet without rows for
311
+ # products the assortment already lists.
312
+ transaction do
313
+ Spree::CatalogProduct.upsert_all(rows, **opts)
314
+ # An owned list prices this assortment and nothing else, so it
315
+ # follows it: those placeholder rows are what the spreadsheet edits.
316
+ price_list&.add_products(new_ids)
317
+ touch
318
+ end
319
+
320
+ new_ids.size
321
+ end
322
+
323
+ # Drops products from the assortment, and the rows an owned list carried
324
+ # for them — a price for something this audience can no longer see is
325
+ # dead weight, and would reappear if the product were added back.
326
+ #
327
+ # @param product_ids [Array<Integer>] raw product PKs
328
+ # @return [Integer] how many were removed
329
+ def remove_products(product_ids)
330
+ return 0 if product_ids.blank?
331
+
332
+ removed = 0
333
+
334
+ transaction do
335
+ removed = catalog_products.where(product_id: product_ids).delete_all
336
+ next if removed.zero?
337
+
338
+ price_list&.remove_products(product_ids)
339
+ # Terms go with the products they were stated for. Left behind, a
340
+ # merchant who removes a SKU and later re-adds it gets the old
341
+ # minimum back — terms they believe they deleted.
342
+ quantity_rules.where(variant_id: Spree::Variant.where(product_id: product_ids).select(:id)).delete_all
343
+ touch
344
+ end
345
+
346
+ removed
347
+ end
348
+
349
+ # Copies the price list's products into the assortment — the explicit
350
+ # "the wholesale range is already priced" convenience. Deliberately never
351
+ # automatic: an empty assortment is a pricing-only overlay that hides
352
+ # nothing, so turning a catalog restrictive is a curation act.
353
+ #
354
+ # @return [Integer] how many products were added
355
+ def import_products_from_price_list
356
+ return 0 if price_list.nil?
357
+
358
+ add_products(price_list.product_ids)
359
+ end
360
+
361
+ private
362
+
363
+ # Runs before anything is written, so a foreign-store list is a validation
364
+ # error on the catalog rather than a RecordNotSaved raised out of the
365
+ # child's own same-store check.
366
+ def price_list_in_same_store
367
+ return if price_list.nil? || store_id.nil?
368
+ return if price_list.store_id == store_id
369
+
370
+ errors.add(:price_list, :invalid)
371
+ end
372
+
373
+ # An unsaved list is saved inside this record's own save, so its problems
374
+ # have to surface here — otherwise the save just returns false with no
375
+ # message and the merchant is told nothing.
376
+ def pending_price_list_is_valid
377
+ return if price_list.nil? || price_list.persisted? || price_list.valid?
378
+
379
+ price_list.errors.each do |error|
380
+ errors.add(:price_list, error.message)
381
+ end
382
+ end
383
+
384
+ # A list belongs to exactly one catalog, so claiming one another catalog
385
+ # already owns would silently un-price that catalog. Moving a list is a
386
+ # detach on the current owner followed by an attach here — two deliberate
387
+ # acts, not a side effect of picking a familiar name.
388
+ def price_list_not_owned_elsewhere
389
+ return if price_list.nil? || !price_list.persisted?
390
+
391
+ # Read the stored owner rather than the in-memory one: the caller may
392
+ # hold a copy loaded before another catalog claimed it.
393
+ owner_id = Spree::PriceList.where(id: price_list.id).pick(:catalog_id)
394
+ return if owner_id.nil? || owner_id == id
395
+
396
+ errors.add(:price_list, :owned_by_another_catalog)
397
+ end
398
+
399
+ # Applies the deferred binding inside the save transaction: the newly
400
+ # claimed list points here, and a list this catalog is giving up is
401
+ # released. Written through the child, since the FK lives on the list.
402
+ def apply_pending_price_list
403
+ return unless defined?(@pending_price_list)
404
+
405
+ pending = @pending_price_list
406
+ remove_instance_variable(:@pending_price_list)
407
+
408
+ # An unsaved list is persisted through its own lifecycle — it has no id
409
+ # to bind yet, and skipping that would silently drop it. Any list this
410
+ # catalog already owns is released first, or the one-live-list-per-
411
+ # catalog rule rejects the replacement before it can take over.
412
+ #
413
+ # `save` rather than `save!`: two concurrent creates both see no owner
414
+ # and both insert, and the unique index rejects the loser. That is a
415
+ # lost race, not a server error, so it fails the save with a message
416
+ # the same way a visible conflict does.
417
+ if pending && !pending.persisted?
418
+ release_owned_price_list
419
+ pending.catalog_id = id
420
+
421
+ unless save_pending_list(pending)
422
+ raise ActiveRecord::RecordNotUnique,
423
+ "catalog #{id} was given a price list by another request"
424
+ end
425
+
426
+ finish_price_list_binding
427
+ return
428
+ end
429
+
430
+ association(:price_list).reset
431
+ previous = association(:price_list).load_target
432
+ return if previous&.id == pending&.id
433
+
434
+ release_owned_price_list(previous)
435
+
436
+ if pending
437
+ # Compare-and-swap on the claim: only an unowned list is taken. The
438
+ # validation already refuses a list whose owner is visible, so this
439
+ # only fires when a concurrent request claimed it in between — the
440
+ # write raises and rolls the transaction back rather than silently
441
+ # un-pricing the catalog that won.
442
+ claimed = Spree::PriceList.where(id: pending.id, catalog_id: nil).update_all(catalog_id: id)
443
+
444
+ if claimed.zero?
445
+ raise ActiveRecord::RecordNotUnique,
446
+ "price list #{pending.id} was claimed by another catalog"
447
+ end
448
+
449
+ # The conditional UPDATE bypasses the instance, so tell the caller's
450
+ # copy what was written — otherwise it still reads catalog_id as nil
451
+ # and a later `price_list.catalog = nil` looks like a no-op and
452
+ # silently fails to detach.
453
+ sync_written_catalog_id(pending, id)
454
+ end
455
+
456
+ finish_price_list_binding
457
+ end
458
+
459
+ # Saves the new list, treating a lost race for this catalog's single
460
+ # live-list slot as a failure rather than an exception: the DB unique
461
+ # index is what decides, since two concurrent creates each see no owner.
462
+ def save_pending_list(price_list)
463
+ price_list.save
464
+ rescue ActiveRecord::RecordNotUnique
465
+ false
466
+ end
467
+
468
+ # Compare-and-swap on the release: a list another request has already
469
+ # re-homed must not be sent back to standalone matching, where a
470
+ # rule-less list prices the whole store.
471
+ def release_owned_price_list(previous = nil)
472
+ previous ||= begin
473
+ association(:price_list).reset
474
+ association(:price_list).load_target
475
+ end
476
+ return if previous.nil?
477
+
478
+ released = Spree::PriceList.where(id: previous.id, catalog_id: id).update_all(catalog_id: nil)
479
+ sync_written_catalog_id(previous, nil) if released.positive?
480
+ end
481
+
482
+ # Reflects an `update_all` back onto the in-memory record, so the copy a
483
+ # caller holds agrees with the row and stays clean rather than dirty.
484
+ def sync_written_catalog_id(price_list, catalog_id)
485
+ return if price_list.catalog_id == catalog_id
486
+
487
+ price_list.catalog_id = catalog_id
488
+ price_list.send(:clear_attribute_changes, [:catalog_id])
489
+ end
490
+
491
+ def finish_price_list_binding
492
+ association(:price_list).reset
493
+ # The writes above skip PriceList's own callbacks, so the two things
494
+ # they would have done happen here instead: the `touch: true` on the
495
+ # child's belongs_to, without which the largest possible change to a
496
+ # catalog's pricing leaves its cache key untouched…
497
+ touch if persisted?
498
+ # …and clearing the request's memoized generic-matching set, so a
499
+ # removal is visible to the rest of this request, not the next one.
500
+ Spree::Current.price_lists = nil
501
+ end
502
+ end
503
+ end
@@ -0,0 +1,41 @@
1
+ module Spree
2
+ # Who gets a catalog. Polymorphic, but the assignable set is small and
3
+ # closed: CustomerGroup and Company — buyer audiences only. A company-node
4
+ # assignment applies to the node's subtree.
5
+ #
6
+ # Channel and Market were assignable in the 6.0 pre-release but never read
7
+ # (decisions.md 2026-08-28): a channel's catalog is its `default_catalog`,
8
+ # and a market catalog waits for the regional-assortment design. A future
9
+ # type joins this list together with the resolution code that reads it.
10
+ #
11
+ # The assignment direction is "who gets this catalog", not "what catalogs
12
+ # does this entity have" — resolution queries by catalog.
13
+ class CatalogAssignment < Spree.base_class
14
+ has_prefix_id :cata
15
+
16
+ ASSIGNABLE_TYPES = %w[Spree::CustomerGroup Spree::Company].freeze
17
+
18
+ belongs_to :catalog, class_name: 'Spree::Catalog', inverse_of: :catalog_assignments
19
+ belongs_to :assignable, polymorphic: true
20
+
21
+ validates :assignable_type, inclusion: { in: ASSIGNABLE_TYPES }
22
+ validates :catalog_id, uniqueness: { scope: [:assignable_type, :assignable_id, *spree_base_uniqueness_scope] }
23
+ validate :assignable_in_same_store
24
+
25
+ after_commit -> { Spree::Current.reset_catalog_memos }
26
+
27
+ delegate :store, :store_id, to: :catalog
28
+
29
+ private
30
+
31
+ # Every assignable type is store-scoped, so a cross-store assignment
32
+ # would show one merchant's catalog to another's audience.
33
+ def assignable_in_same_store
34
+ return if assignable.nil? || catalog.nil?
35
+ return unless assignable.respond_to?(:store_id)
36
+ return if assignable.store_id == catalog.store_id
37
+
38
+ errors.add(:assignable, :invalid)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,26 @@
1
+ module Spree
2
+ # The least a whole order must come to under a catalog's agreement, in one
3
+ # currency. Born per currency — one row each — because Spree holds no
4
+ # exchange rates and a threshold converted at read time is a different
5
+ # promise every day.
6
+ class CatalogOrderMinimum < Spree.base_class
7
+ has_prefix_id :com
8
+
9
+ belongs_to :catalog, class_name: 'Spree::Catalog', touch: true, inverse_of: :order_minimums
10
+
11
+ validates :currency, presence: true,
12
+ uniqueness: { scope: [:catalog_id, *spree_base_uniqueness_scope] }
13
+ validates :amount, numericality: { greater_than: 0 }
14
+
15
+ normalizes :currency, with: ->(value) { value&.to_s&.strip&.upcase }
16
+
17
+ delegate :store, :store_id, to: :catalog
18
+
19
+ after_commit -> { Spree::Current.reset_catalog_memos }
20
+
21
+ # @return [Spree::Money]
22
+ def display_amount
23
+ Spree::Money.new(amount, currency: currency)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,100 @@
1
+ module Spree
2
+ # What a buyer on one catalog pays for one variant, and where that number
3
+ # came from. Resolved by {Spree::Catalogs::ResolvePrices}; this object is
4
+ # only the answer.
5
+ #
6
+ # The source is the point: an amount alone cannot tell a merchant whether
7
+ # their agreement actually prices a product or is quietly falling through
8
+ # to the shop price (docs/plans/6.0-catalog-agreement-rework.md).
9
+ #
10
+ # explicit — an amount someone typed on the catalog's own list
11
+ # automatic — that list's percentage applied to the base price
12
+ # base — the variant's normal price; this agreement does not price it
13
+ class CatalogPrice
14
+ include ActiveModel::Model
15
+ include ActiveModel::Attributes
16
+
17
+ # Where a resolved amount came from. A closed set: the reading is only
18
+ # useful if every amount can say which of the three it is.
19
+ SOURCES = %w[explicit automatic base].freeze
20
+
21
+ attribute :amount, :decimal
22
+ attribute :currency, :string
23
+ attribute :source, :string
24
+ # How many quantity tiers sit above this amount — breaks on the list's own
25
+ # rows, or bands on its percentage. Zero for a variant priced at one
26
+ # figure whatever the order size (docs/plans/6.0-volume-pricing.md).
27
+ attribute :break_count, :integer, default: 0
28
+
29
+ # The ladder itself, as {Spree::CatalogPriceTier} rows ordered by quantity
30
+ # — so a merchant reading the agreement sees what the buyer pays at each
31
+ # threshold without opening the price sheet
32
+ # (docs/plans/6.0-volume-pricing.md).
33
+ # The variant this amount prices. Carried so the reading can be addressed
34
+ # by the thing a client acts on — a resolved price has no id of its own,
35
+ # but the variant it belongs to does
36
+ # (docs/plans/6.0-volume-pricing.md).
37
+ attr_accessor :variant
38
+
39
+ attr_writer :tiers
40
+
41
+ validates :source, inclusion: { in: SOURCES }
42
+
43
+ # @return [Array<Spree::CatalogPriceTier>]
44
+ def tiers
45
+ @tiers ||= []
46
+ end
47
+
48
+ # The priced variant, as the API addresses it. A resolved price has no id
49
+ # of its own, so the variant's is what a client would act on
50
+ # (docs/plans/6.0-volume-pricing.md).
51
+ #
52
+ # @return [String, nil]
53
+ def prefixed_id
54
+ variant&.prefixed_id
55
+ end
56
+
57
+ # What distinguishes this variant from its siblings — "Color: White".
58
+ # Blank for a product whose single variant has no options to name.
59
+ #
60
+ # @return [String, nil]
61
+ def label
62
+ variant&.options_text.presence
63
+ end
64
+
65
+ # @return [String, nil]
66
+ def sku
67
+ variant&.sku
68
+ end
69
+
70
+ # True when the catalog's own pricing decided this amount, rather than the
71
+ # shop price showing through.
72
+ # @return [Boolean]
73
+ def from_agreement?
74
+ source != 'base'
75
+ end
76
+
77
+ # Whether the amount is the bottom of a ladder rather than the only price.
78
+ # @return [Boolean]
79
+ def tiered?
80
+ break_count.to_i.positive?
81
+ end
82
+
83
+ # The amount as the wire carries it — see CatalogPriceTier#display_value.
84
+ #
85
+ # @return [String]
86
+ def display_value
87
+ amount.to_s
88
+ end
89
+
90
+ # @return [Spree::Money]
91
+ def money
92
+ Spree::Money.new(amount, currency: currency)
93
+ end
94
+
95
+ # @return [String]
96
+ def display_amount
97
+ money.to_s
98
+ end
99
+ end
100
+ end