solidus_core 2.9.6 → 2.11.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 (575) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/spree.js.erb +31 -2
  3. data/app/controllers/spree/base_controller.rb +1 -0
  4. data/app/helpers/spree/base_helper.rb +4 -4
  5. data/app/helpers/spree/products_helper.rb +2 -1
  6. data/app/jobs/spree/promotion_code_batch_job.rb +2 -2
  7. data/app/mailers/spree/base_mailer.rb +4 -0
  8. data/app/mailers/spree/order_mailer.rb +1 -1
  9. data/app/models/concerns/spree/active_storage_adapter.rb +116 -0
  10. data/app/models/concerns/spree/active_storage_adapter/attachment.rb +69 -0
  11. data/app/models/concerns/spree/active_storage_adapter/normalization.rb +39 -0
  12. data/app/models/concerns/spree/default_price.rb +1 -1
  13. data/app/models/concerns/spree/soft_deletable.rb +18 -0
  14. data/app/models/concerns/spree/user_address_book.rb +87 -33
  15. data/app/models/concerns/spree/user_methods.rb +5 -4
  16. data/app/models/spree/ability.rb +34 -10
  17. data/app/models/spree/address.rb +103 -30
  18. data/app/models/spree/address/name.rb +49 -0
  19. data/app/models/spree/address/state_validator.rb +71 -0
  20. data/app/models/spree/adjustment.rb +21 -10
  21. data/app/models/spree/asset.rb +1 -1
  22. data/app/models/spree/base.rb +1 -2
  23. data/app/models/spree/calculator.rb +1 -1
  24. data/app/models/spree/calculator/default_tax.rb +1 -1
  25. data/app/models/spree/calculator/percent_per_item.rb +4 -4
  26. data/app/models/spree/calculator/price_sack.rb +1 -1
  27. data/app/models/spree/calculator/shipping/flexi_rate.rb +2 -2
  28. data/app/models/spree/calculator/tiered_flat_rate.rb +5 -5
  29. data/app/models/spree/calculator/tiered_percent.rb +6 -6
  30. data/app/models/spree/carton.rb +3 -3
  31. data/app/models/spree/classification.rb +2 -2
  32. data/app/models/spree/credit_card.rb +6 -6
  33. data/app/models/spree/customer_return.rb +5 -3
  34. data/app/models/spree/exchange.rb +1 -1
  35. data/app/models/spree/image/active_storage_attachment.rb +21 -0
  36. data/app/models/spree/image/paperclip_attachment.rb +1 -1
  37. data/app/models/spree/inventory_unit.rb +5 -23
  38. data/app/models/spree/line_item.rb +16 -7
  39. data/app/models/spree/line_item_action.rb +2 -2
  40. data/app/models/spree/log_entry.rb +1 -1
  41. data/app/models/spree/option_type.rb +1 -1
  42. data/app/models/spree/option_value.rb +3 -3
  43. data/app/models/spree/option_values_variant.rb +2 -2
  44. data/app/models/spree/order.rb +85 -30
  45. data/app/models/spree/order/checkout.rb +2 -1
  46. data/app/models/spree/order/payments.rb +2 -2
  47. data/app/models/spree/order_cancellations.rb +1 -1
  48. data/app/models/spree/order_capturing.rb +2 -2
  49. data/app/models/spree/order_contents.rb +2 -2
  50. data/app/models/spree/order_inventory.rb +16 -4
  51. data/app/models/spree/order_merger.rb +6 -4
  52. data/app/models/spree/order_mutex.rb +1 -1
  53. data/app/models/spree/order_promotion.rb +4 -4
  54. data/app/models/spree/order_shipping.rb +1 -1
  55. data/app/models/spree/order_taxation.rb +3 -3
  56. data/app/models/spree/order_updater.rb +11 -10
  57. data/app/models/spree/payment.rb +10 -47
  58. data/app/models/spree/payment/cancellation.rb +3 -3
  59. data/app/models/spree/payment/processing.rb +57 -33
  60. data/app/models/spree/payment_capture_event.rb +1 -1
  61. data/app/models/spree/payment_method.rb +13 -11
  62. data/app/models/spree/payment_method/bogus_credit_card.rb +1 -1
  63. data/app/models/spree/payment_source.rb +1 -1
  64. data/app/models/spree/preference.rb +1 -1
  65. data/app/models/spree/price.rb +3 -9
  66. data/app/models/spree/product.rb +24 -19
  67. data/app/models/spree/product/scopes.rb +223 -210
  68. data/app/models/spree/product_option_type.rb +2 -2
  69. data/app/models/spree/product_promotion_rule.rb +2 -2
  70. data/app/models/spree/product_property.rb +2 -2
  71. data/app/models/spree/promotion.rb +46 -20
  72. data/app/models/spree/promotion/actions/create_quantity_adjustments.rb +1 -1
  73. data/app/models/spree/promotion/actions/free_shipping.rb +6 -5
  74. data/app/models/spree/promotion/rules/option_value.rb +2 -2
  75. data/app/models/spree/promotion/rules/product.rb +3 -3
  76. data/app/models/spree/promotion_action.rb +3 -9
  77. data/app/models/spree/promotion_chooser.rb +2 -2
  78. data/app/models/spree/promotion_code.rb +17 -11
  79. data/app/models/spree/promotion_code/batch_builder.rb +3 -3
  80. data/app/models/spree/promotion_code_batch.rb +2 -2
  81. data/app/models/spree/promotion_handler/coupon.rb +2 -2
  82. data/app/models/spree/promotion_rule.rb +3 -3
  83. data/app/models/spree/promotion_rule_role.rb +3 -3
  84. data/app/models/spree/promotion_rule_store.rb +2 -2
  85. data/app/models/spree/promotion_rule_taxon.rb +2 -2
  86. data/app/models/spree/promotion_rule_user.rb +2 -2
  87. data/app/models/spree/refund.rb +59 -17
  88. data/app/models/spree/reimbursement.rb +32 -13
  89. data/app/models/spree/reimbursement/credit.rb +2 -2
  90. data/app/models/spree/reimbursement/reimbursement_type_engine.rb +1 -1
  91. data/app/models/spree/reimbursement_tax_calculator.rb +1 -1
  92. data/app/models/spree/reimbursement_type/reimbursement_helpers.rb +12 -5
  93. data/app/models/spree/return_authorization.rb +5 -11
  94. data/app/models/spree/return_item.rb +33 -61
  95. data/app/models/spree/return_item/eligibility_validator/default.rb +1 -1
  96. data/app/models/spree/return_item/exchange_variant_eligibility/same_option_value.rb +1 -1
  97. data/app/models/spree/role.rb +1 -1
  98. data/app/models/spree/role_user.rb +2 -2
  99. data/app/models/spree/shipment.rb +9 -43
  100. data/app/models/spree/shipping_calculator.rb +1 -5
  101. data/app/models/spree/shipping_manifest.rb +5 -5
  102. data/app/models/spree/shipping_method.rb +3 -10
  103. data/app/models/spree/shipping_method_category.rb +2 -2
  104. data/app/models/spree/shipping_method_stock_location.rb +2 -2
  105. data/app/models/spree/shipping_method_zone.rb +2 -2
  106. data/app/models/spree/shipping_rate.rb +2 -2
  107. data/app/models/spree/shipping_rate_tax.rb +3 -3
  108. data/app/models/spree/state.rb +2 -2
  109. data/app/models/spree/state_change.rb +2 -2
  110. data/app/models/spree/stock/differentiator.rb +1 -1
  111. data/app/models/spree/stock/inventory_unit_builder.rb +18 -7
  112. data/app/models/spree/stock/inventory_units_finalizer.rb +3 -5
  113. data/app/models/spree/stock/package.rb +2 -2
  114. data/app/models/spree/stock/simple_coordinator.rb +1 -3
  115. data/app/models/spree/stock_item.rb +4 -10
  116. data/app/models/spree/stock_location.rb +2 -2
  117. data/app/models/spree/stock_movement.rb +4 -2
  118. data/app/models/spree/stock_quantities.rb +13 -12
  119. data/app/models/spree/store.rb +1 -1
  120. data/app/models/spree/store_credit.rb +9 -15
  121. data/app/models/spree/store_credit_category.rb +30 -3
  122. data/app/models/spree/store_credit_event.rb +4 -10
  123. data/app/models/spree/store_credit_reason.rb +0 -4
  124. data/app/models/spree/store_payment_method.rb +2 -2
  125. data/app/models/spree/store_shipping_method.rb +2 -2
  126. data/app/models/spree/tax/tax_helpers.rb +1 -1
  127. data/app/models/spree/tax_calculator/default.rb +0 -4
  128. data/app/models/spree/tax_calculator/shipping_rate.rb +0 -3
  129. data/app/models/spree/tax_category.rb +2 -8
  130. data/app/models/spree/tax_rate.rb +12 -8
  131. data/app/models/spree/tax_rate_tax_category.rb +2 -2
  132. data/app/models/spree/taxon.rb +1 -1
  133. data/app/models/spree/taxon/active_storage_attachment.rb +19 -0
  134. data/app/models/spree/taxon/paperclip_attachment.rb +13 -0
  135. data/app/models/spree/unit_cancel.rb +5 -2
  136. data/app/models/spree/user_address.rb +10 -4
  137. data/app/models/spree/user_last_url_storer.rb +46 -0
  138. data/app/models/spree/user_last_url_storer/rules/authentication_rule.rb +36 -0
  139. data/app/models/spree/user_stock_location.rb +2 -2
  140. data/app/models/spree/variant.rb +17 -23
  141. data/app/models/spree/variant/scopes.rb +37 -29
  142. data/app/models/spree/variant_property_rule.rb +6 -2
  143. data/app/models/spree/variant_property_rule_condition.rb +2 -2
  144. data/app/models/spree/variant_property_rule_value.rb +2 -2
  145. data/app/models/spree/wallet/add_payment_sources_to_wallet.rb +9 -4
  146. data/app/models/spree/wallet_payment_source.rb +2 -2
  147. data/app/models/spree/zone.rb +2 -2
  148. data/app/models/spree/zone_member.rb +2 -2
  149. data/config/initializers/inflections.rb +5 -0
  150. data/config/initializers/money.rb +2 -0
  151. data/config/locales/en.yml +78 -8
  152. data/db/default/spree/countries.rb +1 -1
  153. data/db/default/spree/states.rb +12 -4
  154. data/db/default/spree/store_credit.rb +2 -2
  155. data/db/migrate/20180416083007_add_apply_to_all_to_variant_property_rule.rb +12 -0
  156. data/db/migrate/20200320144521_add_default_billng_flag_to_user_addresses.rb +6 -0
  157. data/db/migrate/20200530111458_add_bcc_email_to_spree_stores.rb +7 -0
  158. data/db/migrate/20201008213609_add_discontinue_on_to_spree_products.rb +7 -0
  159. data/lib/generators/solidus/install/install_generator.rb +253 -0
  160. data/lib/generators/{spree → solidus}/install/templates/config/initializers/spree.rb.tt +42 -3
  161. data/lib/generators/{spree → solidus}/install/templates/vendor/assets/javascripts/spree/backend/all.js +0 -0
  162. data/lib/generators/{spree → solidus}/install/templates/vendor/assets/javascripts/spree/frontend/all.js +0 -0
  163. data/lib/generators/{spree → solidus}/install/templates/vendor/assets/stylesheets/spree/backend/all.css +0 -0
  164. data/lib/generators/{spree → solidus}/install/templates/vendor/assets/stylesheets/spree/frontend/all.css +0 -0
  165. data/lib/generators/spree/dummy/dummy_generator.rb +2 -0
  166. data/lib/generators/spree/install/install_generator.rb +7 -189
  167. data/lib/solidus/migrations/promotions_with_code_handlers.rb +1 -1
  168. data/lib/spree/app_configuration.rb +135 -54
  169. data/lib/spree/awesome_nested_set_override.rb +44 -0
  170. data/lib/spree/core.rb +6 -0
  171. data/lib/spree/core/controller_helpers/auth.rb +18 -17
  172. data/lib/spree/core/controller_helpers/current_host.rb +17 -0
  173. data/lib/spree/core/controller_helpers/order.rb +8 -7
  174. data/lib/spree/core/engine.rb +41 -4
  175. data/lib/spree/core/importer/order.rb +47 -33
  176. data/lib/spree/core/importer/product.rb +2 -2
  177. data/lib/spree/core/permalinks.rb +1 -3
  178. data/lib/spree/core/product_filters.rb +16 -15
  179. data/lib/spree/core/role_configuration.rb +2 -2
  180. data/lib/spree/core/search/variant.rb +1 -1
  181. data/lib/spree/core/state_machines.rb +97 -0
  182. data/lib/spree/core/state_machines/inventory_unit.rb +42 -0
  183. data/lib/spree/core/state_machines/order.rb +249 -0
  184. data/lib/spree/core/state_machines/payment.rb +61 -0
  185. data/lib/spree/core/state_machines/reimbursement.rb +33 -0
  186. data/lib/spree/core/state_machines/return_authorization.rb +32 -0
  187. data/lib/spree/core/state_machines/return_item/acceptance_status.rb +51 -0
  188. data/lib/spree/core/state_machines/return_item/reception_status.rb +42 -0
  189. data/lib/spree/core/state_machines/shipment.rb +58 -0
  190. data/lib/spree/core/stock_configuration.rb +1 -0
  191. data/lib/spree/core/validators/email.rb +1 -8
  192. data/lib/spree/core/version.rb +1 -1
  193. data/lib/spree/encryptor.rb +25 -0
  194. data/lib/spree/event.rb +40 -7
  195. data/lib/spree/event/adapters/active_support_notifications.rb +32 -0
  196. data/lib/spree/event/configuration.rb +11 -6
  197. data/lib/spree/event/subscriber.rb +38 -18
  198. data/lib/spree/event/subscriber_registry.rb +92 -0
  199. data/lib/spree/i18n.rb +1 -1
  200. data/lib/spree/mailer_previews/carton_preview.rb +2 -1
  201. data/lib/spree/money.rb +2 -2
  202. data/lib/spree/paranoia_deprecations.rb +32 -12
  203. data/lib/spree/permission_sets/configuration_display.rb +14 -14
  204. data/lib/spree/permission_sets/default_customer.rb +16 -16
  205. data/lib/spree/permission_sets/order_display.rb +11 -11
  206. data/lib/spree/permission_sets/order_management.rb +1 -1
  207. data/lib/spree/permission_sets/product_display.rb +9 -9
  208. data/lib/spree/permission_sets/promotion_display.rb +5 -5
  209. data/lib/spree/permission_sets/restricted_stock_display.rb +2 -2
  210. data/lib/spree/permission_sets/restricted_stock_management.rb +1 -1
  211. data/lib/spree/permission_sets/stock_display.rb +2 -2
  212. data/lib/spree/permission_sets/stock_management.rb +1 -1
  213. data/lib/spree/permission_sets/user_display.rb +3 -3
  214. data/lib/spree/permission_sets/user_management.rb +7 -3
  215. data/lib/spree/permitted_attributes.rb +7 -6
  216. data/lib/spree/preferences/preferable.rb +4 -3
  217. data/lib/spree/preferences/preferable_class_methods.rb +22 -3
  218. data/lib/spree/preferences/static_model_preferences.rb +2 -2
  219. data/lib/spree/testing_support/ability_helpers.rb +9 -9
  220. data/lib/spree/testing_support/authorization_helpers.rb +1 -0
  221. data/lib/spree/testing_support/blacklist_urls.rb +23 -0
  222. data/lib/spree/testing_support/capybara_ext.rb +3 -0
  223. data/lib/spree/testing_support/common_rake.rb +3 -3
  224. data/lib/spree/testing_support/dummy_app.rb +45 -21
  225. data/lib/spree/testing_support/dummy_app/migrations.rb +5 -6
  226. data/lib/spree/testing_support/dummy_app/rake_tasks.rb +6 -4
  227. data/lib/spree/testing_support/factories/address_factory.rb +1 -2
  228. data/lib/spree/testing_support/factories/image_factory.rb +1 -1
  229. data/lib/spree/testing_support/factories/inventory_unit_factory.rb +8 -1
  230. data/lib/spree/testing_support/factories/promotion_factory.rb +13 -0
  231. data/lib/spree/testing_support/factories/refund_factory.rb +1 -0
  232. data/lib/spree/testing_support/factories/reimbursement_factory.rb +1 -1
  233. data/lib/spree/testing_support/factories/return_item_factory.rb +0 -1
  234. data/lib/spree/testing_support/factories/stock_package_factory.rb +1 -1
  235. data/lib/spree/testing_support/factories/store_credit_category_factory.rb +8 -0
  236. data/lib/spree/testing_support/factories/store_credit_event_factory.rb +1 -0
  237. data/lib/spree/testing_support/factories/store_credit_reason_factory.rb +3 -1
  238. data/lib/spree/testing_support/factories/taxon_factory.rb +4 -0
  239. data/lib/spree/testing_support/factories/user_factory.rb +4 -1
  240. data/lib/spree/testing_support/factories/zone_factory.rb +1 -1
  241. data/lib/spree/testing_support/job_helpers.rb +24 -0
  242. data/lib/spree/testing_support/precompiled_assets.rb +15 -0
  243. data/lib/spree/testing_support/preferences.rb +3 -1
  244. data/lib/spree/testing_support/shared_examples/gallery.rb +1 -1
  245. data/lib/spree/testing_support/translations.rb +25 -0
  246. data/solidus_core.gemspec +12 -9
  247. metadata +120 -393
  248. data/script/rails +0 -10
  249. data/spec/fixtures/thinking-cat.jpg +0 -0
  250. data/spec/helpers/base_helper_spec.rb +0 -168
  251. data/spec/helpers/products_helper_spec.rb +0 -202
  252. data/spec/helpers/taxons_helper_spec.rb +0 -43
  253. data/spec/jobs/promotion_code_batch_job_spec.rb +0 -96
  254. data/spec/lib/calculated_adjustments_spec.rb +0 -133
  255. data/spec/lib/i18n_spec.rb +0 -97
  256. data/spec/lib/search/base_spec.rb +0 -87
  257. data/spec/lib/search/variant_spec.rb +0 -115
  258. data/spec/lib/spree/app_configuration_spec.rb +0 -140
  259. data/spec/lib/spree/core/class_constantizer_spec.rb +0 -91
  260. data/spec/lib/spree/core/controller_helpers/auth_spec.rb +0 -73
  261. data/spec/lib/spree/core/controller_helpers/order_spec.rb +0 -126
  262. data/spec/lib/spree/core/controller_helpers/payment_parameters_spec.rb +0 -195
  263. data/spec/lib/spree/core/controller_helpers/pricing_spec.rb +0 -94
  264. data/spec/lib/spree/core/controller_helpers/search_spec.rb +0 -21
  265. data/spec/lib/spree/core/controller_helpers/store_spec.rb +0 -18
  266. data/spec/lib/spree/core/controller_helpers/strong_parameters_spec.rb +0 -48
  267. data/spec/lib/spree/core/current_store_spec.rb +0 -33
  268. data/spec/lib/spree/core/environment_extension_spec.rb +0 -46
  269. data/spec/lib/spree/core/importer/order_spec.rb +0 -484
  270. data/spec/lib/spree/core/role_configuration_spec.rb +0 -155
  271. data/spec/lib/spree/core/stock_configuration_spec.rb +0 -59
  272. data/spec/lib/spree/core/testing_support/factories/address_factory_spec.rb +0 -61
  273. data/spec/lib/spree/core/testing_support/factories/adjustment_factory_spec.rb +0 -20
  274. data/spec/lib/spree/core/testing_support/factories/adjustment_reason_factory_spec.rb +0 -14
  275. data/spec/lib/spree/core/testing_support/factories/calculator_factory_spec.rb +0 -44
  276. data/spec/lib/spree/core/testing_support/factories/carton_factory_spec.rb +0 -14
  277. data/spec/lib/spree/core/testing_support/factories/country_factory_spec.rb +0 -14
  278. data/spec/lib/spree/core/testing_support/factories/credit_card_factory_spec.rb +0 -14
  279. data/spec/lib/spree/core/testing_support/factories/customer_return_factory_spec.rb +0 -39
  280. data/spec/lib/spree/core/testing_support/factories/image_factory_spec.rb +0 -14
  281. data/spec/lib/spree/core/testing_support/factories/inventory_unit_factory_spec.rb +0 -14
  282. data/spec/lib/spree/core/testing_support/factories/line_item_factory_spec.rb +0 -14
  283. data/spec/lib/spree/core/testing_support/factories/option_type_factory_spec.rb +0 -14
  284. data/spec/lib/spree/core/testing_support/factories/option_value_factory_spec.rb +0 -14
  285. data/spec/lib/spree/core/testing_support/factories/order_factory_spec.rb +0 -376
  286. data/spec/lib/spree/core/testing_support/factories/order_promotion_factory_spec.rb +0 -14
  287. data/spec/lib/spree/core/testing_support/factories/payment_factory_spec.rb +0 -40
  288. data/spec/lib/spree/core/testing_support/factories/payment_method_factory_spec.rb +0 -32
  289. data/spec/lib/spree/core/testing_support/factories/price_factory_spec.rb +0 -14
  290. data/spec/lib/spree/core/testing_support/factories/product_factory_spec.rb +0 -32
  291. data/spec/lib/spree/core/testing_support/factories/product_option_type_factory_spec.rb +0 -14
  292. data/spec/lib/spree/core/testing_support/factories/product_property_factory_spec.rb +0 -14
  293. data/spec/lib/spree/core/testing_support/factories/promotion_category_factory_spec.rb +0 -14
  294. data/spec/lib/spree/core/testing_support/factories/promotion_code_factory_spec.rb +0 -14
  295. data/spec/lib/spree/core/testing_support/factories/promotion_factory_spec.rb +0 -32
  296. data/spec/lib/spree/core/testing_support/factories/property_factory_spec.rb +0 -14
  297. data/spec/lib/spree/core/testing_support/factories/refund_factory_spec.rb +0 -14
  298. data/spec/lib/spree/core/testing_support/factories/refund_reason_factory_spec.rb +0 -14
  299. data/spec/lib/spree/core/testing_support/factories/reimbursement_factory_spec.rb +0 -20
  300. data/spec/lib/spree/core/testing_support/factories/reimbursement_type_factory_spec.rb +0 -14
  301. data/spec/lib/spree/core/testing_support/factories/return_authorization_factory_spec.rb +0 -14
  302. data/spec/lib/spree/core/testing_support/factories/return_item_factory_spec.rb +0 -20
  303. data/spec/lib/spree/core/testing_support/factories/return_reason_factory_spec.rb +0 -14
  304. data/spec/lib/spree/core/testing_support/factories/role_factory_spec.rb +0 -20
  305. data/spec/lib/spree/core/testing_support/factories/shipment_factory_spec.rb +0 -14
  306. data/spec/lib/spree/core/testing_support/factories/shipping_category_factory_spec.rb +0 -14
  307. data/spec/lib/spree/core/testing_support/factories/shipping_method_factory_spec.rb +0 -44
  308. data/spec/lib/spree/core/testing_support/factories/shipping_rate_factory_spec.rb +0 -14
  309. data/spec/lib/spree/core/testing_support/factories/state_factory_spec.rb +0 -59
  310. data/spec/lib/spree/core/testing_support/factories/stock_item_factory_spec.rb +0 -14
  311. data/spec/lib/spree/core/testing_support/factories/stock_location_factory_spec.rb +0 -35
  312. data/spec/lib/spree/core/testing_support/factories/stock_movement_factory_spec.rb +0 -14
  313. data/spec/lib/spree/core/testing_support/factories/stock_package_factory_spec.rb +0 -28
  314. data/spec/lib/spree/core/testing_support/factories/store_credit_category_factory_spec.rb +0 -14
  315. data/spec/lib/spree/core/testing_support/factories/store_credit_event_factory_spec.rb +0 -43
  316. data/spec/lib/spree/core/testing_support/factories/store_credit_factory_spec.rb +0 -14
  317. data/spec/lib/spree/core/testing_support/factories/store_credit_reason_factory_spec.rb +0 -14
  318. data/spec/lib/spree/core/testing_support/factories/store_credit_type_factory_spec.rb +0 -20
  319. data/spec/lib/spree/core/testing_support/factories/store_factory_spec.rb +0 -14
  320. data/spec/lib/spree/core/testing_support/factories/tax_category_factory_spec.rb +0 -14
  321. data/spec/lib/spree/core/testing_support/factories/tax_rate_factory_spec.rb +0 -14
  322. data/spec/lib/spree/core/testing_support/factories/taxon_factory_spec.rb +0 -14
  323. data/spec/lib/spree/core/testing_support/factories/taxonomy_factory_spec.rb +0 -14
  324. data/spec/lib/spree/core/testing_support/factories/user_factory_spec.rb +0 -24
  325. data/spec/lib/spree/core/testing_support/factories/variant_factory_spec.rb +0 -56
  326. data/spec/lib/spree/core/testing_support/factories/variant_property_rule_condition_factory_spec.rb +0 -14
  327. data/spec/lib/spree/core/testing_support/factories/variant_property_rule_factory_spec.rb +0 -14
  328. data/spec/lib/spree/core/testing_support/factories/variant_property_rule_value_factory_spec.rb +0 -14
  329. data/spec/lib/spree/core/testing_support/factories/zone_factory_spec.rb +0 -20
  330. data/spec/lib/spree/core/testing_support/preferences_spec.rb +0 -61
  331. data/spec/lib/spree/core/validators/email_spec.rb +0 -53
  332. data/spec/lib/spree/core/version_spec.rb +0 -19
  333. data/spec/lib/spree/event/subscriber_spec.rb +0 -85
  334. data/spec/lib/spree/event_spec.rb +0 -118
  335. data/spec/lib/spree/localized_number_spec.rb +0 -45
  336. data/spec/lib/spree/migrations_spec.rb +0 -32
  337. data/spec/lib/spree/money_spec.rb +0 -298
  338. data/spec/lib/spree/permission_sets/default_customer_spec.rb +0 -22
  339. data/spec/lib/spree/permitted_attributes_spec.rb +0 -41
  340. data/spec/lib/spree/promo/environment_spec.rb +0 -53
  341. data/spec/lib/tasks/dummy_task.rake +0 -12
  342. data/spec/lib/tasks/dummy_task_spec.rb +0 -30
  343. data/spec/lib/tasks/migrations/migrate_shipping_rate_taxes_spec.rb +0 -21
  344. data/spec/mailers/carton_mailer_spec.rb +0 -44
  345. data/spec/mailers/order_mailer_spec.rb +0 -117
  346. data/spec/mailers/promotion_code_batch_mailer_spec.rb +0 -47
  347. data/spec/mailers/reimbursement_mailer_spec.rb +0 -36
  348. data/spec/mailers/test_mailer_spec.rb +0 -13
  349. data/spec/migrate/20190106184413_remove_code_from_spree_promotions_spec.rb +0 -148
  350. data/spec/models/spree/ability_spec.rb +0 -279
  351. data/spec/models/spree/address_spec.rb +0 -376
  352. data/spec/models/spree/adjustment_reason_spec.rb +0 -11
  353. data/spec/models/spree/adjustment_spec.rb +0 -339
  354. data/spec/models/spree/asset_spec.rb +0 -25
  355. data/spec/models/spree/calculator/default_tax_spec.rb +0 -260
  356. data/spec/models/spree/calculator/distributed_amount_spec.rb +0 -82
  357. data/spec/models/spree/calculator/flat_percent_item_total_spec.rb +0 -39
  358. data/spec/models/spree/calculator/flat_rate_spec.rb +0 -52
  359. data/spec/models/spree/calculator/flexi_rate_spec.rb +0 -158
  360. data/spec/models/spree/calculator/free_shipping_spec.rb +0 -8
  361. data/spec/models/spree/calculator/percent_on_line_item_spec.rb +0 -20
  362. data/spec/models/spree/calculator/percent_per_item_spec.rb +0 -12
  363. data/spec/models/spree/calculator/price_sack_spec.rb +0 -35
  364. data/spec/models/spree/calculator/refunds/default_refund_amount_spec.rb +0 -70
  365. data/spec/models/spree/calculator/shipping/flat_percent_item_total_spec.rb +0 -44
  366. data/spec/models/spree/calculator/shipping/flat_rate_spec.rb +0 -18
  367. data/spec/models/spree/calculator/shipping/flexi_rate_spec.rb +0 -56
  368. data/spec/models/spree/calculator/shipping/per_item_spec.rb +0 -25
  369. data/spec/models/spree/calculator/shipping/price_sack_spec.rb +0 -35
  370. data/spec/models/spree/calculator/tiered_flat_rate_spec.rb +0 -99
  371. data/spec/models/spree/calculator/tiered_percent_spec.rb +0 -197
  372. data/spec/models/spree/calculator_spec.rb +0 -43
  373. data/spec/models/spree/carton_spec.rb +0 -137
  374. data/spec/models/spree/classification_spec.rb +0 -114
  375. data/spec/models/spree/concerns/display_money_spec.rb +0 -44
  376. data/spec/models/spree/concerns/ordered_property_value_list_spec.rb +0 -52
  377. data/spec/models/spree/concerns/user_address_book_spec.rb +0 -358
  378. data/spec/models/spree/concerns/user_methods_spec.rb +0 -121
  379. data/spec/models/spree/country_spec.rb +0 -154
  380. data/spec/models/spree/credit_card_spec.rb +0 -373
  381. data/spec/models/spree/customer_return_spec.rb +0 -294
  382. data/spec/models/spree/distributed_amounts_handler_spec.rb +0 -83
  383. data/spec/models/spree/exchange_spec.rb +0 -76
  384. data/spec/models/spree/fulfilment_changer_spec.rb +0 -340
  385. data/spec/models/spree/gallery/product_gallery_spec.rb +0 -21
  386. data/spec/models/spree/gallery/variant_gallery_spec.rb +0 -21
  387. data/spec/models/spree/gateway/bogus_simple.rb +0 -14
  388. data/spec/models/spree/gateway/bogus_spec.rb +0 -14
  389. data/spec/models/spree/gateway_spec.rb +0 -14
  390. data/spec/models/spree/image_spec.rb +0 -25
  391. data/spec/models/spree/inventory_unit_spec.rb +0 -309
  392. data/spec/models/spree/line_item_spec.rb +0 -240
  393. data/spec/models/spree/option_type_spec.rb +0 -16
  394. data/spec/models/spree/option_value_spec.rb +0 -52
  395. data/spec/models/spree/order/address_spec.rb +0 -52
  396. data/spec/models/spree/order/adjustments_spec.rb +0 -29
  397. data/spec/models/spree/order/callbacks_spec.rb +0 -44
  398. data/spec/models/spree/order/checkout_spec.rb +0 -740
  399. data/spec/models/spree/order/finalizing_spec.rb +0 -92
  400. data/spec/models/spree/order/number_generator_spec.rb +0 -47
  401. data/spec/models/spree/order/outstanding_balance_integration_spec.rb +0 -138
  402. data/spec/models/spree/order/payment_spec.rb +0 -280
  403. data/spec/models/spree/order/risk_assessment_spec.rb +0 -70
  404. data/spec/models/spree/order/state_machine_spec.rb +0 -122
  405. data/spec/models/spree/order/totals_spec.rb +0 -26
  406. data/spec/models/spree/order/updating_spec.rb +0 -18
  407. data/spec/models/spree/order/validations_spec.rb +0 -17
  408. data/spec/models/spree/order_cancellations_spec.rb +0 -233
  409. data/spec/models/spree/order_capturing_spec.rb +0 -16
  410. data/spec/models/spree/order_contents_spec.rb +0 -362
  411. data/spec/models/spree/order_inventory_spec.rb +0 -285
  412. data/spec/models/spree/order_merger_spec.rb +0 -162
  413. data/spec/models/spree/order_mutex_spec.rb +0 -89
  414. data/spec/models/spree/order_promotion_spec.rb +0 -33
  415. data/spec/models/spree/order_shipping_spec.rb +0 -247
  416. data/spec/models/spree/order_spec.rb +0 -1694
  417. data/spec/models/spree/order_taxation_spec.rb +0 -128
  418. data/spec/models/spree/order_update_attributes_spec.rb +0 -49
  419. data/spec/models/spree/order_updater_spec.rb +0 -555
  420. data/spec/models/spree/payment/cancellation_spec.rb +0 -84
  421. data/spec/models/spree/payment_create_spec.rb +0 -205
  422. data/spec/models/spree/payment_method/bogus_credit_card_spec.rb +0 -10
  423. data/spec/models/spree/payment_method/check_spec.rb +0 -80
  424. data/spec/models/spree/payment_method/credit_card_spec.rb +0 -68
  425. data/spec/models/spree/payment_method/simple_bogus_credit_card_spec.rb +0 -20
  426. data/spec/models/spree/payment_method/store_credit_spec.rb +0 -325
  427. data/spec/models/spree/payment_method_spec.rb +0 -408
  428. data/spec/models/spree/payment_spec.rb +0 -1270
  429. data/spec/models/spree/permission_sets/base_spec.rb +0 -14
  430. data/spec/models/spree/permission_sets/configuration_display.rb +0 -79
  431. data/spec/models/spree/permission_sets/configuration_management_spec.rb +0 -49
  432. data/spec/models/spree/permission_sets/dashboard_display_spec.rb +0 -23
  433. data/spec/models/spree/permission_sets/order_display_spec.rb +0 -56
  434. data/spec/models/spree/permission_sets/order_management_spec.rb +0 -43
  435. data/spec/models/spree/permission_sets/product_display_spec.rb +0 -57
  436. data/spec/models/spree/permission_sets/product_management_spec.rb +0 -39
  437. data/spec/models/spree/permission_sets/promotion_display_spec.rb +0 -41
  438. data/spec/models/spree/permission_sets/promotion_management_spec.rb +0 -29
  439. data/spec/models/spree/permission_sets/restricted_stock_display_spec.rb +0 -42
  440. data/spec/models/spree/permission_sets/restricted_stock_management_spec.rb +0 -42
  441. data/spec/models/spree/permission_sets/stock_display_spec.rb +0 -25
  442. data/spec/models/spree/permission_sets/stock_management_spec.rb +0 -23
  443. data/spec/models/spree/permission_sets/user_display_spec.rb +0 -39
  444. data/spec/models/spree/permission_sets/user_management_spec.rb +0 -56
  445. data/spec/models/spree/preference_spec.rb +0 -79
  446. data/spec/models/spree/preferences/configuration_spec.rb +0 -27
  447. data/spec/models/spree/preferences/preferable_spec.rb +0 -334
  448. data/spec/models/spree/preferences/scoped_store_spec.rb +0 -62
  449. data/spec/models/spree/preferences/static_model_preferences_spec.rb +0 -79
  450. data/spec/models/spree/preferences/statically_configurable_spec.rb +0 -67
  451. data/spec/models/spree/preferences/store_spec.rb +0 -40
  452. data/spec/models/spree/price_spec.rb +0 -150
  453. data/spec/models/spree/product/scopes_spec.rb +0 -164
  454. data/spec/models/spree/product_duplicator_spec.rb +0 -92
  455. data/spec/models/spree/product_filter_spec.rb +0 -28
  456. data/spec/models/spree/product_property_spec.rb +0 -20
  457. data/spec/models/spree/product_spec.rb +0 -584
  458. data/spec/models/spree/promotion/actions/create_adjustment_spec.rb +0 -126
  459. data/spec/models/spree/promotion/actions/create_item_adjustments_spec.rb +0 -198
  460. data/spec/models/spree/promotion/actions/create_quantity_adjustments_spec.rb +0 -298
  461. data/spec/models/spree/promotion/actions/free_shipping_spec.rb +0 -61
  462. data/spec/models/spree/promotion/rules/first_order_spec.rb +0 -87
  463. data/spec/models/spree/promotion/rules/first_repeat_purchase_since_spec.rb +0 -71
  464. data/spec/models/spree/promotion/rules/item_total_spec.rb +0 -128
  465. data/spec/models/spree/promotion/rules/nth_order_spec.rb +0 -72
  466. data/spec/models/spree/promotion/rules/one_use_per_user_spec.rb +0 -54
  467. data/spec/models/spree/promotion/rules/option_value_spec.rb +0 -96
  468. data/spec/models/spree/promotion/rules/product_spec.rb +0 -193
  469. data/spec/models/spree/promotion/rules/store_spec.rb +0 -35
  470. data/spec/models/spree/promotion/rules/taxon_spec.rb +0 -227
  471. data/spec/models/spree/promotion/rules/user_logged_in_spec.rb +0 -33
  472. data/spec/models/spree/promotion/rules/user_role_spec.rb +0 -88
  473. data/spec/models/spree/promotion/rules/user_spec.rb +0 -39
  474. data/spec/models/spree/promotion_action_spec.rb +0 -44
  475. data/spec/models/spree/promotion_category_spec.rb +0 -19
  476. data/spec/models/spree/promotion_code/batch_builder_spec.rb +0 -107
  477. data/spec/models/spree/promotion_code_batch_spec.rb +0 -54
  478. data/spec/models/spree/promotion_code_spec.rb +0 -206
  479. data/spec/models/spree/promotion_handler/cart_spec.rb +0 -132
  480. data/spec/models/spree/promotion_handler/coupon_spec.rb +0 -419
  481. data/spec/models/spree/promotion_handler/page_spec.rb +0 -45
  482. data/spec/models/spree/promotion_handler/shipping_spec.rb +0 -96
  483. data/spec/models/spree/promotion_rule_spec.rb +0 -34
  484. data/spec/models/spree/promotion_spec.rb +0 -928
  485. data/spec/models/spree/refund_spec.rb +0 -200
  486. data/spec/models/spree/reimbursement/credit_spec.rb +0 -38
  487. data/spec/models/spree/reimbursement/reimbursement_type_engine_spec.rb +0 -144
  488. data/spec/models/spree/reimbursement/reimbursement_type_validator_spec.rb +0 -85
  489. data/spec/models/spree/reimbursement_performer_spec.rb +0 -33
  490. data/spec/models/spree/reimbursement_spec.rb +0 -278
  491. data/spec/models/spree/reimbursement_tax_calculator_spec.rb +0 -52
  492. data/spec/models/spree/reimbursement_type/credit_spec.rb +0 -56
  493. data/spec/models/spree/reimbursement_type/exchange_spec.rb +0 -48
  494. data/spec/models/spree/reimbursement_type/original_payment_spec.rb +0 -110
  495. data/spec/models/spree/reimbursement_type/store_credit_spec.rb +0 -111
  496. data/spec/models/spree/return_authorization_spec.rb +0 -226
  497. data/spec/models/spree/return_item/eligibility_validator/default_spec.rb +0 -79
  498. data/spec/models/spree/return_item/eligibility_validator/inventory_shipped_spec.rb +0 -59
  499. data/spec/models/spree/return_item/eligibility_validator/no_reimbursements_spec.rb +0 -86
  500. data/spec/models/spree/return_item/eligibility_validator/order_completed_spec.rb +0 -35
  501. data/spec/models/spree/return_item/eligibility_validator/rma_required_spec.rb +0 -31
  502. data/spec/models/spree/return_item/eligibility_validator/time_since_purchase_spec.rb +0 -42
  503. data/spec/models/spree/return_item/exchange_variant_eligibility/same_option_value_spec.rb +0 -66
  504. data/spec/models/spree/return_item/exchange_variant_eligibility/same_product_spec.rb +0 -43
  505. data/spec/models/spree/return_item_spec.rb +0 -785
  506. data/spec/models/spree/returns_calculator_spec.rb +0 -16
  507. data/spec/models/spree/shipment_spec.rb +0 -914
  508. data/spec/models/spree/shipping_calculator_spec.rb +0 -57
  509. data/spec/models/spree/shipping_manifest_spec.rb +0 -110
  510. data/spec/models/spree/shipping_method_spec.rb +0 -260
  511. data/spec/models/spree/shipping_rate_spec.rb +0 -154
  512. data/spec/models/spree/shipping_rate_tax_spec.rb +0 -79
  513. data/spec/models/spree/state_spec.rb +0 -43
  514. data/spec/models/spree/stock/allocator/on_hand_first_spec.rb +0 -146
  515. data/spec/models/spree/stock/availability_spec.rb +0 -143
  516. data/spec/models/spree/stock/availability_validator_spec.rb +0 -140
  517. data/spec/models/spree/stock/content_item_spec.rb +0 -70
  518. data/spec/models/spree/stock/differentiator_spec.rb +0 -41
  519. data/spec/models/spree/stock/estimator_spec.rb +0 -241
  520. data/spec/models/spree/stock/inventory_unit_builder_spec.rb +0 -34
  521. data/spec/models/spree/stock/inventory_units_finalizer_spec.rb +0 -58
  522. data/spec/models/spree/stock/location_filter/active_spec.rb +0 -22
  523. data/spec/models/spree/stock/location_sorter/default_first_spec.rb +0 -22
  524. data/spec/models/spree/stock/location_sorter/unsorted_spec.rb +0 -21
  525. data/spec/models/spree/stock/package_spec.rb +0 -182
  526. data/spec/models/spree/stock/quantifier_spec.rb +0 -113
  527. data/spec/models/spree/stock/shipping_rate_selector_spec.rb +0 -18
  528. data/spec/models/spree/stock/shipping_rate_sorter_spec.rb +0 -18
  529. data/spec/models/spree/stock/simple_coordinator_spec.rb +0 -264
  530. data/spec/models/spree/stock/splitter/backordered_spec.rb +0 -31
  531. data/spec/models/spree/stock/splitter/base_spec.rb +0 -22
  532. data/spec/models/spree/stock/splitter/shipping_category_spec.rb +0 -48
  533. data/spec/models/spree/stock/splitter/weight_spec.rb +0 -31
  534. data/spec/models/spree/stock/splitter_chain_spec.rb +0 -66
  535. data/spec/models/spree/stock_item_spec.rb +0 -348
  536. data/spec/models/spree/stock_location_spec.rb +0 -288
  537. data/spec/models/spree/stock_movement_spec.rb +0 -58
  538. data/spec/models/spree/stock_quantities_spec.rb +0 -249
  539. data/spec/models/spree/store_credit_category_spec.rb +0 -19
  540. data/spec/models/spree/store_credit_event_spec.rb +0 -328
  541. data/spec/models/spree/store_credit_spec.rb +0 -900
  542. data/spec/models/spree/store_selector/by_server_name_spec.rb +0 -28
  543. data/spec/models/spree/store_selector/legacy_spec.rb +0 -46
  544. data/spec/models/spree/store_spec.rb +0 -156
  545. data/spec/models/spree/tax/order_adjuster_spec.rb +0 -35
  546. data/spec/models/spree/tax/shipping_rate_taxer_spec.rb +0 -59
  547. data/spec/models/spree/tax/tax_location_spec.rb +0 -79
  548. data/spec/models/spree/tax/taxation_integration_spec.rb +0 -815
  549. data/spec/models/spree/tax_calculator/default_spec.rb +0 -56
  550. data/spec/models/spree/tax_category_spec.rb +0 -50
  551. data/spec/models/spree/tax_rate_spec.rb +0 -316
  552. data/spec/models/spree/taxon_spec.rb +0 -197
  553. data/spec/models/spree/taxonomy_spec.rb +0 -15
  554. data/spec/models/spree/unit_cancel_spec.rb +0 -121
  555. data/spec/models/spree/user_spec.rb +0 -247
  556. data/spec/models/spree/validations/db_maximum_length_validator_spec.rb +0 -33
  557. data/spec/models/spree/variant/price_selector_spec.rb +0 -90
  558. data/spec/models/spree/variant/pricing_options_spec.rb +0 -204
  559. data/spec/models/spree/variant/scopes_spec.rb +0 -94
  560. data/spec/models/spree/variant/vat_price_generator_spec.rb +0 -77
  561. data/spec/models/spree/variant_property_rule_condition_spec.rb +0 -17
  562. data/spec/models/spree/variant_property_rule_spec.rb +0 -85
  563. data/spec/models/spree/variant_property_rule_value_spec.rb +0 -20
  564. data/spec/models/spree/variant_spec.rb +0 -862
  565. data/spec/models/spree/wallet_payment_source_spec.rb +0 -77
  566. data/spec/models/spree/wallet_spec.rb +0 -155
  567. data/spec/models/spree/zone_spec.rb +0 -248
  568. data/spec/rails_helper.rb +0 -46
  569. data/spec/shared_examples/calculator_shared_examples.rb +0 -10
  570. data/spec/spec_helper.rb +0 -36
  571. data/spec/support/big_decimal.rb +0 -7
  572. data/spec/support/concerns/default_price.rb +0 -44
  573. data/spec/support/concerns/payment_source.rb +0 -66
  574. data/spec/support/concerns/working_factories.rb +0 -15
  575. data/spec/support/dummy_ability.rb +0 -7
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'discard'
4
-
5
3
  module Spree
