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
@@ -1,12 +1,7 @@
1
- require_dependency 'spree/order/checkout'
2
- require_dependency 'spree/order/currency_updater'
3
- require_dependency 'spree/order/digital'
4
- require_dependency 'spree/order/payments'
5
- require_dependency 'spree/order/store_credit'
6
- require_dependency 'spree/order/gift_card'
7
1
 
8
2
  module Spree
9
3
  class Order < Spree.base_class
4
+ include Spree::CSV::CustomFieldsHelper
10
5
  has_prefix_id :or # Stripe: or_
11
6
 
12
7
  # Legacy free-text `channel` column was replaced by the `channel_id` FK
@@ -14,64 +9,82 @@ module Spree
14
9
  # 5.4-to-5.5 backfill rake can read it; AR ignores it everywhere else.
15
10
  self.ignored_columns += ['channel']
16
11
 
12
+ # What Orders::UpdateStatuses derives — the only writer of the column.
13
+ PAYMENT_STATUSES = %w(none authorized partially_paid paid partially_refunded refunded overcharged voided).freeze
14
+ # @deprecated legacy machine vocabulary; rows carrying it stay valid until
15
+ # the status migration rewrites them. Removed in 6.1.
17
16
  PAYMENT_STATES = %w(balance_due credit_owed failed paid void)
18
- SHIPMENT_STATES = %w(backorder canceled partial pending ready shipped)
17
+ FULFILLMENT_STATUSES = %w(backorder canceled partial unfulfilled fulfilled delivered pending ready shipped)
18
+ # @deprecated legacy name — remove in 6.1 together with the 'shipped' value
19
+ SHIPMENT_STATES = FULFILLMENT_STATUSES
20
+ # @deprecated legacy machine vocabulary — line-item removability is
21
+ # completion-based since 6.0; removed in 6.1.
19
22
  LINE_ITEM_REMOVABLE_STATES = %w(cart address delivery payment confirm resumed)
20
23
 
21
24
  extend Spree::DisplayMoney
22
25
 
23
- include Spree::Order::Checkout
24
- include Spree::Order::CurrencyUpdater
25
- include Spree::Order::Digital
26
- include Spree::Order::Payments
27
- include Spree::Order::StoreCredit
28
- include Spree::Order::AddressBook
29
- include Spree::Order::Webhooks
30
- include Spree::Core::NumberGenerator.new(prefix: 'R')
31
- include Spree::Order::GiftCard
26
+ include Spree::ActedBy
27
+ include Spree::SingleStoreResource
28
+ include Spree::SanitizableRichText
29
+ include Spree::Purchase::Channel
30
+ include Spree::Purchase::Company
31
+ include Spree::Purchase::Freight
32
+ include Spree::Purchase::QuantityRules
33
+ include Spree::Purchase::PurchaseOrder
34
+ include Spree::Purchase::Market
35
+ include Spree::Purchase::Currency
36
+ include Spree::Purchase::Locale
37
+ include Spree::Purchase::DigitalItems
38
+ include Spree::Purchase::Taxation
39
+ include Spree::Purchase::StoreCredits
40
+ include Spree::Purchase::GiftCards
41
+ include Spree::Purchase::LineItemCurrencies
42
+ include Spree::Purchase::LineItemLookup
43
+ include Spree::Purchase::PaymentProcessing
44
+ include Spree::Purchase::Addresses
45
+ include Spree::Purchase::Validations
46
+ include Spree::Purchase::Totals
47
+ include Spree::Purchase::Lifecycle
48
+ has_spree_number prefix: 'R'
32
49
 
33
50
  include Spree::NumberIdentifier
34
- include Spree::SingleStoreResource
35
51
 
36
52
  publishes_lifecycle_events
37
- include Spree::MemoizedData
38
- include Spree::Metafields
53
+ include Spree::HasCustomFields
39
54
  include Spree::Metadata
55
+ include Spree::HasExternalReferences
40
56
  include Spree::Searchable
41
57
  if defined?(Spree::Security::Orders)
42
58
  include Spree::Security::Orders
43
59
  end
44
- if defined?(Spree::VendorConcern)
45
- include Spree::VendorConcern
46
- end
47
60
 
48
61
  has_secure_token :token, length: 35
49
- has_rich_text :internal_note
50
62
 
51
- MEMOIZED_METHODS = %w(tax_zone)
63
+ has_spree_rich_text :internal_note
52
64
 
53
65
  money_methods :outstanding_balance, :item_total, :adjustment_total,
54
66
  :included_tax_total, :additional_tax_total, :tax_total,
55
- :shipment_total, :promo_total, :total,
67
+ :delivery_total, :discount_total, :total,
56
68
  :cart_promo_total, :pre_tax_item_amount, :pre_tax_total,
57
- :payment_total, :amount_due
69
+ :payment_total, :amount_due, :fee_total,
70
+ :commission_amount_total, :commission_tax_total, :commission_total
58
71
 
59
- alias display_ship_total display_shipment_total
60
- alias_attribute :ship_total, :shipment_total
61
- def amount_due
62
- [outstanding_balance - total_applied_store_credit, 0].max
63
- end
72
+ alias display_ship_total display_delivery_total
73
+ alias_attribute :ship_total, :delivery_total
64
74
 
65
- # Transient warnings populated by remove_out_of_stock_items! and ensure_available_shipping_rates
75
+ # Transient warnings populated by remove_out_of_stock_items! and ensure_available_delivery_rates
66
76
  attribute :warnings, default: -> { [] }
67
77
 
68
78
  # Removes out-of-stock/discontinued items and populates warnings.
69
79
  # Returns self (reloaded if items were removed) with warnings set.
70
80
  # Captured before the call because removing items reloads the order, which
71
81
  # would drop warnings already recorded upstream.
82
+ # @deprecated Only Carts can auto remove out of stock items
72
83
  def remove_out_of_stock_items!
84
+ Spree::Deprecation.warn('Spree::Order#remove_out_of_stock_items! is deprecated and will be removed in Spree 6.1. This method now works only on Spree::Cart objects')
85
+
73
86
  existing_warnings = warnings
74
- result = Spree::Cart::RemoveOutOfStockItems.call(order: self)
87
+ result = Spree::Carts::RemoveOutOfStockItems.call(cart: self)
75
88
  return self unless result.success?
76
89
 
77
90
  order, _messages, new_warnings = result.value
@@ -79,60 +92,100 @@ module Spree
79
92
  order
80
93
  end
81
94
 
82
- # 5.5 API naming bridges (DB columns rename in 6.0)
83
- alias_attribute :discount_total, :promo_total
84
- alias display_discount_total display_promo_total
85
- alias_attribute :customer_note, :special_instructions
86
- alias_attribute :total_quantity, :item_count
87
-
88
- MONEY_THRESHOLD = 100_000_000
89
- MONEY_VALIDATION = {
90
- presence: true,
91
- numericality: {
92
- greater_than: -MONEY_THRESHOLD,
93
- less_than: MONEY_THRESHOLD,
94
- allow_blank: true
95
- },
96
- format: { with: /\A-?\d+(?:\.\d{1,2})?\z/, allow_blank: true }
97
- }.freeze
98
-
99
- POSITIVE_MONEY_VALIDATION = MONEY_VALIDATION.deep_dup.tap do |validation|
100
- validation.fetch(:numericality)[:greater_than_or_equal_to] = 0
101
- end.freeze
102
-
103
- NEGATIVE_MONEY_VALIDATION = MONEY_VALIDATION.deep_dup.tap do |validation|
104
- validation.fetch(:numericality)[:less_than_or_equal_to] = 0
105
- end.freeze
106
-
107
- checkout_flow do
108
- go_to_state :address
109
- go_to_state :delivery, if: ->(order) { order.delivery_required? }
110
- go_to_state :payment, if: ->(order) { order.payment? || order.payment_required? }
111
- go_to_state :confirm, if: ->(order) { order.confirmation_required? }
112
- go_to_state :complete
113
- end
114
-
115
- self.whitelisted_ransackable_associations = %w[shipments user created_by approver canceler promotions bill_address ship_address line_items store channel tags]
95
+ # Checkout-step introspection belongs to Spree::Cart
96
+ # ({Spree::Purchase::CheckoutSteps}) since 6.0 — an order is past checkout
97
+ # by definition. These bridges answer for an upgrader reaching for the
98
+ # Spree 5 API on an order, rather than raising NoMethodError.
99
+ #
100
+ # The step list is data-driven, so it stays accurate here: the registry
101
+ # computes it from the record's own predicates, all of which Order carries.
102
+ # Where the checkout stands within that list is not, which is why the
103
+ # readers below report a finished checkout.
104
+
105
+ # @deprecated Checkout steps belong to Spree::Cart; removed in 6.1.
106
+ def checkout_steps
107
+ Spree::Deprecation.warn('Spree::Order#checkout_steps is deprecated and will be removed in Spree 6.1. Checkout steps belong to Spree::Cart — ask the cart before it is completed.')
108
+ Spree::Checkout::Registry.step_names_for(self)
109
+ end
110
+
111
+ # @deprecated See {#checkout_steps}; removed in 6.1.
112
+ def has_checkout_step?(step)
113
+ Spree::Deprecation.warn('Spree::Order#has_checkout_step? is deprecated and will be removed in Spree 6.1. Checkout steps belong to Spree::Cart — ask the cart before it is completed.')
114
+ step.present? && Spree::Checkout::Registry.step_names_for(self).include?(step.to_s)
115
+ end
116
+
117
+ # @deprecated See {#checkout_steps}; removed in 6.1.
118
+ def checkout_step_index(step)
119
+ Spree::Deprecation.warn('Spree::Order#checkout_step_index is deprecated and will be removed in Spree 6.1. Checkout steps belong to Spree::Cart — ask the cart before it is completed.')
120
+ Spree::Checkout::Registry.step_names_for(self).index(step).to_i
121
+ end
122
+
123
+ # @deprecated See {#checkout_steps}; removed in 6.1. An order has no
124
+ # outstanding step, so this is always 'complete'.
125
+ def current_checkout_step
126
+ Spree::Deprecation.warn("Spree::Order#current_checkout_step is deprecated and will be removed in Spree 6.1. An order is past checkout, so this is always 'complete'.")
127
+ 'complete'
128
+ end
129
+
130
+ # @deprecated See {#checkout_steps}; removed in 6.1.
131
+ def final_checkout_step
132
+ Spree::Deprecation.warn('Spree::Order#final_checkout_step is deprecated and will be removed in Spree 6.1. Checkout steps belong to Spree::Cart — ask the cart before it is completed.')
133
+ Spree::Checkout::Registry.step_names_for(self).reject { |step| step == 'complete' }.last || 'address'
134
+ end
135
+
136
+ # @deprecated See {#checkout_steps}; removed in 6.1. Every step is behind
137
+ # an order, so this is the whole list bar 'complete'.
138
+ def completed_checkout_steps
139
+ Spree::Deprecation.warn("Spree::Order#completed_checkout_steps is deprecated and will be removed in Spree 6.1. An order is past checkout, so every step bar 'complete' is behind it.")
140
+ Spree::Checkout::Registry.step_names_for(self).reject { |step| step == 'complete' }
141
+ end
142
+
143
+ # Standardized column names (renamed in 6.0); legacy readers stay as
144
+ # aliases one release.
145
+ alias_attribute :promo_total, :discount_total
146
+ alias display_promo_total display_discount_total
147
+ alias_attribute :item_count, :total_quantity
148
+
149
+ # @deprecated The column is +customer_note+ since 6.0; removed in 6.1.
150
+ def special_instructions
151
+ Spree::Deprecation.warn('Spree::Order#special_instructions is deprecated and will be removed in Spree 6.1. Use #customer_note instead.')
152
+ customer_note
153
+ end
154
+
155
+ # @deprecated See {#special_instructions}; removed in 6.1.
156
+ def special_instructions=(value)
157
+ Spree::Deprecation.warn('Spree::Order#special_instructions= is deprecated and will be removed in Spree 6.1. Use #customer_note= instead.')
158
+ self.customer_note = value
159
+ end
160
+
161
+ # lock_version (renamed from state_lock_version) drives the API's manual
162
+ # optimistic concurrency (compare client-sent version, 409 on mismatch) —
163
+ # Rails auto-locking must not raise on internal saves.
164
+ self.lock_optimistically = false
165
+
166
+ self.whitelisted_ransackable_associations = %w[fulfillments shipments customer created_by approver canceler promotions bill_address ship_address line_items store channel tags seller order_group]
116
167
  self.whitelisted_ransackable_attributes = %w[
117
- completed_at email number state status payment_state shipment_state
118
- total item_total item_count considered_risky channel_id currency
168
+ completed_at email number status payment_status payment_state fulfillment_status shipment_state delivery_total
169
+ total item_total total_quantity considered_risky channel_id currency coupon_code customer_id seller_id
170
+ order_group_id po_number
119
171
  ]
