solidus_core 3.0.0 → 4.5.1

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 (444) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -2
  3. data/Rakefile +7 -2
  4. data/app/assets/images/logo/solidus.svg +18 -1
  5. data/app/assets/images/logo/solidus_logo.png +0 -0
  6. data/app/controllers/spree/base_controller.rb +1 -3
  7. data/app/helpers/spree/base_helper.rb +3 -3
  8. data/app/helpers/spree/core/controller_helpers/auth.rb +66 -0
  9. data/app/helpers/spree/core/controller_helpers/common.rb +82 -0
  10. data/app/helpers/spree/core/controller_helpers/order.rb +86 -0
  11. data/app/helpers/spree/core/controller_helpers/payment_parameters.rb +165 -0
  12. data/{lib/spree/core/controller_helpers/current_host.rb → app/helpers/spree/core/controller_helpers/pricing.rb} +6 -4
  13. data/app/helpers/spree/core/controller_helpers/search.rb +16 -0
  14. data/app/helpers/spree/core/controller_helpers/store.rb +19 -0
  15. data/app/helpers/spree/core/controller_helpers/strong_parameters.rb +74 -0
  16. data/app/helpers/spree/products_helper.rb +2 -2
  17. data/app/mailers/spree/base_mailer.rb +1 -1
  18. data/app/mailers/spree/carton_mailer.rb +1 -1
  19. data/app/mailers/spree/order_mailer.rb +3 -3
  20. data/app/mailers/spree/reimbursement_mailer.rb +1 -1
  21. data/app/models/concerns/spree/active_storage_adapter/attachment.rb +30 -11
  22. data/app/models/concerns/spree/active_storage_adapter/normalization.rb +1 -1
  23. data/app/models/concerns/spree/active_storage_adapter.rb +1 -18
  24. data/app/models/concerns/spree/default_price.rb +30 -10
  25. data/app/models/concerns/spree/display_money.rb +1 -1
  26. data/app/models/concerns/spree/metadata.rb +64 -0
  27. data/app/models/concerns/spree/named_type.rb +2 -0
  28. data/app/models/concerns/spree/ordered_property_value_list.rb +2 -2
  29. data/app/models/concerns/spree/ransackable_attributes.rb +9 -5
  30. data/app/models/concerns/spree/user_address_book.rb +19 -10
  31. data/app/models/concerns/spree/user_methods.rb +40 -6
  32. data/app/models/spree/address.rb +11 -9
  33. data/app/models/spree/adjustment.rb +15 -76
  34. data/app/models/spree/adjustment_reason.rb +2 -0
  35. data/app/models/spree/calculator/flat_fee.rb +21 -0
  36. data/app/models/spree/calculator/returns/default_refund_amount.rb +1 -1
  37. data/app/models/spree/carton.rb +3 -3
  38. data/app/models/spree/core/state_machines/inventory_unit.rb +42 -0
  39. data/app/models/spree/core/state_machines/order/class_methods.rb +217 -0
  40. data/app/models/spree/core/state_machines/order.rb +42 -0
  41. data/app/models/spree/core/state_machines/payment.rb +61 -0
  42. data/app/models/spree/core/state_machines/reimbursement.rb +33 -0
  43. data/app/models/spree/core/state_machines/return_authorization.rb +32 -0
  44. data/app/models/spree/core/state_machines/return_item/acceptance_status.rb +51 -0
  45. data/app/models/spree/core/state_machines/return_item/reception_status.rb +42 -0
  46. data/app/models/spree/core/state_machines/shipment.rb +58 -0
  47. data/app/models/spree/country.rb +1 -1
  48. data/app/models/spree/credit_card.rb +13 -10
  49. data/app/models/spree/customer_return.rb +6 -3
  50. data/app/models/spree/deprecated_configurable_class.rb +40 -0
  51. data/app/models/spree/fulfilment_changer.rb +56 -29
  52. data/app/models/spree/image/active_storage_attachment.rb +2 -7
  53. data/app/models/spree/image/paperclip_attachment.rb +2 -2
  54. data/app/models/spree/inventory_unit.rb +2 -2
  55. data/app/models/spree/item_total.rb +28 -0
  56. data/app/models/spree/legacy_user.rb +1 -0
  57. data/app/models/spree/line_item.rb +26 -8
  58. data/app/models/spree/log_entry.rb +98 -1
  59. data/app/models/spree/money.rb +120 -0
  60. data/app/models/spree/null_promotion_adjuster.rb +13 -0
  61. data/app/models/spree/null_promotion_advertiser.rb +9 -0
  62. data/app/models/spree/null_promotion_finder.rb +9 -0
  63. data/app/models/spree/null_promotion_handler.rb +44 -0
  64. data/app/models/spree/option_type.rb +1 -1
  65. data/app/models/spree/option_value.rb +4 -3
  66. data/app/models/spree/order/number_generator.rb +7 -1
  67. data/app/models/spree/order.rb +143 -96
  68. data/app/models/spree/order_cancellations.rb +8 -8
  69. data/app/models/spree/order_inventory.rb +7 -5
  70. data/app/models/spree/order_merger.rb +5 -7
  71. data/app/models/spree/order_mutex.rb +2 -2
  72. data/app/models/spree/order_shipping.rb +15 -19
  73. data/app/models/spree/order_taxation.rb +7 -4
  74. data/app/models/spree/order_update_attributes.rb +3 -1
  75. data/app/models/spree/order_updater.rb +25 -63
  76. data/app/models/spree/payment/processing.rb +60 -57
  77. data/app/models/spree/payment.rb +14 -27
  78. data/app/models/spree/payment_create.rb +1 -1
  79. data/app/models/spree/payment_method/bogus_credit_card.rb +18 -14
  80. data/app/models/spree/payment_method/credit_card.rb +0 -4
  81. data/app/models/spree/payment_method/simple_bogus_credit_card.rb +18 -4
  82. data/app/models/spree/payment_method/store_credit.rb +1 -1
  83. data/app/models/spree/payment_method.rb +29 -10
  84. data/app/models/spree/payment_source.rb +5 -1
  85. data/app/models/spree/permission_set.rb +11 -0
  86. data/app/models/spree/permission_sets/base.rb +45 -0
  87. data/app/models/spree/permission_sets/configuration_display.rb +53 -0
  88. data/app/models/spree/permission_sets/configuration_management.rb +52 -0
  89. data/app/models/spree/permission_sets/dashboard_display.rb +28 -0
  90. data/app/models/spree/permission_sets/default_customer.rb +83 -0
  91. data/app/models/spree/permission_sets/order_display.rb +50 -0
  92. data/app/models/spree/permission_sets/order_management.rb +50 -0
  93. data/app/models/spree/permission_sets/product_display.rb +43 -0
  94. data/app/models/spree/permission_sets/product_management.rb +47 -0
  95. data/app/models/spree/permission_sets/restricted_stock_display.rb +33 -0
  96. data/app/models/spree/permission_sets/restricted_stock_management.rb +33 -0
  97. data/app/models/spree/permission_sets/stock_display.rb +26 -0
  98. data/app/models/spree/permission_sets/stock_management.rb +26 -0
  99. data/app/models/spree/permission_sets/super_user.rb +26 -0
  100. data/app/models/spree/permission_sets/user_display.rb +27 -0
  101. data/app/models/spree/permission_sets/user_management.rb +44 -0
  102. data/app/models/spree/preference.rb +1 -1
  103. data/app/models/spree/price.rb +3 -3
  104. data/app/models/spree/product/scopes.rb +23 -10
  105. data/app/models/spree/product.rb +30 -23
  106. data/app/models/spree/product_property.rb +1 -1
  107. data/app/models/spree/property.rb +1 -1
  108. data/app/models/spree/refund.rb +13 -3
  109. data/app/models/spree/refund_reason.rb +6 -1
  110. data/app/models/spree/reimbursement.rb +6 -6
  111. data/app/models/spree/reimbursement_performer.rb +3 -3
  112. data/app/models/spree/reimbursement_tax_calculator.rb +3 -3
  113. data/app/models/spree/reimbursement_type/credit.rb +1 -1
  114. data/app/models/spree/reimbursement_type/reimbursement_helpers.rb +6 -6
  115. data/app/models/spree/reimbursement_type/store_credit.rb +1 -1
  116. data/app/models/spree/reimbursement_type.rb +6 -1
  117. data/app/models/spree/return_authorization.rb +3 -1
  118. data/app/models/spree/return_item.rb +13 -15
  119. data/app/models/spree/return_reason.rb +6 -1
  120. data/app/models/spree/role.rb +3 -1
  121. data/app/models/spree/role_permission.rb +8 -0
  122. data/app/models/spree/shipment.rb +12 -10
  123. data/app/models/spree/shipping_category.rb +2 -0
  124. data/app/models/spree/shipping_rate.rb +2 -3
  125. data/app/models/spree/shipping_rate_tax.rb +1 -1
  126. data/app/models/spree/{order_contents.rb → simple_order_contents.rb} +10 -13
  127. data/app/models/spree/state.rb +1 -1
  128. data/app/models/spree/stock/allocator/on_hand_first.rb +2 -2
  129. data/app/models/spree/stock/availability.rb +11 -3
  130. data/app/models/spree/stock/estimator.rb +1 -1
  131. data/app/models/spree/stock/inventory_unit_builder.rb +1 -1
  132. data/app/models/spree/stock/package.rb +2 -2
  133. data/app/models/spree/stock/quantifier.rb +12 -8
  134. data/app/models/spree/stock/simple_coordinator.rb +38 -28
  135. data/app/models/spree/stock/splitter/shipping_category.rb +1 -1
  136. data/app/models/spree/stock_item.rb +2 -1
  137. data/app/models/spree/stock_location.rb +7 -7
  138. data/app/models/spree/stock_movement.rb +2 -2
  139. data/app/models/spree/store.rb +3 -1
  140. data/app/models/spree/store_credit.rb +31 -16
  141. data/app/models/spree/store_credit_event.rb +4 -3
  142. data/app/models/spree/store_credit_prioritizer.rb +17 -0
  143. data/app/models/spree/store_credit_reason.rb +6 -1
  144. data/app/models/spree/store_selector/by_server_name.rb +1 -1
  145. data/app/models/spree/tax/item_tax.rb +3 -2
  146. data/app/models/spree/tax/order_tax.rb +3 -1
  147. data/app/models/spree/tax/tax_helpers.rb +14 -3
  148. data/app/models/spree/tax/tax_location.rb +4 -7
  149. data/app/models/spree/tax_calculator/default.rb +32 -1
  150. data/app/models/spree/tax_calculator/shipping_rate.rb +2 -2
  151. data/app/models/spree/tax_category.rb +3 -1
  152. data/app/models/spree/tax_rate.rb +14 -1
  153. data/app/models/spree/taxon/active_storage_attachment.rb +2 -2
  154. data/app/models/spree/taxon/paperclip_attachment.rb +4 -4
  155. data/app/models/spree/taxon.rb +25 -3
  156. data/app/models/spree/taxon_brand_selector.rb +22 -0
  157. data/app/models/spree/taxonomy.rb +4 -3
  158. data/app/models/spree/unauthorized_redirect_handler.rb +24 -0
  159. data/app/models/spree/unit_cancel.rb +1 -2
  160. data/app/models/spree/user_address.rb +9 -3
  161. data/app/models/spree/user_last_url_storer/rules/authentication_rule.rb +1 -1
  162. data/app/models/spree/variant/price_selector.rb +25 -8
  163. data/app/models/spree/variant/scopes.rb +4 -0
  164. data/app/models/spree/variant/vat_price_generator.rb +1 -1
  165. data/app/models/spree/variant.rb +64 -37
  166. data/app/models/spree/wallet/add_payment_sources_to_wallet.rb +4 -4
  167. data/app/models/spree/wallet.rb +2 -2
  168. data/app/models/spree/zone.rb +1 -1
  169. data/app/subscribers/spree/order_mailer_subscriber.rb +35 -0
  170. data/app/views/layouts/spree/base_mailer.html.erb +2 -2
  171. data/app/views/spree/order_mailer/cancel_email.html.erb +1 -1
  172. data/app/views/spree/order_mailer/cancel_email.text.erb +1 -1
  173. data/app/views/spree/order_mailer/confirm_email.html.erb +5 -5
  174. data/app/views/spree/order_mailer/confirm_email.text.erb +5 -5
  175. data/app/views/spree/order_mailer/inventory_cancellation_email.html.erb +0 -1
  176. data/config/i18n-tasks.yml +134 -0
  177. data/config/locales/en.yml +439 -338
  178. data/db/default/spree/permission_sets.rb +10 -0
  179. data/db/default/spree/return_reasons.rb +3 -1
  180. data/db/default/spree/states.rb +2 -2
  181. data/db/migrate/20160101010000_solidus_one_four.rb +0 -127
  182. data/db/migrate/20180710170104_create_spree_store_credit_reasons_table.rb +2 -2
  183. data/db/migrate/20201127212108_add_type_before_removal_to_spree_payment_methods.rb +7 -0
  184. data/db/migrate/20210312061050_change_column_null_on_prices.rb +7 -0
  185. data/db/migrate/20210815004823_add_unique_index_to_option_values_variants.rb +16 -0
  186. data/db/migrate/20220419170826_remove_archived_user_addresses.rb +12 -0
  187. data/db/migrate/20220805202442_add_level_to_spree_tax_rates.rb +5 -0
  188. data/db/migrate/20221123152807_add_shipping_category_to_spree_variants.rb +5 -0
  189. data/db/migrate/20230321161854_change_column_null_option_values_option_type_id.rb +5 -0
  190. data/db/migrate/20230425103509_remove_taxon_position.rb +5 -0
  191. data/db/migrate/20230427095534_drop_deprecated_address_id_from_shipments.rb +11 -0
  192. data/db/migrate/20240821173254_create_spree_permission_sets_in_core.rb +9 -0
  193. data/db/migrate/20240821173341_create_spree_roles_permissions_in_core.rb +9 -0
  194. data/db/migrate/20240821173641_add_description_to_spree_roles.rb +5 -0
  195. data/db/migrate/20240904152041_add_privilege_and_category_to_spree_permission_sets.rb +6 -0
  196. data/db/migrate/20250129061658_add_metadata_to_spree_resources.rb +28 -0
  197. data/db/migrate/20250201172950_add_gtin_and_condition_to_spree_variant.rb +6 -0
  198. data/db/migrate/20250207104016_add_primary_taxon_to_products.rb +7 -0
  199. data/db/migrate/20250221152004_add_metadata_to_users.rb +13 -0
  200. data/db/seeds.rb +5 -1
  201. data/lib/generators/solidus/install/app_templates/authentication/custom.rb +16 -0
  202. data/lib/generators/solidus/install/app_templates/authentication/devise.rb +16 -0
  203. data/lib/generators/solidus/install/app_templates/authentication/existing.rb +10 -0
  204. data/lib/generators/solidus/install/app_templates/authentication/none.rb +1 -0
  205. data/lib/generators/solidus/install/app_templates/frontend/none.rb +1 -0
  206. data/lib/generators/solidus/install/app_templates/frontend/starter.rb +1 -0
  207. data/lib/generators/solidus/install/app_templates/payment_method/braintree.rb +5 -0
  208. data/lib/generators/solidus/install/app_templates/payment_method/none.rb +1 -0
  209. data/lib/generators/solidus/install/app_templates/payment_method/paypal.rb +5 -0
  210. data/lib/generators/solidus/install/app_templates/payment_method/stripe.rb +5 -0
  211. data/lib/generators/solidus/install/install_generator.rb +210 -156
  212. data/lib/generators/solidus/install/templates/config/initializers/spree.rb.tt +27 -33
  213. data/lib/generators/solidus/install/templates/vendor/assets/javascripts/spree/backend/all.js +2 -2
  214. data/lib/generators/solidus/update/templates/config/initializers/new_solidus_defaults.rb.tt +30 -0
  215. data/lib/generators/solidus/update/update_generator.rb +124 -0
  216. data/lib/generators/spree/custom_user/custom_user_generator.rb +6 -4
  217. data/lib/generators/spree/custom_user/templates/authentication_helpers.rb.tt +2 -6
  218. data/lib/generators/spree/custom_user/templates/migration.rb.tt +7 -3
  219. data/lib/generators/spree/dummy/dummy_generator.rb +12 -9
  220. data/lib/generators/spree/dummy/templates/rails/application.rb.tt +1 -2
  221. data/lib/generators/spree/dummy/templates/rails/database.yml +48 -63
  222. data/lib/generators/spree/dummy/templates/rails/manifest.js +3 -0
  223. data/lib/generators/spree/dummy/templates/rails/test.rb +7 -2
  224. data/lib/spree/app_configuration.rb +220 -71
  225. data/lib/spree/bus.rb +11 -0
  226. data/lib/spree/core/class_constantizer.rb +2 -2
  227. data/lib/spree/core/controller_helpers/auth.rb +5 -69
  228. data/lib/spree/core/controller_helpers/common.rb +5 -80
  229. data/lib/spree/core/controller_helpers/order.rb +5 -86
  230. data/lib/spree/core/controller_helpers/payment_parameters.rb +5 -165
  231. data/lib/spree/core/controller_helpers/pricing.rb +5 -17
  232. data/lib/spree/core/controller_helpers/search.rb +5 -14
  233. data/lib/spree/core/controller_helpers/store.rb +5 -17
  234. data/lib/spree/core/controller_helpers/strong_parameters.rb +5 -71
  235. data/lib/spree/core/engine.rb +49 -16
  236. data/lib/spree/core/environment/calculators.rb +35 -3
  237. data/lib/spree/core/environment/promotions.rb +25 -4
  238. data/lib/spree/core/environment_extension.rb +16 -2
  239. data/lib/spree/core/importer/order.rb +6 -6
  240. data/lib/spree/core/importer/product.rb +3 -3
  241. data/lib/spree/core/nested_class_set.rb +28 -0
  242. data/lib/spree/core/null_promotion_configuration.rb +84 -0
  243. data/lib/spree/core/product_duplicator.rb +1 -1
  244. data/lib/spree/core/product_filters.rb +2 -2
  245. data/lib/spree/core/search/base.rb +18 -9
  246. data/lib/spree/core/search/variant.rb +2 -2
  247. data/lib/spree/core/state_machines/inventory_unit.rb +5 -40
  248. data/lib/spree/core/state_machines/order.rb +5 -247
  249. data/lib/spree/core/state_machines/payment.rb +5 -59
  250. data/lib/spree/core/state_machines/reimbursement.rb +5 -31
  251. data/lib/spree/core/state_machines/return_authorization.rb +5 -30
  252. data/lib/spree/core/state_machines/return_item/acceptance_status.rb +5 -49
  253. data/lib/spree/core/state_machines/return_item/reception_status.rb +5 -40
  254. data/lib/spree/core/state_machines/shipment.rb +5 -56
  255. data/lib/spree/core/state_machines.rb +48 -81
  256. data/lib/spree/core/stock_configuration.rb +18 -0
  257. data/lib/spree/core/validators/email.rb +2 -4
  258. data/lib/spree/core/version.rb +5 -1
  259. data/lib/spree/core/versioned_value.rb +75 -0
  260. data/lib/spree/core.rb +40 -16
  261. data/lib/spree/deprecated_instance_variable_proxy.rb +57 -0
  262. data/lib/spree/deprecation.rb +3 -51
  263. data/lib/spree/deprecator.rb +9 -0
  264. data/lib/spree/i18n.rb +1 -1
  265. data/lib/spree/mailer_previews/carton_preview.rb +1 -1
  266. data/lib/spree/migration_helpers.rb +3 -3
  267. data/lib/spree/migrations.rb +13 -11
  268. data/lib/spree/money.rb +5 -118
  269. data/lib/spree/permission_sets/base.rb +5 -30
  270. data/lib/spree/permission_sets/configuration_display.rb +5 -23
  271. data/lib/spree/permission_sets/configuration_management.rb +5 -23
  272. data/lib/spree/permission_sets/dashboard_display.rb +5 -9
  273. data/lib/spree/permission_sets/default_customer.rb +5 -35
  274. data/lib/spree/permission_sets/order_display.rb +5 -19
  275. data/lib/spree/permission_sets/order_management.rb +5 -20
  276. data/lib/spree/permission_sets/product_display.rb +5 -17
  277. data/lib/spree/permission_sets/product_management.rb +5 -19
  278. data/lib/spree/permission_sets/restricted_stock_display.rb +5 -16
  279. data/lib/spree/permission_sets/restricted_stock_management.rb +5 -16
  280. data/lib/spree/permission_sets/stock_display.rb +5 -10
  281. data/lib/spree/permission_sets/stock_management.rb +5 -10
  282. data/lib/spree/permission_sets/super_user.rb +5 -9
  283. data/lib/spree/permission_sets/user_display.rb +5 -11
  284. data/lib/spree/permission_sets/user_management.rb +5 -23
  285. data/lib/spree/permission_sets.rb +5 -18
  286. data/lib/spree/permitted_attributes.rb +35 -14
  287. data/lib/spree/preferences/configuration.rb +88 -0
  288. data/lib/spree/preferences/persistable.rb +7 -1
  289. data/lib/spree/preferences/preferable.rb +13 -0
  290. data/lib/spree/preferences/preferable_class_methods.rb +12 -4
  291. data/lib/spree/preferences/preference_differentiator.rb +29 -0
  292. data/lib/spree/preferences/static_model_preferences.rb +25 -10
  293. data/lib/spree/preferences/store.rb +2 -2
  294. data/lib/spree/testing_support/blacklist_urls.rb +1 -1
  295. data/lib/spree/testing_support/bus_helpers.rb +101 -0
  296. data/lib/spree/testing_support/capybara_ext.rb +11 -1
  297. data/lib/spree/testing_support/common_rake.rb +76 -23
  298. data/lib/spree/testing_support/dummy_ability.rb +7 -0
  299. data/lib/spree/testing_support/dummy_app/assets/javascripts/spree/backend/all.js +1 -1
  300. data/lib/spree/testing_support/dummy_app/assets/stylesheets/solidus_admin/tailwind.css +1 -0
  301. data/lib/spree/testing_support/dummy_app/database.yml +39 -28
  302. data/lib/spree/testing_support/dummy_app/migrations.rb +8 -15
  303. data/lib/spree/testing_support/dummy_app/rake_tasks.rb +3 -10
  304. data/lib/spree/testing_support/dummy_app.rb +71 -42
  305. data/lib/spree/testing_support/extension_rake.rb +2 -2
  306. data/lib/spree/testing_support/factories/address_factory.rb +9 -13
  307. data/lib/spree/testing_support/factories/adjustment_factory.rb +1 -13
  308. data/lib/spree/testing_support/factories/adjustment_reason_factory.rb +0 -5
  309. data/lib/spree/testing_support/factories/calculator_factory.rb +4 -10
  310. data/lib/spree/testing_support/factories/carton_factory.rb +2 -10
  311. data/lib/spree/testing_support/factories/country_factory.rb +1 -7
  312. data/lib/spree/testing_support/factories/credit_card_factory.rb +0 -5
  313. data/lib/spree/testing_support/factories/customer_return_factory.rb +2 -11
  314. data/lib/spree/testing_support/factories/image_factory.rb +0 -5
  315. data/lib/spree/testing_support/factories/inventory_unit_factory.rb +4 -14
  316. data/lib/spree/testing_support/factories/line_item_factory.rb +0 -8
  317. data/lib/spree/testing_support/factories/option_type_factory.rb +0 -8
  318. data/lib/spree/testing_support/factories/option_value_factory.rb +0 -5
  319. data/lib/spree/testing_support/factories/order_factory.rb +19 -38
  320. data/lib/spree/testing_support/factories/payment_factory.rb +0 -10
  321. data/lib/spree/testing_support/factories/payment_method_factory.rb +0 -5
  322. data/lib/spree/testing_support/factories/price_factory.rb +0 -7
  323. data/lib/spree/testing_support/factories/product_factory.rb +5 -13
  324. data/lib/spree/testing_support/factories/product_option_type_factory.rb +0 -8
  325. data/lib/spree/testing_support/factories/product_property_factory.rb +0 -8
  326. data/lib/spree/testing_support/factories/property_factory.rb +0 -5
  327. data/lib/spree/testing_support/factories/refund_factory.rb +0 -8
  328. data/lib/spree/testing_support/factories/refund_reason_factory.rb +0 -5
  329. data/lib/spree/testing_support/factories/reimbursement_factory.rb +0 -7
  330. data/lib/spree/testing_support/factories/reimbursement_type_factory.rb +0 -5
  331. data/lib/spree/testing_support/factories/return_authorization_factory.rb +0 -9
  332. data/lib/spree/testing_support/factories/return_item_factory.rb +0 -9
  333. data/lib/spree/testing_support/factories/return_reason_factory.rb +0 -5
  334. data/lib/spree/testing_support/factories/role_factory.rb +0 -5
  335. data/lib/spree/testing_support/factories/shipment_factory.rb +1 -11
  336. data/lib/spree/testing_support/factories/shipping_category_factory.rb +0 -5
  337. data/lib/spree/testing_support/factories/shipping_method_factory.rb +0 -9
  338. data/lib/spree/testing_support/factories/shipping_rate_factory.rb +0 -8
  339. data/lib/spree/testing_support/factories/state_factory.rb +8 -10
  340. data/lib/spree/testing_support/factories/stock_item_factory.rb +5 -9
  341. data/lib/spree/testing_support/factories/stock_location_factory.rb +0 -9
  342. data/lib/spree/testing_support/factories/stock_movement_factory.rb +0 -7
  343. data/lib/spree/testing_support/factories/stock_package_factory.rb +1 -9
  344. data/lib/spree/testing_support/factories/store_credit_category_factory.rb +0 -5
  345. data/lib/spree/testing_support/factories/store_credit_event_factory.rb +0 -8
  346. data/lib/spree/testing_support/factories/store_credit_factory.rb +4 -13
  347. data/lib/spree/testing_support/factories/store_credit_reason_factory.rb +0 -5
  348. data/lib/spree/testing_support/factories/store_credit_type_factory.rb +0 -5
  349. data/lib/spree/testing_support/factories/store_factory.rb +0 -5
  350. data/lib/spree/testing_support/factories/tax_category_factory.rb +0 -8
  351. data/lib/spree/testing_support/factories/tax_rate_factory.rb +0 -9
  352. data/lib/spree/testing_support/factories/taxon_factory.rb +5 -10
  353. data/lib/spree/testing_support/factories/taxonomy_factory.rb +3 -6
  354. data/lib/spree/testing_support/factories/user_factory.rb +6 -9
  355. data/lib/spree/testing_support/factories/variant_factory.rb +0 -10
  356. data/lib/spree/testing_support/factories/variant_property_rule_condition_factory.rb +0 -8
  357. data/lib/spree/testing_support/factories/variant_property_rule_factory.rb +0 -9
  358. data/lib/spree/testing_support/factories/variant_property_rule_value_factory.rb +0 -8
  359. data/lib/spree/testing_support/factories/zone_factory.rb +1 -9
  360. data/lib/spree/testing_support/factory_bot.rb +6 -29
  361. data/lib/spree/testing_support/flaky.rb +22 -0
  362. data/lib/spree/testing_support/order_walkthrough.rb +7 -6
  363. data/lib/spree/testing_support/sequences.rb +0 -5
  364. data/lib/spree/testing_support/shared_examples/calculator.rb +10 -0
  365. data/lib/spree/testing_support/shared_examples/order_factory.rb +141 -0
  366. data/lib/spree/testing_support/shared_examples/working_factory.rb +15 -0
  367. data/lib/spree/testing_support/silence_deprecations.rb +9 -0
  368. data/lib/spree/user_class_handle.rb +2 -2
  369. data/lib/tasks/colorado_delivery_fee.rake +28 -0
  370. data/lib/tasks/payment_method.rake +29 -0
  371. data/lib/tasks/solidus/delete_prices_with_nil_amount.rake +8 -0
  372. data/solidus_core.gemspec +18 -8
  373. metadata +233 -117
  374. data/app/jobs/spree/promotion_code_batch_job.rb +0 -26
  375. data/app/mailers/spree/promotion_code_batch_mailer.rb +0 -15
  376. data/app/models/spree/calculator/distributed_amount.rb +0 -33
  377. data/app/models/spree/calculator/flat_percent_item_total.rb +0 -23
  378. data/app/models/spree/calculator/flexi_rate.rb +0 -22
  379. data/app/models/spree/calculator/percent_on_line_item.rb +0 -13
  380. data/app/models/spree/calculator/tiered_flat_rate.rb +0 -52
  381. data/app/models/spree/calculator/tiered_percent.rb +0 -62
  382. data/app/models/spree/line_item_action.rb +0 -8
  383. data/app/models/spree/order_promotion.rb +0 -27
  384. data/app/models/spree/promotion/actions/create_adjustment.rb +0 -77
  385. data/app/models/spree/promotion/actions/create_item_adjustments.rb +0 -99
  386. data/app/models/spree/promotion/actions/create_quantity_adjustments.rb +0 -139
  387. data/app/models/spree/promotion/actions/free_shipping.rb +0 -58
  388. data/app/models/spree/promotion/rules/first_order.rb +0 -38
  389. data/app/models/spree/promotion/rules/first_repeat_purchase_since.rb +0 -36
  390. data/app/models/spree/promotion/rules/item_total.rb +0 -53
  391. data/app/models/spree/promotion/rules/nth_order.rb +0 -45
  392. data/app/models/spree/promotion/rules/one_use_per_user.rb +0 -25
  393. data/app/models/spree/promotion/rules/option_value.rb +0 -50
  394. data/app/models/spree/promotion/rules/product.rb +0 -74
  395. data/app/models/spree/promotion/rules/store.rb +0 -22
  396. data/app/models/spree/promotion/rules/taxon.rb +0 -87
  397. data/app/models/spree/promotion/rules/user.rb +0 -30
  398. data/app/models/spree/promotion/rules/user_logged_in.rb +0 -20
  399. data/app/models/spree/promotion/rules/user_role.rb +0 -45
  400. data/app/models/spree/promotion.rb +0 -284
  401. data/app/models/spree/promotion_action.rb +0 -43
  402. data/app/models/spree/promotion_category.rb +0 -8
  403. data/app/models/spree/promotion_chooser.rb +0 -34
  404. data/app/models/spree/promotion_code/batch_builder.rb +0 -64
  405. data/app/models/spree/promotion_code.rb +0 -50
  406. data/app/models/spree/promotion_code_batch.rb +0 -27
  407. data/app/models/spree/promotion_handler/cart.rb +0 -55
  408. data/app/models/spree/promotion_handler/coupon.rb +0 -123
  409. data/app/models/spree/promotion_handler/page.rb +0 -26
  410. data/app/models/spree/promotion_handler/shipping.rb +0 -61
  411. data/app/models/spree/promotion_rule.rb +0 -55
  412. data/app/models/spree/promotion_rule_role.rb +0 -8
  413. data/app/models/spree/promotion_rule_store.rb +0 -10
  414. data/app/models/spree/promotion_rule_taxon.rb +0 -8
  415. data/app/models/spree/promotion_rule_user.rb +0 -10
  416. data/app/models/spree/tax/shipping_rate_taxer.rb +0 -24
  417. data/app/subscribers/spree/mailer_subscriber.rb +0 -25
  418. data/app/views/spree/promotion_code_batch_mailer/promotion_code_batch_errored.text.erb +0 -2
  419. data/app/views/spree/promotion_code_batch_mailer/promotion_code_batch_finished.text.erb +0 -2
  420. data/db/migrate/20161017102621_create_spree_promotion_code_batch.rb +0 -38
  421. data/db/migrate/20180202190713_create_promotion_rule_stores.rb +0 -12
  422. data/db/migrate/20180328172631_add_join_characters_to_promotion_code_batch.rb +0 -11
  423. data/db/migrate/20190106184413_remove_code_from_spree_promotions.rb +0 -42
  424. data/lib/generators/solidus/install/templates/vendor/assets/javascripts/spree/frontend/all.js +0 -10
  425. data/lib/generators/solidus/install/templates/vendor/assets/stylesheets/spree/frontend/all.css +0 -9
  426. data/lib/generators/spree/dummy/templates/rails/script/rails +0 -6
  427. data/lib/solidus/migrations/promotions_with_code_handlers.rb +0 -66
  428. data/lib/spree/event/adapters/active_support_notifications.rb +0 -67
  429. data/lib/spree/event/configuration.rb +0 -25
  430. data/lib/spree/event/subscriber.rb +0 -86
  431. data/lib/spree/event/subscriber_registry.rb +0 -94
  432. data/lib/spree/event.rb +0 -119
  433. data/lib/spree/permission_sets/promotion_display.rb +0 -15
  434. data/lib/spree/permission_sets/promotion_management.rb +0 -15
  435. data/lib/spree/testing_support/dummy_app/assets/javascripts/spree/frontend/all.js +0 -10
  436. data/lib/spree/testing_support/dummy_app/assets/stylesheets/spree/frontend/all.css +0 -9
  437. data/lib/spree/testing_support/dummy_app/views/layouts/application.html.erb +0 -1
  438. data/lib/spree/testing_support/factories/order_promotion_factory.rb +0 -16
  439. data/lib/spree/testing_support/factories/promotion_category_factory.rb +0 -12
  440. data/lib/spree/testing_support/factories/promotion_code_factory.rb +0 -16
  441. data/lib/spree/testing_support/factories/promotion_factory.rb +0 -92
  442. data/lib/spree/testing_support/factories.rb +0 -11
  443. data/lib/spree/testing_support.rb +0 -31
  444. data/lib/tasks/upgrade.rake +0 -15
