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
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ module Core
5
+ class StateMachines
6
+ module ReturnItem
7
+ # Return Items' reception status state machine
8
+ #
9
+ # for each event the following instance methods are dynamically implemented:
10
+ # #<event_name>
11
+ # #<event_name>!
12
+ # #can_<event_name>?
13
+ #
14
+ # for each state the following instance methods are implemented:
15
+ # #<state_name>?
16
+ #
17
+ module ReceptionStatus
18
+ extend ActiveSupport::Concern
19
+
20
+ included do
21
+ state_machine :reception_status, initial: :awaiting do
22
+ after_transition to: ::Spree::ReturnItem::COMPLETED_RECEPTION_STATUSES, do: :attempt_accept, if: :can_attempt_accept?
23
+ after_transition to: ::Spree::ReturnItem::COMPLETED_RECEPTION_STATUSES, do: :check_unexchange
24
+ after_transition to: :received, do: :process_inventory_unit!
25
+
26
+ event(:cancel) { transition to: :cancelled, from: :awaiting }
27
+
28
+ event(:receive) { transition to: :received, from: ::Spree::ReturnItem::INTERMEDIATE_RECEPTION_STATUSES + [:awaiting] }
29
+ event(:unexchange) { transition to: :unexchanged, from: [:awaiting] }
30
+ event(:give) { transition to: :given_to_customer, from: :awaiting }
31
+ event(:lost) { transition to: :lost_in_transit, from: :awaiting }
32
+ event(:wrong_item_shipped) { transition to: :shipped_wrong_item, from: :awaiting }
33
+ event(:short_shipped) { transition to: :short_shipped, from: :awaiting }
34
+ event(:in_transit) { transition to: :in_transit, from: :awaiting }
35
+ event(:expired) { transition to: :expired, from: :awaiting }
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ module Core
5
+ class StateMachines
6
+ # Shipments' state machine
7
+ #
8
+ # for each event the following instance methods are dynamically implemented:
9
+ # #<event_name>
10
+ # #<event_name>!
11
+ # #can_<event_name>?
12
+ #
13
+ # for each state the following instance methods are implemented:
14
+ # #<state_name>?
15
+ #
16
+ module Shipment
17
+ extend ActiveSupport::Concern
18
+
19
+ included do
20
+ state_machine initial: :pending, use_transactions: false do
21
+ event :ready do
22
+ transition from: :pending, to: :shipped, if: :can_transition_from_pending_to_shipped?
23
+ transition from: :pending, to: :ready, if: :can_transition_from_pending_to_ready?
24
+ end
25
+
26
+ event :pend do
27
+ transition from: :ready, to: :pending
28
+ end
29
+
30
+ event :ship do
31
+ transition from: [:ready, :canceled], to: :shipped
32
+ end
33
+ after_transition to: :shipped, do: :after_ship
34
+
35
+ event :cancel do
36
+ transition to: :canceled, from: [:pending, :ready]
37
+ end
38
+ after_transition to: :canceled, do: :after_cancel
39
+
40
+ event :resume do
41
+ transition from: :canceled, to: :ready, if: :can_transition_from_canceled_to_ready?
42
+ transition from: :canceled, to: :pending
43
+ end
44
+ after_transition from: :canceled, to: [:pending, :ready, :shipped], do: :after_resume
45
+
46
+ after_transition do |shipment, transition|
47
+ shipment.state_changes.create!(
48
+ previous_state: transition.from,
49
+ next_state: transition.to,
50
+ name: 'shipment'
51
+ )
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -8,7 +8,7 @@ module Spree
8
8
 
9
9
  validates :name, :iso_name, presence: true
10
10
 
11
- self.whitelisted_ransackable_attributes = %w[name]
11
+ self.allowed_ransackable_attributes = %w[name]
12
12
 
13
13
  def self.default
14
14
  find_by!(iso: Spree::Config.default_country_iso)
@@ -21,9 +21,6 @@ module Spree
21
21
 
22
22
  scope :with_payment_profile, -> { where('gateway_customer_profile_id IS NOT NULL') }
23
23
 