120
172
  self.whitelisted_ransackable_scopes = %w[complete incomplete refunded partially_refunded search multi_search]
121
173
 
122
- attr_reader :coupon_code
123
- attr_accessor :temporary_address
124
-
125
174
  # Set to false on admin-initiated flows to suppress customer-facing emails.
126
175
  attr_accessor :notify_customer
127
176
 
128
- attribute :state_machine_resumed, :boolean
129
177
 
130
178
  STATUSES = %w[draft placed canceled].freeze
131
179
 
132
180
  attribute :status, :string, default: 'draft'
133
181
  validates :status, inclusion: { in: STATUSES }
134
182
 
183
+ # Orders belonging to the given seller. Passing nil selects the
184
+ # operator's own sales, which on a store with no sellers is every order.
185
+ scope :for_seller, ->(seller) { where(seller_id: seller.respond_to?(:id) ? seller.id : seller) }
186
+
135
187
  scope :drafts, -> { where(status: 'draft') }
188
+ scope :not_drafts, -> { where.not(status: 'draft') }
136
189
  scope :placed_orders, -> { where(status: 'placed') }
137
190
  scope :canceled_orders, -> { where(status: 'canceled') }
138
191
 
@@ -143,126 +196,127 @@ module Spree
143
196
  self.tag_list = tags
144
197
  end
145
198
 
146
- ASSOCIATED_USER_ATTRIBUTES = [:user_id, :email, :bill_address_id, :ship_address_id]
147
-
148
- # 6.0 forward-compat: User→Customer rename. Column stays user_id in 5.x.
149
- alias_attribute :customer_id, :user_id
150
-
151
- belongs_to :user, class_name: "::#{Spree.user_class}", optional: true, autosave: true
152
- belongs_to :created_by, class_name: "::#{Spree.admin_user_class}", optional: true
153
- belongs_to :approver, class_name: "::#{Spree.admin_user_class}", optional: true
154
- belongs_to :canceler, class_name: "::#{Spree.admin_user_class}", optional: true
155
-
156
- belongs_to :bill_address, foreign_key: :bill_address_id, class_name: 'Spree::Address',
157
- optional: true, dependent: :destroy
158
- alias_method :billing_address, :bill_address
159
- alias_method :billing_address=, :bill_address=
160
- alias_attribute :billing_address_id, :bill_address_id
199
+ ASSOCIATED_CUSTOMER_ATTRIBUTES = [:customer_id, :email, :bill_address_id, :ship_address_id]
161
200
 
162
- belongs_to :ship_address, foreign_key: :ship_address_id, class_name: 'Spree::Address',
163
- optional: true, dependent: :destroy
164
- alias_method :shipping_address, :ship_address
165
- alias_method :shipping_address=, :ship_address=
166
- alias_attribute :shipping_address_id, :ship_address_id
201
+ # @deprecated Use {Spree::Purchase::PaymentProcessing#payment_methods};
202
+ # removed in 6.1.
203
+ def collect_frontend_payment_methods
204
+ Spree::Deprecation.warn('Spree::Order#collect_frontend_payment_methods is deprecated and will be removed in Spree 6.1. Use #payment_methods instead.')
205
+ payment_methods
206
+ end
207
+
208
+ include Spree::DeprecatedCustomerAlias
209
+
210
+ belongs_to :customer, class_name: "::#{Spree.customer_class}", optional: true, autosave: true
211
+ # The cart this order was completed from (unique — the completion
212
+ # idempotency key). Backoffice draft orders have no cart.
213
+ belongs_to :cart, class_name: 'Spree::Cart', optional: true, inverse_of: :order
214
+ # The checkout this order was placed in, when it was placed alongside
215
+ # others — one per seller on a marketplace. A single-seller or first-party
216
+ # only checkout produces a bare order and no group.
217
+ belongs_to :order_group, class_name: 'Spree::OrderGroup', optional: true, inverse_of: :orders
218
+ # Whose sale this is. Nil on the operator's own goods, including the
219
+ # first-party child of a mixed marketplace checkout.
220
+ belongs_to :seller, class_name: 'Spree::Seller', optional: true
221
+ acted_by :created_by, :approver, :canceler
222
+ belongs_to :cancel_reason, class_name: 'Spree::OrderCancellationReason', optional: true, inverse_of: :orders
167
223
 
168
- belongs_to :store, class_name: 'Spree::Store'
169
- belongs_to :market, class_name: 'Spree::Market', optional: true
170
- belongs_to :channel, class_name: 'Spree::Channel', optional: true
171
224
  belongs_to :preferred_stock_location, class_name: 'Spree::StockLocation', optional: true
172
225
 
173
226
  with_options dependent: :destroy do
174
- has_many :state_changes, as: :stateful, class_name: 'Spree::StateChange'
175
227
  has_many :line_items, -> { order(:created_at) }, inverse_of: :order, class_name: 'Spree::LineItem'
176
228
  has_many :payments, class_name: 'Spree::Payment'
177
229
  has_many :payment_sessions, inverse_of: :order, class_name: 'Spree::PaymentSession'
178
- has_many :return_authorizations, inverse_of: :order, class_name: 'Spree::ReturnAuthorization'
179
- has_many :adjustments, -> { order(:created_at) }, as: :adjustable, class_name: 'Spree::Adjustment'
180
- has_many :cancellations, -> { order(:created_at) }, inverse_of: :order, class_name: 'Spree::OrderCancellation'
181
- has_many :approvals, -> { order(:created_at) }, inverse_of: :order, class_name: 'Spree::OrderApproval'
182
- end
183
- has_many :reimbursements, inverse_of: :order, class_name: 'Spree::Reimbursement'
184
- has_many :customer_returns, class_name: 'Spree::CustomerReturn', through: :return_authorizations
185
- has_many :line_item_adjustments, through: :line_items, source: :adjustments
186
- has_many :inventory_units, inverse_of: :order, class_name: 'Spree::InventoryUnit'
230
+ has_many :returns, -> { order(:created_at) }, inverse_of: :order, class_name: 'Spree::Return'
231
+ has_many :exchanges, -> { order(:created_at) }, inverse_of: :order, class_name: 'Spree::Exchange'
232
+ has_many :claims, -> { order(:created_at) }, inverse_of: :order, class_name: 'Spree::Claim'
233
+ end
234
+ has_many :fulfillment_items, inverse_of: :order, class_name: 'Spree::FulfillmentItem'
235
+ has_many :inventory_units, class_name: 'Spree::FulfillmentItem', inverse_of: :order, deprecated: true
187
236
  has_many :stock_reservations, class_name: 'Spree::StockReservation', inverse_of: :order, dependent: :destroy
188
- has_many :return_items, through: :inventory_units, class_name: 'Spree::ReturnItem'
237
+ has_many :return_line_items, through: :returns, class_name: 'Spree::ReturnLineItem', source: :return_line_items
189
238
  has_many :variants, through: :line_items
190
239
  has_many :products, through: :variants
191
- has_many :refunds, through: :payments
192
- has_many :all_adjustments,
193
- class_name: 'Spree::Adjustment',
194
- foreign_key: :order_id,
195
- dependent: :destroy,
196
- inverse_of: :order
240
+ # Every refund names the order it puts right — its own payments' refunds
241
+ # stamp it automatically, and a refund against a payment shared by a split
242
+ # checkout names the one child being refunded. Keyed on that column rather
243
+ # than walked through payments, which a grouped order does not own.
244
+ has_many :refunds, class_name: 'Spree::Refund', inverse_of: :order, dependent: :nullify
245
+
246
+ # Typed adjustment rows owned by this order (line-, fulfillment- and
247
+ # order-level). See docs/plans/6.0-6.1-split-adjustments.md.
248
+ has_many :tax_lines, class_name: 'Spree::TaxLine', dependent: :destroy, inverse_of: :order
249
+ # delete, not destroy: the snapshot is readonly once written, and destroy
250
+ # refuses readonly records. It has no dependents of its own.
251
+ has_one :tax_identifier, class_name: 'Spree::TaxIdentifier', as: :owner,
252
+ dependent: :delete, inverse_of: :owner
253
+ has_many :discounts, class_name: 'Spree::Discount', dependent: :destroy, inverse_of: :order
254
+ has_many :fees, class_name: 'Spree::Fee', dependent: :destroy, inverse_of: :order
255
+
256
+ # What the marketplace charged its sellers on this order. Off-order by
257
+ # design: commission never reaches a total the customer pays, so this is a
258
+ # ledger the order merely hosts. See docs/plans/6.0-multi-vendor-marketplace.md.
259
+ has_many :commission_lines, class_name: 'Spree::CommissionLine', dependent: :destroy, inverse_of: :order
260
+
261
+ # This order's share of the payments made against its group. Empty on an
262
+ # ungrouped order, whose payments are its own (see #settlement_payments).
263
+ has_many :payment_splits, class_name: 'Spree::PaymentSplit', dependent: :destroy, inverse_of: :order
264
+
265
+ has_many :line_item_tax_lines, through: :line_items, source: :tax_lines
266
+ has_many :line_item_discounts, through: :line_items, source: :discounts
197
267
 