@@ -26,6 +26,7 @@ module Spree
26
26
  include ::Spree::Config.state_machines.order
27
27
 
28
28
  include Spree::Order::Payments
29
+ include Metadata
29
30
 
30
31
  class InsufficientStock < StandardError
31
32
  attr_reader :items
@@ -38,9 +39,21 @@ module Spree
38
39
  class CannotRebuildShipments < StandardError; end
39
40
 
40
41
  extend Spree::DisplayMoney
41
- money_methods :outstanding_balance, :item_total, :adjustment_total,
42
- :included_tax_total, :additional_tax_total, :tax_total,
43
- :shipment_total, :total, :order_total_after_store_credit, :total_available_store_credit
42
+ money_methods(
43
+ :outstanding_balance,
44
+ :item_total,
45
+ :adjustment_total,
46
+ :included_tax_total,
47
+ :additional_tax_total,
48
+ :tax_total,
49
+ :shipment_total,
50
+ :total,
51
+ :order_total_after_store_credit,
52
+ :total_available_store_credit,
53
+ :item_total_before_tax,
54
+ :shipment_total_before_tax,
55
+ :item_total_excluding_vat
56
+ )
44
57
  alias :display_ship_total :display_shipment_total
45
58
 
46
59
  checkout_flow do
@@ -50,8 +63,8 @@ module Spree
50
63
  go_to_state :confirm
