solidus_core 4.1.6 → 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 (308) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/logo/solidus.svg +18 -1
  3. data/app/assets/images/logo/solidus_logo.png +0 -0
  4. data/app/helpers/spree/base_helper.rb +2 -2
  5. data/app/helpers/spree/core/controller_helpers/auth.rb +66 -0
  6. data/app/helpers/spree/core/controller_helpers/common.rb +82 -0
  7. data/app/helpers/spree/core/controller_helpers/order.rb +86 -0
  8. data/app/helpers/spree/core/controller_helpers/payment_parameters.rb +165 -0
  9. data/app/helpers/spree/core/controller_helpers/pricing.rb +19 -0
  10. data/app/helpers/spree/core/controller_helpers/search.rb +16 -0
  11. data/app/helpers/spree/core/controller_helpers/store.rb +19 -0
  12. data/app/helpers/spree/core/controller_helpers/strong_parameters.rb +74 -0
  13. data/app/mailers/spree/base_mailer.rb +1 -1
  14. data/app/mailers/spree/carton_mailer.rb +1 -1
  15. data/app/mailers/spree/order_mailer.rb +3 -3
  16. data/app/mailers/spree/reimbursement_mailer.rb +1 -1
  17. data/app/models/concerns/spree/active_storage_adapter/normalization.rb +1 -1
  18. data/app/models/concerns/spree/active_storage_adapter.rb +1 -1
  19. data/app/models/concerns/spree/display_money.rb +1 -1
  20. data/app/models/concerns/spree/metadata.rb +64 -0
  21. data/app/models/concerns/spree/named_type.rb +2 -0
  22. data/app/models/concerns/spree/ordered_property_value_list.rb +2 -2
  23. data/app/models/concerns/spree/user_address_book.rb +8 -9
  24. data/app/models/concerns/spree/user_methods.rb +3 -3
  25. data/app/models/spree/address.rb +10 -8
  26. data/app/models/spree/adjustment.rb +15 -65
  27. data/app/models/spree/adjustment_reason.rb +2 -0
  28. data/app/models/spree/calculator/returns/default_refund_amount.rb +1 -1
  29. data/app/models/spree/carton.rb +2 -2
  30. data/app/models/spree/core/state_machines/inventory_unit.rb +42 -0
  31. data/app/models/spree/core/state_machines/order/class_methods.rb +217 -0
  32. data/app/models/spree/core/state_machines/order.rb +42 -0
  33. data/app/models/spree/core/state_machines/payment.rb +61 -0
  34. data/app/models/spree/core/state_machines/reimbursement.rb +33 -0
  35. data/app/models/spree/core/state_machines/return_authorization.rb +32 -0
  36. data/app/models/spree/core/state_machines/return_item/acceptance_status.rb +51 -0
  37. data/app/models/spree/core/state_machines/return_item/reception_status.rb +42 -0
  38. data/app/models/spree/core/state_machines/shipment.rb +58 -0
  39. data/app/models/spree/credit_card.rb +12 -9
  40. data/app/models/spree/customer_return.rb +2 -0
  41. data/app/models/spree/deprecated_configurable_class.rb +40 -0
  42. data/app/models/spree/fulfilment_changer.rb +4 -4
  43. data/app/models/spree/inventory_unit.rb +2 -2
  44. data/app/models/spree/item_total.rb +28 -0
  45. data/app/models/spree/legacy_user.rb +1 -0
  46. data/app/models/spree/line_item.rb +22 -4
  47. data/app/models/spree/money.rb +120 -0
  48. data/app/models/spree/null_promotion_adjuster.rb +13 -0
  49. data/app/models/spree/null_promotion_advertiser.rb +9 -0
  50. data/app/models/spree/null_promotion_finder.rb +9 -0
  51. data/app/models/spree/null_promotion_handler.rb +44 -0
  52. data/app/models/spree/option_value.rb +1 -0
  53. data/app/models/spree/order.rb +54 -36
  54. data/app/models/spree/order_cancellations.rb +8 -8
  55. data/app/models/spree/order_inventory.rb +6 -4
  56. data/app/models/spree/order_merger.rb +1 -1
  57. data/app/models/spree/order_mutex.rb +2 -2
  58. data/app/models/spree/order_shipping.rb +9 -9
  59. data/app/models/spree/order_taxation.rb +1 -0
  60. data/app/models/spree/order_updater.rb +19 -40
  61. data/app/models/spree/payment/processing.rb +2 -2
  62. data/app/models/spree/payment.rb +3 -2
  63. data/app/models/spree/payment_create.rb +1 -1
  64. data/app/models/spree/payment_method/bogus_credit_card.rb +14 -9
  65. data/app/models/spree/payment_method/simple_bogus_credit_card.rb +12 -6
  66. data/app/models/spree/payment_method/store_credit.rb +1 -1
  67. data/app/models/spree/payment_method.rb +3 -1
  68. data/app/models/spree/payment_source.rb +5 -1
  69. data/app/models/spree/permission_set.rb +11 -0
  70. data/app/models/spree/permission_sets/base.rb +45 -0
  71. data/app/models/spree/permission_sets/configuration_display.rb +53 -0
  72. data/app/models/spree/permission_sets/configuration_management.rb +52 -0
  73. data/app/models/spree/permission_sets/dashboard_display.rb +28 -0
  74. data/app/models/spree/permission_sets/default_customer.rb +83 -0
  75. data/app/models/spree/permission_sets/order_display.rb +50 -0
  76. data/app/models/spree/permission_sets/order_management.rb +50 -0
  77. data/app/models/spree/permission_sets/product_display.rb +43 -0
  78. data/app/models/spree/permission_sets/product_management.rb +47 -0
  79. data/app/models/spree/permission_sets/restricted_stock_display.rb +33 -0
  80. data/app/models/spree/permission_sets/restricted_stock_management.rb +33 -0
  81. data/app/models/spree/permission_sets/stock_display.rb +26 -0
  82. data/app/models/spree/permission_sets/stock_management.rb +26 -0
  83. data/app/models/spree/permission_sets/super_user.rb +26 -0
  84. data/app/models/spree/permission_sets/user_display.rb +27 -0
  85. data/app/models/spree/permission_sets/user_management.rb +44 -0
  86. data/app/models/spree/preference.rb +1 -1
  87. data/app/models/spree/product.rb +13 -9
  88. data/app/models/spree/refund.rb +3 -1
  89. data/app/models/spree/refund_reason.rb +6 -1
  90. data/app/models/spree/reimbursement.rb +4 -4
  91. data/app/models/spree/reimbursement_performer.rb +3 -3
  92. data/app/models/spree/reimbursement_tax_calculator.rb +2 -2
  93. data/app/models/spree/reimbursement_type/credit.rb +1 -1
  94. data/app/models/spree/reimbursement_type/reimbursement_helpers.rb +6 -6
  95. data/app/models/spree/reimbursement_type/store_credit.rb +1 -1
  96. data/app/models/spree/reimbursement_type.rb +6 -1
  97. data/app/models/spree/return_authorization.rb +2 -0
  98. data/app/models/spree/return_item.rb +10 -10
  99. data/app/models/spree/return_reason.rb +6 -1
  100. data/app/models/spree/role.rb +3 -1
  101. data/app/models/spree/role_permission.rb +8 -0
  102. data/app/models/spree/shipment.rb +9 -7
  103. data/app/models/spree/shipping_category.rb +2 -0
  104. data/app/models/spree/shipping_rate.rb +2 -3
  105. data/app/models/spree/{order_contents.rb → simple_order_contents.rb} +8 -12
  106. data/app/models/spree/stock/estimator.rb +1 -1
  107. data/app/models/spree/stock/inventory_unit_builder.rb +1 -1
  108. data/app/models/spree/stock/package.rb +2 -2
  109. data/app/models/spree/stock/simple_coordinator.rb +36 -22
  110. data/app/models/spree/stock_item.rb +1 -0
  111. data/app/models/spree/stock_location.rb +5 -5
  112. data/app/models/spree/store.rb +3 -1
  113. data/app/models/spree/store_credit.rb +17 -15
  114. data/app/models/spree/store_credit_event.rb +4 -3
  115. data/app/models/spree/store_credit_reason.rb +6 -1
  116. data/app/models/spree/store_selector/by_server_name.rb +1 -1
  117. data/app/models/spree/tax/tax_helpers.rb +12 -1
  118. data/app/models/spree/tax_calculator/default.rb +3 -3
  119. data/app/models/spree/tax_calculator/shipping_rate.rb +1 -1
  120. data/app/models/spree/tax_category.rb +3 -1
  121. data/app/models/spree/tax_rate.rb +7 -3
  122. data/app/models/spree/taxon.rb +22 -2
  123. data/app/models/spree/taxon_brand_selector.rb +22 -0
  124. data/app/models/spree/taxonomy.rb +2 -2
  125. data/app/models/spree/unauthorized_redirect_handler.rb +24 -0
  126. data/app/models/spree/unit_cancel.rb +1 -2
  127. data/app/models/spree/user_address.rb +9 -3
  128. data/app/models/spree/variant/scopes.rb +4 -0
  129. data/app/models/spree/variant/vat_price_generator.rb +1 -1
  130. data/app/models/spree/variant.rb +21 -8
  131. data/app/models/spree/wallet.rb +2 -2
  132. data/app/views/spree/order_mailer/cancel_email.html.erb +1 -1
  133. data/app/views/spree/order_mailer/cancel_email.text.erb +1 -1
  134. data/app/views/spree/order_mailer/confirm_email.html.erb +5 -5
  135. data/app/views/spree/order_mailer/confirm_email.text.erb +5 -5
  136. data/app/views/spree/order_mailer/inventory_cancellation_email.html.erb +0 -1
  137. data/config/locales/en.yml +33 -90
  138. data/db/default/spree/permission_sets.rb +10 -0
  139. data/db/default/spree/return_reasons.rb +3 -1
  140. data/db/default/spree/states.rb +1 -1
  141. data/db/migrate/20160101010000_solidus_one_four.rb +0 -127
  142. data/db/migrate/20220419170826_remove_archived_user_addresses.rb +12 -0
  143. data/db/migrate/20230427095534_drop_deprecated_address_id_from_shipments.rb +1 -1
  144. data/db/migrate/20240821173254_create_spree_permission_sets_in_core.rb +9 -0
  145. data/db/migrate/20240821173341_create_spree_roles_permissions_in_core.rb +9 -0
  146. data/db/migrate/20240821173641_add_description_to_spree_roles.rb +5 -0
  147. data/db/migrate/20240904152041_add_privilege_and_category_to_spree_permission_sets.rb +6 -0
  148. data/db/migrate/20250129061658_add_metadata_to_spree_resources.rb +28 -0
  149. data/db/migrate/20250201172950_add_gtin_and_condition_to_spree_variant.rb +6 -0
  150. data/db/migrate/20250207104016_add_primary_taxon_to_products.rb +7 -0
  151. data/db/migrate/20250221152004_add_metadata_to_users.rb +13 -0
  152. data/db/seeds.rb +1 -0
  153. data/lib/generators/solidus/install/app_templates/authentication/custom.rb +0 -5
  154. data/lib/generators/solidus/install/app_templates/frontend/starter.rb +1 -1
  155. data/lib/generators/solidus/install/install_generator.rb +64 -15
  156. data/lib/generators/solidus/install/templates/config/initializers/spree.rb.tt +15 -12
  157. data/lib/generators/solidus/update/update_generator.rb +1 -1
  158. data/lib/generators/spree/dummy/dummy_generator.rb +1 -1
  159. data/lib/generators/spree/dummy/templates/rails/application.rb.tt +1 -1
  160. data/lib/generators/spree/dummy/templates/rails/database.yml +41 -93
  161. data/lib/generators/spree/dummy/templates/rails/manifest.js +3 -0
  162. data/lib/generators/spree/dummy/templates/rails/test.rb +6 -1
  163. data/lib/spree/app_configuration.rb +102 -67
  164. data/lib/spree/core/class_constantizer.rb +2 -2
  165. data/lib/spree/core/controller_helpers/auth.rb +5 -61
  166. data/lib/spree/core/controller_helpers/common.rb +5 -80
  167. data/lib/spree/core/controller_helpers/order.rb +5 -86
  168. data/lib/spree/core/controller_helpers/payment_parameters.rb +5 -163
  169. data/lib/spree/core/controller_helpers/pricing.rb +5 -17
  170. data/lib/spree/core/controller_helpers/search.rb +5 -14
  171. data/lib/spree/core/controller_helpers/store.rb +5 -17
  172. data/lib/spree/core/controller_helpers/strong_parameters.rb +5 -71
  173. data/lib/spree/core/engine.rb +13 -5
  174. data/lib/spree/core/environment/calculators.rb +35 -3
  175. data/lib/spree/core/environment/promotions.rb +25 -4
  176. data/lib/spree/core/environment_extension.rb +16 -2
  177. data/lib/spree/core/importer/order.rb +5 -5
  178. data/lib/spree/core/importer/product.rb +3 -3
  179. data/lib/spree/core/nested_class_set.rb +28 -0
  180. data/lib/spree/core/null_promotion_configuration.rb +84 -0
  181. data/lib/spree/core/product_filters.rb +1 -1
  182. data/lib/spree/core/search/variant.rb +2 -2
  183. data/lib/spree/core/state_machines/inventory_unit.rb +5 -40
  184. data/lib/spree/core/state_machines/order.rb +5 -251
  185. data/lib/spree/core/state_machines/payment.rb +5 -59
  186. data/lib/spree/core/state_machines/reimbursement.rb +5 -31
  187. data/lib/spree/core/state_machines/return_authorization.rb +5 -30
  188. data/lib/spree/core/state_machines/return_item/acceptance_status.rb +5 -49
  189. data/lib/spree/core/state_machines/return_item/reception_status.rb +5 -40
  190. data/lib/spree/core/state_machines/shipment.rb +5 -56
  191. data/lib/spree/core/state_machines.rb +48 -81
  192. data/lib/spree/core/validators/email.rb +1 -1
  193. data/lib/spree/core/version.rb +2 -2
  194. data/lib/spree/core.rb +2 -14
  195. data/lib/spree/deprecator.rb +9 -0
  196. data/lib/spree/i18n.rb +1 -1
  197. data/lib/spree/mailer_previews/carton_preview.rb +1 -1
  198. data/lib/spree/money.rb +5 -118
  199. data/lib/spree/permission_sets/base.rb +5 -30
  200. data/lib/spree/permission_sets/configuration_display.rb +5 -41
  201. data/lib/spree/permission_sets/configuration_management.rb +5 -40
  202. data/lib/spree/permission_sets/dashboard_display.rb +5 -14
  203. data/lib/spree/permission_sets/default_customer.rb +5 -71
  204. data/lib/spree/permission_sets/order_display.rb +5 -38
  205. data/lib/spree/permission_sets/order_management.rb +5 -38
  206. data/lib/spree/permission_sets/product_display.rb +5 -31
  207. data/lib/spree/permission_sets/product_management.rb +5 -35
  208. data/lib/spree/permission_sets/restricted_stock_display.rb +5 -21
  209. data/lib/spree/permission_sets/restricted_stock_management.rb +5 -21
  210. data/lib/spree/permission_sets/stock_display.rb +5 -14
  211. data/lib/spree/permission_sets/stock_management.rb +5 -14
  212. data/lib/spree/permission_sets/super_user.rb +5 -14
  213. data/lib/spree/permission_sets/user_display.rb +5 -15
  214. data/lib/spree/permission_sets/user_management.rb +5 -32
  215. data/lib/spree/permission_sets.rb +5 -18
  216. data/lib/spree/permitted_attributes.rb +21 -9
  217. data/lib/spree/preferences/configuration.rb +4 -0
  218. data/lib/spree/preferences/persistable.rb +7 -1
  219. data/lib/spree/preferences/store.rb +2 -2
  220. data/lib/spree/testing_support/capybara_ext.rb +11 -1
  221. data/lib/spree/testing_support/common_rake.rb +1 -0
  222. data/lib/spree/testing_support/dummy_ability.rb +7 -0
  223. data/lib/spree/testing_support/dummy_app/assets/stylesheets/solidus_admin/tailwind.css +1 -0
  224. data/lib/spree/testing_support/dummy_app/database.yml +37 -46
  225. data/lib/spree/testing_support/dummy_app/migrations.rb +8 -15
  226. data/lib/spree/testing_support/dummy_app/rake_tasks.rb +3 -6
  227. data/lib/spree/testing_support/dummy_app.rb +33 -19
  228. data/lib/spree/testing_support/factories/adjustment_factory.rb +1 -2
  229. data/lib/spree/testing_support/factories/calculator_factory.rb +1 -5
  230. data/lib/spree/testing_support/factories/carton_factory.rb +2 -2
  231. data/lib/spree/testing_support/factories/customer_return_factory.rb +2 -2
  232. data/lib/spree/testing_support/factories/inventory_unit_factory.rb +3 -3
  233. data/lib/spree/testing_support/factories/order_factory.rb +13 -24
  234. data/lib/spree/testing_support/factories/product_factory.rb +1 -1
  235. data/lib/spree/testing_support/factories/shipment_factory.rb +1 -1
  236. data/lib/spree/testing_support/factories/stock_item_factory.rb +5 -1
  237. data/lib/spree/testing_support/factories/stock_package_factory.rb +1 -1
  238. data/lib/spree/testing_support/factories/user_factory.rb +1 -1
  239. data/lib/spree/testing_support/factories/zone_factory.rb +1 -1
  240. data/lib/spree/testing_support/order_walkthrough.rb +3 -3
  241. data/lib/spree/testing_support/shared_examples/calculator.rb +10 -0
  242. data/lib/spree/testing_support/shared_examples/order_factory.rb +141 -0
  243. data/lib/spree/testing_support/shared_examples/working_factory.rb +15 -0
  244. data/lib/tasks/colorado_delivery_fee.rake +2 -2
  245. data/solidus_core.gemspec +7 -10
  246. metadata +107 -109
  247. data/app/jobs/spree/promotion_code_batch_job.rb +0 -26
  248. data/app/mailers/spree/promotion_code_batch_mailer.rb +0 -15
  249. data/app/models/spree/calculator/distributed_amount.rb +0 -33
  250. data/app/models/spree/calculator/flat_percent_item_total.rb +0 -23
  251. data/app/models/spree/calculator/flexi_rate.rb +0 -22
  252. data/app/models/spree/calculator/percent_on_line_item.rb +0 -13
  253. data/app/models/spree/calculator/tiered_flat_rate.rb +0 -52
  254. data/app/models/spree/calculator/tiered_percent.rb +0 -62
  255. data/app/models/spree/line_item_action.rb +0 -8
  256. data/app/models/spree/order_promotion.rb +0 -27
  257. data/app/models/spree/promotion/actions/create_adjustment.rb +0 -81
  258. data/app/models/spree/promotion/actions/create_item_adjustments.rb +0 -98
  259. data/app/models/spree/promotion/actions/create_quantity_adjustments.rb +0 -139
  260. data/app/models/spree/promotion/actions/free_shipping.rb +0 -59
  261. data/app/models/spree/promotion/order_adjustments_recalculator.rb +0 -92
  262. data/app/models/spree/promotion/rules/first_order.rb +0 -38
  263. data/app/models/spree/promotion/rules/first_repeat_purchase_since.rb +0 -36
  264. data/app/models/spree/promotion/rules/item_total.rb +0 -86
  265. data/app/models/spree/promotion/rules/nth_order.rb +0 -45
  266. data/app/models/spree/promotion/rules/one_use_per_user.rb +0 -25
  267. data/app/models/spree/promotion/rules/option_value.rb +0 -50
  268. data/app/models/spree/promotion/rules/product.rb +0 -86
  269. data/app/models/spree/promotion/rules/store.rb +0 -26
  270. data/app/models/spree/promotion/rules/taxon.rb +0 -91
  271. data/app/models/spree/promotion/rules/user.rb +0 -34
  272. data/app/models/spree/promotion/rules/user_logged_in.rb +0 -20
  273. data/app/models/spree/promotion/rules/user_role.rb +0 -45
  274. data/app/models/spree/promotion.rb +0 -271
  275. data/app/models/spree/promotion_action.rb +0 -47
  276. data/app/models/spree/promotion_category.rb +0 -8
  277. data/app/models/spree/promotion_chooser.rb +0 -34
  278. data/app/models/spree/promotion_code/batch_builder.rb +0 -64
  279. data/app/models/spree/promotion_code.rb +0 -54
  280. data/app/models/spree/promotion_code_batch.rb +0 -27
  281. data/app/models/spree/promotion_handler/cart.rb +0 -75
  282. data/app/models/spree/promotion_handler/coupon.rb +0 -123
  283. data/app/models/spree/promotion_handler/page.rb +0 -26
  284. data/app/models/spree/promotion_handler/shipping.rb +0 -61
  285. data/app/models/spree/promotion_rule.rb +0 -55
  286. data/app/models/spree/promotion_rule_role.rb +0 -8
  287. data/app/models/spree/promotion_rule_store.rb +0 -10
  288. data/app/models/spree/promotion_rule_taxon.rb +0 -8
  289. data/app/models/spree/promotion_rule_user.rb +0 -10
  290. data/app/views/spree/promotion_code_batch_mailer/promotion_code_batch_errored.text.erb +0 -2
  291. data/app/views/spree/promotion_code_batch_mailer/promotion_code_batch_finished.text.erb +0 -2
  292. data/bin/rails +0 -13
  293. data/db/migrate/20161017102621_create_spree_promotion_code_batch.rb +0 -38
  294. data/db/migrate/20180202190713_create_promotion_rule_stores.rb +0 -12
  295. data/db/migrate/20180328172631_add_join_characters_to_promotion_code_batch.rb +0 -11
  296. data/db/migrate/20190106184413_remove_code_from_spree_promotions.rb +0 -42
  297. data/db/migrate/20220317165036_set_promotions_with_any_policy_to_all_if_possible.rb +0 -20
  298. data/db/migrate/20230322085416_remove_match_policy_from_spree_promotion.rb +0 -5
  299. data/db/migrate/20230325132905_remove_unused_columns_from_promotion_rules.rb +0 -6
  300. data/db/migrate/20230325161633_drop_unused_promo_action_line_items.rb +0 -13
  301. data/lib/generators/spree/dummy/templates/rails/script/rails +0 -6
  302. data/lib/solidus/migrations/promotions_with_code_handlers.rb +0 -66
  303. data/lib/spree/permission_sets/promotion_display.rb +0 -25
  304. data/lib/spree/permission_sets/promotion_management.rb +0 -25
  305. data/lib/spree/testing_support/factories/order_promotion_factory.rb +0 -8
  306. data/lib/spree/testing_support/factories/promotion_category_factory.rb +0 -7
  307. data/lib/spree/testing_support/factories/promotion_code_factory.rb +0 -8
  308. data/lib/spree/testing_support/factories/promotion_factory.rb +0 -98