198
268
  has_many :order_promotions, class_name: 'Spree::OrderPromotion'
199
269
  has_many :promotions, through: :order_promotions, class_name: 'Spree::Promotion'
200
270
 
201
- has_many :shipments, class_name: 'Spree::Shipment', dependent: :destroy, inverse_of: :order do
271
+ has_many :fulfillments, -> { order(:created_at, :id) }, class_name: 'Spree::Fulfillment', dependent: :destroy, inverse_of: :order do
202
272
  def states
203
- pluck(:state).uniq
273
+ pluck(:status).uniq
204
274
  end
205
275
  end
206
- has_many :shipment_adjustments, through: :shipments, source: :adjustments
276
+ has_many :fulfillment_tax_lines, through: :fulfillments, source: :tax_lines
277
+ has_many :fulfillment_discounts, through: :fulfillments, source: :discounts
207
278
 
208
279
  alias items line_items
209
- alias discounts order_promotions
210
- alias fulfillments shipments
211
- alias_attribute :delivery_total, :shipment_total
212
- alias display_delivery_total display_shipment_total
213
- alias_attribute :fulfillment_status, :shipment_state
214
- alias_attribute :payment_status, :payment_state
280
+ # Legacy names — removed in 6.1 (real names: fulfillments, delivery_total,
281
+ # fulfillment_status since 6.0)
282
+ has_many :shipments, class_name: 'Spree::Fulfillment', inverse_of: :order, deprecated: true
283
+ alias_attribute :shipment_total, :delivery_total
284
+ alias display_shipment_total display_delivery_total
285
+ alias_attribute :shipment_state, :fulfillment_status
286
+ # Deprecated alias — the column is payment_status since 6.0; remove in 6.1.
287
+ alias_attribute :payment_state, :payment_status
215
288
 
216
289
  delegate :has_markets?, to: :store, prefix: true
217
290
 
218
291
  accepts_nested_attributes_for :line_items
219
- accepts_nested_attributes_for :bill_address
220
- accepts_nested_attributes_for :ship_address
221
- alias shipping_address_attributes= ship_address_attributes=
222
- alias billing_address_attributes= bill_address_attributes=
223
292
  accepts_nested_attributes_for :payments, reject_if: :credit_card_nil_payment?
224
- accepts_nested_attributes_for :shipments
225
-
226
- # Needs to happen before save_permalink is called
227
- before_validation :ensure_market_presence
228
- before_validation :ensure_channel_presence
229
- before_validation :ensure_currency_presence
230
- before_validation :ensure_locale_presence
231
- before_validation :resolve_market_from_currency, if: -> { persisted? && currency_changed? && !skip_market_resolution }
232
-
233
- before_validation :clone_billing_address, if: :use_billing?
234
- before_validation :clone_shipping_address, if: :use_shipping?
235
- attr_accessor :use_billing, :use_shipping, :skip_market_resolution
293
+ accepts_nested_attributes_for :fulfillments
294
+ # @deprecated legacy writer — removed in 6.1
295
+ alias shipments_attributes= fulfillments_attributes=
236
296
 
237
297
  before_create :link_by_email
238
- before_update :ensure_updated_shipments, :homogenize_line_item_currencies, if: :currency_changed?
239
-
240
- with_options presence: true do
241
- # we want to have this case_sentive: true as changing it to false causes all SQL to use LOWER(slug)
242
- # which is very costly and slow on large set of records
243
- validates :email, length: { maximum: 254, allow_blank: true }, email: { allow_blank: true }, if: :require_email
244
- validates :item_count, numericality: { greater_than_or_equal_to: 0, less_than: 2**31, only_integer: true, allow_blank: true }
245
- validates :store
246
- validates :currency
247
- validates :locale
248
- end
249
- validates :payment_state, inclusion: { in: PAYMENT_STATES, allow_blank: true }
250
- validates :shipment_state, inclusion: { in: SHIPMENT_STATES, allow_blank: true }
251
- validates :item_total, POSITIVE_MONEY_VALIDATION
252
- validates :adjustment_total, MONEY_VALIDATION
253
- validates :included_tax_total, POSITIVE_MONEY_VALIDATION
254
- validates :additional_tax_total, POSITIVE_MONEY_VALIDATION
255
- validates :payment_total, MONEY_VALIDATION
256
- validates :shipment_total, MONEY_VALIDATION
257
- validates :promo_total, NEGATIVE_MONEY_VALIDATION
258
- validates :total, MONEY_VALIDATION
259
- validates :market, presence: true, if: :store_has_markets?
260
- validate :currency_must_be_supported_by_store
261
- validate :locale_must_be_supported_by_store
262
-
298
+ before_update :ensure_updated_fulfillments, :homogenize_line_item_currencies, if: :currency_changed?
299
+ # Record-state deletion eligibility is enforced here, not in ability rules —
300
+ # secret-key API requests never consult CanCanCan (Axis A/B split,
301
+ # docs/plans/decisions.md 2026-08-05).
302
+ before_destroy :ensure_can_be_deleted
303
+
304
+ # Shared money/quantity validations live in Spree::Purchase::Validations;
305
+ # only order-specific rules stay here.
306
+ validates :email, presence: true, length: { maximum: 254, allow_blank: true }, email: { allow_blank: true }, if: :require_email
307
+ validates :payment_status, inclusion: { in: PAYMENT_STATUSES | PAYMENT_STATES, allow_blank: true }
308
+ validates :fulfillment_status, inclusion: { in: FULFILLMENT_STATUSES, allow_blank: true }
309
+
310
+ # @deprecated Both warn and run the full recalculation; use
311
+ # {#recalculate_totals!}. Removed in 6.1.
263
312
  delegate :update_totals, :persist_totals, to: :updater
264
313
  delegate :merge!, to: :merger
265
- delegate :firstname, :lastname, to: :bill_address, prefix: true, allow_nil: true
314
+ delegate :first_name, :last_name, to: :bill_address, prefix: true, allow_nil: true
315
+
316
+ # @deprecated The delegated names follow the renamed address columns since
317
+ # 6.0; removed in 6.1.
318
+ alias bill_address_firstname bill_address_first_name
319
+ alias bill_address_lastname bill_address_last_name
266
320
 
267
321
  class_attribute :update_hooks
268
322
  self.update_hooks = Set.new
@@ -271,12 +325,14 @@ module Spree
271
325
  scope :completed_between, ->(start_date, end_date) { where(completed_at: start_date..end_date) }
272
326
  scope :complete, -> { where.not(completed_at: nil) }
273
327
  scope :incomplete, -> { where(completed_at: nil) }
274
- scope :canceled, -> { where(state: %w[canceled partially_canceled]) }
275
- scope :not_canceled, -> { where.not(state: %w[canceled partially_canceled]) }
276
- scope :ready_to_ship, -> { where(shipment_state: %w[ready pending]) }
277
- scope :partially_shipped, -> { where(shipment_state: %w[partial]) }
278
- scope :not_shipped, -> { where(shipment_state: %w[ready pending partial]) }
279
- scope :shipped, -> { where(shipment_state: %w[shipped]) }
328
+ scope :canceled, -> { where(status: 'canceled') }
329
+ scope :not_canceled, -> { where.not(status: 'canceled') }
330
+ # Nil-tolerant channel filter for optional scoping (nil means all channels).
331
+ scope :for_channel, ->(channel) { channel ? where(channel_id: channel.id) : all }
332
+ scope :ready_to_ship, -> { where(fulfillment_status: %w[unfulfilled]) }
333
+ scope :partially_shipped, -> { where(fulfillment_status: %w[partial]) }
334
+ scope :not_shipped, -> { where(fulfillment_status: %w[unfulfilled partial]) }
335
+ scope :shipped, -> { where(fulfillment_status: %w[fulfilled delivered shipped]) }
280
336
  scope :refunded, lambda {
281
337
  joins(:refunds).group(:id).having("sum(#{Spree::Refund.table_name}.amount) = #{Spree::Order.table_name}.total")
282
338
  }
@@ -297,15 +353,18 @@ module Spree
297
353
 
298
354
  conditions = []
299
355
  conditions << arel_table[:number].lower.matches(query_pattern)
356
+ # An accountant holds one reference or the other — ours or their own
357
+ # purchase order — and both have to find the same transaction.
358
+ conditions << arel_table[:po_number].lower.matches(query_pattern)
300
359
 
301
- conditions << search_condition(Spree::Address, :firstname, sanitized_query)
302
- conditions << search_condition(Spree::Address, :lastname, sanitized_query)
360
+ conditions << search_condition(Spree::Address, :first_name, sanitized_query)
361
+ conditions << search_condition(Spree::Address, :last_name, sanitized_query)
303
362
 
304
363
  full_name = NameOfPerson::PersonName.full(sanitized_query)
305
364
 
306
365
  if full_name.first.present? && full_name.last.present?
307
- conditions << search_condition(Spree::Address, :firstname, full_name.first)
308
- conditions << search_condition(Spree::Address, :lastname, full_name.last)
366
+ conditions << search_condition(Spree::Address, :first_name, full_name.first)
367
+ conditions << search_condition(Spree::Address, :last_name, full_name.last)
309
368
  end
310
369
 
311
370
  left_joins(:bill_address).where(arel_table[:email].lower.eq(query.downcase)).or(where(conditions.reduce(:or)))
@@ -347,55 +406,42 @@ module Spree
347
406
  # Use this method in other gems that wish to register their own custom logic
348
407
  # that should be called after Order#update
349
408
  def self.register_update_hook(hook)
409
+ Spree::Deprecation.warn('Order.register_update_hook is deprecated and will be removed in Spree 6.1')
350
410
  update_hooks.add(hook)
351
411
  end
352
412
 
353
- # For compatibility with Calculator::PriceSack
354
- def amount
355
- line_items.inject(0.0) { |sum, li| sum + li.amount }
356
- end
357
-
358
- # Sum of all line item amounts pre-tax
359
- def pre_tax_item_amount
360
- line_items.sum(:pre_tax_amount)
361
- end
362
-
363
413
  # Sum of the eligible promotion adjustments applied to the order itself
364
- # (whole-order discounts created by Promotion::Actions::CreateAdjustment),
365
- # as opposed to promotions applied to individual line items or shipments.
366
- # Zero or negative.
414
+ # (whole-order discounts created by Promotion::Actions::CreateAdjustment,
415
+ # distributed proportionally across line items), as opposed to promotions
416
+ # applied to individual line items or fulfillments. Zero or negative.
367
417
  #
368
418
  # @return [BigDecimal]
369
419
  def order_level_promo_total
370
- adjustments.promotion.eligible.sum(:amount)
420
+ discounts.promotion.where(promotion_action_id: promotion_actions_of_scope(:order)).sum(:amount)
371
421
  end