51
64
  end
52
65
 
53
- self.whitelisted_ransackable_associations = %w[shipments user order_promotions promotions bill_address ship_address line_items]
54
- self.whitelisted_ransackable_attributes = %w[bill_address_name completed_at created_at email number state payment_state shipment_state total store_id]
66
+ self.allowed_ransackable_associations = %w[shipments user bill_address ship_address line_items]
67
+ self.allowed_ransackable_attributes = %w[completed_at created_at email number state payment_state shipment_state total store_id]
55
68
 
56
69
  attr_reader :coupon_code
57
70
  attr_accessor :temporary_address
@@ -60,11 +73,15 @@ module Spree
60
73
 
61
74
  # Customer info
62
75
  belongs_to :user, class_name: Spree::UserClassHandle.new, optional: true
76
+
63
77
  belongs_to :bill_address, foreign_key: :bill_address_id, class_name: 'Spree::Address', optional: true
64
- alias_attribute :billing_address, :bill_address
78
+ alias_method :billing_address, :bill_address
79
+ alias_method :billing_address=, :bill_address=
65
80
 
66
81
  belongs_to :ship_address, foreign_key: :ship_address_id, class_name: 'Spree::Address', optional: true
67
- alias_attribute :shipping_address, :ship_address
82
+ alias_method :shipping_address, :ship_address
83
+ alias_method :shipping_address=, :ship_address=
84
+
68
85
  alias_attribute :ship_total, :shipment_total
