[MERGE] point_of_sale, pos_restaurant: some more polish
This commit is contained in:
@@ -4,7 +4,7 @@ import werkzeug.utils
|
||||
|
||||
from openerp import http
|
||||
from openerp.http import request
|
||||
from openerp.addons.web.controllers.main import login_redirect
|
||||
from openerp.addons.web.controllers.main import login_redirect, abort_and_redirect
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -15,6 +15,7 @@ class PosController(http.Controller):
|
||||
def a(self, debug=False, **k):
|
||||
cr, uid, context, session = request.cr, request.uid, request.context, request.session
|
||||
|
||||
# if user not logged in, log him in
|
||||
if not session.uid:
|
||||
return login_redirect()
|
||||
|
||||
@@ -25,3 +26,4 @@ class PosController(http.Controller):
|
||||
PosSession.login(cr, uid, pos_session_ids, context=context)
|
||||
|
||||
return request.render('point_of_sale.index')
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ class pos_config(osv.osv):
|
||||
'iface_print_auto': fields.boolean('Automatic Receipt Printing', help='The receipt will automatically be printed at the end of each order'),
|
||||
'iface_precompute_cash': fields.boolean('Prefill Cash Payment', help='The payment input will behave similarily to bank payment input, and will be prefilled with the exact due amount'),
|
||||
'iface_tax_included': fields.boolean('Include Taxes in Prices', help='The displayed prices will always include all taxes, even if the taxes have been setup differently'),
|
||||
'iface_start_categ_id': fields.many2one('pos.category','Start Category', help='The point of sale will display this product category by default. If no category is specified, all available products will be shown'),
|
||||
'receipt_header': fields.text('Receipt Header',help="A short text that will be inserted as a header in the printed receipt"),
|
||||
'receipt_footer': fields.text('Receipt Footer',help="A short text that will be inserted as a footer in the printed receipt"),
|
||||
'proxy_ip': fields.char('IP Address', help='The hostname or ip address of the hardware proxy, Will be autodetected if left empty', size=45),
|
||||
@@ -93,6 +94,7 @@ class pos_config(osv.osv):
|
||||
'barcode_nomenclature_id': fields.many2one('barcode.nomenclature','Barcodes', help='Defines what kind of barcodes are available and how they are assigned to products, customers and cashiers', required=True),
|
||||
'group_pos_manager_id': fields.many2one('res.groups','Point of Sale Manager Group', help='This field is there to pass the id of the pos manager group to the point of sale client'),
|
||||
'group_pos_user_id': fields.many2one('res.groups','Point of Sale User Group', help='This field is there to pass the id of the pos user group to the point of sale client'),
|
||||
'tip_product_id': fields.many2one('product.product','Tip Product', help="The product used to encode the customer tip. Leave empty if you do not accept tips."),
|
||||
}
|
||||
|
||||
def _check_cash_control(self, cr, uid, ids, context=None):
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,paid,done" statusbar_colors='{"cancel":"red"}'/>
|
||||
</header>
|
||||
<sheet>
|
||||
<group col="4" colspan="4">
|
||||
<group col="4" colspan="4" name="order_fields">
|
||||
<field name="name"/>
|
||||
<field name="date_order"/>
|
||||
<field name="session_id" required="1"/>
|
||||
@@ -699,6 +699,8 @@
|
||||
<field name="iface_vkeyboard" />
|
||||
<field name="iface_invoicing" />
|
||||
<field name="iface_precompute_cash" />
|
||||
<field name="iface_start_categ_id" />
|
||||
<field name="tip_product_id" />
|
||||
</group>
|
||||
<group>
|
||||
<field name="iface_fullscreen" />
|
||||
|
||||
@@ -365,6 +365,11 @@ td {
|
||||
cursor: pointer;
|
||||
min-width: 45px;
|
||||
}
|
||||
|
||||
.pos .order-button:first-child {
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
.pos .order-button.selected{
|
||||
font-weight: 900;
|
||||
background: #EEEEEE;
|
||||
@@ -419,7 +424,7 @@ td {
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
vertical-align: top;
|
||||
margin-left: 8px;
|
||||
margin-left: 0px;
|
||||
overflow: hidden;
|
||||
overflow-x: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
@@ -513,23 +518,29 @@ td {
|
||||
top:0px;
|
||||
bottom:0;
|
||||
border-right: solid 1px #CECBCB;
|
||||
border-right: solid 3px #787878;
|
||||
background: #e2e2e2;
|
||||
}
|
||||
|
||||
.pos .leftpane .pads {
|
||||
background: #F0EEEE;
|
||||
white-space: nowrap;
|
||||
border-top: solid 3px rgb(110, 200, 155);
|
||||
}
|
||||
|
||||
/* ********* The control buttons ********* */
|
||||
|
||||
.pos .control-buttons {
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-webkit-flex-flow: row wrap;
|
||||
flex-flow: row wrap;
|
||||
padding: 8px 13px 0px 11px;
|
||||
padding: 8px 16px 0px 11px;
|
||||
margin-bottom: -6px;
|
||||
}
|
||||
.pos .control-button {
|
||||
flex: 1;
|
||||
-webkit-flex-grow: 1;
|
||||
flex-grow: 1;
|
||||
background: #e2e2e2;
|
||||
border: solid 1px #cacaca;
|
||||
border: solid 1px #bfbfbf;
|
||||
display: inline-block;
|
||||
line-height: 38px;
|
||||
min-width: 80px;
|
||||
@@ -541,22 +552,41 @@ td {
|
||||
margin-bottom: 6px;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
transition: all linear 150ms;
|
||||
}
|
||||
.pos .control-button:hover {
|
||||
background: #efefef;
|
||||
}
|
||||
.pos .control-button:active {
|
||||
background: black;
|
||||
color: white;
|
||||
border-color: black;
|
||||
}
|
||||
.pos .control-button .fa{
|
||||
margin-right: 4px;
|
||||
}
|
||||
.pos .control-button .control-button-number {
|
||||
color: rgb(226, 226, 226);
|
||||
background: rgb(85, 85, 85);
|
||||
display: inline-block;
|
||||
height: 28px;
|
||||
vertical-align: middle;
|
||||
font-weight: bold;
|
||||
line-height: 28px;
|
||||
width: 28px;
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
margin-left: -16px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.pos .control-button.highlight,
|
||||
.pos .button.highlight {
|
||||
background: #6EC89B !important;
|
||||
border: solid 1px #6EC89B !important;
|
||||
/* border: solid 1px #6EC89B !important; */
|
||||
border: solid 1px #64AF8A !important;
|
||||
color: white !important;
|
||||
}
|
||||
.pos .control-button:active {
|
||||
background: #7F82AC;
|
||||
border: solid 1px #7F82AC;
|
||||
color: white;
|
||||
}
|
||||
.pos .control-button.disabled,
|
||||
.pos .control-button.disabled:active{
|
||||
background: #e2e2e2;
|
||||
@@ -569,27 +599,54 @@ td {
|
||||
/* ********* The actionpad (payment, set customer) ********* */
|
||||
|
||||
.pos .actionpad {
|
||||
padding: 8px 3px 8px 19px;
|
||||
display: inline-block;
|
||||
float: left;
|
||||
padding: 0;
|
||||
margin: 16px;
|
||||
margin-top: 8px;
|
||||
margin-right: 0;
|
||||
text-align: center;
|
||||
vertical-align: top;
|
||||
width: 183px;
|
||||
max-height: 350px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
width: 188px;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
border-top: 1px solid;
|
||||
border-left: 1px solid;
|
||||
border-color: #bfbfbf;
|
||||
border-top-left-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
.pos .actionpad .button {
|
||||
height: 50px;
|
||||
display: block;
|
||||
height: 54px;
|
||||
width: 100%;
|
||||
margin: 0px -6px 4px -2px;
|
||||
font-weight: bold;
|
||||
vertical-align: middle;
|
||||
color: #555555;
|
||||
font-size: 14px;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
border-right: 1px solid;
|
||||
border-bottom: 1px solid;
|
||||
border-color: #bfbfbf;
|
||||
transition: all 150ms linear;
|
||||
}
|
||||
.pos .actionpad .button:hover {
|
||||
background: #efefef;
|
||||
}
|
||||
.pos .actionpad .button:active {
|
||||
background: black;
|
||||
border-color: black;
|
||||
color: white;
|
||||
}
|
||||
.pos .actionpad .button:first-child {
|
||||
border-top-left-radius: 4px;
|
||||
}
|
||||
.pos .actionpad .button:last-child {
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
.pos .actionpad .button.pay {
|
||||
height: 158px;
|
||||
height: 162px;
|
||||
}
|
||||
.pos .actionpad .button.pay .fa {
|
||||
display: block;
|
||||
@@ -607,23 +664,46 @@ td {
|
||||
/* ********* The Numpad ********* */
|
||||
|
||||
.pos .numpad {
|
||||
padding: 8px 8px 8px 4px;
|
||||
display: inline-block;
|
||||
float: right;
|
||||
text-align: center;
|
||||
margin: 16px;
|
||||
margin-top: 8px;
|
||||
margin-left: 0px;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
border-top: 1px solid;
|
||||
border-color: #bfbfbf;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
.pos .numpad button {
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
margin: 0px 3px 4px 0px;
|
||||
float: left;
|
||||
height: 54px;
|
||||
width: 54px;
|
||||
font-weight: bold;
|
||||
vertical-align: middle;
|
||||
color: #555555;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
border-right: 1px solid;
|
||||
border-bottom: 1px solid;
|
||||
border-color: #bfbfbf;
|
||||
transition: all 150ms linear;
|
||||
}
|
||||
.pos .numpad button:hover {
|
||||
background: #efefef;
|
||||
}
|
||||
.pos .numpad button:active {
|
||||
background: black;
|
||||
color: white;
|
||||
border-color: transparent;
|
||||
}
|
||||
.pos .numpad button:nth-child(4) {
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
.pos .numpad button:last-child {
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
.pos .input-button {
|
||||
font-size: 24px;
|
||||
}
|
||||
@@ -755,6 +835,7 @@ td {
|
||||
|
||||
.pos .categories {
|
||||
position: relative;
|
||||
border-bottom: solid 3px rgb(110, 200, 155);
|
||||
}
|
||||
.pos .categories h4 {
|
||||
display: inline-block;
|
||||
@@ -810,7 +891,7 @@ td {
|
||||
}
|
||||
.pos .category-simple-button:active{
|
||||
color: white;
|
||||
background: #7f82ac;
|
||||
background: black;
|
||||
|
||||
-webkit-transition-property: background, border;
|
||||
-webkit-transition-duration: 0.2s;
|
||||
@@ -860,9 +941,9 @@ td {
|
||||
display: inline-block;
|
||||
line-height: 100px;
|
||||
font-size: 11px;
|
||||
margin: 5px !important;
|
||||
width: 120px;
|
||||
height:120px;
|
||||
margin: 8px !important;
|
||||
width: 122px;
|
||||
height:115px;
|
||||
background:#fff;
|
||||
border: 1px solid #e2e2e2;
|
||||
border-radius: 3px;
|
||||
@@ -962,6 +1043,14 @@ td {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1024px) {
|
||||
.screen .screen-content{
|
||||
border-left: dashed 1px rgb(215,215,215);
|
||||
border-right: dashed 1px rgb(215,215,215);
|
||||
}
|
||||
}
|
||||
|
||||
.screen .top-content{
|
||||
position: absolute;
|
||||
left: 0px; top: 0px; right: 0px;
|
||||
@@ -980,12 +1069,24 @@ td {
|
||||
border-radius: 3px;
|
||||
border: solid 1px rgb(209, 209, 209);
|
||||
cursor: pointer;
|
||||
transition: all 150ms linear;
|
||||
}
|
||||
.screen .top-content .button.highlight{
|
||||
.screen .top-content .button:hover {
|
||||
background: #efefef;
|
||||
}
|
||||
.screen .top-content .button:active {
|
||||
background: black;
|
||||
border-color: black;
|
||||
color: white;
|
||||
}
|
||||
.screen .top-content .button.highlight {
|
||||
background: rgb(110,200,155);
|
||||
color: white;
|
||||
border: solid 1px rgb(110,200,155);
|
||||
}
|
||||
.screen .top-content .button.highlight:hover {
|
||||
background: rgb(120,210,165);
|
||||
}
|
||||
.screen .top-content .button.back {
|
||||
left: 0px;
|
||||
margin-left: 16px;
|
||||
@@ -1068,14 +1169,31 @@ td {
|
||||
display: inline-block;
|
||||
width: 50%;
|
||||
box-sizing: border-box;
|
||||
padding: 8px;
|
||||
padding: 16px;
|
||||
text-align: center;
|
||||
float: left;
|
||||
}
|
||||
.pos .payment-numpad .numpad button {
|
||||
width: 66px;
|
||||
height: 66px;
|
||||
.pos .payment-numpad .numpad {
|
||||
float: none;
|
||||
border-radius: 4px;
|
||||
border-top: 1px solid;
|
||||
border-left: 1px solid;
|
||||
border-color: #cacaca;
|
||||
width: 296px;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
}
|
||||
.pos .payment-numpad .numpad button {
|
||||
width: 74px;
|
||||
height: 74px;
|
||||
}
|
||||
.pos .payment-numpad .numpad button:first-child {
|
||||
border-top-left-radius: 4px;
|
||||
}
|
||||
.pos .payment-numpad .numpad button:nth-child(16) {
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
|
||||
.pos .paymentlines-container {
|
||||
padding: 16px;
|
||||
padding-top: 0;
|
||||
@@ -1121,6 +1239,11 @@ td {
|
||||
.pos .paymentline .col-change {
|
||||
min-width: 90px;
|
||||
}
|
||||
.pos .paymentline.extra .col-due {
|
||||
border-radius: 0 0 6px 6px;
|
||||
border-top: solid 1px rgb(230, 230, 230);
|
||||
font-weight: bold;
|
||||
}
|
||||
.pos .paymentline .col-change.highlight {
|
||||
background: rgb(184, 152, 204);
|
||||
}
|
||||
@@ -1136,18 +1259,65 @@ td {
|
||||
width: 50%;
|
||||
box-sizing: border-box;
|
||||
padding: 16px;
|
||||
padding-left: 0;
|
||||
float: right;
|
||||
}
|
||||
.payment-screen .payment-buttons .button {
|
||||
background: rgb(220,220,220);
|
||||
line-height: 48px;
|
||||
margin-bottom: 4px;
|
||||
border-radius: 3px;
|
||||
background: #e2e2e2;
|
||||
line-height: 73px;
|
||||
font-size: 16px;
|
||||
padding: 0px 8px;
|
||||
border: solid 1px rgb(200,200,200);
|
||||
border-top-width: 0;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
transition: background-color, border-color, color 150ms linear;
|
||||
}
|
||||
.payment-screen .payment-buttons .button:hover {
|
||||
background-color: #efefef;
|
||||
}
|
||||
.payment-screen .payment-buttons .button:first-child {
|
||||
border-top-left-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
border-top-width: 1px;
|
||||
}
|
||||
.payment-screen .payment-buttons .button:last-child {
|
||||
border-bottom-left-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
}
|
||||
.payment-screen .payment-buttons .button.highlight:not(:first-child) {
|
||||
margin-top: -1px;
|
||||
border-top: solid 1px;
|
||||
}
|
||||
.payment-screen .payment-buttons .button:active {
|
||||
background: black;
|
||||
border-color: black;
|
||||
color: white;
|
||||
}
|
||||
.payment-screen .payment-buttons .button.highlight .fa {
|
||||
border-color: rgba(0, 0, 0, 0.109804);
|
||||
background: rgba(0, 0, 0, 0.0980392);
|
||||
}
|
||||
.payment-screen .payment-buttons .button .fa {
|
||||
position: absolute;
|
||||
left: 11px;
|
||||
top: 50%;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
margin-top: -25px;
|
||||
vertical-align: middle;
|
||||
border-radius: 26px;
|
||||
border: 1px solid rgba(0,0,0,0.2);
|
||||
border-image-source: initial;
|
||||
border-image-slice: initial;
|
||||
border-image-width: initial;
|
||||
border-image-outset: initial;
|
||||
border-image-repeat: initial;
|
||||
background: rgba(255,255,255,0.4);
|
||||
font-size: 20px;
|
||||
transition: all 150ms linear;
|
||||
}
|
||||
.payment-screen .paymentlines-empty .total {
|
||||
text-align: center;
|
||||
@@ -1486,7 +1656,7 @@ td {
|
||||
top: 0px;
|
||||
width:100%;
|
||||
height: 100%;
|
||||
background: #F0EEEE;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.pos .order-scroller{
|
||||
@@ -1505,26 +1675,24 @@ td {
|
||||
|
||||
.pos .order{
|
||||
background: white;
|
||||
padding-bottom:15px;
|
||||
padding-top:15px;
|
||||
margin-left:16px;
|
||||
margin-right:16px;
|
||||
margin-top:16px;
|
||||
margin-bottom:16px;
|
||||
font-size:16px;
|
||||
border-radius: 3px;
|
||||
border: solid 1px rgb(220,220,220);
|
||||
padding-bottom: 8px;
|
||||
padding-top: 8px;
|
||||
font-size: 16px;
|
||||
text-align: left;
|
||||
max-width: 500px;
|
||||
-webkit-transform: translate3d(0,0,0);
|
||||
}
|
||||
|
||||
.pos .order .empty{
|
||||
text-align:center;
|
||||
margin-top: 15px;
|
||||
margin-bottom: 5px;
|
||||
color:#999;
|
||||
font-weight: normal;
|
||||
.pos .order .order-empty {
|
||||
text-align: center;
|
||||
margin: 48px;
|
||||
color: #DDD;
|
||||
}
|
||||
.pos .order .order-empty .fa {
|
||||
font-size: 64px;
|
||||
}
|
||||
.pos .order .order-empty h1 {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.pos .order .summary{
|
||||
@@ -1542,8 +1710,11 @@ td {
|
||||
border-top: solid 2px;
|
||||
border-color:#777;
|
||||
}
|
||||
.pos .order .summary .total {
|
||||
font-size: 22px;
|
||||
}
|
||||
.pos .order .summary .line .subentry{
|
||||
font-size: 14px;
|
||||
font-size: 16px;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
}
|
||||
@@ -1642,6 +1813,21 @@ td {
|
||||
text-shadow: 0px 2px white, 0px 2px 2px rgba(0, 0, 0, 0.27);
|
||||
border-bottom: dashed 1px rgb(215,215,215);
|
||||
}
|
||||
.pos .splitbill-screen .order {
|
||||
background: white;
|
||||
padding-bottom:15px;
|
||||
padding-top:15px;
|
||||
margin-left:16px;
|
||||
margin-right:16px;
|
||||
margin-top:16px;
|
||||
margin-bottom:16px;
|
||||
font-size:16px;
|
||||
border-radius: 3px;
|
||||
border: solid 1px rgb(220,220,220);
|
||||
text-align: left;
|
||||
max-width: 500px;
|
||||
-webkit-transform: translate3d(0,0,0);
|
||||
}
|
||||
.splitbill-screen .order .orderline.selected{
|
||||
background: rgb(110,200,155);
|
||||
color: white;
|
||||
@@ -1661,23 +1847,33 @@ td {
|
||||
font-size: 24px;
|
||||
vertical-align: top;
|
||||
}
|
||||
.splitbill-screen .paymentmethods,
|
||||
.payment-screen .paymentmethods {
|
||||
.paymentmethods {
|
||||
margin: 16px;
|
||||
}
|
||||
.splitbill-screen .paymentmethods .button,
|
||||
.payment-screen .paymentmethods .button {
|
||||
background: rgb(221, 221, 221);
|
||||
line-height: 40px;
|
||||
margin-bottom: 4px;
|
||||
border-radius: 3px;
|
||||
.paymentmethods .button {
|
||||
background: #e2e2e2;
|
||||
line-height: 49px;
|
||||
font-size: 16px;
|
||||
border: solid 1px rgb(202, 202, 202);
|
||||
border-top-width: 0px;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
}
|
||||
.splitbill-screen .paymentmethod.active,
|
||||
.payment-screen .paymentmethod.active {
|
||||
.paymentmethods .button:first-child {
|
||||
border-top-width: 1px;
|
||||
border-top-left-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
}
|
||||
.paymentmethods .button:last-child {
|
||||
border-bottom-left-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
}
|
||||
.paymentmethods .button:active {
|
||||
background: black;
|
||||
border-color: black;
|
||||
color: white;
|
||||
}
|
||||
.paymentmethod .button.active {
|
||||
background: #6EC89B;
|
||||
color: white;
|
||||
border-color: #6EC89B;
|
||||
@@ -1907,8 +2103,8 @@ td {
|
||||
}
|
||||
.pos .popup .button:active{
|
||||
color: white;
|
||||
background: #7f82ac;
|
||||
border: 1px solid #7f82ac;
|
||||
background: black;
|
||||
border: 1px solid black;
|
||||
|
||||
-webkit-transition-property: background, border;
|
||||
-webkit-transition-duration: 0.2s;
|
||||
@@ -1949,6 +2145,9 @@ td {
|
||||
box-sizing: border-box;
|
||||
width: 80%;
|
||||
}
|
||||
.pos .popup-number .popup-input {
|
||||
text-align: center;
|
||||
}
|
||||
.pos .popup input:focus,
|
||||
.pos .popup-input.active {
|
||||
outline: none;
|
||||
@@ -2039,8 +2238,8 @@ td {
|
||||
/* ********* The Webkit Scrollbar ********* */
|
||||
|
||||
.pos *::-webkit-scrollbar{
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
}
|
||||
.pos *::-webkit-scrollbar-track{
|
||||
background: rgb(224,224,224);
|
||||
@@ -2048,6 +2247,7 @@ td {
|
||||
}
|
||||
.pos *::-webkit-scrollbar-thumb{
|
||||
background: rgb(168,168,168);
|
||||
background: #393939;
|
||||
min-height: 30px;
|
||||
}
|
||||
|
||||
|
||||
@@ -157,13 +157,10 @@ openerp.point_of_sale.load_chrome = function load_chrome(instance, module){ //mo
|
||||
'print_receipt',
|
||||
'scale_read',
|
||||
],
|
||||
minimized: false,
|
||||
init: function(parent,options){
|
||||
this._super(parent,options);
|
||||
var self = this;
|
||||
|
||||
this.minimized = false;
|
||||
|
||||
// for dragging the debug widget around
|
||||
this.dragging = false;
|
||||
this.dragpos = {x:0, y:0};
|
||||
@@ -202,8 +199,24 @@ openerp.point_of_sale.load_chrome = function load_chrome(instance, module){ //mo
|
||||
event.stopPropagation();
|
||||
};
|
||||
},
|
||||
show: function() {
|
||||
var self = this;
|
||||
this.$el.css({opacity:0});
|
||||
this.$el.removeClass('oe_hidden');
|
||||
this.$el.animate({opacity:1},250,'swing');
|
||||
},
|
||||
hide: function() {
|
||||
var self = this;
|
||||
this.$el.animate({opacity:0,},250,'swing',function(){
|
||||
self.$el.addClass('oe_hidden');
|
||||
});
|
||||
},
|
||||
start: function(){
|
||||
var self = this;
|
||||
|
||||
if (this.pos.debug) {
|
||||
this.show();
|
||||
}
|
||||
|
||||
this.el.addEventListener('mouseleave', this.dragend_handler);
|
||||
this.el.addEventListener('mouseup', this.dragend_handler);
|
||||
@@ -215,14 +228,7 @@ openerp.point_of_sale.load_chrome = function load_chrome(instance, module){ //mo
|
||||
this.el.addEventListener('touchmove', this.dragmove_handler);
|
||||
|
||||
this.$('.toggle').click(function(){
|
||||
var content = self.$('.content');
|
||||
var bg = self.$el;
|
||||
if(!self.minimized){
|
||||
content.animate({'height':'0'},200);
|
||||
}else{
|
||||
content.css({'height':'auto'});
|
||||
}
|
||||
self.minimized = !self.minimized;
|
||||
self.hide();
|
||||
});
|
||||
this.$('.button.set_weight').click(function(){
|
||||
var kg = Number(self.$('input.weight').val());
|
||||
@@ -409,6 +415,9 @@ openerp.point_of_sale.load_chrome = function load_chrome(instance, module){ //mo
|
||||
this.chrome = this; // So that chrome's childs have chrome set automatically
|
||||
this.pos.gui = this.gui;
|
||||
|
||||
this.logo_click_time = 0;
|
||||
this.logo_click_count = 0;
|
||||
|
||||
this.widget = {}; // contains references to subwidgets instances
|
||||
|
||||
this.cleanup_dom();
|
||||
@@ -437,17 +446,45 @@ openerp.point_of_sale.load_chrome = function load_chrome(instance, module){ //mo
|
||||
},
|
||||
|
||||
build_chrome: function() {
|
||||
var self = this;
|
||||
FastClick.attach(document.body);
|
||||
|
||||
instance.webclient.set_content_full_screen(true);
|
||||
|
||||
this.renderElement();
|
||||
|
||||
this.$('.pos-logo').click(function(){
|
||||
self.click_logo();
|
||||
});
|
||||
|
||||
if(this.pos.config.iface_big_scrollbars){
|
||||
this.$el.addClass('big-scrollbars');
|
||||
}
|
||||
},
|
||||
|
||||
click_logo: function() {
|
||||
if (this.pos.debug) {
|
||||
this.widget.debug.show();
|
||||
} else {
|
||||
var self = this;
|
||||
var time = (new Date()).getTime();
|
||||
var delay = 500;
|
||||
if (this.logo_click_time + 500 < time) {
|
||||
this.logo_click_time = time;
|
||||
this.logo_click_count = 1;
|
||||
} else {
|
||||
this.logo_click_time = time;
|
||||
this.logo_click_count += 1;
|
||||
if (this.logo_click_count >= 6) {
|
||||
this.logo_click_count = 0;
|
||||
this.gui.sudo().then(function(){
|
||||
self.widget.debug.show();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
disable_rubberbanding: function(){
|
||||
// prevent the pos body from being scrollable.
|
||||
document.body.addEventListener('touchmove',function(event){
|
||||
@@ -521,7 +558,6 @@ openerp.point_of_sale.load_chrome = function load_chrome(instance, module){ //mo
|
||||
loading_show: function(){
|
||||
this.$('.loader').removeClass('oe_hidden').animate({opacity:1},150,'swing');
|
||||
},
|
||||
|
||||
widgets: [
|
||||
{
|
||||
'name': 'order_selector',
|
||||
@@ -570,7 +606,6 @@ openerp.point_of_sale.load_chrome = function load_chrome(instance, module){ //mo
|
||||
'name': 'debug',
|
||||
'widget': module.DebugWidget,
|
||||
'append': '.pos-content',
|
||||
'condition': function(){ return this.pos.debug },
|
||||
},
|
||||
],
|
||||
|
||||
|
||||
@@ -1470,6 +1470,33 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo
|
||||
get_last_orderline: function(){
|
||||
return this.orderlines.at(this.orderlines.length -1);
|
||||
},
|
||||
get_tip: function() {
|
||||
var tip_product = this.pos.db.get_product_by_id(this.pos.config.tip_product_id[0]);
|
||||
var lines = this.get_orderlines();
|
||||
if (!tip_product) {
|
||||
return 0;
|
||||
} else {
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
if (lines[i].get_product() === tip_product) {
|
||||
return lines[i].get_unit_price();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
set_tip: function(tip) {
|
||||
var tip_product = this.pos.db.get_product_by_id(this.pos.config.tip_product_id[0]);
|
||||
var lines = this.get_orderlines();
|
||||
if (tip_product) {
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
if (lines[i].get_product() === tip_product) {
|
||||
lines[i].set_unit_price(tip);
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.add_product(tip_product, {quantity: 1, price: tip });
|
||||
}
|
||||
},
|
||||
remove_orderline: function( line ){
|
||||
this.assert_editable();
|
||||
this.orderlines.remove(line);
|
||||
|
||||
@@ -194,7 +194,7 @@ openerp.point_of_sale.load_popups = function load_popups(instance, module) {
|
||||
var self = this;
|
||||
this._super(options);
|
||||
|
||||
this.inputbuffer = options.value || '';
|
||||
this.inputbuffer = '' + options.value || '';
|
||||
this.renderElement();
|
||||
this.firstinput = true;
|
||||
},
|
||||
|
||||
@@ -400,8 +400,7 @@ openerp.point_of_sale.load_screens = function load_screens(instance, module){ //
|
||||
this.pos.bind('change:selectedOrder', this.change_selected_order, this);
|
||||
|
||||
this.line_click_handler = function(event){
|
||||
self.pos.get_order().select_orderline(this.orderline);
|
||||
self.numpad_state.reset();
|
||||
self.click_line(this.orderline, event);
|
||||
};
|
||||
|
||||
if (this.pos.get_order()) {
|
||||
@@ -409,6 +408,10 @@ openerp.point_of_sale.load_screens = function load_screens(instance, module){ //
|
||||
}
|
||||
|
||||
},
|
||||
click_line: function(orderline, event) {
|
||||
this.pos.get_order().select_orderline(orderline);
|
||||
this.numpad_state.reset();
|
||||
},
|
||||
set_value: function(val) {
|
||||
var order = this.pos.get_order();
|
||||
if (order.get_selected_orderline()) {
|
||||
@@ -519,6 +522,10 @@ openerp.point_of_sale.load_screens = function load_screens(instance, module){ //
|
||||
},
|
||||
update_summary: function(){
|
||||
var order = this.pos.get_order();
|
||||
if (!order.get_orderlines().length) {
|
||||
return;
|
||||
}
|
||||
|
||||
var total = order ? order.get_total_with_tax() : 0;
|
||||
var taxes = order ? total - order.get_total_without_tax() : 0;
|
||||
|
||||
@@ -548,7 +555,8 @@ openerp.point_of_sale.load_screens = function load_screens(instance, module){ //
|
||||
this.subcategories = [];
|
||||
this.product_list_widget = options.product_list_widget || null;
|
||||
this.category_cache = new module.DomCache();
|
||||
this.set_category();
|
||||
this.start_categ_id = this.pos.config.iface_start_categ_id ? this.pos.config.iface_start_categ_id[0] : 0;
|
||||
this.set_category(this.pos.db.get_category_by_id(this.start_categ_id));
|
||||
|
||||
this.switch_category_handler = function(event){
|
||||
self.set_category(self.pos.db.get_category_by_id(Number(this.dataset['categoryId'])));
|
||||
@@ -645,12 +653,14 @@ openerp.point_of_sale.load_screens = function load_screens(instance, module){ //
|
||||
this.el = el_node;
|
||||
|
||||
var hasimages = false; //if none of the subcategories have images, we don't display buttons with icons
|
||||
/*
|
||||
for(var i = 0; i < this.subcategories.length; i++){
|
||||
if(this.subcategories[i].image){
|
||||
hasimages = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
var list_container = el_node.querySelector('.category-list');
|
||||
if (list_container) {
|
||||
@@ -683,7 +693,7 @@ openerp.point_of_sale.load_screens = function load_screens(instance, module){ //
|
||||
|
||||
// resets the current category to the root category
|
||||
reset_category: function(){
|
||||
this.set_category();
|
||||
this.set_category(this.pos.db.get_category_by_id(this.start_categ_id));
|
||||
this.renderElement();
|
||||
},
|
||||
|
||||
@@ -1510,12 +1520,19 @@ openerp.point_of_sale.load_screens = function load_screens(instance, module){ //
|
||||
}
|
||||
|
||||
var lines = order.get_paymentlines();
|
||||
var due = order.get_due();
|
||||
var extradue = 0;
|
||||
if (due && lines.length && due !== order.get_due(lines[lines.length-1])) {
|
||||
extradue = due;
|
||||
}
|
||||
|
||||
|
||||
this.$('.paymentlines-container').empty();
|
||||
var lines = $(QWeb.render('PaymentScreen-Paymentlines', {
|
||||
widget: this,
|
||||
order: order,
|
||||
paymentlines: lines,
|
||||
extradue: extradue,
|
||||
}));
|
||||
|
||||
lines.on('click','.delete-button',function(){
|
||||
@@ -1557,6 +1574,27 @@ openerp.point_of_sale.load_screens = function load_screens(instance, module){ //
|
||||
this.$('.js_invoice').removeClass('highlight');
|
||||
}
|
||||
},
|
||||
click_tip: function(){
|
||||
var self = this;
|
||||
var order = this.pos.get_order();
|
||||
var tip = order.get_tip();
|
||||
var change = order.get_change();
|
||||
var value = tip;
|
||||
|
||||
if (tip === 0 && change > 0 ) {
|
||||
value = change;
|
||||
}
|
||||
|
||||
this.gui.show_popup('number',{
|
||||
'title': tip ? _t('Change Tip') : _t('Add Tip'),
|
||||
'value': value,
|
||||
'confirm': function(value) {
|
||||
order.set_tip(Number(value));
|
||||
self.order_changes();
|
||||
self.render_paymentlines();
|
||||
}
|
||||
});
|
||||
},
|
||||
click_set_customer: function(){
|
||||
this.gui.show_screen('clientlist');
|
||||
},
|
||||
@@ -1586,6 +1624,10 @@ openerp.point_of_sale.load_screens = function load_screens(instance, module){ //
|
||||
this.$('.js_set_customer').click(function(){
|
||||
self.click_set_customer();
|
||||
});
|
||||
|
||||
this.$('.js_tip').click(function(){
|
||||
self.click_tip();
|
||||
});
|
||||
this.$('.js_invoice').click(function(){
|
||||
self.click_invoice();
|
||||
});
|
||||
|
||||
@@ -131,7 +131,6 @@
|
||||
<button class="input-button numpad-backspace">
|
||||
<img style="pointer-events: none;" src="/point_of_sale/static/src/img/backspace.png" width="24" height="21" />
|
||||
</button>
|
||||
<br />
|
||||
</div>
|
||||
</t>
|
||||
|
||||
@@ -512,6 +511,11 @@
|
||||
</tr>
|
||||
</t>
|
||||
</t>
|
||||
<t t-if='extradue'>
|
||||
<tr class='paymentline extra' t-att-data-cid='0'>
|
||||
<td class='col-due'> <t t-esc='widget.format_currency_no_symbol(extradue)' /> </td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
</t>
|
||||
@@ -541,7 +545,6 @@
|
||||
<button class="input-button numpad-backspace" data-action='BACKSPACE' >
|
||||
<img src="/point_of_sale/static/src/img/backspace.png" width="24" height="21" />
|
||||
</button>
|
||||
<br />
|
||||
</div>
|
||||
</t>
|
||||
|
||||
@@ -595,6 +598,11 @@
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
<t t-if='widget.pos.config.tip_product_id'>
|
||||
<div class='button js_tip'>
|
||||
<i class='fa fa-heart' /> Tip
|
||||
</div>
|
||||
</t>
|
||||
<t t-if='widget.pos.config.iface_cashdrawer'>
|
||||
<div class='button js_cashdrawer'>
|
||||
<i class='fa fa-archive' /> Open Cashbox
|
||||
@@ -668,6 +676,9 @@
|
||||
<div>Served by <t t-esc='receipt.cashier' /></div>
|
||||
</div>
|
||||
</t>
|
||||
<t t-if='!receipt.customer_count'>
|
||||
<div>Guests: <t t-esc='receipt.customer_count' /></div>
|
||||
</t>
|
||||
</div>
|
||||
<br /><br />
|
||||
|
||||
@@ -983,17 +994,29 @@
|
||||
<button class="input-button number-char" data-action='1'>1</button>
|
||||
<button class="input-button number-char" data-action='2'>2</button>
|
||||
<button class="input-button number-char" data-action='3'>3</button>
|
||||
<button class="mode-button add" data-action='+10'>+10</button>
|
||||
<t t-if="widget.options.cheap">
|
||||
<button class="mode-button add" data-action='+1'>+1</button>
|
||||
</t><t t-if="!widget.options.cheap">
|
||||
<button class="mode-button add" data-action='+10'>+10</button>
|
||||
</t>
|
||||
<br />
|
||||
<button class="input-button number-char" data-action='4'>4</button>
|
||||
<button class="input-button number-char" data-action='5'>5</button>
|
||||
<button class="input-button number-char" data-action='6'>6</button>
|
||||
<button class="mode-button add" data-action='+20'>+20</button>
|
||||
<t t-if="widget.options.cheap">
|
||||
<button class="mode-button add" data-action='+2'>+2</button>
|
||||
</t><t t-if="!widget.options.cheap">
|
||||
<button class="mode-button add" data-action='+20'>+20</button>
|
||||
</t>
|
||||
<br />
|
||||
<button class="input-button number-char" data-action='7'>7</button>
|
||||
<button class="input-button number-char" data-action='8'>8</button>
|
||||
<button class="input-button number-char" data-action='9'>9</button>
|
||||
<button class="mode-button add" data-action='+50'>+50</button>
|
||||
<t t-if="widget.options.cheap">
|
||||
<button class="mode-button add" data-action='+5'>+5</button>
|
||||
</t><t t-if="!widget.options.cheap">
|
||||
<button class="mode-button add" data-action='+50'>+50</button>
|
||||
</t>
|
||||
<br />
|
||||
<button class="input-button numpad-char" data-action='CLEAR' >C</button>
|
||||
<button class="input-button number-char" data-action='0'>0</button>
|
||||
@@ -1004,12 +1027,12 @@
|
||||
<br />
|
||||
</div>
|
||||
<div class="footer">
|
||||
<div class="button confirm">
|
||||
Ok
|
||||
</div>
|
||||
<div class="button cancel">
|
||||
Cancel
|
||||
</div>
|
||||
<div class="button confirm">
|
||||
Ok
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1074,21 +1097,23 @@
|
||||
<div class="order-container">
|
||||
<div class="order-scroller touch-scrollable">
|
||||
<div class="order">
|
||||
<ul class="orderlines">
|
||||
<t t-if="orderlines.length === 0">
|
||||
<li class="orderline empty">
|
||||
Your shopping cart is empty
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
<div class="summary clearfix">
|
||||
<div t-attf-class="line #{orderlines.length === 0 ? 'empty' : ''}">
|
||||
<div class='entry total'>
|
||||
<span class="label">Total: </span> <span class="value">0.00 €</span>
|
||||
<div class='subentry'>Taxes: <span class="value">0.00€</span></div>
|
||||
<t t-if="orderlines.length === 0" >
|
||||
<div class='order-empty'>
|
||||
<i class='fa fa-shopping-cart' />
|
||||
<h1>Your shopping cart is empty</h1>
|
||||
</div>
|
||||
</t>
|
||||
<t t-if="orderlines.length > 0">
|
||||
<ul class="orderlines"></ul>
|
||||
<div class="summary clearfix">
|
||||
<div class="line">
|
||||
<div class='entry total'>
|
||||
<span class="label">Total: </span> <span class="value">0.00 €</span>
|
||||
<div class='subentry'>Taxes: <span class="value">0.00€</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1097,9 +1122,9 @@
|
||||
|
||||
|
||||
<t t-name="DebugWidget">
|
||||
<div class="debug-widget">
|
||||
<div class="debug-widget oe_hidden">
|
||||
<h1>Debug Window</h1>
|
||||
<div class="toggle">▾</div>
|
||||
<div class="toggle"><i class='fa fa-times' /></div>
|
||||
<div class="content">
|
||||
<p class="category">Electronic Scale</p>
|
||||
<ul>
|
||||
|
||||
@@ -31,34 +31,41 @@ _logger = logging.getLogger(__name__)
|
||||
class restaurant_floor(osv.osv):
|
||||
_name = 'restaurant.floor'
|
||||
_columns = {
|
||||
'name': fields.char('Floor Name', size=32, required=True, help='An internal identification of the restaurant floor'),
|
||||
'name': fields.char('Floor Name', required=True, help='An internal identification of the restaurant floor'),
|
||||
'pos_config_id': fields.many2one('pos.config','Point of Sale'),
|
||||
'background_image': fields.binary('Background Image', help='A background image used to display a floor layout in the point of sale interface'),
|
||||
'background_color': fields.char('Background Color', help='The background color of the floor layout, (must be specified in a html-compatible format)'),
|
||||
'table_ids': fields.one2many('restaurant.table','floor_id','Tables', help='The list of tables in this floor'),
|
||||
'sequence': fields.integer('Sequence',help='Used to sort Floors'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'sequence': 1,
|
||||
'background_color': 'rgb(210, 210, 210)',
|
||||
}
|
||||
|
||||
def set_background_color(self, cr, uid, id, background, context=None):
|
||||
self.write(cr, uid, [id], {'background_color': background}, context=context)
|
||||
|
||||
class restaurant_table(osv.osv):
|
||||
_name = 'restaurant.table'
|
||||
_columns = {
|
||||
'name': fields.char('Table Name', size=32, required=True, help='An internal identification of a table'),
|
||||
'floor_id': fields.many2one('restaurant.floor','Floor'),
|
||||
'shape': fields.selection([('square','Square'),('round','Round')],'Shape', required=True),
|
||||
'position_h': fields.float('Horizontal Position', help="The table's horizontal position from the left side to the table's center, in percentage of the floor's width"),
|
||||
'position_v': fields.float('Vertical Position', help="The table's vertical position from the top to the table's center, in percentage of the floor's height"),
|
||||
'width': fields.float('Width', help="The table's width in percentage of the floor's width"),
|
||||
'height': fields.float('Height', help="The table's height in percentage of the floor's height"),
|
||||
'color': fields.char('Color', size=32, help="The table's color"),
|
||||
'position_h': fields.float('Horizontal Position', help="The table's horizontal position from the left side to the table's center, in pixels"),
|
||||
'position_v': fields.float('Vertical Position', help="The table's vertical position from the top to the table's center, in pixels"),
|
||||
'width': fields.float('Width', help="The table's width in pixels"),
|
||||
'height': fields.float('Height', help="The table's height in pixels"),
|
||||
'seats': fields.integer('Seats', help="The default number of customer served at this table."),
|
||||
'color': fields.char('Color', help="The table's color, expressed as a valid 'background' CSS property value"),
|
||||
'active': fields.boolean('Active',help='If false, the table is deactivated and will not be available in the point of sale'),
|
||||
'pos_order_ids':fields.one2many('pos.order','table_id','Pos Orders', help='The orders served at this table'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'shape': 'square',
|
||||
'seats': 1,
|
||||
'position_h': 10,
|
||||
'position_v': 10,
|
||||
'height': 50,
|
||||
@@ -116,4 +123,11 @@ class pos_order(osv.osv):
|
||||
_inherit = 'pos.order'
|
||||
_columns = {
|
||||
'table_id': fields.many2one('restaurant.table','Table', help='The table where this order was served'),
|
||||
'customer_count' : fields.integer('Guests', help='The amount of customers that have been served by this order.'),
|
||||
}
|
||||
|
||||
def _order_fields(self, cr, uid, ui_order, context=None):
|
||||
fields = super(pos_order,self)._order_fields(cr,uid,ui_order,context)
|
||||
fields['table_id'] = ui_order.get('table_id',0)
|
||||
fields['customer_count'] = ui_order.get('customer_count',0)
|
||||
return fields
|
||||
|
||||
@@ -2,6 +2,21 @@
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
|
||||
<!-- POS ORDERS -->
|
||||
|
||||
<record model="ir.ui.view" id="view_pos_pos_form">
|
||||
<field name="name">pos.order.form.view.inherit</field>
|
||||
<field name="model">pos.order</field>
|
||||
<field name="inherit_id" ref="point_of_sale.view_pos_pos_form"></field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[@name='order_fields']" position="inside">
|
||||
<field name="table_id"/>
|
||||
<field name="customer_count"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- RESTAURANTS FLOORS -->
|
||||
|
||||
<record model="ir.ui.view" id="view_restaurant_floor_form">
|
||||
@@ -14,10 +29,12 @@
|
||||
<field name="name" />
|
||||
<field name="pos_config_id" />
|
||||
<field name="background_image" widget="image" />
|
||||
<field name="background_color" />
|
||||
</group>
|
||||
<field name="table_ids">
|
||||
<tree string='Tables'>
|
||||
<field name="name" />
|
||||
<field name="seats" />
|
||||
<field name="shape" />
|
||||
</tree>
|
||||
</field>
|
||||
@@ -61,10 +78,12 @@
|
||||
<form string="Restaurant Table">
|
||||
<group col="2">
|
||||
<field name="name" />
|
||||
<field name="floor_id" />
|
||||
<field name="seats" />
|
||||
</group>
|
||||
<group col="4" string="Appearance">
|
||||
<field name="shape" />
|
||||
<field name="color" />
|
||||
</group>
|
||||
<group col="4">
|
||||
<field name="position_h" />
|
||||
<field name="position_v" />
|
||||
<field name="width" />
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
.screen .screen-content-flexbox {
|
||||
margin: 0px auto;
|
||||
max-width: 1024px;
|
||||
text-align: left;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
@@ -49,25 +48,21 @@
|
||||
background-repeat: no-repeat;
|
||||
overflow: hidden;
|
||||
background-size: cover;
|
||||
transition: all 300ms ease-in-out;
|
||||
}
|
||||
|
||||
.floor-map .tables {
|
||||
position: relative;
|
||||
}
|
||||
@media screen and (min-width: 1024px) {
|
||||
.floor-map {
|
||||
margin: 8px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.floor-selector {
|
||||
margin: 8px;
|
||||
margin-bottom: 0;
|
||||
box-sizing: border-box;
|
||||
width: auto;
|
||||
border: none;
|
||||
}
|
||||
.floor-selector .button {
|
||||
border-left: none;
|
||||
}
|
||||
.floor-selector .button.active{
|
||||
border-radius: 3px;
|
||||
.floor-map .tables {
|
||||
max-width: 1024px;
|
||||
margin: auto;
|
||||
max-height: 540px;
|
||||
border-radius: 0px 0px 6px 6px;
|
||||
border: dashed 2px rgba(0,0,0,0.1);
|
||||
border-top: none;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,11 +75,42 @@
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
box-shadow: 0px 3px rgba(0,0,0,0.07);
|
||||
transition: background, background-color 300ms ease-in-out;
|
||||
}
|
||||
.floor-map .table .table-cover {
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 0; right: 0; bottom: 0;
|
||||
border-radius: 0px 0px 3px 3px;
|
||||
background: rgba(0,0,0,0.2);
|
||||
}
|
||||
.floor-map .table .table-cover.full {
|
||||
border-radius: 3px 3px 3px 3px;
|
||||
}
|
||||
.floor-map .table .table-seats {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
line-height: 20px;
|
||||
font-size: 16px;
|
||||
border-radius: 50%;
|
||||
margin-left: -10px;
|
||||
margin-bottom: 4px;
|
||||
background: black;
|
||||
color: white;
|
||||
opacity: 0.2;
|
||||
z-index: 3;
|
||||
}
|
||||
.floor-map .table .label {
|
||||
display: block;
|
||||
max-height: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
bottom: 5px;
|
||||
z-index: 5;
|
||||
}
|
||||
.floor-map .table.selected {
|
||||
outline: solid rgba(255,255,255,0.3);
|
||||
@@ -96,7 +122,7 @@
|
||||
top: 0;
|
||||
right: 0;
|
||||
font-size: 20px;
|
||||
margin: 4px;
|
||||
margin: 8px;
|
||||
line-height: 32px;
|
||||
width: 32px;
|
||||
text-align: center;
|
||||
@@ -106,20 +132,21 @@
|
||||
}
|
||||
.floor-map .edit-button.editing.active {
|
||||
background: #444;
|
||||
border-color: transparent;
|
||||
color: white;
|
||||
}
|
||||
.floor-map .edit-bar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 40px;
|
||||
margin: 4px;
|
||||
line-height: 32px;
|
||||
margin: 8px;
|
||||
line-height: 34px;
|
||||
text-align: center;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
border: solid 1px rgba(0,0,0,0.2);
|
||||
background: #F0EEEE;
|
||||
background: rgba(255,255,255,0.5);
|
||||
z-index: 100;
|
||||
}
|
||||
.floor-map .edit-bar .edit-button {
|
||||
position: relative;
|
||||
@@ -127,14 +154,15 @@
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
margin-right: -4px;
|
||||
border-right: solid 1px rgba(0,0,0,0.1);
|
||||
border-right: solid 1px rgba(0,0,0,0.2);
|
||||
transition: all 150ms linear;
|
||||
}
|
||||
.floor-map .edit-bar .edit-button.disabled {
|
||||
opacity: 0.5;
|
||||
border-right: solid 1px rgba(0,0,0,0.2);
|
||||
cursor: default;
|
||||
}
|
||||
.floor-map .edit-bar .edit-button.disabled > * {
|
||||
opacity: 0.5;
|
||||
}
|
||||
.floor-map .edit-bar .color-picker {
|
||||
position: absolute;
|
||||
left: -106px;
|
||||
@@ -192,6 +220,7 @@
|
||||
box-shadow: 0px 2px 3px rgba(0,0,0,0.2);
|
||||
cursor: grab;
|
||||
transition: all 150ms linear;
|
||||
z-index: 100;
|
||||
}
|
||||
.floor-map .table.selected .table-handle:hover {
|
||||
width: 20px;
|
||||
@@ -217,6 +246,7 @@
|
||||
line-height: 20px;
|
||||
border-radius: 10px;
|
||||
font-size: 16px;
|
||||
z-index: 10;
|
||||
}
|
||||
.floor-map .table .order-count.notify-printing {
|
||||
background: red;
|
||||
@@ -239,6 +269,18 @@
|
||||
.pos .order-button.floor-button .fa{
|
||||
font-size: 24px;
|
||||
}
|
||||
/* ------ ORDER LINE STATUS ------- */
|
||||
|
||||
.pos .order .orderline.dirty {
|
||||
border-left: solid 6px #6EC89B;
|
||||
color: #6EC89B;
|
||||
padding-left: 9px;
|
||||
}
|
||||
.pos .order .orderline.skip {
|
||||
border-left: solid 6px #7F82AC;
|
||||
color: #7F82AC;
|
||||
padding-left: 9px;
|
||||
}
|
||||
|
||||
|
||||
/* ------ ORDER NOTES ------- */
|
||||
|
||||
@@ -5,7 +5,7 @@ openerp.pos_restaurant.load_floors = function(instance,module){
|
||||
// At POS Startup, load the floors, and add them to the pos model
|
||||
module.load_models({
|
||||
model: 'restaurant.floor',
|
||||
fields: ['name','background_image','table_ids','sequence'],
|
||||
fields: ['name','background_color','table_ids','sequence'],
|
||||
domain: function(self){ return [['pos_config_id','=',self.config.id]] },
|
||||
loaded: function(self,floors){
|
||||
self.floors = floors;
|
||||
@@ -27,7 +27,7 @@ openerp.pos_restaurant.load_floors = function(instance,module){
|
||||
// them with their floor.
|
||||
module.load_models({
|
||||
model: 'restaurant.table',
|
||||
fields: ['name','width','height','position_h','position_v','shape','floor_id','color'],
|
||||
fields: ['name','width','height','position_h','position_v','shape','floor_id','color','seats'],
|
||||
loaded: function(self,tables){
|
||||
self.tables_by_id = {};
|
||||
for (var i = 0; i < tables.length; i++) {
|
||||
@@ -161,8 +161,8 @@ openerp.pos_restaurant.load_floors = function(instance,module){
|
||||
}
|
||||
},
|
||||
set_table_color: function(color){
|
||||
this.table.color = color;
|
||||
this.renderElement();
|
||||
this.table.color = _.escape(color);
|
||||
this.$el.css({'background': this.table.color});
|
||||
},
|
||||
set_table_name: function(name){
|
||||
if (name) {
|
||||
@@ -170,6 +170,12 @@ openerp.pos_restaurant.load_floors = function(instance,module){
|
||||
this.renderElement();
|
||||
}
|
||||
},
|
||||
set_table_seats: function(seats){
|
||||
if (seats) {
|
||||
this.table.seats = Number(seats);
|
||||
this.renderElement();
|
||||
}
|
||||
},
|
||||
// The table's positioning is handled via css absolute positioning,
|
||||
// which is handled here.
|
||||
table_style: function(){
|
||||
@@ -187,7 +193,7 @@ openerp.pos_restaurant.load_floors = function(instance,module){
|
||||
unit(Math.max(table.width,table.height)/2) : '3px',
|
||||
};
|
||||
if (table.color) {
|
||||
style['background-color'] = table.color;
|
||||
style['background'] = table.color;
|
||||
}
|
||||
if (table.height >= 150 && table.width >= 150) {
|
||||
style['font-size'] = '32px';
|
||||
@@ -238,6 +244,13 @@ openerp.pos_restaurant.load_floors = function(instance,module){
|
||||
}
|
||||
self.renderElement();
|
||||
});
|
||||
}, function(err,event) {
|
||||
self.gui.show_popup('error',{
|
||||
'title':_t('Changes could not be saved'),
|
||||
'body': _t('Check your internet connection and access rights'),
|
||||
});
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
});
|
||||
},
|
||||
// destroy the table. We do not really destroy it, we set it
|
||||
@@ -283,8 +296,10 @@ openerp.pos_restaurant.load_floors = function(instance,module){
|
||||
},
|
||||
renderElement: function(){
|
||||
var self = this;
|
||||
this.order_count = this.pos.get_table_orders(this.table).length;
|
||||
this.notifications = this.get_notifications();
|
||||
this.order_count = this.pos.get_table_orders(this.table).length;
|
||||
this.customer_count = this.pos.get_customer_count(this.table);
|
||||
this.fill = Math.min(1,Math.max(0,this.customer_count / this.table.seats));
|
||||
this.notifications = this.get_notifications();
|
||||
this._super();
|
||||
|
||||
this.$el.on('mouseup', function(event){ self.click_handler(event,$(this)); });
|
||||
@@ -347,6 +362,29 @@ openerp.pos_restaurant.load_floors = function(instance,module){
|
||||
background_image_url: function(floor) {
|
||||
return '/web/binary/image?model=restaurant.floor&id='+floor.id+'&field=background_image';
|
||||
},
|
||||
get_floor_style: function() {
|
||||
var style = "";
|
||||
if (this.floor.background_image) {
|
||||
style += "background-image: url(" + this.background_image_url(this.floor) + "); ";
|
||||
}
|
||||
if (this.floor.background_color) {
|
||||
style += "background-color: " + _.escape(this.floor.background_color) + ";";
|
||||
}
|
||||
return style;
|
||||
},
|
||||
set_background_color: function(background) {
|
||||
this.floor.background_color = background;
|
||||
(new instance.web.Model('restaurant.floor'))
|
||||
.call('set_background_color',[this.floor.id, background]).fail(function(err,event){
|
||||
self.gui.show_popup('error',{
|
||||
'title':_t('Changes could not be saved'),
|
||||
'body': _t('Check your internet connection and access rights'),
|
||||
});
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
});
|
||||
this.$('.floor-map').css({"background-color": _.escape(background)});
|
||||
},
|
||||
deselect_tables: function(){
|
||||
for (var i = 0; i < this.table_widgets.length; i++) {
|
||||
var table = this.table_widgets[i];
|
||||
@@ -378,13 +416,18 @@ openerp.pos_restaurant.load_floors = function(instance,module){
|
||||
}
|
||||
},
|
||||
tool_colorpicker_open: function(){
|
||||
this.$('.color-picker').addClass('oe_hidden');
|
||||
if (this.selected_table) {
|
||||
this.$('.color-picker').removeClass('oe_hidden');
|
||||
this.$('.color-picker.fg-picker').removeClass('oe_hidden');
|
||||
} else {
|
||||
this.$('.color-picker.bg-picker').removeClass('oe_hidden');
|
||||
}
|
||||
},
|
||||
tool_colorpicker_pick: function(event,$el){
|
||||
if (this.selected_table) {
|
||||
this.selected_table.set_table_color($el[0].style['background-color']);
|
||||
} else {
|
||||
this.set_background_color($el[0].style['background-color']);
|
||||
}
|
||||
},
|
||||
tool_colorpicker_close: function(){
|
||||
@@ -402,6 +445,19 @@ openerp.pos_restaurant.load_floors = function(instance,module){
|
||||
});
|
||||
}
|
||||
},
|
||||
tool_change_seats: function(){
|
||||
var self = this;
|
||||
if (this.selected_table) {
|
||||
this.gui.show_popup('number',{
|
||||
'title':_t('Number of Seats ?'),
|
||||
'cheap': true,
|
||||
'value': this.selected_table.table.seats,
|
||||
'confirm': function(value) {
|
||||
self.selected_table.set_table_seats(value);
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
tool_duplicate_table: function(){
|
||||
if (this.selected_table) {
|
||||
var tw = this.create_table(this.selected_table.table);
|
||||
@@ -413,20 +469,36 @@ openerp.pos_restaurant.load_floors = function(instance,module){
|
||||
},
|
||||
tool_new_table: function(){
|
||||
var tw = this.create_table({
|
||||
'position_v': 50,
|
||||
'position_h': 50,
|
||||
'width': 50,
|
||||
'height': 50,
|
||||
'name': 'T1',
|
||||
'position_v': 100,
|
||||
'position_h': 100,
|
||||
'width': 75,
|
||||
'height': 75,
|
||||
'shape': 'square',
|
||||
'seats': 1,
|
||||
});
|
||||
this.select_table(tw);
|
||||
},
|
||||
new_table_name: function(name){
|
||||
if (name) {
|
||||
var num = Number((name.match(/\d+/g) || [])[0] || 0);
|
||||
var str = (name.replace(/\d+/g,''));
|
||||
var n = {num: num, str:str};
|
||||
n.num += 1;
|
||||
this.last_name = n;
|
||||
} else if (this.last_name) {
|
||||
this.last_name.num += 1;
|
||||
} else {
|
||||
this.last_name = {num: 1, str:'T'};
|
||||
}
|
||||
return '' + this.last_name.str + this.last_name.num;
|
||||
},
|
||||
create_table: function(params) {
|
||||
var table = {};
|
||||
for (var p in params) {
|
||||
table[p] = params[p];
|
||||
}
|
||||
|
||||
table.name = this.new_table_name(params.name);
|
||||
|
||||
delete table['id'];
|
||||
table.floor_id = [this.floor.id,''];
|
||||
@@ -434,7 +506,7 @@ openerp.pos_restaurant.load_floors = function(instance,module){
|
||||
|
||||
this.floor.tables.push(table);
|
||||
var tw = new module.TableWidget(this,{table: table});
|
||||
tw.appendTo('.floor-map');
|
||||
tw.appendTo('.floor-map .tables');
|
||||
this.table_widgets.push(tw);
|
||||
return tw;
|
||||
},
|
||||
@@ -499,7 +571,7 @@ openerp.pos_restaurant.load_floors = function(instance,module){
|
||||
var tw = new module.TableWidget(this,{
|
||||
table: this.floor.tables[i],
|
||||
});
|
||||
tw.appendTo(this.$('.floor-map'));
|
||||
tw.appendTo(this.$('.floor-map .tables'));
|
||||
this.table_widgets.push(tw);
|
||||
}
|
||||
|
||||
@@ -527,6 +599,10 @@ openerp.pos_restaurant.load_floors = function(instance,module){
|
||||
self.tool_rename_table();
|
||||
});
|
||||
|
||||
this.$('.edit-button.seats').click(function(event){
|
||||
self.tool_change_seats();
|
||||
});
|
||||
|
||||
this.$('.edit-button.trash').click(function(event){
|
||||
self.tool_trash_table();
|
||||
});
|
||||
@@ -538,7 +614,6 @@ openerp.pos_restaurant.load_floors = function(instance,module){
|
||||
|
||||
this.$('.color-picker .color').click(function(event){
|
||||
self.tool_colorpicker_pick(event,$(this));
|
||||
self.tool_colorpicker_close();
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
@@ -546,8 +621,9 @@ openerp.pos_restaurant.load_floors = function(instance,module){
|
||||
self.toggle_editing();
|
||||
});
|
||||
|
||||
this.$('.floor-map').click(function(event){
|
||||
if (event.target === self.$('.floor-map')[0]) {
|
||||
this.$('.floor-map,.floor-map .tables').click(function(event){
|
||||
if (event.target === self.$('.floor-map')[0] ||
|
||||
event.target === self.$('.floor-map .tables')[0]) {
|
||||
self.deselect_tables();
|
||||
}
|
||||
});
|
||||
@@ -589,6 +665,13 @@ openerp.pos_restaurant.load_floors = function(instance,module){
|
||||
if (!this.table) {
|
||||
this.table = this.pos.table;
|
||||
}
|
||||
if (!this.customer_count) {
|
||||
if (this.table) {
|
||||
this.customer_count = this.table.seats;
|
||||
} else {
|
||||
this.customer_count = 1;
|
||||
}
|
||||
}
|
||||
this.save_to_db();
|
||||
},
|
||||
export_as_JSON: function() {
|
||||
@@ -597,19 +680,29 @@ openerp.pos_restaurant.load_floors = function(instance,module){
|
||||
json.table_id = this.table ? this.table.id : false;
|
||||
json.floor = this.table ? this.table.floor.name : false;
|
||||
json.floor_id = this.table ? this.table.floor.id : false;
|
||||
json.customer_count = this.customer_count;
|
||||
return json;
|
||||
},
|
||||
init_from_JSON: function(json) {
|
||||
_super_order.init_from_JSON.apply(this,arguments);
|
||||
this.table = this.pos.tables_by_id[json.table_id];
|
||||
this.floor = this.table ? this.pos.floors_by_id[json.floor_id] : undefined;
|
||||
this.customer_count = json.customer_count || 1;
|
||||
},
|
||||
export_for_printing: function() {
|
||||
var json = _super_order.export_for_printing.apply(this,arguments);
|
||||
json.table = this.table ? this.table.name : undefined;
|
||||
json.floor = this.table ? this.table.floor.name : undefined;
|
||||
json.customer_count = this.get_customer_count();
|
||||
return json;
|
||||
},
|
||||
get_customer_count: function(){
|
||||
return this.customer_count;
|
||||
},
|
||||
set_customer_count: function(count) {
|
||||
this.customer_count = Math.max(count,0);
|
||||
this.trigger('change');
|
||||
},
|
||||
});
|
||||
|
||||
// We need to modify the OrderSelector to hide itself when we're on
|
||||
@@ -724,6 +817,16 @@ openerp.pos_restaurant.load_floors = function(instance,module){
|
||||
return t_orders;
|
||||
},
|
||||
|
||||
// get customer count at table
|
||||
get_customer_count: function(table) {
|
||||
var orders = this.get_table_orders(table);
|
||||
var count = 0;
|
||||
for (var i = 0; i < orders.length; i++) {
|
||||
count += orders[i].get_customer_count();
|
||||
}
|
||||
return count;
|
||||
},
|
||||
|
||||
// When we validate an order we go back to the floor plan.
|
||||
// When we cancel an order and there is multiple orders
|
||||
// on the table, stay on the table.
|
||||
@@ -740,6 +843,50 @@ openerp.pos_restaurant.load_floors = function(instance,module){
|
||||
_super_posmodel.on_removed_order.apply(this,arguments);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
});
|
||||
|
||||
module.TableGuestsButton = module.ActionButtonWidget.extend({
|
||||
template: 'TableGuestsButton',
|
||||
guests: function() {
|
||||
if (this.pos.get_order()) {
|
||||
return this.pos.get_order().customer_count;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
button_click: function() {
|
||||
var self = this;
|
||||
this.gui.show_popup('number', {
|
||||
'title': _t('Guests ?'),
|
||||
'cheap': true,
|
||||
'value': this.pos.get_order().customer_count,
|
||||
'confirm': function(value) {
|
||||
value = Math.max(1,Number(value));
|
||||
self.pos.get_order().set_customer_count(value);
|
||||
self.renderElement();
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
module.OrderWidget.include({
|
||||
update_summary: function(){
|
||||
this._super();
|
||||
if (this.getParent().action_buttons &&
|
||||
this.getParent().action_buttons.guests) {
|
||||
this.getParent().action_buttons.guests.renderElement();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
module.define_action_button({
|
||||
'name': 'guests',
|
||||
'widget': module.TableGuestsButton,
|
||||
'condition': function(){
|
||||
return this.pos.config.iface_floorplan;
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -51,10 +51,65 @@ openerp.pos_restaurant.load_multiprint = function(instance,module){
|
||||
self.printers.push(printer);
|
||||
}
|
||||
}
|
||||
self.config.iface_printers = !!self.printers.length;
|
||||
},
|
||||
});
|
||||
|
||||
var _super_orderline = module.Orderline.prototype;
|
||||
module.Orderline = module.Orderline.extend({
|
||||
initialize: function(args) {
|
||||
_super_orderline.initialize.apply(this,arguments);
|
||||
if (!this.pos.config.iface_printers) {
|
||||
return;
|
||||
}
|
||||
if (typeof this.mp_dirty === 'undefined') {
|
||||
// mp dirty is true if this orderline has changed
|
||||
// since the last kitchen print
|
||||
this.mp_dirty = true;
|
||||
}
|
||||
if (!this.mp_skip) {
|
||||
// mp_skip is true if the cashier want this orderline
|
||||
// not to be sent to the kitchen
|
||||
this.mp_skip = false;
|
||||
}
|
||||
},
|
||||
init_from_JSON: function(json) {
|
||||
_super_orderline.init_from_JSON.apply(this,arguments);
|
||||
this.mp_dirty = json.mp_dirty;
|
||||
this.mp_skip = json.mp_skip;
|
||||
},
|
||||
export_as_JSON: function() {
|
||||
var json = _super_orderline.export_as_JSON.apply(this,arguments);
|
||||
json.mp_dirty = this.mp_dirty;
|
||||
json.mp_skip = this.mp_skip;
|
||||
return json;
|
||||
},
|
||||
set_quantity: function(quantity) {
|
||||
if (this.pos.config.iface_printers && quantity !== this.quantity) {
|
||||
this.mp_dirty = true;
|
||||
}
|
||||
_super_orderline.set_quantity.apply(this,arguments);
|
||||
},
|
||||
can_be_merged_with: function(orderline) {
|
||||
return (!this.mp_skip) &&
|
||||
(!orderline.mp_skip) &&
|
||||
_super_orderline.can_be_merged_with.apply(this,arguments);
|
||||
},
|
||||
set_skip: function(skip) {
|
||||
if (this.mp_dirty && skip && !this.mp_skip) {
|
||||
this.mp_skip = true;
|
||||
this.trigger('change',this);
|
||||
}
|
||||
if (this.mp_skip && !skip) {
|
||||
this.mp_dirty = true;
|
||||
this.mp_skip = false;
|
||||
this.trigger('change',this);
|
||||
}
|
||||
},
|
||||
set_dirty: function(dirty) {
|
||||
this.mp_dirty = dirty;
|
||||
this.trigger('change',this);
|
||||
},
|
||||
get_line_diff_hash: function(){
|
||||
if (this.get_note()) {
|
||||
return this.get_product().id + '|' + this.get_note();
|
||||
@@ -64,11 +119,44 @@ openerp.pos_restaurant.load_multiprint = function(instance,module){
|
||||
},
|
||||
});
|
||||
|
||||
module.OrderWidget.include({
|
||||
render_orderline: function(orderline) {
|
||||
var node = this._super(orderline);
|
||||
if (this.pos.config.iface_printers) {
|
||||
if (orderline.mp_skip) {
|
||||
node.classList.add('skip');
|
||||
} else if (orderline.mp_dirty) {
|
||||
node.classList.add('dirty');
|
||||
}
|
||||
}
|
||||
return node;
|
||||
},
|
||||
click_line: function(line, event) {
|
||||
if (!this.pos.config.iface_printers) {
|
||||
this._super(line, event);
|
||||
} else if (this.pos.get_order().selected_orderline !== line) {
|
||||
this.mp_dbclk_time = (new Date()).getTime();
|
||||
} else if (!this.mp_dbclk_time) {
|
||||
this.mp_dbclk_time = (new Date()).getTime();
|
||||
} else if (this.mp_dbclk_time + 500 > (new Date()).getTime()) {
|
||||
line.set_skip(!line.mp_skip);
|
||||
this.mp_dbclk_time = 0;
|
||||
} else {
|
||||
this.mp_dbclk_time = (new Date()).getTime();
|
||||
}
|
||||
|
||||
this._super(line, event);
|
||||
},
|
||||
});
|
||||
|
||||
var _super_order = module.Order.prototype;
|
||||
module.Order = module.Order.extend({
|
||||
build_line_resume: function(){
|
||||
var resume = {};
|
||||
this.orderlines.each(function(line){
|
||||
if (line.mp_skip) {
|
||||
return;
|
||||
}
|
||||
var line_hash = line.get_line_diff_hash();
|
||||
var qty = Number(line.get_quantity());
|
||||
var note = line.get_note();
|
||||
@@ -85,6 +173,9 @@ openerp.pos_restaurant.load_multiprint = function(instance,module){
|
||||
},
|
||||
saveChanges: function(){
|
||||
this.saved_resume = this.build_line_resume();
|
||||
this.orderlines.each(function(line){
|
||||
line.set_dirty(false);
|
||||
});
|
||||
this.trigger('change',this);
|
||||
},
|
||||
computeChanges: function(categories){
|
||||
@@ -229,13 +320,6 @@ openerp.pos_restaurant.load_multiprint = function(instance,module){
|
||||
order.saveChanges();
|
||||
}
|
||||
},
|
||||
hilight: function(hi){
|
||||
if (hi) {
|
||||
this.$el.addClass('highlight');
|
||||
} else {
|
||||
this.$el.removeClass('highlight');
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
module.define_action_button({
|
||||
|
||||
@@ -125,6 +125,9 @@ openerp.pos_restaurant.load_splitbill = function(instance, module){
|
||||
neworder.saveChanges();
|
||||
}
|
||||
|
||||
neworder.set_customer_count(1);
|
||||
order.set_customer_count(order.get_customer_count() - 1);
|
||||
|
||||
this.pos.get('orders').add(neworder);
|
||||
this.pos.set('selectedOrder',neworder);
|
||||
}
|
||||
|
||||
@@ -17,15 +17,30 @@
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<t t-name="TableGuestsButton">
|
||||
<div class='control-button'>
|
||||
<span class='control-button-number'>
|
||||
<t t-esc="widget.guests()" />
|
||||
</span>
|
||||
Guests
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="TableWidget">
|
||||
<t t-if='!widget.selected'>
|
||||
<div class='table' t-att-style='widget.table_style_str()'>
|
||||
<span
|
||||
t-if="widget.table.shape !== 'round'"
|
||||
t-att-class='"table-cover " + (widget.fill >= 1 ? "full" : "")'
|
||||
t-att-style='"height: " + Math.ceil(widget.fill * 100) + "%;"'
|
||||
></span>
|
||||
<t t-if='widget.order_count'>
|
||||
<span t-att-class='"order-count " + (widget.notifications.printing ? "notify-printing":"")'><t t-esc='widget.order_count'/></span>
|
||||
</t>
|
||||
<span class='label'>
|
||||
<t t-esc='widget.table.name' />
|
||||
</span>
|
||||
<span class="table-seats"><t t-esc="widget.table.seats" /></span>
|
||||
</div>
|
||||
</t>
|
||||
<t t-if='widget.selected'>
|
||||
@@ -33,6 +48,7 @@
|
||||
<span class='label'>
|
||||
<t t-esc='widget.table.name' />
|
||||
</span>
|
||||
<span class="table-seats"><t t-esc="widget.table.seats" /></span>
|
||||
<span class='table-handle top'></span>
|
||||
<span class='table-handle bottom'></span>
|
||||
<span class='table-handle left'></span>
|
||||
@@ -70,7 +86,8 @@
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
<div class='floor-map' t-att-style='widget.floor.background_image ? ("background-image:url("+widget.background_image_url(widget.floor)+");") :"" '>
|
||||
<div class='floor-map' t-att-style='widget.get_floor_style()' >
|
||||
<div class='tables'></div>
|
||||
<span class='edit-button editing'><i class='fa fa-pencil'></i></span>
|
||||
<div class='edit-bar oe_hidden'>
|
||||
<span class='edit-button new-table'>
|
||||
@@ -82,25 +99,42 @@
|
||||
<span class='edit-button rename needs-selection'>
|
||||
<i class='fa fa-font'></i>
|
||||
</span>
|
||||
<span class='edit-button seats needs-selection'>
|
||||
<i class='fa fa-user'></i>
|
||||
</span>
|
||||
<span class='edit-button shape needs-selection'>
|
||||
<span class='button-option square'><i class='fa fa-square-o'></i></span>
|
||||
<span class='button-option round oe_hidden'><i class='fa fa-circle-o'></i></span>
|
||||
</span>
|
||||
<span class='edit-button color needs-selection'>
|
||||
<span class='edit-button color'>
|
||||
<i class='fa fa-tint'></i>
|
||||
<div class='color-picker oe_hidden'>
|
||||
<div class='color-picker fg-picker oe_hidden'>
|
||||
<div class='close-picker'>
|
||||
<i class='fa fa-times' />
|
||||
</div>
|
||||
<span class='color tl' style='background-color:#EB6D6D' />
|
||||
<span class='color' style='background-color:#35D374' />
|
||||
<span class='color tr' style='background-color:#6C6DEC' />
|
||||
<span class='color tl' style='background-color:#EB6D6D' />
|
||||
<span class='color' style='background-color:#35D374' />
|
||||
<span class='color tr' style='background-color:#6C6DEC' />
|
||||
<span class='color' style='background-color:#EBBF6D' />
|
||||
<span class='color' style='background-color:#EBEC6D' />
|
||||
<span class='color' style='background-color:#AC6DAD' />
|
||||
<span class='color bl' style='background-color:#6C6D6D' />
|
||||
<span class='color' style='background-color:#ACADAD' />
|
||||
<span class='color br' style='background-color:#4ED2BE' />
|
||||
<span class='color bl' style='background-color:#6C6D6D' />
|
||||
<span class='color' style='background-color:#ACADAD' />
|
||||
<span class='color br' style='background-color:#4ED2BE' />
|
||||
</div>
|
||||
<div class='color-picker bg-picker oe_hidden'>
|
||||
<div class='close-picker'>
|
||||
<i class='fa fa-times' />
|
||||
</div>
|
||||
<span class='color tl' style='background-color:rgb(244, 149, 149)' />
|
||||
<span class='color' style='background-color:rgb(130, 233, 171)' />
|
||||
<span class='color tr' style='background-color:rgb(136, 137, 242)' />
|
||||
<span class='color' style='background-color:rgb(255, 214, 136)' />
|
||||
<span class='color' style='background-color:rgb(254, 255, 154)' />
|
||||
<span class='color' style='background-color:rgb(209, 171, 210)' />
|
||||
<span class='color bl' style='background-color:rgb(75, 75, 75)' />
|
||||
<span class='color' style='background-color:rgb(210, 210, 210)' />
|
||||
<span class='color br' style='background-color:rgb(127, 221, 236)' />
|
||||
</div>
|
||||
</span>
|
||||
<span class='edit-button trash needs-selection'>
|
||||
|
||||
Reference in New Issue
Block a user