372
422
 
373
- # Sum of all line item and shipment pre-tax
374
- def pre_tax_total
375
- pre_tax_item_amount + shipments.sum(:pre_tax_amount)
423
+ # Promotion actions of the given discount scope, covering both the 6.0
424
+ # class names and the legacy STI names still present in the type column
425
+ # until the 6.1 data migration.
426
+ def promotion_actions_of_scope(scope)
427
+ Spree::PromotionAction.where(type: Spree::PromotionAction.types_for_discount_scope(scope))
376
428
  end
377
429
 
378
430
  # Returns the subtotal used for analytics integrations
379
431
  # It's a sum of the item total and the promo total
380
432
  # @return [Float]
381
433
  def analytics_subtotal
382
- (item_total + line_items.sum(:promo_total)).to_f
434
+ (item_total + line_items.sum(:discount_total)).to_f
383
435
  end
384
436
 
437
+
438
+ # @deprecated Use {#fulfillment_discount}; removed in 6.1.
385
439
  def shipping_discount
386
- shipment_adjustments.non_tax.eligible.sum(:amount) * - 1
440
+ Spree::Deprecation.warn('Spree::Order#shipping_discount is deprecated and will be removed in Spree 6.1. Use #fulfillment_discount instead.')
441
+ fulfillment_discount
387
442
  end
388
443
 
389
- def completed?
390
- completed_at.present?
391
- end
392
444
 
393
- # True when the order is mid-checkout: past the `cart` state but not yet
394
- # completed or canceled. Used by stock reservation hooks and any flow
395
- # that should only run during the active checkout phase.
396
- def in_checkout?
397
- !cart? && !complete? && !canceled?
398
- end
399
445
 
400
446
  def draft?
401
447
  status == 'draft'
@@ -405,10 +451,26 @@ module Spree
405
451
  status == 'placed'
406
452
  end
407
453
 
454
+ def canceled?
455
+ status == 'canceled'
456
+ end
457
+
458
+ # @deprecated machine vocabulary — data-derived bridge for the 6.0
459
+ # transition, removed in 6.1. An order is "cart-like" while a draft
460
+ # with no checkout data.
461
+ def cart?
462
+ draft? && !completed? && email.blank? && ship_address_id.blank?
463
+ end
464
+
465
+ # Derived, not stored (Decision 8): some but not all fulfillments canceled.
466
+ def partially_canceled?
467
+ !canceled? && fulfillments.canceled.any? && fulfillments.not_canceled.any?
468
+ end
469
+
408
470
  # Checks if the order is fully refunded
409
471
  # @return [Boolean]
410
472
  def order_refunded?
411
- return false if item_count.zero?
473
+ return false if total_quantity.zero?
412
474
  return false if refunds_total.zero?
413
475
 
414
476
  payment_state.in?(%w[void failed]) || refunds_total == total_minus_store_credits - additional_tax_total.abs
@@ -421,12 +483,107 @@ module Spree
421
483
  # Checks if the order is partially refunded
422
484
  # @return [Boolean]
423
485
  def partially_refunded?
424
- return false if item_count.zero?
486
+ return false if total_quantity.zero?
425
487
  return false if payment_state.in?(%w[void failed]) || refunds.empty?
426
488
 
427
489
  refunds_total < total_minus_store_credits - additional_tax_total.abs
428
490
  end
429
491
 
492
+ # When the buyer's statutory right of withdrawal expires — the EU
493
+ # cooling-off period (Consumer Rights Directive 2011/83/EU Art. 9).
494
+ #
495
+ # Derived rather than stored, because the clock starts when the buyer takes
496
+ # physical possession: a value written at placement would be wrong the
497
+ # moment a parcel arrived.
498
+ #
499
+ # Nil until the last live parcel is delivered. Counting from completion
500
+ # instead would expire the deadline before the statutory period had even
501
+ # begun — the buyer would be told their right had run out while they were
502
+ # still waiting for the goods. A right whose start has not happened yet has
503
+ # no end date to report.
504
+ #
505
+ # @return [ActiveSupport::TimeWithZone, nil] nil when the market grants no
506
+ # withdrawal right, the order is not complete, or delivery is outstanding
507
+ def withdrawal_period_ends_at
508
+ return nil unless withdrawal_right_applies?
509
+
510
+ started_at = withdrawal_period_starts_at
511
+ return nil if started_at.nil?
512
+
513
+ started_at + withdrawal_period_days.days
514
+ end
515
+
516
+ # Whether the buyer may still withdraw.
517
+ #
518
+ # True while delivery is outstanding: the right cannot have lapsed before
519
+ # it started, so an order still in transit is always within its period even
520
+ # though no deadline can be named yet.
521
+ #
522
+ # A canceled order is not: withdrawal is how a buyer ends a contract that
523
+ # is still standing, and cancellation has already ended this one. Without
524
+ # the guard, cancellation empties the live fulfillments, no start date can
525
+ # be found, and the open-ended reading above would keep the order reporting
526
+ # itself as withdrawable forever.
527
+ #
528
+ # @return [Boolean]
529
+ def within_withdrawal_period?
530
+ return false unless withdrawal_right_applies?
531
+
532
+ deadline = withdrawal_period_ends_at
533
+ # No deadline yet means nothing has been delivered, so the clock that
534
+ # would end the right has not started.
535
+ deadline.nil? || deadline.future?
536
+ end
537
+
538
+ # Whether a statutory right to withdraw exists on this order at all. A
539
+ # cancelled order has already ended the contract the right would end, and
540
+ # a market that sets no period grants none. Stated once because both
541
+ # readers above need the same answer.
542
+ def withdrawal_right_applies?
543
+ completed? && !canceled? && withdrawal_period_days.present?
544
+ end
545
+
546
+ # The moment the cooling-off period starts: receipt of the goods. The
547
+ # Consumer Rights Directive treats an order delivered in instalments as
548
+ # received when the LAST one arrives, so a partly-delivered order has not
549
+ # started its clock at all — reading the max over the delivered subset
550
+ # would start it at the first parcel and could expire the right while the
551
+ # buyer is still waiting for the rest.
552
+ #
553
+ # @return [ActiveSupport::TimeWithZone, nil] nil until every parcel that is
554
+ # still live has been delivered
555
+ def withdrawal_period_starts_at
556
+ live = fulfillments.reject(&:canceled?)
557
+ return nil if live.empty?
558
+
559
+ received = live.map { |fulfillment| withdrawal_receipt_of(fulfillment) }
560
+ return nil if received.any?(&:blank?)
561
+
562
+ received.max
563
+ end
564
+
565
+ # When one fulfillment counts as received.
566
+ #
567
+ # Digital content has no delivery event and no carrier to report one, so
568
+ # waiting for `delivered_at` would leave a mixed order's clock stopped
569
+ # forever — the physical parcel arrives and the deadline never appears.
570
+ # The Directive treats digital content differently from goods anyway
571
+ # (Art. 16(m)); handing it over is the moment it reaches the buyer.
572
+ #
573
+ # @param fulfillment [Spree::Fulfillment]
574
+ # @return [ActiveSupport::TimeWithZone, nil]
575
+ def withdrawal_receipt_of(fulfillment)
576
+ return fulfillment.delivered_at || fulfillment.fulfilled_at if fulfillment.digital?
577
+
578
+ fulfillment.delivered_at
579
+ end
580
+
581
+ # @return [Integer, nil] nil where no market says otherwise — a statutory
582
+ # notice is not something to assume on an order with no region attached
583
+ def withdrawal_period_days
584
+ market&.preferred_withdrawal_period_days
585
+ end
586
+
430
587
  # Indicates whether or not the user is allowed to proceed to checkout.
431
588
  # Currently this is implemented as a check for whether or not there is at
432
589
  # least one LineItem in the Order. Feel free to override this logic in your
@@ -435,33 +592,11 @@ module Spree
435
592
  line_items.exists?
436
593
  end
437
594
 
438
- # Does this order require a delivery (physical or digital).
439
- def delivery_required?
440
- true # true for Spree, can be decorated
441
- end
442
-
443
- # Is this a free order in which case the payment step should be skipped
444
- def payment_required?
445
- total.to_f > 0.0
446
- end
447
-
448
- # If true, causes the confirmation step to happen during the checkout process
449
- def confirmation_required?
450
- Spree::Config[:always_include_confirm_step] ||
451
- payments.valid.map(&:payment_method).compact.any?(&:confirmation_required?) ||
452
- # Little hacky fix for #4117
453
- # If this wasn't here, order would transition to address state on confirm failure
454
- # because there would be no valid payments any more.
455
- confirm?
456
- end
457
595
 
458
596
  def email_required?
459
597
  require_email
460
598
  end
461
599
 
462
- def backordered?
463
- shipments.any?(&:backordered?)
464
- end
465
600
 
466
601
  # Check if the shipping address is a quick checkout address
467
602
  # quick checkout addresses are incomplete as wallet providers like Apple Pay and Google Pay
@@ -475,141 +610,188 @@ module Spree
475
610
  # Either fully digital or not digital at all
476
611
  # @return [Boolean]
477
612
  def quick_checkout_available?
478
- payment_required? && shipments.count <= 1 && (digital? || !some_digital? || !delivery_required?)
613
+ payment_required? && fulfillments.count <= 1 && (digital? || !some_digital? || !delivery_step_required?)
479
614
  end
480
615
 
481
616
  # Check if quick checkout requires an address collection
482
- # If the order is digital or not delivery required, then we don't need to collect an address
483
617
  # @return [Boolean]
484
618
  def quick_checkout_require_address?
485
- !digital? && delivery_required?
619
+ shipping_address_required?
486
620
  end
487
621
 
488
- # Returns the relevant zone (if any) to be used for taxation purposes.
489
- # Uses default tax zone unless there is a specific match
490
- def tax_zone
491
- @tax_zone ||= Zone.match(tax_address) || Zone.default_tax
622
+ # @deprecated Use {#recalculate_totals!} for money and {#update_statuses!}
623
+ # for payment/fulfillment statuses; removed in 6.1.
624
+ def updater
625
+ @updater ||= Spree.order_updater.new(self)
492
626
  end
493
627
 
494
- # Returns the address for taxation based on configuration
495
- def tax_address
496
- Spree::Config[:tax_using_ship_address] ? ship_address : bill_address
628
+ # Recomputes and persists money totals (item, tax, promotion, delivery)
629
+ # and derived item counts. Convenience for
630
+ # {Spree::Orders::RecalculateTotals}.
631
+ def recalculate_totals!
632
+ Spree.order_recalculate_totals_workflow.call(order: self)
497
633
  end
498
634
 
499
- def updater
500
- @updater ||= Spree.order_updater.new(self)
635
+ # Derives and persists payment_status / fulfillment_status from the
636
+ # order's payment, refund and fulfillment records. Convenience for
637
+ # {Spree::Orders::UpdateStatuses}, the sole status writer.
638
+ def update_statuses!
639
+ Spree.order_update_statuses_service.call(order: self)
501
640
  end
