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,146 @@
|
|
1
|
+
|
2
|
+
class CabooseStore::Schema < Caboose::Utilities::Schema
|
3
|
+
|
4
|
+
def self.schema
|
5
|
+
{
|
6
|
+
CabooseStore::Category => [
|
7
|
+
[ :parent_id , :integer ],
|
8
|
+
[ :name , :string ],
|
9
|
+
[ :url , :string ],
|
10
|
+
[ :slug , :string ],
|
11
|
+
[ :image_file_name , :string ],
|
12
|
+
[ :image_content_type , :string ],
|
13
|
+
[ :image_file_size , :integer ],
|
14
|
+
[ :image_updated_at , :datetime ],
|
15
|
+
[ :square_offset_x , :integer ],
|
16
|
+
[ :square_offset_y , :integer ],
|
17
|
+
[ :square_scale_factor , :numeric ],
|
18
|
+
[ :sort , :integer ]
|
19
|
+
],
|
20
|
+
CabooseStore::CategoryMembership => [
|
21
|
+
[ :category_id , :integer ],
|
22
|
+
[ :product_id , :integer ]
|
23
|
+
],
|
24
|
+
CabooseStore::Discount => [
|
25
|
+
[ :id , :integer ],
|
26
|
+
[ :name , :string ],
|
27
|
+
[ :code , :string ],
|
28
|
+
[ :amount_flat , :numeric ],
|
29
|
+
[ :amount_percentage , :numeric ],
|
30
|
+
[ :no_shipping , :boolean ],
|
31
|
+
[ :no_tax , :boolean ]
|
32
|
+
],
|
33
|
+
CabooseStore::OrderDiscount => [
|
34
|
+
[ :order_id , :integer ],
|
35
|
+
[ :discount_id , :integer ]
|
36
|
+
],
|
37
|
+
CabooseStore::OrderLineItem => [
|
38
|
+
[ :order_id , :integer ],
|
39
|
+
[ :variant_id , :integer ],
|
40
|
+
[ :quantity , :integer ],
|
41
|
+
[ :status , :string ],
|
42
|
+
[ :tracking_number , :string ],
|
43
|
+
[ :quantity_shipped , :integer ],
|
44
|
+
[ :unit_price , :numeric ],
|
45
|
+
[ :variant_sku , :string ]
|
46
|
+
],
|
47
|
+
CabooseStore::Order => [
|
48
|
+
[ :email , :string ],
|
49
|
+
[ :order_number , :string ],
|
50
|
+
[ :subtotal , :numeric ],
|
51
|
+
[ :tax , :numeric ],
|
52
|
+
[ :shipping , :numeric ],
|
53
|
+
[ :discount , :numeric ],
|
54
|
+
[ :total , :numeric ],
|
55
|
+
[ :customer_id , :integer ],
|
56
|
+
[ :payment_id , :integer ],
|
57
|
+
[ :gateway_id , :integer ],
|
58
|
+
[ :financial_status , :string ],
|
59
|
+
[ :shipping_address_id , :integer ],
|
60
|
+
[ :billing_address_id , :integer ],
|
61
|
+
[ :notes , :text ],
|
62
|
+
[ :status , :string ],
|
63
|
+
[ :date_created , :datetime ],
|
64
|
+
[ :date_authorized , :datetime ],
|
65
|
+
[ :date_captured , :datetime ],
|
66
|
+
[ :date_cancelled , :datetime ],
|
67
|
+
[ :referring_site , :text ],
|
68
|
+
[ :landing_page , :string ],
|
69
|
+
[ :landing_page_ref , :string ],
|
70
|
+
[ :shipping_method_code , :string ],
|
71
|
+
[ :shipping_method , :string ],
|
72
|
+
[ :handling , :numeric ],
|
73
|
+
[ :transaction_id , :string ],
|
74
|
+
[ :auth_code , :string ],
|
75
|
+
[ :alternate_id , :integer ],
|
76
|
+
[ :auth_amount , :numeric ],
|
77
|
+
[ :date_shipped , :datetime ]
|
78
|
+
],
|
79
|
+
CabooseStore::ProductImage => [
|
80
|
+
[ :product_id , :integer ],
|
81
|
+
[ :title , :string ],
|
82
|
+
[ :image_file_name , :string ],
|
83
|
+
[ :image_content_type , :string ],
|
84
|
+
[ :image_file_size , :integer ],
|
85
|
+
[ :image_updated_at , :datetime ],
|
86
|
+
[ :square_offset_x , :integer ],
|
87
|
+
[ :square_offset_y , :integer ],
|
88
|
+
[ :square_scale_factor , :numeric ]
|
89
|
+
],
|
90
|
+
CabooseStore::ProductImageVariant => [
|
91
|
+
[ :product_image_id , :integer ],
|
92
|
+
[ :variant_id , :integer ]
|
93
|
+
],
|
94
|
+
CabooseStore::Product => [
|
95
|
+
[ :title , :string ],
|
96
|
+
[ :description , :text ],
|
97
|
+
[ :handle , :string ],
|
98
|
+
[ :vendor_id , :integer ],
|
99
|
+
[ :option1 , :string ],
|
100
|
+
[ :option2 , :string ],
|
101
|
+
[ :option3 , :string ],
|
102
|
+
[ :category_id , :integer ],
|
103
|
+
[ :status , :string ],
|
104
|
+
[ :default1 , :string ],
|
105
|
+
[ :default2 , :string ],
|
106
|
+
[ :default3 , :string ],
|
107
|
+
[ :seo_title , :string ],
|
108
|
+
[ :seo_description , :string ],
|
109
|
+
[ :alternate_id , :integer ],
|
110
|
+
[ :date_available , :datetime ]
|
111
|
+
],
|
112
|
+
CabooseStore::Review => [
|
113
|
+
[ :product_id , :integer ],
|
114
|
+
[ :content , :string ],
|
115
|
+
[ :name , :string ],
|
116
|
+
[ :rating , :decimal ]
|
117
|
+
],
|
118
|
+
CabooseStore::Variant => [
|
119
|
+
[ :sku , :string ],
|
120
|
+
[ :barcode , :string ],
|
121
|
+
[ :price , :numeric ],
|
122
|
+
[ :available , :boolean ],
|
123
|
+
[ :quantity_in_stock , :integer ],
|
124
|
+
[ :allow_backorder , :boolean ],
|
125
|
+
[ :weight , :decimal ],
|
126
|
+
[ :length , :decimal ],
|
127
|
+
[ :width , :decimal ],
|
128
|
+
[ :height , :decimal ],
|
129
|
+
[ :cylinder , :boolean ],
|
130
|
+
[ :option1 , :string ],
|
131
|
+
[ :option2 , :string ],
|
132
|
+
[ :option3 , :string ],
|
133
|
+
[ :requires_shipping , :boolean ],
|
134
|
+
[ :taxable , :boolean ],
|
135
|
+
[ :product_id , :integer ],
|
136
|
+
[ :shipping_unit_value , :numeric ],
|
137
|
+
[ :alternate_id , :integer ],
|
138
|
+
[ :status , :string ]
|
139
|
+
],
|
140
|
+
CabooseStore::Vendor => [
|
141
|
+
[ :name , :string ]
|
142
|
+
]
|
143
|
+
}
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'active_shipping'
|
2
|
+
include ActiveMerchant::Shipping
|
3
|
+
|
4
|
+
module CabooseStore
|
5
|
+
class ShippingCalculator
|
6
|
+
|
7
|
+
# Calculates the total cost of shipping
|
8
|
+
# Providers can be ups, fedex, or usps
|
9
|
+
#
|
10
|
+
# padded envelope, 5 lbs, 90210 => $7.62
|
11
|
+
# padded envelope, 20 lbs, 90210 => $13.99
|
12
|
+
# box1 , 20 lbs, 90210 => $20.00
|
13
|
+
# box2 , 30 lbs, 90210 => $25.00
|
14
|
+
def self.rates(order, service_code = nil)
|
15
|
+
|
16
|
+
total = 0.0
|
17
|
+
weight = 0.0
|
18
|
+
order.line_items.each do |li|
|
19
|
+
total = total + (li.variant.shipping_unit_value.nil? ? 0 : li.variant.shipping_unit_value)
|
20
|
+
weight = weight + li.variant.weight
|
21
|
+
end
|
22
|
+
|
23
|
+
length = 0
|
24
|
+
width = 0
|
25
|
+
height = 0
|
26
|
+
|
27
|
+
if total <= 5 # padded envelope
|
28
|
+
length = 15.5
|
29
|
+
width = 9.5
|
30
|
+
height = 6
|
31
|
+
elsif total <= 10 # box1
|
32
|
+
length = 12
|
33
|
+
width = 8
|
34
|
+
height = 5
|
35
|
+
else # box2
|
36
|
+
length = 20
|
37
|
+
width = 16
|
38
|
+
height = 14
|
39
|
+
end
|
40
|
+
|
41
|
+
origin = Location.new(:country => 'US', :state => 'AL', :city => 'Tuscaloosa', :zip => '35405')
|
42
|
+
destination = Location.new(:country => 'US', :state => order.shipping_address.state, :city => order.shipping_address.city, :postal_code => order.shipping_address.zip)
|
43
|
+
packages = [Package.new(weight, [length, width, height], :units => :imperial)]
|
44
|
+
|
45
|
+
ups = UPS.new(
|
46
|
+
:key => '7CBEA07A8AA3279A',
|
47
|
+
:login => 'ABBE FINE',
|
48
|
+
:password => '*TuskWear10*',
|
49
|
+
:origin_account => 'A102Y2'
|
50
|
+
#:login => Tuskwear::Application.config.shipping[:ups][:login],
|
51
|
+
#:password => Tuskwear::Application.config.shipping[:ups][:password],
|
52
|
+
#:key => Tuskwear::Application.config.shipping[:ups][:key]
|
53
|
+
)
|
54
|
+
response = ups.find_rates(origin, destination, packages)
|
55
|
+
|
56
|
+
rates = []
|
57
|
+
response.rates.each do |r|
|
58
|
+
next if r.service_code != '03' && r.service_code !='02'
|
59
|
+
rates << {
|
60
|
+
'service_code' => r.service_code,
|
61
|
+
'service_name' => r.service_name,
|
62
|
+
'total_price' => r.total_price,
|
63
|
+
'negotiated_rate' => r.negotiated_rate # - 300
|
64
|
+
}
|
65
|
+
end
|
66
|
+
return rates
|
67
|
+
end
|
68
|
+
|
69
|
+
# Return the rate for the given service code
|
70
|
+
def self.rate(order, service_code)
|
71
|
+
self.rates(order).each do |r|
|
72
|
+
next if r['service_code'] != service_code
|
73
|
+
return r
|
74
|
+
end
|
75
|
+
return nil
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
|
2
|
+
module CabooseStore
|
3
|
+
class States
|
4
|
+
def States.all
|
5
|
+
return {
|
6
|
+
'AL' => 'Alabama',
|
7
|
+
'AK' => 'Alaska',
|
8
|
+
'AZ' => 'Arizona',
|
9
|
+
'AR' => 'Arkansas',
|
10
|
+
'CA' => 'California',
|
11
|
+
'CO' => 'Colorado',
|
12
|
+
'CT' => 'Connecticut',
|
13
|
+
'DE' => 'Delaware',
|
14
|
+
'DC' => 'District of Columbia',
|
15
|
+
'FL' => 'Florida',
|
16
|
+
'GA' => 'Georgia',
|
17
|
+
'HI' => 'Hawaii',
|
18
|
+
'ID' => 'Idaho',
|
19
|
+
'IL' => 'Illinois',
|
20
|
+
'IN' => 'Indiana',
|
21
|
+
'IA' => 'Iowa',
|
22
|
+
'KS' => 'Kansas',
|
23
|
+
'KY' => 'Kentucky',
|
24
|
+
'LA' => 'Louisiana',
|
25
|
+
'ME' => 'Maine',
|
26
|
+
'MT' => 'Montana',
|
27
|
+
'NE' => 'Nebraska',
|
28
|
+
'NV' => 'Nevada',
|
29
|
+
'NH' => 'New Hampshire',
|
30
|
+
'NJ' => 'New Jersey',
|
31
|
+
'NM' => 'New Mexico',
|
32
|
+
'NY' => 'New York',
|
33
|
+
'NC' => 'North Carolina',
|
34
|
+
'ND' => 'North Dakota',
|
35
|
+
'OH' => 'Ohio',
|
36
|
+
'OK' => 'Oklahoma',
|
37
|
+
'OR' => 'Oregon',
|
38
|
+
'MD' => 'Maryland',
|
39
|
+
'MA' => 'Massachusetts',
|
40
|
+
'MI' => 'Michigan',
|
41
|
+
'MN' => 'Minnesota',
|
42
|
+
'MS' => 'Mississippi',
|
43
|
+
'MO' => 'Missouri',
|
44
|
+
'PA' => 'Pennsylvania',
|
45
|
+
'RI' => 'Rhode Island',
|
46
|
+
'SC' => 'South Carolina',
|
47
|
+
'SD' => 'South Dakota',
|
48
|
+
'TN' => 'Tennessee',
|
49
|
+
'TX' => 'Texas',
|
50
|
+
'UT' => 'Utah',
|
51
|
+
'VT' => 'Vermont',
|
52
|
+
'VA' => 'Virginia',
|
53
|
+
'WA' => 'Washington',
|
54
|
+
'WV' => 'West Virginia',
|
55
|
+
'WI' => 'Wisconsin',
|
56
|
+
'WY' => 'Wyoming'
|
57
|
+
}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
module CabooseStore
|
3
|
+
class TaxCalculator
|
4
|
+
|
5
|
+
# Calculates the total cost of shipping
|
6
|
+
# Providers can be ups, fedex, or usps
|
7
|
+
def self.tax_rate(address)
|
8
|
+
city = address.city.downcase
|
9
|
+
rate = 0.00
|
10
|
+
rate = rate + 0.05 if city == 'brookwood'
|
11
|
+
rate = rate + 0.05 if city == 'coaling'
|
12
|
+
rate = rate + 0.05 if city == 'coker'
|
13
|
+
rate = rate + 0.05 if city == 'holt'
|
14
|
+
rate = rate + 0.05 if city == 'holt CDP'
|
15
|
+
rate = rate + 0.05 if city == 'lake View'
|
16
|
+
rate = rate + 0.05 if city == 'moundville'
|
17
|
+
rate = rate + 0.05 if city == 'northport'
|
18
|
+
rate = rate + 0.05 if city == 'tuscaloosa'
|
19
|
+
rate = rate + 0.05 if city == 'vance'
|
20
|
+
rate = rate + 0.05 if city == 'woodstock'
|
21
|
+
rate = rate + 0.04 if address.state.downcase == 'al' || address.state.downcase == 'alabama'
|
22
|
+
return rate
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
|
2
|
+
module CabooseStore
|
3
|
+
class TaxLine < ActiveRecord::Base
|
4
|
+
|
5
|
+
attr_accessible :id,
|
6
|
+
:title, # The name of the tax, eg. QST or VAT
|
7
|
+
:price, # The amount
|
8
|
+
:rate, # The rate. It will return 0.175 if it is 17.5%
|
9
|
+
:rate_percentage # The tax rate in human readable form. It will return 17.5 if the rate is 0.175
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
module CabooseStore
|
3
|
+
class Variant < ActiveRecord::Base
|
4
|
+
self.table_name = "store_variants"
|
5
|
+
|
6
|
+
belongs_to :product
|
7
|
+
has_many :product_image_variants
|
8
|
+
has_many :product_images, :through => :product_image_variants
|
9
|
+
|
10
|
+
attr_accessible :id, # Variant’s unique id.
|
11
|
+
:product_id,
|
12
|
+
:sku, # The variant's SKU.
|
13
|
+
:barcode, # Returns the barcode value of the variant.
|
14
|
+
:price, # Variant’s price.
|
15
|
+
:quantity_in_stock, # How many of this variants are in stock for this shop.
|
16
|
+
:allow_backorder, # Whether to allow items with no inventory to be added to the cart
|
17
|
+
:status, # Current status: active, inactive, deleted
|
18
|
+
:weight, # The weight of the variant. This will always be in metric grams.
|
19
|
+
:length, # Length of variant in inches
|
20
|
+
:width, # Width of variant in inches
|
21
|
+
:height, # Height of variant in inches
|
22
|
+
:option1, # Returns the value of option1 for given variant
|
23
|
+
:option2, # If a product has a second option defined, then returns the value of this variant's option2.
|
24
|
+
:option3, # If a product has a third option defined, then returns the value of this variant's option3.
|
25
|
+
:requires_shipping, # Returns true if the variant is shippable or false if it is a service or a digital good.
|
26
|
+
:taxable # Returns true if the variant is taxable or false if it is not.
|
27
|
+
|
28
|
+
# Concatenation of all the variant's option values, joined by " / "
|
29
|
+
def title
|
30
|
+
return self.options.join(' / ')
|
31
|
+
end
|
32
|
+
|
33
|
+
def options
|
34
|
+
arr = []
|
35
|
+
arr << self.option1 if self.option1 && self.option1.strip.length > 0
|
36
|
+
arr << self.option2 if self.option2 && self.option2.strip.length > 0
|
37
|
+
arr << self.option3 if self.option3 && self.option3.strip.length > 0
|
38
|
+
return arr
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<li class="thumb">
|
2
|
+
<a href="<%= category.url %>">
|
3
|
+
<figure class="thumb-image" style="background-image: url('https://dmwwflw4i3miv.cloudfront.net/categories/<%= category.id %>_medium.jpg');"></figure>
|
4
|
+
<div class="thumb-title"><%= category.name %></div>
|
5
|
+
</a>
|
6
|
+
</li> <!-- .thumb -->
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<%
|
2
|
+
style = square_image(product.featured_image)
|
3
|
+
arr = product.price_range
|
4
|
+
price = arr[0] == arr[1] ? number_to_currency(arr[0]) : "#{number_to_currency(arr[0])}-#{number_to_currency(arr[1])}"
|
5
|
+
price << " Out of stock" if !product.in_stock
|
6
|
+
%>
|
7
|
+
<li class="thumb">
|
8
|
+
<a href="/products/<%= product.id %>">
|
9
|
+
<figure class="thumb-image" style="<%= style %>"></figure>
|
10
|
+
<div class="thumb-title"><%= product.title %></div>
|
11
|
+
<div class="thumb-price"><%= price %></div>
|
12
|
+
</a>
|
13
|
+
</li> <!-- .thumb -->
|
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
<div id='cart'></div>
|
3
|
+
<%= content_for :caboose_js do %>
|
4
|
+
<%= javascript_include_tag 'cart' %>
|
5
|
+
<script type='text/javascript'>
|
6
|
+
|
7
|
+
var modal = false;
|
8
|
+
$(window).load(function() {
|
9
|
+
var line_items = <%= raw Caboose.json(line_items(@order)) %>;
|
10
|
+
var c = new Cart(line_items);
|
11
|
+
c.print();
|
12
|
+
if (c.line_items.length > 0)
|
13
|
+
modal = new CabooseModal(600);
|
14
|
+
else
|
15
|
+
modal = new CabooseModal(400, 50);
|
16
|
+
});
|
17
|
+
|
18
|
+
</script>
|
19
|
+
<% end %>
|
@@ -0,0 +1,82 @@
|
|
1
|
+
<%
|
2
|
+
cat = @category
|
3
|
+
%>
|
4
|
+
<h1>Edit Category</h1>
|
5
|
+
|
6
|
+
<p><div id='category_<%= cat.id %>_name' ></div></p>
|
7
|
+
<p><div id='category_<%= cat.id %>_slug' ></div></p>
|
8
|
+
<p><div id='category_<%= cat.id %>_square_offset_x' ></div></p>
|
9
|
+
<p><div id='category_<%= cat.id %>_square_offset_y' ></div></p>
|
10
|
+
<p><div id='category_<%= cat.id %>_square_scale_factor' ></div></p>
|
11
|
+
<p><div id='category_<%= cat.id %>_image' ></div></p>
|
12
|
+
|
13
|
+
<h2>Products</h2>
|
14
|
+
<% if cat.products && cat.products.count > 0 %>
|
15
|
+
<ul>
|
16
|
+
<% cat.products.each do |p| %>
|
17
|
+
<li><a href='/admin/products/<%= p.id %>/general'><%= p.title %></a></li>
|
18
|
+
<% end %>
|
19
|
+
</ul>
|
20
|
+
<% else %>
|
21
|
+
<p>This category has no products.</p>
|
22
|
+
<% end %>
|
23
|
+
|
24
|
+
<div id='message'></div>
|
25
|
+
<p>
|
26
|
+
<input type='button' value='< Back' onclick="window.location='/admin/categories';" />
|
27
|
+
<input type='button' value='Delete Category' onclick="delete_category(<%= cat.id %>);" />
|
28
|
+
</p>
|
29
|
+
|
30
|
+
|
31
|
+
<% content_for :caboose_js do %>
|
32
|
+
<%= javascript_include_tag "caboose/model/all" %>
|
33
|
+
<script type='text/javascript'>
|
34
|
+
|
35
|
+
var modal = false;
|
36
|
+
$(window).load(function() {
|
37
|
+
modal = new CabooseModal(800);
|
38
|
+
});
|
39
|
+
|
40
|
+
$(document).ready(function() {
|
41
|
+
m = new ModelBinder({
|
42
|
+
name: 'Category',
|
43
|
+
id: <%= cat.id %>,
|
44
|
+
update_url: '/admin/categories/<%= cat.id %>',
|
45
|
+
authenticity_token: '<%= form_authenticity_token %>',
|
46
|
+
attributes: [
|
47
|
+
{ name: 'name' , nice_name: 'Name' , type: 'text' , value: <%= raw Caboose.json(cat.name ) %>, width: 400 },
|
48
|
+
{ name: 'slug' , nice_name: 'Slug' , type: 'text' , value: <%= raw Caboose.json(cat.slug ) %>, width: 400 },
|
49
|
+
{ name: 'square_offset_x' , nice_name: 'Offset X' , type: 'text' , value: <%= raw Caboose.json(cat.square_offset_x ) %>, width: 200 },
|
50
|
+
{ name: 'square_offset_y' , nice_name: 'Offset Y' , type: 'text' , value: <%= raw Caboose.json(cat.square_offset_y ) %>, width: 200 },
|
51
|
+
{ name: 'square_scale_factor' , nice_name: 'Scale Factor' , type: 'text' , value: <%= raw Caboose.json(cat.square_scale_factor ) %>, width: 200 },
|
52
|
+
{ name: 'image' , nice_name: 'Image' , type: 'image' , value: <%= raw Caboose.json(cat.image.url(:medium) ) %>, width: 200 }
|
53
|
+
]
|
54
|
+
});
|
55
|
+
});
|
56
|
+
|
57
|
+
function delete_category(cat_id, confirm)
|
58
|
+
{
|
59
|
+
if (!confirm)
|
60
|
+
{
|
61
|
+
var p = $('<p/>').addClass('note error').css('margin-bottom', '10px')
|
62
|
+
.append("Are you sure you want to delete the category?<br />This can't be undone.<br /><br />")
|
63
|
+
.append($('<input/>').attr('type', 'button').val('Yes').click(function() { delete_category(cat_id, true); })).append(' ')
|
64
|
+
.append($('<input/>').attr('type', 'button').val('No').click(function() { $('#message').empty(); modal.autosize(); }));
|
65
|
+
modal.autosize(p, 'message');
|
66
|
+
return;
|
67
|
+
}
|
68
|
+
modal.autosize("<p class='loading'>Deleting the category...</p>");
|
69
|
+
$.ajax({
|
70
|
+
url: '/admin/categories/' + cat_id,
|
71
|
+
type: 'delete',
|
72
|
+
success: function(resp) {
|
73
|
+
if (resp.error)
|
74
|
+
modal.autosize("<p class='note error'>" + resp.error + "</p>");
|
75
|
+
if (resp.redirect)
|
76
|
+
window.location = resp.redirect
|
77
|
+
}
|
78
|
+
});
|
79
|
+
}
|
80
|
+
|
81
|
+
</script>
|
82
|
+
<% end %>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<h1>Categories</h1>
|
2
|
+
|
3
|
+
<div id='new_button'><a href='/admin/categories/new'><span>New Category</span></a></div>
|
4
|
+
|
5
|
+
<%= raw categories_tree(@top_category) %>
|
6
|
+
|
7
|
+
<% content_for :caboose_js do %>
|
8
|
+
<script type='text/javascript'>
|
9
|
+
$(document).ready(function() {
|
10
|
+
var modal = new CabooseModal(800);
|
11
|
+
});
|
12
|
+
</script>
|
13
|
+
<% end %>
|
@@ -0,0 +1,45 @@
|
|
1
|
+
<%
|
2
|
+
p = @product
|
3
|
+
%>
|
4
|
+
<h1>New Category</h1>
|
5
|
+
|
6
|
+
<form action='/admin/categories' method='post' id='new_form'>
|
7
|
+
<select name='parent_id'>
|
8
|
+
<option value=''>-- Parent Category --</option>
|
9
|
+
<%= raw categories_options(@top_category) %>
|
10
|
+
</select>
|
11
|
+
<input type='hidden' name='authenticity_token' value="<%= form_authenticity_token %>" />
|
12
|
+
<p><input type='text' name='name' value='' placeholder='Category Name' style='width: 400px;' /></p>
|
13
|
+
<div id='message'></div>
|
14
|
+
<p>
|
15
|
+
<input type='button' value='< Back' onclick="window.location='/admin/categories';" />
|
16
|
+
<input type='submit' value='Add Category' onclick='add_category(); return false' />
|
17
|
+
</p>
|
18
|
+
</form>
|
19
|
+
|
20
|
+
<% content_for :caboose_js do %>
|
21
|
+
<%= javascript_include_tag "caboose/model/all" %>
|
22
|
+
<script type='text/javascript'>
|
23
|
+
|
24
|
+
function add_category()
|
25
|
+
{
|
26
|
+
modal.autosize("<p class='loading'>Adding category...</p>");
|
27
|
+
$.ajax({
|
28
|
+
url: '/admin/categories',
|
29
|
+
type: 'post',
|
30
|
+
data: $('#new_form').serialize(),
|
31
|
+
success: function(resp) {
|
32
|
+
if (resp.error)
|
33
|
+
modal.autosize("<p class='note error'>" + resp.error + "</p>");
|
34
|
+
if (resp.redirect)
|
35
|
+
window.location = resp.redirect
|
36
|
+
}
|
37
|
+
});
|
38
|
+
}
|
39
|
+
|
40
|
+
var modal = false;
|
41
|
+
$(window).load(function() {
|
42
|
+
modal = new CabooseModal(800);
|
43
|
+
});
|
44
|
+
</script>
|
45
|
+
<% end %>
|