6
4
  # Products represent an entity for sale in a store. Products can have
7
5
  # variations, called variants. Product properties include description,
@@ -15,17 +13,13 @@ module Spree
15
13
  extend FriendlyId
16
14
  friendly_id :slug_candidates, use: :history
17
15
 
18
- acts_as_paranoid
19
- include Spree::ParanoiaDeprecations
20
-
21
- include Discard::Model
22
- self.discard_column = :deleted_at
16
+ include Spree::SoftDeletable
23
17
 
24
18
  after_discard do
25
19
  variants_including_master.discard_all
26
20
  self.product_option_types = []
27
21
  self.product_properties = []
28
- self.classifications = []
22
+ self.classifications.destroy_all
29
23
  self.product_promotion_rules = []
30
24
  end
31
25
 
@@ -44,11 +38,11 @@ module Spree
44
38
  has_many :product_promotion_rules, dependent: :destroy
45
39
  has_many :promotion_rules, through: :product_promotion_rules
46
40
 
47
- belongs_to :tax_category, class_name: 'Spree::TaxCategory'
48
- belongs_to :shipping_category, class_name: 'Spree::ShippingCategory', inverse_of: :products
41
+ belongs_to :tax_category, class_name: 'Spree::TaxCategory', optional: true
42
+ belongs_to :shipping_category, class_name: 'Spree::ShippingCategory', inverse_of: :products, optional: true
49
43
 
