end of day commit
This commit is contained in:
@@ -30,7 +30,7 @@ gem 'simply_stored' , :git => 'git://github.com/bterkuile/simply_stored.git'
|
||||
gem 'devise', '2.0.4'
|
||||
gem 'devise_simply_stored'
|
||||
|
||||
gem 'rqrcode-rails3'
|
||||
gem 'rqrcode'
|
||||
gem 'mini_magick'
|
||||
#gem "less-rails-bootstrap-devise", :git => 'git://github.com/bigbento/less-rails-bootstrap-devise.git'
|
||||
|
||||
|
||||
+1
-3
@@ -157,8 +157,6 @@ GEM
|
||||
rest-client (1.6.7)
|
||||
mime-types (>= 1.16)
|
||||
rqrcode (0.4.2)
|
||||
rqrcode-rails3 (0.1.5)
|
||||
rqrcode (>= 0.4.2)
|
||||
rspec (2.11.0)
|
||||
rspec-core (~> 2.11.0)
|
||||
rspec-expectations (~> 2.11.0)
|
||||
@@ -240,7 +238,7 @@ DEPENDENCIES
|
||||
mini_magick
|
||||
pry
|
||||
rails (= 3.2.8)
|
||||
rqrcode-rails3
|
||||
rqrcode
|
||||
rspec-rails
|
||||
sass-rails (~> 3.2.3)
|
||||
selenium-webdriver
|
||||
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
<map version="0.9.0">
|
||||
<!-- To view this file, download free mind mapping software FreeMind from http://freemind.sourceforge.net -->
|
||||
<node COLOR="#000000" CREATED="1346248504629" ID="ID_685891399" MODIFIED="1346249525729" TEXT="Qr scan">
|
||||
<font NAME="SansSerif" SIZE="20"/>
|
||||
<hook NAME="accessories/plugins/AutomaticLayout.properties"/>
|
||||
<node COLOR="#0033ff" CREATED="1346248520045" ID="ID_454905514" MODIFIED="1346249526866" POSITION="right" TEXT="I already have an open list">
|
||||
<edge STYLE="sharp_bezier" WIDTH="8"/>
|
||||
<font NAME="SansSerif" SIZE="18"/>
|
||||
<node COLOR="#00b439" CREATED="1346248563729" ID="ID_733708643" MODIFIED="1346249526869" TEXT="Table is from same supplier">
|
||||
<edge STYLE="bezier" WIDTH="thin"/>
|
||||
<font NAME="SansSerif" SIZE="16"/>
|
||||
<node COLOR="#990000" CREATED="1346248693439" ID="ID_916776491" MODIFIED="1346249526871" TEXT="Offer to move table">
|
||||
<font NAME="SansSerif" SIZE="14"/>
|
||||
<node COLOR="#111111" CREATED="1346248699370" ID="ID_1684994680" MODIFIED="1346252084515" TEXT="If yes, move table and show product"/>
|
||||
<node COLOR="#111111" CREATED="1346248725406" ID="ID_10610841" MODIFIED="1346252095940" TEXT="If no, show products"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#00b439" CREATED="1346248579841" ID="ID_227890554" MODIFIED="1346249526872" TEXT="Table is from other supplier">
|
||||
<edge STYLE="bezier" WIDTH="thin"/>
|
||||
<font NAME="SansSerif" SIZE="16"/>
|
||||
<node COLOR="#990000" CREATED="1346248754701" ID="ID_1748068243" MODIFIED="1346249459783" TEXT="Warning, cannot do with open list">
|
||||
<font NAME="SansSerif" SIZE="14"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#00b439" CREATED="1346248860563" ID="ID_141169907" MODIFIED="1346249526873" TEXT="Table is your current table">
|
||||
<edge STYLE="bezier" WIDTH="thin"/>
|
||||
<font NAME="SansSerif" SIZE="16"/>
|
||||
<node COLOR="#990000" CREATED="1346248869002" ID="ID_418218218" MODIFIED="1346249459784" TEXT="Do nothing!">
|
||||
<font NAME="SansSerif" SIZE="14"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#0033ff" CREATED="1346248530523" ID="ID_1378676144" MODIFIED="1346249526875" POSITION="left" TEXT="I do not have an open list">
|
||||
<edge STYLE="sharp_bezier" WIDTH="8"/>
|
||||
<font NAME="SansSerif" SIZE="18"/>
|
||||
<node COLOR="#00b439" CREATED="1346248595465" ID="ID_313049528" MODIFIED="1346249526877" TEXT="Table is occupied by other user">
|
||||
<edge STYLE="bezier" WIDTH="thin"/>
|
||||
<font NAME="SansSerif" SIZE="16"/>
|
||||
<node COLOR="#990000" CREATED="1346248635520" ID="ID_1246071370" MODIFIED="1346249459786" TEXT="Option: Join this table">
|
||||
<font NAME="SansSerif" SIZE="14"/>
|
||||
</node>
|
||||
<node COLOR="#990000" CREATED="1346249385937" ID="ID_146376441" MODIFIED="1346249526878" TEXT="Option: Show products">
|
||||
<font NAME="SansSerif" SIZE="14"/>
|
||||
<node COLOR="#111111" CREATED="1346249395535" ID="ID_152885983" MODIFIED="1346249459786" TEXT="Show products without ordering options"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#00b439" CREATED="1346248619233" ID="ID_1502347679" MODIFIED="1346249526883" TEXT="Table is not occupied by other user">
|
||||
<edge STYLE="bezier" WIDTH="thin"/>
|
||||
<font NAME="SansSerif" SIZE="16"/>
|
||||
<node COLOR="#990000" CREATED="1346248629824" ID="ID_1685359507" MODIFIED="1346249459791">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Show products with ordering options
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<font NAME="SansSerif" SIZE="14"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</map>
|
||||
@@ -2,3 +2,11 @@ jQuery ->
|
||||
$("a[rel=popover]").popover()
|
||||
$(".tooltip").tooltip()
|
||||
$("a[rel=tooltip]").tooltip()
|
||||
$('input.currency').each(->
|
||||
obj = $(this)
|
||||
original_width = obj.width()
|
||||
obj.wrap("<div class='input-prepend'>")
|
||||
currency_sign = $("<span class='add-on'>€</span>")
|
||||
obj.before(currency_sign)
|
||||
obj.css('width', (original_width - currency_sign.outerWidth())+'px')
|
||||
)
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* Cookie plugin
|
||||
*
|
||||
* Copyright (c) 2006 Klaus Hartl (stilbuero.de)
|
||||
* Dual licensed under the MIT and GPL licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a cookie with the given name and value and other optional parameters.
|
||||
*
|
||||
* @example $.cookie('the_cookie', 'the_value');
|
||||
* @desc Set the value of a cookie.
|
||||
* @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
|
||||
* @desc Create a cookie with all available options.
|
||||
* @example $.cookie('the_cookie', 'the_value');
|
||||
* @desc Create a session cookie.
|
||||
* @example $.cookie('the_cookie', null);
|
||||
* @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
|
||||
* used when the cookie was set.
|
||||
*
|
||||
* @param String name The name of the cookie.
|
||||
* @param String value The value of the cookie.
|
||||
* @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
|
||||
* @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
|
||||
* If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
|
||||
* If set to null or omitted, the cookie will be a session cookie and will not be retained
|
||||
* when the the browser exits.
|
||||
* @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
|
||||
* @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
|
||||
* @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
|
||||
* require a secure protocol (like HTTPS).
|
||||
* @type undefined
|
||||
*
|
||||
* @name $.cookie
|
||||
* @cat Plugins/Cookie
|
||||
* @author Klaus Hartl/klaus.hartl@stilbuero.de
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the value of a cookie with the given name.
|
||||
*
|
||||
* @example $.cookie('the_cookie');
|
||||
* @desc Get the value of a cookie.
|
||||
*
|
||||
* @param String name The name of the cookie.
|
||||
* @return The value of the cookie.
|
||||
* @type String
|
||||
*
|
||||
* @name $.cookie
|
||||
* @cat Plugins/Cookie
|
||||
* @author Klaus Hartl/klaus.hartl@stilbuero.de
|
||||
*/
|
||||
jQuery.cookie = function(name, value, options) {
|
||||
if (typeof value != 'undefined') { // name and value given, set cookie
|
||||
options = options || {};
|
||||
if (value === null) {
|
||||
value = '';
|
||||
options.expires = -1;
|
||||
}
|
||||
var expires = '';
|
||||
if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
|
||||
var date;
|
||||
if (typeof options.expires == 'number') {
|
||||
date = new Date();
|
||||
date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
|
||||
} else {
|
||||
date = options.expires;
|
||||
}
|
||||
expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
|
||||
}
|
||||
// CAUTION: Needed to parenthesize options.path and options.domain
|
||||
// in the following expressions, otherwise they evaluate to undefined
|
||||
// in the packed version for some reason...
|
||||
var path = options.path ? '; path=' + (options.path) : '';
|
||||
var domain = options.domain ? '; domain=' + (options.domain) : '';
|
||||
var secure = options.secure ? '; secure' : '';
|
||||
document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
|
||||
} else { // only name given, get cookie
|
||||
var cookieValue = null;
|
||||
if (document.cookie && document.cookie != '') {
|
||||
var cookies = document.cookie.split(';');
|
||||
for (var i = 0; i < cookies.length; i++) {
|
||||
var cookie = jQuery.trim(cookies[i]);
|
||||
// Does this cookie string begin with the name we want?
|
||||
if (cookie.substring(0, name.length + 1) == (name + '=')) {
|
||||
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cookieValue;
|
||||
}
|
||||
};
|
||||
@@ -59,8 +59,8 @@ root.Quser=
|
||||
row.append($('<td class="currency"></td>').html(Qrammer.currency(order.total_amount)))
|
||||
foot.append('<tr><td></td><td class="currency"><strong>'+Qrammer.currency(res.total_amount)+'</strong></td></tr>')
|
||||
)
|
||||
order_selected_products: ()->
|
||||
h = {}
|
||||
order_selected_products: (h)->
|
||||
h ||= {}
|
||||
for product_id, info of window.active_products_list
|
||||
h['products['+product_id+']'] = info.number
|
||||
$.post('/user/order_selected_products', h, ((res) -> Quser.handle_response(res)), 'json')
|
||||
@@ -92,48 +92,67 @@ root.Quser=
|
||||
table.show()
|
||||
|
||||
load_active_list_products: ->
|
||||
$.get('/user/list_products.json', (res) ->
|
||||
window.products = res
|
||||
Quser.populate_products_table('/user/list_products.json', true)
|
||||
load_table_products: (table_id, occupied)->
|
||||
Quser.populate_products_table('/user/list_products_for_table.json?table_id='+table_id, !occupied)
|
||||
populate_products_table: (src, include_order_buttons)->
|
||||
$.get(src, (res) ->
|
||||
body = $('#products-table tbody')
|
||||
for category, products of window.products
|
||||
for category, products of res
|
||||
body.append('<tr><td colspan="4"><h4>'+category+'<h4></td></tr>')
|
||||
for product in products
|
||||
row = $('<tr></tr>')
|
||||
button = $('<button class="btn btn-mini btn-primary">Add</button>')
|
||||
callback = ((prod) ->
|
||||
->
|
||||
product_count_holder = $('#order-product-count-'+prod._id)
|
||||
count = parseInt(product_count_holder.text())
|
||||
product_count_holder.text(1)
|
||||
Quser.add_product(prod, count)
|
||||
)(product)
|
||||
button.click(callback)
|
||||
row.append('<td>'+product.name+'</td>')
|
||||
order_product_count = $('<span id="order-product-count-'+product._id+'" class="order-product-count">1</span>')
|
||||
order_count_minus = $('<span class="btn btn-info btn-mini">-</span>')
|
||||
order_count_minus.click(->
|
||||
val_holder = $(this).siblings('.order-product-count')
|
||||
val = parseInt(val_holder.text())
|
||||
val_holder.text(val - 1) if val > 1
|
||||
)
|
||||
order_count_plus = $('<span class="btn btn-info btn-mini">+</span>')
|
||||
order_count_plus.click(->
|
||||
val_holder = $(this).siblings('.order-product-count')
|
||||
val = parseInt(val_holder.text())
|
||||
val_holder.text(val + 1)
|
||||
)
|
||||
row.append($('<td class="order-count-cell"></td>').append(order_count_minus).append(' ').append(order_product_count).append(' ').append(order_count_plus))
|
||||
if include_order_buttons
|
||||
button = $('<button class="btn btn-mini btn-primary">Add</button>')
|
||||
callback = ((prod) ->
|
||||
->
|
||||
product_count_holder = $('#order-product-count-'+prod._id)
|
||||
count = parseInt(product_count_holder.text())
|
||||
product_count_holder.text(1)
|
||||
Quser.add_product(prod, count)
|
||||
)(product)
|
||||
button.click(callback)
|
||||
order_product_count = $('<span id="order-product-count-'+product._id+'" class="order-product-count">1</span>')
|
||||
order_count_minus = $('<span class="btn btn-info btn-mini">-</span>')
|
||||
order_count_minus.click(->
|
||||
val_holder = $(this).siblings('.order-product-count')
|
||||
val = parseInt(val_holder.text())
|
||||
val_holder.text(val - 1) if val > 1
|
||||
)
|
||||
order_count_plus = $('<span class="btn btn-info btn-mini">+</span>')
|
||||
order_count_plus.click(->
|
||||
val_holder = $(this).siblings('.order-product-count')
|
||||
val = parseInt(val_holder.text())
|
||||
val_holder.text(val + 1)
|
||||
)
|
||||
row.append($('<td class="order-count-cell"></td>').append(order_count_minus).append(' ').append(order_product_count).append(' ').append(order_count_plus))
|
||||
row.append('<td>'+Qrammer.currency(product.price)+'</td>')
|
||||
row.append($('<td></td>').append(button))
|
||||
row.append($('<td></td>').append(button)) if include_order_buttons
|
||||
body.append(row)
|
||||
)
|
||||
|
||||
actions_for_table: (table_id)->
|
||||
$.get('/user/table_info.json?table_id='+table_id, (res)->
|
||||
actions_for_table: (table)->
|
||||
table = JSON.parse(table) if typeof(table) == 'string'
|
||||
$.get('/user/table_info.json?table_id='+table.table_id, (res)->
|
||||
if res.occupied
|
||||
alert('Table is occupied')
|
||||
else
|
||||
$.post('/user/create_list.json', {table_id: table_id}, (res)-> Quser.handle_response(res))
|
||||
if res.other_supplier
|
||||
#TODO cannot do something with other supplier when list is active
|
||||
else if res.current_table_id && res.current_table_id == table.table_id
|
||||
#nothing has changed, show product list
|
||||
window.location = '/user/list_products'
|
||||
else if res.current_table_id && res.current_table_id != table.table_id
|
||||
#TODO Offer to move table
|
||||
$.post('/user/move_table', {table_id: table.table_id}, (res2)->
|
||||
if res2.occupied
|
||||
alert('Cannot move to occupied table')
|
||||
else
|
||||
window.location = '/user/list_products'
|
||||
)
|
||||
else
|
||||
#$.post('/user/create_list.json', {table_id: table.table_id}, (res)-> Quser.handle_response(res))
|
||||
window.location = '/user/list_products_for_table?table_id='+table.table_id
|
||||
, 'json')
|
||||
add_product: (product, count) ->
|
||||
count ||= 1
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
form
|
||||
input.currency
|
||||
text-align: right
|
||||
@@ -79,3 +79,5 @@ table
|
||||
list-style: none
|
||||
margin: 0
|
||||
padding: 0
|
||||
li
|
||||
float: left
|
||||
|
||||
@@ -17,9 +17,16 @@ body
|
||||
height: 44px
|
||||
background-repeat: no-repeat
|
||||
width: 45px
|
||||
background-image: image-url('icons/section-table.png')
|
||||
.table-number
|
||||
//background-image: image-url('icons/section-table.png')
|
||||
.table-link
|
||||
margin-top: -45px
|
||||
.table-number
|
||||
position: absolute
|
||||
top: 0
|
||||
line-height: 44px
|
||||
width: 45px
|
||||
font-size: 42px
|
||||
text-align: center
|
||||
.action-button-container
|
||||
margin-right: -20px
|
||||
&.section-tables-active
|
||||
|
||||
@@ -14,9 +14,9 @@ class ApplicationController < ActionController::Base
|
||||
end
|
||||
end
|
||||
def check_active_list_state
|
||||
if session[:active_list_id]
|
||||
if current_user.try(:active_list_id)
|
||||
unless active_list.active?
|
||||
session[:active_list_id] = nil
|
||||
current_user.list_is_closed!
|
||||
redirect_to user_root_path, alert: t('messages.the_list_has_been_closed', list: List.model_name.human)
|
||||
end
|
||||
end
|
||||
@@ -24,8 +24,8 @@ class ApplicationController < ActionController::Base
|
||||
end
|
||||
|
||||
def active_list
|
||||
return nil unless session[:active_list_id].present?
|
||||
@active_list ||= List.find(session[:active_list_id])
|
||||
return nil unless current_user.try(:active_list_id).present?
|
||||
@active_list ||= List.find(current_user.active_list_id)
|
||||
end
|
||||
alias :active_list_object :active_list
|
||||
helper_method :active_list_object
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
class DashboardController < ApplicationController
|
||||
|
||||
before_filter :check_active_list_state, except: :home
|
||||
def home
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -16,9 +13,17 @@ class DashboardController < ApplicationController
|
||||
end
|
||||
|
||||
|
||||
def supplier_home
|
||||
redirect_to active_orders_supplier_path(Supplier.first)
|
||||
# GET /select_qr_image
|
||||
# GET /select_qr_image.png
|
||||
# GET /select_qr_image.svg
|
||||
def table_qr_image
|
||||
@table = Table.find(params[:table_id])
|
||||
code = {table_id: @table.id}.to_json
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.svg { render :qrcode => code, :level => :l, :unit => 10, table_number: @table.number }
|
||||
format.png { render qrcode: code, table_number: @table.number }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
module Suppliers
|
||||
class ApplicationController < ::ApplicationController
|
||||
before_filter :authenticate_supplier!
|
||||
layout 'tablet'
|
||||
|
||||
end
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
module Suppliers
|
||||
class ProductCategoriesController < Suppliers::ApplicationController
|
||||
|
||||
# GET /product_categories
|
||||
# GET /product_categories.json
|
||||
def index
|
||||
@product_categories = current_supplier.product_categories
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
format.json { render json: @product_categories }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /product_categories/1
|
||||
# GET /product_categories/1.json
|
||||
def show
|
||||
@product_category = ProductCategory.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
format.json { render json: @product_category }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /product_categories/new
|
||||
# GET /product_categories/new.json
|
||||
def new
|
||||
@product_category = ProductCategory.new
|
||||
|
||||
respond_to do |format|
|
||||
format.html # new.html.erb
|
||||
format.json { render json: @product_category }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /product_categories/1/edit
|
||||
def edit
|
||||
@product_category = ProductCategory.find(params[:id])
|
||||
end
|
||||
|
||||
# POST /product_categories
|
||||
# POST /product_categories.json
|
||||
def create
|
||||
@product_category = ProductCategory.new(params[:product_category])
|
||||
@product_category.supplier = current_supplier
|
||||
|
||||
respond_to do |format|
|
||||
if @product_category.save
|
||||
format.html { redirect_to [:suppliers, @product_category], notice: t('action.create.successfull', model: ProductCategory.model_name.human) }
|
||||
format.json { render json: @product_category, status: :created, location: @product_category }
|
||||
else
|
||||
format.html { render action: "new" }
|
||||
format.json { render json: @product_category.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# PUT /product_categories/1
|
||||
# PUT /product_categories/1.json
|
||||
def update
|
||||
@product_category = ProductCategory.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
if @product_category.update_attributes(params[:product_category])
|
||||
format.html { redirect_to [:suppliers, @product_category], notice: t('action.update.successfull', model: ProductCategory.model_name.human) }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
format.html { render action: "edit" }
|
||||
format.json { render json: @product_category.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /product_categories/1
|
||||
# DELETE /product_categories/1.json
|
||||
def destroy
|
||||
@product_category = ProductCategory.find(params[:id])
|
||||
@product_category.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to suppliers_product_categories_url, notice: t('action.destroy.successfull', model: ProductCategory.model_name.human) }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,88 @@
|
||||
module Suppliers
|
||||
class ProductsController < Suppliers::ApplicationController
|
||||
|
||||
# GET /products
|
||||
# GET /products.json
|
||||
def index
|
||||
@products = current_supplier.products
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
format.json { render json: @products }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /products/1
|
||||
# GET /products/1.json
|
||||
def show
|
||||
@product = Product.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
format.json { render json: @product }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /products/new
|
||||
# GET /products/new.json
|
||||
def new
|
||||
@product = Product.new
|
||||
@product.product_category_id = params[:product_category_id].presence
|
||||
|
||||
respond_to do |format|
|
||||
format.html # new.html.erb
|
||||
format.json { render json: @product }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /products/1/edit
|
||||
def edit
|
||||
@product = Product.find(params[:id])
|
||||
end
|
||||
|
||||
# POST /products
|
||||
# POST /products.json
|
||||
def create
|
||||
@product = Product.new(params[:product])
|
||||
@product.supplier = current_supplier
|
||||
|
||||
respond_to do |format|
|
||||
if @product.save
|
||||
format.html { redirect_to [:suppliers, @product], notice: t('action.create.successfull', model: Product.model_name.human) }
|
||||
format.json { render json: @product, status: :created, location: @product }
|
||||
else
|
||||
format.html { render action: "new" }
|
||||
format.json { render json: @product.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# PUT /products/1
|
||||
# PUT /products/1.json
|
||||
def update
|
||||
@product = Product.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
if @product.update_attributes(params[:product])
|
||||
format.html { redirect_to [:suppliers, @product], notice: t('action.update.successfull', model: Product.model_name.human) }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
format.html { render action: "edit" }
|
||||
format.json { render json: @product.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /products/1
|
||||
# DELETE /products/1.json
|
||||
def destroy
|
||||
@product = Product.find(params[:id])
|
||||
@product.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to suppliers_products_url, notice: t('action.destroy.successfull', model: Product.model_name.human) }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -82,19 +82,6 @@ class TablesController < ApplicationController
|
||||
end
|
||||
end
|
||||
|
||||
# GET /tables/qrcode
|
||||
# GET /tables/qrcode.png
|
||||
# GET /tables/qrcode.svg
|
||||
def qrcode
|
||||
@table = Table.find(params[:id])
|
||||
code = @table.id
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.svg { render :qrcode => code, :level => :l, :unit => 10 }
|
||||
format.png { render qrcode: code }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_relation_options
|
||||
|
||||
@@ -9,6 +9,7 @@ class UserController < ApplicationController
|
||||
end
|
||||
|
||||
# POST /user/create_list {table_id: 1234}
|
||||
#DEPRICATED
|
||||
def create_list
|
||||
@table = Table.find(params[:table_id])
|
||||
if @table.occupied?
|
||||
@@ -17,11 +18,8 @@ class UserController < ApplicationController
|
||||
format.json { render json: js_alert(t('messages.table_is_occupied'))}
|
||||
end
|
||||
else
|
||||
@list = List.new(table: @table, supplier_id: @table.supplier_id)
|
||||
@list.add_user current_user
|
||||
#@list.add_user(current_user)
|
||||
@list.save
|
||||
session[:active_list_id] = @list.id
|
||||
if @list = List.from_table( @table, current_user )
|
||||
end
|
||||
respond_to do |format|
|
||||
format.html { redirect_to user_list_products_path }
|
||||
format.json { render json: js_notice('table_created')}
|
||||
@@ -31,9 +29,15 @@ class UserController < ApplicationController
|
||||
|
||||
def table_info
|
||||
@table = Table.find(params[:table_id])
|
||||
res = {}
|
||||
res[:ocupied] = @table.occupied?
|
||||
if list.present?
|
||||
res[:other_supplier] = true if list.supplier_id != @table.supplier_id
|
||||
res[:current_table_id] = list.table_id
|
||||
end
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
render json: {occupied: @table.occupied?}
|
||||
render json: res
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -56,6 +60,22 @@ class UserController < ApplicationController
|
||||
end
|
||||
end
|
||||
|
||||
def list_products_for_table
|
||||
@table = Table.find(params[:table_id])
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
render layout: 'phone'
|
||||
end
|
||||
format.json do
|
||||
products = @table.supplier.products
|
||||
products.include_relation(:product_categories)
|
||||
products.sort_by!{|p| p.product_category.try(:position) || 90000}
|
||||
h = products.inject({}){|h, p| n = p.product_category.try(:name) || 'other'; h[n] ||= []; h[n] << p; h}
|
||||
render json: h
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# GET /user/current_list.json
|
||||
# Information about the currently active list
|
||||
# This information includes detailed order information
|
||||
@@ -97,7 +117,7 @@ class UserController < ApplicationController
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
if !list.try(:active?)
|
||||
session[:active_list_id] = nil
|
||||
current_user.list_is_closed!
|
||||
render json: {list_active: false}
|
||||
return
|
||||
else
|
||||
@@ -144,8 +164,8 @@ class UserController < ApplicationController
|
||||
# GET /user/list_history/:list_id
|
||||
def history_list
|
||||
@list = List.find(params[:list_id])
|
||||
if params[:list_closed].present? && session[:active_list_id] == @list.id
|
||||
session[:active_list_id] = nil
|
||||
if params[:list_closed].present? && current_user.active_list_id == @list.id
|
||||
current_user.list_is_closed!
|
||||
flash.now[:notice] = t('messages.the_list_has_been_closed', list: List.model_name.human)
|
||||
end
|
||||
redirect_to user_root_path, alert: t('messages.illegal_history_list_attempt') and return unless @list.user_ids.include?(current_user.id)
|
||||
@@ -154,7 +174,19 @@ class UserController < ApplicationController
|
||||
|
||||
|
||||
def order_selected_products
|
||||
@list = list
|
||||
if list.present?
|
||||
@list = list
|
||||
else
|
||||
@table = Table.find(params[:table_id])
|
||||
if @table.occupied?
|
||||
#TODO handle placint order on occupied table
|
||||
else
|
||||
if @list = List.from_table( @table, current_user )
|
||||
else
|
||||
#TODO handle second list creation for user
|
||||
end
|
||||
end
|
||||
end
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
redirect_to(root_path, alert: t('messages.cannot_order_on_non_active_list')) and return unless @list.active?
|
||||
@@ -168,4 +200,14 @@ class UserController < ApplicationController
|
||||
end
|
||||
end
|
||||
end
|
||||
def move_table
|
||||
return unless list.present?
|
||||
@table = Table.find(params[:table_id])
|
||||
if @table.occupied?
|
||||
render json: {occupied: true}
|
||||
else
|
||||
list.move_to_table @table
|
||||
render json: {occupied: false}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -26,8 +26,28 @@ module ApplicationHelper
|
||||
'Qwaiter'
|
||||
end
|
||||
|
||||
# Helper for displaying HTML currency values
|
||||
def currency(amount, opts={})
|
||||
amount ||= 0.0
|
||||
amount = amount.to_f
|
||||
#prefix = case company.currency
|
||||
# when 'GBP' then '£ '
|
||||
# when 'USD' then '$ '
|
||||
# else '€ '
|
||||
# end
|
||||
prefix = '€ '
|
||||
return (prefix + ("%.2f" % amount)).html_safe
|
||||
|
||||
# Rails native is ambiguous since is uses translation hashes
|
||||
options = {:unit => '€'}.merge(opts)
|
||||
number_to_currency(amount, options)
|
||||
end
|
||||
def list_open?
|
||||
session[:active_list_id].present?
|
||||
active_list_id.present?
|
||||
end
|
||||
|
||||
def active_list_id
|
||||
current_user.try(:active_list_id)
|
||||
end
|
||||
|
||||
def no_content_given(model)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
class Administrator
|
||||
include SimplyStored::Couch
|
||||
include Devise::Orm::SimplyStored
|
||||
devise :database_authenticatable, :rememberable #, :recoverable, :rememberable, :trackable, :registerable
|
||||
end
|
||||
@@ -8,6 +8,7 @@ class List
|
||||
has_many :orders, dependent: :destroy
|
||||
belongs_to :table
|
||||
belongs_to :supplier
|
||||
belongs_to :section
|
||||
has_and_belongs_to_many :users, storing_keys: true
|
||||
|
||||
validates :table_id, presence: true
|
||||
@@ -15,6 +16,16 @@ class List
|
||||
|
||||
view :by_supplier_id_and_id, key: [:supplier_id, :_id]
|
||||
|
||||
def self.from_table table, user
|
||||
return if user.has_active_list?
|
||||
list = new table: table, supplier_id: table.supplier_id, section_id: table.section_id
|
||||
list.add_user user
|
||||
list.save
|
||||
user.active_list_id = list.id
|
||||
user.save
|
||||
list
|
||||
end
|
||||
|
||||
def close!
|
||||
orders.map(&:close!)
|
||||
self.state = 'closed'
|
||||
@@ -48,6 +59,13 @@ class List
|
||||
@order
|
||||
end
|
||||
|
||||
def move_to_table to_table
|
||||
TableMove.create list: self, from_table_id: table_id, to_table: to_table
|
||||
self.table = to_table
|
||||
self.section_id = to_table.section_id
|
||||
save
|
||||
end
|
||||
|
||||
def as_json
|
||||
super.merge(table_number: table_number)
|
||||
end
|
||||
|
||||
@@ -6,6 +6,7 @@ class Order
|
||||
belongs_to :list
|
||||
belongs_to :user
|
||||
belongs_to :supplier
|
||||
belongs_to :section
|
||||
|
||||
has_many :product_orders, dependent: :destroy
|
||||
#has_many :products, through: :product_orders
|
||||
|
||||
@@ -7,6 +7,8 @@ class ProductCategory
|
||||
belongs_to :supplier
|
||||
has_many :products
|
||||
|
||||
attr_protected :supplier_id
|
||||
|
||||
validates :position, numericality: true
|
||||
validates :supplier_id, presence: true
|
||||
end
|
||||
|
||||
@@ -7,6 +7,8 @@ class Section
|
||||
|
||||
belongs_to :supplier
|
||||
has_many :tables
|
||||
has_many :lists
|
||||
has_many :orders
|
||||
|
||||
attr_protected :supplier_id
|
||||
|
||||
|
||||
+2
-1
@@ -23,7 +23,8 @@ class Table
|
||||
}|, reduce_function: '_sum'
|
||||
|
||||
def occupied?
|
||||
not self.class.database.view(self.class.active_lists(key: id, reduce: true)).zero?
|
||||
return @is_occupied if instance_variable_defined?(:'@is_occupied')
|
||||
@is_occupied = !self.class.database.view(self.class.active_lists(key: id, reduce: true)).zero?
|
||||
end
|
||||
|
||||
def name
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
class TableMove
|
||||
include SimplyStored::Couch
|
||||
belongs_to :list
|
||||
belongs_to :from_table, class_name: 'Table'
|
||||
belongs_to :to_table, class_name: 'Table'
|
||||
end
|
||||
@@ -1,10 +1,21 @@
|
||||
class User
|
||||
include SimplyStored::Couch
|
||||
include Devise::Orm::SimplyStored
|
||||
property :active_list_id
|
||||
|
||||
devise :database_authenticatable, :recoverable, :rememberable, :trackable, :registerable
|
||||
|
||||
has_and_belongs_to_many :lists, storing_keys: false
|
||||
has_many :orders
|
||||
|
||||
validates_uniqueness_of :email
|
||||
|
||||
def list_is_closed!
|
||||
self.active_list_id = nil
|
||||
save
|
||||
end
|
||||
|
||||
def has_active_list?
|
||||
active_list_id.present?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.page-header= title 'Select Qr code'
|
||||
ul#qr-list
|
||||
- for table in @tables
|
||||
li= link_to_function image_tag(url_for(qrcode_table_path(table, format: :png))), %|Quser.actions_for_table('#{table.id}')|
|
||||
li= link_to_function image_tag(url_for(table_qr_image_path(table_id: table.id, format: :png))), %|Quser.actions_for_table({table_id: '#{table.id}'})|
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
doctype html
|
||||
html lang="en"
|
||||
head
|
||||
meta charset="utf-8"
|
||||
meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"
|
||||
meta name="viewport" content="width=device-width, initial-scale=1.0"
|
||||
title= content_for?(:title) ? yield(:title) : application_title
|
||||
= csrf_meta_tags
|
||||
|
||||
/! Le HTML5 shim, for IE6-8 support of HTML elements
|
||||
/[if lt IE 9]
|
||||
= javascript_include_tag "http://html5shim.googlecode.com/svn/trunk/html5.js"
|
||||
= stylesheet_link_tag "application", :media => "all"
|
||||
link href="images/apple-touch-icon-144x144.png" rel="apple-touch-icon-precomposed" sizes="144x144"
|
||||
link href="images/apple-touch-icon-114x114.png" rel="apple-touch-icon-precomposed" sizes="114x114"
|
||||
link href="images/apple-touch-icon-72x72.png" rel="apple-touch-icon-precomposed" sizes="72x72"
|
||||
link href="images/apple-touch-icon.png" rel="apple-touch-icon-precomposed"
|
||||
link href="images/favicon.ico" rel="shortcut icon"
|
||||
|
||||
body
|
||||
.navbar.navbar-fixed-top
|
||||
.navbar-inner
|
||||
.container
|
||||
a.btn.btn-navbar data-target=".nav-collapse" data-toggle="collapse"
|
||||
span.icon-bar
|
||||
span.icon-bar
|
||||
span.icon-bar
|
||||
a.brand href=root_path = application_title
|
||||
.container.nav-collapse
|
||||
ul.nav
|
||||
li= link_to User.model_name.human_plural, users_path
|
||||
li= link_to Supplier.model_name.human_plural, suppliers_path
|
||||
li= link_to Table.model_name.human_plural, tables_path
|
||||
li= link_to Product.model_name.human_plural, products_path
|
||||
li= link_to List.model_name.human_plural, lists_path
|
||||
li= link_to Order.model_name.human_plural, orders_path
|
||||
li= link_to ProductCategory.model_name.human_plural, product_categories_path
|
||||
|
||||
.container
|
||||
|
||||
.content
|
||||
- if flash[:alert].present?
|
||||
.alert.alert-error
|
||||
a.close data-dismiss="alert" ×
|
||||
div= flash[:alert]
|
||||
- if flash[:notice].present?
|
||||
.alert.alert-success
|
||||
a.close data-dismiss="alert" ×
|
||||
div= flash[:notice]
|
||||
.row
|
||||
.span9
|
||||
= yield
|
||||
.span3
|
||||
.well.sidebar-nav
|
||||
h3= application_title
|
||||
ul.nav.nav-list
|
||||
li.nav-header Links
|
||||
li= link_to "Home", root_path
|
||||
li= link_to "Companytools", 'http://www.companytools.nl/'
|
||||
= yield :sidebar
|
||||
|
||||
footer
|
||||
p © Companytools 2012
|
||||
/!
|
||||
Javascripts
|
||||
\==================================================
|
||||
/! Placed at the end of the document so the pages load faster
|
||||
= javascript_include_tag "application"
|
||||
= yield :footer
|
||||
@@ -16,8 +16,6 @@ html lang="en"
|
||||
link href="images/apple-touch-icon-72x72.png" rel="apple-touch-icon-precomposed" sizes="72x72"
|
||||
link href="images/apple-touch-icon.png" rel="apple-touch-icon-precomposed"
|
||||
link href="images/favicon.ico" rel="shortcut icon"
|
||||
javascript:
|
||||
var active_list_id = #{session[:active_list_id] ? "'#{session[:active_list_id]}'" : 'null'};
|
||||
|
||||
body
|
||||
.navbar.navbar-fixed-top
|
||||
@@ -30,13 +28,8 @@ html lang="en"
|
||||
a.brand href=root_path = application_title
|
||||
.container.nav-collapse
|
||||
ul.nav
|
||||
li= link_to User.model_name.human_plural, users_path
|
||||
li= link_to Supplier.model_name.human_plural, suppliers_path
|
||||
li= link_to Table.model_name.human_plural, tables_path
|
||||
li= link_to Product.model_name.human_plural, products_path
|
||||
li= link_to List.model_name.human_plural, lists_path
|
||||
li= link_to Order.model_name.human_plural, orders_path
|
||||
li= link_to ProductCategory.model_name.human_plural, product_categories_path
|
||||
li= link_to User.model_name.human_plural, user_root_path
|
||||
li= link_to Supplier.model_name.human_plural, supplier_root_path
|
||||
|
||||
.container
|
||||
|
||||
|
||||
@@ -18,7 +18,10 @@ html lang="en"
|
||||
link href="images/apple-touch-icon.png" rel="apple-touch-icon-precomposed"
|
||||
link href="images/favicon.ico" rel="shortcut icon"
|
||||
javascript:
|
||||
var active_list_id = #{session[:active_list_id] ? "'#{session[:active_list_id]}'" : 'null'};
|
||||
// Dummy holder when Qmobile object is not supplied by the mobile phone
|
||||
var QMobile = {
|
||||
scanQr: function(){window.location = '/select_qrcode'}
|
||||
}
|
||||
|
||||
body
|
||||
.navbar.navbar-fixed-top
|
||||
@@ -31,8 +34,6 @@ html lang="en"
|
||||
a.brand href=user_root_path = application_title
|
||||
.container.nav-collapse
|
||||
ul.nav#top-navigation-list
|
||||
- if list_open?
|
||||
li= link_to 'Move table', '#'
|
||||
li= link_to 'View history', user_list_history_path
|
||||
|
||||
.container
|
||||
|
||||
@@ -17,8 +17,6 @@ html lang="en"
|
||||
link href="images/apple-touch-icon-72x72.png" rel="apple-touch-icon-precomposed" sizes="72x72"
|
||||
link href="images/apple-touch-icon.png" rel="apple-touch-icon-precomposed"
|
||||
link href="images/favicon.ico" rel="shortcut icon"
|
||||
javascript:
|
||||
var active_list_id = #{session[:active_list_id] ? "'#{session[:active_list_id]}'" : 'null'};
|
||||
|
||||
body
|
||||
.navbar.navbar-fixed-top.navbar-inverse
|
||||
@@ -32,12 +30,20 @@ html lang="en"
|
||||
ul.nav#top-navigation-list
|
||||
li= link_to t('supplier.menu.active_orders', orders: Order.model_name.human_plural), supplier_active_orders_path
|
||||
li= link_to t('supplier.menu.active_lists', lists: List.model_name.human_plural), supplier_active_lists_path
|
||||
li= link_to ProductCategory.model_name.human_plural, suppliers_product_categories_path
|
||||
li= link_to Product.model_name.human_plural, suppliers_products_path
|
||||
li= link_to Section.model_name.human_plural, suppliers_sections_path
|
||||
li= link_to Table.model_name.human_plural, suppliers_tables_path
|
||||
ul.nav.pull-right
|
||||
li.dropdown
|
||||
a.dropdown-toggle href="#" data-toggle="dropdown"
|
||||
= current_supplier.email
|
||||
b.caret
|
||||
ul.dropdown-menu
|
||||
li= link_to 'Logout', destroy_supplier_session_path, method: :delete
|
||||
.container.nav-collapse
|
||||
|
||||
.container
|
||||
|
||||
.content
|
||||
- if flash[:alert].present?
|
||||
.alert.alert-error
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
.control-group class=(@product_category.errors[:supplier_id].any? ? 'error' : nil)
|
||||
= f.label :supplier_id, Supplier.model_name.human, class: 'control-label'
|
||||
.controls
|
||||
= f.select :supplier_id, options_for_select(@suppliers.map{|a| [a.name, a.id]}), include_blank: nil
|
||||
= f.collection_select :supplier_id, @suppliers, :id, :name, include_blank: nil
|
||||
.form-actions
|
||||
= f.submit nil, class: 'btn btn-primary'
|
||||
'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
- model_class = ProductCategory
|
||||
div.page-header= title :index, model_class
|
||||
.page-header= title :index, model_class
|
||||
- if @product_categories.any?
|
||||
table.table.table-striped
|
||||
thead
|
||||
@@ -7,16 +7,16 @@ div.page-header= title :index, model_class
|
||||
th= model_class.human_attribute_name(:name)
|
||||
th= model_class.human_attribute_name(:position)
|
||||
th= Supplier.model_name.human
|
||||
th= model_class.human_attribute_name(:created_at)
|
||||
th=t 'helpers.actions'
|
||||
th.timestamp= model_class.human_attribute_name(:created_at)
|
||||
th.actions=t 'helpers.actions'
|
||||
tbody
|
||||
- @product_categories.each do |product_category|
|
||||
tr
|
||||
td= link_to product_category.name, product_category
|
||||
td.link= link_to product_category.name, product_category
|
||||
td= product_category.position
|
||||
td= link_to_if product_category.supplier.present?, product_category.supplier.try(:name), product_category.supplier
|
||||
td=l product_category.created_at, format: :short
|
||||
td
|
||||
td.link= link_to_if product_category.supplier.present?, product_category.supplier.try(:name), product_category.supplier
|
||||
td.timestamp=l product_category.created_at, format: :short
|
||||
td.actions
|
||||
= link_to t('helpers.links.edit'), [:edit, product_category], class: 'btn btn-mini'
|
||||
'
|
||||
= link_to t("helpers.links.destroy"), product_category, method: :delete, data: {confirm: are_you_sure? }, class: 'btn btn-mini btn-danger'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
- model_class = Product
|
||||
div.page-header= title :index, model_class
|
||||
.page-header= title :index, model_class
|
||||
- if @products.any?
|
||||
table.table.table-striped
|
||||
thead
|
||||
@@ -9,18 +9,18 @@ div.page-header= title :index, model_class
|
||||
th= model_class.human_attribute_name(:price)
|
||||
th= ProductCategory.model_name.human
|
||||
th= Supplier.model_name.human
|
||||
th= model_class.human_attribute_name(:created_at)
|
||||
th=t 'helpers.actions'
|
||||
th.timestamp= model_class.human_attribute_name(:created_at)
|
||||
th.actions=t 'helpers.actions'
|
||||
tbody
|
||||
- @products.each do |product|
|
||||
tr
|
||||
td= link_to product.name, product
|
||||
td.link= link_to product.name, product
|
||||
td= product.code
|
||||
td= product.price
|
||||
td= link_to_if product.product_category.present?, product.product_category.try(:name), product.product_category
|
||||
td= link_to_if product.supplier.present?, product.supplier.try(:name), product.supplier
|
||||
td=l product.created_at, format: :short
|
||||
td
|
||||
td.link= link_to_if product.product_category.present?, product.product_category.try(:name), product.product_category
|
||||
td.link= link_to_if product.supplier.present?, product.supplier.try(:name), product.supplier
|
||||
td.timestamp=l product.created_at, format: :short
|
||||
td.actions
|
||||
= link_to t('helpers.links.edit'), [:edit, product], class: 'btn btn-mini'
|
||||
'
|
||||
= link_to t("helpers.links.destroy"), product, method: :delete, data: {confirm: are_you_sure? }, class: 'btn btn-mini btn-danger'
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
= form_for [:suppliers, @product_category], html: {class: 'form-horizontal' } do |f|
|
||||
= render 'error_messages', target: @product_category
|
||||
.control-group class=(@product_category.errors[:name].any? ? 'error' : nil)
|
||||
= f.label :name, class: 'control-label'
|
||||
.controls
|
||||
= f.text_field :name, class: 'text_field'
|
||||
.control-group class=(@product_category.errors[:position].any? ? 'error' : nil)
|
||||
= f.label :position, class: 'control-label'
|
||||
.controls
|
||||
= f.text_field :position, class: 'text_field'
|
||||
.form-actions
|
||||
= f.submit nil, class: 'btn btn-primary'
|
||||
'
|
||||
= link_to t("helpers.links.cancel"), suppliers_product_categories_path, class: 'btn'
|
||||
@@ -0,0 +1,4 @@
|
||||
- model_class = ProductCategory
|
||||
.page-header
|
||||
= title :edit, model_class
|
||||
= render 'form'
|
||||
@@ -0,0 +1,24 @@
|
||||
- model_class = ProductCategory
|
||||
.page-header= title :index, model_class
|
||||
- if @product_categories.any?
|
||||
table.table.table-striped
|
||||
thead
|
||||
tr
|
||||
th= model_class.human_attribute_name(:name)
|
||||
th= model_class.human_attribute_name(:position)
|
||||
th.timestamp= model_class.human_attribute_name(:created_at)
|
||||
th.actions=t 'helpers.actions'
|
||||
tbody
|
||||
- @product_categories.each do |product_category|
|
||||
tr
|
||||
td.link= link_to product_category.name, [:suppliers, product_category]
|
||||
td= product_category.position
|
||||
td.timestamp=l product_category.created_at, format: :short
|
||||
td.actions
|
||||
= link_to t('helpers.links.edit'), [:edit, :suppliers, product_category], class: 'btn btn-mini'
|
||||
'
|
||||
= link_to t("helpers.links.destroy"), [:suppliers, product_category], method: :delete, data: {confirm: are_you_sure? }, class: 'btn btn-mini btn-danger'
|
||||
- else
|
||||
= no_content_given model_class
|
||||
= link_to t("helpers.links.new"), new_suppliers_product_category_path, class: 'btn btn-primary'
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
- model_class = ProductCategory
|
||||
.page-header
|
||||
= title :new, model_class
|
||||
= render 'form'
|
||||
@@ -0,0 +1,18 @@
|
||||
- model_class = ProductCategory
|
||||
.page-header= title :show, @product_category
|
||||
|
||||
dl.dl-horizontal.show-list
|
||||
dt= model_class.human_attribute_name(:name)
|
||||
dd= @product_category.name
|
||||
dt= model_class.human_attribute_name(:position)
|
||||
dd= @product_category.position
|
||||
|
||||
.form-actions
|
||||
= link_to t("helpers.links.back"), suppliers_product_categories_path, class: 'btn'
|
||||
'
|
||||
= link_to t('helpers.links.edit'), [:edit, :suppliers, @product_category], class: 'btn'
|
||||
'
|
||||
= link_to t("helpers.links.destroy"), [:suppliers, @product_category], method: :delete, data: {confirm: are_you_sure? }, class: 'btn btn-danger'
|
||||
- content_for :row do
|
||||
- @products = @product_category.products
|
||||
= render template: 'suppliers/products/index'
|
||||
@@ -0,0 +1,22 @@
|
||||
= form_for [:suppliers, @product], html: {class: 'form-horizontal' } do |f|
|
||||
= render 'error_messages', target: @product
|
||||
.control-group class=(@product.errors[:name].any? ? 'error' : nil)
|
||||
= f.label :name, class: 'control-label'
|
||||
.controls
|
||||
= f.text_field :name, class: 'text_field'
|
||||
.control-group class=(@product.errors[:code].any? ? 'error' : nil)
|
||||
= f.label :code, class: 'control-label'
|
||||
.controls
|
||||
= f.text_field :code, class: 'text_field'
|
||||
.control-group class=(@product.errors[:price].any? ? 'error' : nil)
|
||||
= f.label :price, class: 'control-label'
|
||||
.controls
|
||||
= f.text_field :price, class: ['text_field', :currency]
|
||||
.control-group class=(@product.errors[:product_category_id].any? ? 'error' : nil)
|
||||
= f.label :product_category_id, ProductCategory.model_name.human, class: 'control-label'
|
||||
.controls
|
||||
= f.collection_select :product_category_id, current_supplier.product_categories, :id, :name, include_blank: ''
|
||||
.form-actions
|
||||
= f.submit nil, class: 'btn btn-primary'
|
||||
'
|
||||
= link_to t("helpers.links.cancel"), suppliers_products_path, class: 'btn'
|
||||
@@ -0,0 +1,4 @@
|
||||
- model_class = Product
|
||||
.page-header
|
||||
= title :edit, model_class
|
||||
= render 'form'
|
||||
@@ -0,0 +1,28 @@
|
||||
- model_class = Product
|
||||
.page-header= title :index, model_class
|
||||
- if @products.any?
|
||||
table.table.table-striped
|
||||
thead
|
||||
tr
|
||||
th= model_class.human_attribute_name(:name)
|
||||
th= model_class.human_attribute_name(:code)
|
||||
th.currency= model_class.human_attribute_name(:price)
|
||||
th= ProductCategory.model_name.human
|
||||
th.timestamp= model_class.human_attribute_name(:created_at)
|
||||
th.actions=t 'helpers.actions'
|
||||
tbody
|
||||
- @products.each do |product|
|
||||
tr
|
||||
td.link= link_to product.name, product
|
||||
td= product.code
|
||||
td.currency=currency product.price
|
||||
td.link= link_to_if product.product_category.present?, product.product_category.try(:name), [:suppliers, product.product_category]
|
||||
td.timestamp=l product.created_at, format: :short
|
||||
td.actions
|
||||
= link_to t('helpers.links.edit'), [:edit, :suppliers, product], class: 'btn btn-mini'
|
||||
'
|
||||
= link_to t("helpers.links.destroy"), [:suppliers, product], method: :delete, data: {confirm: are_you_sure? }, class: 'btn btn-mini btn-danger'
|
||||
- else
|
||||
= no_content_given model_class
|
||||
= link_to t("helpers.links.new"), new_suppliers_product_path(product_category_id: @product_category.try(:id)), class: 'btn btn-primary'
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
- model_class = Product
|
||||
.page-header
|
||||
= title :new, model_class
|
||||
= render 'form'
|
||||
@@ -0,0 +1,20 @@
|
||||
- model_class = Product
|
||||
.page-header= title :show, @product
|
||||
|
||||
dl.dl-horizontal.show-list
|
||||
dt= model_class.human_attribute_name(:name)
|
||||
dd= @product.name
|
||||
dt= model_class.human_attribute_name(:code)
|
||||
dd= @product.code
|
||||
dt= model_class.human_attribute_name(:price)
|
||||
dd= @product.price
|
||||
- if @product.product_category.present?
|
||||
dt= ProductCategory.model_name.human
|
||||
dd= link_to @product.product_category.name, @product.product_category
|
||||
|
||||
.form-actions
|
||||
= link_to t("helpers.links.back"), suppliers_products_path, class: 'btn'
|
||||
'
|
||||
= link_to t('helpers.links.edit'), [:edit, :suppliers, @product], class: 'btn'
|
||||
'
|
||||
= link_to t("helpers.links.destroy"), [:suppliers, @product], method: :delete, data: {confirm: are_you_sure? }, class: 'btn btn-danger'
|
||||
@@ -16,7 +16,8 @@
|
||||
- for table in @section.tables
|
||||
.section-table.hide{ id="section-table-#{table.id}" data-position-x=table.position_x data-position-y=table.position_y data-table-id=table.id}
|
||||
.pull-right.action-button-container
|
||||
= link_to table.number, [:suppliers, table], class: 'btn btn-mini table-number'
|
||||
= link_to :i, [:suppliers, table], class: 'btn btn-mini table-link'
|
||||
.table-number = table.number
|
||||
.span3
|
||||
h3= t('table.has_no_section')
|
||||
.well.section-tables-container.section-tables-inactive
|
||||
@@ -24,7 +25,8 @@
|
||||
.section-table{ id="section-table-#{table.id}" data-position-x=table.position_x data-position-y=table.position_y data-table-id=table.id}
|
||||
.pull-right.action-button-container
|
||||
button.btn.btn-primary.btn-mini onClick="Qsupplier.move_table_to_active_section('#{table.id}')" +
|
||||
= link_to table.number, [:suppliers, table], class: 'btn btn-mini table-number'
|
||||
= link_to :i, [:suppliers, table], class: 'btn btn-mini table-link'
|
||||
.table-number = table.number
|
||||
.clearfix
|
||||
- content_for :footer do
|
||||
javascript:
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
ul.nav.nav-tabs.nav-stacked
|
||||
li
|
||||
button.btn.btn-primary onClick="QMobile.scanQr()" Scan Qr
|
||||
- if list_open?
|
||||
li= link_to 'Place order', user_list_products_path(supplier_id: active_list.supplier.id)
|
||||
li= link_to 'Active list', user_active_list_path
|
||||
- else
|
||||
li= link_to 'Join table with Qr scan', '/select_qrcode'
|
||||
li
|
||||
button.btn.btn-primary onClick="QMobile.scanQr()" Scan Qr
|
||||
li= link_to 'Place order', user_list_products_path
|
||||
li= link_to 'Show active list', user_active_list_path
|
||||
li= link_to 'Subscribe to list', '#'
|
||||
li= link_to 'Check out menu', '#'
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
.page-header= title 'User list history'
|
||||
p Todo
|
||||
ul
|
||||
- for list in @lists
|
||||
li= link_to l(list.created_at, format: :short), user_history_list_path(list_id: list.id)
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
span#list-needs-help-button
|
||||
table#products-table.table.table-striped.table-hover
|
||||
tbody
|
||||
-# content_for :sidebar do
|
||||
table#active-order-table.table.table-striped.hide
|
||||
thead
|
||||
tr
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
.page-header
|
||||
h4= t('user.show_products.title', products: Product.model_name.human_plural)
|
||||
table#products-table.table.table-striped.table-hover
|
||||
tbody
|
||||
table#active-order-table.table.table-striped.hide
|
||||
thead
|
||||
tr
|
||||
th Product
|
||||
th #
|
||||
th.currency Total
|
||||
th
|
||||
tbody
|
||||
tfoot
|
||||
tr
|
||||
td colspan=2
|
||||
button class="btn btn-primary" onClick="Quser.order_selected_products({table_id: '#{@table.id}'})" Bestellen
|
||||
|
|
||||
button class="btn btn btn-warning" onClick="Qrammer.clear_active_list()" Clear
|
||||
td.currency
|
||||
strong#active-order-total
|
||||
td
|
||||
- content_for :footer do
|
||||
javascript:
|
||||
jQuery(function(){
|
||||
Quser.load_table_products('#{@table.id}', #{@table.occupied? ? 'true' : 'false'});
|
||||
})
|
||||
|
||||
@@ -77,3 +77,4 @@ module Qrammer
|
||||
config.assets.version = '1.0'
|
||||
end
|
||||
end
|
||||
require 'rqrcode-rails3'
|
||||
|
||||
@@ -38,6 +38,7 @@ Qrammer::Application.configure do
|
||||
|
||||
# Do not compress assets
|
||||
config.assets.compress = false
|
||||
config.assets.logger = Logger.new('/dev/null')
|
||||
|
||||
# Expands the lines which load the assets
|
||||
config.assets.debug = true
|
||||
|
||||
@@ -191,7 +191,7 @@ Devise.setup do |config|
|
||||
# Configure sign_out behavior.
|
||||
# Sign_out action can be scoped (i.e. /users/sign_out affects only :user scope).
|
||||
# The default is true, which means any logout action will sign out all active scopes.
|
||||
# config.sign_out_all_scopes = true
|
||||
config.sign_out_all_scopes = false
|
||||
|
||||
# ==> Navigation configuration
|
||||
# Lists the formats that should be treated as navigational. Formats like
|
||||
@@ -205,7 +205,7 @@ Devise.setup do |config|
|
||||
# config.navigational_formats = ["*/*", :html]
|
||||
|
||||
# The default HTTP method used to sign out a resource. Default is :delete.
|
||||
config.sign_out_via = :delete
|
||||
config.sign_out_via = [:delete, :get]
|
||||
|
||||
# ==> OmniAuth
|
||||
# Add a new OmniAuth provider. Check the wiki for more information on setting
|
||||
|
||||
+13
-8
@@ -1,13 +1,11 @@
|
||||
Qrammer::Application.routes.draw do
|
||||
devise_for :users
|
||||
devise_for :suppliers
|
||||
authenticate :supplier do
|
||||
devise_for :administrators
|
||||
|
||||
#authenticate :administrator do
|
||||
resources :users
|
||||
resources :tables do
|
||||
member do
|
||||
get :qrcode
|
||||
end
|
||||
end
|
||||
resources :tables
|
||||
resources :orders do
|
||||
member do
|
||||
post :is_being_processed
|
||||
@@ -18,7 +16,7 @@ Qrammer::Application.routes.draw do
|
||||
resources :lists
|
||||
resources :products
|
||||
resources :product_categories
|
||||
end
|
||||
#end
|
||||
|
||||
get '/supplier' => 'supplier#home', as: :supplier_root
|
||||
get '/supplier/active_orders' => 'supplier#active_orders', as: :supplier_active_orders
|
||||
@@ -38,9 +36,11 @@ Qrammer::Application.routes.draw do
|
||||
post '/user/list_needs_payment' => 'user#list_needs_payment', as: :user_list_needs_payment
|
||||
match '/user/create_list' => 'user#create_list', as: :user_create_list
|
||||
get '/user/list_products' => 'user#list_products', as: :user_list_products
|
||||
get '/user/list_products_for_table' => 'user#list_products_for_table', as: :user_list_products_for_table
|
||||
match '/user/list_history' => 'user#list_history', as: :user_list_history
|
||||
match '/user/list_history/:list_id' => 'user#history_list', as: :user_history_list
|
||||
post '/user/order_selected_products' => 'user#order_selected_products', as: :user_order_selected_products
|
||||
post '/user/move_table' => 'user#move_table', as: :user_move_table
|
||||
get '/user/table_info' => 'user#table_info', as: :user_table_info
|
||||
|
||||
match '/show_products' => 'dashboard#show_products', as: :user_products
|
||||
@@ -48,10 +48,15 @@ Qrammer::Application.routes.draw do
|
||||
namespace :suppliers, path: '/supplier' do
|
||||
resources :sections
|
||||
resources :tables
|
||||
resources :products
|
||||
resources :product_categories
|
||||
root to: 'sections#index'
|
||||
end
|
||||
|
||||
match "/:action", controller: 'dashboard'
|
||||
#DEMO & DEVELOPMENT
|
||||
get '/select_qrcode' => 'dashboard#select_qrcode'
|
||||
get '/table_qr_image' => 'dashboard#table_qr_image', as: :table_qr_image
|
||||
#match "/:action", controller: 'dashboard'
|
||||
|
||||
# The priority is based upon order of creation:
|
||||
# first created -> highest priority.
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
require 'action_controller'
|
||||
require 'rqrcode'
|
||||
require 'rqrcode-rails3/size_calculator.rb'
|
||||
require 'rqrcode-rails3/renderers/svg.rb'
|
||||
|
||||
module RQRCode
|
||||
Mime::Type.register "image/svg+xml", :svg unless Mime::Type.lookup_by_extension(:svg)
|
||||
Mime::Type.register "image/png", :png unless Mime::Type.lookup_by_extension(:png)
|
||||
|
||||
extend SizeCalculator
|
||||
|
||||
ActionController::Renderers.add :qrcode do |string, options|
|
||||
format = self.request.format.symbol
|
||||
size = options[:size] || RQRCode.minimum_qr_size_from_string(string)
|
||||
level = options[:level] || :h
|
||||
|
||||
qrcode = RQRCode::QRCode.new(string, :size => size, :level => level)
|
||||
svg = RQRCode::Renderers::SVG::render(qrcode, options)
|
||||
|
||||
data = \
|
||||
if format == :png
|
||||
image = MiniMagick::Image.read(svg) { |i| i.format "svg" }
|
||||
image.format "png"
|
||||
png = image.to_blob
|
||||
else
|
||||
svg
|
||||
end
|
||||
|
||||
self.response_body = render_to_string(:text => data, :template => nil)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,109 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="318.89764"
|
||||
height="318.89764"
|
||||
id="svg2991"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.2 r9819"
|
||||
sodipodi:docname="table_qr_image.svg">
|
||||
<defs
|
||||
id="defs3">
|
||||
<filter
|
||||
id="filter3789"
|
||||
inkscape:label="Cutout"
|
||||
x="0"
|
||||
y="0"
|
||||
width="1"
|
||||
height="1"
|
||||
inkscape:menu="Shadows and Glows"
|
||||
inkscape:menu-tooltip="Drop shadow under the cut-out of the shape"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur3791"
|
||||
in="SourceAlpha"
|
||||
stdDeviation="4.2" />
|
||||
<feOffset
|
||||
id="feOffset3793"
|
||||
dy="5"
|
||||
dx="5"
|
||||
result="result91" />
|
||||
<feComposite
|
||||
id="feComposite3795"
|
||||
in2="result91"
|
||||
operator="out"
|
||||
in="SourceGraphic" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.3773478"
|
||||
inkscape:cx="107.03459"
|
||||
inkscape:cy="78.51279"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="mm"
|
||||
inkscape:window-width="1440"
|
||||
inkscape:window-height="856"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata2995">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,141.73227)">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:semi-expanded;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffb213;fill-opacity:1;stroke:none;font-family:BankGothic Md BT;-inkscape-font-specification:BankGothic Md BT Semi-Expanded"
|
||||
x="80.589668"
|
||||
y="-90.740822"
|
||||
id="text4695"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4697"
|
||||
x="80.589668"
|
||||
y="-90.740822">Qwaiter</tspan></text>
|
||||
<g
|
||||
id="g3838"
|
||||
transform="matrix(0.49177687,0,0,0.49177687,49.419301,-77.511451)">#qrcode
|
||||
</g>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
|
||||
x="277.10553"
|
||||
y="160.40939"
|
||||
id="text3799"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3801"
|
||||
x="277.10553"
|
||||
y="160.40939">#table_number</tspan></text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
@@ -0,0 +1,50 @@
|
||||
module RQRCode
|
||||
module Renderers
|
||||
class SVG
|
||||
class << self
|
||||
# Render the SVG from the qrcode string provided from the RQRCode gem
|
||||
# Options:
|
||||
# offset - Padding around the QR Code (e.g. 10)
|
||||
# unit - How many pixels per module (Default: 11)
|
||||
# fill - Background color (e.g "ffffff" or :white)
|
||||
# color - Foreground color for the code (e.g. "000000" or :black)
|
||||
|
||||
def render(qrcode, options={})
|
||||
offset = options[:offset].to_i || 0
|
||||
color = options[:color] || "000"
|
||||
unit = options[:unit] || 11
|
||||
|
||||
# height and width dependent on offset and QR complexity
|
||||
dimension = (qrcode.module_count*unit) + (2*offset)
|
||||
|
||||
xml_tag = %{<?xml version="1.0" standalone="yes"?>}
|
||||
open_tag = %{<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" width="#{dimension}" height="#{dimension}">}
|
||||
close_tag = "</svg>"
|
||||
|
||||
result = []
|
||||
qrcode.modules.each_index do |c|
|
||||
tmp = []
|
||||
qrcode.modules.each_index do |r|
|
||||
y = c*unit + offset
|
||||
x = r*unit + offset
|
||||
|
||||
next unless qrcode.is_dark(c, r)
|
||||
tmp << %{<rect width="#{unit}" height="#{unit}" x="#{x}" y="#{y}" style="fill:##{color}"/>}
|
||||
end
|
||||
result << tmp.join("\n")
|
||||
end
|
||||
|
||||
if options[:fill]
|
||||
result.unshift %{<rect width="#{dimension}" height="#{dimension}" x="0" y="0" style="fill:##{options[:fill]}"/>}
|
||||
end
|
||||
|
||||
svg = [xml_tag, open_tag, result, close_tag].flatten.join("\n")
|
||||
svg = File.read(File.expand_path('../../qr_container.svg', __FILE__))
|
||||
svg.gsub!(/#table_number/, options[:table_number].to_s)
|
||||
svg.gsub!(/#qrcode/, result.join("\n"))
|
||||
svg
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,40 @@
|
||||
module RQRCode
|
||||
module SizeCalculator
|
||||
# size - seems to follow this logic
|
||||
# # | input | modules
|
||||
# | size | created
|
||||
#-------|-------|--------
|
||||
# 1 | 7 | 21
|
||||
# 2 | 14 | 25 (+4)
|
||||
# 3 | 24 | 29 -
|
||||
# 4 | 34 | 33 -
|
||||
# 5 | 44 | 37 -
|
||||
# 6 | 58 | 41 -
|
||||
# 7 | 64 | 45 -
|
||||
# 8 | 84 | 49 -
|
||||
# 9 | 98 | 53 -
|
||||
# 10 | 119 | 57 -
|
||||
# 11 | 137 | 61 -
|
||||
# 12 | 155 | 65 -
|
||||
# 13 | 177 | 69 -
|
||||
# 14 | 194 | 73 -
|
||||
|
||||
QR_CHAR_SIZE_VS_SIZE = [7, 14, 24, 34, 44, 58, 64, 84, 98, 119, 137, 155, 177, 194]
|
||||
|
||||
def minimum_qr_size_from_string(string)
|
||||
QR_CHAR_SIZE_VS_SIZE.each_with_index do |size, index|
|
||||
return (index + 1) if string.size < size
|
||||
end
|
||||
|
||||
# If it's particularly big, we'll try and create codes until it accepts
|
||||
i = QR_CHAR_SIZE_VS_SIZE.size
|
||||
begin
|
||||
i += 1
|
||||
RQRCode::QRCode.new(string, :size => i)
|
||||
return i
|
||||
rescue RQRCode::QRCodeRunTimeError
|
||||
retry
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2,6 +2,18 @@ Stories:
|
||||
- Person moves to different table
|
||||
- Person tries to create list on occupied table
|
||||
- Person walks away without paying
|
||||
- Person checks out menu through qr scan
|
||||
- Other persion occupies the table by placing an order
|
||||
- Person tries to order something
|
||||
-> Is informed that the table is not occupied
|
||||
-> redirect to user_root_path
|
||||
- Person1 check out the products by scanning the Qr of an empty table
|
||||
- Person2 checks out the products by scanning the Qr of the same table
|
||||
- Person2 places order and gets the list
|
||||
- Person has an active list and creates an order
|
||||
- Supplier closes the list
|
||||
- Person submits order
|
||||
-> Cannot orde on closed list
|
||||
|
||||
Person actions:
|
||||
When list is open:
|
||||
@@ -42,3 +54,21 @@ Wireless wachtwoord via qr code
|
||||
|
||||
|
||||
handle closed list on list update for user list
|
||||
|
||||
Scan qr button:
|
||||
If table is not occupied:
|
||||
- if there is an open list
|
||||
- if the scan is of the same supplier
|
||||
- Offer to move table
|
||||
- else
|
||||
- Cannot perform action with open list
|
||||
- else
|
||||
View menu direct
|
||||
- When order is placed:
|
||||
- create list
|
||||
- add order to list
|
||||
- table is assigned to person (occupied)
|
||||
If table is occupied:
|
||||
- Offer to Join
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user