@@ -25,7 +25,7 @@ module Spree
25
25
  Spree::InventoryUnit.new(
26
26
  pending: true,
27
27
  variant: line_item.variant,
28
- line_item: line_item
28
+ line_item:
29
29
  )
30
30
  end
31
31
  end
@@ -124,8 +124,8 @@ module Spree
124
124
  contents.each { |content_item| content_item.inventory_unit.state = content_item.state.to_s }
125
125
 
126
126
  Spree::Shipment.new(
127
- order: order,
128
- stock_location: stock_location,
127
+ order:,
128
+ stock_location:,
129
129
  inventory_units: contents.map(&:inventory_unit)
130
130
  )
131
131
  end
@@ -22,39 +22,65 @@ module Spree
22
22
  class SimpleCoordinator
23
23
  attr_reader :order
24
24
 
25
+ # @api private
26
+ attr_reader :inventory_units, :splitters, :stock_locations,
27
+ :filtered_stock_locations, :inventory_units_by_variant, :desired,
28
+ :availability, :allocator, :packages
29
+
25
30
  def initialize(order, inventory_units = nil)
26
31
  @order = order
27
32
  @inventory_units =
28
33
  inventory_units || Spree::Config.stock.inventory_unit_builder_class.new(order).units
29
34
  @splitters = Spree::Config.environment.stock_splitters