502
641
 
642
+ # @deprecated Use {#recalculate_totals!}; removed in 6.1.
503
643
  def update_with_updater!
504
- updater.update
644
+ Spree::Deprecation.warn('Spree::Order#update_with_updater! is deprecated and will be removed in Spree 6.1. Use #recalculate_totals! instead.')
645
+ recalculate_totals!
505
646
  end
506
647
 
648
+ # @deprecated Use {Spree::Carts::Merge}; removed in 6.1.
507
649
  def merger
508
650
  @merger ||= Spree::OrderMerger.new(self)
509
651
  end
510
652
 
511
- def ensure_store_presence
512
- Spree::Deprecation.warn('Spree::Order#ensure_store_presence is deprecated and will be removed in Spree 6.0. ensure_store instead.')
513
- ensure_store
514
- end
515
-
516
- def ensure_market_presence
517
- self.market ||= Spree::Current.market || store&.default_market
518
- end
519
-
520
- def ensure_channel_presence
521
- return if channel_id.present?
522
-
523
- self.channel = store&.default_channel
524
- end
525
-
526
- # @return [Boolean] true when this order has no registered user and its
527
- # channel forbids guest checkout (see Spree::Channel::Gating). Enforced by
528
- # the checkout completion service and the v3 Store API so every completion
529
- # path (controller, payment webhook) is covered.
530
- #
531
- # A +prices_hidden+ channel also disallows guest completion regardless of
532
- # the +guest_checkout+ flag — prices are withheld from guests, and a buyer
533
- # who cannot see prices cannot meaningfully place an order. This dissolves
534
- # the otherwise contradictory "prices hidden but guests may buy" config.
535
- def guest_checkout_disallowed?
536
- return false if user_id.present?
537
- return false if channel.blank?
538
- return true if channel.storefront_prices_hidden?
539
-
540
- !channel.resolved_guest_checkout
541
- end
542
653
 
543
654
  def allow_cancel?
544
655
  return false if !completed? || canceled?
545
656
 
546
- shipment_state.nil? || %w{ready backorder pending canceled}.include?(shipment_state)
657
+ fulfillment_status.nil? || %w{unfulfilled backorder canceled}.include?(fulfillment_status)
547
658
  end
659
+ alias can_cancel? allow_cancel?
548
660
 
549
661
  def all_inventory_units_returned?
550
662
  inventory_units.all?(&:returned?)
551
663
  end
552
664
 
553
665
  # Associates the specified user with the order.
554
- # Delegates to {Spree::Cart::Associate} service.
666
+ # Delegates to {Spree::Carts::Associate} service.
555
667
  #
556
- # @param user [Spree.user_class] the user to associate with the order
557
- # @param override_email [Boolean] whether to override the order email with the user's email
668
+ # @param customer [Spree.customer_class] the customer to associate with the order
669
+ # @param override_email [Boolean] whether to override the order email with the customer's email
558
670
  # @return [Spree::ServiceModule::Result]
671
+ def associate_customer!(customer, override_email = true)
672
+ Spree.cart_associate_service.call(guest_cart: self, customer: customer, override_email: override_email)
673
+ end
674
+
675
+ # @deprecated Use {#associate_customer!}; removed in 6.1.
559
676
  def associate_user!(user, override_email = true)
560
- Spree.cart_associate_service.call(guest_order: self, user: user, override_email: override_email)
677
+ Spree::Deprecation.warn('Spree::Order#associate_user! is deprecated and will be removed in Spree 6.1. Use #associate_customer! instead.')
678
+ associate_customer!(user, override_email)
561
679
  end
562
680
 
563
- def disassociate_user!
564
- nullified_attributes = ASSOCIATED_USER_ATTRIBUTES.index_with(nil)
681
+ def disassociate_customer!
682
+ nullified_attributes = ASSOCIATED_CUSTOMER_ATTRIBUTES.index_with(nil)
565
683
 
566
684
  update!(nullified_attributes)
567
685
  end
568
686
 
569
- def quantity_of(variant, options = {})
570
- line_item = find_line_item_by_variant(variant, options)
571
- line_item ? line_item.quantity : 0
572
- end
573
-
574
- def find_line_item_by_variant(variant, options = {})
575
- line_items.detect do |line_item|
576
- line_item.variant_id == variant.id &&
577
- Spree.cart_compare_line_items_service.new.call(order: self, line_item: line_item, options: options).value
578
- end
687
+ # @deprecated Use {#disassociate_customer!}; removed in 6.1.
688
+ def disassociate_user!
689
+ Spree::Deprecation.warn('Spree::Order#disassociate_user! is deprecated and will be removed in Spree 6.1. Use #disassociate_customer! instead.')
690
+ disassociate_customer!
579
691
  end
580
692
 
581
- # Creates new tax charges if there are any applicable rates. If prices already
582
- # include taxes then price adjustments are created instead.
693
+ # Re-estimates tax through the configured provider (writes TaxLine rows
694
+ # with replace-all semantics).
583
695
  def create_tax_charge!
584
- Spree::TaxRate.adjust(self, line_items)
585
- Spree::TaxRate.adjust(self, shipments) if shipments.any?
696
+ tax_provider.estimate(self, **tax_estimate_inputs)
586
697
  end
587
698
 
588
699
  def create_shipment_tax_charge!
589
- Spree::TaxRate.adjust(self, shipments) if shipments.any?
700
+ tax_provider.estimate(self, fulfillments.to_a, **tax_estimate_inputs) if fulfillments.any?
590
701
  end
591
702
 
703
+ # Re-prices every line from the catalog.
704
+ #
705
+ # A completed order's money is frozen — re-pricing would rewrite what the
706
+ # customer was actually charged — so this refuses rather than reporting a
707
+ # success it did not deliver. Post-placement price changes belong to the
708
+ # order-change substrate (docs/plans/6.1-order-change-substrate.md).
709
+ #
710
+ # @raise [RuntimeError] when the order is already completed
711
+ # @return [void]
592
712
  def update_line_item_prices!
713
+ raise 'cannot re-price a completed order' if completed?
714
+
593
715
  transaction do
594
716
  line_items.reload.each(&:update_price)
595
717
  save!
596
718
  end
597
719
  end
598
720
 
721
+ # Refunds are already netted out of payment_total by
722
+ # Spree::Carts::RecalculateTotals, so returns and claims need no separate
723
+ # term here — the legacy reimbursement payout was the only one that sat
724
+ # outside that sum.
599
725
  def outstanding_balance
600
726
  if canceled?
601
727
  -1 * payment_total
602
728
  else
603
- total - (payment_total + reimbursement_paid_total)
729
+ total - payment_total
604
730
  end
605
731
  end
606
732
 
607
- def reimbursement_paid_total
608
- reimbursements.sum(&:paid_amount)
733
+
734
+ # The payments that settle this order.
735
+ #
736
+ # An order placed in a split checkout has none of its own: the customer
737
+ # made one payment for the whole basket, against the group. Anything asking
738
+ # what money exists for this order — capture on dispatch, refunds, the
739
+ # admin payments panel — reads it here, and reads its own share of it from
740
+ # {#payment_splits}.
741
+ #
742
+ # @return [ActiveRecord::Relation<Spree::Payment>]
743
+ def settlement_payments
744
+ order_group_id.present? ? order_group.payments : payments
745
+ end
746
+
747
+ # What has been captured against this order, net of refunds.
748
+ #
749
+ # An order placed in a split checkout owns no payments, so its own
750
+ # +payment_total+ stays at zero however much the customer paid — the
751
+ # figure comes from its share of the group's payments instead, the same
752
+ # way {Spree::Orders::UpdateStatuses} derives +payment_status+. The
753
+ # group's own total will not do: once one seller has been captured and
754
+ # another has not, no proportion of it describes either.
755
+ #
756
+ # @return [BigDecimal]
757
+ def net_captured_total
758
+ return payment_total unless grouped?
759
+
760
+ payment_splits.sum(&:net_captured_amount)
609
761
  end
610
762
 
611
- def outstanding_balance?
612
- outstanding_balance != 0
763
+ # Payments still to be collected for this order, wherever they live.
764
+ #
765
+ # @return [ActiveRecord::Relation<Spree::Payment>, Array<Spree::Payment>]
766
+ def settlement_pending_payments
767
+ grouped? ? settlement_payments.pending : pending_payments
768
+ end
769
+
770
+ # @return [Boolean] whether this order was placed alongside others in one
771
+ # checkout, and therefore shares their payment
772
+ def grouped?
773
+ order_group_id.present?
774
+ end
775
+
776
+ # This order and any placed alongside it in the same checkout.
777
+ #
778
+ # The set anything counting *checkouts* rather than orders works from — a
779
+ # promotion's usage limit, for one, which must not be spent several times
780
+ # over because a basket happened to span several sellers.
781
+ #
782
+ # @return [Array<Integer>]
783
+ def sibling_order_ids
784
+ return [id] unless grouped?
785
+
786
+ order_group.orders.ids
787
+ end
788
+
789
+ # This order's share of one payment made against its group.
790
+ #
791
+ # @param payment [Spree::Payment]
792
+ # @return [Spree::PaymentSplit, nil]
793
+ def payment_split_for(payment)
794
+ payment_splits.find_by(payment_id: payment.id)
613
795
  end
614
796
 
615
797
  def name
@@ -619,8 +801,8 @@ module Spree
619
801
  end
620
802
 
621
803
  def full_name
622
- @full_name ||= if user.present? && user.name.present?
623
- user.full_name
804
+ @full_name ||= if customer.present? && customer.name.present?
805
+ customer.full_name
624
806
  else
625
807
  billing_address&.full_name || email
626
808
  end
@@ -646,62 +828,38 @@ module Spree
646
828
  def backordered_variants
647
829
  variants.
648
830
  where(track_inventory: true).
649
- joins(:stock_items, :product).
650
- where(Spree::StockItem.table_name => { count_on_hand: ..0, backorderable: true })
831
+ joins(:stock_levels, :product).
832
+ where(Spree::StockLevel.table_name => { backorderable: true }).
833
+ where("#{Spree::StockLevel.table_name}.count_on_hand - #{Spree::StockLevel.table_name}.allocated_count <= ?", 0)
651
834
  end
652
835
 
653
836
  def can_ship?
654
- complete? || resumed? || awaiting_return? || returned?
837
+ placed?
655
838
  end
656
839
 
657
840
  def uneditable?
658
- complete? || canceled? || returned?
841
+ completed? || canceled?
659
842
  end
660
843
 
661
844
  # Finalizes an in progress order after checkout is complete.
662
845
  # Called after transition to complete state when payments will have been processed
846
+ # @deprecated Completion lives in {Spree::Orders::Complete} (checkout
847
+ # reaches it through +Spree.carts_complete_workflow+). Removed in 6.1.
663
848
  def finalize!
