caboose-cms 0.4.151 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (166) hide show
  1. checksums.yaml +8 -8
  2. data/app/assets/javascripts/caboose/admin_products.js +79 -0
  3. data/app/assets/javascripts/caboose/application.js +2 -1
  4. data/app/assets/javascripts/caboose/cart.js +168 -0
  5. data/app/assets/javascripts/caboose/checkout.js +151 -0
  6. data/app/assets/javascripts/caboose/checkout_module.js +312 -0
  7. data/app/assets/javascripts/caboose/checkout_step1.js +179 -0
  8. data/app/assets/javascripts/caboose/checkout_step2.js +39 -0
  9. data/app/assets/javascripts/caboose/checkout_step3.js +34 -0
  10. data/app/assets/javascripts/caboose/checkout_step4.js +97 -0
  11. data/app/assets/javascripts/caboose/main.js +99 -8
  12. data/app/assets/javascripts/caboose/product.js +284 -0
  13. data/app/assets/stylesheets/caboose/admin_products.css +86 -0
  14. data/app/assets/templates/caboose/cart/add_to_cart.jst.ejs +7 -0
  15. data/app/assets/templates/caboose/cart/line_items.jst.ejs +41 -0
  16. data/app/assets/templates/caboose/checkout/address.jst.ejs +53 -0
  17. data/app/assets/templates/caboose/checkout/forms/guest.jst.ejs +8 -0
  18. data/app/assets/templates/caboose/checkout/forms/register.jst.ejs +11 -0
  19. data/app/assets/templates/caboose/checkout/forms/signin.jst.ejs +7 -0
  20. data/app/assets/templates/caboose/checkout/line_items.jst.ejs +31 -0
  21. data/app/assets/templates/caboose/checkout/login.jst.ejs +21 -0
  22. data/app/assets/templates/caboose/checkout/payment.jst.ejs +5 -0
  23. data/app/assets/templates/caboose/checkout/shipping.jst.ejs +18 -0
  24. data/app/assets/templates/caboose/product/images.jst.ejs +8 -0
  25. data/app/assets/templates/caboose/product/options.jst.ejs +19 -0
  26. data/app/controllers/caboose/application_controller.rb +29 -1
  27. data/app/controllers/caboose/cart_controller.rb +52 -0
  28. data/app/controllers/caboose/categories_controller.rb +108 -0
  29. data/app/controllers/caboose/checkout_controller.rb +325 -0
  30. data/app/controllers/caboose/orders_controller.rb +439 -0
  31. data/app/controllers/caboose/product_images_controller.rb +38 -0
  32. data/app/controllers/caboose/products_controller.rb +737 -0
  33. data/app/controllers/caboose/reviews_controller.rb +15 -0
  34. data/app/controllers/caboose/variants_controller.rb +218 -0
  35. data/app/controllers/caboose/vendors_controller.rb +73 -0
  36. data/app/helpers/caboose/application_helper.rb +4 -0
  37. data/app/helpers/caboose/categories_helper.rb +82 -0
  38. data/app/helpers/caboose/checkout_helper.rb +20 -0
  39. data/app/helpers/caboose/products_helper.rb +8 -0
  40. data/app/mailers/caboose/orders_mailer.rb +30 -0
  41. data/app/models/caboose/address.rb +26 -0
  42. data/app/models/caboose/category.rb +89 -0
  43. data/app/models/caboose/category_membership.rb +10 -0
  44. data/app/models/caboose/core_plugin.rb +15 -37
  45. data/app/models/caboose/customization_membership.rb +10 -0
  46. data/app/models/caboose/discount.rb +16 -0
  47. data/app/models/caboose/line_item.rb +81 -0
  48. data/app/models/caboose/message.rb +20 -0
  49. data/app/models/caboose/order.rb +191 -0
  50. data/app/models/caboose/order_discount.rb +10 -0
  51. data/app/models/caboose/order_pdf.rb +78 -0
  52. data/app/models/caboose/payment_processors/authorizenet.rb +53 -0
  53. data/app/models/caboose/payment_processors/base.rb +39 -0
  54. data/app/models/caboose/payment_processors/payscape.rb +94 -0
  55. data/app/models/caboose/product.rb +145 -0
  56. data/app/models/caboose/product_image.rb +62 -0
  57. data/app/models/caboose/product_image_variant.rb +10 -0
  58. data/app/models/caboose/review.rb +13 -0
  59. data/app/models/caboose/schema.rb +205 -1
  60. data/app/models/caboose/search_filter.rb +191 -0
  61. data/app/models/caboose/shipping_calculator.rb +81 -0
  62. data/app/models/caboose/states.rb +61 -52
  63. data/app/models/caboose/tax_calculator.rb +23 -0
  64. data/app/models/caboose/tax_line.rb +9 -0
  65. data/app/models/caboose/variant.rb +99 -0
  66. data/app/models/caboose/vendor.rb +22 -0
  67. data/app/views/caboose/cart/index.html.erb +8 -0
  68. data/app/views/caboose/categories/admin_edit.html.erb +79 -0
  69. data/app/views/caboose/categories/admin_index.html.erb +11 -0
  70. data/app/views/caboose/categories/admin_new.html.erb +62 -0
  71. data/app/views/caboose/checkout/_address_form.html.erb +111 -0
  72. data/app/views/caboose/checkout/_billing_form.html.erb +47 -0
  73. data/app/views/caboose/checkout/_cart.html.erb +52 -0
  74. data/app/views/caboose/checkout/_confirm.html.erb +61 -0
  75. data/app/views/caboose/checkout/_order_discount.html.erb +40 -0
  76. data/app/views/caboose/checkout/_shipping_address.html.erb +10 -0
  77. data/app/views/caboose/checkout/_shipping_method.html.erb +2 -0
  78. data/app/views/caboose/checkout/_shipping_method_form.html.erb +21 -0
  79. data/app/views/caboose/checkout/billing.html.erb +11 -0
  80. data/app/views/caboose/checkout/discount.html.erb +11 -0
  81. data/app/views/caboose/checkout/empty.html.erb +2 -0
  82. data/app/views/caboose/checkout/error.html.erb +2 -0
  83. data/app/views/caboose/checkout/index.html.erb +43 -0
  84. data/app/views/caboose/checkout/login.html.erb +2 -0
  85. data/app/views/caboose/checkout/payment.html.erb +79 -0
  86. data/app/views/caboose/checkout/relay.html.erb +23 -0
  87. data/app/views/caboose/checkout/relay_old.html.erb +12 -0
  88. data/app/views/caboose/checkout/relay_postMessage.html.erb +19 -0
  89. data/app/views/caboose/checkout/shipping.html.erb +15 -0
  90. data/app/views/caboose/checkout/step_four.html.erb +93 -0
  91. data/app/views/caboose/checkout/step_one.html.erb +56 -0
  92. data/app/views/caboose/checkout/step_one_old.html.erb +13 -0
  93. data/app/views/caboose/checkout/step_three.html.erb +23 -0
  94. data/app/views/caboose/checkout/step_two.html.erb +52 -0
  95. data/app/views/caboose/checkout/step_two_old.html.erb +14 -0
  96. data/app/views/caboose/checkout/thanks.html.erb +5 -0
  97. data/app/views/caboose/orders/_admin_footer.html.erb +2 -0
  98. data/app/views/caboose/orders/_admin_header.html.erb +31 -0
  99. data/app/views/caboose/orders/_quickbooks_order.html.erb +0 -0
  100. data/app/views/caboose/orders/admin_delete_form.html.erb +21 -0
  101. data/app/views/caboose/orders/admin_edit.html.erb +271 -0
  102. data/app/views/caboose/orders/admin_index.html.erb +89 -0
  103. data/app/views/caboose/orders/admin_new.html.erb +42 -0
  104. data/app/views/caboose/orders/admin_print.html.erb +72 -0
  105. data/app/views/caboose/orders_mailer/customer_new_order.html.erb +1 -0
  106. data/app/views/caboose/orders_mailer/customer_status_updated.html.erb +1 -0
  107. data/app/views/caboose/orders_mailer/fulfillment_new_order.html.erb +1 -0
  108. data/app/views/caboose/orders_mailer/shipping_order_ready.html.erb +1 -0
  109. data/app/views/caboose/products/_admin_footer.html.erb +2 -0
  110. data/app/views/caboose/products/_admin_header.html.erb +32 -0
  111. data/app/views/caboose/products/_sort_options.html.erb +19 -0
  112. data/app/views/caboose/products/admin_add_upcs.html.erb +58 -0
  113. data/app/views/caboose/products/admin_delete_form.html.erb +21 -0
  114. data/app/views/caboose/products/admin_edit_categories.html.erb +73 -0
  115. data/app/views/caboose/products/admin_edit_category_images.html.erb +233 -0
  116. data/app/views/caboose/products/admin_edit_description.html.erb +38 -0
  117. data/app/views/caboose/products/admin_edit_general.html.erb +104 -0
  118. data/app/views/caboose/products/admin_edit_images.html.erb +236 -0
  119. data/app/views/caboose/products/admin_edit_options.html.erb +51 -0
  120. data/app/views/caboose/products/admin_edit_seo.html.erb +37 -0
  121. data/app/views/caboose/products/admin_edit_variant_columns.html.erb +75 -0
  122. data/app/views/caboose/products/admin_edit_variant_sort_order.html.erb +63 -0
  123. data/app/views/caboose/products/admin_edit_variants.html.erb +171 -0
  124. data/app/views/caboose/products/admin_edit_variants_single.html.erb +68 -0
  125. data/app/views/caboose/products/admin_group_variants.html.erb +433 -0
  126. data/app/views/caboose/products/admin_index.html.erb +95 -0
  127. data/app/views/caboose/products/admin_new.html.erb +41 -0
  128. data/app/views/caboose/products/admin_sort.html copy.erb +155 -0
  129. data/app/views/caboose/products/admin_sort.html.erb +254 -0
  130. data/app/views/caboose/products/details.html.erb +438 -0
  131. data/app/views/caboose/products/index.html.erb +46 -0
  132. data/app/views/caboose/products/not_available.html.erb +35 -0
  133. data/app/views/caboose/variants/admin_edit.html.erb +82 -0
  134. data/app/views/caboose/variants/admin_group.html.erb +184 -0
  135. data/app/views/caboose/variants/admin_new.html.erb +59 -0
  136. data/app/views/caboose/vendors/admin_edit.html.erb +24 -0
  137. data/app/views/caboose/vendors/admin_index.html.erb +30 -0
  138. data/app/views/caboose/vendors/admin_new.html.erb +34 -0
  139. data/app/views/layouts/caboose/store/_banner.html.erb +10 -0
  140. data/app/views/layouts/caboose/store/_banner2.html.erb +10 -0
  141. data/app/views/layouts/caboose/store/_footer.html.erb +55 -0
  142. data/app/views/layouts/caboose/store/_header.html.erb +69 -0
  143. data/app/views/layouts/caboose/store/_sidebar.html.erb +27 -0
  144. data/app/views/layouts/caboose/store/application.html.erb +33 -0
  145. data/app/views/layouts/caboose/store/authorize_net.erb +18 -0
  146. data/app/views/layouts/caboose/store/layout_about.html.erb +42 -0
  147. data/app/views/layouts/caboose/store/layout_blog.html.erb +159 -0
  148. data/app/views/layouts/caboose/store/layout_confirm.html.erb +85 -0
  149. data/app/views/layouts/caboose/store/layout_contact.html.erb +38 -0
  150. data/app/views/layouts/caboose/store/layout_default.html.erb +10 -0
  151. data/app/views/layouts/caboose/store/layout_detail.html.erb +114 -0
  152. data/app/views/layouts/caboose/store/layout_order.html.erb +77 -0
  153. data/app/views/layouts/caboose/store/layout_pricing.html.erb +182 -0
  154. data/app/views/layouts/caboose/store/layout_product.html.erb +110 -0
  155. data/app/views/layouts/caboose/store/layout_profile.html.erb +55 -0
  156. data/app/views/layouts/caboose/store/layout_single.html.erb +3 -0
  157. data/app/views/layouts/caboose/store/layout_testimonial.html.erb +110 -0
  158. data/app/views/layouts/caboose/store/layout_testing.html.erb +4 -0
  159. data/config/routes.rb +126 -0
  160. data/lib/caboose.rb +46 -1
  161. data/lib/caboose/engine.rb +39 -1
  162. data/lib/caboose/version.rb +1 -1
  163. data/lib/tasks/caboose.rake +12 -0
  164. metadata +151 -4
  165. data/app/assets/javascripts/caboose/admin_page_edit_content_bak.js +0 -164
  166. data/app/assets/javascripts/caboose/model/#Untitled-1# +0 -2
