solidus_core 4.6.1 → 4.7.0

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 (331) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +13 -13
  3. data/app/controllers/spree/base_controller.rb +2 -2
  4. data/app/helpers/spree/base_helper.rb +24 -24
  5. data/app/helpers/spree/checkout_helper.rb +7 -7
  6. data/app/helpers/spree/core/controller_helpers/auth.rb +1 -1
  7. data/app/helpers/spree/core/controller_helpers/common.rb +3 -2
  8. data/app/helpers/spree/core/controller_helpers/order.rb +3 -5
  9. data/app/helpers/spree/core/controller_helpers/payment_parameters.rb +1 -2
  10. data/app/helpers/spree/core/controller_helpers/strong_parameters.rb +10 -10
  11. data/app/helpers/spree/products_helper.rb +5 -5
  12. data/app/helpers/spree/store_helper.rb +1 -1
  13. data/app/mailers/spree/carton_mailer.rb +3 -3
  14. data/app/mailers/spree/order_mailer.rb +4 -4
  15. data/app/mailers/spree/reimbursement_mailer.rb +2 -2
  16. data/app/models/concerns/spree/active_storage_adapter/attachment.rb +5 -5
  17. data/app/models/concerns/spree/active_storage_adapter/normalization.rb +5 -5
  18. data/app/models/concerns/spree/active_storage_adapter.rb +2 -2
  19. data/app/models/concerns/spree/adjustment_source.rb +4 -4
  20. data/app/models/concerns/spree/display_money.rb +2 -2
  21. data/app/models/concerns/spree/named_type.rb +1 -1
  22. data/app/models/concerns/spree/ordered_property_value_list.rb +2 -2
  23. data/app/models/concerns/spree/preferences/persistable.rb +1 -1
  24. data/app/models/concerns/spree/ransackable_attributes.rb +1 -0
  25. data/app/models/concerns/spree/soft_deletable.rb +2 -1
  26. data/app/models/concerns/spree/state_change_tracking.rb +11 -7
  27. data/app/models/concerns/spree/user_address_book.rb +12 -12
  28. data/app/models/concerns/spree/user_methods.rb +9 -9
  29. data/app/models/concerns/spree/user_reporting.rb +1 -0
  30. data/app/models/spree/ability.rb +1 -1
  31. data/app/models/spree/address/name.rb +1 -1
  32. data/app/models/spree/address.rb +7 -7
  33. data/app/models/spree/adjustment.rb +11 -10
  34. data/app/models/spree/adjustment_reason.rb +2 -2
  35. data/app/models/spree/billing_integration.rb +2 -2
  36. data/app/models/spree/calculator/default_tax.rb +2 -2
  37. data/app/models/spree/calculator/flat_fee.rb +1 -1
  38. data/app/models/spree/calculator/flat_rate.rb +2 -2
  39. data/app/models/spree/calculator/returns/default_refund_amount.rb +3 -3
  40. data/app/models/spree/calculator/shipping/flat_percent_item_total.rb +2 -2
  41. data/app/models/spree/calculator/shipping/flat_rate.rb +3 -3
  42. data/app/models/spree/calculator/shipping/flexi_rate.rb +8 -8
  43. data/app/models/spree/calculator/shipping/per_item.rb +3 -3
  44. data/app/models/spree/calculator/shipping/price_sack.rb +3 -3
  45. data/app/models/spree/calculator.rb +31 -6
  46. data/app/models/spree/carton.rb +4 -4
  47. data/app/models/spree/classification.rb +2 -2
  48. data/app/models/spree/core/state_machines/order/class_methods.rb +3 -3
  49. data/app/models/spree/core/state_machines/return_item/acceptance_status.rb +1 -1
  50. data/app/models/spree/country.rb +1 -1
  51. data/app/models/spree/credit_card.rb +27 -27
  52. data/app/models/spree/customer_return.rb +5 -4
  53. data/app/models/spree/distributed_amounts_handler.rb +1 -1
  54. data/app/models/spree/fulfilment_changer.rb +22 -22
  55. data/app/models/spree/image/active_storage_attachment.rb +2 -2
  56. data/app/models/spree/image/paperclip_attachment.rb +8 -8
  57. data/app/models/spree/in_memory_order_updater.rb +262 -0
  58. data/app/models/spree/inventory_unit.rb +11 -11
  59. data/app/models/spree/item_total.rb +1 -1
  60. data/app/models/spree/legacy_user.rb +2 -2
  61. data/app/models/spree/line_item.rb +21 -11
  62. data/app/models/spree/log_entry.rb +3 -3
  63. data/app/models/spree/mergeable_orders_finder.rb +44 -0
  64. data/app/models/spree/money.rb +2 -1
  65. data/app/models/spree/null_promotion_adjuster.rb +1 -1
  66. data/app/models/spree/option_type.rb +1 -1
  67. data/app/models/spree/option_value.rb +2 -2
  68. data/app/models/spree/order/number_generator.rb +1 -1
  69. data/app/models/spree/order.rb +66 -64
  70. data/app/models/spree/order_cancellations.rb +1 -3
  71. data/app/models/spree/order_inventory.rb +5 -8
  72. data/app/models/spree/order_mutex.rb +1 -1
  73. data/app/models/spree/order_shipping.rb +1 -1
  74. data/app/models/spree/order_updater.rb +59 -37
  75. data/app/models/spree/payment/cancellation.rb +2 -2
  76. data/app/models/spree/payment/processing.rb +22 -22
  77. data/app/models/spree/payment.rb +26 -26
  78. data/app/models/spree/payment_capture_event.rb +2 -2
  79. data/app/models/spree/payment_create.rb +1 -1
  80. data/app/models/spree/payment_method/bogus_credit_card.rb +18 -18
  81. data/app/models/spree/payment_method/check.rb +3 -3
  82. data/app/models/spree/payment_method/credit_card.rb +1 -1
  83. data/app/models/spree/payment_method/simple_bogus_credit_card.rb +3 -3
  84. data/app/models/spree/payment_method/store_credit.rb +13 -13
  85. data/app/models/spree/payment_method.rb +12 -11
  86. data/app/models/spree/payment_source.rb +2 -2
  87. data/app/models/spree/permission_sets/dashboard_display.rb +3 -3
  88. data/app/models/spree/permission_sets/default_customer.rb +1 -1
  89. data/app/models/spree/preference.rb +1 -1
  90. data/app/models/spree/price.rb +7 -6
  91. data/app/models/spree/product/scopes.rb +23 -23
  92. data/app/models/spree/product.rb +37 -41
  93. data/app/models/spree/product_option_type.rb +2 -2
  94. data/app/models/spree/product_property.rb +3 -3
  95. data/app/models/spree/refund.rb +10 -10
  96. data/app/models/spree/refund_reason.rb +2 -2
  97. data/app/models/spree/reimbursement/credit.rb +1 -1
  98. data/app/models/spree/reimbursement.rb +8 -8
  99. data/app/models/spree/reimbursement_tax_calculator.rb +1 -1
  100. data/app/models/spree/reimbursement_type/reimbursement_helpers.rb +1 -1
  101. data/app/models/spree/reimbursement_type.rb +2 -2
  102. data/app/models/spree/return_authorization.rb +7 -6
  103. data/app/models/spree/return_item/eligibility_validator/base_validator.rb +2 -2
  104. data/app/models/spree/return_item/eligibility_validator/default.rb +1 -1
  105. data/app/models/spree/return_item/eligibility_validator/inventory_shipped.rb +1 -1
  106. data/app/models/spree/return_item/eligibility_validator/no_reimbursements.rb +1 -1
  107. data/app/models/spree/return_item/eligibility_validator/order_completed.rb +1 -1
  108. data/app/models/spree/return_item/eligibility_validator/rma_required.rb +1 -1
  109. data/app/models/spree/return_item/eligibility_validator/time_since_purchase.rb +1 -1
  110. data/app/models/spree/return_item/exchange_variant_eligibility/same_option_value.rb +6 -6
  111. data/app/models/spree/return_item.rb +31 -30
  112. data/app/models/spree/return_reason.rb +1 -1
  113. data/app/models/spree/role.rb +1 -1
  114. data/app/models/spree/role_user.rb +1 -1
  115. data/app/models/spree/shipment.rb +37 -29
  116. data/app/models/spree/shipping_method.rb +9 -9
  117. data/app/models/spree/shipping_method_category.rb +2 -2
  118. data/app/models/spree/shipping_rate.rb +12 -10
  119. data/app/models/spree/shipping_rate_tax.rb +5 -4
  120. data/app/models/spree/simple_order_contents.rb +2 -2
  121. data/app/models/spree/state.rb +1 -1
  122. data/app/models/spree/state_change_tracker.rb +31 -0
  123. data/app/models/spree/stock/availability.rb +9 -9
  124. data/app/models/spree/stock/availability_validator.rb +3 -3
  125. data/app/models/spree/stock/differentiator.rb +2 -2
  126. data/app/models/spree/stock/estimator.rb +4 -4
  127. data/app/models/spree/stock/inventory_validator.rb +1 -1
  128. data/app/models/spree/stock/package.rb +3 -3
  129. data/app/models/spree/stock_item.rb +5 -5
  130. data/app/models/spree/stock_location.rb +6 -6
  131. data/app/models/spree/stock_movement.rb +2 -2
  132. data/app/models/spree/stock_quantities.rb +2 -2
  133. data/app/models/spree/store.rb +3 -3
  134. data/app/models/spree/store_credit.rb +30 -29
  135. data/app/models/spree/store_credit_category.rb +2 -2
  136. data/app/models/spree/store_credit_event.rb +6 -6
  137. data/app/models/spree/store_credit_reason.rb +1 -1
  138. data/app/models/spree/store_credit_type.rb +3 -3
  139. data/app/models/spree/store_selector/by_server_name.rb +1 -1
  140. data/app/models/spree/store_selector/legacy.rb +1 -1
  141. data/app/models/spree/tax/item_tax.rb +1 -0
  142. data/app/models/spree/tax/order_tax.rb +1 -0
  143. data/app/models/spree/tax_category.rb +3 -3
  144. data/app/models/spree/tax_rate.rb +5 -5
  145. data/app/models/spree/tax_rate_tax_category.rb +2 -2
  146. data/app/models/spree/taxon/active_storage_attachment.rb +2 -2
  147. data/app/models/spree/taxon/paperclip_attachment.rb +4 -4
  148. data/app/models/spree/taxon.rb +16 -17
  149. data/app/models/spree/taxon_brand_selector.rb +3 -3
  150. data/app/models/spree/unauthorized_redirect_handler.rb +1 -1
  151. data/app/models/spree/unit_cancel.rb +4 -4
  152. data/app/models/spree/user_address.rb +3 -3
  153. data/app/models/spree/user_last_url_storer/rules/authentication_rule.rb +6 -8
  154. data/app/models/spree/user_last_url_storer.rb +1 -1
  155. data/app/models/spree/variant/price_selector.rb +1 -1
  156. data/app/models/spree/variant/scopes.rb +9 -9
  157. data/app/models/spree/variant.rb +25 -25
  158. data/app/models/spree/variant_property_rule.rb +2 -2
  159. data/app/models/spree/variant_property_rule_condition.rb +1 -1
  160. data/app/models/spree/wallet/add_payment_sources_to_wallet.rb +4 -4
  161. data/app/models/spree/wallet/default_payment_builder.rb +1 -1
  162. data/app/models/spree/wallet_payment_source.rb +2 -2
  163. data/app/models/spree/zone.rb +18 -18
  164. data/app/models/spree/zone_member.rb +1 -1
  165. data/app/subscribers/spree/carton_shipped_mailer_subscriber.rb +2 -2
  166. data/app/subscribers/spree/order_cancel_mailer_subscriber.rb +2 -2
  167. data/app/subscribers/spree/order_confirmation_mailer_subscriber.rb +2 -2
  168. data/app/subscribers/spree/order_inventory_cancellation_mailer_subscriber.rb +2 -2
  169. data/app/subscribers/spree/reimbursement_mailer_subscriber.rb +2 -2
  170. data/config/initializers/assets.rb +1 -1
  171. data/config/initializers/db_query_matchers.rb +9 -0
  172. data/config/initializers/friendly_id.rb +2 -2
  173. data/config/initializers/inflections.rb +1 -1
  174. data/config/initializers/money.rb +1 -1
  175. data/config/locales/en.yml +1 -0
  176. data/db/default/spree/countries.rb +7 -7
  177. data/db/default/spree/return_reasons.rb +11 -11
  178. data/db/default/spree/stock_locations.rb +1 -1
  179. data/db/default/spree/store_credit.rb +3 -4
  180. data/db/default/spree/stores.rb +1 -1
  181. data/db/default/spree/zones.rb +5 -5
  182. data/db/migrate/20160101010000_solidus_one_four.rb +16 -16
  183. data/db/migrate/20160420044191_create_spree_wallet_payment_sources.rb +3 -3
  184. data/db/migrate/20160420181916_migrate_credit_cards_to_wallet_payment_sources.rb +7 -6
  185. data/db/migrate/20161014221052_add_available_to_columns_and_remove_display_on_from_payment_methods.rb +10 -10
  186. data/db/migrate/20161123154034_add_available_to_users_and_remove_display_on_from_shipping_methods.rb +6 -6
  187. data/db/migrate/20161129035810_add_index_to_spree_payments_number.rb +1 -1
  188. data/db/migrate/20170319191942_remove_order_id_from_inventory_units.rb +4 -4
  189. data/db/migrate/20180322142651_add_amount_remaining_to_store_credit_events.rb +9 -16
  190. data/db/migrate/20200320144521_add_default_billng_flag_to_user_addresses.rb +1 -0
  191. data/db/migrate/20210815004823_add_unique_index_to_option_values_variants.rb +3 -3
  192. data/db/migrate/20250207104016_add_primary_taxon_to_products.rb +1 -1
  193. data/db/migrate/20250214094207_add_reverse_charge_status_to_store.rb +1 -1
  194. data/db/migrate/20250225051308_add_vat_id_email_and_reverse_charge_status_to_addresses.rb +1 -1
  195. data/db/migrate/20250605105424_add_shipping_category_foreign_keys.rb +3 -3
  196. data/db/seeds.rb +3 -3
  197. data/lib/generators/solidus/install/app_templates/authentication/custom.rb +2 -2
  198. data/lib/generators/solidus/install/app_templates/authentication/devise.rb +3 -3
  199. data/lib/generators/solidus/install/app_templates/authentication/existing.rb +3 -1
  200. data/lib/generators/solidus/install/app_templates/frontend/starter.rb +1 -1
  201. data/lib/generators/solidus/install/app_templates/payment_method/braintree.rb +1 -1
  202. data/lib/generators/solidus/install/app_templates/payment_method/paypal.rb +1 -1
  203. data/lib/generators/solidus/install/app_templates/payment_method/stripe.rb +2 -2
  204. data/lib/generators/solidus/install/install_generator.rb +51 -51
  205. data/lib/generators/solidus/install/templates/config/initializers/spree.rb.tt +3 -0
  206. data/lib/generators/solidus/update/update_generator.rb +29 -29
  207. data/lib/generators/spree/custom_user/custom_user_generator.rb +6 -6
  208. data/lib/generators/spree/dummy/dummy_generator.rb +22 -24
  209. data/lib/generators/spree/dummy/templates/rails/boot.rb +3 -3
  210. data/lib/generators/spree/dummy/templates/rails/test.rb +4 -4
  211. data/lib/solidus_core.rb +1 -1
  212. data/lib/spree/app_configuration.rb +66 -47
  213. data/lib/spree/bus.rb +1 -1
  214. data/lib/spree/config.rb +1 -1
  215. data/lib/spree/core/active_merchant_dependencies.rb +8 -8
  216. data/lib/spree/core/class_constantizer.rb +1 -1
  217. data/lib/spree/core/engine.rb +15 -15
  218. data/lib/spree/core/environment.rb +1 -1
  219. data/lib/spree/core/environment_extension.rb +2 -2
  220. data/lib/spree/core/importer/order.rb +15 -15
  221. data/lib/spree/core/importer/product.rb +4 -4
  222. data/lib/spree/core/importer.rb +2 -2
  223. data/lib/spree/core/null_promotion_configuration.rb +7 -7
  224. data/lib/spree/core/permalinks.rb +1 -1
  225. data/lib/spree/core/product_filters.rb +94 -93
  226. data/lib/spree/core/role_configuration.rb +3 -3
  227. data/lib/spree/core/search/base.rb +5 -6
  228. data/lib/spree/core/search/variant.rb +3 -3
  229. data/lib/spree/core/stock_configuration.rb +10 -49
  230. data/lib/spree/core/validators/email.rb +1 -1
  231. data/lib/spree/core/version.rb +3 -3
  232. data/lib/spree/core/versioned_value.rb +4 -6
  233. data/lib/spree/core.rb +49 -49
  234. data/lib/spree/deprecated_instance_variable_proxy.rb +1 -1
  235. data/lib/spree/deprecation.rb +1 -1
  236. data/lib/spree/deprecator.rb +2 -2
  237. data/lib/spree/i18n.rb +2 -2
  238. data/lib/spree/localized_number.rb +3 -3
  239. data/lib/spree/manipulative_query_monitor.rb +19 -0
  240. data/lib/spree/migrations.rb +2 -2
  241. data/lib/spree/permitted_attributes.rb +10 -10
  242. data/lib/spree/preferences/configuration.rb +5 -5
  243. data/lib/spree/preferences/preferable.rb +8 -10
  244. data/lib/spree/preferences/preferable_class_methods.rb +16 -16
  245. data/lib/spree/preferences/preference_differentiator.rb +1 -1
  246. data/lib/spree/preferences/scoped_store.rb +2 -2
  247. data/lib/spree/preferences/static_model_preferences.rb +2 -2
  248. data/lib/spree/preferences/store.rb +6 -6
  249. data/lib/spree/testing_support/ability_helpers.rb +30 -30
  250. data/lib/spree/testing_support/authorization_helpers.rb +6 -5
  251. data/lib/spree/testing_support/blacklist_urls.rb +1 -1
  252. data/lib/spree/testing_support/bus_helpers.rb +1 -1
  253. data/lib/spree/testing_support/capybara_driver.rb +1 -1
  254. data/lib/spree/testing_support/capybara_ext.rb +12 -12
  255. data/lib/spree/testing_support/common_rake.rb +17 -16
  256. data/lib/spree/testing_support/dummy_ability.rb +1 -1
  257. data/lib/spree/testing_support/dummy_app/migrations.rb +1 -1
  258. data/lib/spree/testing_support/dummy_app/rake_tasks.rb +5 -5
  259. data/lib/spree/testing_support/dummy_app/routes.rb +1 -1
  260. data/lib/spree/testing_support/dummy_app.rb +34 -34
  261. data/lib/spree/testing_support/extension_rake.rb +2 -2
  262. data/lib/spree/testing_support/factories/address_factory.rb +12 -12
  263. data/lib/spree/testing_support/factories/adjustment_factory.rb +7 -7
  264. data/lib/spree/testing_support/factories/adjustment_reason_factory.rb +1 -1
  265. data/lib/spree/testing_support/factories/calculator_factory.rb +6 -6
  266. data/lib/spree/testing_support/factories/carton_factory.rb +1 -1
  267. data/lib/spree/testing_support/factories/country_factory.rb +3 -3
  268. data/lib/spree/testing_support/factories/credit_card_factory.rb +3 -3
  269. data/lib/spree/testing_support/factories/customer_return_factory.rb +2 -2
  270. data/lib/spree/testing_support/factories/image_factory.rb +2 -2
  271. data/lib/spree/testing_support/factories/inventory_unit_factory.rb +4 -4
  272. data/lib/spree/testing_support/factories/line_item_factory.rb +2 -2
  273. data/lib/spree/testing_support/factories/option_type_factory.rb +2 -2
  274. data/lib/spree/testing_support/factories/option_value_factory.rb +2 -2
  275. data/lib/spree/testing_support/factories/order_factory.rb +16 -16
  276. data/lib/spree/testing_support/factories/payment_factory.rb +9 -9
  277. data/lib/spree/testing_support/factories/payment_method_factory.rb +10 -10
  278. data/lib/spree/testing_support/factories/price_factory.rb +2 -2
  279. data/lib/spree/testing_support/factories/product_factory.rb +2 -2
  280. data/lib/spree/testing_support/factories/product_option_type_factory.rb +1 -1
  281. data/lib/spree/testing_support/factories/product_property_factory.rb +1 -1
  282. data/lib/spree/testing_support/factories/property_factory.rb +3 -3
  283. data/lib/spree/testing_support/factories/refund_factory.rb +2 -2
  284. data/lib/spree/testing_support/factories/refund_reason_factory.rb +1 -1
  285. data/lib/spree/testing_support/factories/reimbursement_factory.rb +1 -1
  286. data/lib/spree/testing_support/factories/reimbursement_type_factory.rb +1 -1
  287. data/lib/spree/testing_support/factories/return_authorization_factory.rb +3 -3
  288. data/lib/spree/testing_support/factories/return_item_factory.rb +1 -1
  289. data/lib/spree/testing_support/factories/return_reason_factory.rb +1 -1
  290. data/lib/spree/testing_support/factories/role_factory.rb +2 -2
  291. data/lib/spree/testing_support/factories/shipment_factory.rb +3 -3
  292. data/lib/spree/testing_support/factories/shipping_category_factory.rb +1 -1
  293. data/lib/spree/testing_support/factories/shipping_method_factory.rb +7 -7
  294. data/lib/spree/testing_support/factories/shipping_rate_factory.rb +1 -1
  295. data/lib/spree/testing_support/factories/state_factory.rb +4 -4
  296. data/lib/spree/testing_support/factories/stock_item_factory.rb +1 -1
  297. data/lib/spree/testing_support/factories/stock_location_factory.rb +7 -7
  298. data/lib/spree/testing_support/factories/stock_movement_factory.rb +3 -3
  299. data/lib/spree/testing_support/factories/stock_package_factory.rb +3 -3
  300. data/lib/spree/testing_support/factories/store_credit_category_factory.rb +1 -1
  301. data/lib/spree/testing_support/factories/store_credit_event_factory.rb +8 -8
  302. data/lib/spree/testing_support/factories/store_credit_factory.rb +1 -1
  303. data/lib/spree/testing_support/factories/store_credit_reason_factory.rb +1 -1
  304. data/lib/spree/testing_support/factories/store_credit_type_factory.rb +6 -6
  305. data/lib/spree/testing_support/factories/store_factory.rb +2 -2
  306. data/lib/spree/testing_support/factories/tax_category_factory.rb +1 -1
  307. data/lib/spree/testing_support/factories/tax_rate_factory.rb +1 -1
  308. data/lib/spree/testing_support/factories/taxon_factory.rb +3 -3
  309. data/lib/spree/testing_support/factories/taxonomy_factory.rb +1 -1
  310. data/lib/spree/testing_support/factories/user_factory.rb +2 -2
  311. data/lib/spree/testing_support/factories/variant_factory.rb +2 -2
  312. data/lib/spree/testing_support/factories/variant_property_rule_condition_factory.rb +1 -1
  313. data/lib/spree/testing_support/factories/variant_property_rule_factory.rb +1 -1
  314. data/lib/spree/testing_support/factories/variant_property_rule_value_factory.rb +1 -1
  315. data/lib/spree/testing_support/factories/zone_factory.rb +3 -3
  316. data/lib/spree/testing_support/factory_bot.rb +1 -1
  317. data/lib/spree/testing_support/flaky.rb +3 -2
  318. data/lib/spree/testing_support/flash.rb +2 -2
  319. data/lib/spree/testing_support/order_walkthrough.rb +7 -7
  320. data/lib/spree/testing_support/preferences.rb +1 -1
  321. data/lib/spree/testing_support/rake.rb +1 -1
  322. data/lib/spree/testing_support/shared_examples/calculator.rb +1 -1
  323. data/lib/spree/testing_support/shared_examples/gallery.rb +7 -7
  324. data/lib/spree/testing_support/shared_examples/order_factory.rb +9 -9
  325. data/lib/spree/testing_support/shared_examples/state_change_tracking.rb +25 -0
  326. data/lib/spree/testing_support/shared_examples/working_factory.rb +1 -1
  327. data/lib/spree/testing_support/translations.rb +1 -1
  328. data/lib/spree_core.rb +1 -1
  329. data/lib/tasks/payment_method.rake +2 -2
  330. data/solidus_core.gemspec +49 -49
  331. metadata +62 -54