30
35
 
31
- filtered_stock_locations = Spree::Config.stock.location_filter_class.new(Spree::StockLocation.all, @order).filter
36
+ @filtered_stock_locations = Spree::Config.stock.location_filter_class.new(load_stock_locations, order).filter
32
37
  sorted_stock_locations = Spree::Config.stock.location_sorter_class.new(filtered_stock_locations).sort
33
38
  @stock_locations = sorted_stock_locations
34
39
 
35
40
  @inventory_units_by_variant = @inventory_units.group_by(&:variant)
36
- @desired = Spree::StockQuantities.new(@inventory_units_by_variant.transform_values(&:count))
41
+ @desired = Spree::StockQuantities.new(inventory_units_by_variant.transform_values(&:count))
37
42
  @availability = Spree::Stock::Availability.new(
38
- variants: @desired.variants,
39
- stock_locations: @stock_locations
43
+ variants: desired.variants,
44
+ stock_locations:
40
45
  )
41
46
 
42
- @allocator = Spree::Config.stock.allocator_class.new(@availability)
47
+ @allocator = Spree::Config.stock.allocator_class.new(availability)
43
48
  end
44
49
 
45
50
  def shipments
46
- @shipments ||= build_shipments
51
+ @shipments ||= begin
52
+ @packages = build_packages
53
+ shipments = build_shipments
54
+
55
+ # Make sure we don't add the proposed shipments to the order
56
+ order.shipments = order.shipments - shipments
57
+
58
+ shipments
59
+ end
47
60
  end