@@ -0,0 +1,10 @@
1
+ module Caboose
2
+ class ProductImageVariant < ActiveRecord::Base
3
+ self.table_name = 'store_product_image_variants'
4
+
5
+ belongs_to :product_image
6
+ belongs_to :variant
7
+
8
+ attr_accessible :product_image_id, :variant_id
9
+ end
10
+ end
@@ -0,0 +1,13 @@
1
+ module Caboose
2
+ class Review < ActiveRecord::Base
3
+ self.table_name = 'store_reviews'
4
+
5
+ belongs_to :product
6
+
7
+ attr_accessible :id,
8
+ :product_id,
9
+ :name,
10
+ :rating,
11
+ :content
12
+ end
13
+ end
@@ -84,6 +84,23 @@ class Caboose::Schema < Caboose::Utilities::Schema
84
84
  [ :ab_variant_id , :integer ],
85
85
  [ :ab_option_id , :integer ]
86
86
  ],
87
+ Caboose::Address => [
88
+ [ :name , :string ],
89
+ [ :first_name , :string ],
90
+ [ :last_name , :string ],
91
+ [ :street , :string ],
92
+ [ :address1 , :string ],
93
+ [ :address2 , :string ],
94
+ [ :company , :string ],
95
+ [ :city , :string ],
96
+ [ :state , :string ],
97
+ [ :province , :string ],
98
+ [ :province_code , :string ],
99
+ [ :zip , :string ],
100
+ [ :country , :string ],
101
+ [ :country_code , :string ],
102
+ [ :phone , :string ]
103
+ ],
87
104
  Caboose::Asset => [
88
105
  [ :page_id , :integer ],
89
106
  [ :user_id , :integer ],
@@ -177,18 +194,65 @@ class Caboose::Schema < Caboose::Utilities::Schema
177
194
  [ :repeat_count , :integer ],
178
195
  [ :date_end , :date ]
179
196
  ],