@@ -18,7 +18,7 @@ module Spree
18
18
  if product.save
19
19
  variants_attrs.each do |variant_attribute|
20
20
  # make sure the product is assigned before the options=
21
- product.variants.create({ product: }.merge(variant_attribute))
21
+ product.variants.create({product:}.merge(variant_attribute))
22
22
  end
23
23
 
24
24
  set_up_options
@@ -31,11 +31,11 @@ module Spree
31
31
  if product.update(product_attrs)
32
32
  variants_attrs.each do |variant_attribute|
33
33
  # update the variant if the id is present in the payload
34
- if variant_attribute['id'].present?
35
- product.variants.find(variant_attribute['id'].to_i).update(variant_attribute)
34
+ if variant_attribute["id"].present?
35
+ product.variants.find(variant_attribute["id"].to_i).update(variant_attribute)
36
36
  else
37
37
  # make sure the product is assigned before the options=
38
- product.variants.create({ product: }.merge(variant_attribute))
38
+ product.variants.create({product:}.merge(variant_attribute))
39
39
  end
40
40
  end
41
41
 
@@ -7,5 +7,5 @@ module Spree
7
7
  end
8
8
  end
9
9
 
10
- require 'spree/core/importer/order'
11
- require 'spree/core/importer/product'
10
+ require "spree/core/importer/order"
11
+ require "spree/core/importer/product"
@@ -6,7 +6,7 @@ module Spree
6
6
  include Spree::Core::EnvironmentExtension