50
44
  has_one :master,
51
- -> { where(is_master: true).with_deleted },
45
+ -> { where(is_master: true).with_discarded },
52
46
  inverse_of: :product,
53
47
  class_name: 'Spree::Variant',
54
48
  autosave: true
@@ -121,7 +115,7 @@ module Spree
121
115
  validates :name, presence: true
122
116
  validates :price, presence: true, if: proc { Spree::Config[:require_master_price] }
123
117
  validates :shipping_category_id, presence: true
124
- validates :slug, presence: true, uniqueness: { allow_blank: true }
118
+ validates :slug, presence: true, uniqueness: { allow_blank: true, case_sensitive: true }
125
119
 
126
120
  attr_accessor :option_values_hash
127
121
 
@@ -134,7 +128,7 @@ module Spree
134
128
  self.whitelisted_ransackable_attributes = %w[name slug]
135
129
 
136
130
  def self.ransackable_scopes(_auth_object = nil)
137
- %i(with_deleted with_variant_sku_cont)
131
+ %i(with_discarded with_variant_sku_cont)
138
132
  end
139
133
 
140
134
  # @return [Boolean] true if there are any variants
@@ -174,11 +168,22 @@ module Spree
174
168
  end
175
169
 
176
170
  # Determines if product is available. A product is available if it has not