197
+ Caboose::Category => [
198
+ [ :parent_id , :integer ],
199
+ [ :name , :string ],
200
+ [ :url , :string ],
201
+ [ :slug , :string ],
202
+ [ :status , :string ],
203
+ [ :image_file_name , :string ],
204
+ [ :image_content_type , :string ],
205
+ [ :image_file_size , :integer ],
206
+ [ :image_updated_at , :datetime ],
207
+ [ :square_offset_x , :integer ],
208
+ [ :square_offset_y , :integer ],
209
+ [ :square_scale_factor , :numeric ],
210
+ [ :sort_order , :integer ]
211
+ ],
212
+ Caboose::CategoryMembership => [
213
+ [ :category_id , :integer ],
214
+ [ :product_id , :integer ]
215
+ ],
216
+ Caboose::CustomizationMembership => [
217
+ [ :product_id , :integer ],
218
+ [ :customization_id , :integer ]
219
+ ],
180
220
  Caboose::DatabaseSession => [
181
221
  [ :session_id , :string , :null => false ],
182
222
  [ :data , :text ],
183
223
  [ :created_at , :datetime , :null => true ],
184
224
  [ :updated_at , :datetime , :null => true ]
185
225
  ],
226
+ Caboose::Discount => [
227
+ [ :name , :string ],
228
+ [ :code , :string ],
229
+ [ :amount_current , :numeric ],
230
+ [ :amount_total , :numeric ],
231
+ [ :amount_flat , :numeric ],
232
+ [ :amount_percentage , :numeric ],
233
+ [ :no_shipping , :boolean ],
234
+ [ :no_tax , :boolean ]
235
+ ],
186
236
  Caboose::Domain => [
187
237
  [ :site_id , :integer ],
188
238
  [ :domain , :string ],
189
239
  [ :primary , :boolean, { :default => false }],
190
240
  [ :under_construction , :boolean, { :default => false }]
191
241
  ],