24
- # needed for some of the ActiveMerchant gateways (eg. SagePay)
25
- alias_attribute :brand, :cc_type
26
-
27
24
  # Taken from ActiveMerchant
28
25
  # https://github.com/activemerchant/active_merchant/blob/2f2acd4696e8de76057b5ed670b9aa022abc1187/lib/active_merchant/billing/credit_card_methods.rb#L5
29
26
  CARD_TYPES = {
@@ -95,9 +92,15 @@ module Spree
95
92
  end
96
93
  end
97
94
 
95
+ # needed for some of the ActiveMerchant gateways (eg. SagePay)
96
+ alias_attribute :brand, :cc_type
97
+
98
+ # Rails 7.1+ won't use the custom setter with alias_attribute
99
+ alias_method :brand=, :cc_type=
100
+
98
101
  # Sets the last digits field based on the assigned credit card number.
99
102
  def set_last_digits
100
- self.last_digits ||= number.to_s.length <= 4 ? number : number.to_s.slice(-4..-1)
103
+ self.last_digits ||= number.to_s.length <= 4 ? number : number.to_s.slice(-4..)
101
104
  end
102
105
 
103
106
  # @return [String] the credit card type if it can be determined from the
@@ -152,12 +155,12 @@ module Spree
152
155
  # card that represents this credit card
153
156
  def to_active_merchant
154
157
  ActiveMerchant::Billing::CreditCard.new(
155
- number: number,
156
- month: month,
157
- year: year,
158
- verification_value: verification_value,
159
- first_name: first_name,
160
- last_name: last_name
158
+ number:,
159
+ month:,
160
+ year:,
161
+ verification_value:,
162
+ first_name:,
163
+ last_name:
161
164
  )
162
165
  end
163
166
 
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Spree
4
4
  class CustomerReturn < Spree::Base
5
+ include Metadata
6
+
5
7
  belongs_to :stock_location, optional: true
6
8
 
7
9
  has_many :return_items, inverse_of: :customer_return
@@ -17,7 +19,7 @@ module Spree
17
19
 
18
20
  accepts_nested_attributes_for :return_items
19
21
 
20
- self.whitelisted_ransackable_attributes = ['number']
22
+ self.allowed_ransackable_attributes = ['number']
21
23
 
22
24
  extend DisplayMoney
23
25
  money_methods :total, :total_excluding_vat, :amount
@@ -40,7 +42,8 @@ module Spree
40
42
  # Temporarily tie a customer_return to one order
41
43
  def order
42
44
  return nil if return_items.blank?
43
- return_items.first.inventory_unit.order
45
+
46
+ return_items.first.inventory_unit&.order
44
47
  end
45
48
 
46
49
  def fully_reimbursed?
@@ -65,7 +68,7 @@ module Spree
65
68
  end
66
69
 
67
70
  def return_items_belong_to_same_order
68
- if return_items.reject{ |return_item| return_item.inventory_unit.order_id == order_id }.any?
71
+ if return_items.reject{ |return_item| return_item.inventory_unit&.order_id == order_id }.any?
69
72
  errors.add(:base, I18n.t('spree.return_items_cannot_be_associated_with_multiple_orders'))
70
73
  end
71
74
  end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ class DeprecatedConfigurableClass
5
+ def self.new(*_args, &_block)
6
+ @deprecation_proxy ||= DeprecationProxy.new
7
+ end
8
+
9
+ def self.method_missing(method_name, *args, &block)
10
+ @deprecation_proxy ||= DeprecationProxy.new
11
+ @deprecation_proxy.send(method_name, args, block)
12
+ end
13
+
14
+ def self.respond_to_missing?(_method_name, _include_private = false)
15
+ true
16
+ end
17
+
18
+ class DeprecationProxy
19
+ def method_missing(_method_name, *_args, &_block)
20
+ issue_deprecation_warning
21
+ self
22
+ end
23
+
24
+ def respond_to_missing?(_method_name, _include_private = false)
25
+ true
26
+ end
27
+
28
+ private
29
+
30
+ def issue_deprecation_warning
31
+ Spree.deprecator.warn(
32
+ <<-WARNING
33
+ It appears you are using Solidus' Legacy promotion system. This system has been extracted into the
34
+ `solidus_legacy_promotions` gem. Please add the gem to your Gemfile and follow in the instructions in the README.
35
+ WARNING
36
+ )
37
+ end
38
+ end
39
+ end
40
+ end
@@ -20,15 +20,16 @@ module Spree
20
20
  include ActiveModel::Validations
21
21
 
22
22
  attr_accessor :current_shipment, :desired_shipment
23
- attr_reader :variant, :quantity, :current_stock_location, :desired_stock_location
23
+ attr_reader :variant, :quantity, :current_stock_location, :desired_stock_location, :track_inventory
24
24
 
25
- def initialize(current_shipment:, desired_shipment:, variant:, quantity:)
25
+ def initialize(current_shipment:, desired_shipment:, variant:, quantity:, track_inventory:)
26
26
  @current_shipment = current_shipment
27
27
  @desired_shipment = desired_shipment
28
28
  @current_stock_location = current_shipment.stock_location
29
29
  @desired_stock_location = desired_shipment.stock_location
30
30
  @variant = variant
31
31
  @quantity = quantity
32
+ @track_inventory = track_inventory
32
33
  end
33
34
 
34
35
  validates :quantity, numericality: { greater_than: 0 }
@@ -45,6 +46,45 @@ module Spree
45
46
  return false if invalid?
46
47
  desired_shipment.save! if desired_shipment.new_record?
47
48
 
49
+ if track_inventory
50
+ run_tracking_inventory
51
+ else
52
+ run_without_tracking_inventory
53
+ end
54
+
55
+ # We modified the inventory units at the database level for speed reasons.
56
+ # The downside of that is that we need to reload the associations.
57
+ current_shipment.inventory_units.reload
58
+ desired_shipment.inventory_units.reload
59
+
60
+ # If the current shipment now has no inventory units left, we won't need it any longer.
61
+ if current_shipment.inventory_units.length.zero?
62
+ current_shipment.destroy!
63
+ else
64
+ # The current shipment has changed, so we need to make sure that shipping rates
65
+ # have the correct amount.
66
+ current_shipment.refresh_rates
67
+ end
68
+
69
+ # The desired shipment has also change, so we need to make sure shipping rates
70
+ # are up-to-date, too.
71
+ desired_shipment.refresh_rates
72
+
73
+ # In order to reflect the changes in the order totals
74
+ desired_shipment.order.reload
75
+ desired_shipment.order.recalculate
76
+
77
+ true
78
+ end
79
+
80
+ private
81
+
82
+ # When moving things from one stock location to another, we need to restock items
83
+ # from the current location and unstock them at the desired location.
84
+ # Also, when we want to track inventory changes, we need to make sure that we have
85
+ # enough stock at the desired location to fulfil the order. Based on how many items
86
+ # we can take from the desired location, we could end up with some items being backordered.
87
+ def run_tracking_inventory
48
88
  # Retrieve how many on hand items we can take from desired stock location
49
89
  available_quantity = [desired_shipment.stock_location.count_on_hand(variant), default_on_hand_quantity].max
50
90
 
@@ -67,46 +107,33 @@ module Spree
67
107
  # We order by state, because `'backordered' < 'on_hand'`.
68
108
  current_shipment.
69
109
  inventory_units.
70
- where(variant: variant).
110
+ where(variant:).
71
111
  order(state: :asc).
72
112
  limit(new_on_hand_quantity).
73
113
  update_all(shipment_id: desired_shipment.id, state: :on_hand)
74
114
 
75
115
  current_shipment.
76
116
  inventory_units.
77
- where(variant: variant).
117
+ where(variant:).
78
118
  order(state: :asc).
79
119
  limit(quantity - new_on_hand_quantity).
80
120
  update_all(shipment_id: desired_shipment.id, state: :backordered)
81
121
  end
122
+ end
82
123
 
83
- # We modified the inventory units at the database level for speed reasons.
84
- # The downside of that is that we need to reload the associations.
85
- current_shipment.inventory_units.reload
86
- desired_shipment.inventory_units.reload
87
-
88
- # If the current shipment now has no inventory units left, we won't need it any longer.
89
- if current_shipment.inventory_units.length.zero?
90
- current_shipment.destroy!
91
- else
92
- # The current shipment has changed, so we need to make sure that shipping rates
93
- # have the correct amount.
94
- current_shipment.refresh_rates
124
+ # When we don't track inventory, we can just move the inventory units from one shipment
125
+ # to the other.
126
+ def run_without_tracking_inventory
127
+ ActiveRecord::Base.transaction do
128
+ current_shipment.
129
+ inventory_units.
130
+ where(variant:).
131
+ order(state: :asc).
132
+ limit(quantity).
133
+ update_all(shipment_id: desired_shipment.id)
95
134
  end
96
-
97
- # The desired shipment has also change, so we need to make sure shipping rates
98
- # are up-to-date, too.
99
- desired_shipment.refresh_rates
100
-
101
- # In order to reflect the changes in the order totals
102
- desired_shipment.order.reload
103
- desired_shipment.order.recalculate
104
-
105
- true
106
135
  end
107
136
 
108
- private
109
-
110
137
  # We don't need to handle stock counts for incomplete orders. Also, if
111
138
  # the new shipment and the desired shipment will ship from the same stock location,
112
139
  # unstocking and restocking will not be necessary.
@@ -118,7 +145,7 @@ module Spree
118
145
  if current_stock_location != desired_stock_location
119
146
  0
120
147
  else
121
- current_shipment.inventory_units.where(variant: variant).on_hand.count
148
+ current_shipment.inventory_units.where(variant:).on_hand.count
122
149
  end
123
150
  end
124
151
 
@@ -12,13 +12,8 @@ module Spree::Image::ActiveStorageAttachment
12
12
  validate :supported_content_type
13
13
 
14
14
  has_attachment :attachment,
15
- styles: {
16
- mini: '48x48>',
17
- small: '400x400>',
18
- product: '680x680>',
19
- large: '1200x1200>'
20
- },
21
- default_style: :product
15
+ styles: Spree::Config.product_image_styles,
16
+ default_style: Spree::Config.product_image_style_default
22
17
 
23
18
  def supported_content_type
24
19
  unless attachment.content_type.in?(Spree::Config.allowed_image_mime_types)
@@ -7,8 +7,8 @@ module Spree::Image::PaperclipAttachment
7
7
  validate :no_attachment_errors
8
8
 
9
9
  has_attached_file :attachment,
10
- styles: { mini: '48x48>', small: '400x400>', product: '680x680>', large: '1200x1200>' },
11
- default_style: :product,
10
+ styles: Spree::Config.product_image_styles,
11
+ default_style: Spree::Config.product_image_style_default,
12
12
  default_url: 'noimage/:style.png',
13
13
  url: '/spree/products/:id/:style/:basename.:extension',
14
14
  path: ':rails_root/public/spree/products/:id/:style/:basename.:extension',
@@ -64,7 +64,7 @@ module Spree
64
64
  # stock location that is associated with this inventory unit's variant
65
65
  def find_stock_item
66
66
  Spree::StockItem.where(stock_location_id: shipment.stock_location_id,
67
- variant_id: variant_id).first
67
+ variant_id:).first
68
68
  end