48
61
 
49
62
  private
50
63
 
64
+ def load_stock_locations
65
+ Spree::StockLocation.all
66
+ end
67
+
51
68
  def build_shipments
69
+ # Turn the Stock::Packages into a Shipment with rates
70
+ packages.map do |package|
71
+ shipment = package.shipment = package.to_shipment
72
+ shipment.shipping_rates = Spree::Config.stock.estimator_class.new.shipping_rates(package)
73
+ shipment
74
+ end
75
+ end
76
+
77
+ def build_packages
52
78
  # Allocate any available on hand inventory and remaining desired inventory from backorders
53
- on_hand_packages, backordered_packages, leftover = @allocator.allocate_inventory(@desired)
79
+ on_hand_packages, backordered_packages, leftover = allocator.allocate_inventory(desired)
54
80
 
55
81
  raise Spree::Order::InsufficientStock.new(items: leftover.quantities) unless leftover.empty?
56
82
 
57
- packages = @stock_locations.map do |stock_location|
83
+ packages = stock_locations.map do |stock_location|
58
84
  # Combine on_hand and backorders into a single package per-location
59
85
  on_hand = on_hand_packages[stock_location.id] || Spree::StockQuantities.new
60
86
  backordered = backordered_packages[stock_location.id] || Spree::StockQuantities.new
