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
@@ -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,16 @@ 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
+
45
+ # Sets this store credit's amount to a new value,
46
+ # parsing it as a localized number if the new value is a string.
47
+ #
48
+ # @param number [String, #to_d] a new amount
49
+ def amount=(number)
50
+ self[:amount] = Spree::LocalizedNumber.parse(number)
51
+ end
52
+
43
53
  def amount_remaining
44
54
  return 0.0.to_d if invalidated?
45
55
  amount - amount_used - amount_authorized
@@ -48,7 +58,7 @@ class Spree::StoreCredit < Spree::PaymentSource
48
58
  def authorize(amount, order_currency, options = {})
49
59
  authorization_code = options[:action_authorization_code]
50
60
  if authorization_code
51
- 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:)
52
62
  # Don't authorize again on capture
53
63
  return true
54
64
  end
@@ -82,7 +92,7 @@ class Spree::StoreCredit < Spree::PaymentSource
82
92
 
83
93
  def capture(amount, authorization_code, order_currency, options = {})
84
94
  return false unless authorize(amount, order_currency, action_authorization_code: authorization_code)
85
- 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:)
86
96
 
87
97
  if amount <= auth_event.amount
88
98
  if currency != order_currency
@@ -107,7 +117,7 @@ class Spree::StoreCredit < Spree::PaymentSource
107
117
  end
108
118
 
109
119
  def void(authorization_code, options = {})