664
- # lock all adjustments (coupon promotions, etc.)
665
- all_adjustments.each(&:close)
666
-
667
- # update payment and shipment(s) states, and save
668
- updater.update_payment_state
669
- shipments.each do |shipment|
670
- shipment.update!(self)
671
- shipment.finalize!
672
- end
673
-
674
- updater.update_shipment_state
675
- self.status = 'placed'
676
- save!
677
- updater.run_hooks
678
-
679
- touch :completed_at
680
-
681
- send_order_placed_webhook
682
-
683
- consider_risk
684
-
685
- publish_order_completed_event
849
+ Spree::Deprecation.warn('Spree::Order#finalize! is deprecated and will be removed in Spree 6.1. Completion runs through Spree.order_complete_workflow (Spree::Orders::Complete).')
850
+ Spree.order_complete_workflow.call(order: self, payment_pending: true)
686
851
  end
687
852
 
688
853
  def fulfill!
689
- shipments.each { |shipment| shipment.update!(self) if shipment.persisted? }
690
- updater.update_shipment_state
854
+ fulfillments.each { |shipment| shipment.update!(self) if shipment.persisted? }
691
855
  save!
856
+ update_statuses!
692
857
  end
693
858
 
694
- # Helper methods for checkout steps
695
- def paid?
696
- payments.valid.completed.size == payments.valid.size && payments.valid.sum(:amount) >= total
697
- end
698
859
 
699
- def payment_methods
700
- @payment_methods ||= store.payment_methods.active.available_on_front_end.select { |pm| pm.available_for_order?(self) }
701
- end
702
860
 
703
861
  def available_payment_methods(store = nil)
704
- Spree::Deprecation.warn('`Order#available_payment_methods` is deprecated and will be removed in Spree 5.5. Use `collect_frontend_payment_methods` instead.')
862
+ Spree::Deprecation.warn('`Order#available_payment_methods` is deprecated and will be removed in Spree 6.1. Use `payment_methods` instead.')
705
863
 
706
864
  @available_payment_methods ||= collect_payment_methods(store)
707
865
  end
@@ -713,99 +871,111 @@ module Spree
713
871
  ##
714
872
  # Check to see if any line item variants are discontinued.
715
873
  # If so add error and restart checkout.
874
+ # @deprecated Completion validation lives in
875
+ # {Spree::Checkout::DefaultRequirements} (the +discontinued+ stock
876
+ # error). Removed in 6.1.
716
877
  def ensure_line_item_variants_are_not_discontinued
878
+ Spree::Deprecation.warn('Spree::Order#ensure_line_item_variants_are_not_discontinued is deprecated and will be removed in Spree 6.1. Completion validation lives in Spree::Checkout::Requirements.')
717
879
  if line_items.any? { |li| !li.variant || li.variant.discontinued? }
718
- restart_checkout_flow
719
- errors.add(:base, Spree.t(:discontinued_variants_present))
880
+ errors.add(:base, :discontinued_variants_present, message: Spree.t(:discontinued_variants_present))
720
881
  false
721
882
  else
722
883
  true
723
884
  end
724
885
  end
725
886
 
887
+ # @deprecated Completion validation lives in
888
+ # {Spree::Checkout::DefaultRequirements} (the +out_of_stock+ stock
889
+ # error). Removed in 6.1.
726
890
  def ensure_line_items_are_in_stock
891
+ Spree::Deprecation.warn('Spree::Order#ensure_line_items_are_in_stock is deprecated and will be removed in Spree 6.1. Completion validation lives in Spree::Checkout::Requirements.')
727
892
  if insufficient_stock_lines.present?
728
- restart_checkout_flow
729
- errors.add(:base, Spree.t(:insufficient_stock_lines_present))
893
+ errors.add(:base, :insufficient_stock_lines_present, message: Spree.t(:insufficient_stock_lines_present))
730
894
  false
731
895
  else
732
896
  true
733
897
  end
734
898
  end
735
899
 
736
- def empty!
737
- raise Spree.t(:cannot_empty_completed_order) if completed?
738
-
739
- result = Spree.cart_empty_service.call(order: self)
740
- result.value
741
- end
742
-
743
900
  def use_all_coupon_codes
901
+ Spree::Deprecation.warn('Spree::Order#use_all_coupon_codes is deprecated and will be removed in Spree 6.1. Use Spree::CouponCodes::CouponCodesHandler instead.')
744
902
  Spree::CouponCodes::CouponCodesHandler.new(order: self).use_all_codes
745
903
  end
746
904
 
747
- def has_step?(step)
748
- checkout_steps.include?(step)
749
- end
905
+ normalizes :coupon_code, with: ->(code) { code.to_s.strip.downcase.presence }
750
906
 
751
- def state_changed(name)
752
- state = "#{name}_state"
753
- if persisted?
754
- old_state = send("#{state}_was")
755
- new_state = send(state)
756
- unless old_state == new_state
757
- log_state_changes(state_name: name, old_state: old_state, new_state: new_state)
758
- end
759
- end
760
- end
761
-
762
- def log_state_changes(state_name:, old_state:, new_state:)
763
- state_changes.create(
764
- previous_state: old_state,
765
- next_state: new_state,
766
- name: state_name,
767
- user_id: user_id
768
- )
907
+ def can_add_coupon?
908
+ Spree::Deprecation.warn('Spree::Order#can_add_coupon? is deprecated and will be removed in Spree 6.1. Use Spree::Promotion.order_activatable? instead.')
909
+ Spree::Promotion.order_activatable?(self)
769
910
  end
770
911
 
771
- def coupon_code=(code)
772
- @coupon_code = begin
773
- code.strip.downcase
774
- rescue StandardError
775
- nil
776
- end
912
+ def shipped?
913
+ %w(partial shipped fulfilled delivered).include?(fulfillment_status)
777
914
  end
778
915
 
779
- def can_add_coupon?
780
- Spree::Promotion.order_activatable?(self)
916
+ # True when every fulfillment has left the merchant's hands — the signal
917
+ # order.fulfilled publishes on. `delivered` counts: it is downstream of
918
+ # fulfilled, so a delivered order must not read as un-fulfilled.
919
+ def fully_fulfilled?
920
+ fulfillments.fulfilled_or_delivered.size == fulfillments.size
781
921
  end
782
922
 
783
- def shipped?
784
- %w(partial shipped).include?(shipment_state)
923
+ # True when every fulfillment reached confirmed receipt — the signal
924
+ # order.delivered publishes on.
925
+ def fully_delivered?
926
+ total = fulfillments.size
927
+ total.positive? && fulfillments.delivered.size == total
785
928
  end
786
929
 
930
+ # @deprecated Use {#fully_fulfilled?}; removed in 6.1.
787
931
  def fully_shipped?
788
- shipments.shipped.size == shipments.size
932
+ Spree::Deprecation.warn('Spree::Order#fully_shipped? is deprecated and will be removed in Spree 6.1. Use #fully_fulfilled? instead.')
933
+ fully_fulfilled?
789
934
  end
790
935
 
791
- def create_proposed_shipments
792
- all_adjustments.shipping.delete_all
936
+ def rebuild_fulfillments!
937
+ discounts.for_fulfillments.delete_all
938
+ tax_lines.for_fulfillments.delete_all
939
+ fees.for_fulfillments.delete_all
793
940
 
794
- shipment_ids = shipments.map(&:id)
795
- StateChange.where(stateful_type: 'Spree::Shipment', stateful_id: shipment_ids).delete_all
796
- ShippingRate.where(shipment_id: shipment_ids).delete_all
941
+ shipment_ids = fulfillments.map(&:id)
942
+ DeliveryRate.where(fulfillment_id: shipment_ids).delete_all
797
943
 
798
- shipments.delete_all
944
+ fulfillments.delete_all
799
945
 
800
946
  # Inventory Units which are not associated to any shipment (unshippable)
801
947
  # and are not returned or shipped should be deleted
802
- inventory_units.on_hand_or_backordered.delete_all
948
+ fulfillment_items.on_hand_or_backordered.delete_all
803
949
 
804
- self.shipments = order_routing_strategy.for_allocation.map do |package|
805
- package.to_shipment.tap { |s| s.address_id = ship_address_id }
950
+ self.fulfillments = order_routing_strategy.for_allocation.map do |package|
951
+ package.to_fulfillment.tap { |fulfillment| fulfillment.address_id = ship_address_id }
806
952
  end
807
953
  end
808
954
 
955
+ # @deprecated Use {#rebuild_fulfillments!}; removed in 6.1.
956
+ def create_proposed_fulfillments
957
+ Spree::Deprecation.warn('Spree::Order#create_proposed_fulfillments is deprecated and will be removed in Spree 6.1. Use #rebuild_fulfillments! instead.')
958
+ rebuild_fulfillments!
959
+ end
960
+
961
+ # @deprecated Use {#rebuild_fulfillments!}; removed in 6.1.
962
+ def create_proposed_shipments
963
+ Spree::Deprecation.warn('Spree::Order#create_proposed_shipments is deprecated and will be removed in Spree 6.1. Use #rebuild_fulfillments! instead.')
964
+ rebuild_fulfillments!
965
+ end
966
+
967
+ # @deprecated Use {#delivery_step_required?}; removed in 6.1.
968
+ def delivery_required?
969
+ Spree::Deprecation.warn('Spree::Order#delivery_required? is deprecated and will be removed in Spree 6.1. Use #delivery_step_required? (delivery-step applicability) or #shipping_address_required? (address collection) instead.')
970
+ delivery_step_required?
971
+ end
972
+
973
+ # @deprecated Use {#shipping_address_required?}; removed in 6.1.
974
+ def requires_ship_address?
975
+ Spree::Deprecation.warn('Spree::Order#requires_ship_address? is deprecated and will be removed in Spree 6.1. Use #shipping_address_required? instead.')
976
+ shipping_address_required?
977
+ end
978
+
809
979
  # Resolves the routing strategy from the channel override first, then the
810
980
  # store default. Only a registered Spree::OrderRouting::Strategy::Base
811
981
  # subclass is used; any other value (an unregistered/typo'd class, or a
@@ -839,27 +1009,35 @@ module Spree
839
1009
  @total_weight ||= line_items.joins(:variant).includes(:variant).map(&:item_weight).sum
840
1010
  end
841
1011
 
842
- # Returns line items that have no shipping rates
1012
+ # Returns line items that have no delivery rates
1013
+ #
1014
+ # Deliberately not memoized: callers destroy fulfillments between reads
1015
+ # (see {#ensure_available_delivery_rates}), so a cached value would
1016
+ # describe fulfillments that no longer exist.
843
1017
  #
844
1018
  # @return [Array<Spree::LineItem>]
845
- def line_items_without_shipping_rates
846
- @line_items_without_shipping_rates ||= shipments.map do |shipment|
847
- shipment.manifest.map(&:line_item) if shipment.shipping_rates.blank?
1019
+ def line_items_without_delivery_rates
1020
+ fulfillments.map do |fulfillment|
1021
+ fulfillment.manifest.map(&:line_item) if fulfillment.delivery_rates.blank?
848
1022
  end.flatten.compact