69
69
 
70
70
  # @return [Spree::ReturnItem] a valid return item for this inventory unit
@@ -114,7 +114,7 @@ module Spree
114
114
 
115
115
  def ensure_can_destroy
116
116
  if !backordered? && !on_hand?
117
- errors.add(:state, :cannot_destroy, state: state)
117
+ errors.add(:state, :cannot_destroy, state:)
118
118
  throw :abort
119
119
  end
120
120
 
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Spree::ItemTotal
4
+ def initialize(item)
5
+ @item = item
6
+ end
7
+
8
+ def recalculate!
9
+ tax_adjustments = item.adjustments.select do |adjustment|
10
+ adjustment.tax? && !adjustment.marked_for_destruction?
11
+ end
12
+
13
+ # Included tax adjustments are those which are included in the price.
14
+ # These ones should not affect the eventual total price.
15
+ #
16
+ # Additional tax adjustments are the opposite, affecting the final total.
17
+ item.included_tax_total = tax_adjustments.select(&:included?).sum(&:amount)
18
+ item.additional_tax_total = tax_adjustments.reject(&:included?).sum(&:amount)
19
+
20
+ item.adjustment_total = item.adjustments.reject { |adjustment|
21
+ adjustment.marked_for_destruction? || adjustment.included?
22
+ }.sum(&:amount)
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :item
28
+ end
@@ -7,6 +7,7 @@ module Spree
7
7
  # spree_auth_devise)
