shoppe 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|