849
1023
  end
850
1024
 
1025
+ # @deprecated Use {#line_items_without_delivery_rates}; removed in 6.1.
1026
+ def line_items_without_shipping_rates
1027
+ Spree::Deprecation.warn('Spree::Order#line_items_without_shipping_rates is deprecated and will be removed in Spree 6.1. Use #line_items_without_delivery_rates instead.')
1028
+ line_items_without_delivery_rates
1029
+ end
1030
+
851
1031
  # Checks if all line items cannot be shipped
852
1032
  #
853
1033
  # @returns Boolean
854
1034
  def all_line_items_invalid?
855
- line_items_without_shipping_rates.size == line_items.count
1035
+ line_items_without_delivery_rates.size == line_items.count
856
1036
  end
857
1037
 
858
1038
  def apply_free_shipping_promotions
859
1039
  Spree::PromotionHandler::FreeShipping.new(self).activate
860
- shipments.each { |shipment| Spree::Adjustable::AdjustmentsUpdater.update(shipment) }
861
- create_shipment_tax_charge!
862
- update_with_updater!
1040
+ recalculate_totals!
863
1041
  end
864
1042
 
865
1043
  # Applies user promotions when login after filling the cart
@@ -867,55 +1045,61 @@ module Spree
867
1045
  ::Spree::PromotionHandler::Cart.new(self).activate
868
1046
  end
869
1047
 
870
- # Clean shipments and make order back to address state
871
- #
872
- # At some point the might need to force the order to transition from address
873
- # to delivery again so that proper updated shipments are created.
874
- # e.g. customer goes back from payment step and changes order items
875
- def ensure_updated_shipments
876
- if shipments.any? && !completed?
877
- shipments.destroy_all
878
- update_column(:shipment_total, 0)
1048
+ # Drops stale fulfillments so they are rebuilt from current items.
1049
+ def ensure_updated_fulfillments
1050
+ if fulfillments.any? && !completed?
1051
+ fulfillments.destroy_all
1052
+ update_column(:delivery_total, 0)
879
1053
 
880
1054
  # Manually publish update event since update_column bypasses callbacks
881
1055
  publish_event('order.updated')
882
-
883
- restart_checkout_flow
884
1056
  end
885
1057
  end
886
1058
 
887
- def restart_checkout_flow
888
- update_columns(
889
- state: 'cart',
890
- updated_at: Time.current
891
- )
892
-
893
- # Manually publish update event since update_columns bypasses callbacks
894
- publish_event('order.updated')
895
-
896
- next! unless line_items.empty?
1059
+ # @deprecated Use {#ensure_updated_fulfillments}; removed in 6.1.
1060
+ def ensure_updated_shipments
1061
+ Spree::Deprecation.warn('Spree::Order#ensure_updated_fulfillments is deprecated and will be removed in Spree 6.1. Use #ensure_updated_fulfillments instead.')
1062
+ ensure_updated_fulfillments
897
1063
  end
898
1064
 
899
- def refresh_shipment_rates(shipping_method_filter = ShippingMethod::DISPLAY_ON_FRONT_END)
900
- shipments.map { |s| s.refresh_rates(shipping_method_filter) }
1065
+ # Re-quotes every fulfillment for the given audience.
1066
+ #
1067
+ # @param audience [Symbol] {Spree::DeliveryMethod::STOREFRONT} (default)
1068
+ # or {Spree::DeliveryMethod::BACKOFFICE}
1069
+ # @return [Array<Array<Spree::DeliveryRate>>]
1070
+ def refresh_delivery_rates(audience = DeliveryMethod::STOREFRONT)
1071
+ fulfillments.map { |fulfillment| fulfillment.refresh_rates(audience) }
901
1072
  end
902
1073
 
903
- def shipping_eq_billing_address?
904
- bill_address == ship_address
1074
+ # @deprecated Use {#refresh_delivery_rates}; removed in 6.1.
1075
+ def refresh_shipment_rates(audience = DeliveryMethod::STOREFRONT)
1076
+ Spree::Deprecation.warn('Spree::Order#refresh_shipment_rates is deprecated and will be removed in Spree 6.1. Use #refresh_delivery_rates instead.')
1077
+ refresh_delivery_rates(audience)
905
1078
  end
906
1079
 
907
1080
  def set_shipments_cost
908
- shipments.each(&:update_amounts)
909
- updater.update_shipment_total
910
- updater.update_adjustment_total
911
- persist_totals
1081
+ Spree::Deprecation.warn('Spree::Order#set_shipments_cost is deprecated and will be removed in Spree 6.1l. Please use set_fulfillments_cost instead')
1082
+ set_fulfillments_cost
1083
+ end
1084
+
1085
+ def set_fulfillments_cost
1086
+ fulfillments.each(&:update_amounts)
1087
+ recalculate_totals!
912
1088
  end
913
1089
 
914
1090
  def shipping_method
915
- # This query will select the first available shipping method from the shipments.
916
- # It will use subquery to first select the shipping method id from the shipments' selected_shipping_rate.
917
- Spree::ShippingMethod.
918
- where(id: shipments.with_selected_shipping_method.limit(1).pluck(:shipping_method_id)).
1091
+ Spree::Deprecation.warn('Spree::Order#shipping_method is deprecated and will be removed in Spree 6.1. Please use Spree::Order#delivery_method')
1092
+ delivery_method
1093
+ end
1094
+
1095
+ # Returns first available delivery method from the fulfillments
1096
+ # Useful for analytics and CSV exports
1097
+ # @return [Spree::DeliveryMethod]
1098
+ def delivery_method
1099
+ # This query will select the first available delivery method from the fulfillments.
1100
+ # It will use subquery to first select the delivery method id from the fulfillments' selected_delivery_rate.
1101
+ Spree::DeliveryMethod.
1102
+ where(id: fulfillments.with_selected_delivery_method.limit(1).pluck(:delivery_method_id)).
919
1103
  limit(1).
920
1104
  first
921
1105
  end
@@ -925,22 +1109,38 @@ module Spree
925
1109
  end
926
1110
 
927
1111
  # Cancels the order and records the canceler.
928
- # Delegates to {Spree::Orders::Cancel} service.
1112
+ # Delegates to {Spree::Orders::Cancel} workflow.
929
1113
  #
930
- # @param user [Spree.user_class, nil] the user who canceled the order
1114
+ # @deprecated Call {Spree.order_cancel_workflow} directly it exposes the
1115
+ # full cancellation vocabulary (reason, note, refund_payments,
1116
+ # notify_customer) this wrapper cannot pass through.
1117
+ # @param user [Spree.customer_class, nil] the user who canceled the order
931
1118
  # @param canceled_at [Time, nil] the time of cancellation (defaults to current time)
932
1119
  # @return [Spree::ServiceModule::Result]
933
1120
  def canceled_by(user, canceled_at = nil)
934
- Spree.order_cancel_service.call(order: self, canceler: user, canceled_at: canceled_at)
1121
+ Spree::Deprecation.warn('Spree::Order#canceled_by is deprecated and will be removed in Spree 6.1. Use Spree.order_cancel_workflow (Spree::Orders::Cancel) instead.')
1122
+ Spree.order_cancel_workflow.call(order: self, canceler: user, canceled_at: canceled_at)
1123
+ end
1124
+
1125
+ # Machine-free lifecycle: cancellation runs through the
1126
+ # {Spree::Orders::Cancel} workflow. There is no way back — a canceled
1127
+ # order stays canceled, as it does on every comparable platform.
1128
+ def cancel
1129
+ Spree.order_cancel_workflow.call(order: self).success?
1130
+ end
1131
+
1132
+ def cancel!
1133
+ cancel || raise(ActiveRecord::RecordInvalid.new(self))
935
1134
  end
936
1135
 
937
1136
  # Approves the order and records the approver.
938
1137
  # Delegates to {Spree::Orders::Approve} service.
939
1138
  #
940
- # @param user [Spree.user_class, nil] the user who approved the order
1139
+ # @param actor [Object, nil] who approved it — an admin user or an API
1140
+ # key (see Spree.actor_classes)
941
1141
  # @return [Spree::ServiceModule::Result]
942
- def approved_by(user = nil)
943
- Spree.order_approve_service.call(order: self, approver: user)
1142
+ def approved_by(actor = nil)
1143
+ Spree.order_approve_service.call(order: self, approver: actor)
944
1144
  end
945
1145
 
946
1146
  def approved?
@@ -951,14 +1151,6 @@ module Spree
951
1151
  !approved?
952
1152
  end
953
1153
 
954
- def can_be_destroyed?
955
- Spree::Deprecation.warn('Spree::Order#can_be_destroyed? is deprecated and will be removed in the next major version. Use Spree::Order#can_be_deleted? instead.')
956
- can_be_deleted?
957
- end
958
-
959
- def can_be_deleted?
960
- !completed? && payments.completed.empty?
961
- end
962
1154
 
963
1155
  def consider_risk
964
1156
  considered_risky! if is_risky? && !approved?
@@ -979,26 +1171,10 @@ module Spree
979
1171
  Spree.order_approve_service.call(order: self)
980
1172
  end
981
1173
 
982
- def tax_total
983
- included_tax_total + additional_tax_total
984
- end
985
-
986
- def quantity
987
- line_items.sum(:quantity)
988
- end
989
-
990
- def has_non_reimbursement_related_refunds?
991
- refunds.non_reimbursement.exists? ||
992
- payments.offset_payment.exists? # how old versions of spree stored refunds
993
- end
994
-
995
1174
  def collect_backend_payment_methods
996
- store.payment_methods.active.available_on_back_end.select { |pm| pm.available_for_order?(self) }
1175
+ store.payment_methods.active.select { |pm| pm.available_for_order?(self) }
997
1176
  end
998
1177
 
999
- def collect_frontend_payment_methods
1000
- store.payment_methods.active.available_on_front_end.select { |pm| pm.available_for_order?(self) }
1001
- end
1002
1178
 
1003
1179
  # determines whether the inventory is fully discounted
1004
1180
  #
@@ -1023,9 +1199,7 @@ module Spree
1023
1199
  # Returns the IDs of the valid promotions for the order
1024
1200
  # @return [Array<Integer>]
1025
1201
  def valid_promotion_ids
1026
- all_adjustments.eligible.nonzero.promotion.promotion.eligible.nonzero.promotion.
1027
- joins("INNER JOIN #{Spree::PromotionAction.table_name} ON #{Spree::PromotionAction.table_name}.id = #{Spree::Adjustment.table_name}.source_id").
1028
- pluck("#{Spree::PromotionAction.table_name}.promotion_id").compact.uniq
1202
+ discounts.promotion.nonzero.where.not(promotion_id: nil).distinct.pluck(:promotion_id)
1029
1203
  end