110
- 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:)
111
121
  update!({
112
122
  action: VOID_ACTION,
113
123
  action_amount: auth_event.amount,
@@ -125,7 +135,7 @@ class Spree::StoreCredit < Spree::PaymentSource
125
135
 
126
136
  def credit(amount, authorization_code, order_currency, options = {})
127
137
  # Find the amount related to this authorization_code in order to add the store credit back
128
- 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:)
129
139
 
130
140
  if currency != order_currency # sanity check to make sure the order currency hasn't changed since the auth
131
141
  errors.add(:base, I18n.t('spree.store_credit.currency_mismatch'))
@@ -150,7 +160,12 @@ class Spree::StoreCredit < Spree::PaymentSource
150
160
  end
151
161
 
152
162
  def generate_authorization_code
153
- "#{id}-SC-#{Time.current.utc.strftime('%Y%m%d%H%M%S%6N')}"
163
+ [
164
+ id,
165
+ 'SC',
166
+ Time.current.utc.strftime('%Y%m%d%H%M%S%6N'),
167
+ SecureRandom.uuid
168
+ ].join('-')
154
169
  end
155
170
 
156
171
  def editable?
@@ -206,25 +221,25 @@ class Spree::StoreCredit < Spree::PaymentSource
206
221
 
207
222
  def create_credit_record_params(amount)
208
223
  {
209
- amount: amount,
210
- user_id: user_id,
211
- category_id: category_id,
212
- created_by_id: created_by_id,
213
- currency: currency,
214
- type_id: type_id,
224
+ amount:,
225
+ user_id:,
226
+ category_id:,
227
+ created_by_id:,
228
+ currency:,
229
+ type_id:,
215
230
  memo: credit_allocation_memo
216
231
  }
217
232
  end
218
233
 
219
234
  def credit_allocation_memo
220
- I18n.t("spree.store_credit.credit_allocation_memo", id: id)
235
+ I18n.t("spree.store_credit.credit_allocation_memo", id:)
221
236
  end
222
237
 
223
238
  def store_event
224
239
  return unless saved_change_to_amount? || saved_change_to_amount_used? || saved_change_to_amount_authorized? || [ELIGIBLE_ACTION, INVALIDATE_ACTION].include?(action)
225
240
 
226
241
  event = if action
227
- store_credit_events.build(action: action)
242
+ store_credit_events.build(action:)
228
243
  else
229
244
  store_credit_events.where(action: ALLOCATION_ACTION).first_or_initialize
230
245
  end
@@ -232,10 +247,10 @@ class Spree::StoreCredit < Spree::PaymentSource
232
247
  event.update!({
233
248
  amount: action_amount || amount,
234
249
  authorization_code: action_authorization_code || event.authorization_code || generate_authorization_code,
235
- amount_remaining: amount_remaining,
236
- user_total_amount: user.available_store_credit_total(currency: currency),
250
+ amount_remaining:,
251
+ user_total_amount: user.available_store_credit_total(currency:),
237
252
  originator: action_originator,
238
- store_credit_reason: store_credit_reason
253
+ store_credit_reason:
239
254
  })
240
255
  end
241
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
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ class StoreCreditPrioritizer
5
+ def initialize(credits, _order)
6
+ @credits = credits
7
+ end
8
+
9
+ def call
10
+ credits.order_by_priority
11
+ end
12
+
13
+ private
14
+
15
+ attr_reader :credits
16
+ end
17
+ end
@@ -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,9 +5,10 @@ module Spree
5
5
  # Simple object used to hold tax data for an item.
6
6
  #
7
7
  # This generic object will hold the amount of tax that should be applied to
8
- # an item. (Either a {Spree::LineItem} or a {Spree::Shipment}.)
8
+ # an item. (Either a {Spree::Order}, a {Spree::LineItem} or a {Spree::Shipment}.)
9
9
  #
10
- # @attr_reader [Integer] item_id the {Spree::LineItem} or {Spree::Shipment} ID
10
+ # @attr_reader [Integer] item_id the {Spree::LineItem} or {Spree::Shipment} ID.
11
+ # Or blank if an order-level tax.
11
12
  # @attr_reader [String] label information about the taxes
12
13
  # @attr_reader [Spree::TaxRate] tax_rate will be used as the source for tax
13
14
  # adjustments
@@ -8,13 +8,15 @@ module Spree
8
8
  # adjustments on an order.
9
9
  #
10
10
  # @attr_reader [Integer] order_id the {Spree::Order} these taxes apply to
11
+ # @attr_reader [Array<Spree::Tax::ItemTax>] order_taxes an array of tax
12
+ # data for the order
11
13
  # @attr_reader [Array<Spree::Tax::ItemTax>] line_item_taxes an array of
12
14
  # tax data for order's line items
13
15
  # @attr_reader [Array<Spree::Tax::ItemTax>] shipment_taxes an array of
14
16
  # tax data for the order's shipments
15
17
  class OrderTax
16
18
  include ActiveModel::Model
17
- attr_accessor :order_id, :line_item_taxes, :shipment_taxes
19
+ attr_accessor :order_id, :order_taxes, :line_item_taxes, :shipment_taxes
18
20
  end
19
21
  end
20
22
  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
- @rates_for_order ||= Spree::TaxRate.for_address(item.order.tax_address)
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
- @rates_for_order.select do |rate|
12
- rate.active? && rate.tax_categories.map(&:id).include?(item.tax_category_id)
22
+ @rates_for_item.select do |rate|
23
+ rate.active? && rate.tax_categories.map(&:id).include?(tax_category_id)
13
24
  end
14
25
  end
15
26
  end
@@ -8,7 +8,7 @@ module Spree
8
8
  # @attr_reader [Integer] country_id the ID of a Spree::Country object
9
9
  # @attr_reader [Integer] state_id the ID of a Spree::State object
10
10
  class TaxLocation
11
- attr_reader :country_id, :state_id
11
+ attr_reader :country, :state
12
12
 
13
13
  # Create a new TaxLocation object
14
14
  #
@@ -19,18 +19,15 @@ module Spree
19
19
  #
20
20
  # @return [Spree::Tax::TaxLocation] a Spree::Tax::TaxLocation object
21
21
  def initialize(country: nil, state: nil)
22
- @country_id = country && country.id
23
- @state_id = state && state.id
22
+ @country, @state = country, state
24
23
  end
24
+ delegate :id, to: :state, prefix: true, allow_nil: true
25
+ delegate :id, to: :country, prefix: true, allow_nil: true
25
26
 
26
27
  def ==(other)
27
28
  state_id == other.state_id && country_id == other.country_id
28
29
  end
29
30
 
30
- def country
31
- Spree::Country.find_by(id: country_id)
32
- end
33
-
34
31
  def empty?
35
32
  country_id.nil? && state_id.nil?
36
33
  end
@@ -25,6 +25,7 @@ module Spree
25
25
  def calculate
26
26
  Spree::Tax::OrderTax.new(
27
27
  order_id: order.id,
28
+ order_taxes: order_rates,
28
29
  line_item_taxes: line_item_rates,
29
30
  shipment_taxes: shipment_rates
30
31
  )
@@ -34,6 +35,23 @@ module Spree
34
35
 
35
36
  attr_reader :order
36
37
 
38
+ # Calculate the order-level taxes.
39
+ #
40
+ # @private
41
+ # @return [Array<Spree::Tax::ItemTax>] calculated taxes for the order
42
+ def order_rates
43
+ rates_for_order.map do |rate|
44
+ amount = rate.compute_amount(order)
45
+
46
+ Spree::Tax::ItemTax.new(
47
+ label: rate.adjustment_label(amount),
48
+ tax_rate: rate,
49
+ amount:,
50
+ included_in_price: rate.included_in_price
51
+ )
52
+ end
53
+ end
54
+
37
55
  # Calculate the taxes for line items.
38
56
  #
39
57
  # @private
@@ -71,11 +89,24 @@ module Spree
71
89
  item_id: item.id,
72
90
  label: rate.adjustment_label(amount),
73
91
  tax_rate: rate,
74
- amount: amount,
92
+ amount:,
75
93
  included_in_price: rate.included_in_price
76
94
  )
