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,15 @@
1
+ module Caboose
2
+ class ReviewsController < Caboose::ApplicationController
3
+
4
+ def add
5
+ content = params[:content]
6
+ product_id = params[:product_id]
7
+ rating = params[:rating]
8
+ name = params[:name]
9
+ r = Review.new(:content => content, :product_id => product_id, :rating => rating, :name => name)
10
+ r.save
11
+ render :json => true
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,218 @@
1
+ module Caboose
2
+ class VariantsController < Caboose::ApplicationController
3
+
4
+ # POST /variants/find-by-options
5
+ def find_by_options
6
+
7
+ # Find the variant based on the product ID and options
8
+ variant = Variant.find_by_options(params[:product_id], params[:option1], params[:option2], params[:option3])
9
+
10
+ # If there are customizations, find the correct variant
11
+ customizations = if params[:customizations]
12
+ params[:customizations].map do |customization_id, options|
13
+ Variant.find_by_options(customization_id, options[:option1], options[:option2], options[:option3])
14
+ end
15
+ else
16
+ Array.new
17
+ end
18
+
19
+ render :json => { :variant => variant, :customizations => customizations }
20
+ end
21
+
22
+ # GET /variants/:id/display-image
23
+ def display_image
24
+ ap "File is found"
25
+ render :json => Variant.find(params[:id]).product_images.first
26
+ end
27
+
28
+ #=============================================================================
29
+ # Admin actions
30
+ #=============================================================================
31
+
32
+ # GET /admin/variants/:variant_id/edit
33
+ # GET /admin/products/:product_id/variants/:variant_id/edit
34
+ def admin_edit
35
+ return if !user_is_allowed('variants', 'edit')
36
+ @variant = Variant.find(params[:variant_id])
37
+ @product = @variant.product
38
+ render :layout => 'caboose/admin'
39
+ end
40
+
41
+ # GET /admin/variants
42
+ def admin_group
43
+ return if !user_is_allowed('variants', 'edit')
44
+
45
+ joins = []
46
+ where = ''
47
+ values = []
48
+
49
+ if params[:category_ids]
50
+ joins << [:category_memberships]
51
+ where << 'store_category_memberships.category_id IN (?)'
52
+ values << params[:category_ids]
53
+ end
54
+
55
+ if params[:vendor_ids]
56
+ joins << [:vendor]
57
+ where << 'store_vendors.id IN (?)'
58
+ values << params[:vendor_ids]
59
+ end
60
+
61
+ if params[:title]
62
+ where << 'LOWER(store_products.title) LIKE ?'
63
+ values << "%#{params[:title].downcase}%"
64
+ end
65
+
66
+ # Query for all relevant products
67
+ products = values.any? ? Caboose::Product.joins(joins).where([where].concat(values)) : []
68
+
69
+ # Grab variants for each product
70
+ @variants = products.collect { |product| product.variants }.flatten
71
+
72
+ # Grab all categories; except for all and uncategorized
73
+ @categories = Caboose::Category.where('parent_id IS NOT NULL')
74
+
75
+ # Grab all vendors
76
+ @vendors = Caboose::Vendor.all
77
+
78
+ render layout: 'caboose/admin'
79
+ end
80
+
81
+ # PUT /admin/variants/:id
82
+ def admin_update
83
+ return if !user_is_allowed('variants', 'edit')
84
+
85
+ resp = Caboose::StdClass.new({'attributes' => {}})
86
+ v = Variant.find(params[:id])
87
+
88
+ save = true
89
+ params.each do |name,value|
90
+ case name
91
+ when 'alternate_id'
92
+ v.alternate_id = value
93
+ when 'sku'
94
+ v.sku = value
95
+ when 'barcode'
96
+ v.barcode = value
97
+ when 'price'
98
+ v.price = value
99
+ when 'quantity_in_stock'
100
+ v.quantity_in_stock = value
101
+ when 'ignore_quantity'
102
+ v.ignore_quantity = value
103
+ when 'allow_backorder'
104
+ v.allow_backorder = value
105
+ when 'status'
106
+ v.status = value
107
+ when 'weight'
108
+ v.weight = value
109
+ when 'length'
110
+ v.length = value
111
+ when 'width'
112
+ v.width = value
113
+ when 'height'
114
+ v.height = value
115
+ when 'option1'
116
+ v.option1 = value
117
+ when 'option2'
118
+ v.option2 = value
119
+ when 'option3'
120
+ v.option3 = value
121
+ when 'requires_shipping'
122
+ v.requires_shipping = value
123
+ when 'taxable'
124
+ v.taxable = value
125
+ end
126
+ end
127
+ resp.success = save && v.save
128
+ render :json => resp
129
+ end
130
+
131
+ # GET /admin/products/:id/variants/new
132
+ def admin_new
133
+ return if !user_is_allowed('variants', 'add')
134
+ @top_categories = ProductCategory.where(:parent_id => nil).reorder('name').all
135
+ @product_id = params[:id]
136
+ @variant = Variant.new
137
+ render :layout => 'caboose/admin'
138
+ end
139
+
140
+ # POST /admin/products/:id/variants
141
+ def admin_add
142
+ return if !user_is_allowed('variants', 'add')
143
+ resp = Caboose::StdClass.new(
144
+ :error => nil,
145
+ :refresh => nil
146
+ )
147
+
148
+ p = Product.find(params[:id])
149
+ v = Variant.new(:product_id => p.id)
150
+ v.option1 = p.default1
151
+ v.option2 = p.default2
152
+ v.option3 = p.default3
153
+ v.status = 'Active'
154
+ v.save
155
+ resp.refresh = true
156
+ render :json => resp
157
+ end
158
+
159
+ # PUT /admin/variants/:id/attach-to-image
160
+ def admin_attach_to_image
161
+ render :json => false if !user_is_allowed('variants', 'edit')
162
+ variant_id = params[:id].to_i
163
+ img = ProductImage.find(params[:product_image_id])
164
+
165
+ exists = false
166
+ img.variants.each do |v|
167
+ if v.id == variant_id
168
+ exists = true
169
+ break
170
+ end
171
+ end
172
+ if exists
173
+ render :json => true
174
+ return
175
+ end
176
+
177
+ img.variants = [] if img.variants.nil?
178
+ img.variants << Variant.find(variant_id)
179
+ img.save
180
+
181
+ render :json => true
182
+ end
183
+
184
+ # PUT /admin/variants/:id/unattach-from-image
185
+ def admin_unattach_from_image
186
+ render :json => false if !user_is_allowed('variants', 'edit')
187
+ v = Variant.find(params[:id])
188
+ img = ProductImage.find(params[:product_image_id])
189
+ img.variants.delete(v)
190
+ img.save
191
+ render :json => true
192
+ end
193
+
194
+ # DELETE /admin/variants/:id
195
+ def admin_delete
196
+ return if !user_is_allowed('variants', 'delete')
197
+ v = Variant.find(params[:id])
198
+ v.status = 'Deleted'
199
+ v.save
200
+ render :json => Caboose::StdClass.new({
201
+ :redirect => "/admin/products/#{v.product_id}/variants"
202
+ })
203
+ end
204
+
205
+ # GET /admin/variants/status-options
206
+ def admin_status_options
207
+ arr = ['Active', 'Inactive', 'Deleted']
208
+ options = []
209
+ arr.each do |status|
210
+ options << {
211
+ :value => status,
212
+ :text => status
213
+ }
214
+ end
215
+ render :json => options
216
+ end
217
+ end
218
+ end
@@ -0,0 +1,73 @@
1
+ module Caboose
2
+ class VendorsController < Caboose::ApplicationController
3
+
4
+ # GET /admin/vendors/status-options
5
+ def status_options
6
+ options = Array.new
7
+
8
+ ['Active', 'Inactive', 'Deleted'].each do |status|
9
+ options << {
10
+ :text => status,
11
+ :value => status
12
+ }
13
+ end
14
+
15
+ render :json => options
16
+ end
17
+
18
+ # GET /admin/vendors/new
19
+ def admin_new
20
+ render :layout => 'caboose/admin'
21
+ end
22
+
23
+ # POST /admin/vendors/create
24
+ def admin_create
25
+ render :json => { :success => false, :message => 'Must define a name' } and return if params[:name].nil? || params[:name].empty?
26
+
27
+ vendor = Vendor.new
28
+ vendor.name = params[:name]
29
+ vendor.status = 'Inactive'
30
+
31
+ render :json => { :success => vendor.save, :redirect => "/admin/vendors/#{vendor.id}/edit" }
32
+ end
33
+
34
+ # GET /admin/vendors
35
+ def admin_index
36
+ @pager = Caboose::Pager.new(params, {
37
+ 'name_like' => ''
38
+ }, {
39
+ 'model' => 'Caboose::Vendor',
40
+ 'sort' => 'name',
41
+ 'desc' => false,
42
+ 'base_url' => '/admin/vendors',
43
+ 'items_per_page' => 25,
44
+ 'use_url_params' => false
45
+ });
46
+
47
+ @vendors = @pager.items
48
+
49
+ render :layout => 'caboose/admin'
50
+ end
51
+
52
+ # GET /admin/vendors/:id/edit
53
+ def admin_edit
54
+ @vendor = Vendor.find(params[:id])
55
+ render :layout => 'caboose/admin'
56
+ end
57
+
58
+ # PUT /admin/vendors/:id/update
59
+ def admin_update
60
+ vendor = Vendor.find(params[:id])
61
+
62
+ params.each do |name, value|
63
+ case name
64
+ when 'name' then vendor.name = value
65
+ when 'status' then vendor.status = value
66
+ end
67
+ end
68
+
69
+ render :json => { :success => vendor.save }
70
+ end
71
+ end
72
+ end
73
+
@@ -22,5 +22,9 @@ tinyMCE.init({
22
22
  //]]>
23
23
  </script>\n"
24
24
  end
25
+
26
+ def parent_categories
27
+ Caboose::Category.find(1).children.where(:status => 'Active')
28
+ end
25
29
  end
26
30
  end
@@ -0,0 +1,82 @@
1
+ module Caboose
2
+ module CategoriesHelper
3
+ def root_category
4
+ Caboose::Category.root
5
+ end
6
+
7
+ def top_level_categories
8
+ Caboose::Category.top_level
9
+ end
10
+
11
+ def category_list(category=root_category)
12
+ content_tag :ul, category_list_items(category)
13
+ end
14
+
15
+ def category_list_items(category)
16
+
17
+ # Link to category
18
+ link = link_to(category.name, "/admin/categories/#{category.id}/edit")
19
+
20
+ # Recursively find category children
21
+ children = content_tag :ul, category.children.collect { |child| category_list_items(child) }.join.to_s.html_safe if category.children.any?
22
+
23
+ # Return the list item
24
+ content_tag :li, link.concat(children)
25
+ end
26
+
27
+ def category_select(form_name, category=root_category, selected_id=nil)
28
+
29
+ # Collect all recursive options from specified category down
30
+ options = category_options(category, selected_id)
31
+
32
+ # Prepend the root category
33
+ options.unshift([category.name, category.id])
34
+
35
+ # Create select tag
36
+ select_tag form_name, options_for_select(options)
37
+ end
38
+
39
+ def category_options(category, selected_id, prefix="")
40
+
41
+ # Array to hold options
42
+ options = Array.new
43
+
44
+ # Recusively tterate over all child categories
45
+ category.children.collect do |child|
46
+ options << ["#{prefix} - #{child.name}", child.id]
47
+ options.concat category_options(child, selected_id, "#{prefix} -")
48
+ end
49
+
50
+ # Return the options array
51
+ return options
52
+ end
53
+
54
+ def category_checkboxes(top_categories, selected_ids = nil)
55
+ str = "<ul>"
56
+ top_categories.each do |cat|
57
+ category_checkboxes_helper(cat, selected_ids, str)
58
+ end
59
+ str << "</ul>"
60
+ return str
61
+ end
62
+
63
+ def category_checkboxes_helper(cat, selected_ids, str, prefix = "")
64
+ str << "<li>"
65
+ if cat.children && cat.children.count > 0
66
+ str << "<input type='checkbox' id='cat_#{cat.id}' value='#{cat.id}'"
67
+ str << " checked='true'" if selected_ids && selected_ids.include?(cat.id)
68
+ str << "> <label for='#{cat.id}'><h3>#{cat.name}</h3></label>"
69
+ else
70
+ str << "<input type='checkbox' id='cat_#{cat.id}' value='#{cat.id}'"
71
+ str << " checked='true'" if selected_ids && selected_ids.include?(cat.id)
72
+ str << "> <label for='#{cat.id}'>#{cat.name}</label>"
73
+ end
74
+ cat.children.each do |cat2|
75
+ str << "<ul>"
76
+ category_checkboxes_helper(cat2, selected_ids, str, "#{prefix}&nbsp;&nbsp;")
77
+ str << "</ul>"
78
+ end
79
+ str << "</li>"
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,20 @@
1
+ module Caboose
2
+ module CheckoutHelper
3
+
4
+ def checkout_nav(i)
5
+ str = ""
6
+ str << "<div id='checkout-nav'>"
7
+ str << " <ul>"
8
+ str << " <li class='odd' id='checkout_nav1'><a href='#{i <= 1 ? '#' : '/checkout/step-one' }' class='#{i == 1 ? 'current' : (i < 1 ? 'not_done' : 'done')}'><span>User Account </span></a></li>"
9
+ str << " <li class='even' id='checkout_nav2'><a href='#{i <= 2 ? '#' : '/checkout/step-two' }' class='#{i == 2 ? 'current' : (i < 2 ? 'not_done' : 'done')}'><span>Addresses </span></a></li>"
10
+ str << " <li class='odd' id='checkout_nav3'><a href='#{i <= 3 ? '#' : '/checkout/step-three' }' class='#{i == 3 ? 'current' : (i < 3 ? 'not_done' : 'done')}'><span>Shipping </span></a></li>"
11
+ str << " <li class='even' id='checkout_nav4'><a href='#{i <= 4 ? '#' : '/checkout/step-four' }' class='#{i == 4 ? 'current' : (i < 4 ? 'not_done' : 'done')}'><span>Payment </span></a></li>"
12
+ str << " <li class='odd' id='checkout_nav5'><a href='#{i <= 5 ? '#' : '/checkout/step-five' }' class='#{i == 5 ? 'current' : (i < 5 ? 'not_done' : 'done')}'><span>Confirm </span></a></li>"
13
+ str << " </ul>"
14
+ str << "</div>"
15
+ return str
16
+ end
17
+
18
+ end
19
+ end
20
+
@@ -15,5 +15,13 @@ module Caboose
15
15
  return 0
16
16
  end
17
17
 
18
+ def active_products
19
+ Caboose::Product.active
20
+ end
21
+
22
+ def caboose_sort_options
23
+ render :partial => '/caboose/products/sort_options'
24
+ end
25
+
18
26
  end
19
27
  end
@@ -0,0 +1,30 @@
1
+ module Caboose
2
+ class OrdersMailer < ActionMailer::Base
3
+ default :from => Caboose::from_address.nil? ? 'caboose-store.actionmailer@gmail.com' : Caboose::from_address
4
+
5
+ # Sends a confirmation email to the customer about a new order
6
+ def customer_new_order(order)
7
+ @order = order
8
+ mail(:to => order.customer.email, :subject => 'Thank you for your order!')
9
+ end
10
+
11
+ # Sends a notification email to the fulfillment dept about a new order
12
+ def fulfillment_new_order(order)
13
+ @order = order
14
+ mail(:to => Caboose::fulfillment_email, :subject => 'New Order')
15
+ end
16
+
17
+ # Sends a notification email to the shipping dept that an order is ready to be shipped
18
+ def shipping_order_ready(order)
19
+ @order = order
20
+ mail(:to => Caboose::shipping_email, :subject => 'Order ready for shipping')
21
+ end
22
+
23
+ # Sends a notification email to the customer that the status of the order has been changed
24
+ def customer_status_updated(order)
25
+ @order = order
26
+ mail(:to => order.customer.email, :subject => 'Order status update')
27
+ end
28
+ end
29
+ end
30
+