Implement waiter ordering and improvements

This commit is contained in:
2014-03-24 10:02:57 +01:00
parent 474d5f88c6
commit 6c2427e082
24 changed files with 128 additions and 48 deletions
@@ -18,6 +18,7 @@
// require bootstrap-typeahead // require bootstrap-typeahead
//= require bootstrap //= require bootstrap
//= require js-routes //= require js-routes
//= require translations
//= require qwaiter //= require qwaiter
//= require ./qsupplier //= require ./qsupplier
//= require handlebars //= require handlebars
@@ -28,6 +29,9 @@
//= require_self //= require_self
//= require moment //= require moment
var Qstorage = localStorage; var Qstorage = localStorage;
$.extend($translations.en, <%= I18n.t('supplier', locale: :en).to_json %>);
$.extend($translations.nl, <%= I18n.t('supplier', locale: :nl).to_json %>);
String.prototype.capitalize = function() { String.prototype.capitalize = function() {
return this.charAt(0).toUpperCase() + this.slice(1); return this.charAt(0).toUpperCase() + this.slice(1);
} }
@@ -1,17 +1,15 @@
var $translations = { $translations = {
en: { en: {
models: <%= I18n.t('activemodel.models', locale: :en).to_json %>, models: <%= I18n.t('activemodel.models', locale: :en).to_json %>,
attributes: <%= I18n.t('activemodel.attributes', locale: :en).to_json %>, attributes: <%= I18n.t('activemodel.attributes', locale: :en).to_json %>,
helpers: <%= I18n.t('helpers', locale: :en).to_json %>, helpers: <%= I18n.t('helpers', locale: :en).to_json %>,
pagination: <%= I18n.t('views.pagination', locale: :en).to_json %>, pagination: <%= I18n.t('views.pagination', locale: :en).to_json %>,
<%= I18n.t('supplier', locale: :en).to_json[1..-2] %>
}, },
nl: { nl: {
models: <%= I18n.t('activemodel.models', locale: :nl).to_json %>, models: <%= I18n.t('activemodel.models', locale: :nl).to_json %>,
attributes: <%= I18n.t('activemodel.attributes', locale: :nl).to_json %>, attributes: <%= I18n.t('activemodel.attributes', locale: :nl).to_json %>,
helpers: <%= I18n.t('helpers', locale: :nl).to_json %>, helpers: <%= I18n.t('helpers', locale: :nl).to_json %>,
pagination: <%= I18n.t('views.pagination', locale: :nl).to_json %>, pagination: <%= I18n.t('views.pagination', locale: :nl).to_json %>,
<%= I18n.t('supplier', locale: :nl).to_json[1..-2] %>
} }
} }
@@ -1,8 +1,9 @@
App.ProductCategoriesController = Ember.ArrayController.extend App.ProductCategoriesController = Ember.ArrayController.extend
needs: ['table'] #needs: ['table']
actions: actions:
addProduct: (product)-> addProduct: (product)->
if table = @get('controllers.table.model') if table_route = App.Router.router.currentHandlerInfos.find((r) -> r.name == 'table')
table = table_route.context
if existing = @store.all('product_order').find((po)->po.get('table') == table and po.get('product') == product) if existing = @store.all('product_order').find((po)->po.get('table') == table and po.get('product') == product)
existing.increment() existing.increment()
else else
@@ -0,0 +1 @@
App.SectionController = Ember.ObjectController.extend {}
@@ -1 +1,2 @@
App.SectionsController = Ember.ArrayController.extend {} App.SectionsController = Ember.ArrayController.extend
needs: ['section']
@@ -5,4 +5,19 @@ App.TableController = Ember.ObjectController.extend
actions: actions:
clearProductOrders: -> clearProductOrders: ->
@get('product_orders').every (product_order)->product_order.deleteRecord() @get('product_orders').toArray().forEach (product_order)->
product_order.unloadRecord()
orderProducts: ->
orders = @get('product_orders').toArray()
data = orders.map( (order)->order.serialize() )
dataObject = {order: {}}
for product_order in data
dataObject['table_id'] = product_order.table_id
dataObject['order'][product_order.product_id] = product_order.quantity
$.ajax
url: Routes.order_products_waiter_path(),
type: "POST",
data: JSON.stringify(dataObject),
contentType: "application/json",
dataType: 'json'
orders.invoke 'unloadRecord'
@@ -1,7 +1,7 @@
# For more information see: http://emberjs.com/guides/routing/ # For more information see: http://emberjs.com/guides/routing/
# and for queryParams: https://github.com/alexspeller/website/blob/a96d9afe4506454b155cc64299e86e558ce3c9f1/source/guides/routing/query-params.md # and for queryParams: https://github.com/alexspeller/website/blob/a96d9afe4506454b155cc64299e86e558ce3c9f1/source/guides/routing/query-params.md
App.Router.reopen App.Router.reopen
location: 'history' #location: 'history'
rootURL: '/waiter' rootURL: '/waiter'
App.Router.map -> App.Router.map ->
@@ -1,4 +1,3 @@
h2 Food!
each product_category in controller each product_category in controller
if product_category.products if product_category.products
h5= product_category.name h5= product_category.name
@@ -1,6 +1,5 @@
.row .row
.section-tables.small-12.medium-6.large-4.columns .section-tables.small-12.medium-6.large-4.columns
h2 Tables
each table in tables each table in tables
= link-to 'table' table class="panel section-table" = link-to 'table' table class="panel section-table"
= table.number = table.number
@@ -0,0 +1,2 @@
= link-to 'section' this
= title
@@ -1,9 +1,7 @@
dl.sub-nav dl.sub-nav
dt Section: dt= t 'model.section'
each section in controller each section in controller
dd view App.SectionHeaderView context=section
= link-to 'section' section
= section.title
else else
dd No available sections dd No available sections
hr hr
@@ -2,7 +2,8 @@ hr.hide-for-large-up
if product_orders if product_orders
a.tiny.button.right{action clearProductOrders} href="#" x a.tiny.button.right{action clearProductOrders} href="#" x
h4 h4
| Table = t 'models.table'
|
= number = number
.panel .panel
ul.product-orders ul.product-orders
@@ -17,3 +18,5 @@ h4
li.total li.total
| Total | Total
span.currency=currency orderTotal span.currency=currency orderTotal
if product_orders
a.tiny.button.right{action orderProducts} href="#" = t 'product_orders.order_button'
@@ -0,0 +1,8 @@
App.SectionHeaderView = Ember.View.extend
templateName: 'section_header'
tagName: 'dd'
classNameBindings: ['active']
active: (->
if @get('context.id') == @get('controller.controllers.section.model.id') then 'active' else ''
).property('controller.controllers.section.model.id')
@@ -1,7 +0,0 @@
#= require jquery
#= require jquery_ujs
#= require ./app/application
#= require foundation
#= require_directory .
#= require_self
$(document).foundation()
@@ -0,0 +1,15 @@
#= require jquery
#= require jquery_ujs
#= require ./app/application
#= require foundation
#= require moment
#= require jquery.ui.datepicker
#= require translations
#= require js-routes
#= require_directory .
#= require_self
@Qstorage = localStorage
$.extend($translations.en, <%= I18n.t('waiter', locale: :en).to_json %>);
$.extend($translations.nl, <%= I18n.t('waiter', locale: :nl).to_json %>);
$(document).foundation()
setLocale('en')
+2 -2
View File
@@ -286,12 +286,12 @@ class UserController < ApplicationController
respond_to do |format| respond_to do |format|
format.html do format.html do
redirect_to(user_root_path, alert: t('messages.cannot_order_on_non_active_list')) and return unless @list.active? redirect_to(user_root_path, alert: t('messages.cannot_order_on_non_active_list')) and return unless @list.active?
@list.place_order current_user, params[:products] @list.place_order params[:products], user: current_user
redirect_to user_root_path, notice: t('messages.order_is_placed') redirect_to user_root_path, notice: t('messages.order_is_placed')
end end
format.json do format.json do
render json: json_alert('messages.cannot_order_on_non_active_list') and return unless @list.active? render json: json_alert('messages.cannot_order_on_non_active_list') and return unless @list.active?
@list.place_order current_user, params[:products] @list.place_order params[:products], user: current_user
render json: json_notice('messages.order_is_placed', location: :active_list) render json: json_notice('messages.order_is_placed', location: :active_list)
end end
end end
+15
View File
@@ -18,4 +18,19 @@ class WaiterController < ApplicationController
format.json { render json: ProductCategory.all.include_relation(:product), root: 'product_categories', each_serializer: ProductCategorySerializer } format.json { render json: ProductCategory.all.include_relation(:product), root: 'product_categories', each_serializer: ProductCategorySerializer }
end end
end end
def order_products
@table= Table.find_by_supplier_id_and_id!(current_supplier.id, params[:table_id])
@list = List.from_table_by_employee(@table, current_employee)
@list.place_order params[:order], employee: current_employee
render nothing: true
end
def current_supplier
@current_supplier ||= Supplier.first
end
def current_employee
@current_employee ||= current_supplier.employees.first
end
end end
+10
View File
@@ -0,0 +1,10 @@
class Employee
include SimplyStored::Couch
devise :database_authenticatable, :recoverable, :rememberable, :trackable #, :omniauthable, :omniauth_providers => [:facebook] #, :token_authenticatable , :registerable
belongs_to :supplier
has_many :orders
has_and_belongs_to_many :lists, storing_keys: false
end
+31 -23
View File
@@ -17,6 +17,7 @@ class List
belongs_to :supplier belongs_to :supplier
belongs_to :section belongs_to :section
has_and_belongs_to_many :users, storing_keys: true has_and_belongs_to_many :users, storing_keys: true
has_and_belongs_to_many :employees, storing_keys: true
attr_protected :supplier_id attr_protected :supplier_id
@@ -76,6 +77,17 @@ class List
list list
end end
# Create, a list given a table and a employee
def self.from_table_by_employee table, employee
unless list = table.active_list
list = new table: table, section_id: table.section_id
list.supplier_id = table.supplier_id
list.add_employee employee
list.save
end
list
end
def self.for_supplier(supplier, options = {}) def self.for_supplier(supplier, options = {})
total_entries = database.view(for_supplier_view({startkey: ["#{supplier.id}\u9999"], endkey: [supplier.id], include_docs: false, reduce: true, descending: true})) total_entries = database.view(for_supplier_view({startkey: ["#{supplier.id}\u9999"], endkey: [supplier.id], include_docs: false, reduce: true, descending: true}))
options[:total_entries] = total_entries options[:total_entries] = total_entries
@@ -142,9 +154,7 @@ class List
def needs_help! def needs_help!
self.needs_help = true self.needs_help = true
if save if save
for user_id in user_ids broadcast_users 'list_needs_help', id: id
broadcast_user user_id, 'list_needs_help', id: id
end
broadcast_supplier(supplier_id, 'list_needs_help', id: id) broadcast_supplier(supplier_id, 'list_needs_help', id: id)
end end
end end
@@ -152,9 +162,7 @@ class List
def is_helped! def is_helped!
self.needs_help = false self.needs_help = false
if save if save
for user_id in user_ids broadcast_users 'list_helped', id: id
broadcast_user user_id, 'list_helped', id: id
end
broadcast_supplier supplier_id, 'list_helped', id: id broadcast_supplier supplier_id, 'list_helped', id: id
end end
end end
@@ -162,9 +170,7 @@ class List
def needs_payment! def needs_payment!
self.needs_payment = true self.needs_payment = true
if save if save
for user_id in user_ids broadcast_users 'list_needs_payment', id: id
broadcast_user user_id, 'list_needs_payment', id: id
end
broadcast_supplier supplier_id, 'list_needs_payment', id: id broadcast_supplier supplier_id, 'list_needs_payment', id: id
end end
end end
@@ -173,9 +179,7 @@ class List
self.is_paid = true self.is_paid = true
self.paid_at ||= Time.now self.paid_at ||= Time.now
if save if save
for user_id in user_ids broadcast_users 'list_is_paid', id: id
broadcast_user user_id, 'list_is_paid', id: id
end
broadcast_supplier supplier_id, 'list_is_paid', id: id broadcast_supplier supplier_id, 'list_is_paid', id: id
end end
end end
@@ -192,9 +196,7 @@ class List
order.section_id = self.section_id order.section_id = self.section_id
order.save order.save
end end
for user_id in user_ids broadcast_users 'list_changed_table', list: as_json, section_title: to_table.section.try(:title), from_table_id: from_table
broadcast_user user_id, 'list_changed_table', list: as_json, section_title: to_table.section.try(:title), from_table_id: from_table
end
broadcast_supplier supplier_id, 'list_changed_table', list: as_json, section_title: to_table.section.try(:title), from_table_id: from_table broadcast_supplier supplier_id, 'list_changed_table', list: as_json, section_title: to_table.section.try(:title), from_table_id: from_table
end end
end end
@@ -214,7 +216,7 @@ class List
def unlink_user(user) def unlink_user(user)
changed = join_requests.delete(user.id) changed = join_requests.delete(user.id)
changed ||= user_ids.delete(user.id) changed ||= Array.wrap(user_ids).delete(user.id)
if user.active_list_id == id if user.active_list_id == id
user.active_list_id = nil user.active_list_id = nil
user.save user.save
@@ -265,10 +267,9 @@ class List
state == 'active' state == 'active'
end end
def place_order(user, products) def place_order(products, user: nil, employee: nil)
return false unless products.any? return false unless products.any?
return false unless user order = Order.create list: self, supplier: supplier, user: user, employee: employee, section_id: section_id
order = Order.create list: self, supplier: supplier, user: user, section_id: section_id
return unless order.id return unless order.id
orders_placed_count = supplier.increment_orders_placed_count! orders_placed_count = supplier.increment_orders_placed_count!
loaded_products = self.class.database.load_document products.keys loaded_products = self.class.database.load_document products.keys
@@ -279,16 +280,23 @@ class List
end end
set_price set_price
save save
for user_id in user_ids
broadcast_user user_id, 'new_order', order: order.with_products_as_json, total_amount: price
broadcast_user user_id, 'orders_placed_count', count: orders_placed_count broadcast_users 'new_order', order: order.with_products_as_json, total_amount: price
end broadcast_users 'orders_placed_count', count: orders_placed_count
broadcast_supplier supplier.id, 'list_update', active_model_serializer.new(self).as_json broadcast_supplier supplier.id, 'list_update', active_model_serializer.new(self).as_json
broadcast_supplier supplier.id, 'new_order', OrderSerializer.new(order) broadcast_supplier supplier.id, 'new_order', OrderSerializer.new(order)
broadcast_supplier supplier.id, 'orders_placed_count', count: orders_placed_count broadcast_supplier supplier.id, 'orders_placed_count', count: orders_placed_count
order order
end end
def broadcast_users(message, content = {})
for user_id in Array.wrap(user_ids)
broadcast_user user_id, message, content
end
end
def as_json(*args) def as_json(*args)
super.merge(id: id, table_number: table_number, has_active_orders: has_active_orders? ) super.merge(id: id, table_number: table_number, has_active_orders: has_active_orders? )
end end
+1 -1
View File
@@ -8,11 +8,11 @@ class Order
belongs_to :user belongs_to :user
belongs_to :supplier belongs_to :supplier
belongs_to :section belongs_to :section
belongs_to :employee
has_many :product_orders, dependent: :destroy has_many :product_orders, dependent: :destroy
#has_many :products, through: :product_orders #has_many :products, through: :product_orders
validates :supplier_id, presence: true validates :supplier_id, presence: true
validates :user_id, presence: true
view :active_for_supplier_view, type: :custom, map_function: %[function(doc){ view :active_for_supplier_view, type: :custom, map_function: %[function(doc){
if(doc.ruby_class == 'Order' && (doc.state == 'placed' || doc.state == 'active')){ if(doc.ruby_class == 'Order' && (doc.state == 'placed' || doc.state == 'active')){
+1
View File
@@ -29,6 +29,7 @@ class Supplier
#has_many :lists, through: :tables #has_many :lists, through: :tables
has_many :orders, dependent: :destroy has_many :orders, dependent: :destroy
has_many :sections, dependent: :destroy has_many :sections, dependent: :destroy
has_many :employees
after_create :add_section_on_create after_create :add_section_on_create
+4
View File
@@ -0,0 +1,4 @@
en:
waiter:
product_orders:
order_button: Order
+4
View File
@@ -0,0 +1,4 @@
nl:
waiter:
product_orders:
order_button: Bestel
+1
View File
@@ -30,6 +30,7 @@ Qwaiter::Application.routes.draw do
get '/waiter/sections' => 'waiter#sections' get '/waiter/sections' => 'waiter#sections'
get '/waiter/product_categories' => 'waiter#product_categories' get '/waiter/product_categories' => 'waiter#product_categories'
get '/waiter/*rest' => redirect('/waiter') # Ember app refresh get '/waiter/*rest' => redirect('/waiter') # Ember app refresh
post '/waiter/order_products' => 'waiter#order_products', as: :order_products_waiter
post '/supplier/close_list' => 'supplier#close_list', as: :supplier_close_list post '/supplier/close_list' => 'supplier#close_list', as: :supplier_close_list