177
- # been deleted and the available_on date is in the past.
171
+ # been deleted, the available_on date is in the past
172
+ # and the discontinue_on date is nil or in the future.
178
173
  #
179
174
  # @return [Boolean] true if this product is available
180
175
  def available?
181
- !(available_on.nil? || available_on.future?) && !deleted?
176
+ !deleted? && available_on&.past? && !discontinued?
177
+ end
178
+
179
+ # Determines if product is discontinued.
180
+ #
181
+ # A product is discontinued if the discontinue_on date
182
+ # is not nil and in the past.
183
+ #
184
+ # @return [Boolean] true if this product is discontinued
185
+ def discontinued?
186
+ !!discontinue_on&.past?
182
187
  end
183
188
 
184
189
  # Groups variants by the specified option type.
@@ -190,7 +195,7 @@ module Spree
190
195
  # @return [Hash] option_type as keys, array of variants as values.
191
196
  def categorise_variants_from_option(opt_type, pricing_options = Spree::Config.default_pricing_options)
192
197
  return {} unless option_types.include?(opt_type)
193
- variants.with_prices(pricing_options).group_by { |v| v.option_values.detect { |o| o.option_type == opt_type } }
198
+ variants.with_prices(pricing_options).group_by { |variant| variant.option_values.detect { |option| option.option_type == opt_type } }
194
199
  end
