solidus_core 2.9.5 → 2.10.2

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 (221) hide show
  1. checksums.yaml +4 -4
  2. data/app/helpers/spree/base_helper.rb +4 -4
  3. data/app/helpers/spree/products_helper.rb +2 -1
  4. data/app/jobs/spree/promotion_code_batch_job.rb +2 -2
  5. data/app/models/concerns/spree/user_address_book.rb +2 -2
  6. data/app/models/concerns/spree/user_methods.rb +2 -2
  7. data/app/models/spree/address.rb +13 -17
  8. data/app/models/spree/adjustment.rb +20 -9
  9. data/app/models/spree/asset.rb +1 -1
  10. data/app/models/spree/base.rb +0 -2
  11. data/app/models/spree/calculator.rb +1 -1
  12. data/app/models/spree/calculator/price_sack.rb +1 -1
  13. data/app/models/spree/calculator/shipping/flexi_rate.rb +2 -2
  14. data/app/models/spree/calculator/tiered_flat_rate.rb +5 -5
  15. data/app/models/spree/calculator/tiered_percent.rb +6 -6
  16. data/app/models/spree/carton.rb +3 -3
  17. data/app/models/spree/classification.rb +2 -2
  18. data/app/models/spree/credit_card.rb +4 -4
  19. data/app/models/spree/customer_return.rb +1 -1
  20. data/app/models/spree/image/paperclip_attachment.rb +1 -1
  21. data/app/models/spree/inventory_unit.rb +5 -23
  22. data/app/models/spree/line_item.rb +4 -4
  23. data/app/models/spree/line_item_action.rb +2 -2
  24. data/app/models/spree/log_entry.rb +1 -1
  25. data/app/models/spree/option_value.rb +1 -1
  26. data/app/models/spree/option_values_variant.rb +2 -2
  27. data/app/models/spree/order.rb +11 -27
  28. data/app/models/spree/order/checkout.rb +1 -1
  29. data/app/models/spree/order/payments.rb +2 -2
  30. data/app/models/spree/order_cancellations.rb +1 -1
  31. data/app/models/spree/order_capturing.rb +2 -2
  32. data/app/models/spree/order_contents.rb +2 -2
  33. data/app/models/spree/order_mutex.rb +1 -1
  34. data/app/models/spree/order_promotion.rb +3 -3
  35. data/app/models/spree/order_shipping.rb +1 -1
  36. data/app/models/spree/order_taxation.rb +3 -3
  37. data/app/models/spree/payment.rb +8 -45
  38. data/app/models/spree/payment/processing.rb +3 -3
  39. data/app/models/spree/payment_capture_event.rb +1 -1
  40. data/app/models/spree/payment_method.rb +5 -2
  41. data/app/models/spree/payment_method/bogus_credit_card.rb +1 -1
  42. data/app/models/spree/payment_source.rb +1 -1
  43. data/app/models/spree/price.rb +2 -2
  44. data/app/models/spree/product.rb +5 -5
  45. data/app/models/spree/product/scopes.rb +218 -210
  46. data/app/models/spree/product_option_type.rb +2 -2
  47. data/app/models/spree/product_promotion_rule.rb +2 -2
  48. data/app/models/spree/product_property.rb +2 -2
  49. data/app/models/spree/promotion.rb +28 -13
  50. data/app/models/spree/promotion/actions/create_quantity_adjustments.rb +1 -1
  51. data/app/models/spree/promotion/actions/free_shipping.rb +1 -1
  52. data/app/models/spree/promotion/rules/option_value.rb +2 -2
  53. data/app/models/spree/promotion/rules/product.rb +3 -3
  54. data/app/models/spree/promotion_action.rb +2 -2
  55. data/app/models/spree/promotion_chooser.rb +2 -2
  56. data/app/models/spree/promotion_code.rb +11 -10
  57. data/app/models/spree/promotion_code/batch_builder.rb +3 -3
  58. data/app/models/spree/promotion_code_batch.rb +1 -1
  59. data/app/models/spree/promotion_rule.rb +2 -2
  60. data/app/models/spree/promotion_rule_role.rb +2 -2
  61. data/app/models/spree/promotion_rule_store.rb +2 -2
  62. data/app/models/spree/promotion_rule_taxon.rb +2 -2
  63. data/app/models/spree/promotion_rule_user.rb +2 -2
  64. data/app/models/spree/refund.rb +5 -5
  65. data/app/models/spree/reimbursement.rb +5 -13
  66. data/app/models/spree/reimbursement/credit.rb +2 -2
  67. data/app/models/spree/reimbursement/reimbursement_type_engine.rb +1 -1
  68. data/app/models/spree/reimbursement_tax_calculator.rb +1 -1
  69. data/app/models/spree/reimbursement_type/reimbursement_helpers.rb +2 -2
  70. data/app/models/spree/return_authorization.rb +4 -10
  71. data/app/models/spree/return_item.rb +13 -52
  72. data/app/models/spree/return_item/eligibility_validator/default.rb +1 -1
  73. data/app/models/spree/role_user.rb +2 -2
  74. data/app/models/spree/shipment.rb +7 -41
  75. data/app/models/spree/shipping_calculator.rb +0 -4
  76. data/app/models/spree/shipping_manifest.rb +3 -3
  77. data/app/models/spree/shipping_method.rb +2 -2
  78. data/app/models/spree/shipping_method_category.rb +2 -2
  79. data/app/models/spree/shipping_method_stock_location.rb +2 -2
  80. data/app/models/spree/shipping_method_zone.rb +2 -2
  81. data/app/models/spree/shipping_rate.rb +2 -2
  82. data/app/models/spree/shipping_rate_tax.rb +2 -2
  83. data/app/models/spree/state.rb +2 -2
  84. data/app/models/spree/state_change.rb +2 -2
  85. data/app/models/spree/stock/differentiator.rb +1 -1
  86. data/app/models/spree/stock/package.rb +1 -1
  87. data/app/models/spree/stock_item.rb +3 -3
  88. data/app/models/spree/stock_location.rb +2 -2
  89. data/app/models/spree/stock_movement.rb +2 -2
  90. data/app/models/spree/stock_quantities.rb +13 -12
  91. data/app/models/spree/store_credit.rb +8 -8
  92. data/app/models/spree/store_credit_event.rb +3 -3
  93. data/app/models/spree/store_payment_method.rb +2 -2
  94. data/app/models/spree/store_shipping_method.rb +2 -2
  95. data/app/models/spree/tax_calculator/default.rb +0 -4
  96. data/app/models/spree/tax_calculator/shipping_rate.rb +0 -3
  97. data/app/models/spree/tax_rate.rb +5 -1
  98. data/app/models/spree/tax_rate_tax_category.rb +2 -2
  99. data/app/models/spree/taxon/paperclip_attachment.rb +13 -0
  100. data/app/models/spree/unit_cancel.rb +5 -2
  101. data/app/models/spree/user_address.rb +2 -2
  102. data/app/models/spree/user_last_url_storer.rb +46 -0
  103. data/app/models/spree/user_last_url_storer/rules/authentication_rule.rb +36 -0
  104. data/app/models/spree/user_stock_location.rb +2 -2
  105. data/app/models/spree/variant.rb +10 -10
  106. data/app/models/spree/variant/scopes.rb +37 -29
  107. data/app/models/spree/variant_property_rule.rb +1 -1
  108. data/app/models/spree/variant_property_rule_condition.rb +2 -2
  109. data/app/models/spree/variant_property_rule_value.rb +2 -2
  110. data/app/models/spree/wallet/add_payment_sources_to_wallet.rb +1 -1
  111. data/app/models/spree/wallet_payment_source.rb +2 -2
  112. data/app/models/spree/zone.rb +1 -1
  113. data/app/models/spree/zone_member.rb +2 -2
  114. data/config/initializers/inflections.rb +5 -0
  115. data/config/initializers/money.rb +2 -0
  116. data/config/locales/en.yml +34 -3
  117. data/lib/generators/spree/dummy/dummy_generator.rb +2 -0
  118. data/lib/generators/spree/install/templates/config/initializers/spree.rb.tt +8 -0
  119. data/lib/spree/app_configuration.rb +18 -3
  120. data/lib/spree/core.rb +12 -0
  121. data/lib/spree/core/controller_helpers/auth.rb +1 -13
  122. data/lib/spree/core/controller_helpers/strong_parameters.rb +21 -7
  123. data/lib/spree/core/engine.rb +2 -2
  124. data/lib/spree/core/importer/order.rb +29 -28
  125. data/lib/spree/core/importer/product.rb +2 -2
  126. data/lib/spree/core/product_filters.rb +15 -15
  127. data/lib/spree/core/role_configuration.rb +2 -2
  128. data/lib/spree/core/search/variant.rb +1 -1
  129. data/lib/spree/core/state_machines.rb +78 -0
  130. data/lib/spree/core/state_machines/inventory_unit.rb +42 -0
  131. data/lib/spree/core/state_machines/payment.rb +61 -0
  132. data/lib/spree/core/state_machines/reimbursement.rb +33 -0
  133. data/lib/spree/core/state_machines/return_authorization.rb +32 -0
  134. data/lib/spree/core/state_machines/return_item/acceptance_status.rb +51 -0
  135. data/lib/spree/core/state_machines/return_item/reception_status.rb +42 -0
  136. data/lib/spree/core/state_machines/shipment.rb +58 -0
  137. data/lib/spree/core/stock_configuration.rb +1 -0
  138. data/lib/spree/core/validators/email.rb +1 -8
  139. data/lib/spree/core/version.rb +1 -1
  140. data/lib/spree/money.rb +2 -2
  141. data/lib/spree/permission_sets/default_customer.rb +1 -1
  142. data/lib/spree/permission_sets/user_management.rb +3 -0
  143. data/lib/spree/permitted_attributes.rb +78 -9
  144. data/lib/spree/preferences/static_model_preferences.rb +2 -2
  145. data/lib/spree/testing_support/dummy_app.rb +4 -1
  146. data/lib/spree/testing_support/dummy_app/rake_tasks.rb +6 -2
  147. data/lib/spree/testing_support/factories/inventory_unit_factory.rb +8 -1
  148. data/lib/spree/testing_support/factories/promotion_factory.rb +7 -0
  149. data/lib/spree/testing_support/factories/stock_package_factory.rb +1 -1
  150. data/lib/spree/testing_support/factories/user_factory.rb +4 -1
  151. data/solidus_core.gemspec +6 -6
  152. data/spec/lib/search/base_spec.rb +5 -1
  153. data/spec/lib/search/variant_spec.rb +1 -1
  154. data/spec/lib/spree/core/controller_helpers/strong_parameters_spec.rb +8 -1
  155. data/spec/lib/spree/core/stock_configuration_spec.rb +36 -0
  156. data/spec/lib/spree/core/validators/email_spec.rb +18 -18
  157. data/spec/lib/spree/event_spec.rb +15 -3
  158. data/spec/lib/spree/permitted_attributes_spec.rb +41 -0
  159. data/spec/models/spree/ability_spec.rb +1 -1
  160. data/spec/models/spree/address_spec.rb +23 -0
  161. data/spec/models/spree/calculator/refunds/default_refund_amount_spec.rb +1 -1
  162. data/spec/models/spree/calculator/shipping/flat_percent_item_total_spec.rb +1 -1
  163. data/spec/models/spree/calculator/shipping/flat_rate_spec.rb +1 -1
  164. data/spec/models/spree/calculator/shipping/flexi_rate_spec.rb +2 -2
  165. data/spec/models/spree/calculator/shipping/per_item_spec.rb +1 -1
  166. data/spec/models/spree/calculator/shipping/price_sack_spec.rb +24 -15
  167. data/spec/models/spree/carton_spec.rb +10 -2
  168. data/spec/models/spree/classification_spec.rb +21 -9
  169. data/spec/models/spree/concerns/user_address_book_spec.rb +4 -4
  170. data/spec/models/spree/concerns/user_methods_spec.rb +5 -4
  171. data/spec/models/spree/credit_card_spec.rb +2 -2
  172. data/spec/models/spree/customer_return_spec.rb +1 -1
  173. data/spec/models/spree/order/checkout_spec.rb +1 -1
  174. data/spec/models/spree/order/outstanding_balance_integration_spec.rb +5 -5
  175. data/spec/models/spree/order/payment_spec.rb +1 -1
  176. data/spec/models/spree/order_contents_spec.rb +1 -1
  177. data/spec/models/spree/order_inventory_spec.rb +3 -3
  178. data/spec/models/spree/order_merger_spec.rb +3 -3
  179. data/spec/models/spree/order_shipping_spec.rb +1 -1
  180. data/spec/models/spree/order_spec.rb +14 -21
  181. data/spec/models/spree/order_updater_spec.rb +4 -3
  182. data/spec/models/spree/payment_create_spec.rb +6 -16
  183. data/spec/models/spree/payment_spec.rb +12 -12
  184. data/spec/models/spree/permission_sets/user_management_spec.rb +2 -0
  185. data/spec/models/spree/preference_spec.rb +4 -4
  186. data/spec/models/spree/preferences/preferable_spec.rb +3 -3
  187. data/spec/models/spree/preferences/statically_configurable_spec.rb +2 -2
  188. data/spec/models/spree/promotion/rules/first_repeat_purchase_since_spec.rb +2 -2
  189. data/spec/models/spree/promotion/rules/nth_order_spec.rb +2 -2
  190. data/spec/models/spree/promotion/rules/taxon_spec.rb +1 -0
  191. data/spec/models/spree/promotion_rule_spec.rb +6 -6
  192. data/spec/models/spree/promotion_spec.rb +71 -54
  193. data/spec/models/spree/reimbursement_type/original_payment_spec.rb +3 -3
  194. data/spec/models/spree/return_item/exchange_variant_eligibility/same_product_spec.rb +1 -1
  195. data/spec/models/spree/return_item_spec.rb +11 -11
  196. data/spec/models/spree/returns_calculator_spec.rb +2 -2
  197. data/spec/models/spree/shipment_spec.rb +6 -6
  198. data/spec/models/spree/shipping_calculator_spec.rb +1 -13
  199. data/spec/models/spree/shipping_method_spec.rb +32 -0
  200. data/spec/models/spree/stock/availability_validator_spec.rb +2 -2
  201. data/spec/models/spree/stock/differentiator_spec.rb +2 -2
  202. data/spec/models/spree/stock/estimator_spec.rb +3 -3
  203. data/spec/models/spree/stock/inventory_units_finalizer_spec.rb +4 -4
  204. data/spec/models/spree/stock/package_spec.rb +28 -28
  205. data/spec/models/spree/stock/quantifier_spec.rb +2 -2
  206. data/spec/models/spree/stock/simple_coordinator_spec.rb +11 -11
  207. data/spec/models/spree/stock/splitter/base_spec.rb +4 -4
  208. data/spec/models/spree/stock/splitter/shipping_category_spec.rb +7 -7
  209. data/spec/models/spree/stock_quantities_spec.rb +1 -1
  210. data/spec/models/spree/store_credit_spec.rb +8 -8
  211. data/spec/models/spree/tax_category_spec.rb +1 -1
  212. data/spec/models/spree/tax_rate_spec.rb +1 -0
  213. data/spec/models/spree/taxon_spec.rb +2 -2
  214. data/spec/models/spree/taxons/paperclip_attachment_spec.rb +29 -0
  215. data/spec/models/spree/unit_cancel_spec.rb +5 -0
  216. data/spec/models/spree/user_last_url_storer/rules/authentication_rule_spec.rb +31 -0
  217. data/spec/models/spree/user_last_url_storer_spec.rb +60 -0
  218. data/spec/models/spree/user_spec.rb +3 -3
  219. metadata +46 -39
  220. data/spec/migrate/20190106184413_remove_code_from_spree_promotions_spec.rb +0 -148
  221. data/spec/models/spree/order/updating_spec.rb +0 -18