242
+ Caboose::LineItem => [
243
+ [ :order_id , :integer ],
244
+ [ :variant_id , :integer ],
245
+ [ :parent_id , :integer ],
246
+ [ :quantity , :integer , :default => 0 ],
247
+ [ :status , :string ],
248
+ [ :tracking_number , :string ],
249
+ #[ :unit_price , :numeric ],
250
+ [ :price , :numeric , :default => 0 ],
251
+ [ :notes , :text ],
252
+ [ :custom1 , :string ],
253
+ [ :custom2 , :string ],
254
+ [ :custom3 , :string ]
255
+ ],
192
256
  Caboose::MediaCategory => [
193
257
  [ :parent_id , :integer ],
194
258
  [ :site_id , :integer ],
@@ -206,6 +270,46 @@ class Caboose::Schema < Caboose::Utilities::Schema
206
270
  [ :description , :text ],
207
271
  [ :file , :attachment ]
208
272
  ],
273
+ Caboose::Order => [
274
+ [ :email , :string ],
275
+ [ :order_number , :string ],
276
+ [ :subtotal , :numeric , :default => 0 ],
277
+ [ :tax , :numeric , :default => 0 ],
278
+ [ :shipping , :numeric , :default => 0 ],
279
+ [ :handling , :numeric , :default => 0 ],
280
+ [ :discount , :numeric , :default => 0 ],
281
+ [ :total , :numeric , :default => 0 ],
282
+ [ :customer_id , :integer ],
283
+ [ :payment_id , :integer ],
284
+ [ :gateway_id , :integer ],
285
+ [ :financial_status , :string ],
286
+ [ :shipping_address_id , :integer ],
287
+ [ :billing_address_id , :integer ],
288
+ [ :notes , :text ],
289
+ [ :status , :string ],
290
+ [ :date_created , :datetime ],
291
+ [ :date_authorized , :datetime ],
292
+ [ :date_captured , :datetime ],
293
+ [ :date_cancelled , :datetime ],
294
+ [ :referring_site , :text ],
295
+ [ :landing_page , :string ],
296
+ [ :landing_page_ref , :string ],
297
+ [ :shipping_method , :string ],
298
+ [ :shipping_method_code , :string ],
299
+ [ :transaction_id , :string ],
300
+ [ :auth_code , :string ],
301
+ [ :alternate_id , :integer ],
302
+ [ :auth_amount , :numeric ],
303
+ [ :date_shipped , :datetime ],
304
+ [ :transaction_id , :string ],
305
+ [ :transaction_service , :string ],
306
+ [ :amount_discounted , :numeric ],
307
+ [ :decremented , :boolean ]
308
+ ],
309
+ Caboose::OrderDiscount => [
310
+ [ :order_id , :integer ],
311
+ [ :discount_id , :integer ]
312
+ ],
209
313
  Caboose::Page => [
210
314
  [ :site_id , :integer ],
211
315
  [ :parent_id , :integer ],
@@ -270,6 +374,51 @@ class Caboose::Schema < Caboose::Utilities::Schema
270
374
  [ :post_id , :integer ],
271
375
  [ :post_category_id , :integer ]
272
376
  ],