77
95
  end
78
96
  end
97
+
98
+ # @private
99
+ # @return [Array<Spree::TaxRate>] rates that apply to an order
100
+ def rates_for_order
101
+ tax_category_ids = Set[
102
+ *@order.line_items.map(&:variant_tax_category_id),
103
+ *@order.shipments.map(&:tax_category_id)
104
+ ]
105
+ rates = Spree::TaxRate.active.order_level.for_address(@order.tax_address)
106
+ rates.select do |rate|
107
+ tax_category_ids.intersect?(rate.tax_category_ids.to_set)
108
+ end
109
+ end
79
110
  end
80
111
  end
81
112
  end
@@ -9,7 +9,7 @@ module Spree
9
9
  # looking to provide their own calculator should adhere to the API of this
10
10
  # class.
11
11
  #
12
- # @see Spree::Tax::ShippingRateTaxer
12
+ # @see Spree::Stock::Estimator
13
13
  class ShippingRate
14
14
  include Spree::Tax::TaxHelpers
15
15
 
@@ -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,6 +11,11 @@ module Spree
11
11
  include Spree::CalculatedAdjustments
12
12
  include Spree::AdjustmentSource
13
13
 
14
+ enum :level, {
15
+ item: 0,
16
+ order: 1
17
+ }, suffix: true
18
+
14
19
  belongs_to :zone, class_name: "Spree::Zone", inverse_of: :tax_rates, optional: true
15
20
 
16
21
  has_many :tax_rate_tax_categories,
@@ -27,10 +32,12 @@ module Spree
27
32
 
28
33
  validates :amount, presence: true, numericality: true
29
34
 
35
+ self.allowed_ransackable_associations = %w[tax_categories zone]
36
+
30
37
  # Finds all tax rates whose zones match a given address
31
38
  scope :for_address, ->(address) { joins(:zone).merge(Spree::Zone.for_address(address)) }
32
39
  scope :for_country,
33
- ->(country) { for_address(Spree::Tax::TaxLocation.new(country: country)) }
40
+ ->(country) { for_address(Spree::Tax::TaxLocation.new(country:)) }
34
41
  scope :active, -> do
35
42
  table = arel_table
36
43
  time = Time.current
@@ -106,6 +113,10 @@ module Spree
106
113
  )
107
114
  end
108
115
 
116
+ def display_amount
117
+ amount_for_adjustment_label
118
+ end
119
+
109
120
  private
110
121
 
111
122
  def amount_for_adjustment_label
@@ -116,6 +127,8 @@ module Spree
116
127
  end
117
128
 
118
129
  def translation_key(_amount)
130
+ return "flat_fee" if calculator.is_a?(Spree::Calculator::FlatFee)
131
+
119
132
  key = included_in_price? ? "vat" : "sales_tax"
120
133
  key += "_with_rate" if show_rate_in_label?
121
134
  key.to_sym
@@ -6,8 +6,8 @@ module Spree::Taxon::ActiveStorageAttachment
6
6
 
7
7
  included do
8
8
  has_attachment :icon,