@@ -2,159 +2,162 @@
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).order(Spree::Price.arel_table[:amount].asc)
33
+ end
31
34
 
32
- add_search_scope :descend_by_master_price do
33
- joins(master: :default_price).order(Spree::Price.arel_table[:amount].desc)
34
- end
35
+ add_search_scope :descend_by_master_price do
36
+ joins(master: :default_price).order(Spree::Price.arel_table[:amount].desc)
37
+ end
35
38
 
36
- add_search_scope :price_between do |low, high|
37
- joins(master: :default_price).where(Price.table_name => { amount: low..high })
38
- end
39
+ add_search_scope :price_between do |low, high|
40
+ joins(master: :default_price).where(Price.table_name => { amount: low..high })
41
+ end
39
42
 
40
- add_search_scope :master_price_lte do |price|
41
- joins(master: :default_price).where("#{price_table_name}.amount <= ?", price)
42
- end
43
+ add_search_scope :master_price_lte do |price|
44
+ joins(master: :default_price).where("#{price_table_name}.amount <= ?", price)
45
+ end
43
46
 
44
- add_search_scope :master_price_gte do |price|
45
- joins(master: :default_price).where("#{price_table_name}.amount >= ?", price)
46
- end
47
+ add_search_scope :master_price_gte do |price|
48
+ joins(master: :default_price).where("#{price_table_name}.amount >= ?", price)
49
+ end
47
50
 
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
51
+ # This scope selects products in taxon AND all its descendants
52
+ # If you need products only within one taxon use
53
+ #
54
+ # Spree::Product.joins(:taxons).where(Taxon.table_name => { id: taxon.id })
55
+ #
56
+ # If you're using count on the result of this scope, you must use the
57
+ # `:distinct` option as well:
58
+ #
59
+ # Spree::Product.in_taxon(taxon).count(distinct: true)
60
+ #
61
+ # This is so that the count query is distinct'd:
62
+ #
63
+ # SELECT COUNT(DISTINCT "spree_products"."id") ...
64
+ #
65
+ # vs.
66
+ #
67
+ # SELECT COUNT(*) ...
68
+ add_search_scope :in_taxon do |taxon|
69
+ includes(:classifications)
70
+ .where('spree_products_taxons.taxon_id' => taxon.self_and_descendants.pluck(:id))
71
+ .select(Spree::Classification.arel_table[:position])
72
+ .order(Spree::Classification.arel_table[:position].asc)
73
+ end
71
74
 
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
75
+ # This scope selects products in all taxons AND all its descendants
76
+ # If you need products only within one taxon use
77
+ #
78
+ # Spree::Product.taxons_id_eq([x,y])
79
+ add_search_scope :in_taxons do |*taxons|
80
+ taxons = get_taxons(taxons)
81
+ taxons.first ? prepare_taxon_conditions(taxons) : where(nil)
82
+ end
80
83
 
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
84
+ # a scope that finds all products having property specified by name, object or id
85
+ add_search_scope :with_property do |property|
86
+ joins(:properties).where(property_conditions(property))
87
+ end
85
88
 
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
89
+ # a simple test for product with a certain property-value pairing
90
+ # note that it can test for properties with NULL values, but not for absent values
91
+ add_search_scope :with_property_value do |property, value|
92
+ joins(:properties)
93
+ .where("#{Spree::ProductProperty.table_name}.value = ?", value)
94
+ .where(property_conditions(property))
95
+ end
93
96
 
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
97
+ add_search_scope :with_option do |option|
98
+ option_types = Spree::OptionType.table_name
99
+ conditions = case option
100
+ when String then { "#{option_types}.name" => option }
101
+ when OptionType then { "#{option_types}.id" => option.id }
102
+ else { "#{option_types}.id" => option.to_i }
103
+ end
101
104
 