377
+ Caboose::Product => [
378
+ [ :alternate_id , :string ],
379
+ [ :title , :string ],
380
+ [ :caption , :string ],
381
+ [ :description , :text ],
382
+ [ :handle , :string ],
383
+ [ :vendor_id , :integer ],
384
+ [ :option1 , :string ],
385
+ [ :option2 , :string ],
386
+ [ :option3 , :string ],
387
+ [ :category_id , :integer ],
388
+ [ :status , :string ],
389
+ [ :default1 , :string ],
390
+ [ :default2 , :string ],
391
+ [ :default3 , :string ],
392
+ [ :seo_title , :string ],
393
+ [ :seo_description , :string ],
394
+ [ :alternate_id , :string ],
395
+ [ :date_available , :datetime ],
396
+ [ :custom_input , :text ],
397
+ [ :sort_order , :integer ],
398
+ [ :featured , :boolean , :default => false ]
399
+ ],
400
+ Caboose::ProductImage => [
401
+ [ :product_id , :integer ],
402
+ [ :title , :string ],
403
+ [ :position , :integer ],
404
+ [ :image_file_name , :string ],
405
+ [ :image_content_type , :string ],
406
+ [ :image_file_size , :integer ],
407
+ [ :image_updated_at , :datetime ],
408
+ [ :square_offset_x , :integer ],
409
+ [ :square_offset_y , :integer ],
410
+ [ :square_scale_factor , :numeric ]
411
+ ],
412
+ Caboose::ProductImageVariant => [
413
+ [ :product_image_id , :integer ],
414
+ [ :variant_id , :integer ]
415
+ ],
416
+ Caboose::Review => [
417
+ [ :product_id , :integer ],
418
+ [ :content , :string ],
419
+ [ :name , :string ],
420
+ [ :rating , :decimal ]
421
+ ],
273
422
  Caboose::Role => [
274
423
  [ :parent_id , :integer ],
275
424
  [ :name , :string ],
@@ -283,6 +432,18 @@ class Caboose::Schema < Caboose::Utilities::Schema
283
432
  [ :role_id , :integer ],
284
433
  [ :permission_id , :integer ]
285
434
  ],