@@ -71,19 +97,7 @@ module Spree
71
97
  end.compact
72
98
 
73
99
  # Split the packages
74
- packages = split_packages(packages)
75
-
76
- # Turn the Stock::Packages into a Shipment with rates
77
- shipments = packages.map do |package|
78
- shipment = package.shipment = package.to_shipment
79
- shipment.shipping_rates = Spree::Config.stock.estimator_class.new.shipping_rates(package)
80
- shipment
81
- end
82
-
83
- # Make sure we don't add the proposed shipments to the order
84
- order.shipments = order.shipments - shipments
85
-
86
- shipments
100
+ split_packages(packages)
87
101
  end
88
102
 
89
103
  def split_packages(initial_packages)
@@ -96,7 +110,7 @@ module Spree
96
110
  def get_units(quantities)
97
111
  # Change our raw quantities back into inventory units
98
112
  quantities.flat_map do |variant, quantity|
99
- @inventory_units_by_variant[variant].shift(quantity)
113
+ inventory_units_by_variant[variant].shift(quantity)
100
114
  end
101
115
  end
102
116
  end
@@ -21,6 +21,7 @@ module Spree
21
21
  after_touch { variant.touch }
22
22
 
23
23
  self.allowed_ransackable_attributes = ['count_on_hand', 'stock_location_id']
24
+ self.allowed_ransackable_associations = %w[variant]
24
25
 
25
26
  # @return [Array<Spree::InventoryUnit>] the backordered inventory units
26
27
  # associated with this stock item
@@ -39,7 +39,7 @@ module Spree
39
39
 
40
40
  # Wrapper for creating a new stock item respecting the backorderable config
41
41
  def propagate_variant(variant)
42
- stock_items.create!(variant: variant, backorderable: backorderable_default)
42
+ stock_items.create!(variant:, backorderable: backorderable_default)
43
43
  end
44
44
 
45
45
  # Return either an existing stock item or create a new one. Useful in
@@ -55,7 +55,7 @@ module Spree
55
55
  #
56
56
  # @return [StockItem] Corresponding StockItem for the StockLocation's variant.
57
57
  def stock_item(variant_id)
58
- stock_items.where(variant_id: variant_id).order(:id).first
58
+ stock_items.where(variant_id:).order(:id).first
59
59
  end
60
60
 
61
61
  # Attempts to look up StockItem for the variant, and creates one if not found.
@@ -101,8 +101,8 @@ module Spree
101
101
  if quantity < 1 && !stock_item(variant)
102
102
  raise InvalidMovementError.new(I18n.t('spree.negative_movement_absent_item'))
103
103
  end
104
- stock_item_or_create(variant).stock_movements.create!(quantity: quantity,
105
- originator: originator)
104
+ stock_item_or_create(variant).stock_movements.create!(quantity:,
105
+ originator:)
106
106
  end
107
107
 
108
108
  def fill_status(variant, quantity)
@@ -121,7 +121,7 @@ module Spree
121
121
 
122
122
  def ensure_one_default
123
123
  if default
124
- Spree::StockLocation.where(default: true).where.not(id: id).find_each do |stock_location|
124
+ Spree::StockLocation.where(default: true).where.not(id:).find_each do |stock_location|
125
125
  stock_location.default = false
126
126
  stock_location.save!
127
127
  end