69
86
 
70
87
  belongs_to :store, class_name: 'Spree::Store', optional: true
@@ -92,8 +109,6 @@ module Spree
92
109
  foreign_key: :order_id,
93
110
  dependent: :destroy,
94
111
  inverse_of: :order
95
- has_many :order_promotions, class_name: 'Spree::OrderPromotion'
96
- has_many :promotions, through: :order_promotions
97
112
 
98
113
  # Payments
99
114
  has_many :payments, dependent: :destroy, inverse_of: :order
@@ -102,7 +117,7 @@ module Spree
102
117
  # Returns
103
118
  has_many :return_authorizations, dependent: :destroy, inverse_of: :order
104
119
  has_many :return_items, through: :inventory_units
105
- has_many :customer_returns, through: :return_items
120
+ has_many :customer_returns, -> { distinct }, through: :return_items
106
121
  has_many :reimbursements, inverse_of: :order
107
122
  has_many :refunds, through: :payments
108
123
 
@@ -123,12 +138,14 @@ module Spree
123
138
  before_validation :set_currency
124
139
  before_validation :generate_order_number, on: :create
125
140
  before_validation :assign_billing_to_shipping_address, if: :use_billing?
141
+ before_validation :assign_shipping_to_billing_address, if: :use_shipping?
126
142
  attr_accessor :use_billing