1030
1204
 
1031
1205
  # Returns the valid coupon promotions for the order
@@ -1037,43 +1211,50 @@ module Spree
1037
1211
  end
1038
1212
 
1039
1213
  # Returns item and whole order discount amount for Order
1040
- # without Shipment discounts (eg. Free Shipping)
1214
+ # without fulfillment discounts (eg. Free Shipping)
1041
1215
  # @return [BigDecimal]
1042
1216
  def cart_promo_total
1043
- all_adjustments.eligible.nonzero.promotion.
1044
- where.not(adjustable_type: 'Spree::Shipment').
1045
- sum(:amount)
1217
+ Spree::Deprecation.warn('Spree::Order#cart_promo_total is deprecated and will be removed in Spree 6.1. Please use order.cart.discount_total instead')
1218
+ discounts.promotion.nonzero.for_line_items.sum(:amount)
1046
1219
  end
1047
1220
 
1048
1221
  def has_free_shipping?
1049
- shipment_adjustments.
1050
- joins(:promotion_action).
1051
- where(spree_adjustments: { eligible: true, source_type: 'Spree::PromotionAction' },
1052
- spree_promotion_actions: { type: 'Spree::Promotion::Actions::FreeShipping' }).exists?
1222
+ discounts.promotion.for_fulfillments.exists?
1053
1223
  end
1054
1224
 
1055
- def to_csv(_store = nil)
1056
- metafields_for_csv ||= Spree::MetafieldDefinition.for_resource_type('Spree::Order').order(:namespace, :key).map do |mf_def|
1057
- metafields.find { |mf| mf.metafield_definition_id == mf_def.id }&.csv_value
1058
- end
1225
+ # @param omit_headers [Array<String>] columns to leave out, named by their
1226
+ # header. A seller's export drops the buyer's email this way — see
1227
+ # Spree::Exports::Orders.
1228
+ def to_csv(store = nil, omit_headers: [])
1229
+ store ||= self.store
1230
+ # Through the shared helper so the value row is built from exactly the
1231
+ # definitions, in exactly the order, that Export#custom_fields_headers
1232
+ # used for the header row — a mismatch shifts every value column.
1233
+ custom_field_values = custom_fields_for_csv(self, store)
1059
1234
 
1060
1235
  csv_lines = []
1061
- all_line_items.each_with_index do |line_item, index|
1062
- csv_lines << Spree::CSV::OrderLineItemPresenter.new(self, line_item, index, metafields_for_csv).call
1236
+ line_items.each_with_index do |line_item, index|
1237
+ csv_lines << Spree::CSV::OrderLineItemPresenter.new(
1238
+ self, line_item, index, custom_field_values, omit_headers: omit_headers
1239
+ ).call
1063
1240
  end
1064
1241
  csv_lines
1065
1242
  end
1066
1243
 
1067
1244
  def all_line_items
1245
+ Spree::Deprecation.warn('Spree::Order#all_line_items is deprecated and will be removed in Spree 6.1. Please use Spree::Order#line_items instead')
1068
1246
  line_items
1069
1247
  end
1070
1248
 
1071
- def requires_ship_address?
1072
- !digital?
1073
- end
1074
-
1075
1249
  private
1076
1250
 
1251
+ def ensure_can_be_deleted
1252
+ return true if can_be_deleted?
1253
+
1254
+ errors.add(:base, :order_cannot_be_deleted, message: Spree.t(:order_cannot_be_deleted))
1255
+ throw :abort
1256
+ end
1257
+
1077
1258
  def valid_order_routing_strategy_class(klass_name)
1078
1259
  return if klass_name.blank?
1079
1260
 
@@ -1088,30 +1269,36 @@ module Spree
1088
1269
  end
1089
1270
 
1090
1271
  def link_by_email
1091
- self.email = user.email if user
1272
+ self.email = customer.email if customer
1092
1273
  end
1093
1274
 
1094
1275
  # Determine if email is required (we don't want validation errors before we hit the checkout)
1095
1276
  # we need to add delivery to the list for quick checkouts
1096
1277
  def require_email
1097
- true unless new_record? || ['cart', 'address', 'delivery'].include?(state)
1278
+ !new_record? && (completed? || placed?)
1098
1279
  end
1099
1280
 
1100
1281
  def ensure_line_items_present
1101
1282
  unless line_items.present?
1102
- errors.add(:base, Spree.t(:there_are_no_items_for_this_order)) && (return false)
1283
+ errors.add(:base, :there_are_no_items_for_this_order, message: Spree.t(:there_are_no_items_for_this_order)) && (return false)
1103
1284
  end
1104
1285
  end
1105
1286
 
1106
- def ensure_available_shipping_rates
1107
- if shipments.empty? || line_items_without_shipping_rates.present?
1287
+ def ensure_available_delivery_rates
1288
+ # Captured before destroy_all — afterwards there are no fulfillments
1289
+ # left to derive the undeliverable items from.
1290
+ undeliverable_line_items = line_items_without_delivery_rates
1291
+
1292
+ if fulfillments.empty? || undeliverable_line_items.present?
1108
1293
  # After this point, order redirects back to 'address' state and asks user to pick a proper address
1109
1294
  # Therefore, shipments are not necessary at this point.
1110
- shipments.destroy_all
1295
+ fulfillments.destroy_all
1111
1296
 
1112
- if line_items_without_shipping_rates.present?
1113
- errors.add(:base, Spree.t(:products_cannot_be_shipped, product_names: line_items_without_shipping_rates.map(&:name).to_sentence))
1114
- self.warnings |= line_items_without_shipping_rates.map do |line_item|
1297
+ if undeliverable_line_items.present?
1298
+ product_names = undeliverable_line_items.map(&:name).to_sentence
1299
+ errors.add(:base, :products_cannot_be_shipped, product_names: product_names,
1300
+ message: Spree.t(:products_cannot_be_shipped, product_names: product_names))
1301
+ self.warnings |= undeliverable_line_items.map do |line_item|
1115
1302
  {
1116
1303
  code: 'delivery_unavailable',
1117
1304
  message: Spree.t('cart_line_item.delivery_unavailable', li_name: line_item.name),
@@ -1120,7 +1307,7 @@ module Spree
1120
1307
  }
1121
1308
  end
1122
1309
  else
1123
- errors.add(:base, Spree.t(:items_cannot_be_shipped))
1310
+ errors.add(:base, :items_cannot_be_shipped, message: Spree.t(:items_cannot_be_shipped))
1124
1311
  self.warnings |= [{ code: 'delivery_unavailable', message: Spree.t(:items_cannot_be_shipped) }]
1125
1312
  end
1126
1313
 
@@ -1128,85 +1315,10 @@ module Spree
1128
1315
  end
1129
1316
  end
1130
1317
 
1131
- def after_cancel
1132
- update_column(:status, 'canceled')
1133
-
1134
- shipments.each(&:cancel!)
1135
-
1136
- # payments fully covered by gift card won't be refunded
1137
- # we want to only void the payment
1138
- if gift_card.present? && covered_by_store_credit?
1139
- payments.completed.store_credits.each(&:void!)
1140
- else
1141
- payments.completed.each(&:cancel!)
1142
- payments.incomplete.not_store_credits.each(&:void_transaction!)
1143
- payments.store_credits.pending.each(&:void!)
1144
- end
1145
-
1146
- update_with_updater!
1147
- send_order_canceled_webhook
1148
- end
1149
-
1150
- def after_resume
1151
- update_column(:status, 'placed')
1152
-
1153
- shipments.each(&:resume!)
1154
- consider_risk
1155
- send_order_resumed_webhook
1156
- publish_order_resumed_event
1157
- end
1158
-
1159
- def use_billing?
1160
- use_billing.in?([true, 'true', '1'])
1161
- end
1162
-
1163
- def use_shipping?
1164
- use_shipping.in?([true, 'true', '1'])
1165
- end
1166
-
1167
- def ensure_currency_presence
1168
- self.currency ||= store&.default_currency
1169
- end
1170
-
1171
- # Sets the locale from Spree::Current.locale when not already set.
1172
- # Called as a before_validation callback, mirroring ensure_currency_presence.
1173
- def ensure_locale_presence
1174
- self.locale ||= Spree::Current.locale
1175
- end
1176
-
1177
- def currency_must_be_supported_by_store
1178
- return if currency.blank? || store.blank?
1179
-
1180
- supported_codes = store.supported_currencies_list.map(&:iso_code)
1181
- unless supported_codes.include?(currency)
1182
- errors.add(:currency, Spree.t(:currency_not_supported_by_store))
1183
- end
1184
- end
1185
-
1186
- # Validates that the order's locale is within the store's supported locales.
1187
- # Mirrors currency_must_be_supported_by_store.
1188
- def locale_must_be_supported_by_store
1189
- return if locale.blank? || store.blank?
1190
-
1191
- unless store.supported_locales_list.include?(locale)
1192
- errors.add(:locale, Spree.t(:locale_not_supported_by_store))
1193
- end
1194
- end
1195
-
1196
- # When currency changes, auto-resolve the matching market.
1197
- # Only applies when the store has markets configured.
1198
- def resolve_market_from_currency
1199
- return unless store_has_markets?
1200
- return if market&.currency == currency
1201
-
1202
- resolved = store.markets.find_by(currency: currency)
1203
- self.market = resolved if resolved
1204
- end
1205
-
1206
1318
  def collect_payment_methods
1207
- Spree::Deprecation.warn('`Order#collect_payment_methods` is deprecated and will be removed in Spree 5.5. Use `collect_frontend_payment_methods` instead.')
1319
+ Spree::Deprecation.warn('`Order#collect_payment_methods` is deprecated and will be removed in Spree 6.1. Use `payment_methods` instead.')
1208
1320
 
1209
- store.payment_methods.available_on_front_end.select { |pm| pm.available_for_order?(self) }
1321
+ store.payment_methods.active.storefront_visible.select { |pm| pm.available_for_order?(self) }
1210
1322
  end
1211
1323
 
1212
1324
  def credit_card_nil_payment?(attributes)
@@ -1214,21 +1326,14 @@ module Spree
1214
1326
  end
1215
1327
 
1216
1328
  def recalculate_store_credit_payment
1217
- updater.update_adjustment_total if using_store_credit?
1329
+ recalculate_totals! if using_store_credit?
1218
1330
 
1219
1331
  if gift_card.present?
1220
1332
  recalculate_gift_card
1221
1333
  elsif using_store_credit?
1222
- Spree.checkout_add_store_credit_service.call(order: self)
1334
+ Spree.store_credit_apply_service.call(order: self)
1223
1335
  end
1224
1336
  end
1225
1337
 
1226
- def publish_order_completed_event
1227
- publish_event('order.completed', event_payload.merge(notify_customer: notify_customer))
1228
- end
1229
-
1230
- def publish_order_resumed_event
1231
- publish_event('order.resumed')
1232
- end
1233
1338
  end
1234
1339
  end