195
200
  deprecate :categorise_variants_from_option, deprecator: Spree::Deprecation
196
201
 
@@ -323,7 +328,7 @@ module Spree
323
328
 
324
329
  def any_variants_not_track_inventory?
325
330
  if variants_including_master.loaded?
326
- variants_including_master.any? { |v| !v.should_track_inventory? }
331
+ variants_including_master.any? { |variant| !variant.should_track_inventory? }
327
332
  else
328
333
  !Spree::Config.track_inventory_levels || variants_including_master.where(track_inventory: false).exists?
329
334
  end
@@ -381,11 +386,11 @@ module Spree
381
386
 
382
387
  # Iterate through this product's taxons and taxonomies and touch their timestamps in a batch
383
388
  def touch_taxons
384
- taxons_to_touch = taxons.map(&:self_and_ancestors).flatten.uniq
389
+ taxons_to_touch = taxons.flat_map(&:self_and_ancestors).uniq
385
390
  unless taxons_to_touch.empty?
386
391
  Spree::Taxon.where(id: taxons_to_touch.map(&:id)).update_all(updated_at: Time.current)
387
392
 
388
- taxonomy_ids_to_touch = taxons_to_touch.map(&:taxonomy_id).flatten.uniq
393
+ taxonomy_ids_to_touch = taxons_to_touch.flat_map(&:taxonomy_id).uniq
389
394
  Spree::Taxonomy.where(id: taxonomy_ids_to_touch).update_all(updated_at: Time.current)