@@ -22,6 +22,8 @@ module Spree
22
22
  validates :url, presence: true
23
23
  validates :mail_from_address, presence: true
24
24
 
25
+ self.allowed_ransackable_attributes = %w[name url code]
26
+
25
27
  before_save :ensure_default_exists_and_is_unique
26
28
  before_destroy :validate_not_default
27
29
 
@@ -56,7 +58,7 @@ module Spree
56
58
 
57
59
  def ensure_default_exists_and_is_unique
58
60
  if default
59
- Spree::Store.where.not(id: id).update_all(default: false)
61
+ Spree::Store.where.not(id:).update_all(default: false)
60
62
  elsif Spree::Store.where(default: true).count == 0
61
63
  self.default = true
62
64
  end
@@ -40,6 +40,8 @@ class Spree::StoreCredit < Spree::PaymentSource
40
40
  extend Spree::DisplayMoney
41
41
  money_methods :amount, :amount_used, :amount_authorized
42
42
 
43
+ alias_method :display_number, :category_name
44
+
43
45
  # Sets this store credit's amount to a new value,
44
46
  # parsing it as a localized number if the new value is a string.
45
47
  #
@@ -56,7 +58,7 @@ class Spree::StoreCredit < Spree::PaymentSource
56
58
  def authorize(amount, order_currency, options = {})
57
59
  authorization_code = options[:action_authorization_code]
58
60
  if authorization_code
59
- if store_credit_events.find_by(action: AUTHORIZE_ACTION, authorization_code: authorization_code)
61
+ if store_credit_events.find_by(action: AUTHORIZE_ACTION, authorization_code:)
60
62
  # Don't authorize again on capture
61
63
  return true
62
64
  end
@@ -90,7 +92,7 @@ class Spree::StoreCredit < Spree::PaymentSource
90
92
 
91
93
  def capture(amount, authorization_code, order_currency, options = {})
92
94
  return false unless authorize(amount, order_currency, action_authorization_code: authorization_code)
93
- auth_event = store_credit_events.find_by!(action: AUTHORIZE_ACTION, authorization_code: authorization_code)
95
+ auth_event = store_credit_events.find_by!(action: AUTHORIZE_ACTION, authorization_code:)
94
96
 
95
97
  if amount <= auth_event.amount
96
98
  if currency != order_currency
@@ -115,7 +117,7 @@ class Spree::StoreCredit < Spree::PaymentSource
115
117
  end
116
118
 
117
119
  def void(authorization_code, options = {})
