shoppe 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/Rakefile +18 -0
- data/app/assets/images/shoppe/document.svg +1 -0
- data/app/assets/images/shoppe/logo.svg +47 -0
- data/app/assets/images/shoppe/shoppe.svg +25 -0
- data/app/assets/images/shoppe/square.svg +9 -0
- data/app/assets/images/shoppe/statuses/accepted.svg +14 -0
- data/app/assets/images/shoppe/statuses/paid.svg +16 -0
- data/app/assets/images/shoppe/statuses/received.svg +15 -0
- data/app/assets/images/shoppe/statuses/rejected.svg +14 -0
- data/app/assets/images/shoppe/statuses/shipped.svg +14 -0
- data/app/assets/javascripts/shoppe/application.coffee +11 -0
- data/app/assets/stylesheets/shoppe/application.scss +302 -0
- data/app/assets/stylesheets/shoppe/elements.scss +73 -0
- data/app/assets/stylesheets/shoppe/reset.scss +93 -0
- data/app/assets/stylesheets/shoppe/sub.scss +90 -0
- data/app/assets/stylesheets/shoppe/variables.scss +1 -0
- data/app/controllers/shoppe/application_controller.rb +39 -0
- data/app/controllers/shoppe/attachments_controller.rb +12 -0
- data/app/controllers/shoppe/dashboard_controller.rb +7 -0
- data/app/controllers/shoppe/delivery_service_prices_controller.rb +42 -0
- data/app/controllers/shoppe/delivery_services_controller.rb +45 -0
- data/app/controllers/shoppe/orders_controller.rb +36 -0
- data/app/controllers/shoppe/product_categories_controller.rb +45 -0
- data/app/controllers/shoppe/products_controller.rb +45 -0
- data/app/controllers/shoppe/sessions_controller.rb +31 -0
- data/app/controllers/shoppe/users_controller.rb +46 -0
- data/app/helpers/shoppe/application_helper.rb +10 -0
- data/app/helpers/shoppe/shoppe_helper.rb +28 -0
- data/app/mailers/shoppe/order_mailer.rb +25 -0
- data/app/mailers/shoppe/user_mailer.rb +10 -0
- data/app/models/shoppe/delivery_service.rb +22 -0
- data/app/models/shoppe/delivery_service_price.rb +19 -0
- data/app/models/shoppe/order.rb +325 -0
- data/app/models/shoppe/order_item.rb +113 -0
- data/app/models/shoppe/product.rb +56 -0
- data/app/models/shoppe/product_category.rb +22 -0
- data/app/models/shoppe/user.rb +41 -0
- data/app/views/layouts/shoppe/application.html.haml +35 -0
- data/app/views/layouts/shoppe/sub.html.haml +10 -0
- data/app/views/shoppe/delivery_service_prices/_form.html.haml +28 -0
- data/app/views/shoppe/delivery_service_prices/edit.html.haml +5 -0
- data/app/views/shoppe/delivery_service_prices/index.html.haml +22 -0
- data/app/views/shoppe/delivery_service_prices/new.html.haml +5 -0
- data/app/views/shoppe/delivery_services/_form.html.haml +35 -0
- data/app/views/shoppe/delivery_services/edit.html.haml +5 -0
- data/app/views/shoppe/delivery_services/index.html.haml +24 -0
- data/app/views/shoppe/delivery_services/new.html.haml +5 -0
- data/app/views/shoppe/order_mailer/accepted.text.erb +12 -0
- data/app/views/shoppe/order_mailer/received.text.erb +12 -0
- data/app/views/shoppe/order_mailer/rejected.text.erb +10 -0
- data/app/views/shoppe/order_mailer/shipped.text.erb +16 -0
- data/app/views/shoppe/orders/index.html.haml +60 -0
- data/app/views/shoppe/orders/show.html.haml +117 -0
- data/app/views/shoppe/product_categories/_form.html.haml +25 -0
- data/app/views/shoppe/product_categories/edit.html.haml +6 -0
- data/app/views/shoppe/product_categories/index.html.haml +15 -0
- data/app/views/shoppe/product_categories/new.html.haml +5 -0
- data/app/views/shoppe/products/_form.html.haml +71 -0
- data/app/views/shoppe/products/edit.html.haml +5 -0
- data/app/views/shoppe/products/index.html.haml +27 -0
- data/app/views/shoppe/products/new.html.haml +5 -0
- data/app/views/shoppe/sessions/new.html.haml +12 -0
- data/app/views/shoppe/sessions/reset.html.haml +11 -0
- data/app/views/shoppe/user_mailer/new_password.text.erb +9 -0
- data/app/views/shoppe/users/_form.html.haml +26 -0
- data/app/views/shoppe/users/edit.html.haml +5 -0
- data/app/views/shoppe/users/index.html.haml +17 -0
- data/app/views/shoppe/users/new.html.haml +5 -0
- data/config/routes.rb +24 -0
- data/config/shoppe.example.yml +6 -0
- data/db/migrate/20130926094549_create_shoppe_initial_schema.rb +116 -0
- data/db/seeds.rb +85 -0
- data/db/seeds_data/poe400.jpg +0 -0
- data/db/seeds_data/snom-870-blk.jpg +0 -0
- data/db/seeds_data/snom-870-grey.jpg +0 -0
- data/db/seeds_data/snom-mm2.jpg +0 -0
- data/db/seeds_data/spa303.jpg +0 -0
- data/db/seeds_data/t18p.jpg +0 -0
- data/db/seeds_data/t20p.jpg +0 -0
- data/db/seeds_data/t22p.jpg +0 -0
- data/db/seeds_data/t26p.jpg +0 -0
- data/db/seeds_data/t41pn.jpg +0 -0
- data/db/seeds_data/t46gn.jpg +0 -0
- data/db/seeds_data/w52p.jpg +0 -0
- data/db/seeds_data/yhs32.jpg +0 -0
- data/lib/shoppe.rb +41 -0
- data/lib/shoppe/engine.rb +35 -0
- data/lib/shoppe/errors/inappropriate_delivery_service.rb +11 -0
- data/lib/shoppe/errors/insufficient_stock_to_fulfil.rb +19 -0
- data/lib/shoppe/errors/not_enough_stock.rb +19 -0
- data/lib/shoppe/errors/payment_declined.rb +15 -0
- data/lib/shoppe/setup_generator.rb +14 -0
- data/lib/shoppe/version.rb +3 -0
- data/lib/tasks/shoppe.rake +17 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -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/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +23 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +29 -0
- data/test/dummy/config/environments/production.rb +80 -0
- data/test/dummy/config/environments/test.rb +36 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +12 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +3 -0
- data/test/dummy/config/shoppe.yml +7 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/schema.rb +119 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +893 -0
- data/test/dummy/log/test.log +6397 -0
- data/test/dummy/public/404.html +58 -0
- data/test/dummy/public/422.html +58 -0
- data/test/dummy/public/500.html +57 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/models/shoppe/basket_test.rb +26 -0
- data/test/models/shoppe/user_test.rb +37 -0
- data/test/shoppe_test.rb +17 -0
- data/test/test_helper.rb +4 -0
- metadata +453 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
- @page_title = "Users"
|
2
|
+
|
3
|
+
= content_for :header do
|
4
|
+
%p.buttons=link_to "New user", :new_user, :class => 'button green'
|
5
|
+
%h2 Users
|
6
|
+
|
7
|
+
.table
|
8
|
+
%table.data
|
9
|
+
%thead
|
10
|
+
%tr
|
11
|
+
%th Name
|
12
|
+
%th E-Mail Address
|
13
|
+
%tbody
|
14
|
+
- for user in @users
|
15
|
+
%tr
|
16
|
+
%td= link_to user.full_name, [:edit, user]
|
17
|
+
%td= user.email_address
|
data/config/routes.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
Shoppe::Engine.routes.draw do
|
2
|
+
|
3
|
+
get 'attachment/:id/:filename.:extension' => 'attachments#show'
|
4
|
+
resources :product_categories
|
5
|
+
resources :products
|
6
|
+
resources :orders do
|
7
|
+
post :search, :on => :collection
|
8
|
+
post :accept, :on => :member
|
9
|
+
post :reject, :on => :member
|
10
|
+
post :ship, :on => :member
|
11
|
+
post :pay, :on => :member
|
12
|
+
end
|
13
|
+
resources :delivery_services do
|
14
|
+
resources :delivery_service_prices
|
15
|
+
end
|
16
|
+
resources :users
|
17
|
+
resources :attachments, :only => :destroy
|
18
|
+
get 'login' => 'sessions#new'
|
19
|
+
post 'login' => 'sessions#create'
|
20
|
+
match 'login/reset' => 'sessions#reset', :via => [:get, :post]
|
21
|
+
|
22
|
+
delete 'logout' => 'sessions#destroy'
|
23
|
+
root :to => 'dashboard#home'
|
24
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
class CreateShoppeInitialSchema < ActiveRecord::Migration
|
2
|
+
def up
|
3
|
+
create_table "shoppe_delivery_service_prices", force: true do |t|
|
4
|
+
t.integer "delivery_service_id"
|
5
|
+
t.string "code"
|
6
|
+
t.decimal "price", precision: 8, scale: 2
|
7
|
+
t.decimal "tax_rate", precision: 8, scale: 2
|
8
|
+
t.decimal "min_weight", precision: 8, scale: 2
|
9
|
+
t.decimal "max_weight", precision: 8, scale: 2
|
10
|
+
t.datetime "created_at"
|
11
|
+
t.datetime "updated_at"
|
12
|
+
end
|
13
|
+
|
14
|
+
create_table "shoppe_delivery_services", force: true do |t|
|
15
|
+
t.string "name"
|
16
|
+
t.string "code"
|
17
|
+
t.boolean "default", default: false
|
18
|
+
t.boolean "active", default: true
|
19
|
+
t.datetime "created_at"
|
20
|
+
t.datetime "updated_at"
|
21
|
+
t.string "courier"
|
22
|
+
t.string "tracking_url"
|
23
|
+
end
|
24
|
+
|
25
|
+
create_table "shoppe_order_items", force: true do |t|
|
26
|
+
t.integer "order_id"
|
27
|
+
t.integer "product_id"
|
28
|
+
t.integer "quantity", default: 1
|
29
|
+
t.decimal "unit_price", precision: 8, scale: 2
|
30
|
+
t.decimal "tax_amount", precision: 8, scale: 2
|
31
|
+
t.decimal "tax_rate", precision: 8, scale: 2
|
32
|
+
t.decimal "weight", precision: 8, scale: 3, default: 0.0
|
33
|
+
t.datetime "created_at"
|
34
|
+
t.datetime "updated_at"
|
35
|
+
end
|
36
|
+
|
37
|
+
create_table "shoppe_orders", force: true do |t|
|
38
|
+
t.string "token"
|
39
|
+
t.string "first_name"
|
40
|
+
t.string "last_name"
|
41
|
+
t.string "company"
|
42
|
+
t.string "address1"
|
43
|
+
t.string "address2"
|
44
|
+
t.string "address3"
|
45
|
+
t.string "address4"
|
46
|
+
t.string "postcode"
|
47
|
+
t.string "email_address"
|
48
|
+
t.string "phone_number"
|
49
|
+
t.string "status"
|
50
|
+
t.datetime "received_at"
|
51
|
+
t.datetime "accepted_at"
|
52
|
+
t.datetime "shipped_at"
|
53
|
+
t.datetime "created_at"
|
54
|
+
t.datetime "updated_at"
|
55
|
+
t.integer "delivery_service_id"
|
56
|
+
t.decimal "delivery_price", precision: 8, scale: 2
|
57
|
+
t.decimal "delivery_tax_rate", precision: 8, scale: 2
|
58
|
+
t.decimal "delivery_tax_amount", precision: 8, scale: 2
|
59
|
+
t.datetime "paid_at"
|
60
|
+
t.integer "accepted_by"
|
61
|
+
t.integer "shipped_by"
|
62
|
+
t.string "consignment_number"
|
63
|
+
t.datetime "rejected_at"
|
64
|
+
t.integer "rejected_by"
|
65
|
+
t.string "ip_address"
|
66
|
+
t.string "country"
|
67
|
+
t.string "payment_reference"
|
68
|
+
t.string "payment_method"
|
69
|
+
end
|
70
|
+
|
71
|
+
create_table "shoppe_product_categories", force: true do |t|
|
72
|
+
t.string "name"
|
73
|
+
t.string "permalink"
|
74
|
+
t.text "description"
|
75
|
+
t.datetime "created_at"
|
76
|
+
t.datetime "updated_at"
|
77
|
+
end
|
78
|
+
|
79
|
+
create_table "shoppe_products", force: true do |t|
|
80
|
+
t.integer "product_category_id"
|
81
|
+
t.string "title"
|
82
|
+
t.string "sku"
|
83
|
+
t.string "permalink"
|
84
|
+
t.text "description"
|
85
|
+
t.text "short_description"
|
86
|
+
t.boolean "active", default: true
|
87
|
+
t.decimal "weight", precision: 8, scale: 3, default: 0.0
|
88
|
+
t.decimal "price", precision: 8, scale: 2, default: 0.0
|
89
|
+
t.decimal "tax_rate", precision: 8, scale: 2, default: 0.0
|
90
|
+
t.integer "stock", default: 0
|
91
|
+
t.datetime "created_at"
|
92
|
+
t.datetime "updated_at"
|
93
|
+
t.boolean "featured", default: false
|
94
|
+
t.text "in_the_box"
|
95
|
+
end
|
96
|
+
|
97
|
+
create_table "shoppe_users", force: true do |t|
|
98
|
+
t.string "first_name"
|
99
|
+
t.string "last_name"
|
100
|
+
t.string "email_address"
|
101
|
+
t.string "password_digest"
|
102
|
+
t.datetime "created_at"
|
103
|
+
t.datetime "updated_at"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def down
|
108
|
+
drop_table :shoppe_delivery_service_prices
|
109
|
+
drop_table :shoppe_delivery_services
|
110
|
+
drop_table :shoppe_order_items
|
111
|
+
drop_table :shoppe_orders
|
112
|
+
drop_table :shoppe_product_categories
|
113
|
+
drop_table :shoppe_products
|
114
|
+
drop_table :shoppe_users
|
115
|
+
end
|
116
|
+
end
|
data/db/seeds.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# delivery services
|
4
|
+
|
5
|
+
ds = Shoppe::DeliveryService.create!(:name => "Royal Mail (1st class)", :code => 'RMFC', :courier => 'Royal Mail', :tracking_url => 'http://royalmail.com/track/{{consignment_number}}')
|
6
|
+
ds.delivery_service_prices.create!(:min_weight => 0, :max_weight => 0.050, :price => 0.60, :tax_rate => 0.0)
|
7
|
+
|
8
|
+
|
9
|
+
ds = Shoppe::DeliveryService.create!(:name => "Royal Mail (signed for)", :code => 'RMSF', :courier => 'Royal Mail', :tracking_url => 'http://royalmail.com/track/{{consignment_number}}')
|
10
|
+
ds.delivery_service_prices.create!(:min_weight => 0, :max_weight => 1, :price => 5.0, :tax_rate => 20.0)
|
11
|
+
ds.delivery_service_prices.create!(:min_weight => 1, :max_weight => 5, :price => 8.0, :tax_rate => 20.0)
|
12
|
+
ds.delivery_service_prices.create!(:min_weight => 5, :max_weight => 10, :price => 10.0, :tax_rate => 20.0)
|
13
|
+
ds.delivery_service_prices.create!(:min_weight => 10, :max_weight => 25, :price => 12.0, :tax_rate => 20.0)
|
14
|
+
ds.delivery_service_prices.create!(:min_weight => 25, :max_weight => 50, :price => 16.25, :tax_rate => 20.0)
|
15
|
+
|
16
|
+
ds = Shoppe::DeliveryService.create!(:name => "Next Day Delivery (before 4pm)", :default => true, :code => 'ND16', :courier => 'UPS', :tracking_url => 'http://trackingurl.com/track/{{consignment_number}}')
|
17
|
+
ds.delivery_service_prices.create!(:min_weight => 0, :max_weight => 1, :price => 7.0, :tax_rate => 20.0)
|
18
|
+
ds.delivery_service_prices.create!(:min_weight => 1, :max_weight => 5, :price => 9.0, :tax_rate => 20.0)
|
19
|
+
ds.delivery_service_prices.create!(:min_weight => 5, :max_weight => 20, :price => 11.50, :tax_rate => 20.0)
|
20
|
+
|
21
|
+
ds = Shoppe::DeliveryService.create!(:name => "Next Day Delivery (before 10am)", :code => 'NS10', :courier => 'UPS', :tracking_url => 'http://trackingurl.com/track/{{consignment_number}}')
|
22
|
+
ds.delivery_service_prices.create!(:min_weight => 0, :max_weight => 1, :price => 17.0, :tax_rate => 20.0)
|
23
|
+
ds.delivery_service_prices.create!(:min_weight => 1, :max_weight => 5, :price => 19.0, :tax_rate => 20.0)
|
24
|
+
ds.delivery_service_prices.create!(:min_weight => 5, :max_weight => 20, :price => 27.0, :tax_rate => 20.0)
|
25
|
+
|
26
|
+
ds = Shoppe::DeliveryService.create!(:name => "Saturday Delivery", :code => 'NDSA16', :courier => 'UPS', :tracking_url => 'http://trackingurl.com/track/{{consignment_number}}')
|
27
|
+
ds.delivery_service_prices.create!(:min_weight => 0, :max_weight => 1, :price => 27.0, :tax_rate => 20.0)
|
28
|
+
ds.delivery_service_prices.create!(:min_weight => 1, :max_weight => 5, :price => 29.0, :tax_rate => 20.0)
|
29
|
+
ds.delivery_service_prices.create!(:min_weight => 5, :max_weight => 20, :price => 37.0, :tax_rate => 20.0)
|
30
|
+
|
31
|
+
# categories
|
32
|
+
cat1 = Shoppe::ProductCategory.create!(:name => 'VoIP Phones')
|
33
|
+
cat2 = Shoppe::ProductCategory.create!(:name => 'VoIP Accessories')
|
34
|
+
cat3 = Shoppe::ProductCategory.create!(:name => 'Network Eqipment')
|
35
|
+
|
36
|
+
def get_file(name, content_type = 'image/jpeg')
|
37
|
+
file = ActionDispatch::Http::UploadedFile.new(:tempfile => File.open(File.join(Shoppe.root, 'db', 'seeds_data', name), 'rb'))
|
38
|
+
file.original_filename = name
|
39
|
+
file.content_type = content_type
|
40
|
+
file
|
41
|
+
end
|
42
|
+
|
43
|
+
lorem = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
|
44
|
+
|
45
|
+
pro = cat1.products.create!(:title => 'Yealink T20P', :sku => 'YL-SIP-T20P', :description => lorem, :short_description => 'If cheap & cheerful is what you’re after, the Yealink T20P is what you’re looking for.', :weight => 1.119, :price => 54.99, :tax_rate => 20.0, :stock => 20, :featured => true)
|
46
|
+
pro.default_image_file = get_file('t20p.jpg')
|
47
|
+
pro.save!
|
48
|
+
|
49
|
+
pro = cat1.products.create!(:title => 'Yealink T22P', :sku => 'YL-SIP-T22P', :description => lorem, :short_description => lorem, :weight => 1.419, :price => 64.99, :tax_rate => 20.0, :stock => 12)
|
50
|
+
pro.default_image_file = get_file('t22p.jpg')
|
51
|
+
pro.save!
|
52
|
+
|
53
|
+
pro = cat1.products.create!(:title => 'Yealink T26P', :sku => 'YL-SIP-T26P', :description => lorem, :short_description => lorem, :weight => 2.23, :price => 88.99, :tax_rate => 20.0, :stock => 5)
|
54
|
+
pro.default_image_file = get_file('t26p.jpg')
|
55
|
+
pro.save!
|
56
|
+
|
57
|
+
pro = cat1.products.create!(:title => 'Yealink T46GN', :sku => 'YL-SIP-T46GN', :description => lorem, :short_description => 'Colourful, sharp, fast & down right sexy. The Yealink T46P will make your scream!', :weight => 2.23, :price => 149.99, :tax_rate => 20.0, :stock => 5, :featured => true)
|
58
|
+
pro.default_image_file = get_file('t46gn.jpg')
|
59
|
+
pro.save!
|
60
|
+
|
61
|
+
pro = cat1.products.create!(:title => 'Snom 870 (Grey)', :sku => 'SM-870-GREY', :description => lorem, :short_description => 'The perfect & beautiful VoIP phone for the discerning professional desk.', :weight => 2.4, :price => 235.00, :tax_rate => 20.0, :stock => 2)
|
62
|
+
pro.default_image_file = get_file('snom-870-grey.jpg')
|
63
|
+
pro.save!
|
64
|
+
|
65
|
+
pro = cat1.products.create!(:title => 'Snom 870 (Black)', :sku => 'SM-870-BLK', :description => lorem, :short_description => 'The perfect & beautiful VoIP phone for the discerning professional desk.', :weight => 2.4, :price => 235.00, :tax_rate => 20.0, :stock => 0, :featured => true)
|
66
|
+
pro.default_image_file = get_file('snom-870-blk.jpg')
|
67
|
+
pro.save!
|
68
|
+
|
69
|
+
pro = cat2.products.create!(:title => 'Yealink Mono Headset', :sku => 'YL-YHS32', :description => lorem, :short_description => 'If you\'re often on the phone, this headset will make your life 100x easier. Guaranteed*.', :weight => 0.890, :price => 34.99, :tax_rate => 20.0, :stock => 3, :featured => true)
|
70
|
+
pro.default_image_file = get_file('yhs32.jpg')
|
71
|
+
pro.save!
|
72
|
+
|
73
|
+
pro = cat2.products.create!(:title => 'Snom Wired Headset (MM2)', :sku => 'SM-MM2', :description => lorem, :short_description => lorem, :weight => 0.780, :price => 38.00, :tax_rate => 20.0, :stock => 0)
|
74
|
+
pro.default_image_file = get_file('snom-mm2.jpg')
|
75
|
+
pro.save!
|
76
|
+
|
77
|
+
pro = cat2.products.create!(:title => 'Snom Wired Headset (MM3)', :sku => 'SM-MM3', :description => lorem, :short_description => lorem, :weight => 0.780, :price => 38.00, :tax_rate => 20.0, :stock => 1)
|
78
|
+
pro.default_image_file = get_file('snom-mm2.jpg')
|
79
|
+
pro.save!
|
80
|
+
|
81
|
+
pro = cat1.products.create!(:title => 'Yealink W52P', :sku => 'TL-SIP-W52P', :description => lorem, :short_description => 'Wireless SIP phones are hard to come by but this beauty from Yealink is fab.', :weight => 1.280, :price => 99.99, :tax_rate => 20.0, :stock => 1, :featured => true)
|
82
|
+
pro.default_image_file = get_file('w52p.jpg')
|
83
|
+
pro.save!
|
84
|
+
|
85
|
+
user = Shoppe::User.create!(:first_name => 'Adam', :last_name => 'Cooke', :email_address => 'adam@niftyware.io', :password => 'llamafarm', :password_confirmation => 'llamafarm')
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/lib/shoppe.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'haml'
|
2
|
+
require 'bcrypt'
|
3
|
+
require 'dynamic_form'
|
4
|
+
require 'kaminari'
|
5
|
+
require 'ransack'
|
6
|
+
require 'nifty/utils'
|
7
|
+
require 'nifty/key_value_store'
|
8
|
+
require 'nifty/attachments'
|
9
|
+
|
10
|
+
module Shoppe
|
11
|
+
|
12
|
+
class Error < StandardError; end
|
13
|
+
|
14
|
+
class << self
|
15
|
+
def root
|
16
|
+
File.expand_path('../../', __FILE__)
|
17
|
+
end
|
18
|
+
|
19
|
+
def config
|
20
|
+
@config ||= begin
|
21
|
+
path = Rails.root.join('config', 'shoppe.yml')
|
22
|
+
if File.exist?(path)
|
23
|
+
config = YAML.load_file(path).with_indifferent_access
|
24
|
+
setup_config(config)
|
25
|
+
config
|
26
|
+
else
|
27
|
+
$stderr.puts "Shoppe configuration file missing at #{path}"
|
28
|
+
{}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def setup_config(config)
|
34
|
+
ActionMailer::Base.smtp_settings = config[:smtp_settings] if config[:smtp_settings]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
# Start your engines.
|
41
|
+
require "shoppe/engine"
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Shoppe
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
isolate_namespace Shoppe
|
4
|
+
|
5
|
+
if Shoppe.respond_to?(:root)
|
6
|
+
config.autoload_paths << File.join(Shoppe.root, 'lib')
|
7
|
+
end
|
8
|
+
|
9
|
+
# We don't want any automatic generators in the engine.
|
10
|
+
config.generators do |g|
|
11
|
+
g.orm :active_record
|
12
|
+
g.test_framework false
|
13
|
+
g.stylesheets false
|
14
|
+
g.javascripts false
|
15
|
+
g.helper false
|
16
|
+
end
|
17
|
+
|
18
|
+
initializer 'shoppe.initialize' do |app|
|
19
|
+
# Preload the config
|
20
|
+
Shoppe.config
|
21
|
+
|
22
|
+
# Load our migrations into the application's db/migrate path
|
23
|
+
unless app.root.to_s.match root.to_s
|
24
|
+
config.paths["db/migrate"].expanded.each do |expanded_path|
|
25
|
+
app.config.paths["db/migrate"] << expanded_path
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
generators do
|
31
|
+
require 'shoppe/setup_generator'
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Shoppe
|
2
|
+
module Errors
|
3
|
+
class InsufficientStockToFulfil < Error
|
4
|
+
|
5
|
+
def initialize(options)
|
6
|
+
@options = options
|
7
|
+
end
|
8
|
+
|
9
|
+
def order
|
10
|
+
@options[:order]
|
11
|
+
end
|
12
|
+
|
13
|
+
def out_of_stock_items
|
14
|
+
@options[:out_of_stock_items]
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Shoppe
|
2
|
+
module Errors
|
3
|
+
class NotEnoughStock < Error
|
4
|
+
|
5
|
+
def initialize(options)
|
6
|
+
@options = options
|
7
|
+
end
|
8
|
+
|
9
|
+
def available_stock
|
10
|
+
@options[:product].stock
|
11
|
+
end
|
12
|
+
|
13
|
+
def requested_stock
|
14
|
+
@options[:requested_stock]
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
module Shoppe
|
3
|
+
class SetupGenerator < Rails::Generators::Base
|
4
|
+
|
5
|
+
def create_route
|
6
|
+
route 'mount Shoppe::Engine => "/shoppe"'
|
7
|
+
end
|
8
|
+
|
9
|
+
def create_config_file
|
10
|
+
create_file "config/shoppe.yml", File.read(File.join(Shoppe.root, 'config', 'shoppe.example.yml'))
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|