8
8
  class LegacyUser < Spree::Base
9
9
  include UserMethods
10
+ include Metadata
10
11
 
11
12
  self.table_name = 'spree_users'
12
13
 
@@ -10,6 +10,8 @@ module Spree
10
10
  # promotion system.
11
11
  #
12
12
  class LineItem < Spree::Base
13
+ include Metadata
14
+
13
15
  belongs_to :order, class_name: "Spree::Order", inverse_of: :line_items, touch: true, optional: true
14
16
  belongs_to :variant, -> { with_discarded }, class_name: "Spree::Variant", inverse_of: :line_items, optional: true
15
17
  belongs_to :tax_category, class_name: "Spree::TaxCategory", optional: true
@@ -19,9 +21,6 @@ module Spree
19
21
  has_many :adjustments, as: :adjustable, inverse_of: :adjustable, dependent: :destroy
20
22
  has_many :inventory_units, inverse_of: :line_item
21
23
 
22
- has_many :line_item_actions, dependent: :destroy
23
- has_many :actions, through: :line_item_actions
24
-
25
24
  before_validation :normalize_quantity
26
25
  before_validation :set_required_attributes
27
26
 
@@ -39,12 +38,13 @@ module Spree
39
38
  before_destroy :destroy_inventory_units
40
39
 