435
+ Caboose::SearchFilter => [
436
+ [ :url , :string ],
437
+ [ :title_like , :string ],
438
+ [ :search_like , :string ],
439
+ [ :category_id , :integer ],
440
+ [ :category , :text ],
441
+ [ :vendors , :text ],
442
+ [ :option1 , :text ],
443
+ [ :option2 , :text ],
444
+ [ :option3 , :text ],
445
+ [ :prices , :text ]
446
+ ],
286
447
  Caboose::Setting => [
287
448
  [ :name , :string ],
288
449
  [ :value , :text ]
@@ -325,7 +486,40 @@ class Caboose::Schema < Caboose::Utilities::Schema
325
486
  [ :password_reset_sent , :datetime ],
326
487
  [ :token , :string ],
327
488
  [ :date_created , :datetime ],
328
- [ :image , :attachment ]
489
+ [ :image , :attachment ],
490
+ [ :is_guest , :boolean , { :default => false }]
491
+ ],
492
+ Caboose::Variant => [
493
+ [ :sku , :string ],
494
+ [ :barcode , :string ],
495
+ [ :price , :numeric , :default => 0 ],
496
+ [ :available , :boolean ],
497
+ #[ :quantity_in_stock , :integer ],
498
+ [ :quantity , :integer , :default => 0 ],
499
+ [ :ignore_quantity , :boolean ],
500
+ [ :allow_backorder , :boolean ],
501
+ [ :weight , :decimal ],
502
+ [ :length , :decimal ],
503
+ [ :width , :decimal ],
504
+ [ :height , :decimal ],
505
+ [ :cylinder , :boolean ],
506
+ [ :option1 , :string ],
507
+ [ :option2 , :string ],
508
+ [ :option3 , :string ],
509
+ [ :requires_shipping , :boolean ],
510
+ [ :taxable , :boolean ],
511
+ [ :product_id , :integer ],
512
+ [ :shipping_unit_value , :numeric ],
513
+ [ :alternate_id , :string ],
514
+ [ :status , :string ],
515
+ [ :option1_sort_order , :integer , { :defult => 0 }],
516
+ [ :option2_sort_order , :integer , { :defult => 0 }],
517
+ [ :option3_sort_order , :integer , { :defult => 0 }],
518
+ [ :sort_order , :integer , { :defult => 0 }]
519
+ ],
520
+ Caboose::Vendor => [
521
+ [ :name , :string ],
522
+ [ :status , :string, { default: 'Active' } ]
329
523
  ]
330
524
  }
331
525
 
@@ -483,6 +677,16 @@ class Caboose::Schema < Caboose::Utilities::Schema
483
677
  cat = Caboose::MediaCategory.where("parent_id is null and site_id = ? and name = ?", site.id, 'Files').first