118
- if auth_event = store_credit_events.find_by(action: AUTHORIZE_ACTION, authorization_code: authorization_code)
120
+ if auth_event = store_credit_events.find_by(action: AUTHORIZE_ACTION, authorization_code:)
119
121
  update!({
120
122
  action: VOID_ACTION,
121
123
  action_amount: auth_event.amount,
@@ -133,7 +135,7 @@ class Spree::StoreCredit < Spree::PaymentSource
133
135
 
134
136
  def credit(amount, authorization_code, order_currency, options = {})
135
137
  # Find the amount related to this authorization_code in order to add the store credit back
136
- capture_event = store_credit_events.find_by(action: CAPTURE_ACTION, authorization_code: authorization_code)
138
+ capture_event = store_credit_events.find_by(action: CAPTURE_ACTION, authorization_code:)
137
139
 
138
140
  if currency != order_currency # sanity check to make sure the order currency hasn't changed since the auth
139
141
  errors.add(:base, I18n.t('spree.store_credit.currency_mismatch'))
@@ -219,25 +221,25 @@ class Spree::StoreCredit < Spree::PaymentSource
219
221
 
220
222
  def create_credit_record_params(amount)
221
223
  {
222
- amount: amount,
223
- user_id: user_id,
224
- category_id: category_id,
225
- created_by_id: created_by_id,
226
- currency: currency,
227
- type_id: type_id,
224
+ amount:,
225
+ user_id:,
226
+ category_id:,
227
+ created_by_id:,
228
+ currency:,
229
+ type_id:,
228
230
  memo: credit_allocation_memo
229
231
  }
230
232
  end
231
233
 
232
234
  def credit_allocation_memo
233
- I18n.t("spree.store_credit.credit_allocation_memo", id: id)
235
+ I18n.t("spree.store_credit.credit_allocation_memo", id:)
234
236
  end
235
237
 
236
238
  def store_event
237
239
  return unless saved_change_to_amount? || saved_change_to_amount_used? || saved_change_to_amount_authorized? || [ELIGIBLE_ACTION, INVALIDATE_ACTION].include?(action)
238
240
 
239
241
  event = if action
240
- store_credit_events.build(action: action)
242
+ store_credit_events.build(action:)
241
243
  else
242
244
  store_credit_events.where(action: ALLOCATION_ACTION).first_or_initialize
243
245
  end
@@ -245,10 +247,10 @@ class Spree::StoreCredit < Spree::PaymentSource
245
247
  event.update!({
246
248
  amount: action_amount || amount,
247
249
  authorization_code: action_authorization_code || event.authorization_code || generate_authorization_code,
248
- amount_remaining: amount_remaining,
249
- user_total_amount: user.available_store_credit_total(currency: currency),
250
+ amount_remaining:,
251
+ user_total_amount: user.available_store_credit_total(currency:),
250
252
  originator: action_originator,
251
- store_credit_reason: store_credit_reason
253
+ store_credit_reason:
252
254
  })
253
255
  end
254
256
 
@@ -3,6 +3,7 @@
3
3
  module Spree
4
4
  class StoreCreditEvent < Spree::Base
5
5
  include Spree::SoftDeletable
6
+ include Metadata
6
7
 
7
8
  belongs_to :store_credit, optional: true
8
9
  belongs_to :originator, polymorphic: true, optional: true
@@ -33,15 +34,15 @@ module Spree
33
34
  end
34
35
 
35
36
  def display_amount
36
- Spree::Money.new(amount, { currency: currency })
37
+ Spree::Money.new(amount, { currency: })
37
38
  end
38
39
 
39
40
  def display_user_total_amount
40
- Spree::Money.new(user_total_amount, { currency: currency })
41
+ Spree::Money.new(user_total_amount, { currency: })
41
42
  end
42
43
 
43
44
  def display_remaining_amount
44
- Spree::Money.new(amount_remaining, { currency: currency })
45
+ Spree::Money.new(amount_remaining, { currency: })
45
46
  end
46
47
 
47
48
  def display_event_date
@@ -1,7 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Spree::StoreCreditReason < Spree::Base
4
- include Spree::NamedType
4
+ scope :active, -> { where(active: true) }
5
+ default_scope -> { order(arel_table[:name].lower) }
6
+
7
+ validates :name, presence: true, uniqueness: { case_sensitive: false, allow_blank: true }
5
8
 
6
9
  has_many :store_credit_events, inverse_of: :store_credit_reason
10
+
11
+ self.allowed_ransackable_attributes = %w[name]
7
12
  end
@@ -25,7 +25,7 @@ module Spree
25
25
  store = Spree::Store.where(url: server_name).or(Store.where(default: true)).order(default: :asc).first
26
26
 
27
27
  # Provide a fallback, mostly for legacy/testing purposes
28
- store || Spree::Store.new
28
+ store || Spree::Store.new(url: server_name)
29
29
  end
30
30
  end
31
31
  end
@@ -5,11 +5,22 @@ module Spree
5
5
  module TaxHelpers
6
6
  private
7
7
 
8
+ # Select active rates matching tax category and address
9
+ #
10
+ # @private
11
+ # @param [Spree::LineItem, Spree::Shipment, Spree::ShippingRate] item
12
+ # the line item, shipment, or shipping rate to select rates for
13
+ # @return [Array<Spree::TaxRate>] the active Tax Rates that match both
14
+ # Tax Category and the item's order's tax address
8
15
  def rates_for_item(item)
9
16
  @rates_for_item ||= Spree::TaxRate.item_level.for_address(item.order.tax_address)
17
+ # try is used here to ensure that a LineItem has rates selected for the
18
+ # currently configured Tax Category. Shipments and ShippingRates do not
19
+ # implement variant_tax_category_id, so try is necessary instead of .&
20
+ tax_category_id = item.try(:variant_tax_category_id) || item.tax_category_id
10
21
 
11
22
  @rates_for_item.select do |rate|
12
- rate.active? && rate.tax_categories.map(&:id).include?(item.tax_category_id)
23
+ rate.active? && rate.tax_categories.map(&:id).include?(tax_category_id)
13
24
  end
14
25
  end
15
26
  end
@@ -46,7 +46,7 @@ module Spree
46
46
  Spree::Tax::ItemTax.new(
47
47
  label: rate.adjustment_label(amount),
48
48
  tax_rate: rate,
49
- amount: amount,
49
+ amount:,
50
50
  included_in_price: rate.included_in_price
51
51
  )
52
52
  end
@@ -89,7 +89,7 @@ module Spree
89
89
  item_id: item.id,
90
90
  label: rate.adjustment_label(amount),
91
91
  tax_rate: rate,
92
- amount: amount,
92
+ amount:,
93
93
  included_in_price: rate.included_in_price
94
94
  )
95
95
  end
@@ -99,7 +99,7 @@ module Spree
99
99
  # @return [Array<Spree::TaxRate>] rates that apply to an order
100
100
  def rates_for_order
101
101
  tax_category_ids = Set[
102
- *@order.line_items.map(&:tax_category_id),
102
+ *@order.line_items.map(&:variant_tax_category_id),
103
103
  *@order.shipments.map(&:tax_category_id)
104
104
  ]
105
105
  rates = Spree::TaxRate.active.order_level.for_address(@order.tax_address)
@@ -35,7 +35,7 @@ module Spree
35
35
  item_id: shipping_rate.id,
36
36
  label: rate.adjustment_label(amount),
37
37
  tax_rate: rate,
38
- amount: amount
38
+ amount:
39
39
  )
40
40
  end
41
41
  end
@@ -4,6 +4,8 @@ module Spree
4
4
  class TaxCategory < Spree::Base
5
5
  include Spree::SoftDeletable
6
6
 
7
+ self.allowed_ransackable_attributes = %w[name description]
8
+
7
9
  after_discard do
8
10
  self.tax_rate_tax_categories = []
9
11
  end
@@ -28,7 +30,7 @@ module Spree
28
30
 
29
31
  def ensure_one_default
30
32
  if is_default
31
- Spree::TaxCategory.where(is_default: true).where.not(id: id).update_all(is_default: false, updated_at: Time.current)
33
+ Spree::TaxCategory.where(is_default: true).where.not(id:).update_all(is_default: false, updated_at: Time.current)
32
34
  end
33
35
  end
34
36
  end
@@ -11,10 +11,10 @@ module Spree
11
11
  include Spree::CalculatedAdjustments
12
12
  include Spree::AdjustmentSource
13
13
 
14
- enum level: {
14
+ enum :level, {
15
15
  item: 0,
16
16
  order: 1
17
- }, _suffix: true
17
+ }, suffix: true
18
18
 
19
19
  belongs_to :zone, class_name: "Spree::Zone", inverse_of: :tax_rates, optional: true
20
20
 
@@ -37,7 +37,7 @@ module Spree
37
37
  # Finds all tax rates whose zones match a given address
38
38
  scope :for_address, ->(address) { joins(:zone).merge(Spree::Zone.for_address(address)) }
39
39
  scope :for_country,
40
- ->(country) { for_address(Spree::Tax::TaxLocation.new(country: country)) }
40
+ ->(country) { for_address(Spree::Tax::TaxLocation.new(country:)) }
41
41
  scope :active, -> do
42
42
  table = arel_table
43
43
  time = Time.current
@@ -113,6 +113,10 @@ module Spree
113
113
  )
114
114
  end
115
115
 
116
+ def display_amount
117
+ amount_for_adjustment_label
118
+ end
119
+
116
120
  private
117
121
 
118
122
  def amount_for_adjustment_label
@@ -4,6 +4,9 @@ require 'spree/core/product_filters'
4
4
 
5
5
  module Spree
6
6
  class Taxon < Spree::Base
7
+ extend FriendlyId
8
+ friendly_id :permalink, use: :history, slug_column: :permalink
9
+
7
10
  acts_as_nested_set dependent: :destroy