9
- styles: { mini: '32x32>', normal: '128x128>' },
10
- default_style: :mini
9
+ styles: Spree::Config.taxon_image_styles,
10
+ default_style: Spree::Config.taxon_image_style_default
11
11
  validate :icon_is_an_image
12
12
  end
13
13
  end
@@ -5,14 +5,14 @@ module Spree::Taxon::PaperclipAttachment
5
5
 
6
6
  included do
7
7
  has_attached_file :icon,
8
- styles: { mini: '32x32>', normal: '128x128>' },
9
- default_style: :mini,
8
+ styles: Spree::Config.taxon_image_styles,
9
+ default_style: Spree::Config.taxon_image_style_default,
10
10
  url: '/spree/taxons/:id/:style/:basename.:extension',
11
11
  path: ':rails_root/public/spree/taxons/:id/:style/:basename.:extension',
12
12
  default_url: '/assets/default_taxon.png'
13
13
 
14
14
  validates_attachment :icon,
15
- content_type: { content_type: %w[image/jpg image/jpeg image/png image/gif] }
15
+ content_type: { content_type: Spree::Config.allowed_image_mime_types }
16
16
  end
17
17
 
18
18
  def icon_present?
@@ -25,6 +25,6 @@ module Spree::Taxon::PaperclipAttachment
25
25
  attached_file = send(definition)
26
26
  return false unless attached_file.exists?
27
27
 
28
- attached_file.destroy
28
+ attached_file.destroy && save
29
29
  end
30
30
  end
@@ -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,21 +16,22 @@ 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
23
+ validates :name, uniqueness: { scope: :parent_id, message: :must_be_unique_under_same_parent }
21
24
  validates :meta_keywords, length: { maximum: 255 }
22
25
  validates :meta_description, length: { maximum: 255 }
23
26
  validates :meta_title, length: { maximum: 255 }
27
+ validates :taxonomy_id, uniqueness: { scope: :parent_id, message: :can_have_only_one_root }, if: -> { root? }
24
28
 
25
29
  after_save :touch_ancestors_and_taxonomy
26
30
  after_touch :touch_ancestors_and_taxonomy
27
31
 
28
32
  include ::Spree::Config.taxon_attachment_module
29
33
 
30
- self.whitelisted_ransackable_attributes = %w[name]
34
+ self.allowed_ransackable_attributes = %w[name]
31
35
 
32
36
  # @return [String] meta_title if set otherwise a string containing the
33
37
  # root name and taxon name
@@ -119,6 +123,24 @@ module Spree
119
123
  end
120
124
  end
121
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
+
122
144
  private
123
145
 
124
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
@@ -5,6 +5,7 @@ module Spree
5
5
  acts_as_list
6
6
 
7
7
  validates :name, presence: true
8
+ validates :name, uniqueness: true
8
9
 
9
10
  has_many :taxons, inverse_of: :taxonomy
10
11
  has_one :root, -> { where parent_id: nil }, class_name: "Spree::Taxon", dependent: :destroy
@@ -13,18 +14,18 @@ module Spree
13
14
 
14
15
  default_scope -> { order(position: :asc) }
15
16
 
16
- self.whitelisted_ransackable_attributes = %w[name]
17
+ self.allowed_ransackable_attributes = %w[name]
17
18
 
18
19
  private
19
20
 
20
21
  def set_name
21
22
  if root
22
23
  root.update_columns(
23
- name: name,
24
+ name:,
24
25
  updated_at: Time.current
25
26
  )
26
27
  else
27
- self.root = Spree::Taxon.create!(taxonomy_id: id, name: name)
28
+ self.root = Spree::Taxon.create!(taxonomy_id: id, name:)
28
29
  end
29
30
  end
30
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
@@ -4,7 +4,7 @@ module Spree
4
4
  class UserLastUrlStorer
5
5
  module Rules
6
6
  # This is the basic rule that ships with Solidus that avoids storing in
7
- # session the current path for login/loout/signup routes, avoiding possibly
7
+ # session the current path for login/logout/signup routes, avoiding possibly
8
8
  # infinte redirects.
9
9
  module AuthenticationRule
10
10
  AUTHENTICATION_ROUTES = %w[spree_signup_path spree_login_path spree_logout_path]