102
- joins(:option_types).where(conditions)
103
- end
105
+ joins(:option_types).where(conditions)
106
+ end
104
107
 
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
108
+ add_search_scope :with_option_value do |option, value|
109
+ option_values = Spree::OptionValue.table_name
110
+ option_type_id = case option
111
+ when String then Spree::OptionType.find_by(name: option) || option.to_i
112
+ when Spree::OptionType then option.id
113
+ else option.to_i
114
+ end
112
115
 
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
116
+ conditions = "#{option_values}.name = ? AND #{option_values}.option_type_id = ?", value, option_type_id
117
+ group('spree_products.id').joins(variants_including_master: :option_values).where(conditions)
118
+ end
116
119
 
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
120
+ # Finds all products which have either:
121
+ # 1) have an option value with the name matching the one given
122
+ # 2) have a product property with a value matching the one given
123
+ add_search_scope :with do |value|
124
+ includes(variants_including_master: :option_values).
125
+ includes(:product_properties).
126
+ where("#{Spree::OptionValue.table_name}.name = ? OR #{Spree::ProductProperty.table_name}.value = ?", value, value)
127
+ end
125
128
 
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
129
+ # Finds all products that have a name containing the given words.
130
+ add_search_scope :in_name do |words|
131
+ like_any([:name], prepare_words(words))
132
+ end
130
133
 
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
134
+ # Finds all products that have a name or meta_keywords containing the given words.
135
+ add_search_scope :in_name_or_keywords do |words|
136
+ like_any([:name, :meta_keywords], prepare_words(words))
137
+ end
135
138
 
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
139
+ # Finds all products that have a name, description, meta_description or meta_keywords containing the given keywords.
140
+ add_search_scope :in_name_or_description do |words|
141
+ like_any([:name, :description, :meta_description, :meta_keywords], prepare_words(words))
142
+ end
140
143
 
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
144
+ # Finds all products that have the ids matching the given collection of ids.
145
+ # Alternatively, you could use find(collection_of_ids), but that would raise an exception if one product couldn't be found
146
+ add_search_scope :with_ids do |*ids|
147
+ where(id: ids)
148
+ end
146
149
 
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(%{
150
+ # Sorts products from most popular (popularity is extracted from how many
151
+ # times use has put product in cart, not completed orders)
152
+ #
153
+ # there is alternative faster and more elegant solution, it has small drawback though,
154
+ # it doesn stack with other scopes :/
155
+ #
156
+ # 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",
157
+ # order: 'COALESCE(cnt, 0) DESC'
158
+ add_search_scope :descend_by_popularity do
159
+ joins(:master).
160
+ order(%{
158
161
  COALESCE((
159
162
  SELECT
160
163
  COUNT(#{Spree::LineItem.quoted_table_name}.id)
@@ -168,93 +171,98 @@ module Spree
168
171
  popular_variants.product_id = #{Spree::Product.quoted_table_name}.id
169
172
  ), 0) DESC
170
173
  })
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
174
+ end
197
175
 
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
176
+ add_search_scope :not_deleted do
177
+ where("#{Spree::Product.quoted_table_name}.deleted_at IS NULL or #{Spree::Product.quoted_table_name}.deleted_at >= ?", Time.current)
178
+ end
224
179
 
225
- class << self
226
- private
180
+ scope :with_master_price, -> do
181
+ joins(:master).where(Spree::Price.where(Spree::Variant.arel_table[:id].eq(Spree::Price.arel_table[:variant_id])).arel.exists)
182
+ end
183
+ # Can't use add_search_scope for this as it needs a default argument
184
+ def self.available(available_on = nil)
185
+ with_master_price.where("#{Spree::Product.quoted_table_name}.available_on <= ?", available_on || Time.current)
186
+ end
187
+ search_scopes << :available
227
188
 
228
- def price_table_name
229
- Spree::Price.quoted_table_name
230
- end
189
+ add_search_scope :taxons_name_eq do |name|
190
+ group("spree_products.id").joins(:taxons).where(Spree::Taxon.arel_table[:name].eq(name))
191
+ end
231
192
 
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
193
+ def self.with_variant_sku_cont(sku)
194
+ sku_match = "%#{sku}%"
195
+ variant_table = Spree::Variant.arel_table
196
+ subquery = Spree::Variant.where(variant_table[:sku].matches(sku_match).and(variant_table[:product_id].eq(arel_table[:id])))
197
+ where(subquery.arel.exists)
198
+ end
237
199
 
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
200
+ def self.distinct_by_product_ids(sort_order = nil)
201
+ Spree::Deprecation.warn "Product.distinct_by_product_ids is deprecated and should not be used"
202
+
203
+ sort_column = sort_order.split(" ").first
204
+
205
+ # Postgres will complain when using ordering by expressions not present in
206
+ # SELECT DISTINCT. e.g.
207
+ #
208
+ # PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY
209
+ # expressions must appear in select list. e.g.
210
+ #
211
+ # SELECT DISTINCT "spree_products".* FROM "spree_products" LEFT OUTER JOIN
212
+ # "spree_variants" ON "spree_variants"."product_id" = "spree_products"."id" AND "spree_variants"."is_master" = 't'
213
+ # AND "spree_variants"."deleted_at" IS NULL LEFT OUTER JOIN "spree_prices" ON
214
+ # "spree_prices"."variant_id" = "spree_variants"."id" AND "spree_prices"."currency" = 'USD'
215
+ # AND "spree_prices"."deleted_at" IS NULL WHERE "spree_products"."deleted_at" IS NULL AND ('t'='t')
216
+ # ORDER BY "spree_prices"."amount" ASC LIMIT 10 OFFSET 0
217
+ #
218
+ # Don't allow sort_column, a variable coming from params,
219
+ # to be anything but a column in the database
220
+ if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' && !column_names.include?(sort_column)
221
+ all
222
+ else
223
+ distinct
224
+ end
225
+ end
245
226
 
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
227
+ class << self
228
+ private
229
+
230
+ def price_table_name
231
+ Spree::Price.quoted_table_name
232
+ end
233
+
234
+ # specifically avoid having an order for taxon search (conflicts with main order)
235
+ def prepare_taxon_conditions(taxons)
236
+ ids = taxons.map { |taxon| taxon.self_and_descendants.pluck(:id) }.flatten.uniq
237
+ joins(:taxons).where("#{Spree::Taxon.table_name}.id" => ids)
238
+ end
239
+
240
+ # Produce an array of keywords for use in scopes.
241
+ # Always return array with at least an empty string to avoid SQL errors
242
+ def prepare_words(words)
243
+ return [''] if words.blank?
244
+
245
+ splitted = words.split(/[,\s]/).map(&:strip)
246
+ splitted.any? ? splitted : ['']
247
+ end
248
+
249
+ def get_taxons(*ids_or_records_or_names)
250
+ taxons = Spree::Taxon.table_name
251
+ ids_or_records_or_names.flatten.map { |taxon|
252
+ case taxon
253
+ when Integer then Spree::Taxon.find_by(id: taxon)
254
+ when ActiveRecord::Base then taxon
255
+ when String
256
+ Spree::Taxon.find_by(name: taxon) ||
257
+ Spree::Taxon.where("#{taxons}.permalink LIKE ? OR #{taxons}.permalink = ?", "%/#{taxon}/", "#{taxon}/").first
258
+ end
259
+ }.compact.flatten.uniq
260
+ end
255
261
  end
256
- }.compact.flatten.uniq
262
+ end
257
263
  end
264
+
265
+ ::Spree::Product.prepend self
258
266
  end
259
267
  end
260
268
  end