41
40
  delegate :name, :description, :sku, :should_track_inventory?, to: :variant
41
+ delegate :tax_category, :tax_category_id, to: :variant, prefix: true
42
42
  delegate :currency, to: :order, allow_nil: true
43
43
 
44
44
  attr_accessor :target_shipment, :price_currency
45
45
 
46
- self.whitelisted_ransackable_associations = ['variant']
47
- self.whitelisted_ransackable_attributes = ['variant_id']
46
+ self.allowed_ransackable_associations = ['variant']
47
+ self.allowed_ransackable_attributes = ['variant_id']
48
48
 
49
49
  # @return [BigDecimal] the amount of this line item, which is the line
50
50
  # item's price multiplied by its quantity.
@@ -62,7 +62,7 @@ module Spree
62
62
  # @return [BigDecimal] the amount of this item, taking into consideration
63
63
  # all non-tax adjustments.
64
64
  def total_before_tax
65
- amount + adjustments.select { |value| !value.tax? && value.eligible? }.sum(&:amount)
65
+ amount + adjustments.reject(&:tax?).sum(&:amount)
66
66
  end
67
67
 
68
68
  # @return [BigDecimal] the amount of this line item before VAT tax
@@ -123,7 +123,7 @@ module Spree
123
123
  # a price for this line item, even if there is no existing price
124
124
  # for the associated line item in the order currency.
125
125
  unless options.key?(:price) || options.key?('price')
126
- self.money_price = variant.price_for(pricing_options)
126
+ self.money_price = variant.price_for_options(pricing_options)&.money
127
127
  end
128
128
  end
129
129
 
@@ -131,6 +131,24 @@ module Spree
131
131
  Spree::Config.pricing_options_class.from_line_item(self)
132
132
  end
133
133
 
134
+ # @return [Spree::TaxCategory] the variant's tax category
135
+ #
136
+ # This returns the variant's tax category if the tax category ID on the line_item is nil. It looks
137
+ # like an association, but really is an override.
138
+ #
139
+ def tax_category
140
+ super || variant_tax_category
141
+ end
142
+
143
+ # @return [Integer] the variant's tax category ID
144
+ #
145
+ # This returns the variant's tax category ID if the tax category ID on the line_id is nil. It looks
146
+ # like an association, but really is an override.
147
+ #
148
+ def tax_category_id
149
+ super || variant_tax_category_id
150
+ end
151
+
134
152
  private
135
153
 
136
154
  # Sets the quantity to zero if it is nil or less than zero.
