@http.route('/pos/web', type='http', auth='none')
def a(self, debug=False, **k):
- print '\nDEBUG',debug,'\n'
js_list = manifest_list('js',db=request.db, debug=debug)
css_list = manifest_list('css',db=request.db, debug=debug)
print css_list
print js_list
- js_list = [ js for js in js_list if 'select2' not in js ]
-
js = "\n".join('<script type="text/javascript" src="%s"></script>' % i for i in js_list)
css = "\n".join('<link rel="stylesheet" href="%s">' % i for i in css_list)
r = html_template % {
'css': css,
'modules': simplejson.dumps(module_boot(request.db)),
'init': """
- window.navigator.standalone = true;
+ console.log('LOADED');
var wc = new s.web.WebClient();
- wc.appendTo($(document.body));
wc.show_application = function(){
+ console.log('SHOW APPLICATION');
wc.action_manager.do_action("pos.ui");
};
wc.show_login = function(){
+ console.log('SHOW LOGIN');
window.location.href = '/';
}
+ wc.appendTo($(document.body));
+ console.log('APPENDED');
"""
}
return r
background: rgba(0,0,0,0.82);
color: white;
padding-bottom: 10px;
- cursor:move;
+ cursor: move;
+ -webkit-transform: translate3d(0,0,0);
}
.pos .debug-widget .toggle{
position: absolute;
+++ /dev/null
-@font-face{
- font-family: 'Inconsolata';
- src: url(../fonts/Inconsolata.otf);
-}
-
-.point-of-sale {
- padding: 0;
- margin: 0;
- background-color: #f0eeee;
- font-family: "Lucida Grande", Helvetica, Verdana, Arial;
- color: #555555;
- font-size: 12px;
- position: absolute;
- left: 0;
- top: 0;
- width: 100%;
- height: 100%;
- -webkit-user-select: none;
- -moz-user-select: none;
- user-select: none;
-}
-
-.point-of-sale .shadow-top{
- position: absolute;
- top:0;
- left:0;
- right:0;
- height:10px;
- background: -webkit-linear-gradient(top,rgba(0,0,0,0.09),rgba(0,0,0,0));
- background: -moz-linear-gradient(top,rgba(0,0,0,0.09),rgba(0,0,0,0));
- background: -ms-linear-gradient(top,rgba(0,0,0,0.09),rgba(0,0,0,0));
- background: linear-gradient(top,rgba(0,0,0,0.09),rgba(0,0,0,0));
-}
-
-.point-of-sale .darker-shadow-top{
- position: absolute;
- top:0;
- left:0;
- right:0;
- height:10px;
- background: -webkit-linear-gradient(top,rgba(0,0,0,0.15),rgba(0,0,0,0));
- background: -moz-linear-gradient(top,rgba(0,0,0,0.15),rgba(0,0,0,0));
- background: -ms-linear-gradient(top,rgba(0,0,0,0.15),rgba(0,0,0,0));
- background: linear-gradient(top,rgba(0,0,0,0.15),rgba(0,0,0,0));
-}
-
-/* ********* The black loading screen ********* */
-
-.point-of-sale .loader{
- background-color: #222;
- position:absolute;
- left:0px;
- top:0px;
- width:100%;
- height:100%;
- z-index: 999;
- text-align: center;
-}
-.point-of-sale .loader img{
- position:absolute;
- top:50%;
- left:50%;
-}
-
-/* ********* Generic element styling ********* */
-
-.point-of-sale a {
- text-decoration: none;
- color: #555555;
-}
-.point-of-sale button, .point-of-sale a.button {
- display: inline-block;
- cursor: pointer;
- padding: 4px 10px;
- font-size: 11px;
- border: 1px solid #cacaca;
- border-radius: 4px;
- background: #e2e2e2;
- background: -webkit-gradient(linear, left top, left bottom, from(#f0f0f0), to(#e2e2e2));
- background: -moz-linear-gradient(#f0f0f0, #e2e2e2);
- background: -ms-linear-gradient(#f0f0f0, #e2e2e2);
- background: linear-gradient(#f0f0f0, #e2e2e2);
-}
-.point-of-sale ul, .point-of-sale ol {
- padding: 0;
- margin: 0;
-}
-.point-of-sale li {
- list-style-type: none;
-}
-.point-of-sale .pos-right-align {
- text-align: right;
-}
-.point-of-sale .pos-right-align input {
- text-align: right;
- border: 1px solid #cecbcb;
- border-radius: 4px;
-}
-
-/* ********* The black header bar ********* */
-
-
-.point-of-sale #topheader {
- position:absolute;
- left:0;
- top:0;
- width: 100%;
- height: 33px;
- margin:0;
- padding:0;
- color: gray;
- border-top: solid 1px #d3d3d3;
- border-bottom: solid 1px black;
- background: #393939;
- background: -moz-linear-gradient(#7b7979, #393939);
- background: -webkit-gradient(linear, left top, left bottom, from(#7b7979), to(#393939));
-}
-
-/* a) The left part of the top-bar */
-
-.point-of-sale #branding{
- position: absolute;
- display: table-cell;
- left:0;
- top:0;
- width:439px;
- height:100%;
- margin:0;
- padding:0;
- border-right: 1px solid #373737;
- text-align:left;
- line-height:100%;
- vertical-align: middle;
-}
-.point-of-sale #branding img {
- height: 32px;
- width: 116px;
- margin-left:5px;
- vertical-align:middle;
-}
-.point-of-sale #branding .username{
- float:right;
- color:#DDD;
- font-size:16px;
- margin-right:32px;
- margin-top:10px;
- font-style:italic;
-}
-
-/* b) The right part of the top-bar */
-
-.point-of-sale #rightheader {
- position: absolute;
- left:440px;
- right:0;
- top:0;
- height:100%;
-}
-
-.point-of-sale #rightheader button {
- color: #273072;
- height:27px;
- margin:3px;
- margin-right:0px;
- border: 1px solid #353A7E;
- background: #7f82ac;
- background: -webkit-gradient(linear, left top, left bottom, from(#b2b3d7), to(#7f82ac));
- background: -moz-linear-gradient(#b2b3d7, #7f82ac);
- background: -ms-linear-gradient(#b2b3d7, #7f82ac);
- background: linear-gradient(#b2b3d7, #7f82ac);
-}
-
-.point-of-sale #rightheader button.neworder-button {
- width: 32px;
- margin-left:4px;
- margin-right:4px;
-}
-
-.point-of-sale div#order-selector {
- display: inline;
-}
-.point-of-sale ol#orders {
- display: inline;
-}
-.point-of-sale li.order-selector-button {
- display: inline;
-}
-.point-of-sale li.selected-order button {
- font-weight: 900;
-}
-
-/* c) The session buttons */
-
-.point-of-sale #rightheader .header-button{
- float:right;
- height:32px;
- padding-left:10px;
- padding-right:10px;
- border-right: 1px solid #3a3a3a;
- border-left: 1px solid #3a3a3a;
- color:#DDD;
- line-height:32px;
- text-align:center;
- cursor: pointer;
-
- -webkit-transition-property: background;
- -webkit-transition-duration: 0.2s;
- -webkit-transition-timing-function: ease-out;
-}
-.point-of-sale #rightheader .header-button:last-child{
- border-left: 1px solid #3a3a3a;
-}
-
-/* c) The notifications indicator */
-
-.point-of-sale .oe_pos_synch-notification{
- float:right;
- color: rgba(255,255,255,0.4);
- padding: 8px;
- line-height:16px;
- font-size:16px;
- vertical-align:middle;
- font-style: italic;
- cursor:pointer;
-}
-
-.point-of-sale .oe_pos_synch-notification .oe_status_red{
- display:inline-block;
- cursor:pointer;
- width:16px; height:16px;
- background: url("../img/gtk-no.png") no-repeat ;
-}
-
-.point-of-sale .oe_pos_synch-notification .oe_status_green{
- display:inline-block;
- width:16px; height:16px;
- background: url("../img/gtk-yes.png") no-repeat;
-}
-
-/* ********* Contains everything below the bar ********* */
-
-.point-of-sale #content {
- width: 100%;
- position: absolute;
- top: 35px;
- bottom: 0;
- background: #F0EEEE;
-}
-
-/* ********* The leftpane contains the order, numpad and paypad ********* */
-
-.point-of-sale #leftpane {
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- -ms-box-sizing: border-box;
- box-sizing: border-box;
- position:absolute;
- left:0;
- width:440px;
- top:0px;
- /*bottom:105px;*/
- bottom:0;
- border-right: solid 1px #CECBCB;
- background-color: white;
-}
-.point-of-sale #leftpane footer {
- position: absolute;
- bottom: 0;
- left: 0;
- width: 100%;
- background: #F0EEEE;
- white-space: nowrap;
-}
-
-/* ********* The paypad contains the payment buttons ********* */
-
-.point-of-sale #paypad {
- padding: 8px 4px 8px 8px;
- display: inline-block;
- text-align: center;
- vertical-align: top;
-}
-.point-of-sale #paypad button {
- height: 54px;
- width: 208px;
- margin: 0 -3px;
- font-weight: bold;
- vertical-align: middle;
- color: #555555;
- border-top: 1px solid #efefef;
- font-size: 14px;
-}
-
-/* ********* The Numpad ********* */
-
-.point-of-sale #numpad {
- padding: 8px 8px 8px 4px;
- display: inline-block;
- text-align: center;
-}
-.point-of-sale #numpad button {
- height: 54px;
- width: 54px;
- margin: 0 -3px;
- font-weight: bold;
- vertical-align: middle;
- color: #555555;
- border-top: 1px solid #efefef;
-}
-.point-of-sale #numpad .selected-mode {
- color: white;
- background: #7f82ac;
- background: -webkit-gradient(linear, left top, left bottom, from(#9d9fc5), to(#7f82ac));
- background: -moz-linear-gradient(#9d9fc5, #7f82ac);
- background: -ms-linear-gradient(#9d9fc5, #7f82ac);
- background: linear-gradient(#9d9fc5, #7f82ac);
-}
-.point-of-sale .input-button {
- font-size: 24px;
-}
-.point-of-sale .mode-button, .point-of-sale #numpad-delete, .point-of-sale #numpad-minus {
- font-size: 14px;
-}
-
-/* ********* The right pane contains the screens and headers ********* */
-
-.point-of-sale #rightpane {
- position: absolute;
- top: 0;
- /*bottom: 105px;*/
- bottom:0;
- left: 440px;
- right: 0;
- vertical-align: top;
-}
-
-.point-of-sale #rightpane header {
- padding: 0;
- height: 32px;
- border-bottom: 1px solid #cecbcb;
- background: #d3d3d3;
- background: -moz-linear-gradient(white, #d3d3d3);
- background: -webkit-gradient(linear, left top, left bottom, from(white), to(#d3d3d3));
-}
-
-/* ********* The product list ********* */
-
-.point-of-sale .product-list {
- padding:10px;
-}
-
-.point-of-sale .product-list-scroller{
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- -ms-box-sizing: border-box;
- box-sizing: border-box;
- width:100%;
- height:100%;
- overflow: hidden;
-}
-.point-of-sale .product-list-container {
- position:absolute;
- top:0px;
- bottom:0px;
- left:0px;
- right:0px;
- background: #eeedff;
-}
-
-/* a) the product list navigation bar */
-
-.point-of-sale .breadcrumb li {
- float: left;
- line-height: 32px;
- height: 32px;
-}
-.point-of-sale .breadcrumb li:last-child {
- padding-right: 3px;
- border-right: 1px solid #c5c5c5;
-}
-.point-of-sale .breadcrumb a {
- display: inline-block;
- padding: 0 9px;
- vertical-align: top;
- text-shadow: #f7f7f7 0 1px 1px;
- color: #555555;
- font-weight: bold;
-}
-.point-of-sale .bc-arrow {
- height: 33px;
-}
-.point-of-sale .homeimg {
- width: 19px;
- height: 19px;
- margin: 6px 0;
-}
-
-/* b) the search box */
-
-.point-of-sale .searchbox {
- position: absolute;
- right: 2px;
-}
-.point-of-sale .searchbox input {
- width: 130px;
- border-radius: 11px;
- border: 1px solid #cecbcb;
- padding: 3px 19px;
- margin: 6px;
- background: url("../img/search.png") no-repeat 5px;
- background-color: white;
-}
-.point-of-sale .search-clear {
- position: absolute;
- top: 11px;
- right: 11px;
- cursor: pointer;
- display: none;
-}
-
-/* c) the categories list */
-
-.point-of-sale #categories {
- /*background:#f0f0f0;*/
- position: relative;
- background-image: url('../img/bg.png');
- border-bottom: 1px solid #cecbcb;
-}
-.point-of-sale #categories .white-gradient{
- position: absolute;
- top:50%;
- left:0;
- right:0;
- bottom:0;
- background: -webkit-linear-gradient(bottom,rgba(255,255,255,0.5),rgba(255,255,255,0));
- background: -moz-linear-gradient(bottom,rgba(255,255,255,0.5),rgba(255,255,255,0));
- background: -ms-linear-gradient(bottom,rgba(255,255,255,0.5),rgba(255,255,255,0));
- background: linear-gradient(bottom,rgba(255,255,255,0.5),rgba(255,255,255,0));
-}
-.point-of-sale #categories h4 {
- display: inline-block;
- margin: 9px 5px;
-}
-
-.point-of-sale .category-list{
- padding:10px;
-}
-/* d) the category button */
-
-.point-of-sale .category-button {
- position: relative;
- vertical-align: top;
- display: inline-block;
- font-size: 11px;
- margin: 5px;
- width: 120px;
- height:120px;
- background:#fff;
- border: 1px solid #fff;
- border-radius: 3px;
- -webkit-box-shadow: 0px 1px 8px rgba(0,0,0,0.2);
- -moz-box-shadow: 0px 1px 8px rgba(0,0,0,0.2);
- box-shadow: 0px 1px 8px rgba(0,0,0,0.2);
- cursor: pointer;
-}
-
-.point-of-sale .category-simple-button{
- position: relative;
- display: inline-block;
- font-size: 14px;
- margin-right:10px;
- padding:5px;
-
- cursor: pointer;
- border: 1px solid #cacaca;
- border-radius: 4px;
-
- background: #e2e2e2;
- background: -webkit-linear-gradient(#f0f0f0, #e2e2e2);
- background: -moz-linear-gradient(#f0f0f0, #e2e2e2);
- background: -ms-linear-gradient(#f0f0f0, #e2e2e2);
- background: linear-gradient(#f0f0f0, #e2e2e2);
- -webkit-box-shadow: 0px 2px 2px rgba(0,0,0, 0.1);
- -moz-box-shadow: 0px 2px 2px rgba(0,0,0, 0.1);
- box-shadow: 0px 2px 2px rgba(0,0,0, 0.1);
-}
-
-.point-of-sale .category-button .category-img {
- position: relative;
- width: 120px;
- height: 100px;
- text-align: center;
- cursor: pointer;
-}
-
-.point-of-sale .category-button .category-img img {
- max-height: 100px;
- max-width: 120px;
-}
-
-.point-of-sale .category-button .category-name {
- position: absolute;
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- -ms-box-sizing: border-box;
- box-sizing: border-box;
- top:auto;
- left: 2px;
- right: 2px;
- bottom: 2px;
- background: #8a89ba; /*-webkit-linear-gradient(-90deg,rgba(138,137,186,0),rgba(138,137,186,1), rgba(138,137,186,1));*/
- padding: 3px;
- /*color:#8a89ba;*/
- color: #FFF;
- cursor: pointer;
- border-radius: 3px;
-}
-
-/* e) the product */
-
-.point-of-sale .product {
- position:relative;
- vertical-align: top;
- display: inline-block;
- line-height: 100px;
- font-size: 11px;
- margin: 5px;
- width: 120px;
- height:120px;
- background:#fff;
- border: 1px solid #fff;
- border-radius: 3px;
- -webkit-box-shadow: 0px 1px 8px rgba(127,130,172,0.4);
- -moz-box-shadow: 0px 1px 8px rgba(127,130,172,0.4);
- box-shadow: 0px 1px 8px rgba(127,130,172,0.4);
-}
-
-.point-of-sale .product .product-img {
- position: relative;
- width: 120px;
- height: 100px;
- background: white;
- text-align: center;
-}
-
-.point-of-sale .product .product-img img {
- max-height: 100px;
- max-width: 120px;
-}
-
-.point-of-sale .product .price-tag {
- position: absolute;
- top: 2px;
- right: 2px;
- vertical-align: top;
- color: white;
- line-height: 14px;
- background: #7f82ac;
- padding: 2px 5px;
- border-radius: 3px;
-}
-
-.point-of-sale .product .product-name {
- position: absolute;
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- -ms-box-sizing: border-box;
- box-sizing: border-box;
- bottom:0;
- top:auto;
- line-height: 14px;
- width:100%;
- background: -webkit-linear-gradient(-90deg,rgba(255,255,255,0),rgba(255,255,255,1), rgba(255,255,255,1));
- background: -moz-linear-gradient(-90deg,rgba(255,255,255,0),rgba(255,255,255,1), rgba(255,255,255,1));
- background: -ms-linear-gradient(-90deg,rgba(255,255,255,0),rgba(255,255,255,1), rgba(255,255,255,1));
- background: linear-gradient(-90deg,rgba(255,255,255,0),rgba(255,255,255,1), rgba(255,255,255,1));
- /*background:#FFF;*/
- padding: 3px;
- padding-top:15px;
-}
-
-
-/* ********* The Screens ********* */
-
-.point-of-sale .screen {
- position:absolute;
- text-align: center;
- top:0px;
- bottom:0px;
- width:100%;
-}
-.point-of-sale .screen header h2 {
- margin-top: 0px;
- padding-top: 7px;
-}
-.point-of-sale .screen p{
- font-size: 18px;
-}
-
-/* a) Layout for the Product Screen */
-
-.point-of-sale .screen .layout-table {
- border:none;
- width:100%;
- height:100%;
-}
-
-.point-of-sale .screen .header-row {
- border:none;
- width:100%;
- height:0px;
-}
-
-.point-of-sale .screen .header-cell{
- border:none;
- width:100%;
- height:0px;
-}
-.point-of-sale .screen .content-row {
- width:100%;
- height:100%;
-}
-.point-of-sale .screen .content-cell{
- width:100%;
-}
-.point-of-sale .screen .content-cell .content-container{
- height:100%;
- position:relative;
-}
-
-/* b) The payment screen */
-
-.point-of-sale .pos-step-container {
- display: inline-block;
- font-size: 1.5em;
-}
-.point-of-sale .greyed-out{
- color: #AAA;
-}
-.point-of-sale .pos-step-container input{
- font-size: 1em;
-}
-
-.point-of-sale .pos-payment-container {
- text-align: left;
- min-width: 500px;
-}
-.point-of-sale .pos-payment-container .left-block{
- display: inline-block;
- width:49%;
- margin:0;
- padding:0;
- text-align:left;
-}
-.point-of-sale .pos-payment-container .header{
- margin-top: 50px;
- margin-bottom:20px;
- font-weight: bold;
-}
-.point-of-sale .pos-payment-container .infoline{
- margin-top:5px;
- margin-bottom:5px;
-}
-.point-of-sale .pos-payment-container .right-block{
- display: inline-block;
- width:49%;
- margin:0;
- padding:0;
- text-align:right;
-}
-.point-of-sale .pos-payment-container table {
- width: 100%;
- margin-bottom: 20px;
-}
-.point-of-sale .pos-payment-container td {
- vertical-align: middle;
-}
-.point-of-sale .pos-payment-container .paymentline-type {
- font-size: 1em;
- font-weight: bold;
- margin-right:10px;
-}
-
-/* c) The receipt screen */
-
-.point-of-sale .pos-receipt-container {
- font-size: 0.75em;
-}
-
-.point-of-sale .pos-sale-ticket {
- text-align: left;
- width: 300px;
- background-color: white;
- margin: 20px;
- padding: 15px;
- padding-bottom:30px;
- display: inline-block;
- font-family: "Inconsolata";
- -webkit-box-shadow: 0px 5px 16px rgba(0,0,0, 0.3);
- -moz-box-shadow: 0px 5px 16px rgba(0,0,0, 0.3);
- box-shadow: 0px 5px 16px rgba(0,0,0, 0.3);
-}
-.point-of-sale .pos-sale-ticket .emph{
- font-size: 20px;
- margin:5px;
-}
-.point-of-sale .pos-sale-ticket table {
- width: 100%;
- border: 0;
-}
-.point-of-sale .pos-sale-ticket table td {
- border: 0;
-}
-
-@media print {
- .point-of-sale #topheader, .point-of-sale #leftpane {
- display: none !important;
- }
- .point-of-sale #content {
- top: 0px !important;
- }
- .point-of-sale #rightpane {
- left: 0px !important;
- background-color: white;
- }
- #receipt-screen header {
- display: none !important;
- }
- #receipt-screen {
- text-align: left;
- }
- .pos-sale-ticket {
- margin: 0;
- }
-}
-
-/* d) The Scale screen */
-
-.point-of-sale .scale-screen .display{
- position:relative;
- width:600px;
- height:190px;
- margin-top: 100px;
- margin-left: auto;
- margin-right: auto;
-}
-
-.point-of-sale .scale-screen .product-picture {
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- -ms-box-sizing: border-box;
- box-sizing: border-box;
- display: float;
- float: right;
- margin: 5px;
- width: 180px;
- height:180px;
- line-height:180px;
- cursor:pointer;
-
- background:#fff;
- border: 1px solid #fff;
- border-radius: 3px;
- -webkit-box-shadow: 0px 1px 8px rgba(0,0,0,0.2);
- -moz-box-shadow: 0px 1px 8px rgba(0,0,0,0.2);
- box-shadow: 0px 1px 8px rgba(0,0,0,0.2);
-}
-
-.point-of-sale .scale-screen .product-picture img{
- vertical-align: middle;
- cursor:pointer;
-}
-
-.point-of-sale .scale-screen .product-picture .product-price{
- position: absolute;
- top:8px;
- right:8px;
- width:auto;
- height:auto;
- line-height:1;
- color:white;
- background: #7f82ac;
- padding: 2px 5px;
- border-radius: 3px;
- cursor:pointer;
-}
-
-.point-of-sale .scale-screen .product-name {
- position: absolute;
- left:0;
- top:20px;
- height:50px;
- font-size:40px;
- line-height:50px;
- text-align:right;
- right:225px;
-}
-.point-of-sale .scale-screen .weight{
- position: absolute;
- left:0;
- height:90px;
- bottom:15px;
- right:220px;
- padding:5px;
-}
-.point-of-sale .scale-screen .weight p{
- display: inline-block;
- text-align:right;
- line-height: 90px;
- font-size: 80px;
- width:100%;
- height:100%;
- margin:0;
- font-family: "Inconsolata";
-}
-
-/* e) The Welcome Screen */
-.point-of-sale .goodbye-message{
- position: absolute;
- left:50%;
- top:30%;
- width:500px;
- height:400px;
- margin-left: -250px;
- margin-top: -200px;
- padding:10px;
- padding-top:20px;
- text-align:center;
- font-size:20px;
- font-weight:bold;
- background-color: #F0EEEE;
- border: 1px solid #E0DDDD;
- -webkit-box-shadow: 0px 10px 20px rgba(0,0,0, 0.3);
- -moz-box-shadow: 0px 10px 20px rgba(0,0,0, 0.3);
- -ms-box-shadow: 0px 10px 20px rgba(0,0,0, 0.3);
- z-index:1150;
-}
-
-/* ********* The OrderWidget ********* */
-
-.point-of-sale .order-container{
- position: absolute;
- top: 0px;
- bottom: 232px;
- width:100%;
- background: #F0EEEE;
-}
-
-.point-of-sale .order-scroller{
- width:100%;
- height:100%;
- overflow:hidden;
-}
-
-.point-of-sale .order{
- background: #F00;
- background: -webkit-linear-gradient(0deg,rgba(245,245,245,1),rgba(255,255,255,1), rgba(245,245,245,1));
- background: -moz-linear-gradient(0deg,rgba(245,245,245,1),rgba(255,255,255,1), rgba(245,245,245,1));
- background: -ms-linear-gradient(0deg,rgba(245,245,245,1),rgba(255,255,255,1), rgba(245,245,245,1));
- background: linear-gradient(0deg,rgba(245,245,245,1),rgba(255,255,255,1), rgba(245,245,245,1));
- padding-bottom:15px;
- padding-top:15px;
- margin-left:16px;
- margin-right:16px;
- margin-top:16px;
- margin-bottom:16px;
- font-size:16px;
- -webkit-box-shadow: 0px 5px 16px rgba(0,0,0, 0.3);
- -moz-box-shadow: 0px 5px 16px rgba(0,0,0, 0.3);
- box-shadow: 0px 5px 16px rgba(0,0,0, 0.3);
-
-}
-
-.point-of-sale .order .empty{
- text-align:center;
- margin-top: 15px;
- margin-bottom: 5px;
- color:#999;
- font-weight: normal;
-}
-
-.point-of-sale .order .summary{
- width:100%;
- text-align:right;
- font-weight: bold;
- margin-top:20px;
- margin-bottom:10px;
-}
-.point-of-sale .order .summary .line{
- margin-right:15px;
- padding-top:5px;
- border-top: solid 2px;
- border-color:#777;
-}
-.point-of-sale .order .summary .line.empty{
- border-color:#BBB;
- color:#999;
-}
-
-/* ********* The OrderLineWidget ********* */
-
-.point-of-sale .order .orderline{
- width:100%;
- margin:0px;
- padding-top:3px;
- padding-bottom:10px;
- padding-left:15px;
- padding-right:15px;
- cursor: pointer;
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- -ms-box-sizing: border-box;
- box-sizing: border-box;
- -webkit-transition: background 250ms ease-in-out;
- -moz-transition: background 250ms ease-in-out;
- transition: background 250ms ease-in-out;
-}
-
-.point-of-sale .order .orderline.selected{
- background: rgba(140,143,183,0.2);
- -webkit-transition: background 250ms ease-in-out;
- -moz-transition: background 250ms ease-in-out;
- transition: background 250ms ease-in-out;
- cursor: default;
-}
-.point-of-sale .order .orderline .product-name{
- padding:0;
- display:inline-block;
- font-weight: bold;
- width:80%;
- overflow:hidden;
-}
-.point-of-sale .order .orderline .price{
- padding:0;
- font-weight: bold;
- float:right;
-}
-.point-of-sale .order .orderline .info-list{
- color: #888;
- margin-left:10px;
-}
-.point-of-sale .order .orderline .info-list em{
- color: #777;
- font-weight: bold;
- font-style:normal;
-}
-
-/* ********* The ActionBarWidget ********* */
-
-.point-of-sale .pos-actionbar{
- position:absolute;
- left: 0;
- bottom: 0px;
- height: 105px;
- width: 100%;
- margin: 0;
- background: #f5f5f5; /*#ebebeb;*/
- border-top: solid 1px #afafb6;
- z-index:900;
-}
-
-.point-of-sale .pos-actionbar ul{
- list-style: none;
-}
-
-.point-of-sale .pos-actionbar-left-pane{
- height: 100%;
- width: 434px;
- margin: 0px;
- padding-left:3px;
- padding-right:3px;
- border-right: solid 1px #dfdfdf;
- float: left;
-}
-
-.point-of-sale .pos-actionbar-button-list{
- height: 100%;
- margin: 0px;
- padding-left:3px;
- padding-right:3px;
- overflow:hidden;
-}
-
-.point-of-sale .pos-actionbar .button{
- width: 90px;
- height: 90px;
- text-align:center;
- margin:3px;
- margin-top:6px;
- float:left;
-
- font-size: 14px;
- font-weight: bold;
-
- cursor: pointer;
-
- border: 1px solid #cacaca;
- border-radius: 4px;
-
- background: #e2e2e2;
- background: -webkit-linear-gradient(#f0f0f0, #e2e2e2);
- background: -moz-linear-gradient(#f0f0f0, #e2e2e2);
- background: -ms-linear-gradient(#f0f0f0, #e2e2e2);
- background: linear-gradient(#f0f0f0, #e2e2e2);
- -webkit-box-shadow: 0px 2px 2px rgba(0,0,0, 0.1);
- -moz-box-shadow: 0px 2px 2px rgba(0,0,0, 0.1);
- box-shadow: 0px 2px 2px rgba(0,0,0, 0.1);
-}
-.point-of-sale .pos-actionbar .button .label{
- margin-top: 37px;
-}
-.point-of-sale .pos-actionbar .button .icon{
- margin-top: 10px;
-}
-
-.point-of-sale .pos-actionbar .button.disabled *{
- opacity: 0.5;
-}
-
-.point-of-sale .pos-actionbar .button.rightalign{
- float:right;
-}
-
-/* ********* The PopupWidgets ********* */
-
-.point-of-sale .modal-dialog{
- position: absolute;
- left: 0;
- top: 0;
- width: 100%;
- height:100%;
- background-color: rgba(0,0,0,0.5);
- z-index:1000;
-}
-.point-of-sale .modal-dialog .popup{
- position: absolute;
- left:50%;
- top:50%;
- width:500px;
- height:400px;
- margin-left: -250px;
- margin-top: -200px;
- padding:10px;
- padding-top:20px;
- text-align:center;
- font-size:20px;
- font-weight:bold;
- background-color: #F0EEEE;
- border: 1px solid #E0DDDD;
- -webkit-box-shadow: 0px 10px 20px rgba(0,0,0, 0.3);
- -moz-box-shadow: 0px 10px 20px rgba(0,0,0, 0.3);
- -ms-box-shadow: 0px 10px 20px rgba(0,0,0, 0.3);
- z-index:1200;
-}
-.point-of-sale .popup .footer{
- position:absolute;
- bottom:0;
- left:0;
- width:100%;
- height:60px;
- border-top: 1px solid #E0DDDD;
-}
-.point-of-sale .popup .button{
- float:right;
- width: 110px;
- height: 40px;
- line-height:40px;
- text-align:center;
- margin:3px;
- margin-top:10px;
- margin-right:10px;
-
- font-size: 14px;
- font-weight: bold;
-
- cursor: pointer;
-
- border: 1px solid #cacaca;
- border-radius: 4px;
-
- background: #e2e2e2;
- background: -webkit-linear-gradient(#f0f0f0, #e2e2e2);
- background: -moz-linear-gradient(#f0f0f0, #e2e2e2);
- background: -ms-linear-gradient(#f0f0f0, #e2e2e2);
- background: linear-gradient(#f0f0f0, #e2e2e2);
- -webkit-box-shadow: 0px 2px 2px rgba(0,0,0, 0.3);
- -moz-box-shadow: 0px 2px 2px rgba(0,0,0, 0.3);
- box-shadow: 0px 2px 2px rgba(0,0,0, 0.3);
-}
-
-.point-of-sale .popup .button.big-left{
- position:absolute;
- top: 120px;
- left:40px;
- width: 180px;
- height: 180px;
- line-height:180px;
-}
-
-.point-of-sale .popup .button.big-right{
- position:absolute;
- top: 120px;
- right:40px;
- width: 180px;
- height: 180px;
- line-height:180px;
-}
-
-/* ********* The ScrollBarWidget ********* */
-
-.point-of-sale .scrollbar{
- position:absolute;
- top:7px;
- right:7px;
- width:48px;
- bottom:7px;
- background: rgba(0,0,0,0.1);
-
-}
-.point-of-sale .scrollbar .button{
- width:100%;
- height: 48px;
- line-height: 38px;
- text-align: center;
- font-size:48px;
- border-radius: 4px;
- cursor: pointer;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- transition: all 250ms ease-in-out;
-}
-.point-of-sale .scrollbar .button{
- color:white;
- background: rgba(0,0,0,0.6);
- -webkit-box-shadow: 0px 1px 4px rgba(0,0,0,0.01);
- -moz-box-shadow: 0px 1px 4px rgba(0,0,0,0.01);
- box-shadow: 0px 1px 4px rgba(0,0,0,0.01);
- text-shadow: rgba(255,255,255,0.5) 0px 0px 10px;
- -webkit-transition: all 250ms ease-in-out;
- -moz-transition: all 250ms ease-in-out;
- transition: all 250ms ease-in-out;
-}
-.point-of-sale .scrollbar .button.disabled{
- background: rgba(0,0,0,0.3);
- color:rgba(255,255,255,0.5);
- -webkit-transition: all 250ms ease-in-out;
- -moz-transition: all 250ms ease-in-out;
- transition: all 250ms ease-in-out;
-}
-.point-of-sale .scrollbar .down-button{
- position:absolute;
- bottom:0px;
-}
-.point-of-sale .scrollbar .up-button{
- position:absolute;
- top:0px;
-}
-.point-of-sale .scrollbar .scroller{
- position:absolute;
- top:33%;
- bottom:50%;
- width:100%;
- background: rgba(0,0,0,0.1);
- border-radius: 4px;
-}
-
+++ /dev/null
-v Affichage Catégories doivent respecter le poids
-v Affichage Catégories par poids doivent avoir une hiérarchie plate
-v Le Onscreen keyboard ne fonctionne plus
-v Scrolling dans la sélection produit et dans
- la liste de courses
-v Réductions
-v Redesign liste de courses
-v bugs scans produits par prix par poids
-v si pas photo photo par defaut
-v WebSQL
-v Redesign header, bouton retour aux backend en mode caissière
-v bouton exit en mode caissière doit retourner au backend.
-v posting orders
-v bug ajout ligne payment à zero + curseur dedans + suppression + design plus grand
-v si case print via proxy cochée, alors on skip l'ecran receipt
-v bouton exit self checkout
-v demarrage en mode self-checkout si self-checkout
-v produits poid code barre non reconnus
-v activer popup client aux écrans self-checkout
-v discount pas plus grand que 100
-v numpad dans l'écran payment pour pouvoir entrer le montant
-v différence de total. Methode d'arrondis
-
-- login alternatif
-- user preferences : désactiver la balance etc.
-- numpad state parfois sans state
-- numpad state en mode pesée ?? le cacher ?
-- Redesign du receipt
-- retirer le receipt screen
-- le numpad en mode paymenet marche pas
-- l'écran de payement est hyper laid
-- l'écran de pesée est hyper laid
-x générer les données de printing
-x popups d'erreur certainement buggés
-
-TODO AUG 20
------------
-
-* GREEN STATUS
- - make it green !
-
-* TRUNK
- - Connection status tooltip
- v Remove receipt screen
- - Finish the receipt JSON generation
- - Modifie le widget de liste course
- v supprimer l'écran
- v bloquer sur l'impression
- v L'impression est foireuse
- - description_sales
-
-* CLIENT
- v create a new branch
- - Self-checkout welcome screen
- ~ removal of products for the root category
- - Terminal de payement
- - Code à barres
- - Vidanges
- - Design
- - Backport
- - CSS pour écran résistif
- - Test sur matos
-
'orders': new module.OrderCollection(),
//this is the product list as seen by the product list widgets, it will change based on the category filters
- 'products': new module.ProductCollection(),
'cashRegisters': null,
'bank_statements': null,
}
if(parsed_code.type === 'price'){
- selectedOrder.addProduct(new module.Product(product), {price:parsed_code.value});
+ selectedOrder.addProduct(product, {price:parsed_code.value});
}else if(parsed_code.type === 'weight'){
- selectedOrder.addProduct(new module.Product(product), {quantity:parsed_code.value, merge:false});
+ selectedOrder.addProduct(product, {quantity:parsed_code.value, merge:false});
}else{
- selectedOrder.addProduct(new module.Product(product));
+ selectedOrder.addProduct(product);
}
return true;
},
model: module.CashRegister,
});
- module.Product = Backbone.Model.extend({
- get_image_url: function(){
- return instance.session.url('/web/binary/image', {model: 'product.product', field: 'image_medium', id: this.get('id')});
- },
- });
-
- module.ProductCollection = Backbone.Collection.extend({
- model: module.Product,
- });
-
// An orderline represent one element of the content of a client's shopping cart.
// An orderline contains a product, its quantity, its price, discount. etc.
// An Order contains zero or more Orderlines.
this.pos = options.pos;
this.order = options.order;
this.product = options.product;
- this.price = options.product.get('price');
+ this.price = options.product.price;
this.quantity = 1;
this.quantityStr = '1';
this.discount = 0;
var disc = Math.min(Math.max(parseFloat(discount) || 0, 0),100);
this.discount = disc;
this.discountStr = '' + disc;
- this.trigger('change');
+ this.trigger('change',this);
},
// returns the discount [0,100]%
get_discount: function(){
this.quantityStr = '' + this.quantity;
}
}
- this.trigger('change');
+ this.trigger('change',this);
},
// return the quantity of product
get_quantity: function(){
},
// return the unit of measure of the product
get_unit: function(){
- var unit_id = (this.product.get('uos_id') || this.product.get('uom_id'));
+ var unit_id = (this.product.uos_id || this.product.uom_id);
if(!unit_id){
return undefined;
}
// selects or deselects this orderline
set_selected: function(selected){
this.selected = selected;
- this.trigger('change');
+ this.trigger('change',this);
},
// returns true if this orderline is selected
is_selected: function(){
// when we add an new orderline we want to merge it with the last line to see reduce the number of items
// in the orderline. This returns true if it makes sense to merge the two
can_be_merged_with: function(orderline){
- if( this.get_product().get('id') !== orderline.get_product().get('id')){ //only orderline of the same product can be merged
+ if( this.get_product().id !== orderline.get_product().id){ //only orderline of the same product can be merged
return false;
}else if(this.get_product_type() !== orderline.get_product_type()){
return false;
qty: this.get_quantity(),
price_unit: this.get_unit_price(),
discount: this.get_discount(),
- product_id: this.get_product().get('id'),
+ product_id: this.get_product().id,
};
},
//used to create a json of the ticket, to be sent to the printer
unit_name: this.get_unit().name,
price: this.get_unit_price(),
discount: this.get_discount(),
- product_name: this.get_product().get('name'),
+ product_name: this.get_product().name,
price_display : this.get_display_price(),
price_with_tax : this.get_price_with_tax(),
price_without_tax: this.get_price_without_tax(),
tax: this.get_tax(),
- product_description: this.get_product().get('description'),
- product_description_sale: this.get_product().get('description_sale'),
+ product_description: this.get_product().description,
+ product_description_sale: this.get_product().description_sale,
};
},
// changes the base price of the product for this orderline
set_unit_price: function(price){
this.price = round_di(parseFloat(price) || 0, 2);
- this.trigger('change');
+ this.trigger('change',this);
},
get_unit_price: function(){
var rounding = this.pos.get('currency').rounding;
var product_list = this.pos.get('product_list');
var product = this.get_product();
- var taxes_ids = product.get('taxes_id');;
- var taxes = self.pos.get('taxes');
+ var taxes_ids = product.taxes_id;
+ var taxes = self.pos.taxes;
var taxtotal = 0;
_.each(taxes_ids, function(el) {
var tax = _.detect(taxes, function(t) {return t.id === el;});
},
addProduct: function(product, options){
options = options || {};
- var attr = product.toJSON();
+ var attr = JSON.parse(JSON.stringify(product));
attr.pos = this.pos;
attr.order = this;
var line = new module.Orderline({}, {pos: this.pos, order: this, product: product});
this.selected_orderline = undefined;
}
},
+ deselectLine: function(){
+ if(this.selected_orderline){
+ this.selected_orderline.set_selected(false);
+ this.selected_orderline = undefined;
+ }
+ },
});
module.OrderCollection = Backbone.Collection.extend({
}
var cashregister = selfCheckoutRegisters[0] || self.pos.get('cashRegisters').models[0];
- currentOrder.addPaymentLine(cashregister);
+ currentOrder.add_payment_line(cashregister);
self.pos.push_order(currentOrder)
currentOrder.destroy();
self.pos.proxy.transaction_end();
start: function(){ //FIXME this should work as renderElement... but then the categories aren't properly set. explore why
var self = this;
- this.product_categories_widget = new module.ProductCategoriesWidget(this,{});
- this.product_categories_widget.replace($('.placeholder-ProductCategoriesWidget'));
this.product_list_widget = new module.ProductListWidget(this,{
click_product_action: function(product){
- if(product.get('to_weight') && self.pos.iface_electronic_scale){
+ if(product.to_weight && self.pos.iface_electronic_scale){
self.pos_widget.screen_selector.set_current_screen( self.cashier_mode ? self.scale_screen : self.client_scale_screen, {product: product});
}else{
self.pos.get('selectedOrder').addProduct(product);
}
},
+ product_list: this.pos.db.get_product_by_category(0)
});
this.product_list_widget.replace($('.placeholder-ProductListWidget'));
+
+ this.product_categories_widget = new module.ProductCategoriesWidget(this,{
+ product_list_widget: this.product_list_widget,
+ });
+ this.product_categories_widget.replace($('.placeholder-ProductCategoriesWidget'));
},
show: function(){
this.product_categories_widget.reset_category();
- this.pos_widget.order_widget.set_numpad_state(this.pos_widget.numpad.state);
+ this.pos_widget.order_widget.set_editable(true);
if(this.pos_widget.screen_selector.current_mode === 'client'){
this.add_action_button({
close: function(){
this._super();
- this.pos_widget.order_widget.set_numpad_state(null);
- this.pos_widget.payment_screen.set_numpad_state(null);
+
+ this.pos_widget.order_widget.set_editable(false);
+
if(this.pos.iface_vkeyboard && this.pos_widget.onscreen_keyboard){
this.pos_widget.onscreen_keyboard.hide();
}
},
-
});
module.ReceiptScreenWidget = module.ScreenWidget.extend({
this._super();
var self = this;
- this.pos_widget.set_numpad_visible(false);
-
var print_button = this.add_action_button({
label: _t('Print'),
icon: '/point_of_sale/static/src/img/icons/png48/printer.png',
},
close: function(){
this._super();
- this.pos_widget.set_numpad_visible(true);
}
});
this._super(parent,options);
this.model = options.model;
this.pos.bind('change:selectedOrder', this.change_selected_order, this);
- this.bindPaymentLineEvents();
+ this.bind_payment_line_events();
this.bind_orderline_events();
this.paymentlinewidgets = [];
this.focusedLine = null;
this.hotkey_handler = function(event){
if(event.which === 13){
- self.validateCurrentOrder();
+ self.validate();
}else if(event.which === 27){
self.back();
}
this.pos.proxy.open_cashbox();
}
- this.set_numpad_state(this.pos_widget.numpad.state);
-
+ this.enable_numpad();
+
this.add_action_button({
label: _t('Back'),
icon: '/point_of_sale/static/src/img/icons/png48/go-previous.png',
name: 'validation',
icon: '/point_of_sale/static/src/img/icons/png48/validate.png',
click: function(){
- self.validateCurrentOrder();
+ self.validate();
},
});
name: 'invoice',
icon: '/point_of_sale/static/src/img/icons/png48/invoice.png',
click: function(){
- self.validateCurrentOrder({invoice: true});
+ self.validate({invoice: true});
},
});
}
});
}
- this.updatePaymentSummary();
+ this.update_payment_summary();
this.line_refocus();
},
close: function(){
this._super();
- this.pos_widget.order_widget.set_numpad_state(null);
- this.pos_widget.payment_screen.set_numpad_state(null);
+ this.disable_numpad();
$('body').off('keyup',this.hotkey_handler);
},
back: function() {
});
this.pos_widget.screen_selector.set_current_screen(this.back_screen);
},
- validateCurrentOrder: function(options) {
+ validate: function(options) {
var self = this;
options = options || {};
var currentOrder = this.pos.get('selectedOrder');
- if(!this.isPaymentPaid()){
+ if(!this.is_paid()){
return;
}
$("input").blur();
},250);
},
- bindPaymentLineEvents: function() {
+ bind_payment_line_events: function() {
this.currentPaymentLines = (this.pos.get('selectedOrder')).get('paymentLines');
- this.currentPaymentLines.bind('add', this.addPaymentLine, this);
+ this.currentPaymentLines.bind('add', this.add_payment_line, this);
this.currentPaymentLines.bind('remove', this.renderElement, this);
- this.currentPaymentLines.bind('all', this.updatePaymentSummary, this);
+ this.currentPaymentLines.bind('all', this.update_payment_summary, this);
},
bind_orderline_events: function() {
this.currentOrderLines = (this.pos.get('selectedOrder')).get('orderLines');
- this.currentOrderLines.bind('all', this.updatePaymentSummary, this);
+ this.currentOrderLines.bind('all', this.update_payment_summary, this);
},
change_selected_order: function() {
this.currentPaymentLines.unbind();
- this.bindPaymentLineEvents();
+ this.bind_payment_line_events();
this.currentOrderLines.unbind();
this.bind_orderline_events();
this.renderElement();
this.focusedLine.focus();
}
},
- addPaymentLine: function(newPaymentLine) {
+ add_payment_line: function(newPaymentLine) {
var self = this;
var l = new module.PaymentlineWidget(this, {
payment_line: newPaymentLine,
this.paymentlinewidgets = [];
this.currentPaymentLines.each(_.bind( function(paymentLine) {
- this.addPaymentLine(paymentLine);
+ this.add_payment_line(paymentLine);
}, this));
- this.updatePaymentSummary();
+ this.update_payment_summary();
},
deleteLine: function(lineWidget) {
this.currentPaymentLines.remove([lineWidget.payment_line]);
lineWidget.destroy();
},
- isPaymentPaid: function(){
+ is_paid: function(){
var currentOrder = this.pos.get('selectedOrder');
return (currentOrder.getTotalTaxIncluded() >= 0.000001
&& currentOrder.getPaidTotal() + 0.000001 >= currentOrder.getTotalTaxIncluded());
},
- updatePaymentSummary: function() {
+ update_payment_summary: function() {
var currentOrder = this.pos.get('selectedOrder');
var paidTotal = currentOrder.getPaidTotal();
var dueTotal = currentOrder.getTotalTaxIncluded();
}
if(this.pos_widget.action_bar){
- this.pos_widget.action_bar.set_button_disabled('validation', !this.isPaymentPaid());
- this.pos_widget.action_bar.set_button_disabled('invoice', !this.isPaymentPaid());
+ this.pos_widget.action_bar.set_button_disabled('validation', !this.is_paid());
+ this.pos_widget.action_bar.set_button_disabled('invoice', !this.is_paid());
+ }
+ },
+ enable_numpad: function(){
+ this.disable_numpad(); //ensure we don't register the callbacks twice
+ this.numpad_state = this.pos_widget.numpad.state;
+ if(this.numpad_state){
+ this.numpad_state.reset();
+ this.numpad_state.changeMode('payment');
+ this.numpad_state.bind('set_value', this.set_value, this);
+ this.numpad_state.bind('change:mode', this.set_mode_back_to_payment, this);
+ }
+
+ },
+ disable_numpad: function(){
+ if(this.numpad_state){
+ this.numpad_state.unbind('set_value', this.set_value);
+ this.numpad_state.unbind('change:mode',this.set_mode_back_to_payment);
}
},
- set_numpad_state: function(numpadState) {
- if (this.numpadState) {
- this.numpadState.unbind('set_value', this.set_value);
- this.numpadState.unbind('change:mode', this.setNumpadMode);
- }
- this.numpadState = numpadState;
- if (this.numpadState) {
- this.numpadState.bind('set_value', this.set_value, this);
- this.numpadState.bind('change:mode', this.setNumpadMode, this);
- this.numpadState.reset();
- this.setNumpadMode();
- }
- },
- setNumpadMode: function() {
- this.numpadState.set({mode: 'payment'});
+ set_mode_back_to_payment: function() {
+ this.numpad_state.set({mode: 'payment'});
},
set_value: function(val) {
this.currentPaymentLines.last().set_amount(val);
+++ /dev/null
-/*
- * This Widget provides a javascript scrollbar that is suitable to use with resistive
- * tactile screens.
- *
- * Options:
- * target_widget : the widget that will be scrolled.
- * target_selector : if you don't want to scroll the root element of the the widget, you can provide a
- * jquery selector string that will match on the widget's dom element. If there is no widget provided,
- * it will match on the document
- * step: on each click, the target will be scrolled by it's deplayed size multiplied by this value.
- * duration: this is the duration of the scrolling animation
- * wheel_step: the target will be scrolled by wheel_step pixels on each mouse scroll.
- * track_bottom: the target will be kept on bottom when it's on the bottom and the size has changed
- * on_show: this function will be called with the scrollbar as sole argument when the scrollbar is shown
- * on_hide: this function will be called with the scrollbar as sole argument when the scrollbar is hidden
- */
-function openerp_pos_scrollbar(instance, module){ //module is instance.point_of_sale
-
- module.ScrollbarWidget = instance.web.Widget.extend({
- template:'ScrollbarWidget',
-
- init: function(parent,options){
- var self = this;
- options = options || {};
- this._super(parent,options);
- this.target_widget = options.target_widget;
- this.target_selector = options.target_selector;
- this.scroll_target = this.target().scrollTop();
- this.scroll_step = options.step || 0.8;
- this.scroll_duration = options.duration || 250;
- this.wheel_step = options.wheel_step || 80;
- this.name = options.name || 'unnamed';
- this.bottom = false; // true if the scroller cannot be scrolled further
- this.track_bottom = options.track_bottom || false;
- this.on_show = options.on_show || function(){};
- this.on_hide = options.on_hide || function(){};
-
- // these handlers are declared once for the object's lifetime so that we can bind and unbind them.
- this.resize_handler = function(){
- setTimeout(function(){
- if(self.bottom && self.track_bottom){
- self.set_position(Number.MAX_VALUE);
- }
- self.update_scroller_dimensions();
- self.update_button_status();
- self.auto_hide(false);
- },0);
- };
- this.target_mousewheel_handler = function(event,delta){
- self.scroll(delta*self.wheel_step);
- }
- },
-
- renderElement: function(){
- this._super();
- var self = this;
- this.$('.up-button').off('click').click(function(){
- self.page_up();
- });
- this.$('.down-button').off('click').click(function(){
- self.page_down();
- });
- this.update_scroller_dimensions(false);
- this.update_button_status();
- this.auto_hide(false);
- this.$el.bind('mousewheel',function(event,delta){
- self.scroll(delta*self.wheel_step);
- return false;
- });
- this.$el.bind('click',function(event){
- var vpos = event.pageY - self.$el.offset().top;
- var spos = self.scroller_dimensions();
- if(vpos > spos.bar_pos && vpos < spos.pos){
- self.page_up();
- }else if( (vpos < spos.bar_pos + spos.bar_height) &&
- (vpos > spos.pos + spos.height) ){
- self.page_down();
- }
- });
- // FIXME: use the event bus to handle window resize events
- $(window).unbind('resize',this.resize_handler);
- $(window).bind('resize',this.resize_handler);
-
- this.target().unbind('mousewheel',this.target_mousewheel_handler);
- this.target().bind('mousewheel',this.target_mousewheel_handler);
-
- // because the rendering is asynchronous we must wait for the next javascript update
- // for good dimensions values
- setTimeout(function(){
- self.update_scroller_dimensions(false);
- self.update_button_status();
- self.auto_hide(false);
- },0);
- },
-
- destroy: function(){
- $(window).unbind('resize',this.resize_handler);
- this.target().unbind('mousewheel',this.target_mousewheel_handler);
- this._super();
- },
-
- // shows the scrollbar. if animated is true, it will do it in an animated fashion
- show: function(animated){ //FIXME: animated show and hide don't work ... ?
- if(animated){
- this.$el.removeClass('oe_hidden').animate({'width':'48px'}, 500, 'swing');
- }else{
- this.$el.removeClass('oe_hidden').css('width','48px');
- }
- this.on_show(this);
- },
-
- // hides the scrollbar. if animated is true, it will do it in a animated fashion
- hide: function(animated){
- var self = this;
- if(animated){
- this.$el.animate({'width':'0px'}, 500, 'swing', function(){ self.$el.addClass('oe_hidden');});
- }else{
- this.$el.addClass('oe_hidden').css('width','0px');
- }
- this.on_hide(this);
- },
-
- // returns the scroller position and other information as a dictionnary with the following fields:
- // pos: the position in pixels of the top of the scroller starting from the top of the scrollbar
- // height: the height of the scroller in pixels
- // bar_pos: the position of the top of the scrollbar's inner region, starting from the top
- // bar_height: the height of the scrollbar's inner region
- scroller_dimensions: function(){
- var target = this.target()[0];
- var scroller_height = target.clientHeight / target.scrollHeight || 0;
- var scroller_pos = this.scroll_target / target.scrollHeight || 0;
- var button_up_height = this.$('.up-button')[0].offsetHeight || 48;
- var button_down_height = this.$('.down-button')[0].offsetHeight || 48;
-
- var bar_height = this.$el[0].offsetHeight || 96;
- var scrollbar_height = bar_height - button_up_height - button_down_height;
-
- scroller_pos = scroller_pos * scrollbar_height + button_up_height;
- scroller_height = scroller_height * scrollbar_height;
-
- return { pos: Math.round(scroller_pos),
- height: Math.round(scroller_height),
- bar_pos: button_up_height,
- bar_height: scrollbar_height };
- },
-
-
- //checks if it should show or hide the scrollbar based on the target content and then show or hide it
- // if animated is true, then the scrollbar will be shown or hidden with an animation
- auto_hide: function(animated){
- var target = this.target()[0];
- if(target.clientHeight && (target.clientHeight === target.scrollHeight)){
- this.hide(animated);
- }else{
- this.show(animated);
- }
- },
-
- //returns the pageup/down scrolling distance in pixels
- get_scroll_step: function(){
- var target = this.target()[0];
- var step = target.clientHeight * this.scroll_step;
- var c = target.scrollHeight / step;
- var c = Math.max(1,Math.ceil(c));
- return target.scrollHeight / c;
- },
-
- //sets the scroller to the correct size and position based on the target scrolling status
- //if animated is true, the scroller will move smoothly to its destination
- update_scroller_dimensions: function(animated){
- var dim = this.scroller_dimensions();
- var target = this.target()[0];
- if(animated){
- this.$('.scroller').animate({'top':dim.pos+'px', 'height': dim.height+'px'},this.scroll_duration);
- }else{
- this.$('.scroller').css({'top':dim.pos+'px', 'height': dim.height+'px'});
- }
- if(this.scroll_target + target.clientHeight >= target.scrollHeight){
- this.bottom = true;
- }else{
- this.bottom = false;
- }
- },
-
- //disable or enable the up/down buttons according to the scrolled position
- update_button_status: function(){
- var target = this.target()[0];
- this.$('.up-button').removeClass('disabled');
- this.$('.down-button').removeClass('disabled');
- if(this.scroll_target === 0){
- this.$('.up-button').addClass('disabled');
- }
- if(this.scroll_target + target.clientHeight >= target.scrollHeight){
- this.$('.down-button').addClass('disabled');
- }
- },
-
- //returns the jquery object of the scrolling target
- target: function(){
- if(this.target_widget){
- if(this.target_selector){
- return this.target_widget.$(this.target_selector);
- }else{
- return this.target_widget.$el;
- }
- }else if(this.target_selector){
- return $(this.target_selector);
- }else{
- return undefined;
- }
- },
-
- //scroll one page up
- page_up: function(){
- return this.set_position(this.scroll_target - this.get_scroll_step(), true);
- },
-
- //scroll one page down
- page_down: function(){
- return this.set_position(this.scroll_target + this.get_scroll_step(), true);
- },
-
- //scrolls up or down by pixels
- scroll: function(pixels){
- return this.set_position(this.scroll_target - pixels, false);
- },
-
- //scroll to a specific position (in pixels).
- //if animated is true, it will do this in an animated fashion with a duration equal to scroll_duration
- set_position: function(position,animated){
- var self = this;
- var target = this.target()[0];
- var bottom = target.scrollHeight-target.clientHeight;
- this.scroll_target = Math.max(0,Math.min(bottom,position));
- if(this.scroll_target === 0){
- this.position = 'top';
- }else if(this.scroll_target === 'bottom'){
- this.position = 'bottom';
- }else{
- this.position = 'center';
- }
- if(animated){
- this.target().animate({'scrollTop':this.scroll_target},this.scroll_duration);
- this.update_button_status();
- this.update_scroller_dimensions(true);
- }else{
- this.target().scrollTop(this.scroll_target);
- this.update_scroller_dimensions(false);
- this.update_button_status();
- }
- return this.scroll_target;
- },
-
- //returns the current position of the scrollbar
- get_position: function(){
- return this.scroll_target;
- },
-
- //returns true if it cannot be scrolled further down
- is_at_bottom: function(){
- return this.bottom;
- }
-
- });
-}
init: function(parent, options) {
this._super(parent);
this.state = new module.NumpadState();
+ window.numpadstate = this.state;
+ var self = this;
+ this.state.bind('change:buffer',function(){
+ console.log('BUFFER:',self.state.get('buffer'));
+ })
},
start: function() {
this.state.bind('change:mode', this.changedMode, this);
},
});
- module.OrderlineWidget = module.PosBaseWidget.extend({
- template: 'OrderlineWidget',
- init: function(parent, options) {
- this._super(parent,options);
-
- this.model = options.model;
- this.order = options.order;
-
- this.model.bind('change', this.refresh, this);
- },
- renderElement: function() {
- var self = this;
- this._super();
- this.$el.click(function(){
- self.order.selectLine(self.model);
- self.trigger('order_line_selected');
- });
- if(this.model.is_selected()){
- this.$el.addClass('selected');
- }
- },
- refresh: function(){
- this.renderElement();
- this.trigger('order_line_refreshed');
- },
- destroy: function(){
- this.model.unbind('change',this.refresh,this);
- this._super();
- },
- });
-
module.OrderWidget = module.PosBaseWidget.extend({
template:'OrderWidget',
init: function(parent, options) {
+ var self = this;
this._super(parent,options);
- this.display_mode = options.display_mode || 'numpad'; // 'maximized' | 'actionbar' | 'numpad'
- this.set_numpad_state(options.numpadState);
+ this.editable = false;
this.pos.bind('change:selectedOrder', this.change_selected_order, this);
this.bind_orderline_events();
- this.orderlinewidgets = [];
+ this.line_click_handler = function(event){
+ if(!self.editable){
+ return;
+ }
+ self.pos.get('selectedOrder').selectLine(this.orderline);
+ self.pos_widget.numpad.state.reset();
+ };
+ },
+ enable_numpad: function(){
+ this.disable_numpad(); //ensure we don't register the callbacks twice
+ this.numpad_state = this.pos_widget.numpad.state;
+ if(this.numpad_state){
+ this.numpad_state.reset();
+ this.numpad_state.bind('set_value', this.set_value, this);
+ }
+
},
- set_numpad_state: function(numpadState) {
- if (this.numpadState) {
- this.numpadState.unbind('set_value', this.set_value);
- }
- this.numpadState = numpadState;
- if (this.numpadState) {
- this.numpadState.bind('set_value', this.set_value, this);
- this.numpadState.reset();
- }
+ disable_numpad: function(){
+ if(this.numpad_state){
+ this.numpad_state.unbind('set_value', this.set_value);
+ this.numpad_state.reset();
+ }
+ },
+ set_editable: function(editable){
+ this.editable = editable;
+ if(editable){
+ this.enable_numpad();
+ }else{
+ this.disable_numpad();
+ this.pos.get('selectedOrder').deselectLine();
+ }
},
set_value: function(val) {
var order = this.pos.get('selectedOrder');
- if (order.get('orderLines').length !== 0) {
- var mode = this.numpadState.get('mode');
+ if (this.editable && order.getSelectedLine()) {
+ var mode = this.numpad_state.get('mode');
if( mode === 'quantity'){
order.getSelectedLine().set_quantity(val);
}else if( mode === 'discount'){
}
},
change_selected_order: function() {
- this.currentOrderLines.unbind();
this.bind_orderline_events();
this.renderElement();
},
bind_orderline_events: function() {
- this.currentOrderLines = (this.pos.get('selectedOrder')).get('orderLines');
- this.currentOrderLines.bind('add', function(){ this.renderElement(true);}, this);
- this.currentOrderLines.bind('remove', this.renderElement, this);
+ var lines = this.pos.get('selectedOrder').get('orderLines');
+ lines.unbind();
+ lines.bind('add', function(){
+ this.numpad_state.reset();
+ this.renderElement(true);
+ },this);
+ lines.bind('remove', function(line){
+ this.remove_orderline(line);
+ this.numpad_state.reset();
+ this.update_summary();
+ },this);
+ lines.bind('change', function(line){
+ this.rerender_orderline(line);
+ this.update_summary();
+ },this);
},
update_numpad: function() {
this.selected_line = this.pos.get('selectedOrder').getSelectedLine();
if (this.numpadState)
this.numpadState.reset();
},
- renderElement: function(goto_bottom) {
- var self = this;
- var scroller = this.$('.order-scroller')[0];
- var scrollbottom = true;
- var scrollTop = 0;
- if(scroller){
- var overflow_bottom = scroller.scrollHeight - scroller.clientHeight;
- scrollTop = scroller.scrollTop;
- if( !goto_bottom && scrollTop < 0.9 * overflow_bottom){
- scrollbottom = false;
- }
+ render_orderline: function(orderline){
+ var el_str = openerp.qweb.render('Orderline',{widget:this, line:orderline});
+ var el_node = document.createElement('div');
+ el_node.innerHTML = _.str.trim(el_str);
+ el_node = el_node.childNodes[0];
+ el_node.orderline = orderline;
+ el_node.addEventListener('click',this.line_click_handler);
+
+ orderline.node = el_node;
+ return el_node;
+ },
+ remove_orderline: function(order_line){
+ if(this.pos.get('selectedOrder').get('orderLines').length === 0){
+ this.renderElement();
+ }else{
+ order_line.node.parentNode.removeChild(order_line.node);
}
- this._super();
+ },
+ rerender_orderline: function(order_line){
+ var node = order_line.node;
+ var replacement_line = this.render_orderline(order_line);
+ node.parentNode.replaceChild(replacement_line,node);
+ },
+ replace: function($target){
+ this.renderElement();
+ var target = $target[0];
+ target.parentNode.replaceChild(this.el,target);
+ },
+ renderElement: function(scrollbottom){
+ this.pos_widget.numpad.state.reset();
- // freeing subwidgets
-
- for(var i = 0, len = this.orderlinewidgets.length; i < len; i++){
- this.orderlinewidgets[i].destroy();
+ var order = this.pos.get('selectedOrder');
+ var orderlines = order.get('orderLines').models;
+
+ var el_str = openerp.qweb.render('OrderWidget',{widget:this, order:order, orderlines:orderlines});
+ var el_node = document.createElement('div');
+ el_node.innerHTML = _.str.trim(el_str);
+ el_node = el_node.childNodes[0];
+
+ var list_container = el_node.querySelector('.orderlines');
+ for(var i = 0, len = orderlines.length; i < len; i++){
+ var orderline = this.render_orderline(orderlines[i]);
+ list_container.appendChild(orderline);
}
- this.orderlinewidgets = [];
- var $content = this.$('.orderlines');
- this.currentOrderLines.each(_.bind( function(orderLine) {
- var line = new module.OrderlineWidget(this, {
- model: orderLine,
- order: this.pos.get('selectedOrder'),
- });
- line.on('order_line_selected', self, self.update_numpad);
- line.on('order_line_refreshed', self, self.update_summary);
- line.appendTo($content);
- self.orderlinewidgets.push(line);
- }, this));
- this.update_numpad();
+ if(this.el && this.el.parentNode){
+ this.el.parentNode.replaceChild(el_node,this.el);
+ }
+ this.el = el_node;
this.update_summary();
- scroller = this.$('.order-scroller')[0];
-
- if(scroller){
- if(scrollbottom){
- scroller.scrollTop = scroller.scrollHeight - scroller.clientHeight;
- }else{
- scroller.scrollTop = scrollTop;
- }
+ if(scrollbottom){
+ this.el.querySelector('.order-scroller').scrollTop = 100 * orderlines.length;
}
},
update_summary: function(){
var order = this.pos.get('selectedOrder');
var total = order ? order.getTotalTaxIncluded() : 0;
var taxes = order ? total - order.getTotalTaxExcluded() : 0;
- this.$('.summary .total > .value').html(this.format_currency(total));
- this.$('.summary .total .subentry .value').html(this.format_currency(taxes));
- },
- set_display_mode: function(mode){
- if(this.display_mode !== mode){
- this.display_mode = mode;
- this.renderElement();
- }
+
+ this.el.querySelector('.summary .total > .value').innerText = this.format_currency(total);
+ this.el.querySelector('.summary .total .subentry .value').innerText = this.format_currency(taxes);
},
});
-
module.PaymentlineWidget = module.PosBaseWidget.extend({
template: 'PaymentlineWidget',
init: function(parent, options) {
},
});
- module.CategoryButton = module.PosBaseWidget.extend({
- });
module.ProductCategoriesWidget = module.PosBaseWidget.extend({
template: 'ProductCategoriesWidget',
init: function(parent, options){
this.category = this.pos.root_category;
this.breadcrumb = [];
this.subcategories = [];
+ this.product_list_widget = options.product_list_widget || null;
+ this.category_cache = {};
this.set_category();
+ this.switch_category_handler = function(event){
+ self.set_category(self.pos.db.get_category_by_id(Number(this.dataset['categoryId'])));
+ self.renderElement();
+ };
},
// changes the category. if undefined, sets to root category
},
get_image_url: function(category){
- return instance.session.url('/web/binary/image', {model: 'pos.category', field: 'image_medium', id: category.id});
+ return window.location.origin + '/web/binary/image?model=pos.category&field=image_medium&id='+category.id;
+ },
+
+ render_category: function( category, with_image ){
+ if(!this.category_cache[category.id]){
+
+ if(with_image){
+ var image_url = this.get_image_url(category);
+ var category_html = QWeb.render('CategoryButton',{
+ widget: this,
+ category: category,
+ });
+ category_html = _.str.trim(category_html);
+ var category_node = document.createElement('div');
+ category_node.innerHTML = category_html;
+ category_node = category_node.childNodes[0];
+ var img = category_node.querySelector('img');
+ img.parentNode.replaceChild(this.pos_widget.image_cache.get_image(image_url),img);
+ }else{
+ var category_html = QWeb.render('CategorySimpleButton',{
+ widget: this,
+ category: category,
+ });
+ category_html = _.str.trim(category_html);
+ var category_node = document.createElement('div');
+ category_node.innerHTML = category_html;
+ category_node = category_node.childNodes[0];
+ }
+ this.category_cache[category.id] = category_node;
+ }
+ return this.category_cache[category.id];
+ },
+
+ replace: function($target){
+ this.renderElement();
+ var target = $target[0];
+ target.parentNode.replaceChild(this.el,target);
},
renderElement: function(){
var self = this;
- this._super();
+
+ var el_str = openerp.qweb.render(this.template, {widget: this});
+ var el_node = document.createElement('div');
+ el_node.innerHTML = el_str;
+ el_node = el_node.childNodes[1];
+
+ if(this.el && this.el.parentNode){
+ this.el.parentNode.replaceChild(el_node,this.el);
+ }
+
+ this.el = el_node;
var hasimages = false; //if none of the subcategories have images, we don't display buttons with icons
- _.each(this.subcategories, function(category){
- if(category.image){
+ for(var i = 0; i < this.subcategories.length; i++){
+ if(this.subcategories[i].image){
hasimages = true;
+ break;
}
- });
+ }
- _.each(this.subcategories, function(category){
- if(hasimages){
- var button = QWeb.render('CategoryButton',{category:category});
- var button = _.str.trim(button);
- var button = $(button);
- button.find('img').replaceWith(self.pos_widget.image_cache.get_image(self.get_image_url(category)));
- }else{
- var button = QWeb.render('CategorySimpleButton',{category:category});
- button = _.str.trim(button); // we remove whitespace between buttons to fix spacing
- var button = $(button);
- }
+ var list_container = el_node.querySelector('.category-list');
+ for(var i = 0, len = this.subcategories.length; i < len; i++){
+ list_container.appendChild(this.render_category(this.subcategories[i],hasimages));
+ };
+
+ var buttons = el_node.querySelectorAll('.js-category-switch');
+ for(var i = 0; i < buttons.length; i++){
+ buttons[i].addEventListener('click',this.switch_category_handler);
+ }
- button.appendTo(this.$('.category-list')).click(function(event){
- var id = category.id;
- var cat = self.pos.db.get_category_by_id(id);
- self.set_category(cat);
- self.renderElement();
- });
- });
- // breadcrumb click actions
- this.$(".oe-pos-categories-list a").click(function(event){
- var id = $(event.target).data("category-id");
- var category = self.pos.db.get_category_by_id(id);
- self.set_category(category);
- self.renderElement();
- });
this.search_and_categories();
}
},
- set_product_type: function(type){ // 'all' | 'weightable'
- this.product_type = type;
- this.reset_category();
- },
-
// resets the current category to the root category
reset_category: function(){
this.set_category();
// empties the content of the search box
clear_search: function(){
var products = this.pos.db.get_product_by_category(this.category.id);
- this.pos.get('products').reset(products);
+ this.product_list_widget.set_product_list(products);
this.$('.searchbox input').val('').focus();
this.$('.search-clear').fadeOut();
},
// find all products belonging to the current category
var products = this.pos.db.get_product_by_category(this.category.id);
- self.pos.get('products').reset(products);
+ this.product_list_widget.set_product_list(products);
+ /*
var searchtimeout = null;
// filter the products according to the search string
this.$('.searchbox input').keyup(function(event){
if(query){
if(event.which === 13){
if( self.pos.get('products').size() === 1 ){
- self.pos.get('selectedOrder').addProduct(self.pos.get('products').at(0));
+ self.pos.get('selectedOrder').addProduct(self.pos.get('products').at(0)); // FIXME
self.clear_search();
}
}else{
var products = self.pos.db.search_product_in_category(self.category.id, query);
- self.pos.get('products').reset(products);
+ this.product_list_widget.set_product_list(products);
self.$('.search-clear').fadeIn();
}
}else{
var products = self.pos.db.get_product_by_category(self.category.id);
- self.pos.get('products').reset(products);
+ this.product_list_widget.set_product_list(products);
self.$('.search-clear').fadeOut();
}
},200);
//reset the search when clicking on reset
this.$('.search-clear').click(function(){
self.clear_search();
- });
+ });*/
},
});
- module.ProductListWidget = module.ScreenWidget.extend({
+ module.ProductListWidget = module.PosBaseWidget.extend({
template:'ProductListWidget',
init: function(parent, options) {
var self = this;
this.weight = options.weight || 0;
this.show_scale = options.show_scale || false;
this.next_screen = options.next_screen || false;
- this.click_product_action = options.click_product_action;
- this.pos.get('products').bind('reset', function(){
- self.renderElement();
- });
- },
- renderElement: function() {
- var self = this;
- this._super();
+ this.click_product_handler = function(event){
+ var product = self.pos.db.get_product_by_id(this.dataset['productId']);
+ options.click_product_action(product);
+ };
- var products = this.pos.get('products').models || [];
+ this.product_list = options.product_list || [];
+ this.product_cache = {};
+ },
+ set_product_list: function(product_list){
+ this.product_list = product_list;
+ this.renderElement();
+ },
+ get_product_image_url: function(product){
+ return window.location.origin + '/web/binary/image?model=product.product&field=image_medium&id='+product.id;
+ },
+ replace: function($target){
+ this.renderElement();
+ var target = $target[0];
+ target.parentNode.replaceChild(this.el,target);
+ },
- _.each(products,function(product,i){
- var $product = $(QWeb.render('Product',{ widget:self, product: products[i] }));
- $product.find('img').replaceWith(self.pos_widget.image_cache.get_image(products[i].get_image_url()));
- $product.appendTo(self.$('.product-list'));
- });
+ render_product: function(product){
+ if(!this.product_cache[product.id]){
+ var image_url = this.get_product_image_url(product);
+ var product_html = QWeb.render('Product',{
+ widget: this,
+ product: product,
+ });
+ var product_node = document.createElement('div');
+ product_node.innerHTML = product_html;
+ product_node = product_node.childNodes[1];
+ var img = product_node.querySelector('img');
+ img.parentNode.replaceChild(this.pos_widget.image_cache.get_image(image_url),img);
+ this.product_cache[product.id] = product_node;
+ }
+ return this.product_cache[product.id];
+ },
- this.$el.delegate('.product','touchstart',function TOUCHSTART(){
- console.log('Touchstart',(new Date()).getTime());
- });
+ renderElement: function() {
+ var self = this;
- this.$el.delegate('.product','touchend',function TOUCHEND(){
- console.log('Touchend',(new Date()).getTime());
- });
+ // this._super()
+ var el_str = openerp.qweb.render(this.template, {widget: this});
+ var el_node = document.createElement('div');
+ el_node.innerHTML = el_str;
+ el_node = el_node.childNodes[1];
- this.$el.delegate('.product','click',function TOUCHCLICK(){
- console.log('ClickStart',(new Date()).getTime());
- self.click_product_action(new module.Product(self.pos.db.get_product_by_id(+$(this).data('product-id'))));
- console.log('ClickEnd',(new Date()).getTime());
- });
+ if(this.el && this.el.parentNode){
+ this.el.parentNode.replaceChild(el_node,this.el);
+ }
+ this.el = el_node;
+ var list_container = el_node.querySelector('.product-list');
+ for(var i = 0, len = this.product_list.length; i < len; i++){
+ var product_node = this.render_product(this.product_list[i]);
+ product_node.addEventListener('click',this.click_product_handler);
+ list_container.appendChild(product_node);
+ };
},
});
this.set_left_action_bar_visible(false);
this.numpad.show();
this.paypad.show();
- this.order_widget.set_display_mode('numpad');
}else{
this.numpad.hide();
this.paypad.hide();
- if(this.order_widget.display_mode === 'numpad'){
- this.order_widget.set_display_mode('maximized');
- }
}
}
},
if(visible){
this.set_numpad_visible(false);
this.left_action_bar.show();
- this.order_widget.set_display_mode('actionbar');
}else{
this.left_action_bar.hide();
- if(this.order_widget.display_mode === 'actionbar'){
- this.order_widget.set_display_mode('maximized');
- }
}
}
},
- set_fullscreen: function(){
- if(this.el.webkitRequestFullscreen){
- this.el.webkitRequestFullscreen();
- }
- },
//shows or hide the leftpane (contains the list of orderlines, the numpad, the paypad, etc.)
set_leftpane_visible: function(visible){
if(visible !== this.leftpane_visible){
</t>
<t t-name="CategoryButton">
- <li class='category-button'>
+ <li class='category-button js-category-switch' t-att-data-category-id="category.id" >
<div class="category-img">
<img src="" />
</div>
</t>
<t t-name="CategorySimpleButton">
- <li class='category-simple-button'>
+ <li class='category-simple-button js-category-switch' t-att-data-category-id="category.id" >
<t t-esc="category.name"/>
</li>
</t>
<t t-name="ProductCategoriesWidget">
+ <div>
<header>
<ol class="breadcrumb">
<li class="oe-pos-categories-list">
- <a href="javascript:void(0)">
+ <a href="javascript:void(0)" class="js-category-switch">
<img src="/point_of_sale/static/src/img/home.png" class="homeimg" />
</a>
</li>
<t t-foreach="widget.breadcrumb" t-as="category">
<li class="oe-pos-categories-list">
<img src="/point_of_sale/static/src/img/bc-arrow.png" class="bc-arrow" />
- <a href="javascript:void(0)" t-att-data-category-id="category.id">
+ <a href="javascript:void(0)" class="js-category-switch" t-att-data-category-id="category.id">
<t t-esc="category.name"/>
</a>
</li>
</ol>
</div>
</t>
+ </div>
</t>
<t t-name="ProductListWidget">
<li class='product' t-att-data-product-id="product.id">
<div class="product-img">
<img src='' /> <!-- the product thumbnail -->
- <t t-if="!product.get('to_weight')">
+ <t t-if="!product.to_weight">
<span class="price-tag">
- <t t-esc="widget.format_currency(product.get('price'))"/>
+ <t t-esc="widget.format_currency(product.price)"/>
</span>
</t>
- <t t-if="product.get('to_weight')">
+ <t t-if="product.to_weight">
<span class="price-tag">
- <t t-esc="widget.format_currency(product.get('price'))+'/Kg'"/>
+ <t t-esc="widget.format_currency(product.price)+'/Kg'"/>
</span>
</t>
</div>
<div class="product-name">
- <t t-esc="product.get('name')"/>
+ <t t-esc="product.name"/>
</div>
</li>
</t>
- <t t-name="ScrollbarWidget">
- <div class='scrollbar'>
- <div class='up-button button oe_e'>
- &atilde;
- </div>
-
- <div class='scroller'>
- </div>
-
- <div class='down-button button oe_e'>
- &auml;
- </div>
- </div>
- </t>
-
<t t-name="OrderWidget">
<div class="order-container">
<div class="order-scroller">
<div class="order">
<ul class="orderlines">
- <t t-if="widget.pos.get('selectedOrder').get('orderLines').length === 0">
+ <t t-if="orderlines.length === 0">
<li class="orderline empty">
Your shopping cart is empty
</li>
</t>
-
</ul>
<div class="summary">
- <div t-attf-class="line #{widget.pos.get('selectedOrder').get('orderLines').length === 0 ? 'empty' : ''}">
+ <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>
</div>
</div>
</div>
- <div class="shadow-top"></div>
- <span class="placeholder-ScrollbarWidget"></span>
</div>
</t>
</div>
</t>
- <t t-name="OrderlineWidget">
- <li class="orderline">
+ <t t-name="Orderline">
+ <li t-attf-class="orderline #{ line.selected ? 'selected' : '' }">
<span class="product-name">
- <t t-esc="widget.model.get_product().get('name')"/>
+ <t t-esc="line.get_product().name"/>
</span>
<span class="price">
- <t t-esc="widget.format_currency(widget.model.get_display_price())"/>
+ <t t-esc="widget.format_currency(line.get_display_price())"/>
</span>
<ul class="info-list">
- <t t-if="widget.model.get_quantity_str() !== '1'">
+ <t t-if="line.get_quantity_str() !== '1' || line.selected ">
<li class="info">
<em>
- <t t-esc="widget.model.get_quantity_str()" />
+ <t t-esc="line.get_quantity_str()" />
</em>
- <t t-esc="widget.model.get_unit().name" />
+ <t t-esc="line.get_unit().name" />
at
- <t t-esc="widget.format_currency(widget.model.get_unit_price())" />
+ <t t-esc="widget.format_currency(line.get_unit_price())" />
/
- <t t-esc="widget.model.get_unit().name" />
+ <t t-esc="line.get_unit().name" />
</li>
</t>
- <t t-if="widget.model.get_discount_str() !== '0'">
+ <t t-if="line.get_discount_str() !== '0'">
<li class="info">
With a
<em>
- <t t-esc="widget.model.get_discount_str()" />%
+ <t t-esc="line.get_discount_str()" />%
</em>
discount
</li>
</colgroup>
<tr t-foreach="widget.currentOrderLines.toArray()" t-as="orderline">
<td>
- <t t-esc="orderline.get_product().get('name')"/>
+ <t t-esc="orderline.get_product().name"/>
<t t-if="orderline.get_discount() > 0">
<div class="pos-disc-font">
With a <t t-esc="orderline.get_discount()"/>% discount