143
+ attr_accessor :use_shipping
127
144
 
128
145
  before_create :create_token
129
146
  before_create :link_by_email
130
147
 
131
- validates :email, presence: true, if: :require_email
148
+ validates :email, presence: true, if: :email_required?
132
149
  validates :email, 'spree/email' => true, allow_blank: true
133
150
  validates :guest_token, presence: { allow_nil: true }
134
151
  validates :number, presence: true, uniqueness: { allow_blank: true, case_sensitive: true }
@@ -142,11 +159,29 @@ module Spree
142
159
  find_by! number: value
143
160
  end
144
161
 
162
+ delegate :recalculate, to: :recalculator
163
+
145
164
  delegate :name, to: :bill_address, prefix: true, allow_nil: true
146
165
  alias_method :billing_name, :bill_address_name
147
166
 
148
- class_attribute :line_item_comparison_hooks
149
- self.line_item_comparison_hooks = Set.new
167
+ delegate :line_item_comparison_hooks, to: :class
168
+ class << self
169
+ def line_item_comparison_hooks=(value)
170
+ Spree::Config.line_item_comparison_hooks = value.to_a
171
+ end
172
+ line_item_hooks_deprecation_msg = "Use Spree::Config.line_item_comparison_hooks instead."
173
+ deprecate :line_item_comparison_hooks= => line_item_hooks_deprecation_msg, :deprecator => Spree.deprecator
174
+
175
+ def line_item_comparison_hooks
176
+ Spree::Config.line_item_comparison_hooks
177
+ end
178
+ deprecate line_item_comparison_hooks: line_item_hooks_deprecation_msg, deprecator: Spree.deprecator
179
+
180
+ def register_line_item_comparison_hook(hook)
181
+ Spree::Config.line_item_comparison_hooks << hook
182
+ end
183
+ deprecate register_line_item_comparison_hook: line_item_hooks_deprecation_msg, deprecator: Spree.deprecator
184
+ end
150
185
 