7
7
 
8
8
  # order_adjuster_class allows extensions to provide their own Order Adjuster
9
- class_name_attribute :order_adjuster_class, default: 'Spree::NullPromotionAdjuster'
9
+ class_name_attribute :order_adjuster_class, default: "Spree::NullPromotionAdjuster"
10
10
 
11
11
  # Allows providing a different coupon code handler.
12
12
  # @!attribute [rw] coupon_code_handler_class
@@ -14,7 +14,7 @@ module Spree
14
14
  # @return [Class] an object that conforms to the API of
15
15
  # the standard coupon code handler class
16
16
  # Spree::NullPromotionHandler.
17
- class_name_attribute :coupon_code_handler_class, default: 'Spree::NullPromotionHandler'
17
+ class_name_attribute :coupon_code_handler_class, default: "Spree::NullPromotionHandler"
18
18
 
19
19
  # Allows providing a different promotion finder.
20
20
  # @!attribute [rw] promotion_finder_class
@@ -22,16 +22,16 @@ module Spree
22
22
  # @return [Class] an object that conforms to the API of
23
23
  # the standard promotion finder class
24
24
  # Spree::NullPromotionFinder.
25
- class_name_attribute :promotion_finder_class, default: 'Spree::NullPromotionFinder'
25
+ class_name_attribute :promotion_finder_class, default: "Spree::NullPromotionFinder"
26
26
 
