end of day commit

This commit is contained in:
2012-08-23 18:50:06 +02:00
parent 13dd2bf335
commit 0bae1bcbed
37 changed files with 1157 additions and 83 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 631 B

+458
View File
@@ -0,0 +1,458 @@
<?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:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="128"
height="128"
id="svg2"
version="1.1"
inkscape:version="0.48.2 r9819"
sodipodi:docname="order-check.svg">
<defs
id="defs4">
<linearGradient
inkscape:collect="always"
id="linearGradient3953">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3955" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop3957" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient3927">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3929" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop3931" />
</linearGradient>
<linearGradient
id="linearGradient3871">
<stop
style="stop-color:#424242;stop-opacity:1;"
offset="0"
id="stop3873" />
<stop
id="stop3879"
offset="0.39583334"
style="stop-color:#767676;stop-opacity:1;" />
<stop
style="stop-color:#d5ffd5;stop-opacity:1"
offset="1"
id="stop3875" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3871"
id="linearGradient3877"
x1="8"
y1="73.737183"
x2="86.24353"
y2="2.4637082"
gradientUnits="userSpaceOnUse" />
<filter
inkscape:collect="always"
id="filter3895"
color-interpolation-filters="sRGB">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="1.1"
id="feGaussianBlur3897" />
</filter>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3871"
id="linearGradient3924"
gradientUnits="userSpaceOnUse"
x1="8"
y1="73.737183"
x2="86.24353"
y2="2.4637082" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3927"
id="linearGradient3933"
x1="47.125"
y1="4.515625"
x2="47.125"
y2="79.831711"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3927"
id="linearGradient3947"
gradientUnits="userSpaceOnUse"
x1="47.125"
y1="4.515625"
x2="47.125"
y2="79.831711" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3927"
id="linearGradient3951"
gradientUnits="userSpaceOnUse"
x1="47.125"
y1="4.515625"
x2="47.125"
y2="79.831711" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3953"
id="linearGradient3959"
x1="47.125"
y1="4.515625"
x2="60.753372"
y2="59.765625"
gradientUnits="userSpaceOnUse" />
<filter
inkscape:collect="always"
id="filter3973"
color-interpolation-filters="sRGB">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="0.44890625"
id="feGaussianBlur3975" />
</filter>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3871"
id="linearGradient3982"
gradientUnits="userSpaceOnUse"
x1="8"
y1="73.737183"
x2="86.24353"
y2="2.4637082" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3927"
id="linearGradient3984"
gradientUnits="userSpaceOnUse"
x1="47.125"
y1="4.515625"
x2="47.125"
y2="79.831711" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3953"
id="linearGradient3986"
gradientUnits="userSpaceOnUse"
x1="47.125"
y1="4.515625"
x2="60.753372"
y2="59.765625" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3871"
id="linearGradient3789"
gradientUnits="userSpaceOnUse"
x1="8"
y1="73.737183"
x2="86.24353"
y2="2.4637082" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3927"
id="linearGradient3791"
gradientUnits="userSpaceOnUse"
x1="47.125"
y1="4.515625"
x2="47.125"
y2="79.831711" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3953"
id="linearGradient3793"
gradientUnits="userSpaceOnUse"
x1="47.125"
y1="4.515625"
x2="60.753372"
y2="59.765625" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3871"
id="linearGradient3800"
gradientUnits="userSpaceOnUse"
x1="8"
y1="73.737183"
x2="86.24353"
y2="2.4637082" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3927"
id="linearGradient3802"
gradientUnits="userSpaceOnUse"
x1="47.125"
y1="4.515625"
x2="47.125"
y2="79.831711" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3953"
id="linearGradient3804"
gradientUnits="userSpaceOnUse"
x1="47.125"
y1="4.515625"
x2="60.753372"
y2="59.765625" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3871"
id="linearGradient3815"
gradientUnits="userSpaceOnUse"
x1="8"
y1="73.737183"
x2="86.24353"
y2="2.4637082" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3927"
id="linearGradient3817"
gradientUnits="userSpaceOnUse"
x1="47.125"
y1="4.515625"
x2="47.125"
y2="79.831711" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3953"
id="linearGradient3819"
gradientUnits="userSpaceOnUse"
x1="47.125"
y1="4.515625"
x2="60.753372"
y2="59.765625" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3871"
id="linearGradient3823"
gradientUnits="userSpaceOnUse"
x1="8"
y1="73.737183"
x2="86.24353"
y2="2.4637082"
gradientTransform="matrix(1.0491242,0,0,1.0491242,2.5076726,905.23429)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3871"
id="linearGradient3831"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0491242,0,0,1.0491242,2.5076726,905.23429)"
x1="8"
y1="73.737183"
x2="86.24353"
y2="2.4637082" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3927"
id="linearGradient3833"
gradientUnits="userSpaceOnUse"
x1="47.125"
y1="4.515625"
x2="47.125"
y2="79.831711" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3953"
id="linearGradient3835"
gradientUnits="userSpaceOnUse"
x1="47.125"
y1="4.515625"
x2="60.753372"
y2="59.765625" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3871"
id="linearGradient3839"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0491242,0,0,1.0491242,2.5076726,905.23429)"
x1="8"
y1="73.737183"
x2="86.24353"
y2="2.4637082" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3871"
id="linearGradient3857"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0491242,0,0,1.0491242,2.5076726,905.23429)"
x1="8"
y1="73.737183"
x2="86.24353"
y2="2.4637082" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3927"
id="linearGradient3859"
gradientUnits="userSpaceOnUse"
x1="47.125"
y1="4.515625"
x2="47.125"
y2="79.831711" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3953"
id="linearGradient3861"
gradientUnits="userSpaceOnUse"
x1="47.125"
y1="4.515625"
x2="60.753372"
y2="59.765625" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3871"
id="linearGradient3872"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0491242,0,0,1.0491242,2.5076726,905.23429)"
x1="8"
y1="73.737183"
x2="86.24353"
y2="2.4637082" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3927"
id="linearGradient3874"
gradientUnits="userSpaceOnUse"
x1="47.125"
y1="4.515625"
x2="47.125"
y2="79.831711" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3953"
id="linearGradient3876"
gradientUnits="userSpaceOnUse"
x1="47.125"
y1="4.515625"
x2="60.753372"
y2="59.765625" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3871"
id="linearGradient3880"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0491242,0,0,1.0491242,2.5076726,905.23429)"
x1="8"
y1="73.737183"
x2="86.24353"
y2="2.4637082" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3871"
id="linearGradient3891"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0491242,0,0,1.0491242,2.5076726,905.23429)"
x1="8"
y1="73.737183"
x2="86.24353"
y2="2.4637082" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="4.6911765"
inkscape:cx="50.233542"
inkscape:cy="13.840125"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1436"
inkscape:window-height="856"
inkscape:window-x="4"
inkscape:window-y="0"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid2994"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata7">
<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></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-924.36217)">
<g
id="g3883"
transform="translate(-0.85266458,-1.9184948)"
inkscape:export-filename="/Users/bterkuile/companytools/development/rails/qrammer/app/assets/images/icons/order-check.png"
inkscape:export-xdpi="24.829473"
inkscape:export-ydpi="24.829473">
<path
transform="matrix(1.0491242,0,0,1.0491242,2.5076726,905.23429)"
style="opacity:0.65158374;fill:#000000;fill-opacity:1;stroke:none;filter:url(#filter3895)"
d="m 20,42.362183 10,10 30,-30 10,10 -40,40 -20,-20 z"
id="path3881"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" />
<path
sodipodi:nodetypes="ccccccc"
inkscape:connector-curvature="0"
id="path2996"
d="M 23.490157,949.67748 33.981399,960.16872 65.455125,928.695 75.946367,939.18624 33.981399,981.15121 12.998915,960.16872 z"
style="fill:url(#linearGradient3891);fill-opacity:1;stroke:none" />
</g>
<path
sodipodi:type="inkscape:offset"
inkscape:radius="-0.79549515"
inkscape:original="M 60 22.375 L 30.25 52.125 C 31.759428 51.832546 33.268641 51.520491 34.78125 51.25 C 38.131586 50.650878 42.292564 50.001114 45.65625 49.5625 C 48.40866 49.203595 50.940177 48.935357 53.59375 48.78125 L 70 32.375 L 60 22.375 z M 20 42.375 L 10 52.375 L 14.03125 56.40625 C 19.237958 54.881463 24.442107 53.235169 29.78125 52.21875 C 29.80132 52.21495 29.82368 52.22255 29.84375 52.21875 L 20 42.375 z "
style="fill:url(#linearGradient3859);fill-opacity:1;stroke:url(#linearGradient3861);stroke-width:0.26578051;filter:url(#filter3973)"
id="path3949"
d="M 60,23.5 32.65625,50.84375 c 0.663739,-0.129711 1.331286,-0.255418 2,-0.375 3.364578,-0.601669 7.526087,-1.246737 10.90625,-1.6875 2.645343,-0.344944 5.103246,-0.59175 7.65625,-0.75 L 68.875,32.375 60,23.5 z m -40,20 -8.875,8.875 3.15625,3.15625 C 18.877656,54.179274 23.499328,52.749738 28.25,51.75 L 20,43.5 z" />
<use
x="0"
y="0"
xlink:href="#g3883"
id="use3887"
transform="translate(20.677116,67.573668)"
width="128"
height="128"
inkscape:export-filename="/Users/bterkuile/companytools/development/rails/qrammer/app/assets/images/icons/order-doublecheck.png"
inkscape:export-xdpi="24.829473"
inkscape:export-ydpi="24.829473" />
<use
x="0"
y="0"
xlink:href="#g3883"
id="use3893"
transform="translate(-10.231975,67.573668)"
width="128"
height="128"
inkscape:export-filename="/Users/bterkuile/companytools/development/rails/qrammer/app/assets/images/icons/order-doublecheck.png"
inkscape:export-xdpi="24.829473"
inkscape:export-ydpi="24.829473" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

