caboose-store 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/MIT-LICENSE +20 -0
- data/README.md +113 -0
- data/Rakefile +38 -0
- data/app/assets/images/caboose_store/caboose_logo_small.png +0 -0
- data/app/assets/images/caboose_store/caboose_nav.png +0 -0
- data/app/assets/images/caboose_store/caboose_nav_black.png +0 -0
- data/app/assets/images/caboose_store/default_user_pic.png +0 -0
- data/app/assets/images/caboose_store/loading_green.gif +0 -0
- data/app/assets/images/caboose_store/loading_small_white_on_black.gif +0 -0
- data/app/assets/images/caboose_store/loading_white_on_black.gif +0 -0
- data/app/assets/javascripts/caboose_store/admin.js +20 -0
- data/app/assets/javascripts/caboose_store/application.js +17 -0
- data/app/assets/javascripts/caboose_store/modal.js +52 -0
- data/app/assets/javascripts/caboose_store/modal_integration.js +25 -0
- data/app/assets/javascripts/caboose_store/model.form.page.js +30 -0
- data/app/assets/javascripts/caboose_store/model.form.user.js +36 -0
- data/app/assets/javascripts/caboose_store/shortcut.js +11 -0
- data/app/assets/javascripts/caboose_store/station.js +60 -0
- data/app/assets/stylesheets/caboose_store/admin.css +100 -0
- data/app/assets/stylesheets/caboose_store/application.css +19 -0
- data/app/assets/stylesheets/caboose_store/bound_input.css +1 -0
- data/app/assets/stylesheets/caboose_store/caboose.css +4 -0
- data/app/assets/stylesheets/caboose_store/fonts/big_noodle_titling.ttf +0 -0
- data/app/assets/stylesheets/caboose_store/fonts/big_noodle_titling_oblique.ttf +0 -0
- data/app/assets/stylesheets/caboose_store/fonts.css +5 -0
- data/app/assets/stylesheets/caboose_store/login.css +23 -0
- data/app/assets/stylesheets/caboose_store/modal.css +240 -0
- data/app/assets/stylesheets/caboose_store/page_bar_generator.css +34 -0
- data/app/assets/stylesheets/caboose_store/register.css +25 -0
- data/app/assets/stylesheets/caboose_store/station_modal.css +104 -0
- data/app/assets/stylesheets/caboose_store/station_sidebar.css +232 -0
- data/app/assets/stylesheets/caboose_store/tinymce.css +25 -0
- data/app/controllers/caboose_store/application_controller.rb +18 -0
- data/app/controllers/caboose_store/cart_controller.rb +59 -0
- data/app/controllers/caboose_store/categories_controller.rb +128 -0
- data/app/controllers/caboose_store/checkout_controller.rb +164 -0
- data/app/controllers/caboose_store/orders_controller.rb +264 -0
- data/app/controllers/caboose_store/product_images_controller.rb +38 -0
- data/app/controllers/caboose_store/products_controller.rb +387 -0
- data/app/controllers/caboose_store/reviews_controller.rb +15 -0
- data/app/controllers/caboose_store/variants_controller.rb +152 -0
- data/app/helpers/caboose_store/application_helper.rb +46 -0
- data/app/helpers/caboose_store/cart_helper.rb +28 -0
- data/app/helpers/caboose_store/categories_helper.rb +38 -0
- data/app/helpers/caboose_store/products_helper.rb +87 -0
- data/app/mailers/caboose_store/orders_mailer.rb +36 -0
- data/app/models/caboose_store/address.rb +30 -0
- data/app/models/caboose_store/caboose_store_plugin.rb +22 -0
- data/app/models/caboose_store/category.rb +63 -0
- data/app/models/caboose_store/category_membership.rb +11 -0
- data/app/models/caboose_store/discount.rb +14 -0
- data/app/models/caboose_store/message.rb +22 -0
- data/app/models/caboose_store/order.rb +97 -0
- data/app/models/caboose_store/order_discount.rb +11 -0
- data/app/models/caboose_store/order_line_item.rb +13 -0
- data/app/models/caboose_store/order_pdf.rb +82 -0
- data/app/models/caboose_store/product.rb +78 -0
- data/app/models/caboose_store/product_image.rb +25 -0
- data/app/models/caboose_store/product_image_variant.rb +10 -0
- data/app/models/caboose_store/review.rb +13 -0
- data/app/models/caboose_store/schema.rb +146 -0
- data/app/models/caboose_store/shipping_calculator.rb +79 -0
- data/app/models/caboose_store/states.rb +60 -0
- data/app/models/caboose_store/tax_calculator.rb +26 -0
- data/app/models/caboose_store/tax_line.rb +12 -0
- data/app/models/caboose_store/variant.rb +42 -0
- data/app/models/caboose_store/vendor.rb +7 -0
- data/app/views/caboose_store/application/_category_thumb.html.erb +6 -0
- data/app/views/caboose_store/application/_product_thumb.html.erb +13 -0
- data/app/views/caboose_store/cart/index.html.erb +19 -0
- data/app/views/caboose_store/categories/admin_edit.html.erb +82 -0
- data/app/views/caboose_store/categories/admin_index.html.erb +13 -0
- data/app/views/caboose_store/categories/admin_new.html.erb +45 -0
- data/app/views/caboose_store/checkout/billing.html.erb +168 -0
- data/app/views/caboose_store/checkout/discount.html.erb +166 -0
- data/app/views/caboose_store/checkout/index.html.erb +113 -0
- data/app/views/caboose_store/checkout/quantity_box.html.erb +39 -0
- data/app/views/caboose_store/checkout/shipping.html.erb +90 -0
- data/app/views/caboose_store/checkout/thank_you.html.erb +36 -0
- data/app/views/caboose_store/layouts/_banner.html.erb +10 -0
- data/app/views/caboose_store/layouts/_banner2.html.erb +10 -0
- data/app/views/caboose_store/layouts/_footer.html.erb +55 -0
- data/app/views/caboose_store/layouts/_header.html.erb +69 -0
- data/app/views/caboose_store/layouts/_sidebar.html.erb +27 -0
- data/app/views/caboose_store/layouts/application.html.erb +33 -0
- data/app/views/caboose_store/layouts/authorize_net.erb +18 -0
- data/app/views/caboose_store/layouts/layout_about.html.erb +42 -0
- data/app/views/caboose_store/layouts/layout_blog.html.erb +159 -0
- data/app/views/caboose_store/layouts/layout_confirm.html.erb +85 -0
- data/app/views/caboose_store/layouts/layout_contact.html.erb +38 -0
- data/app/views/caboose_store/layouts/layout_default.html.erb +10 -0
- data/app/views/caboose_store/layouts/layout_detail.html.erb +114 -0
- data/app/views/caboose_store/layouts/layout_order.html.erb +77 -0
- data/app/views/caboose_store/layouts/layout_pricing.html.erb +182 -0
- data/app/views/caboose_store/layouts/layout_product.html.erb +110 -0
- data/app/views/caboose_store/layouts/layout_profile.html.erb +55 -0
- data/app/views/caboose_store/layouts/layout_single.html.erb +3 -0
- data/app/views/caboose_store/layouts/layout_testimonial.html.erb +110 -0
- data/app/views/caboose_store/layouts/layout_testing.html.erb +4 -0
- data/app/views/caboose_store/orders/_admin_footer.html.erb +2 -0
- data/app/views/caboose_store/orders/_admin_header.html.erb +31 -0
- data/app/views/caboose_store/orders/_quickbooks_order.html.erb +0 -0
- data/app/views/caboose_store/orders/admin_delete_form.html.erb +21 -0
- data/app/views/caboose_store/orders/admin_edit.html.erb +173 -0
- data/app/views/caboose_store/orders/admin_index.html.erb +79 -0
- data/app/views/caboose_store/orders/admin_new.html.erb +42 -0
- data/app/views/caboose_store/orders/admin_print.html.erb +72 -0
- data/app/views/caboose_store/orders_mailer/customer_new_order.html.erb +47 -0
- data/app/views/caboose_store/orders_mailer/customer_status_updated.html.erb +49 -0
- data/app/views/caboose_store/orders_mailer/fulfillment_new_order.html.erb +43 -0
- data/app/views/caboose_store/orders_mailer/shipping_order_ready.html.erb +46 -0
- data/app/views/caboose_store/products/_admin_footer.html.erb +2 -0
- data/app/views/caboose_store/products/_admin_header.html.erb +31 -0
- data/app/views/caboose_store/products/admin_delete_form.html.erb +21 -0
- data/app/views/caboose_store/products/admin_edit_categories.html.erb +73 -0
- data/app/views/caboose_store/products/admin_edit_category_images.html.erb +233 -0
- data/app/views/caboose_store/products/admin_edit_description.html.erb +41 -0
- data/app/views/caboose_store/products/admin_edit_general.html.erb +47 -0
- data/app/views/caboose_store/products/admin_edit_images.html.erb +234 -0
- data/app/views/caboose_store/products/admin_edit_options.html.erb +51 -0
- data/app/views/caboose_store/products/admin_edit_seo.html.erb +37 -0
- data/app/views/caboose_store/products/admin_edit_variant_columns.html.erb +75 -0
- data/app/views/caboose_store/products/admin_edit_variants.html.erb +101 -0
- data/app/views/caboose_store/products/admin_edit_variants_single.html.erb +68 -0
- data/app/views/caboose_store/products/admin_index.html.erb +47 -0
- data/app/views/caboose_store/products/admin_new.html.erb +41 -0
- data/app/views/caboose_store/products/details.html.erb +437 -0
- data/app/views/caboose_store/products/index.html.erb +46 -0
- data/app/views/caboose_store/products/not_available.html.erb +35 -0
- data/app/views/caboose_store/variants/admin_edit.html.erb +80 -0
- data/app/views/caboose_store/variants/admin_new.html.erb +59 -0
- data/config/routes.rb +95 -0
- data/lib/caboose-store/caboose_store_helper.rb +35 -0
- data/lib/caboose-store/engine.rb +8 -0
- data/lib/caboose-store/version.rb +3 -0
- data/lib/caboose-store.rb +9 -0
- data/lib/tasks/caboose-store.rake +17 -0
- data/test/caboose_test.rb +7 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config/application.rb +59 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +4 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/test.log +25 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/test_helper.rb +15 -0
- metadata +260 -0
@@ -0,0 +1,59 @@
|
|
1
|
+
module CabooseStore
|
2
|
+
class CartController < ApplicationController
|
3
|
+
|
4
|
+
# GET /cart
|
5
|
+
def index
|
6
|
+
@order = self.get_cart
|
7
|
+
render :layout => 'layouts/caboose/modal'
|
8
|
+
end
|
9
|
+
|
10
|
+
# GET /cart/add/:id
|
11
|
+
def add
|
12
|
+
v = Variant.find(params[:id])
|
13
|
+
@order = self.get_cart
|
14
|
+
|
15
|
+
exists = false
|
16
|
+
@order.line_items.each do |li|
|
17
|
+
next if li.variant.id != v.id
|
18
|
+
li.quantity = li.quantity + 1
|
19
|
+
li.save
|
20
|
+
exists = true
|
21
|
+
break
|
22
|
+
end
|
23
|
+
if !exists
|
24
|
+
li = OrderLineItem.new
|
25
|
+
li.variant = v
|
26
|
+
li.quantity = 1
|
27
|
+
li.unit_price = v.price
|
28
|
+
li.variant_sku = v.sku
|
29
|
+
@order.line_items << li
|
30
|
+
end
|
31
|
+
@order.save
|
32
|
+
|
33
|
+
render 'caboose_store/cart/index', :layout => 'layouts/caboose/modal'
|
34
|
+
end
|
35
|
+
|
36
|
+
# PUT /cart/:id
|
37
|
+
def update
|
38
|
+
resp = Caboose::StdClass.new
|
39
|
+
|
40
|
+
order_id = session['cart_id']
|
41
|
+
variant_id = params[:id].to_i
|
42
|
+
qty = params[:quantity_in_stock].to_i
|
43
|
+
|
44
|
+
if (qty == 0)
|
45
|
+
OrderLineItem.where(:order_id => order_id, :variant_id => variant_id).delete_all
|
46
|
+
else
|
47
|
+
li = OrderLineItem.where(:order_id => order_id, :variant_id => variant_id).first
|
48
|
+
li.quantity = qty
|
49
|
+
li.save
|
50
|
+
end
|
51
|
+
render :json => resp
|
52
|
+
end
|
53
|
+
|
54
|
+
def get_cart
|
55
|
+
# Assumes the init_cart method is running in the parent application controller
|
56
|
+
return Order.find(session['cart_id'])
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
module CabooseStore
|
2
|
+
class CategoriesController < ApplicationController
|
3
|
+
|
4
|
+
#=============================================================================
|
5
|
+
# Admin actions
|
6
|
+
#=============================================================================
|
7
|
+
|
8
|
+
# GET /admin/categories
|
9
|
+
def admin_index
|
10
|
+
return if !user_is_allowed('categories', 'view')
|
11
|
+
@top_category = Category.find(1)
|
12
|
+
render :layout => 'caboose/admin'
|
13
|
+
end
|
14
|
+
|
15
|
+
# GET /admin/categories/:id/edit
|
16
|
+
def admin_edit
|
17
|
+
return if !user_is_allowed('categories', 'edit')
|
18
|
+
@category = Category.find(params[:id])
|
19
|
+
render :layout => 'caboose/admin'
|
20
|
+
end
|
21
|
+
|
22
|
+
# PUT /admin/categories/:id
|
23
|
+
def admin_update
|
24
|
+
return if !user_is_allowed('categories', 'edit')
|
25
|
+
|
26
|
+
resp = Caboose::StdClass.new({'attributes' => {}})
|
27
|
+
cat = Category.find(params[:id])
|
28
|
+
|
29
|
+
save = true
|
30
|
+
params.each do |name,value|
|
31
|
+
case name
|
32
|
+
when 'name'
|
33
|
+
cat.name = value
|
34
|
+
when 'slug'
|
35
|
+
cat.slug = value
|
36
|
+
cat.url = cat.parent ? "#{cat.parent.url}/#{cat.slug}" : "/#{cat.slug}"
|
37
|
+
update_child_category_slugs(cat)
|
38
|
+
when 'square_offset_x'
|
39
|
+
cat.square_offset_x = value
|
40
|
+
when 'square_offset_y'
|
41
|
+
cat.square_offset_y = value
|
42
|
+
when 'square_scale_factor'
|
43
|
+
cat.square_scale_factor = value
|
44
|
+
when 'image'
|
45
|
+
cat.image = value
|
46
|
+
end
|
47
|
+
end
|
48
|
+
resp.success = save && cat.save
|
49
|
+
if params[:image]
|
50
|
+
resp.attributes['image'] = { 'value' => cat.image.url(:medium) }
|
51
|
+
end
|
52
|
+
render json: resp
|
53
|
+
end
|
54
|
+
|
55
|
+
def update_child_category_slugs(cat)
|
56
|
+
return if cat.children.nil?
|
57
|
+
return if cat.children.count == 0
|
58
|
+
cat.children.each do |kid|
|
59
|
+
kid.url = "#{cat.url}/#{kid.slug}"
|
60
|
+
kid.save
|
61
|
+
update_child_category_slugs(kid)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# GET /admin/categories/new
|
66
|
+
def admin_new
|
67
|
+
return if !user_is_allowed('categories', 'add')
|
68
|
+
@top_category = Category.find(1)
|
69
|
+
render :layout => 'caboose/admin'
|
70
|
+
end
|
71
|
+
|
72
|
+
# POST /admin/categories
|
73
|
+
def admin_add
|
74
|
+
return if !user_is_allowed('categories', 'add')
|
75
|
+
|
76
|
+
resp = Caboose::StdClass.new(
|
77
|
+
:error => nil,
|
78
|
+
:redirect => nil
|
79
|
+
)
|
80
|
+
parent_id = params[:parent_id]
|
81
|
+
name = params[:name]
|
82
|
+
|
83
|
+
if parent_id == ''
|
84
|
+
resp.error = "Please select a parent category."
|
85
|
+
elsif name.length == 0
|
86
|
+
resp.error = "The title cannot be empty."
|
87
|
+
else
|
88
|
+
cat = Category.new
|
89
|
+
cat.parent_id = parent_id
|
90
|
+
cat.name = name
|
91
|
+
cat.slug = Category.get_slug(cat.name)
|
92
|
+
cat.save
|
93
|
+
cat.url = cat.parent ? "#{cat.parent.url}/#{cat.slug}" : "/#{cat.slug}"
|
94
|
+
cat.save
|
95
|
+
resp.redirect = "/admin/categories/#{cat.id}/edit"
|
96
|
+
end
|
97
|
+
render :json => resp
|
98
|
+
end
|
99
|
+
|
100
|
+
# DELETE /admin/categories/:id
|
101
|
+
def admin_delete
|
102
|
+
return if !user_is_allowed('categories', 'delete')
|
103
|
+
|
104
|
+
resp = Caboose::StdClass.new(
|
105
|
+
:error => nil,
|
106
|
+
:redirect => nil
|
107
|
+
)
|
108
|
+
|
109
|
+
cat = Category.find(params[:id])
|
110
|
+
if cat.products && cat.products.count > 0
|
111
|
+
resp.error = "You can't delete a category that has products in it."
|
112
|
+
elsif cat.children && cat.children.count > 0
|
113
|
+
resp.error = "You can't delete a category that has child categories."
|
114
|
+
else
|
115
|
+
cat.destroy
|
116
|
+
resp.redirect = '/admin/categories'
|
117
|
+
end
|
118
|
+
|
119
|
+
render :json => resp
|
120
|
+
end
|
121
|
+
|
122
|
+
# GET /admin/categories/options
|
123
|
+
def admin_options
|
124
|
+
return if !user_is_allowed('categories', 'view')
|
125
|
+
render :json => Category.options
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
module CabooseStore
|
2
|
+
class CheckoutController < ApplicationController
|
3
|
+
|
4
|
+
helper :authorize_net
|
5
|
+
protect_from_forgery :except => :authnet_relay_response
|
6
|
+
|
7
|
+
# GET /checkout
|
8
|
+
def index
|
9
|
+
@order = Order.find(session['cart_id'])
|
10
|
+
@is_logged_in = logged_in?
|
11
|
+
if @is_logged_in
|
12
|
+
@order.customer_id = logged_in_user.id
|
13
|
+
@order.save
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# GET /checkout/shipping-address
|
18
|
+
def shipping_address
|
19
|
+
@order = Order.find(session['cart_id'])
|
20
|
+
end
|
21
|
+
|
22
|
+
# PUT /checkout/shipping-address
|
23
|
+
def update_shipping_address
|
24
|
+
resp = Caboose::StdClass.new
|
25
|
+
|
26
|
+
order = Order.find(session['cart_id'])
|
27
|
+
a = order.shipping_address ? order.shipping_address : Address.new
|
28
|
+
a.name = params[:name]
|
29
|
+
a.company = params[:company]
|
30
|
+
a.address1 = params[:address1]
|
31
|
+
a.address2 = params[:address2]
|
32
|
+
a.city = params[:city]
|
33
|
+
a.state = params[:state]
|
34
|
+
a.zip = params[:zip]
|
35
|
+
|
36
|
+
if (a.name.strip.length == 0)
|
37
|
+
resp.error = "A name is required."
|
38
|
+
elsif (a.address1.strip.length == 0)
|
39
|
+
resp.error = "An address is required."
|
40
|
+
elsif (a.city.strip.length == 0)
|
41
|
+
resp.error = "A city is required."
|
42
|
+
elsif (a.state.strip.length == 0)
|
43
|
+
resp.error = "A state is required."
|
44
|
+
elsif (a.zip.strip.length < 5)
|
45
|
+
resp.error = "A valid zip code is required."
|
46
|
+
end
|
47
|
+
|
48
|
+
if (resp.error.nil?)
|
49
|
+
a.save
|
50
|
+
tax_rate = TaxCalculator.tax_rate(a)
|
51
|
+
order.tax = order.subtotal * tax_rate
|
52
|
+
order.shipping_address_id = a.id
|
53
|
+
order.calculate_total
|
54
|
+
order.save
|
55
|
+
resp.redirect = '/checkout/shipping'
|
56
|
+
end
|
57
|
+
render :json => resp
|
58
|
+
end
|
59
|
+
|
60
|
+
# GET /checkout/shipping
|
61
|
+
def shipping
|
62
|
+
@order = Order.find(session['cart_id'])
|
63
|
+
end
|
64
|
+
|
65
|
+
# GET /checkout/shipping-rates
|
66
|
+
def shipping_rates
|
67
|
+
order = Order.find(session['cart_id'])
|
68
|
+
render :json => ShippingCalculator.rates(order)
|
69
|
+
end
|
70
|
+
|
71
|
+
# PUT /checkout/shipping-method
|
72
|
+
def update_shipping_method
|
73
|
+
resp = Caboose::StdClass.new
|
74
|
+
order = Order.find(session['cart_id'])
|
75
|
+
|
76
|
+
code = params[:shipping_method_code]
|
77
|
+
if code.nil? || code.strip.length == 0
|
78
|
+
resp.error = "You must select a shipping method."
|
79
|
+
else
|
80
|
+
order.shipping = params[:shipping].to_f/100
|
81
|
+
order.shipping_method = params[:shipping_method]
|
82
|
+
order.shipping_method_code = params[:shipping_method_code]
|
83
|
+
order.handling = order.shipping * 0.05
|
84
|
+
order.calculate_total
|
85
|
+
order.save
|
86
|
+
resp.redirect = '/checkout/billing'
|
87
|
+
end
|
88
|
+
render :json => resp
|
89
|
+
end
|
90
|
+
|
91
|
+
# GET /checkout/billing
|
92
|
+
def billing
|
93
|
+
@order = Order.find(session['cart_id'])
|
94
|
+
@logged_in_user = logged_in_user
|
95
|
+
@sim_transaction = AuthorizeNet::SIM::Transaction.new(
|
96
|
+
AUTHORIZE_NET_CONFIG['api_login_id'],
|
97
|
+
AUTHORIZE_NET_CONFIG['api_transaction_key'],
|
98
|
+
@order.total,
|
99
|
+
:relay_url => 'https://www.tuskwearcollection.com/checkout/authnet-relay-response',
|
100
|
+
:transaction_type => 'AUTH_ONLY' #AuthorizeNet::Type::AUTHORIZE_ONLY
|
101
|
+
)
|
102
|
+
end
|
103
|
+
|
104
|
+
# POST /checkout/authnet-relay-response
|
105
|
+
def authnet_relay_response
|
106
|
+
sim_response = AuthorizeNet::SIM::Response.new(params)
|
107
|
+
if sim_response.success?(AUTHORIZE_NET_CONFIG['api_login_id'], AUTHORIZE_NET_CONFIG['merchant_hash_value'])
|
108
|
+
if (params[:x_response_code].to_i == 1) # Approved
|
109
|
+
order = Order.find(params[:x_invoice_num])
|
110
|
+
order.date_authorized = DateTime.now
|
111
|
+
order.transaction_id = params[:x_trans_id]
|
112
|
+
order.auth_code = params[:x_auth_code]
|
113
|
+
order.auth_amount = order.total
|
114
|
+
order.financial_status = 'authorized'
|
115
|
+
order.status = 'pending'
|
116
|
+
order.save
|
117
|
+
end
|
118
|
+
end
|
119
|
+
render :text => sim_response.direct_post_reply('https://www.tuskwearcollection.com/checkout/authnet-receipt', :include => true)
|
120
|
+
end
|
121
|
+
|
122
|
+
# GET /checkout/authnet-receipt
|
123
|
+
def authnet_receipt
|
124
|
+
js = ""
|
125
|
+
if (params[:x_response_code].to_i == 1) # Approved
|
126
|
+
js = "parent.window.location = '/checkout/finalize';"
|
127
|
+
else
|
128
|
+
msg = "<p class='note error'>There was an error processing your card:<br /><br />#{params[:x_response_reason_text]}</p>"
|
129
|
+
msg = msg.gsub('"', '')
|
130
|
+
js = "parent.$('#message').html(\"#{msg}\");"
|
131
|
+
end
|
132
|
+
render :text => "<script type='text/javascript'>#{js}</script>"
|
133
|
+
end
|
134
|
+
|
135
|
+
# GET /checkout/finalize
|
136
|
+
def finalize
|
137
|
+
order = Order.find(session['cart_id'])
|
138
|
+
|
139
|
+
# Make sure they didn't come to the page twice
|
140
|
+
if order.line_items.count == 0
|
141
|
+
redirect_to "/"
|
142
|
+
return
|
143
|
+
end
|
144
|
+
|
145
|
+
# Notify the customer
|
146
|
+
OrdersMailer.customer_new_order(order).deliver
|
147
|
+
|
148
|
+
# Notify the fulfillment center
|
149
|
+
OrdersMailer.fulfillment_new_order(order).deliver
|
150
|
+
|
151
|
+
# Add the order to quickbooks
|
152
|
+
#Quickbooks.create_order(order)
|
153
|
+
|
154
|
+
# Clear everything
|
155
|
+
session['cart_id'] = nil
|
156
|
+
|
157
|
+
redirect_to '/checkout/thank-you'
|
158
|
+
end
|
159
|
+
|
160
|
+
def thank_you
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
end
|
@@ -0,0 +1,264 @@
|
|
1
|
+
module CabooseStore
|
2
|
+
class OrdersController < ApplicationController
|
3
|
+
|
4
|
+
helper :authorize_net
|
5
|
+
protect_from_forgery :except => :authnet_relay_response
|
6
|
+
|
7
|
+
# GET /admin/orders
|
8
|
+
def admin_index
|
9
|
+
return if !user_is_allowed('orders', 'view')
|
10
|
+
|
11
|
+
@gen = Caboose::PageBarGenerator.new(params, {
|
12
|
+
'customer_id' => '',
|
13
|
+
'status' => 'pending',
|
14
|
+
'shipping_method_code' => '',
|
15
|
+
'id' => ''
|
16
|
+
},{
|
17
|
+
'model' => 'CabooseStore::Order',
|
18
|
+
'sort' => 'id',
|
19
|
+
'desc' => 1,
|
20
|
+
'base_url' => '/admin/orders'
|
21
|
+
})
|
22
|
+
@orders = @gen.items
|
23
|
+
@customers = Caboose::User.reorder('last_name, first_name').all
|
24
|
+
render :layout => 'caboose/admin'
|
25
|
+
end
|
26
|
+
|
27
|
+
# GET /admin/orders/new
|
28
|
+
def admin_new
|
29
|
+
return if !user_is_allowed('orders', 'add')
|
30
|
+
@products = Product.reorder('title').all
|
31
|
+
render :layout => 'caboose/admin'
|
32
|
+
end
|
33
|
+
|
34
|
+
# GET /admin/orders/:id
|
35
|
+
def admin_edit
|
36
|
+
return if !user_is_allowed('orders', 'edit')
|
37
|
+
@order = Order.find(params[:id])
|
38
|
+
render :layout => 'caboose/admin'
|
39
|
+
end
|
40
|
+
|
41
|
+
# GET /admin/orders/:id/json
|
42
|
+
def admin_json
|
43
|
+
return if !user_is_allowed('orders', 'edit')
|
44
|
+
order = Order.find(params[:id])
|
45
|
+
render :json => order, :include => { :order_line_items => { :include => :variant }}
|
46
|
+
end
|
47
|
+
|
48
|
+
# GET /admin/orders/:id/print
|
49
|
+
def admin_print
|
50
|
+
return if !user_is_allowed('orders', 'edit')
|
51
|
+
|
52
|
+
pdf = OrderPdf.new
|
53
|
+
pdf.order = Order.find(params[:id])
|
54
|
+
send_data pdf.to_pdf, filename: "order_#{pdf.order.id}.pdf", type: "application/pdf", disposition: "inline"
|
55
|
+
|
56
|
+
#@order = Order.find(params[:id])
|
57
|
+
#render :layout => 'caboose/admin'
|
58
|
+
end
|
59
|
+
|
60
|
+
# PUT /admin/orders/:id
|
61
|
+
def admin_update
|
62
|
+
return if !user_is_allowed('orders', 'edit')
|
63
|
+
|
64
|
+
resp = Caboose::StdClass.new({'attributes' => {}})
|
65
|
+
order = Order.find(params[:id])
|
66
|
+
|
67
|
+
save = true
|
68
|
+
params.each do |name,value|
|
69
|
+
case name
|
70
|
+
when 'tax'
|
71
|
+
order.tax = value
|
72
|
+
when 'shipping'
|
73
|
+
order.shipping = value
|
74
|
+
when 'handling'
|
75
|
+
order.handling = value
|
76
|
+
when 'discount'
|
77
|
+
order.discount = value
|
78
|
+
when 'status'
|
79
|
+
order.status = value
|
80
|
+
resp.attributes['status'] = {'text' => value}
|
81
|
+
end
|
82
|
+
end
|
83
|
+
order.calculate_total
|
84
|
+
resp.success = save && order.save
|
85
|
+
render :json => resp
|
86
|
+
end
|
87
|
+
|
88
|
+
# PUT /admin/orders/:order_id/line-items/:id
|
89
|
+
def admin_update_line_item
|
90
|
+
return if !user_is_allowed('orders', 'edit')
|
91
|
+
|
92
|
+
resp = Caboose::StdClass.new({'attributes' => {}})
|
93
|
+
li = OrderLineItem.find(params[:id])
|
94
|
+
|
95
|
+
save = true
|
96
|
+
send_status_email = false
|
97
|
+
params.each do |name,value|
|
98
|
+
case name
|
99
|
+
when 'quantity'
|
100
|
+
li.quantity = value
|
101
|
+
li.save
|
102
|
+
|
103
|
+
# Recalculate everything
|
104
|
+
r = ShippingCalculator.rate(li.order, li.order.shipping_method_code)
|
105
|
+
li.order.shipping = r['negotiated_rate'] / 100
|
106
|
+
li.order.handling = (r['negotiated_rate'] / 100) * 0.05
|
107
|
+
tax_rate = TaxCalculator.tax_rate(li.order.shipping_address)
|
108
|
+
li.order.tax = li.order.subtotal * tax_rate
|
109
|
+
li.order.calculate_total
|
110
|
+
li.order.save
|
111
|
+
|
112
|
+
when 'tracking_number'
|
113
|
+
li.tracking_number = value
|
114
|
+
send_status_email = true
|
115
|
+
when 'status'
|
116
|
+
li.status = value
|
117
|
+
resp.attributes['status'] = {'text' => value}
|
118
|
+
send_status_email = true
|
119
|
+
end
|
120
|
+
end
|
121
|
+
if send_status_email
|
122
|
+
OrdersMailer.customer_status_updated(li.order).deliver
|
123
|
+
end
|
124
|
+
resp.success = save && li.save
|
125
|
+
render :json => resp
|
126
|
+
end
|
127
|
+
|
128
|
+
# DELETE /admin/orders/:id
|
129
|
+
def admin_delete
|
130
|
+
return if !user_is_allowed('orders', 'delete')
|
131
|
+
Order.find(params[:id]).destroy
|
132
|
+
render :json => Caboose::StdClass.new({
|
133
|
+
:redirect => '/admin/orders'
|
134
|
+
})
|
135
|
+
end
|
136
|
+
|
137
|
+
# GET /admin/orders/line-item-status-options
|
138
|
+
def admin_line_item_status_options
|
139
|
+
arr = ['pending', 'ready to ship', 'shipped', 'backordered', 'canceled']
|
140
|
+
options = []
|
141
|
+
arr.each do |status|
|
142
|
+
options << {
|
143
|
+
:value => status,
|
144
|
+
:text => status
|
145
|
+
}
|
146
|
+
end
|
147
|
+
render :json => options
|
148
|
+
end
|
149
|
+
|
150
|
+
# GET /admin/orders/:id/capture
|
151
|
+
def capture_funds
|
152
|
+
return if !user_is_allowed('orders', 'edit')
|
153
|
+
|
154
|
+
resp = Caboose::StdClass.new({
|
155
|
+
'refresh' => nil,
|
156
|
+
'error' => nil,
|
157
|
+
'success' => nil
|
158
|
+
})
|
159
|
+
|
160
|
+
order = Order.find(params[:id])
|
161
|
+
if order.financial_status == 'captured'
|
162
|
+
resp.error = "Funds for this order have already been captured."
|
163
|
+
elsif order.total > order.auth_amount
|
164
|
+
resp.error = "The order total exceeds the authorized amount."
|
165
|
+
else
|
166
|
+
trans = AuthorizeNet::AIM::Transaction.new(
|
167
|
+
AUTHORIZE_NET_CONFIG['api_login_id'],
|
168
|
+
AUTHORIZE_NET_CONFIG['api_transaction_key'],
|
169
|
+
:gateway => :production
|
170
|
+
#:test => true
|
171
|
+
)
|
172
|
+
amount = order.total < order.auth_amount ? order.total : nil
|
173
|
+
r = trans.prior_auth_capture(order.transaction_id, amount)
|
174
|
+
Caboose.log(r.inspect)
|
175
|
+
if r.success?
|
176
|
+
order.financial_status = 'captured'
|
177
|
+
order.save
|
178
|
+
resp.success = "Captured funds successfully."
|
179
|
+
else
|
180
|
+
if r.connection_failure?
|
181
|
+
resp.error = "Error connecting to authorize.net."
|
182
|
+
else
|
183
|
+
resp.error = "Error capture funds."
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
render :json => resp
|
188
|
+
end
|
189
|
+
|
190
|
+
# GET /admin/orders/:id/send-to-quickbooks
|
191
|
+
def admin_send_to_quickbooks
|
192
|
+
return if !user_is_allowed('orders', 'edit')
|
193
|
+
|
194
|
+
resp = Caboose::StdClass.new({
|
195
|
+
'refresh' => nil,
|
196
|
+
'success' => nil,
|
197
|
+
'error' => nil
|
198
|
+
})
|
199
|
+
order = Order.find(params[:id])
|
200
|
+
Quickbooks.create_order(order)
|
201
|
+
resp.success = "Order sent to quickbooks successfully."
|
202
|
+
render :json => resp
|
203
|
+
end
|
204
|
+
|
205
|
+
# GET /admin/orders/status-options
|
206
|
+
def admin_status_options
|
207
|
+
return if !user_is_allowed('categories', 'view')
|
208
|
+
statuses = ['cart', 'pending', 'ready to ship', 'shipped', 'canceled']
|
209
|
+
options = []
|
210
|
+
statuses.each do |s|
|
211
|
+
options << {
|
212
|
+
'text' => s,
|
213
|
+
'value' => s
|
214
|
+
}
|
215
|
+
end
|
216
|
+
render :json => options
|
217
|
+
end
|
218
|
+
|
219
|
+
# GET /admin/orders/authnet-relay-response
|
220
|
+
# POST /admin/orders/authnet-relay-response
|
221
|
+
#def authnet_relay_response
|
222
|
+
# sim_response = AuthorizeNet::SIM::Response.new(params)
|
223
|
+
# if sim_response.success?(AUTHORIZE_NET_CONFIG['api_login_id'], AUTHORIZE_NET_CONFIG['merchant_hash_value'])
|
224
|
+
# if (params[:x_response_code].to_i == 1) # Approved
|
225
|
+
# order = Order.find(params[:x_invoice_num])
|
226
|
+
# order.date_captured = DateTime.now
|
227
|
+
# order.financial_status = 'captured'
|
228
|
+
# order.save
|
229
|
+
# end
|
230
|
+
# end
|
231
|
+
# render :text => sim_response.direct_post_reply('https://tuskwearadmin.herokuapp.com/admin/orders/authnet-receipt', :include => true)
|
232
|
+
#end
|
233
|
+
|
234
|
+
# GET /admin/orders/authnet-receipt
|
235
|
+
#def authnet_receipt
|
236
|
+
# return if !user_is_allowed('orders', 'edit')
|
237
|
+
#
|
238
|
+
# resp = Caboose::StdClass.new({
|
239
|
+
# 'refresh' => nil,
|
240
|
+
# 'error' => nil
|
241
|
+
# })
|
242
|
+
#
|
243
|
+
# if (params[:x_response_code].to_i == 1) # Approved
|
244
|
+
# resp.refresh = true
|
245
|
+
# else
|
246
|
+
# resp.error = "There was an error capture funds:<br /><br />#{params[:x_response_reason_text]}"
|
247
|
+
# end
|
248
|
+
# render :text => "<script type='text/javascript'>parent.capture_funds_response(#{resp.to_json});</script>"
|
249
|
+
#end
|
250
|
+
|
251
|
+
# GET /admin/orders/test-info
|
252
|
+
def admin_mail_test_info
|
253
|
+
TestMailer.test_info.deliver
|
254
|
+
render :text => "Sent email to info@tuskwearcollection.com on #{DateTime.now.strftime("%F %T")}"
|
255
|
+
end
|
256
|
+
|
257
|
+
# GET /admin/orders/test-gmail
|
258
|
+
def admin_mail_test_gmail
|
259
|
+
TestMailer.test_gmail.deliver
|
260
|
+
render :text => "Sent email to william@nine.is on #{DateTime.now.strftime("%F %T")}"
|
261
|
+
end
|
262
|
+
|
263
|
+
end
|
264
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module CabooseStore
|
2
|
+
class ProductImagesController < ApplicationController
|
3
|
+
|
4
|
+
#=============================================================================
|
5
|
+
# Admin actions
|
6
|
+
#=============================================================================
|
7
|
+
|
8
|
+
# GET /admin/product-images/:id/variant-ids
|
9
|
+
def admin_variant_ids
|
10
|
+
return if !user_is_allowed('variants', 'edit')
|
11
|
+
img = ProductImage.find(params[:id])
|
12
|
+
ids = img.variants.collect{ |v| v.id }
|
13
|
+
render :json => ids
|
14
|
+
end
|
15
|
+
|
16
|
+
# GET /admin/product-images/:id/variants
|
17
|
+
def admin_variants
|
18
|
+
return if !user_is_allowed('variants', 'edit')
|
19
|
+
img = ProductImage.find(params[:id])
|
20
|
+
render :json => img.variants
|
21
|
+
end
|
22
|
+
|
23
|
+
# DELETE /admin/product-images/:id
|
24
|
+
def admin_delete
|
25
|
+
return if !user_is_allowed('variants', 'delete')
|
26
|
+
img = ProductImage.find(params[:id]).destroy
|
27
|
+
render :json => true
|
28
|
+
end
|
29
|
+
|
30
|
+
# GET /variant-images/:id
|
31
|
+
def variant_images
|
32
|
+
var = Variant.find(params[:id])
|
33
|
+
img = var.product_images.first
|
34
|
+
render :json => img
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|