27
27
  # Allows getting and setting `Spree::Config.promotion_code_batch_mailer_class`.
28
28
  # Both will issue a deprecation warning.
29
- class_name_attribute :promotion_code_batch_mailer_class, default: 'Spree::DeprecatedConfigurableClass'
29
+ class_name_attribute :promotion_code_batch_mailer_class, default: "Spree::DeprecatedConfigurableClass"
30
30
  deprecate :promotion_code_batch_mailer_class, :promotion_code_batch_mailer_class=, deprecator: Spree.deprecator
31
31
 
32
32
  # Allows getting and setting `Spree::Config.promotion_chooser_class`.
33
33
  # Both will issue a deprecation warning.
34
- class_name_attribute :promotion_chooser_class, default: 'Spree::DeprecatedConfigurableClass'
34
+ class_name_attribute :promotion_chooser_class, default: "Spree::DeprecatedConfigurableClass"
35
35
  deprecate :promotion_chooser_class, :promotion_chooser_class=, deprecator: Spree.deprecator
36
36
 
37
37
  # Allows getting and setting rules. Deprecated.
@@ -64,7 +64,7 @@ module Spree
64
64
  # @return [Class] an object that conforms to the API of
65
65
  # the standard promotion finder class
66
66
  # Spree::NullPromotionHandler.