@@ -149,7 +167,7 @@ module Spree
149
167
  # Set price, cost_price and currency.
150
168
  def set_pricing_attributes
151
169
  self.cost_price ||= variant.cost_price
152
- self.money_price = variant.price_for(pricing_options) if price.nil?
170
+ self.money_price = variant.price_for_options(pricing_options)&.money if price.nil?
153
171
  true
154
172
  end
155
173
 
@@ -2,10 +2,107 @@
2
2
 
3
3
  module Spree
4
4
  class LogEntry < Spree::Base
5
+ # Classes used in core that can be present in serialized details
6
+ #
7
+ # Users can add their own classes in
8
+ # `Spree::Config#log_entry_permitted_classes`.
9
+ #
10
+ # @see Spree::AppConfiguration#log_entry_permitted_classes
11
+ CORE_PERMITTED_CLASSES = [
12
+ ActiveMerchant::Billing::Response,
13
+ ActiveSupport::TimeWithZone,
14
+ Time,
15
+ ActiveSupport::TimeZone
16
+ ].freeze
17
+
18
+ class SerializationError < RuntimeError
19
+ attr_reader :psych_exception
20
+
21
+ def initialize(psych_exception:)
22
+ @psych_exception = psych_exception
23
+ super(default_message)
24
+ end
25
+ end
26
+
27
+ # Raised when a disallowed class is tried to be loaded
28
+ class DisallowedClass < SerializationError
29
+ private
30
+
31
+ def default_message
32
+ <<~MSG
33
+ #{psych_exception.message}
34
+
35
+ You can specify custom classes to be loaded in config/initializers/spree.rb. E.g:
36
+
37
+ Spree.config do |config|
38
+ config.log_entry_permitted_classes = ['MyClass']
39
+ end
40
+ MSG
41
+ end
42
+ end
43
+
44
+ # Raised when YAML contains aliases and they're not enabled
45
+ class BadAlias < SerializationError
46
+ private
47
+
48
+ def default_message
49
+ <<~MSG
50
+ #{psych_exception.message}
51
+
52
+ You can explicitly enable aliases in config/initializers/spree.rb. E.g:
53
+
54
+ Spree.config do |config|
55
+ config.log_entry_allow_aliases = true
56
+ end
57
+ MSG
58
+ end
59
+ end
60
+
61
+ def self.permitted_classes
62
+ CORE_PERMITTED_CLASSES + Spree::Config.log_entry_permitted_classes.map(&:constantize)
63
+ end
64
+
5
65
  belongs_to :source, polymorphic: true, optional: true
6
66
 
7
67
  def parsed_details
8
- @details ||= YAML.load(details)
68
+ handle_psych_serialization_errors do
69
+ @details ||= YAML.safe_load(
70
+ details,
71
+ permitted_classes: self.class.permitted_classes,
72
+ aliases: Spree::Config.log_entry_allow_aliases,
73
+ )
74
+ end
75
+ end
76
+
77
+ def parsed_details=(value)
78
+ handle_psych_serialization_errors do
79
+ self.details = YAML.safe_dump(
80
+ value,
81
+ permitted_classes: self.class.permitted_classes,
82
+ aliases: Spree::Config.log_entry_allow_aliases,
83
+ )
84
+ end
85
+ end
86
+
87
+ def parsed_payment_response_details_with_fallback=(response)
88
+ self.parsed_details = response
89
+ rescue SerializationError, YAML::Exception => e
90
+ # Fall back on wrapping the response and signaling the error to the end user.
91
+ self.parsed_details = ActiveMerchant::Billing::Response.new(
92
+ response.success?,
93
+ "[WARNING: An error occurred while trying to serialize the payment response] #{response.message}",
94
+ { 'data' => response.inspect, 'error' => e.message.to_s },
95
+ )
96
+ end
97
+
98
+ private
99
+
100
+ def handle_psych_serialization_errors
101
+ yield
102
+ rescue Psych::DisallowedClass => e
103
+ raise DisallowedClass.new(psych_exception: e)
104
+ rescue Psych::BadAlias => e
105
+ raise BadAlias.new(psych_exception: e)
9
106
  end
10
107
  end
11
108
  end