solidus_core 2.9.6 → 2.11.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of solidus_core might be problematic. Click here for more details.

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