67
- class_name_attribute :shipping_promotion_handler_class, default: 'Spree::NullPromotionHandler'
67
+ class_name_attribute :shipping_promotion_handler_class, default: "Spree::NullPromotionHandler"
68
68
  deprecate :shipping_promotion_handler_class, deprecator: Spree.deprecator
69
69
  deprecate :shipping_promotion_handler_class=, deprecator: Spree.deprecator
70
70
 
@@ -74,7 +74,7 @@ module Spree
74
74
  # @return [Class] an object that conforms to the API of
75
75
  # the standard promotion advertiser class
76
76
  # Spree::NullPromotionAdvertiser.
77
- class_name_attribute :advertiser_class, default: 'Spree::NullPromotionAdvertiser'
77
+ class_name_attribute :advertiser_class, default: "Spree::NullPromotionAdvertiser"
78
78
 
79
79
  # !@attribute [rw] promotion_api_attributes
80
80
  # @return [Array<Symbol>] Attributes to be returned by the API for a promotion
@@ -44,7 +44,7 @@ module Spree
44
44
  end
45
45
 
46
46
  def generate_permalink
47
- "#{self.class.permalink_prefix}#{Array.new(self.class.permalink_length){ rand(9) }.join}"
47
+ "#{self.class.permalink_prefix}#{Array.new(self.class.permalink_length) { rand(9) }.join}"
48
48
  end
49
49
 
50
50
  def save_permalink(permalink_value = to_param)
@@ -2,64 +2,61 @@
2
2
 
3
3
  module Spree
4
4
  module Core
5
- # THIS FILE SHOULD BE OVER-RIDDEN IN YOUR SITE EXTENSION!
6
- # the exact code probably won't be useful, though you're welcome to modify and reuse
7
- # the current contents are mainly for testing and documentation
8
-
9
- # To override this file...
10
- # 1) Make a copy of it in your sites local /lib/spree folder
11
- # 2) Add it to the config load path, or require it in an initializer, e.g...
5
+ # THIS FILE SHOULD BE OVER-RIDDEN IN YOUR APP!
12
6
  #
13
- # # config/initializers/spree.rb
14
- # require 'spree/product_filters'
7
+ # Use this code as a reference or a starting point for your own product
8
+ # filters.
15
9
  #
10
+ # To override this file make a copy of it in lib/spree/core and modify it.
16
11
 
17
- # set up some basic filters for use with products
12
+ # Each filter has two parts:
13
+ #
14
+ # * a parametrized named scope which expects a list of labels
15
+ # * an object which describes/defines the filter
18
16
  #
19
- # Each filter has two parts
20
- # * a parametrized named scope which expects a list of labels
21
- # * an object which describes/defines the filter
17
+ # The filter description has the following components:
22
18
  #
