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,113 @@
|
|
|
1
|
+
class Shoppe::OrderItem < ActiveRecord::Base
|
|
2
|
+
|
|
3
|
+
# Set the table name
|
|
4
|
+
self.table_name = 'shoppe_order_items'
|
|
5
|
+
|
|
6
|
+
# Relationships
|
|
7
|
+
belongs_to :order, :class_name => 'Shoppe::Order'
|
|
8
|
+
belongs_to :product, :class_name => 'Shoppe::Product'
|
|
9
|
+
|
|
10
|
+
# Validations
|
|
11
|
+
validates :quantity, :numericality => true
|
|
12
|
+
|
|
13
|
+
# Set some values based on the selected product on validation
|
|
14
|
+
before_validation do
|
|
15
|
+
if self.product
|
|
16
|
+
self.unit_price = self.product.price if self.unit_price.blank?
|
|
17
|
+
self.tax_rate = self.product.tax_rate if self.tax_rate.blank?
|
|
18
|
+
if unit_price_changed? || quantity_changed?
|
|
19
|
+
self.tax_amount = (self.sub_total / BigDecimal(100)) * self.tax_rate
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
if product_id_changed? || quantity_changed?
|
|
23
|
+
self.weight = self.quantity * self.product.weight
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# This allows you to add a product to the scoped order. For example Order.first.order_items.add_product(...).
|
|
29
|
+
# This will either increase the quantity of the value in the order or create a new item if one does not
|
|
30
|
+
# exist already.
|
|
31
|
+
def self.add_product(product, quantity = 1)
|
|
32
|
+
transaction do
|
|
33
|
+
if existing = self.where(:product_id => product.id).first
|
|
34
|
+
existing.increase!(quantity)
|
|
35
|
+
existing
|
|
36
|
+
else
|
|
37
|
+
item = self.create(:product => product, :quantity => 0)
|
|
38
|
+
item.increase!(quantity)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# This allows you to remove a product from an order. It will also ensure that the order's
|
|
44
|
+
# custom delivery service is updated.
|
|
45
|
+
def remove
|
|
46
|
+
transaction do
|
|
47
|
+
self.destroy!
|
|
48
|
+
self.order.remove_delivery_service_if_invalid
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# Increase the quantity of items in the order by the number provided. Will raise an error if we don't have
|
|
54
|
+
# the stock to do this.
|
|
55
|
+
def increase!(amount = 1)
|
|
56
|
+
transaction do
|
|
57
|
+
self.quantity += amount
|
|
58
|
+
if self.product.stock < self.quantity
|
|
59
|
+
raise Shoppe::Errors::NotEnoughStock, :product => self.product, :requested_stock => self.quantity
|
|
60
|
+
end
|
|
61
|
+
self.save!
|
|
62
|
+
self.order.remove_delivery_service_if_invalid
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Decreases the quantity of items in the order by the number provided.
|
|
67
|
+
def decrease!(amount = 1)
|
|
68
|
+
transaction do
|
|
69
|
+
self.quantity -= amount
|
|
70
|
+
self.quantity == 0 ? self.destroy : self.save!
|
|
71
|
+
self.order.remove_delivery_service_if_invalid
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Return the sub total for the product
|
|
76
|
+
def sub_total
|
|
77
|
+
quantity * unit_price
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Return the total price including tax for the order line
|
|
81
|
+
def total
|
|
82
|
+
tax_amount + sub_total
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# This method will be triggered when the parent order is confirmed. This should automatically
|
|
86
|
+
# update the stock levels on the source product.
|
|
87
|
+
def confirm!
|
|
88
|
+
self.product.update_stock_level(quantity)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Do we have the stock needed to fulfil this order?
|
|
92
|
+
def in_stock?
|
|
93
|
+
if self.product.respond_to?(:stock)
|
|
94
|
+
self.product.stock >= self.quantity
|
|
95
|
+
else
|
|
96
|
+
true
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Validate the stock level against the product and update as appropriate. This method will be executed
|
|
101
|
+
# before an order is completed. If we have run out of this product, we will update the quantity to an
|
|
102
|
+
# appropriate level (or remove the order item) and return the object.
|
|
103
|
+
def validate_stock_levels
|
|
104
|
+
unless in_stock?
|
|
105
|
+
self.quantity = self.product.stock
|
|
106
|
+
self.quantity == 0 ? self.destroy : self.save!
|
|
107
|
+
self
|
|
108
|
+
else
|
|
109
|
+
false
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
class Shoppe::Product < ActiveRecord::Base
|
|
2
|
+
|
|
3
|
+
# Set the table name
|
|
4
|
+
self.table_name = 'shoppe_products'
|
|
5
|
+
|
|
6
|
+
# Attachments
|
|
7
|
+
attachment :default_image
|
|
8
|
+
attachment :data_sheet
|
|
9
|
+
|
|
10
|
+
# Relationships
|
|
11
|
+
belongs_to :product_category, :class_name => 'Shoppe::ProductCategory'
|
|
12
|
+
has_many :order_items, :dependent => :restrict_with_exception, :class_name => 'Shoppe::OrderItem'
|
|
13
|
+
has_many :orders, :through => :order_items, :class_name => 'Shoppe::Order'
|
|
14
|
+
|
|
15
|
+
# Validations
|
|
16
|
+
validates :product_category_id, :presence => true
|
|
17
|
+
validates :title, :presence => true
|
|
18
|
+
validates :permalink, :presence => true, :uniqueness => true
|
|
19
|
+
validates :sku, :presence => true
|
|
20
|
+
validates :description, :presence => true
|
|
21
|
+
validates :short_description, :presence => true
|
|
22
|
+
validates :weight, :numericality => true
|
|
23
|
+
validates :price, :numericality => true
|
|
24
|
+
validates :tax_rate, :numericality => true
|
|
25
|
+
validates :stock, :numericality => {:only_integer => true}
|
|
26
|
+
|
|
27
|
+
# Set the permalink
|
|
28
|
+
before_validation { self.permalink = self.title.parameterize if self.permalink.blank? && self.title.is_a?(String) }
|
|
29
|
+
|
|
30
|
+
# Scopes
|
|
31
|
+
scope :active, -> { where(:active => true) }
|
|
32
|
+
scope :featured, -> {where(:featured => true)}
|
|
33
|
+
|
|
34
|
+
# Is this product currently in stock?
|
|
35
|
+
def in_stock?
|
|
36
|
+
stock > 0
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Remove the provided number of units from the current stock level of this product
|
|
40
|
+
def update_stock_level(purchased = 1)
|
|
41
|
+
self.stock -= purchased
|
|
42
|
+
self.save!
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Specify which attributes can be searched
|
|
46
|
+
def self.ransackable_attributes(auth_object = nil)
|
|
47
|
+
["id", "title", "sku"] + _ransackers.keys
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Specify which associations can be searched
|
|
51
|
+
def self.ransackable_associations(auth_object = nil)
|
|
52
|
+
[]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
class Shoppe::ProductCategory < ActiveRecord::Base
|
|
2
|
+
|
|
3
|
+
# Set the table name
|
|
4
|
+
self.table_name = 'shoppe_product_categories'
|
|
5
|
+
|
|
6
|
+
# Attachments
|
|
7
|
+
attachment :image
|
|
8
|
+
|
|
9
|
+
# Relationships
|
|
10
|
+
has_many :products, :dependent => :restrict_with_exception, :class_name => 'Shoppe::Product'
|
|
11
|
+
|
|
12
|
+
# Validations
|
|
13
|
+
validates :name, :presence => true
|
|
14
|
+
validates :permalink, :presence => true, :uniqueness => true
|
|
15
|
+
|
|
16
|
+
# Scopes
|
|
17
|
+
scope :ordered, -> { order(:name) }
|
|
18
|
+
|
|
19
|
+
# Set the permalink
|
|
20
|
+
before_validation { self.permalink = self.name.parameterize if self.permalink.blank? && self.name.is_a?(String) }
|
|
21
|
+
|
|
22
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
class Shoppe::User < ActiveRecord::Base
|
|
2
|
+
|
|
3
|
+
# Set the table name
|
|
4
|
+
self.table_name = 'shoppe_users'
|
|
5
|
+
|
|
6
|
+
# Self explanatory I think!
|
|
7
|
+
has_secure_password
|
|
8
|
+
|
|
9
|
+
# Validations
|
|
10
|
+
validates :first_name, :presence => true
|
|
11
|
+
validates :last_name, :presence => true
|
|
12
|
+
validates :email_address, :presence => true
|
|
13
|
+
|
|
14
|
+
# The user's first name & last name concatenated
|
|
15
|
+
def full_name
|
|
16
|
+
"#{first_name} #{last_name}"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# The user's first name & initial of last name concatenated
|
|
20
|
+
def short_name
|
|
21
|
+
"#{first_name} #{last_name[0,1]}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Reset the user's password to something random and e-mail it to them
|
|
25
|
+
def reset_password!
|
|
26
|
+
self.password = SecureRandom.hex(8)
|
|
27
|
+
self.password_confirmation = self.password
|
|
28
|
+
self.save!
|
|
29
|
+
Shoppe::UserMailer.new_password(self).deliver
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Attempt to authenticate a user based on email & password. Returns the
|
|
33
|
+
# user if successful otherwise returns false.
|
|
34
|
+
def self.authenticate(email_address, password)
|
|
35
|
+
user = self.where(:email_address => email_address).first
|
|
36
|
+
return false if user.nil?
|
|
37
|
+
return false unless user.authenticate(password)
|
|
38
|
+
user
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
!!!
|
|
2
|
+
%html
|
|
3
|
+
%head
|
|
4
|
+
%title #{@page_title} - Shoppe
|
|
5
|
+
= stylesheet_link_tag 'shoppe/application'
|
|
6
|
+
= javascript_include_tag 'shoppe/application'
|
|
7
|
+
= csrf_meta_tags
|
|
8
|
+
%body
|
|
9
|
+
%nav.sidebar
|
|
10
|
+
%header.logo
|
|
11
|
+
%h1= link_to "Shoppe", root_path
|
|
12
|
+
%p v#{Shoppe::VERSION}
|
|
13
|
+
%p.logged
|
|
14
|
+
Logged in as #{current_user.full_name}
|
|
15
|
+
%ul
|
|
16
|
+
%li
|
|
17
|
+
%span.pending= Shoppe::Order.pending.count
|
|
18
|
+
= link_to "Orders", [:orders], :class => @active_nav == :orders ? 'active' : ''
|
|
19
|
+
%li= link_to "Products", [:products], :class => @active_nav == :products ? 'active' : ''
|
|
20
|
+
%li= link_to "Product Categories", :product_categories, :class => @active_nav == :product_categories ? 'active' : ''
|
|
21
|
+
%li= link_to "Delivery Services", [:delivery_services], :class => @active_nav == :delivery_services ? 'active' : ''
|
|
22
|
+
%li= link_to "Users", [:users], :class => @active_nav == :users ? 'active' : ''
|
|
23
|
+
%li= link_to "Logout", [:logout], :method => :delete
|
|
24
|
+
|
|
25
|
+
%header.main
|
|
26
|
+
= yield :header
|
|
27
|
+
|
|
28
|
+
#content
|
|
29
|
+
= display_flash
|
|
30
|
+
%section.main
|
|
31
|
+
= yield
|
|
32
|
+
|
|
33
|
+
%footer
|
|
34
|
+
%p.store= link_to "Goto Storefront", '/'
|
|
35
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
= form_for [@delivery_service, @delivery_service_price] do |f|
|
|
2
|
+
= f.error_messages
|
|
3
|
+
= field_set_tag "Weight allowance" do
|
|
4
|
+
%dl
|
|
5
|
+
%dt= f.label :min_weight
|
|
6
|
+
%dd= f.text_field :min_weight
|
|
7
|
+
%dl
|
|
8
|
+
%dt= f.label :max_weight
|
|
9
|
+
%dd= f.text_field :max_weight
|
|
10
|
+
|
|
11
|
+
= field_set_tag "Pricing" do
|
|
12
|
+
%dl
|
|
13
|
+
%dt= f.label :price
|
|
14
|
+
%dd= f.text_field :price
|
|
15
|
+
%dl
|
|
16
|
+
%dt= f.label :tax_rate
|
|
17
|
+
%dd= f.text_field :tax_rate
|
|
18
|
+
|
|
19
|
+
= field_set_tag "Details" do
|
|
20
|
+
%dl
|
|
21
|
+
%dt= f.label :code
|
|
22
|
+
%dd= f.text_field :code
|
|
23
|
+
|
|
24
|
+
%p.submit
|
|
25
|
+
- unless @delivery_service_price.new_record?
|
|
26
|
+
%span.right= link_to "Delete", [@delivery_service, @delivery_service_price], :class => 'button purple', :method => :delete, :data => {:confirm => "Are you sure you wish to remove this price?"}
|
|
27
|
+
= f.submit :class => 'button green'
|
|
28
|
+
= link_to "Cancel", :delivery_services, :class => 'button'
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
- @page_title = "Delivery Services"
|
|
2
|
+
|
|
3
|
+
= content_for :header do
|
|
4
|
+
%p.buttons
|
|
5
|
+
= link_to "New price", [:new, @delivery_service, :delivery_service_price], :class => 'button green'
|
|
6
|
+
= link_to "Back to delivery services", :delivery_services, :class => 'button'
|
|
7
|
+
%h2 Delivery Pricing for #{@delivery_service.name}
|
|
8
|
+
|
|
9
|
+
.table
|
|
10
|
+
%table.data
|
|
11
|
+
%thead
|
|
12
|
+
%tr
|
|
13
|
+
%th Price
|
|
14
|
+
%th Weight Allowance
|
|
15
|
+
%th Code
|
|
16
|
+
%tbody
|
|
17
|
+
- for price in @delivery_service_prices
|
|
18
|
+
%tr
|
|
19
|
+
%td= link_to number_to_currency(price.price), [:edit, @delivery_service, price]
|
|
20
|
+
%td #{price.min_weight}kg → #{price.max_weight}kg
|
|
21
|
+
%td= price.code
|
|
22
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
= form_for @delivery_service do |f|
|
|
2
|
+
= f.error_messages
|
|
3
|
+
= field_set_tag "Details" do
|
|
4
|
+
%dl
|
|
5
|
+
%dt= f.label :name
|
|
6
|
+
%dd= f.text_field :name
|
|
7
|
+
%dl
|
|
8
|
+
%dt= f.label :code
|
|
9
|
+
%dd= f.text_field :code
|
|
10
|
+
%dl
|
|
11
|
+
%dt= f.label :active
|
|
12
|
+
%dd= f.check_box :active
|
|
13
|
+
%dl
|
|
14
|
+
%dt= f.label :default
|
|
15
|
+
%dd= f.check_box :default
|
|
16
|
+
= field_set_tag "Courier" do
|
|
17
|
+
%dl
|
|
18
|
+
%dt= f.label :courier, "Courier Name"
|
|
19
|
+
%dd= f.text_field :courier
|
|
20
|
+
%dl
|
|
21
|
+
%dt= f.label :tracking_url, "Tracking URL"
|
|
22
|
+
%dd
|
|
23
|
+
= f.text_field :tracking_url
|
|
24
|
+
%p.help Use <code>{{consignment_number}}</code> to insert the consignment number.
|
|
25
|
+
|
|
26
|
+
- unless @delivery_service.new_record?
|
|
27
|
+
= field_set_tag "Pricing" do
|
|
28
|
+
%dl
|
|
29
|
+
%dt Pricing
|
|
30
|
+
%dd= link_to "Set pricing for delivery service", [@delivery_service, :delivery_service_prices], :class => 'button button-mini'
|
|
31
|
+
%p.submit
|
|
32
|
+
- unless @delivery_service.new_record?
|
|
33
|
+
%span.right= link_to "Delete", [@delivery_service], :class => 'button purple', :method => :delete, :data => {:confirm => "Are you sure you wish to remove this delivery service?"}
|
|
34
|
+
= f.submit :class => 'button green'
|
|
35
|
+
= link_to "Cancel", :delivery_services, :class => 'button'
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
- @page_title = "Delivery Services"
|
|
2
|
+
|
|
3
|
+
= content_for :header do
|
|
4
|
+
%p.buttons= link_to "New delivery service", :new_delivery_service, :class => 'button green'
|
|
5
|
+
%h2 Delivery Services
|
|
6
|
+
|
|
7
|
+
.table
|
|
8
|
+
%table.data
|
|
9
|
+
%thead
|
|
10
|
+
%tr
|
|
11
|
+
%th Name
|
|
12
|
+
%th Prices
|
|
13
|
+
%th Courier
|
|
14
|
+
%th Active?
|
|
15
|
+
%th Default?
|
|
16
|
+
%tbody
|
|
17
|
+
- for delivery_service in @delivery_services
|
|
18
|
+
%tr
|
|
19
|
+
%td= link_to delivery_service.name, [:edit, delivery_service]
|
|
20
|
+
%td= link_to "Set Prices", [delivery_service, :delivery_service_prices]
|
|
21
|
+
%td= delivery_service.courier
|
|
22
|
+
%td= boolean_tag :active
|
|
23
|
+
%td= boolean_tag :default
|
|
24
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Hello <%=@order.first_name%>!
|
|
2
|
+
|
|
3
|
+
Re: Order #<%=@order.number%>
|
|
4
|
+
|
|
5
|
+
We're pleased to let you know that we have accepted your order and your payment of <%=number_to_currency @order.total%> has been taken from your card successfully.
|
|
6
|
+
|
|
7
|
+
We will e-mail you again when we ship your order from our warehouse.
|
|
8
|
+
|
|
9
|
+
Many thanks,
|
|
10
|
+
|
|
11
|
+
<%=Shoppe.config[:store_name]%>
|
|
12
|
+
<%=Shoppe.config[:email_address]%>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Hello <%=@order.first_name%>!
|
|
2
|
+
|
|
3
|
+
Re: Order #<%=@order.number%>
|
|
4
|
+
|
|
5
|
+
We're pleased to let you know that we have received your order and one of our team will be accepting it shortly.
|
|
6
|
+
|
|
7
|
+
We will e-mail you again when your order has been accepted.
|
|
8
|
+
|
|
9
|
+
Many thanks,
|
|
10
|
+
|
|
11
|
+
<%=Shoppe.config[:store_name]%>
|
|
12
|
+
<%=Shoppe.config[:email_address]%>
|