484
678
  Caboose::MediaCategory.create(:site_id => site.id, :name => 'Files') if cat.nil?
485
679
  end
680
+
681
+ # Make sure a default category exists for all products
682
+ if !Caboose::Category.exists?(1)
683
+ Caboose::Category.create({
684
+ :id => 1,
685
+ :name => 'All Products',
686
+ :url => '/products',
687
+ :slug => 'products'
688
+ })
689
+ end
486
690
 
487
691
  end
488
692
  end
@@ -0,0 +1,191 @@
1
+ require 'json'
2
+
3
+ module Caboose
4
+ class SearchFilter < ActiveRecord::Base
5
+ self.table_name = 'store_search_filters'
6
+
7
+ attr_accessible :id,
8
+ :url,
9
+ :title_like,
10
+ :search_like,
11
+ :category_id,
12
+ :category,
13
+ :vendors,
14
+ :option1,
15
+ :option2,
16
+ :option3,
17
+ :prices
18
+
19
+ before_save :json_encode
20
+ after_initialize :json_decode
21
+
22
+ def json_encode
23
+ self.category = self.category.to_json if not self.category.nil?
24
+ self.vendors = self.vendors.to_json if not self.vendors.nil?
25
+ self.option1 = self.option1.to_json if not self.option1.nil?
26
+ self.option2 = self.option2.to_json if not self.option2.nil?
27
+ self.option3 = self.option3.to_json if not self.option3.nil?
28
+ self.prices = self.prices.to_json if not self.prices.nil?
29
+ end
30
+
31
+ def json_decode
32
+ self.category = JSON.parse(self.category) if not self.category.nil?
33
+ self.vendors = JSON.parse(self.vendors) if not self.vendors.nil?
34
+ self.option1 = JSON.parse(self.option1) if not self.option1.nil?
35
+ self.option2 = JSON.parse(self.option2) if not self.option2.nil?
36
+ self.option3 = JSON.parse(self.option3) if not self.option3.nil?
37
+ self.prices = JSON.parse(self.prices) if not self.prices.nil?
38
+ end
39
+
40
+ def self.exclude_params_from_url(url, exclude_params = nil)
41
+ return url if exclude_params.nil? || exclude_params.count == 0
42
+
43
+ url2 = "#{url}"
44
+ url2[0] = '' if url2.starts_with?('/')
45
+
46
+ if Caboose.use_url_params
47
+ arr = url2.split('/')
48
+ arr2 = []
49
+ i = arr.count - 1
50
+ while i >= 1 do
51
+ k = arr[i-1]
52
+ v = arr[i]
53
+ arr2 << "#{k}/#{v}" if !exclude_params.include?(k)
54
+ i = i - 2
55
+ end
56
+ arr2 << arr[0] if i == 0
57
+ url2 = arr2.reverse.join('/')
58
+ else
59
+ # TODO: Handle removing parameters from the querystring
60
+ end
61
+
62
+ url2 = "/#{url2}" if !url2.starts_with?('/')
63
+ return url2
64
+ end
65
+
66
+ def self.find_from_url(url, pager, exclude_params=nil)
67
+
68
+ # Filter any specified parameters from the url
69
+ filtered_url = self.exclude_params_from_url(url, exclude_params)
70
+
71
+ # If the search filter already exists pass it back
72
+ # return SearchFilter.where(url: pager.options['base_url']) if SearchFilter.exists?(url: pager.options['base_url'])
73
+
74
+ # Create a new search filter
75
+ search_filter = SearchFilter.new
76
+ search_filter.url = filtered_url
77
+
78
+ search_filter.category_id = if pager.params['category_id'].kind_of?(Array)
79
+ pager.params['category_id'].first
80
+ else
81
+ pager.params['category_id']
82
+ end
83
+
84
+ # Grab the category NOTE: A category id is required
85
+ category = Category.find(search_filter.category_id)
86
+
87
+ # Define the category info
88
+ search_filter.category = Hash.new
89
+ search_filter.category['id'] = category.id
90
+ search_filter.category['name'] = category.name
91
+
92
+ # Define children categories info
93
+ search_filter.category['children'] = category.children.collect do |child_category|
94
+ child = Hash.new
95
+ child['id'] = child_category.id
96
+ child['name'] = child_category.name
97
+ child['url'] = child_category.url
98
+
99
+ child
100
+ end
101
+
102
+ # Initialize option hashes
103
+ option1 = { 'name' => [], 'values' => [] }
104
+ option2 = { 'name' => [], 'values' => [] }
105
+ option3 = { 'name' => [], 'values' => [] }
106
+
107
+ # Default min an max values
108
+ min = 0.0
109
+ max = 1000000.0
110
+
111
+ # Set price ranges
112
+ price_ranges = [
113
+ [ 1, 10],
114
+ [ 10, 25],
115
+ [ 25, 50],
116
+ [ 50, 75],
117
+ [ 75, 100],
118
+ [ 100, 150],
119
+ [ 150, 200],
120
+ [ 200, 250],
121
+ [ 250, 300],
122
+ [ 300, 400],
123
+ [ 400, 500],
124
+ [ 500, 1000],
125
+ [ 1000, 2000],
126
+ [ 2000, 3000],
127
+ [ 4000, 5000],
128
+ [ 7000, 7500],
129
+ [ 7500, 10000],
130
+ [10000, 50000]
131
+ ]
132
+
133
+ # Create an array of the same length as the price ranges to hold a match count
134
+ price_range_matches = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
135
+
136
+ # Array to hold all relevant vendor IDs
137
+ vendor_ids = []
138
+
139
+ # Iterate over pager results for product and variant info
140
+ pager.all_items.each do |product|
141
+ option1['name'] << product.option1
142
+ option2['name'] << product.option2
143
+ option3['name'] << product.option3
144
+
145
+ product.variants.each do |variant|
146
+ option1['values'] << variant.option1.strip if !variant.option1.nil?
147
+ option2['values'] << variant.option2.strip if !variant.option2.nil?
148
+ option3['values'] << variant.option3.strip if !variant.option3.nil?
149
+
150
+ # Iterate over price ranges
151
+ price_ranges.each_with_index do |price_range, index|
152
+ min = price_range.first
153
+ max = price_range.last
154
+
155
+ # Skip to next variant if the price isnt defined or is less than $1
156
+ next if variant.price.nil? || variant.price < 1
157
+
158
+ # Increment price count at index if the varaint is within the price range
159
+ if variant.price > min and variant.price < max
160
+ price_range_matches[index] += 1
161
+ vendor_ids << product.vendor_id
162
+ end
163
+ end
164
+ end
165
+ end
166
+
167
+ # Grab all active vendors
168
+ search_filter.vendors = Vendor.where('id IN (?) AND status = ?', vendor_ids.uniq, 'Active')
169
+
170
+ # Remove nil and duplicate values from option name arrays
171
+ option1['name'] = option1['name'].compact.uniq
172
+ option2['name'] = option2['name'].compact.uniq
173
+ option3['name'] = option3['name'].compact.uniq
174
+
175
+ # ?? If option name array have exactly 1 value then set the search filter's option values
176
+ search_filter.option1 = if option1['name'].count == 1 then { 'name' => option1['name'][0], 'values' => option1['values'].compact.uniq.sort } else nil end
177
+ search_filter.option2 = if option2['name'].count == 1 then { 'name' => option2['name'][0], 'values' => option2['values'].compact.uniq.sort } else nil end
178
+ search_filter.option3 = if option3['name'].count == 1 then { 'name' => option3['name'][0], 'values' => option3['values'].compact.uniq.sort } else nil end
179
+
180
+ # Get all price ranges that have matches
181
+ search_filter.prices = price_range_matches.collect.with_index { |matches, index| price_ranges[index] if matches > 0 }.compact
182
+
183
+ # Inject the search filter into the database
184
+ # search_filter.save
185
+
186
+ # Finally, return the filter; NOTE: find out of the database so the hashes get serialized correctly
187
+ # SearchFilter.find(search_filter.id)
188
+ return search_filter
189
+ end
190
+ end
191
+ end