23
- # The filter description has three components
24
- # * a name, for displaying on pages
25
- # * a named scope which will 'execute' the filter
26
- # * a mapping of presentation labels to the relevant condition (in the context of the named scope)
27
- # * an optional list of labels and values (for use with object selection - see taxons examples below)
19
+ # * a name for displaying on pages
20
+ # * a named scope which filters the products
21
+ # * a mapping of presentation labels to the relevant condition (in the
22
+ # context of the named scope)
23
+ # * an optional list of labels and values (for use with object selection -
24
+ # see taxons examples below)
28
25
  #
29
- # The named scopes here have a suffix '_any', following Ransack's convention for a
30
- # scope which returns results which match any of the inputs. This is purely a convention,
31
- # but might be a useful reminder.
26
+ # The named scopes here have a suffix '_any', following Ransack's convention
27
+ # for a scope which returns results which match any of the inputs. This is
28
+ # purely a convention, but might be a useful reminder.
32
29
  #
33
- # When creating a form, the name of the checkbox group for a filter F should be
34
- # the name of F's scope with [] appended, eg "price_range_any[]", and for
35
- # each label you should have a checkbox with the label as its value. On submission,
36
- # Rails will send the action a hash containing (among other things) an array named
30
+ # When creating a form, the name of the checkbox group for a filter F should
31
+ # be the name of F's scope with [] appended, e.g. "price_range_any[]", and
32
+ # for each label you should have a checkbox with the label as its value. On
33
+ # submission, Rails will send the action a hash containing an array named
37
34
  # after the scope whose values are the active labels.
38
35
  #
39
- # Ransack will then convert this array to a call to the named scope with the array
40
- # contents, and the named scope will build a query with the disjunction of the conditions
41
- # relating to the labels, all relative to the scope's context.
36
+ # Ransack will then convert this array to a call to the named scope with the
37
+ # array contents, and the named scope will build a query with the
38
+ # disjunction of the conditions relating to the labels, all relative to the
39
+ # scope's context.
42
40
  #
43
- # The details of how/when filters are used is a detail for specific models (eg products
44
- # or taxons), eg see the taxon model/controller.
45
-
46
- # See specific filters below for concrete examples.
41
+ # The details of how/when filters are used is a detail for specific models.
42
+ # For example, see the Taxon model/controller. See specific filters below
43
+ # for concrete examples.
47
44
  module ProductFilters
48
- # Example: filtering by price
49
- # The named scope just maps incoming labels onto their conditions, and builds the conjunction
50
- # 'price' is in the base scope's context (ie, "select foo from products where ...") so
51
- # we can access the field right away
52
- # The filter identifies which scope to use, then sets the conditions for each price range
45
+ # Example: Filtering by price
53
46
  #
54
- # If user checks off three different price ranges then the argument passed to
55
- # below scope would be something like ["$10 - $15", "$15 - $18", "$18 - $20"]
47
+ # The named scope just maps incoming labels onto their conditions, and
48
+ # builds the conjunction 'price' is in the base scope's context (e.g.
49
+ # "select foo from products where ...") so we can access the field right
50
+ # away. The filter identifies which scope to use, then sets the
51
+ # conditions for each price range.
56
52
  #
53
+ # If user checks off three different price ranges then the argument passed
54
+ # to below scope would be something like ["$10 - $15", "$15 - $18", "$18 -
55
+ # $20"].
57
56
  Spree::Product.add_search_scope :price_range_any do |*opts|
58
- conds = opts.map { |element| Spree::Core::ProductFilters.price_filter[:conds][element] }.reject(&:nil?)
59
- scope = conds.shift
60
- conds.each do |new_scope|
61
- scope = scope.or(new_scope)
62
- end
57
+ scope = opts.filter_map { |element|
58
+ Spree::Core::ProductFilters.price_filter[:conds][element]
59
+ }.inject { |scope1, scope2| scope1.or(scope2) }
63
60
 
64
61
  Spree::Product.joins(master: :prices).where(scope)
65
62
  end
@@ -70,86 +67,90 @@ module Spree
70
67
 
71
68
  def self.price_filter
72
69
  value = Spree::Price.arel_table
73
- conds = [[I18n.t('spree.under_price', price: format_price(10)), value[:amount].lteq(10)],
74
- ["#{format_price(10)} - #{format_price(15)}", value[:amount].between(10..15)],
75
- ["#{format_price(15)} - #{format_price(18)}", value[:amount].between(15..18)],
76
- ["#{format_price(18)} - #{format_price(20)}", value[:amount].between(18..20)],
77
- [I18n.t('spree.or_over_price', price: format_price(20)), value[:amount].gteq(20)]]
70
+ conds = [[I18n.t("spree.under_price", price: format_price(10)), value[:amount].lteq(10)],
71
+ ["#{format_price(10)} - #{format_price(15)}", value[:amount].between(10..15)],
72
+ ["#{format_price(15)} - #{format_price(18)}", value[:amount].between(15..18)],
73
+ ["#{format_price(18)} - #{format_price(20)}", value[:amount].between(18..20)],
74
+ [I18n.t("spree.or_over_price", price: format_price(20)), value[:amount].gteq(20)]]
78
75
  {
79
- name: I18n.t('spree.price_range'),
80
- scope: :price_range_any,
81
- conds: Hash[*conds.flatten],
76
+ name: I18n.t("spree.price_range"),
77
+ scope: :price_range_any,
78
+ conds: Hash[*conds.flatten],
82
79
  labels: conds.map { |key, _value| [key, key] }
83
80
  }
84
81
  end
85
82
 
86
- # Example: filtering by possible brands
83
+ # Example: Filtering by possible brands
87
84
  #
88
- # First, we define the scope. Two interesting points here: (a) we run our conditions
89
- # in the scope where the info for the 'brand' property has been loaded; and (b)
90
- # because we may want to filter by other properties too, we give this part of the
91
- # query a unique name (which must be used in the associated conditions too).
85
+ # First, we define the scope. Two interesting points here:
92
86
  #
93
- # Secondly, the filter. Instead of a static list of values, we pull out all existing
94
- # brands from the db, and then build conditions which test for string equality on
95
- # the (uniquely named) field "p_brand.value". There's also a test for brand info
96
- # being blank: note that this relies on with_property doing a left outer join
97
- # rather than an inner join.
87
+ # * we run our conditions in the scope where the info for the 'brand'
88
+ # property has been loaded; and
89
+ # * because we may want to filter by other properties too, we give this
90
+ # part of the query a unique name (which must be used in the
91
+ # associated conditions too).
92
+ #
93
+ # Second, instead of a static list of values, we pull out all existing
94
+ # brands from the database. Then we build conditions which test for string
95
+ # equality on the (uniquely named) field "p_brand.value". There's also a
96
+ # test for brand info being blank. Note that this relies on
97
+ # `with_property` doing a left outer join rather than an inner join.
98
98
  Spree::Product.add_search_scope :brand_any do |*opts|