390
395
  end
391
396
  end
@@ -2,159 +2,164 @@
2
2
 
3
3
  module Spree
4
4
  class Product < Spree::Base
5
- cattr_accessor :search_scopes do
6
- []
7
- end
5
+ module Scopes
6
+ def self.prepended(base)
7
+ base.class_eval do
8
+ cattr_accessor :search_scopes do
9
+ []
10
+ end
8
11
 
9
- def self.add_search_scope(name, &block)
10
- singleton_class.send(:define_method, name.to_sym, &block)
11
- search_scopes << name.to_sym
12
- end
12
+ def self.add_search_scope(name, &block)
13
+ singleton_class.send(:define_method, name.to_sym, &block)
14
+ search_scopes << name.to_sym
15
+ end
13
16
 
14
- def self.property_conditions(property)
15
- properties = Property.table_name
16
- case property
17
- when String then { "#{properties}.name" => property }
18
- when Property then { "#{properties}.id" => property.id }
19
- else { "#{properties}.id" => property.to_i }
20
- end
21
- end
17
+ def self.property_conditions(property)
18
+ properties = Property.table_name
19
+ case property
20
+ when String then { "#{properties}.name" => property }
21
+ when Property then { "#{properties}.id" => property.id }
22
+ else { "#{properties}.id" => property.to_i }
23
+ end
24
+ end
22
25
 
23
- scope :ascend_by_updated_at, -> { order(updated_at: :asc) }
24
- scope :descend_by_updated_at, -> { order(updated_at: :desc) }
25
- scope :ascend_by_name, -> { order(name: :asc) }
26
- scope :descend_by_name, -> { order(name: :desc) }
26
+ scope :ascend_by_updated_at, -> { order(updated_at: :asc) }
27
+ scope :descend_by_updated_at, -> { order(updated_at: :desc) }
28
+ scope :ascend_by_name, -> { order(name: :asc) }
29
+ scope :descend_by_name, -> { order(name: :desc) }
27
30
 
28
- add_search_scope :ascend_by_master_price do
29
- joins(master: :default_price).order(Spree::Price.arel_table[:amount].asc)
30
- end
31
+ add_search_scope :ascend_by_master_price do
32
+ joins(master: :default_price).select('spree_products.* , spree_prices.amount')
33
+ .order(Spree::Price.arel_table[:amount].asc)
34
+ end
31
35
 
32
- add_search_scope :descend_by_master_price do
33
- joins(master: :default_price).order(Spree::Price.arel_table[:amount].desc)
34
- end
36
+ add_search_scope :descend_by_master_price do
37
+ joins(master: :default_price).select('spree_products.* , spree_prices.amount')
38
+ .order(Spree::Price.arel_table[:amount].desc)
39
+ end
35
40
 
36
- add_search_scope :price_between do |low, high|
37
- joins(master: :default_price).where(Price.table_name => { amount: low..high })
38
- end
41
+ add_search_scope :price_between do |low, high|
42
+ joins(master: :default_price).where(Price.table_name => { amount: low..high })
43
+ end
39
44
 
40
- add_search_scope :master_price_lte do |price|
41
- joins(master: :default_price).where("#{price_table_name}.amount <= ?", price)
42
- end
45
+ add_search_scope :master_price_lte do |price|
46
+ joins(master: :default_price).where("#{price_table_name}.amount <= ?", price)
47
+ end
43
48
 
44
- add_search_scope :master_price_gte do |price|
45
- joins(master: :default_price).where("#{price_table_name}.amount >= ?", price)
46
- end
49
+ add_search_scope :master_price_gte do |price|
50
+ joins(master: :default_price).where("#{price_table_name}.amount >= ?", price)
51
+ end
47
52
 