151
186
  scope :created_between, ->(start_date, end_date) { where(created_at: start_date..end_date) }
152
187
  scope :completed_between, ->(start_date, end_date) { where(completed_at: start_date..end_date) }
@@ -161,7 +196,7 @@ module Spree
161
196
  end
162
197
 
163
198
  def self.by_state(state)
164
- where(state: state)
199
+ where(state:)
165
200
  end
166
201
 
167
202
  def self.complete
@@ -180,12 +215,6 @@ module Spree
180
215
  where.not(state: 'canceled')
181
216
  end
182
217
 
183
- # Use this method in other gems that wish to register their own custom logic
184
- # that should be called when determining if two line items are equal.
185
- def self.register_line_item_comparison_hook(hook)
186
- line_item_comparison_hooks.add(hook)
187
- end
188
-
189
218
  # For compatiblity with Calculator::PriceSack
190
219
  def amount
191
220
  line_items.sum(&:amount)
@@ -195,6 +224,10 @@ module Spree
195
224
  line_items.to_a.sum(&:total_before_tax)
196
225
  end
197
226
 
227
+ def shipment_total_before_tax
228
+ shipments.to_a.sum(&:total_before_tax)
229
+ end
230
+
198
231
  # Sum of all line item amounts pre-tax
199
232
  def item_total_excluding_vat
200
233
  line_items.to_a.sum(&:total_excluding_vat)
@@ -205,7 +238,7 @@ module Spree
205
238
  end
206
239
 
207
240
  def shipping_discount
208
- shipment_adjustments.credit.eligible.sum(:amount) * - 1
241
+ shipment_adjustments.credit.sum(:amount) * - 1
209
242
  end
210
243
 
211
244
  def to_param
@@ -239,22 +272,25 @@ module Spree
239
272
  ship_address
240
273
  else
241
274
  bill_address
242
- end || store.default_cart_tax_location
275
+ end || store&.default_cart_tax_location
243
276
  end
244
277
 
245
- def updater
246
- @updater ||= Spree::OrderUpdater.new(self)
247
- end
248
-
249
- def recalculate
250
- updater.update
278
+ def recalculator
279
+ @recalculator ||= Spree::Config.order_recalculator_class.new(self)
251
280
  end
281
+ alias_method :updater, :recalculator
282
+ deprecate updater: :recalculator, deprecator: Spree.deprecator
252
283
 
253
284
  def assign_billing_to_shipping_address
254
285
  self.ship_address = bill_address if bill_address
255
286
  true
256
287
  end
257
288
 
289
+ def assign_shipping_to_billing_address
290
+ self.bill_address = ship_address if ship_address
291
+ true
292
+ end
293
+
258
294
  def allow_cancel?
259
295
  return false unless completed? && state != 'canceled'
260
296
  shipment_state.nil? || %w{ready backorder pending}.include?(shipment_state)
@@ -269,15 +305,15 @@ module Spree
269
305
  end
270
306
 
271
307
  def contents
272
- @contents ||= Spree::OrderContents.new(self)
308
+ @contents ||= Spree::Config.order_contents_class.new(self)
273
309
  end
274
310
 
275
311
  def shipping
276
- @shipping ||= Spree::OrderShipping.new(self)
312
+ @shipping ||= Spree::Config.order_shipping_class.new(self)
277
313
  end
278
314
 
279
315
  def cancellations
280
- @cancellations ||= Spree::OrderCancellations.new(self)
316
+ @cancellations ||= Spree::Config.order_cancellations_class.new(self)
281
317
  end
282
318
 
283
319
  # Associates the specified user with the order.
@@ -289,7 +325,7 @@ module Spree
289
325
 
290
326
  if persisted?
291
327
  # immediately persist the changes we just made, but don't use save since we might have an invalid address associated
292
- self.class.unscoped.where(id: id).update_all(attrs_to_set)
328
+ self.class.unscoped.where(id:).update_all(attrs_to_set)
293
329
  end
294
330
 
295
331
  assign_attributes(attrs_to_set)
@@ -331,7 +367,7 @@ module Spree
331
367
  def line_item_options_match(line_item, options)
332
368
  return true unless options
333
369
 
334
- line_item_comparison_hooks.all? { |hook|
370
+ Spree::Config.line_item_comparison_hooks.all? { |hook|
335
371
  send(hook, line_item, options)
336
372
  }
337
373
  end
@@ -379,30 +415,9 @@ module Spree
379
415
  Spree::CreditCard.where(id: credit_card_ids)
380
416
  end
381
417
 
382
- # Finalizes an in progress order after checkout is complete.
383
- # Called after transition to complete state when payments will have been processed
384
- def finalize!
385
- # lock all adjustments (coupon promotions, etc.)
386
- all_adjustments.each(&:finalize!)
387
-
388
- # update payment and shipment(s) states, and save
389
- updater.update_payment_state
390
- shipments.each do |shipment|
391
- shipment.update_state
392
- shipment.finalize!
393
- end
394
-
395
- updater.update_shipment_state
396
- save!
397
-
398
- touch :completed_at
399
-
400
- Spree::Event.fire 'order_finalized', order: self
401
- end
402
-
403
418
  def fulfill!
404
419
  shipments.each { |shipment| shipment.update_state if shipment.persisted? }
405
- updater.update_shipment_state
420
+ recalculator.update_shipment_state
406
421
  save!
407
422
  end
408
423
 
@@ -444,7 +459,7 @@ module Spree
444
459
  line_items.destroy_all
445
460
  adjustments.destroy_all
446
461
  shipments.destroy_all
447
- order_promotions.destroy_all
462
+ Spree::Bus.publish :order_emptied, order: self
448
463
 
449
464
  recalculate
450
465
  end
@@ -458,7 +473,7 @@ module Spree
458
473
  end
459
474
 
460
475
  def can_add_coupon?
461
- Spree::Promotion.order_activatable?(self)
476
+ Spree::Config.promotions.coupon_code_handler_class.new(self).can_apply?
462
477
  end
463
478
 
464
479
  def shipped?
@@ -490,28 +505,21 @@ module Spree
490
505
  raise CannotRebuildShipments.new(I18n.t('spree.cannot_rebuild_shipments_shipments_not_pending'))
491
506
  else
492
507
  shipments.destroy_all
493
- self.shipments = Spree::Config.stock.coordinator_class.new(self).shipments
508
+ shipments.push(*Spree::Config.stock.coordinator_class.new(self).shipments)
494
509
  end
495
510
  end
496
511
 
497
512
  def create_shipments_for_line_item(line_item)
498
- units = Spree::Stock::InventoryUnitBuilder.new(self).missing_units_for_line_item(line_item)
513
+ units = Spree::Config.stock.inventory_unit_builder_class.new(self).missing_units_for_line_item(line_item)
514
+
499
515
  Spree::Config.stock.coordinator_class.new(self, units).shipments.each do |shipment|
500
516
  shipments << shipment
501
517
  end
502
518
  end
503
519
 
504
- def apply_shipping_promotions
505
- Spree::PromotionHandler::Shipping.new(self).activate
506
- recalculate
507
- end
508
-
509
- # Clean shipments and make order back to address state
510
- #
511
- # At some point the might need to force the order to transition from address
512
- # to delivery again so that proper updated shipments are created.
513
- # e.g. customer goes back from payment step and changes order items
514
- def ensure_updated_shipments
520
+ # Clean shipments and make order back to address state (or to whatever state
521
+ # is set by restart_checkout_flow in case of state machine modifications)
522
+ def check_shipments_and_restart_checkout
515
523
  if !completed? && shipments.all?(&:pending?)
516
524
  shipments.destroy_all
517
525
  update_column(:shipment_total, 0)
@@ -519,6 +527,9 @@ module Spree
519
527
  end
520
528
  end
521
529
 
530
+ alias_method :ensure_updated_shipments, :check_shipments_and_restart_checkout
531
+ deprecate ensure_updated_shipments: :check_shipments_and_restart_checkout, deprecator: Spree.deprecator
532
+
522
533
  def restart_checkout_flow
523
534
  return if state == 'cart'
524
535
 
@@ -526,7 +537,7 @@ module Spree
526
537
  state: 'cart',
527
538
  updated_at: Time.current
528
539
  )