99
- conds = opts.map { |value| ProductFilters.brand_filter[:conds][value] }.reject(&:nil?)
100
- scope = conds.shift
101
- conds.each do |new_scope|
102
- scope = scope.or(new_scope)
103
- end
104
- Spree::Product.with_property('brand').where(scope)
99
+ scope = opts.filter_map { |value|
100
+ Spree::Core::ProductFilters.brand_filter[:conds][value]
101
+ }.inject { |scope1, scope2| scope1.or(scope2) }
102
+
103
+ Spree::Product.with_property("brand").where(scope)
105
104
  end
106
105
 
107
106
  def self.brand_filter
108
- brand_property = Spree::Property.find_by(name: 'brand')
107
+ brand_property = Spree::Property.find_by(name: "brand")
109
108
  brands = brand_property ? Spree::ProductProperty.where(property_id: brand_property.id).pluck(:value).uniq.map(&:to_s) : []
110
109
  pp = Spree::ProductProperty.arel_table
111
110
  conds = Hash[*brands.flat_map { |brand| [brand, pp[:value].eq(brand)] }]
112
111
  {
113
- name: 'Brands',
114
- scope: :brand_any,
112
+ name: "Brands",
113
+ scope: :brand_any,
115
114
  conds:,
116
115
  labels: brands.sort.map { |key| [key, key] }
117
116
  }
118
117
  end
119
118
 
120
- # Example: a parameterized filter
121
- # The filter above may show brands which aren't applicable to the current taxon,
122
- # so this one only shows the brands that are relevant to a particular taxon and
123
- # its descendants.
119
+ # Example: A parameterized filter
120
+ #
121
+ # The filter above may show brands which aren't applicable to the current
122
+ # taxon, so this one only shows the brands that are relevant to a
123
+ # particular taxon and its descendants.
124
124
  #
125
- # We don't have to give a new scope since the conditions here are a subset of the
126
- # more general filter, so decoding will still work - as long as the filters on a
127
- # page all have unique names (ie, you can't use the two brand filters together
128
- # if they use the same scope). To be safe, the code uses a copy of the scope.
125
+ # We don't need to give a new scope since the conditions here are a subset
126
+ # of the more general filter, so decoding will still work as long as the
127
+ # filters on a page all have unique names (i.e. you can't use the two
128
+ # brand filters together if they use the same scope). To be safe, the code
129
+ # uses a copy of the scope.
129
130
  #
130
- # HOWEVER: what happens if we want a more precise scope? we can't pass
131
- # parametrized scope names to Ransack, only atomic names, so couldn't ask
132
- # for taxon T's customized filter to be used. BUT: we can arrange for the form
133
- # to pass back a hash instead of an array, where the key acts as the (taxon)
134
- # parameter and value is its label array, and then get a modified named scope
135
- # to get its conditions from a particular filter.
131
+ # However, if we want a more precise scope, we can't pass parametrized
132
+ # scope names to Ransack, only atomic names. We can't ask for taxon T's
133
+ # customized filter to be used, but we can arrange for the form to pass
134
+ # back a hash instead of an array where the key acts as the taxon
135
+ # parameter and value is its label array, and then get a modified named
136
+ # scope to get its conditions from a particular filter.
136
137
  #
137
- # The brand-finding code can be simplified if a few more named scopes were added to
138
- # the product properties model.
138
+ # The brand-finding code could be simplified if a few more named scopes
139
+ # were added to the product properties model.
139
140
  Spree::Product.add_search_scope :selective_brand_any do |*opts|
140
141
  Spree::Product.brand_any(*opts)
141
142
  end
142
143
 
143
144
  def self.selective_brand_filter(taxon = nil)
144
145
  taxon ||= Spree::Taxonomy.first.root
145
- brand_property = Spree::Property.find_by(name: 'brand')
146
- scope = Spree::ProductProperty.where(property: brand_property).
147
- joins(product: :taxons).
148
- where("#{Spree::Taxon.table_name}.id" => [taxon] + taxon.descendants)
146
+ brand_property = Spree::Property.find_by(name: "brand")
147
+ scope = Spree::ProductProperty.where(property: brand_property)
148
+ .joins(product: :taxons)
149
+ .where("#{Spree::Taxon.table_name}.id" => [taxon] + taxon.descendants)
149
150
  brands = scope.pluck(:value).uniq
150
151
  {
151
- name: 'Applicable Brands',
152
- scope: :selective_brand_any,
152
+ name: "Applicable Brands",
153
+ scope: :selective_brand_any,
153
154
  labels: brands.sort.map { |key| [key, key] }
154
155
  }
155
156
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'singleton'
4
- require 'spree/core/class_constantizer'
3
+ require "singleton"
4
+ require "spree/core/class_constantizer"
5
5
 
6
6
  module Spree
7
7
  # A class responsible for associating {Spree::Role} with a list of permission sets.
@@ -40,7 +40,7 @@ module Spree
40
40
  # @param ability [CanCan::Ability] the ability to invoke declarations on
41
41
  # @param user [#spree_roles] the user that holds the spree_roles association.
42
42
  def activate_permissions!(ability, user)
43
- spree_roles = ['default'] | user.spree_roles.map(&:name)
43
+ spree_roles = ["default"] | user.spree_roles.map(&:name)
44
44
  applicable_permissions = Set.new
45
45
 
46
46
  spree_roles.each do |role_name|
@@ -37,8 +37,7 @@ module Spree
37
37
  base_scope = base_scope.in_taxon(@properties[:taxon]) unless @properties[:taxon].blank?
38
38
  base_scope = get_products_conditions_for(base_scope, @properties[:keywords])
39
39
  base_scope = add_search_scopes(base_scope)
40
- base_scope = add_eagerload_scopes(base_scope)
41
- base_scope
40
+ add_eagerload_scopes(base_scope)
42
41
  end
43
42
 
44
43
  def add_eagerload_scopes(scope)
@@ -69,10 +68,10 @@ module Spree
69
68
  @properties[:search].each_pair do |name, scope_attribute|