+3 -1
View File
@@ -13,4 +13,6 @@
//= require jquery
//= require jquery_ujs
//= require twitter/bootstrap
//= require_tree .
//= require_directory .
//= require_self
+99 -1
View File
@@ -26,6 +26,101 @@ root.Qrammer =
window.active_list[product._id].number += 1
Qrammer.build_product_list()
build_product_list: ->
table = $('#active-order-table')
tbody = table.find('tbody')
tbody = $('<tbody></tbody>').appendTo(table) unless tbody.length
tbody.find('tr').remove()
total = 0.0
for product_id, info of window.active_list
total += info.product.price * info.number
row = $('<tr></tr>').attr('id', 'active-order-row-'+product_id).appendTo(tbody)
row.append('<td>'+info.product.name+'</td>')
row.append('<td>'+info.number+'</td>')
row.append('<td class="currency">'+Qrammer.currency(info.product.price * info.number)+'</td>')
x_btn = $('<button class="btn btn-warning btn-mini">x</button>').click(-> delete(window.active_list[product_id]) && Qrammer.build_product_list() )
row.append($('<td></td>').append(x_btn))
$('#active-order-total').html(Qrammer.currency(total))
table.show()
clear_active_list: ->
window.active_list = {}
$('#active-order-table').hide()
order_active_list: (post_uri)->
h = {list_id: active_list_id}
for product_id, info of window.active_list
h['products['+product_id+']'] = info.number
$.post(post_uri, h, ((res) -> Qrammer.handle_response(res)), 'json')
handle_response: (res) ->
if(typeof(res) == 'string')
return unless res.length
if res[0] == '{'
res = JSON.parse(res)
else
eval(res)
return
alert(res['message']) if res['message'] && !res['ok']
alert(res['message']) if res['message'] && res['ok']
load_active_order_list: (supplier_id) ->
$.get('/suppliers/'+supplier_id+'/active_order_list.json', (res) ->
body = $('#active-orders-table tbody')
body.find('tr').remove()
foot = $('#active-orders-table tfoot')
if(!res.orders && !res.orders.length)
alert('No orders in list');
return;
for order in res.orders
order_txts = []
row = $('<tr></tr>').appendTo(body)
process_btn = $('<button class="btn btn-success">In process!</button>')
process_callback = ( (ord) ->
->
my_btn = $(this)
$.post('/orders/'+ord.id+'/is_being_processed', {}, (res)-> my_btn.remove())
)(order)
process_btn.click(process_callback)
delivered_btn = $('<button class="btn btn-inverse">Is delivered!</button>')
delivered_callback = ( (ord, r) ->
->
my_btn = $(this)
$.post('/orders/'+ord.id+'/is_delivered', {}, (res)-> r.slideUp('slow'))
)(order, row)
delivered_btn.click(delivered_callback)
for product in order.products
order_txts.push(product.name + ' (' + product['number'] + ')')
row.append($('<td></td>').text(order_txts.join(', ')))
row.append($('<td class="numeric"></td>').text(order.table_number))
row.append($('<td class="currency"></td>').html(Qrammer.currency(order.total_amount)))
td_buttons = $('<td class="actions"></td>')
td_buttons.append(process_btn).append('&nbsp;') if order.state == 'placed'
td_buttons.append(delivered_btn)
row.append(td_buttons)
#foot.append('<tr><td></td><td class="currency"><strong>'+Qrammer.currency(res.total_amount)+'</strong></td></tr>');
)
load_active_lists: (supplier_id) ->
$.get('/suppliers/'+supplier_id+'/active_lists.json', (res) ->
body = $('#active-lists-table tbody')
body.find('tr').remove()
foot = $('#active-lists-table tfoot')
for list in res.lists
order_txts = []
row = $('<tr></tr>').appendTo(body)
close_btn = $('<button class="btn btn-success">Close!</button>')
close_callback = ( (lst, r) ->
->
my_btn = $(this)
$.post('/lists/'+lst._id+'/is_closed', {}, (res)-> r.slideUp('slow'))
)(list, row)
close_btn.click(close_callback)
row.append($('<td></td>').text(list._id))
row.append($('<td class="currency"></td>').html(Qrammer.currency(list.total_amount)))
td_buttons = $('<td class="actions"></td>')
td_buttons.append(close_btn)
row.append(td_buttons)
#foot.append('<tr><td></td><td class="currency"><strong>'+Qrammer.currency(res.total_amount)+'</strong></td></tr>');
)
build_product_list_as_modal: ->
wrapper = $('<div class="modal"></div>')
callback_wrapper = ->
wrapper.modal('hide')
@@ -50,4 +145,7 @@ root.Qrammer =
.append($('<a href="#" class="btn btn-primary">Yes</a>').click(callback_wrapper))
.appendTo(wrapper)
wrapper.modal()
jQuery.ajaxSetup
'beforeSend': (xhr) ->
xhr.setRequestHeader("Accept", "text/javascript")
+33
View File
@@ -0,0 +1,33 @@
table
thead
th
&.currency
text-align: right
tbody
td
&.currency
text-align: right
&.numeric
text-align: right
&.actions
text-align: right
tfoot
td
&.currency
text-align: right
#active-list-table
tbody
tr
td
&:first-child
padding-left: 35px
background-position: 5px center
background-repeat: no-repeat
&.placed
td
&:first-child
background-image: image-url('icons/order-check.png')
&.delivered
td
&:first-child
background-image: image-url('icons/order-doublecheck.png')
+23 -2
View File
@@ -1,10 +1,31 @@
class ApplicationController < ActionController::Base
protect_from_forgery
private
def active_list
List.find(session[:list_id])
def check_active_list_state
if session[:active_list_id]
unless active_list.active?
session[:active_list_id] = nil
redirect_to root_path, alert: t('messages.the_list_has_been_closed')
end
end
end
def active_list
return nil unless session[:active_list_id]
@active_list ||= List.find(session[:active_list_id])
end
def js_alert(message)
{ok: false, message: message}.to_json
end
def js_notice(message)
{ok: true, message: message}.to_json
end
helper_method :active_list
end
+27 -2
View File
@@ -1,5 +1,6 @@
class DashboardController < ApplicationController
before_filter :check_active_list_state, except: :home
def home
end
@@ -17,8 +18,8 @@ class DashboardController < ApplicationController
@list = List.new(table: @table)
#@list.add_user(current_user)
@list.save
session[:list_id] = @list.id
redirect_to root_path
session[:active_list_id] = @list.id
redirect_to action: :show_products
end
end
@@ -27,4 +28,28 @@ class DashboardController < ApplicationController
end
def order_active_list
respond_to do |format|
format.html do
redirect_to(root_path, alert: t('messages.cannot_order_without_list_id')) and return if params[:list_id].blank?
@list = List.find(params[:list_id])
redirect_to(root_path, alert: t('messages.cannot_order_on_non_active_list')) and return unless @list.active?
@list.place_order params[:products]
redirect_to root_path, notice: t('messages.order_is_placed')
end
format.js do
render js: js_alert(t('messages.cannot_order_without_list_id')) and return if params[:list_id].blank?
@list = List.find(params[:list_id])
render js: js_alert(t('messages.cannot_order_on_non_active_list')) and return unless @list.active?
@list.place_order params[:products]
render js: js_notice( t('messages.order_is_placed') )
end
end
end
def view_active_list
redirect_to(root_path, alert: t('messages.there_is_no_list_active')) and return unless session[:active_list_id].present?
end
end
+34
View File
@@ -82,6 +82,40 @@ class ListsController < ApplicationController
end
end
def current
@list = List.find(params[:id])
@list.orders.include_relations(product_orders: :product)
respond_to do |format|
format.json do
h = @list.as_json
h[:orders] = []
list_total = 0.0
for order in @list.orders
ho = {products: []}
order_total = 0.0
for product_order in order.product_orders
order_total += (product_order.amount * product_order.product.price).round(2)
ho[:products] << {name: product_order.product.name, id: product_order.product_id, number: product_order.amount, price: product_order.product.price}
end
ho[:total_amount] = order_total.round(2)
ho[:state] = order.state
list_total += ho[:total_amount]
h[:orders] << ho
end
h[:total_amount] = list_total.round(2)
render json: h
end
end
end
# POST /orders/1/is_delivered
def is_closed
@list = List.find(params[:id])
@list.close!
render nothing: true
end
private
def set_relation_options
+104
View File
@@ -0,0 +1,104 @@
class OrdersController < ApplicationController
before_filter :set_relation_options, only: [:new, :edit, :create, :update]
# GET /orders
# GET /orders.json
def index
@orders = Order.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: @orders }
end
end
# GET /orders/1
# GET /orders/1.json
def show
@order = Order.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @order }
end
end
# GET /orders/new
# GET /orders/new.json
def new
@order = Order.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: @order }
end
end
# GET /orders/1/edit
def edit
@order = Order.find(params[:id])
end
# POST /orders
# POST /orders.json
def create
@order = Order.new(params[:order])
respond_to do |format|
if @order.save
format.html { redirect_to @order, notice: t('action.create.successfull', model: Order.model_name.human) }
format.json { render json: @order, status: :created, location: @order }
else
format.html { render action: "new" }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
end
end
# PUT /orders/1
# PUT /orders/1.json
def update
@order = Order.find(params[:id])
respond_to do |format|
if @order.update_attributes(params[:order])
format.html { redirect_to @order, notice: t('action.update.successfull', model: Order.model_name.human) }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
end
end
# DELETE /orders/1
# DELETE /orders/1.json
def destroy
@order = Order.find(params[:id])
@order.destroy
respond_to do |format|
format.html { redirect_to orders_url, notice: t('action.destroy.successfull', model: Order.model_name.human) }
format.json { head :no_content }
end
end
# POST /orders/1/is_being_processed
def is_being_processed
@order = Order.find(params[:id])
@order.is_being_processed!
render nothing: true
end
# POST /orders/1/is_delivered
def is_delivered
@order = Order.find(params[:id])
@order.is_delivered!
render nothing: true
end
private
def set_relation_options
@lists = List.all
end
end
+52
View File
@@ -98,6 +98,58 @@ class SuppliersController < ApplicationController
end
end
end
# GET /suppliers/1/active_order_list
# GET /suppliers/1/active_order_list.json
def active_order_list
@supplier = Supplier.find(params[:id])
respond_to do |format|
format.html
format.json do
h = @supplier.as_json
h[:orders] = []
list_total = 0.0
for order in @supplier.active_orders
ho = {products: []}
order_total = 0.0
for product_order in order.product_orders
order_total += (product_order.amount * product_order.product.price).round(2)
ho[:products] << {name: product_order.product.name, id: product_order.product_id, number: product_order.amount, price: product_order.product.price}
end
ho[:total_amount] = order_total.round(2)
ho[:state] = order.state
ho[:table_number] = order.table_number
ho[:id] = order.id
list_total += ho[:total_amount]
h[:orders] << ho
end
h[:total_amount] = list_total.round(2)
render json: h
end
end
end
# GET /suppliers/1/active_lists
# GET /suppliers/1/active_lists.json
def active_lists
@supplier = Supplier.find(params[:id])
respond_to do |format|
format.html
format.json do
h = @supplier.as_json
h[:lists] = []
grand_total = 0.0
for list in @supplier.active_lists
hl = list.as_json
hl[:total_amount] = list.orders.inject(0.0){|sum, o| sum + o.product_orders.inject(0.0){|s, po| s + (po.amount * po.product.price).round(2)}}.round(2)
grand_total += hl[:total_amount]
h[:lists] << hl
end
h[:total_amount] = grand_total.round(2)
render json: h
end
end
end
private
def set_relation_options
+1 -1
View File
@@ -19,7 +19,7 @@ module ApplicationHelper
end
def list_open?
session[:list_id].present?
session[:active_list_id].present?
end
def no_content_given(model)
+19 -2
View File
@@ -1,15 +1,18 @@
class List
include SimplyStored::Couch
property :state
property :state, default: 'active' # active, #closed
property :need_help, type: :boolean, default: false
property :needs_payment, type: :boolean, default: false
property :closed_at, type: Time
has_many :orders
has_many :orders, dependent: :destroy
belongs_to :table
has_and_belongs_to_many :users, storing_keys: true
validates :table_id, presence: true
def close!
#TODO: close orders
self.state = 'closed'
self.closed_at = Time.now
save
@@ -18,4 +21,18 @@ class List
def supplier
table.supplier
end
def active?
state == 'active'
end
def place_order(products)
return unless products.any?
@order = Order.create list: self, supplier: supplier
return unless @order.id
products.each do |product_id, number|
number = number.to_i
ProductOrder.create order: @order, product_id: product_id, amount: number if number > 0
end
end
end
+38 -2
View File
@@ -1,9 +1,45 @@
class Order
include SimplyStored::Couch
property :state, default: 'placed' # placed, active, delivered, cancelled
belongs_to :list
belongs_to :user
belongs_to :supplier
has_many :product_orders
has_many :products, through: :product_orders
has_many :product_orders, dependent: :destroy
#has_many :products, through: :product_orders
validates :supplier_id, presence: true
view :active_for_supplier_view, type: :custom, map_function: %[function(doc){
if(doc.ruby_class == 'Order' && (doc.state == 'placed' || doc.state == 'active')){
emit(doc.supplier_id, 1);
}
}], reduce_function: '_sum'
def self.active_for_supplier(supplier_id)
database.view(active_for_supplier_view(key: supplier_id, reduce: false, include_docs: true))
end
def table_number
list.table.number
end
alias table_nr table_number
def placed?
state == 'placed'
end
def active?
state == 'active'
end
def is_being_processed!
self.state = 'active'
save
end
def is_delivered!
self.state = 'delivered'
save
end
end
+4 -1
View File
@@ -1,6 +1,9 @@
class ProductOrder
include SimplyStored::Couch
property :amount, type: Fixnum
belongs_to :product
belongs_to :order
end
+27 -5
View File
@@ -2,9 +2,31 @@ class Supplier
include SimplyStored::Couch
property :name
has_many :lists
has_many :orders, through: :lists
has_many :products
has_many :product_categories
has_many :tables
#has_many :orders, through: :lists
has_many :products, dependent: :destroy
has_many :product_categories, dependent: :destroy
has_many :tables, dependent: :destroy
#has_many :lists, through: :tables
has_many :orders
def active_orders
return @active_orders if @active_orders
@active_orders = Order.active_for_supplier(id)
@active_orders.include_relation(list: :table, product_orders: :order)
@active_orders
end
def active_lists
return @active_lists if @active_lists
@tables ||= active_tables
@tables.include_relation(:lists)
@active_lists = @tables.map(&:lists).flatten.select(&:active?)
@active_lists.include_relations(:table, orders: {product_orders: :product})
end
def active_tables
tables
end
end
+2 -2
View File
@@ -1,14 +1,14 @@
.page-header= title 'Home'
ul.nav.nav-tabs.nav-stacked
- if list_open?
li.active= link_to '&euro; 23,45'.html_safe, '#'
li= link_to 'Place order', '/show_products?supplier_id=' + active_list.supplier.id
li= link_to 'Active list', '#'
li= link_to 'Active list', view_active_list_path
li= link_to 'Request bill', '#'
li= link_to 'I have a question', '#'
- else
li= link_to 'Place order', '/select_qrcode'
li= link_to 'Subscribe to list', '#'
li= link_to 'Check out menu', '#'
ul.nav.nav-tabs.nav-stacked
li= link_to 'View history', '#'
+20 -2
View File
@@ -1,6 +1,24 @@
button onClick='Qrammer.build_product_list()' class='btn btn-inverse'Lijst
table#products-table.table.table-striped.table-hover
tbody
- content_for :sidebar do
table#active-order-table.table.hide
thead
tr
th Product
th #
th.currency Total
th
tbody
tfoot
tr
td colspan=2
button class="btn btn-primary" onClick="Qrammer.order_active_list('/order_active_list')" Bestellen
|&nbsp;
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(){
@@ -8,12 +26,12 @@ table#products-table.table.table-striped.table-hover
window.products = res
body = $('#products-table tbody')
for(var category in window.products){
body.append('<tr><td colspan="3"><h3>'+category+'<h3></td></tr>');
body.append('<tr><td colspan="3"><h4>'+category+'<h4></td></tr>');
var category_ref = window.products[category];
for(var iproduct = 0; iproduct < window.products[category].length; iproduct++){
var product_index = iproduct;
row = $('<tr></tr>');
button = $('<button class="btn btn-primary">Add</button>');
button = $('<button class="btn btn-mini btn-primary">Add</button>');
var callback = (function(ref){
return function(){ Qrammer.add_product(ref[product_index]) }
})(category_ref)
@@ -0,0 +1,37 @@
.page-header
h1 List overview
table#active-list-table.table
thead
tr
th Order
th.currency Price
tbody
tfoot
- content_for :footer do
javascript:
jQuery(function(){
$.get('#{current_list_path(session[:active_list_id], format: :json).html_safe}', function(res){
var body = $('#active-list-table tbody');
var foot = $('#active-list-table tfoot');
if(!res.orders && !res.orders.length){
alert('No orders in list');
return;
}
for(var iorder = 0; iorder < res.orders.length; iorder++){
var order_txts = [];
var order = res.orders[iorder];
var row = $('<tr></tr>').appendTo(body);
row.addClass(order.state);
//if(order.state == 'placed') row.addClass('info');
//if(order.state == 'delivered') row.addClass('success');
if(order.state == 'cancelled') row.addClass('error');
for(var iproduct = 0; iproduct < order.products.length; iproduct++){
var product = order.products[iproduct];
order_txts.push(product.name + ' (' + product['number'] + ')')
}
row.append($('<td></td>').text(order_txts.join(', ')));
row.append($('<td class="currency"></td>').html(Qrammer.currency(res.orders[iorder].total_amount)))
}
foot.append('<tr><td></td><td class="currency"><strong>'+Qrammer.currency(res.total_amount)+'</strong></td></tr>');
})
})
+3
View File
@@ -16,6 +16,8 @@ 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
@@ -56,6 +58,7 @@ html lang="en"
li.nav-header Links
li= link_to "Home", root_path
li= link_to "Companytools", 'http://www.companytools.nl/'
= yield :sidebar
footer
p &copy; Companytools 2012
+14
View File
@@ -0,0 +1,14 @@
= form_for @order, html: {class: 'form-horizontal' } do |f|
= render 'error_messages', target: @order
.control-group class=(@order.errors[:state].any? ? 'error' : nil)
= f.label :state, class: 'control-label'
.controls
= f.text_field :state, class: 'text_field'
.control-group class=(@order.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
.form-actions
= f.submit nil, class: 'btn btn-primary'
'
= link_to t("helpers.links.cancel"), orders_path, class: 'btn'
+4
View File
@@ -0,0 +1,4 @@
- model_class = Order
.page-header
= title :edit, model_class
= render 'form'
+24
View File
@@ -0,0 +1,24 @@
- model_class = Order
div.page-header= title :index, model_class
- if @orders.any?
table.table.table-striped
thead
tr
th= model_class.human_attribute_name(:state)
th= Supplier.model_name.human
th= model_class.human_attribute_name(:created_at)
th=t 'helpers.actions'
tbody
- @orders.each do |order|
tr
td= link_to order.state, order
td= link_to_if order.supplier.present?, order.supplier.try(:name), order.supplier
td=l order.created_at, format: :short
td
= link_to t('helpers.links.edit'), [:edit, order], class: 'btn btn-mini'
'
= link_to t("helpers.links.destroy"), order, 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_order_path, class: 'btn btn-primary'
+4
View File
@@ -0,0 +1,4 @@
- model_class = Order
.page-header
= title :new, model_class
= render 'form'
+16
View File
@@ -0,0 +1,16 @@
- model_class = Order
.page-header= title :show, @order
dl.dl-horizontal.show-list
dt= model_class.human_attribute_name(:state)
dd= @order.state
- if @order.supplier.present?
dt= Supplier.model_name.human
dd= link_to @order.supplier.name, @order.supplier
.form-actions
= link_to t("helpers.links.back"), orders_path, class: 'btn'
'
= link_to t('helpers.links.edit'), [:edit, @order], class: 'btn'
'
= link_to t("helpers.links.destroy"), @order, method: :delete, data: {confirm: are_you_sure? }, class: 'btn btn-danger'
@@ -0,0 +1,15 @@
.page-header= title 'Active lists'
table#active-lists-table.table
thead
tr
th.number Table number
th.currency Price
th.actions
tbody
- content_for :footer do
javascript:
jQuery(function(){
Qrammer.load_active_lists('#{@supplier.id}')
setInterval( "Qrammer.load_active_lists('#{@supplier.id}')", 7500);
});
@@ -0,0 +1,16 @@
.page-header= title 'Active orders'
table#active-orders-table.table
thead
tr
th Order
th.number Table number
th.currency Price
th.actions
tbody
- content_for :footer do
javascript:
jQuery(function(){
Qrammer.load_active_order_list('#{@supplier.id}')
setInterval( "Qrammer.load_active_order_list('#{@supplier.id}')", 7500);
});
+11 -10
View File
@@ -1,41 +1,42 @@
= form_for @user, html: {class: 'form-horizontal' } do |f|
.control-group
= render 'error_messages', target: @user
.control-group class=(@user.errors[:email].any? ? 'error' : nil)
= f.label :email, class: 'control-label'
.controls
= f.text_field :email, class: 'text_field'
.control-group
.control-group class=(@user.errors[:encrypted_password].any? ? 'error' : nil)
= f.label :encrypted_password, class: 'control-label'
.controls
= f.text_field :encrypted_password, class: 'text_field'
.control-group
.control-group class=(@user.errors[:remember_token].any? ? 'error' : nil)
= f.label :remember_token, class: 'control-label'
.controls
= f.text_field :remember_token, class: 'text_field'
.control-group
.control-group class=(@user.errors[:remember_created_at].any? ? 'error' : nil)
= f.label :remember_created_at, class: 'control-label'
.controls
= f.text_field :remember_created_at, class: 'text_field'
.control-group
.control-group class=(@user.errors[:reset_password_token].any? ? 'error' : nil)
= f.label :reset_password_token, class: 'control-label'
.controls
= f.text_field :reset_password_token, class: 'text_field'
.control-group
.control-group class=(@user.errors[:sign_in_count].any? ? 'error' : nil)
= f.label :sign_in_count, class: 'control-label'
.controls
= f.text_field :sign_in_count, class: 'text_field'
.control-group
.control-group class=(@user.errors[:current_sign_in_at].any? ? 'error' : nil)
= f.label :current_sign_in_at, class: 'control-label'
.controls
= f.text_field :current_sign_in_at, class: 'text_field'
.control-group
.control-group class=(@user.errors[:last_sign_in_at].any? ? 'error' : nil)
= f.label :last_sign_in_at, class: 'control-label'
.controls
= f.text_field :last_sign_in_at, class: 'text_field'
.control-group
.control-group class=(@user.errors[:current_sign_in_ip].any? ? 'error' : nil)
= f.label :current_sign_in_ip, class: 'control-label'
.controls
= f.text_field :current_sign_in_ip, class: 'text_field'
.control-group
.control-group class=(@user.errors[:last_sign_in_ip].any? ? 'error' : nil)
= f.label :last_sign_in_ip, class: 'control-label'
.controls
= f.text_field :last_sign_in_ip, class: 'text_field'
+18 -34
View File
@@ -1,38 +1,22 @@
- model_class = User
div class="page-header"= title :index, model_class
table class="table table-striped"
thead
tr
th= model_class.human_attribute_name(:email)
th= model_class.human_attribute_name(:encrypted_password)
th= model_class.human_attribute_name(:remember_token)
th= model_class.human_attribute_name(:remember_created_at)
th= model_class.human_attribute_name(:reset_password_token)
th= model_class.human_attribute_name(:sign_in_count)
th= model_class.human_attribute_name(:current_sign_in_at)
th= model_class.human_attribute_name(:last_sign_in_at)
th= model_class.human_attribute_name(:current_sign_in_ip)
th= model_class.human_attribute_name(:last_sign_in_ip)
th= model_class.human_attribute_name(:created_at)
th=t 'helpers.actions'
tbody
- @users.each do |user|
div.page-header= title :index, model_class
- if @users.any?
table.table.table-striped
thead
tr
td= link_to user.email, user
td= user.encrypted_password
td= user.remember_token
td= user.remember_created_at
td= user.reset_password_token
td= user.sign_in_count
td= user.current_sign_in_at
td= user.last_sign_in_at
td= user.current_sign_in_ip
td= user.last_sign_in_ip
td=l user.created_at, format: :short
td
= link_to t('helpers.links.edit'), [:edit, user], class: 'btn btn-mini'
'
= link_to t("helpers.links.destroy"), user, method: :delete, data: {confirm: are_you_sure? }, class: 'btn btn-mini btn-danger'
th= model_class.human_attribute_name(:email)
th= model_class.human_attribute_name(:created_at)
th=t 'helpers.actions'
tbody
- @users.each do |user|
tr
td= link_to user.email, user
td=l user.created_at, format: :short
td
= link_to t('helpers.links.edit'), [:edit, user], class: 'btn btn-mini'
'
= link_to t("helpers.links.destroy"), user, 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_user_path, class: 'btn btn-primary'
+11 -12
View File
@@ -1,27 +1,26 @@
- model_class = User
.page-header
= title :show, @user
.page-header= title :show, @user
dl.dl-horizontal.show-list
dt= model_class.human_attribute_name(:email) + ':'
dt= model_class.human_attribute_name(:email)
dd= @user.email
dt= model_class.human_attribute_name(:encrypted_password) + ':'
dt= model_class.human_attribute_name(:encrypted_password)
dd= @user.encrypted_password
dt= model_class.human_attribute_name(:remember_token) + ':'
dt= model_class.human_attribute_name(:remember_token)
dd= @user.remember_token
dt= model_class.human_attribute_name(:remember_created_at) + ':'
dt= model_class.human_attribute_name(:remember_created_at)
dd= @user.remember_created_at
dt= model_class.human_attribute_name(:reset_password_token) + ':'
dt= model_class.human_attribute_name(:reset_password_token)
dd= @user.reset_password_token
dt= model_class.human_attribute_name(:sign_in_count) + ':'
dt= model_class.human_attribute_name(:sign_in_count)
dd= @user.sign_in_count
dt= model_class.human_attribute_name(:current_sign_in_at) + ':'
dt= model_class.human_attribute_name(:current_sign_in_at)
dd= @user.current_sign_in_at
dt= model_class.human_attribute_name(:last_sign_in_at) + ':'
dt= model_class.human_attribute_name(:last_sign_in_at)
dd= @user.last_sign_in_at
dt= model_class.human_attribute_name(:current_sign_in_ip) + ':'
dt= model_class.human_attribute_name(:current_sign_in_ip)
dd= @user.current_sign_in_ip
dt= model_class.human_attribute_name(:last_sign_in_ip) + ':'
dt= model_class.human_attribute_name(:last_sign_in_ip)
dd= @user.last_sign_in_ip
.form-actions