529
- next! if !line_items.empty?
540
+ self.next if line_items.any?
530
541
  end
531
542
 
532
543
  def refresh_shipment_rates
@@ -544,9 +555,7 @@ module Spree
544
555
  def canceled_by(user)
545
556
  transaction do
546
557
  cancel!
547
- # rubocop:disable Rails/SkipsModelValidations
548
558
  update_column(:canceler_id, user.id)
549
- # rubocop:enable Rails/SkipsModelValidations
550
559
  end
551
560
  end
552
561
 
@@ -563,8 +572,7 @@ module Spree
563
572
  end
564
573
 
565
574
  def has_non_reimbursement_related_refunds?
566
- refunds.non_reimbursement.exists? ||
567
- payments.offset_payment.exists? # how old versions of spree stored refunds
575
+ refunds.non_reimbursement.exists?
568
576
  end
569
577
 
570
578
  def tax_total
@@ -573,7 +581,7 @@ module Spree
573
581
 
574
582
  def add_store_credit_payments
575
583
  return if user.nil?
576
- return if payments.store_credits.checkout.empty? && user.available_store_credit_total(currency: currency).zero?
584
+ return if payments.store_credits.checkout.empty? && user.available_store_credit_total(currency:).zero?
577
585
 
578
586
  payments.store_credits.checkout.each(&:invalidate!)
579
587
 
@@ -584,18 +592,19 @@ module Spree
584
592
 
585
593
  remaining_total = outstanding_balance - authorized_total
586
594
 
587
- matching_store_credits = user.store_credits.where(currency: currency)
595
+ matching_store_credits = user.store_credits.where(currency:)
588
596
 
589
597
  if matching_store_credits.any?
590
598
  payment_method = Spree::PaymentMethod::StoreCredit.first
599
+ sorter = Spree::Config.store_credit_prioritizer_class.new(matching_store_credits, self)
591
600
 
592
- matching_store_credits.order_by_priority.each do |credit|
601
+ sorter.call.each do |credit|
593
602
  break if remaining_total.zero?
594
603
  next if credit.amount_remaining.zero?
595
604
 
596
605
  amount_to_take = [credit.amount_remaining, remaining_total].min
597
606
  payments.create!(source: credit,
598
- payment_method: payment_method,
607
+ payment_method:,
599
608
  amount: amount_to_take,
600
609
  state: 'checkout',
601
610
  response_code: credit.generate_authorization_code)
@@ -619,13 +628,13 @@ module Spree
619
628
 
620
629
  def covered_by_store_credit?
621
630
  return false unless user
622
- user.available_store_credit_total(currency: currency) >= total
631
+ user.available_store_credit_total(currency:) >= total
623
632
  end
624
633
  alias_method :covered_by_store_credit, :covered_by_store_credit?
625
634
 
626
635
  def total_available_store_credit
627
636
  return 0.0 unless user
628
- user.available_store_credit_total(currency: currency)
637
+ user.available_store_credit_total(currency:)
629
638
  end
630
639
 
631
640
  def order_total_after_store_credit
@@ -636,16 +645,16 @@ module Spree
636
645
  if can_complete? || complete?
637
646
  valid_store_credit_payments.to_a.sum(&:amount)
638
647
  else
639
- [total, (user.try(:available_store_credit_total, currency: currency) || 0.0)].min
648
+ [total, user.try(:available_store_credit_total, currency:) || 0.0].min
640
649
  end
641
650
  end
642
651
 
643
652
  def display_total_applicable_store_credit
644
- Spree::Money.new(-total_applicable_store_credit, { currency: currency })
653
+ Spree::Money.new(-total_applicable_store_credit, { currency: })
645
654
  end
646
655
 
647
656
  def display_store_credit_remaining_after_capture
648
- Spree::Money.new(total_available_store_credit - total_applicable_store_credit, { currency: currency })
657
+ Spree::Money.new(total_available_store_credit - total_applicable_store_credit, { currency: })
649
658
  end
650
659
 
651
660
  def bill_address_attributes=(attributes)
@@ -741,6 +750,27 @@ module Spree
741
750
  end
742
751
  end
743
752
 
753
+ # Finalizes an in progress order after checkout is complete.
754
+ # Called after transition to complete state when payments will have been processed
755
+ def finalize
756
+ # lock all adjustments (coupon promotions, etc.)
757
+ all_adjustments.each(&:finalize!)
758
+
759
+ # update payment and shipment(s) states, and save
760
+ recalculator.update_payment_state
761
+ shipments.each do |shipment|
762
+ shipment.update_state
763
+ shipment.finalize!
764
+ end
765
+
766
+ recalculator.update_shipment_state
767
+ save!
768
+
769
+ touch :completed_at
770
+
771
+ Spree::Bus.publish :order_finalized, order: self
772
+ end
773
+
744
774
  def associate_store
745
775
  self.store ||= Spree::Store.default
746
776
  end
@@ -749,25 +779,33 @@ module Spree
749
779
  self.email = user.email if user
750
780
  end
751
781
 
752
- # Determine if email is required (we don't want validation errors before we hit the checkout)
753
- def require_email
782
+ # Determine if the email is required for this order
783
+ #
784
+ # We don't require email for orders in the cart state or address state because those states
785
+ # precede the entry of an email address.
786
+ #
787
+ # @return [Boolean] true if the email is required
788
+ # @note This method was called require_email before.
789
+ def email_required?
754
790
  true unless new_record? || ['cart', 'address'].include?(state)
755
791
  end
756
792
 
757
793
  def ensure_inventory_units
758
794
  if has_checkout_step?("delivery")
759
- inventory_validator = Spree::Stock::InventoryValidator.new
795
+ inventory_validator = Spree::Config.stock.inventory_validator_class.new
796
+
797
+ errors = line_items.map { |line_item|
798
+ inventory_validator.validate(line_item)
799
+ }.compact
760
800
 
761
- errors = line_items.map { |line_item| inventory_validator.validate(line_item) }.compact
762
801
  raise InsufficientStock if errors.any?
763
802
  end
764
803
  end