48
- # This scope selects products in taxon AND all its descendants
49
- # If you need products only within one taxon use
50
- #
51
- # Spree::Product.joins(:taxons).where(Taxon.table_name => { id: taxon.id })
52
- #
53
- # If you're using count on the result of this scope, you must use the
54
- # `:distinct` option as well:
55
- #
56
- # Spree::Product.in_taxon(taxon).count(distinct: true)
57
- #
58
- # This is so that the count query is distinct'd:
59
- #
60
- # SELECT COUNT(DISTINCT "spree_products"."id") ...
61
- #
62
- # vs.
63
- #
64
- # SELECT COUNT(*) ...
65
- add_search_scope :in_taxon do |taxon|
66
- includes(:classifications)
67
- .where('spree_products_taxons.taxon_id' => taxon.self_and_descendants.pluck(:id))
68
- .select(Spree::Classification.arel_table[:position])
69
- .order(Spree::Classification.arel_table[:position].asc)
70
- end
53
+ # This scope selects products in taxon AND all its descendants
54
+ # If you need products only within one taxon use
55
+ #
56
+ # Spree::Product.joins(:taxons).where(Taxon.table_name => { id: taxon.id })
57
+ #
58
+ # If you're using count on the result of this scope, you must use the
59
+ # `:distinct` option as well:
60
+ #
61
+ # Spree::Product.in_taxon(taxon).count(distinct: true)
62
+ #
63
+ # This is so that the count query is distinct'd:
64
+ #
65
+ # SELECT COUNT(DISTINCT "spree_products"."id") ...
66
+ #
67
+ # vs.
68
+ #
69
+ # SELECT COUNT(*) ...
70
+ add_search_scope :in_taxon do |taxon|
71
+ includes(:classifications)
72
+ .where('spree_products_taxons.taxon_id' => taxon.self_and_descendants.pluck(:id))
73
+ .select(Spree::Classification.arel_table[:position])
74
+ .order(Spree::Classification.arel_table[:position].asc)
75
+ end
71
76
 
72
- # This scope selects products in all taxons AND all its descendants
73
- # If you need products only within one taxon use
74
- #
75
- # Spree::Product.taxons_id_eq([x,y])
76
- add_search_scope :in_taxons do |*taxons|
77
- taxons = get_taxons(taxons)
78
- taxons.first ? prepare_taxon_conditions(taxons) : where(nil)
79
- end
77
+ # This scope selects products in all taxons AND all its descendants
78
+ # If you need products only within one taxon use
79
+ #
80
+ # Spree::Product.taxons_id_eq([x,y])
81
+ add_search_scope :in_taxons do |*taxons|
82
+ taxons = get_taxons(taxons)
83
+ taxons.first ? prepare_taxon_conditions(taxons) : where(nil)
84
+ end
80
85
 
81
- # a scope that finds all products having property specified by name, object or id
82
- add_search_scope :with_property do |property|
83
- joins(:properties).where(property_conditions(property))
84
- end
86
+ # a scope that finds all products having property specified by name, object or id
87
+ add_search_scope :with_property do |property|
88
+ joins(:properties).where(property_conditions(property))
89
+ end
85
90
 
86
- # a simple test for product with a certain property-value pairing
87
- # note that it can test for properties with NULL values, but not for absent values
88
- add_search_scope :with_property_value do |property, value|
89
- joins(:properties)
90
- .where("#{Spree::ProductProperty.table_name}.value = ?", value)
91
- .where(property_conditions(property))
92
- end
91
+ # a simple test for product with a certain property-value pairing
92
+ # note that it can test for properties with NULL values, but not for absent values
93
+ add_search_scope :with_property_value do |property, value|
94
+ joins(:properties)
95
+ .where("#{Spree::ProductProperty.table_name}.value = ?", value)
96
+ .where(property_conditions(property))
97
+ end
93
98
 
94
- add_search_scope :with_option do |option|
95
- option_types = Spree::OptionType.table_name
96
- conditions = case option
97
- when String then { "#{option_types}.name" => option }
98
- when OptionType then { "#{option_types}.id" => option.id }
99
- else { "#{option_types}.id" => option.to_i }
100
- end
99
+ add_search_scope :with_option do |option|
100
+ option_types = Spree::OptionType.table_name
101
+ conditions = case option
102
+ when String then { "#{option_types}.name" => option }
103
+ when OptionType then { "#{option_types}.id" => option.id }
104
+ else { "#{option_types}.id" => option.to_i }
105
+ end
101
106
 
102
- joins(:option_types).where(conditions)
103
- end
107
+ joins(:option_types).where(conditions)
108
+ end
104
109
 
105
- add_search_scope :with_option_value do |option, value|
106
- option_values = Spree::OptionValue.table_name
107
- option_type_id = case option
108
- when String then Spree::OptionType.find_by(name: option) || option.to_i
109
- when Spree::OptionType then option.id
110
- else option.to_i
111
- end
110
+ add_search_scope :with_option_value do |option, value|
111
+ option_values = Spree::OptionValue.table_name
112
+ option_type_id = case option
113
+ when String then Spree::OptionType.find_by(name: option) || option.to_i
114
+ when Spree::OptionType then option.id
115
+ else option.to_i
116
+ end
112
117
 
113
- conditions = "#{option_values}.name = ? AND #{option_values}.option_type_id = ?", value, option_type_id
114
- group('spree_products.id').joins(variants_including_master: :option_values).where(conditions)
115
- end
118
+ conditions = "#{option_values}.name = ? AND #{option_values}.option_type_id = ?", value, option_type_id
119
+ group('spree_products.id').joins(variants_including_master: :option_values).where(conditions)
120
+ end
116
121
 
117
- # Finds all products which have either:
118
- # 1) have an option value with the name matching the one given
119
- # 2) have a product property with a value matching the one given
120
- add_search_scope :with do |value|
121
- includes(variants_including_master: :option_values).
122
- includes(:product_properties).
123
- where("#{Spree::OptionValue.table_name}.name = ? OR #{Spree::ProductProperty.table_name}.value = ?", value, value)
124
- end
122
+ # Finds all products which have either:
123
+ # 1) have an option value with the name matching the one given
124
+ # 2) have a product property with a value matching the one given
125
+ add_search_scope :with do |value|
126
+ includes(variants_including_master: :option_values).
127
+ includes(:product_properties).
128
+ where("#{Spree::OptionValue.table_name}.name = ? OR #{Spree::ProductProperty.table_name}.value = ?", value, value)
129
+ end
125
130
 
126
- # Finds all products that have a name containing the given words.
127
- add_search_scope :in_name do |words|
128
- like_any([:name], prepare_words(words))
129
- end
131
+ # Finds all products that have a name containing the given words.
132
+ add_search_scope :in_name do |words|
133
+ like_any([:name], prepare_words(words))
134
+ end
130
135
 
131
- # Finds all products that have a name or meta_keywords containing the given words.
132
- add_search_scope :in_name_or_keywords do |words|
133
- like_any([:name, :meta_keywords], prepare_words(words))
134
- end
136
+ # Finds all products that have a name or meta_keywords containing the given words.
137
+ add_search_scope :in_name_or_keywords do |words|
138
+ like_any([:name, :meta_keywords], prepare_words(words))
139
+ end
135
140
 
136
- # Finds all products that have a name, description, meta_description or meta_keywords containing the given keywords.
137
- add_search_scope :in_name_or_description do |words|
138
- like_any([:name, :description, :meta_description, :meta_keywords], prepare_words(words))
139
- end
141
+ # Finds all products that have a name, description, meta_description or meta_keywords containing the given keywords.
142
+ add_search_scope :in_name_or_description do |words|
143
+ like_any([:name, :description, :meta_description, :meta_keywords], prepare_words(words))
144
+ end
140
145
 
141
- # Finds all products that have the ids matching the given collection of ids.
142
- # Alternatively, you could use find(collection_of_ids), but that would raise an exception if one product couldn't be found
143
- add_search_scope :with_ids do |*ids|
144
- where(id: ids)
145
- end
146
+ # Finds all products that have the ids matching the given collection of ids.
147
+ # Alternatively, you could use find(collection_of_ids), but that would raise an exception if one product couldn't be found
148
+ add_search_scope :with_ids do |*ids|
149
+ where(id: ids)
150
+ end
146
151
 