8
11
 
9
12
  belongs_to :taxonomy, class_name: 'Spree::Taxonomy', inverse_of: :taxons
@@ -13,8 +16,7 @@ module Spree
13
16
  has_many :promotion_rule_taxons
14
17
  has_many :promotion_rules, through: :promotion_rule_taxons
15
18
 
16
- before_create :set_permalink
17
- before_update :set_permalink
19
+ before_save :set_permalink
18
20
  after_update :update_child_permalinks, if: :saved_change_to_permalink?
19
21
 
20
22
  validates :name, presence: true
@@ -121,6 +123,24 @@ module Spree
121
123
  end
122
124
  end
123
125
 
126
+ # override for {FriendlyId::Slugged#should_generate_new_friendly_id?} method,
127
+ # to control exactly when new friendly ids are set or updated
128
+ def should_generate_new_friendly_id?
129
+ permalink_changed? || super
130
+ end
131
+
132
+ # override for {FriendlyId::Slugged#normalize_friendly_id} method,
133
+ # to control over the slug format
134
+ def normalize_friendly_id(value)
135
+ return '' if value.blank?
136
+
137
+ parts = value.to_s.split('/')
138
+ last_word = parts.pop
139
+ corrected_last_word = Spree::Config.taxon_url_parametizer_class.parameterize(last_word)
140
+
141
+ (parts << corrected_last_word).join('/')
142
+ end
143
+
124
144
  private
125
145
 
126
146
  def touch_ancestors_and_taxonomy
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ class TaxonBrandSelector
5
+ BRANDS_TAXONOMY_NAME = "Brands"
6
+
7
+ def initialize(product)
8
+ @product = product
9
+ end
10
+
11
+ def call
12
+ product.taxons
13
+ .joins(:taxonomy)
14
+ .where(spree_taxonomies: { name: BRANDS_TAXONOMY_NAME })
15
+ .first
16
+ end
17
+
18
+ private
19
+
20
+ attr_reader :product
21
+ end
22
+ end
@@ -21,11 +21,11 @@ module Spree
21
21
  def set_name
22
22
  if root
23
23
  root.update_columns(
24
- name: name,
24
+ name:,
25
25
  updated_at: Time.current
26
26
  )
27
27
  else
28
- self.root = Spree::Taxon.create!(taxonomy_id: id, name: name)
28
+ self.root = Spree::Taxon.create!(taxonomy_id: id, name:)
29
29
  end
30
30
  end
31
31
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ # This service object is responsible for handling unauthorized redirects
5
+ class UnauthorizedRedirectHandler
6
+ # @param controller [ApplicationController] an instance of ApplicationController
7
+ # or its subclasses.
8
+ def initialize(controller)
9
+ @controller = controller
10
+ end
11
+
12
+ # This method is responsible for handling unauthorized redirects
13
+ def call
14
+ flash[:error] = I18n.t('spree.authorization_failure')
15
+ redirect_back(fallback_location: "/unauthorized")
16
+ end
17
+
18
+ private
19
+
20
+ attr_reader :controller
21
+
22
+ delegate :flash, :redirect_back, to: :controller
23
+ end
24
+ end
@@ -20,10 +20,9 @@ class Spree::UnitCancel < Spree::Base
20
20
 
21
21
  self.adjustment = inventory_unit.line_item.adjustments.create!(
22
22
  source: self,
23
- amount: amount,
23
+ amount:,
24
24
  order: inventory_unit.order,
25
25
  label: "#{I18n.t('spree.cancellation')} - #{reason}",
26
- eligible: true,
27
26
  finalized: true
28
27
  )
29
28
 
@@ -6,7 +6,7 @@ module Spree
6
6
  belongs_to :address, class_name: "Spree::Address", optional: true
7
7
 
8
8
  validates_uniqueness_of :address_id, scope: :user_id
9
- validates_uniqueness_of :user_id, conditions: -> { active.default_shipping }, message: :default_address_exists, if: :default?
9
+ validates_uniqueness_of :user_id, conditions: -> { default_shipping }, message: :default_address_exists, if: :default?
10
10
 
11
11
  scope :with_address_values, ->(address_attributes) do
12
12
  joins(:address).merge(
@@ -14,10 +14,16 @@ module Spree
14
14
  )
15
15
  end
16
16
 
17
- scope :all_historical, -> { unscope(where: :archived) }
17
+ scope :all_historical, -> {
18
+ Spree.deprecator.warn("The 'Spree::UserAddress.all_historical` scope does not do anything and will be removed from Solidus 5.")
19
+ all
20
+ }
18
21
  scope :default_shipping, -> { where(default: true) }
19
22
  scope :default_billing, -> { where(default_billing: true) }
20
- scope :active, -> { where(archived: false) }
23
+ scope :active, -> {
24
+ Spree.deprecator.warn("The 'Spree::UserAddress.active` scope does not do anything and will be removed from Solidus 5.")
25
+ all
26
+ }
21
27
 
22
28
  default_scope -> { order([default: :desc, updated_at: :desc]) }
23
29
  end
@@ -10,6 +10,10 @@ module Spree
10
10
  order(Arel.sql("COALESCE((SELECT COUNT(*) FROM #{Spree::LineItem.quoted_table_name} GROUP BY #{Spree::LineItem.quoted_table_name}.variant_id HAVING #{Spree::LineItem.quoted_table_name}.variant_id = #{Spree::Variant.quoted_table_name}.id), 0) DESC"))
11
11
  }
12
12
 
13
+ scope :by_stock_location, ->(stock_location_id) {
14
+ joins(:stock_locations).where(spree_stock_locations: { id: stock_location_id })
15
+ }
16
+
13
17
  class << self
14
18
  # Returns variants that match a given option value
15
19
  #
@@ -41,7 +41,7 @@ module Spree
41
41
  def find_or_initialize_price_by(country_iso, currency)
42
42
  variant.prices.detect do |price|
43
43
  price.country_iso == country_iso && price.currency == currency
44
- end || variant.prices.build(country_iso: country_iso, currency: currency)
44
+ end || variant.prices.build(country_iso:, currency:)
45
45
  end
46
46
 
47
47
  # nil is added to the array so we always have an export price.