765
804
 
766
805
  def ensure_promotions_eligible
767
- adjustment_changed = all_adjustments.eligible.promotion.any? do |adjustment|
768
- !adjustment.calculate_eligibility
769
- end
770
- if adjustment_changed
806
+ Spree::Config.promotions.order_adjuster_class.new(self).call
807
+
808
+ if promo_total_changed?
771
809
  restart_checkout_flow
772
810
  recalculate
773
811
  errors.add(:base, I18n.t('spree.promotion_total_changed_before_complete'))
@@ -776,8 +814,15 @@ module Spree
776
814
  end
777
815
 
778
816
  def validate_line_item_availability
779
- availability_validator = Spree::Stock::AvailabilityValidator.new
780
- raise InsufficientStock unless line_items.all? { |line_item| availability_validator.validate(line_item) }
817
+ availability_validator = Spree::Config.stock.availability_validator_class.new
818
+
819
+ # NOTE: This code assumes that the availability validator will return
820
+ # true for success and false for failure. This is not normally the
821
+ # behaviour of validators, as the framework only cares about the
822
+ # population of the errors, not the return value of the validate method.
823
+ raise InsufficientStock unless line_items.all? { |line_item|
824
+ availability_validator.validate(line_item)
825
+ }
781
826
  end
782
827
 
783
828
  def ensure_line_items_present
@@ -800,9 +845,7 @@ module Spree
800
845
  cancel_payments!
801
846
 
802
847
  send_cancel_email
803
- # rubocop:disable Rails/SkipsModelValidations
804
848
  update_column(:canceled_at, Time.current)
805
- # rubocop:enable Rails/SkipsModelValidations
806
849
  recalculate
807
850
  end
808
851
 
@@ -831,6 +874,10 @@ module Spree
831
874
  use_billing.in?([true, 'true', '1'])
832
875
  end
833
876
 
877
+ def use_shipping?
878
+ use_shipping.in?([true, 'true', '1'])
879
+ end
880
+
834
881
  def set_currency
835
882
  self.currency = Spree::Config[:currency] if self[:currency].nil?
836
883
  end
@@ -36,7 +36,7 @@ class Spree::OrderCancellations
36
36
  Spree::OrderMutex.with_lock!(@order) do
37
37
  Spree::InventoryUnit.transaction do
38
38
  inventory_units.each do |iu|
39
- unit_cancels << short_ship_unit(iu, created_by: created_by)
39
+ unit_cancels << short_ship_unit(iu, created_by:)
40
40
  end
41
41
 
42
42
  update_shipped_shipments(inventory_units)
@@ -67,9 +67,9 @@ class Spree::OrderCancellations
67
67
 
68
68
  Spree::OrderMutex.with_lock!(@order) do
69
69
  unit_cancel = Spree::UnitCancel.create!(
70
- inventory_unit: inventory_unit,
71
- reason: reason,
72
- created_by: created_by
70
+ inventory_unit:,
71
+ reason:,
72
+ created_by:
73
73
  )
74
74
 
75
75
  inventory_unit.cancel!
@@ -89,8 +89,8 @@ class Spree::OrderCancellations
89
89
 
90
90
  Spree::OrderMutex.with_lock!(@order) do
91
91
  return_items = inventory_units.map(&:current_or_new_return_item)
92
- reimbursement = Spree::Reimbursement.new(order: @order, return_items: return_items)
93
- reimbursement.return_all(created_by: created_by)
92
+ reimbursement = Spree::Reimbursement.new(order: @order, return_items:)
93
+ reimbursement.return_all(created_by:)
94
94
  end
95
95
 
96
96
  reimbursement
@@ -100,9 +100,9 @@ class Spree::OrderCancellations
100
100
 
101
101
  def short_ship_unit(inventory_unit, created_by: nil)
102
102
  unit_cancel = Spree::UnitCancel.create!(
103
- inventory_unit: inventory_unit,
103
+ inventory_unit:,
104
104
  reason: Spree::UnitCancel::SHORT_SHIP,
105
- created_by: created_by
105
+ created_by:
106
106
  )
107
107
  unit_cancel.adjust!
108
108
  inventory_unit.cancel!
@@ -57,14 +57,16 @@ module Spree
57
57
  # first unshipped that's leaving from a stock_location that stocks this variant, with availability check
58
58
  # first unshipped that's leaving from a stock_location that stocks this variant, without availability check
59
59
  def determine_target_shipment(quantity)
60
- potential_shipments = order.shipments.select(&:ready_or_pending?)
60
+ potential_shipments = order.shipments.order(:created_at, :id).select(&:ready_or_pending?)
61
61
 
62
62
  potential_shipments.detect do |shipment|
63
63
  shipment.include?(variant)
64
- end || potential_shipments.detect do |shipment|
65
- stock_item = shipment.stock_location.stock_item(variant.id)
66
- if stock_item
67
- stock_item.backorderable? || stock_item.count_on_hand >= quantity
64
+ end || begin
65
+ stock_items = variant.stock_items.sort_by(&:id) # cache stock items to avoid N+1
66
+
67
+ potential_shipments.detect do |shipment|
68
+ stock_item = stock_items.detect { |stock_item| stock_item.stock_location == shipment.stock_location }
69
+ stock_item.backorderable? || stock_item.count_on_hand >= quantity if stock_item
68
70
  end
69
71
  end || potential_shipments.detect do |shipment|
70
72
  variant.stock_location_ids.include?(shipment.stock_location_id)
@@ -13,8 +13,6 @@ module Spree
13
13
  # @return [Spree::Order] The order which items wll be merged into.
14
14
  attr_accessor :order
15
15
 
16
- delegate :updater, to: :order
17
-
18
16
  # Create the OrderMerger
19
17
  #
20
18
  # @api public
@@ -80,7 +78,7 @@ module Spree
80
78
  def find_matching_line_item(other_order_line_item)
81
79
  order.line_items.detect do |my_li|
82
80
  my_li.variant == other_order_line_item.variant &&
83
- order.line_item_comparison_hooks.all? do |hook|
81
+ Spree::Config.line_item_comparison_hooks.all? do |hook|
84
82
  order.send(hook, my_li, other_order_line_item.serializable_hash)
85
83
  end
86
84
  end
@@ -115,8 +113,8 @@ module Spree
115
113
  current_line_item.quantity += other_order_line_item.quantity
116
114
  handle_error(current_line_item) unless current_line_item.save
117
115
  else
118
- order.line_items << other_order_line_item
119
- handle_error(other_order_line_item) unless other_order_line_item.save
116
+ new_line_item = order.line_items.build(other_order_line_item.attributes.except("id"))
117
+ handle_error(new_line_item) unless new_line_item.save
120
118
  end
121
119
  end
122
120
 
@@ -133,13 +131,13 @@ module Spree
133
131
 
134
132
  # Save the order totals after merge
135
133
  #
136
- # It triggers the order updater to ensure that item counts and totals are
134
+ # It triggers the order recalculator to ensure that item counts and totals are
137
135
  # up to date.
138
136
  #
139
137
  # @api private
140
138
  # @return [void]
141
139
  def persist_merge
142
- updater.update
140
+ order.recalculate
143
141
  end
144
142
  end
145
143
  end
@@ -16,10 +16,10 @@ module Spree
16
16
  raise ArgumentError, "order must be supplied" if order.nil?
17
17
 
18
18
  # limit the maximum lock time just in case a lock is somehow left in place accidentally
19
- expired.where(order: order).delete_all
19
+ expired.where(order:).delete_all
20
20
 
21
21
  begin
22
- order_mutex = create!(order: order)
22
+ order_mutex = create!(order:)
23
23
  rescue ActiveRecord::RecordNotUnique
24
24
  error = LockFailed.new("Could not obtain lock on order #{order.id}")
25
25
  logger.error error.inspect