147
- # Sorts products from most popular (popularity is extracted from how many
148
- # times use has put product in cart, not completed orders)
149
- #
150
- # there is alternative faster and more elegant solution, it has small drawback though,
151
- # it doesn stack with other scopes :/
152
- #
153
- # joins: "LEFT OUTER JOIN (SELECT line_items.variant_id as vid, COUNT(*) as cnt FROM line_items GROUP BY line_items.variant_id) AS popularity_count ON variants.id = vid",
154
- # order: 'COALESCE(cnt, 0) DESC'
155
- add_search_scope :descend_by_popularity do
156
- joins(:master).
157
- order(%{
152
+ # Sorts products from most popular (popularity is extracted from how many
153
+ # times use has put product in cart, not completed orders)
154
+ #
155
+ # there is alternative faster and more elegant solution, it has small drawback though,
156
+ # it doesn stack with other scopes :/
157
+ #
158
+ # joins: "LEFT OUTER JOIN (SELECT line_items.variant_id as vid, COUNT(*) as cnt FROM line_items GROUP BY line_items.variant_id) AS popularity_count ON variants.id = vid",
159
+ # order: 'COALESCE(cnt, 0) DESC'
160
+ add_search_scope :descend_by_popularity do
161
+ joins(:master).
162
+ order(%{
158
163
  COALESCE((
159
164
  SELECT
160
165
  COUNT(#{Spree::LineItem.quoted_table_name}.id)
@@ -168,93 +173,101 @@ module Spree
168
173
  popular_variants.product_id = #{Spree::Product.quoted_table_name}.id
169
174
  ), 0) DESC
170
175
  })
171
- end
172
-
173
- add_search_scope :not_deleted do
174
- where("#{Spree::Product.quoted_table_name}.deleted_at IS NULL or #{Spree::Product.quoted_table_name}.deleted_at >= ?", Time.current)
175
- end
176
-
177
- scope :with_master_price, -> do
178
- joins(:master).where(Spree::Price.where(Spree::Variant.arel_table[:id].eq(Spree::Price.arel_table[:variant_id])).arel.exists)
179
- end
180
-
181
- # Can't use add_search_scope for this as it needs a default argument
182
- def self.available(available_on = nil)
183
- with_master_price.where("#{Spree::Product.quoted_table_name}.available_on <= ?", available_on || Time.current)
184
- end
185
- search_scopes << :available
186
-
187
- add_search_scope :taxons_name_eq do |name|
188
- group("spree_products.id").joins(:taxons).where(Spree::Taxon.arel_table[:name].eq(name))
189
- end
190
-
191
- def self.with_variant_sku_cont(sku)
192
- sku_match = "%#{sku}%"
193
- variant_table = Spree::Variant.arel_table
194
- subquery = Spree::Variant.where(variant_table[:sku].matches(sku_match).and(variant_table[:product_id].eq(arel_table[:id])))
195
- where(subquery.arel.exists)
196
- end
176
+ end
197
177
 
198
- def self.distinct_by_product_ids(sort_order = nil)
199
- Spree::Deprecation.warn "Product.distinct_by_product_ids is deprecated and should not be used"
200
-
201
- sort_column = sort_order.split(" ").first
202
-
203
- # Postgres will complain when using ordering by expressions not present in
204
- # SELECT DISTINCT. e.g.
205
- #
206
- # PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY
207
- # expressions must appear in select list. e.g.
208
- #
209
- # SELECT DISTINCT "spree_products".* FROM "spree_products" LEFT OUTER JOIN
210
- # "spree_variants" ON "spree_variants"."product_id" = "spree_products"."id" AND "spree_variants"."is_master" = 't'
211
- # AND "spree_variants"."deleted_at" IS NULL LEFT OUTER JOIN "spree_prices" ON
212
- # "spree_prices"."variant_id" = "spree_variants"."id" AND "spree_prices"."currency" = 'USD'
213
- # AND "spree_prices"."deleted_at" IS NULL WHERE "spree_products"."deleted_at" IS NULL AND ('t'='t')
214
- # ORDER BY "spree_prices"."amount" ASC LIMIT 10 OFFSET 0
215
- #
216
- # Don't allow sort_column, a variable coming from params,
217
- # to be anything but a column in the database
218
- if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' && !column_names.include?(sort_column)
219
- all
220
- else
221
- distinct
222
- end
223
- end
178
+ add_search_scope :not_deleted do
179
+ where("#{Spree::Product.quoted_table_name}.deleted_at IS NULL or #{Spree::Product.quoted_table_name}.deleted_at >= ?", Time.current)
180
+ end
224
181
 
225
- class << self
226
- private
182
+ scope :with_master_price, -> do
183
+ joins(:master).where(Spree::Price.where(Spree::Variant.arel_table[:id].eq(Spree::Price.arel_table[:variant_id])).arel.exists)
184
+ end
185
+ # Can't use add_search_scope for this as it needs a default argument
186
+ def self.available(available_on = nil)
187
+ with_master_price
188
+ .where("#{Spree::Product.quoted_table_name}.available_on <= ?", available_on || Time.current)
189
+ .where("#{Spree::Product.quoted_table_name}.discontinue_on IS NULL OR" \
190
+ "#{Spree::Product.quoted_table_name}.discontinue_on >= ?", Time.current)
191
+ end
192
+ search_scopes << :available
227
193
 
228
- def price_table_name
229
- Spree::Price.quoted_table_name
230
- end
194
+ add_search_scope :taxons_name_eq do |name|
195
+ group("spree_products.id").joins(:taxons).where(Spree::Taxon.arel_table[:name].eq(name))
196
+ end
231
197
 
232
- # specifically avoid having an order for taxon search (conflicts with main order)
233
- def prepare_taxon_conditions(taxons)
234
- ids = taxons.map { |taxon| taxon.self_and_descendants.pluck(:id) }.flatten.uniq
235
- joins(:taxons).where("#{Spree::Taxon.table_name}.id" => ids)
236
- end
198
+ def self.with_variant_sku_cont(sku)
199
+ sku_match = "%#{sku}%"
200
+ variant_table = Spree::Variant.arel_table
201
+ subquery = Spree::Variant.where(variant_table[:sku].matches(sku_match).and(variant_table[:product_id].eq(arel_table[:id])))
202
+ where(subquery.arel.exists)
203
+ end
237
204
 
238
- # Produce an array of keywords for use in scopes.
239
- # Always return array with at least an empty string to avoid SQL errors
240
- def prepare_words(words)
241
- return [''] if words.blank?
242
- a = words.split(/[,\s]/).map(&:strip)
243
- a.any? ? a : ['']
244
- end
205
+ def self.distinct_by_product_ids(sort_order = nil)
206
+ Spree::Deprecation.warn "Product.distinct_by_product_ids is deprecated and should not be used"
207
+
208
+ sort_column = sort_order.split(" ").first
209
+
210
+ # Postgres will complain when using ordering by expressions not present in
211
+ # SELECT DISTINCT. e.g.
212
+ #
213
+ # PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY
214
+ # expressions must appear in select list. e.g.
215
+ #
216
+ # SELECT DISTINCT "spree_products".* FROM "spree_products" LEFT OUTER JOIN
217
+ # "spree_variants" ON "spree_variants"."product_id" = "spree_products"."id" AND "spree_variants"."is_master" = 't'
218
+ # AND "spree_variants"."deleted_at" IS NULL LEFT OUTER JOIN "spree_prices" ON
219
+ # "spree_prices"."variant_id" = "spree_variants"."id" AND "spree_prices"."currency" = 'USD'
220
+ # AND "spree_prices"."deleted_at" IS NULL WHERE "spree_products"."deleted_at" IS NULL AND ('t'='t')
221
+ # ORDER BY "spree_prices"."amount" ASC LIMIT 10 OFFSET 0
222
+ #
223
+ # Don't allow sort_column, a variable coming from params,
224
+ # to be anything but a column in the database
225
+ if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' && !column_names.include?(sort_column)
226
+ all
227
+ else
228
+ distinct
229
+ end
230
+ end
245
231
 
246
- def get_taxons(*ids_or_records_or_names)
247
- taxons = Spree::Taxon.table_name
248
- ids_or_records_or_names.flatten.map { |t|
249
- case t
250
- when Integer then Spree::Taxon.find_by(id: t)
251
- when ActiveRecord::Base then t
252
- when String
253
- Spree::Taxon.find_by(name: t) ||
254
- Spree::Taxon.where("#{taxons}.permalink LIKE ? OR #{taxons}.permalink = ?", "%/#{t}/", "#{t}/").first
232
+ class << self
233
+ private
234
+
235
+ def price_table_name
236
+ Spree::Price.quoted_table_name
237
+ end
238
+
239
+ # specifically avoid having an order for taxon search (conflicts with main order)
240
+ def prepare_taxon_conditions(taxons)
241
+ ids = taxons.flat_map { |taxon| taxon.self_and_descendants.pluck(:id) }.uniq
242
+ joins(:taxons).where("#{Spree::Taxon.table_name}.id" => ids)
243
+ end
244
+
245
+ # Produce an array of keywords for use in scopes.
246
+ # Always return array with at least an empty string to avoid SQL errors
247
+ def prepare_words(words)
248
+ return [''] if words.blank?
249
+
250
+ splitted = words.split(/[,\s]/).map(&:strip)
251
+ splitted.any? ? splitted : ['']
252
+ end
253
+
254
+ def get_taxons(*ids_or_records_or_names)
255
+ taxons = Spree::Taxon.table_name
256
+ ids_or_records_or_names.flatten.map { |taxon|
257
+ case taxon
258
+ when Integer then Spree::Taxon.find_by(id: taxon)
259
+ when ActiveRecord::Base then taxon
260
+ when String
261
+ Spree::Taxon.find_by(name: taxon) ||
262
+ Spree::Taxon.where("#{taxons}.permalink LIKE ? OR #{taxons}.permalink = ?", "%/#{taxon}/", "#{taxon}/").first
263
+ end
264
+ }.compact.flatten.uniq
265
+ end
255
266
  end
256
- }.compact.flatten.uniq
267
+ end
257
268
  end
269
+
270
+ ::Spree::Product.prepend self
258
271
  end
259
272
  end
260
273
  end