70
69
  scope_name = name.to_sym
71
70
 
72
- if base_scope.respond_to?(:search_scopes) && base_scope.search_scopes.include?(scope_name.to_sym)
73
- base_scope = base_scope.send(scope_name, *scope_attribute)
71
+ base_scope = if base_scope.respond_to?(:search_scopes) && base_scope.search_scopes.include?(scope_name.to_sym)
72
+ base_scope.send(scope_name, *scope_attribute)
74
73
  else
75
- base_scope = base_scope.merge(Spree::Product.ransack({ scope_name => scope_attribute }).result)
74
+ base_scope.merge(Spree::Product.ransack({scope_name => scope_attribute}).result)
76
75
  end
77
76
  end
78
77
 
@@ -94,7 +93,7 @@ module Spree
94
93
  @properties[:include_images] = params[:include_images]
95
94
 
96
95
  per_page = params[:per_page].to_i
97
- @properties[:per_page] = per_page > 0 ? per_page : Spree::Config[:products_per_page]
96
+ @properties[:per_page] = (per_page > 0) ? per_page : Spree::Config[:products_per_page]
98
97
  @properties[:page] = (params[:page].to_i <= 0) ? 1 : params[:page].to_i
99
98
  end
100
99
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'active_support/core_ext/class/attribute'
3
+ require "active_support/core_ext/class/attribute"
4
4
 
5
5
  module Spree
6
6
  module Core
@@ -57,8 +57,8 @@ module Spree
57
57
  end
58
58
 
59
59
  def search_term_params(word)
60
- terms = Hash[search_terms(word).map { |term| [term, word] }]
61
- terms.merge(m: 'or')
60
+ terms = search_terms(word).map { |term| [term, word] }.to_h
61
+ terms.merge(m: "or")
62
62
  end
63
63
  end
64
64
  end
@@ -2,55 +2,16 @@
2
2
 
3
3
  module Spree
4
4
  module Core
5
- class StockConfiguration
6
- attr_writer :coordinator_class
7
- attr_writer :estimator_class
8
- attr_writer :location_filter_class
9
- attr_writer :location_sorter_class
10
- attr_writer :allocator_class
11
- attr_writer :inventory_unit_builder_class
12
- attr_writer :availability_validator_class
13
- attr_writer :inventory_validator_class
14
-
15
- def coordinator_class
16
- @coordinator_class ||= '::Spree::Stock::SimpleCoordinator'
17
- @coordinator_class.constantize
18
- end
19
-
20
- def estimator_class
21
- @estimator_class ||= '::Spree::Stock::Estimator'
22
- @estimator_class.constantize
23
- end
24
-
25
- def location_filter_class
26
- @location_filter_class ||= '::Spree::Stock::LocationFilter::Active'
27
- @location_filter_class.constantize
28
- end
29
-
30
- def location_sorter_class
31
- @location_sorter_class ||= '::Spree::Stock::LocationSorter::Unsorted'
32
- @location_sorter_class.constantize
33
- end
34
-
35
- def allocator_class
36
- @allocator_class ||= '::Spree::Stock::Allocator::OnHandFirst'
37
- @allocator_class.constantize
38
- end
39
-
40
- def inventory_unit_builder_class
41
- @inventory_unit_builder_class ||= '::Spree::Stock::InventoryUnitBuilder'
42
- @inventory_unit_builder_class.constantize
43
- end
44
-
45
- def availability_validator_class
46
- @availability_validator_class ||= '::Spree::Stock::AvailabilityValidator'
47
- @availability_validator_class.constantize
48
- end
49
-
50
- def inventory_validator_class
51
- @inventory_validator_class ||= '::Spree::Stock::InventoryValidator'
52
- @inventory_validator_class.constantize
53
- end
5
+ class StockConfiguration < Spree::Preferences::Configuration
6
+ class_name_attribute :coordinator_class, default: "::Spree::Stock::SimpleCoordinator"
7
+ class_name_attribute :estimator_class, default: "::Spree::Stock::Estimator"
8
+ class_name_attribute :location_filter_class, default: "::Spree::Stock::LocationFilter::Active"
9
+ class_name_attribute :location_sorter_class, default: "::Spree::Stock::LocationSorter::Unsorted"
10
+ class_name_attribute :allocator_class, default: "::Spree::Stock::Allocator::OnHandFirst"
11
+ class_name_attribute :inventory_unit_builder_class, default: "::Spree::Stock::InventoryUnitBuilder"
12
+ class_name_attribute :availability_validator_class, default: "::Spree::Stock::AvailabilityValidator"
13
+ class_name_attribute :inventory_validator_class, default: "::Spree::Stock::InventoryValidator"
14
+ class_name_attribute :quantifier_class, default: "::Spree::Stock::Quantifier"
54
15
  end
55
16
  end
56
17
  end
@@ -14,7 +14,7 @@ module Spree
14
14
  class EmailValidator < ActiveModel::EachValidator
15
15
  def validate_each(record, attribute, value)
16
16
  unless Spree::Config.default_email_regexp.match? value
17
- record.errors.add(attribute, :invalid, **{ value: }.merge!(options))
17
+ record.errors.add(attribute, :invalid, value:, **options)
18
18
  end
19
19
  end
20
20
  end
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Spree
4
- VERSION = "4.6.1"
4
+ VERSION = "4.7.0"
5
5
 
6
6
  def self.solidus_version = VERSION
7
7
 
8
- def self.minimum_required_rails_version = "7.0"
8
+ def self.minimum_required_rails_version = "7.2"
9
9
 
10
- def self.previous_solidus_minor_version = "4.5"
10
+ def self.previous_solidus_minor_version = "4.6"
11
11
 
12
12
  def self.solidus_gem_version = Gem::Version.new(solidus_version)
13
13
  end
@@ -41,12 +41,10 @@ module Spree
41
41
  # @param initial_value [Any]
42
42
  # @param boundary [Hash<String, Any>] Map from version number to new value
43
43
  def initialize(initial_value, boundaries = {})
44
- @boundaries = Hash[
45
- { '0' => initial_value }
46
- .merge(boundaries)
47
- .transform_keys { |version| to_gem_version(version) }
48
- .sort
49
- ]
44
+ @boundaries = {"0" => initial_value}
45
+ .merge(boundaries)
46
+ .transform_keys { |version| to_gem_version(version) }
47
+ .sort.to_h
50
48
  end
51
49
 
52
50
  # @param solidus_version [String]