[IMP] point_of_sale: refactored Orderline and Paymentline, new OrderWidget design
bzr revid: fva@openerp.com-20120703114741-3xixto34i2wqfy0v
This commit is contained in:
parent
c753d215dd
commit
0e255c2b90
|
@ -83,7 +83,7 @@ Main features :
|
|||
'certificate' : '001156338024966477869',
|
||||
# Web client
|
||||
'js': [
|
||||
'static/lib/backbone/backbone-0.5.3.js',
|
||||
'static/lib/backbone/backbone-0.9.2.js',
|
||||
'static/lib/mousewheel/jquery.mousewheel-3.0.6.js',
|
||||
'static/src/js/pos_models.js',
|
||||
'static/src/js/pos_basewidget.js',
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
height: 100%;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
/* ********* The black loading screen ********* */
|
||||
|
||||
.point-of-sale .loader{
|
||||
background-color: #222;
|
||||
position:absolute;
|
||||
|
@ -28,16 +31,8 @@
|
|||
left:50%;
|
||||
}
|
||||
|
||||
.point-of-sale table {
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.point-of-sale td {
|
||||
border: 1px solid #e9eaec;
|
||||
}
|
||||
.point-of-sale input {
|
||||
color: #555555;
|
||||
}
|
||||
/* ********* Generic element styling ********* */
|
||||
|
||||
.point-of-sale a {
|
||||
text-decoration: none;
|
||||
color: #555555;
|
||||
|
@ -62,19 +57,16 @@
|
|||
.point-of-sale li {
|
||||
list-style-type: none;
|
||||
}
|
||||
.point-of-sale button img {
|
||||
vertical-align: bottom;
|
||||
}
|
||||
.point-of-sale .pos-right-align {
|
||||
text-align: right;
|
||||
}
|
||||
.point-of-sale .pos-right-align input {
|
||||
text-align: right;
|
||||
}
|
||||
.point-of-sale #container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* ********* The black header bar ********* */
|
||||
|
||||
|
||||
.point-of-sale #topheader {
|
||||
position:absolute;
|
||||
left:0;
|
||||
|
@ -90,16 +82,9 @@
|
|||
background: -moz-linear-gradient(#7b7979, #393939);
|
||||
background: -webkit-gradient(linear, left top, left bottom, from(#7b7979), to(#393939));
|
||||
}
|
||||
.point-of-sale #topheader button {
|
||||
color: black;
|
||||
height:29px;
|
||||
margin:2px;
|
||||
margin-right:0px;
|
||||
border: 1px solid black;
|
||||
background: #7f82ac;
|
||||
background: -moz-linear-gradient(#b2b3d7, #7f82ac);
|
||||
background: -webkit-gradient(linear, left top, left bottom, from(#b2b3d7), to(#7f82ac));
|
||||
}
|
||||
|
||||
/* a) The left part of the top-bar */
|
||||
|
||||
.point-of-sale #branding{
|
||||
position: absolute;
|
||||
display: table-cell;
|
||||
|
@ -120,6 +105,17 @@
|
|||
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;
|
||||
|
@ -127,23 +123,75 @@
|
|||
top:0;
|
||||
height:100%;
|
||||
}
|
||||
.point-of-sale #neworder-button {
|
||||
|
||||
.point-of-sale #rightheader button {
|
||||
color: black;
|
||||
height:29px;
|
||||
margin:2px;
|
||||
margin-right:0px;
|
||||
border: 1px solid black;
|
||||
background: #7f82ac;
|
||||
background: -moz-linear-gradient(#b2b3d7, #7f82ac);
|
||||
background: -webkit-gradient(linear, left top, left bottom, from(#b2b3d7), to(#7f82ac));
|
||||
}
|
||||
|
||||
.point-of-sale #rightheader button.neworder-button {
|
||||
width: 32px;
|
||||
margin-left:5px;
|
||||
margin-left:4px;
|
||||
margin-right:4px;
|
||||
}
|
||||
.point-of-sale #loggedas {
|
||||
float: right;
|
||||
|
||||
.point-of-sale div#order-selector {
|
||||
display: inline;
|
||||
}
|
||||
.point-of-sale #loggedas p {
|
||||
margin: 0 0 3px 0;
|
||||
.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 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; //#E6E4E4; //yellow; //#F0EEEE;
|
||||
background: #F0EEEE;
|
||||
}
|
||||
|
||||
/* ********* The leftpane contains the order, numpad and paypad ********* */
|
||||
|
||||
.point-of-sale #leftpane {
|
||||
-webkit-box-sizing:border-box;
|
||||
position:absolute;
|
||||
|
@ -151,9 +199,6 @@
|
|||
width:440px;
|
||||
top:0px;
|
||||
bottom:105px;
|
||||
/*height: 87%;
|
||||
width: 440px;
|
||||
position: relative;*/
|
||||
border-right: solid 1px #CECBCB;
|
||||
background-color: white;
|
||||
}
|
||||
|
@ -165,6 +210,9 @@
|
|||
background: #F0EEEE;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* ********* The paypad contains the payment buttons ********* */
|
||||
|
||||
.point-of-sale #paypad {
|
||||
padding: 8px 4px 8px 8px;
|
||||
display: inline-block;
|
||||
|
@ -179,6 +227,7 @@
|
|||
vertical-align: middle;
|
||||
color: #555555;
|
||||
border-top: 1px solid #efefef;
|
||||
font-size: 14px;
|
||||
}
|
||||
.point-of-sale #paypad button:hover {
|
||||
color: white;
|
||||
|
@ -186,6 +235,9 @@
|
|||
background: -moz-linear-gradient(#9d9fc5, #7f82ac);
|
||||
background: -webkit-gradient(linear, left top, left bottom, from(#9d9fc5), to(#7f82ac));
|
||||
}
|
||||
|
||||
/* ********* The Numpad ********* */
|
||||
|
||||
.point-of-sale #numpad {
|
||||
padding: 8px 8px 8px 4px;
|
||||
display: inline-block;
|
||||
|
@ -212,15 +264,15 @@
|
|||
background: -moz-linear-gradient(#9d9fc5, #7f82ac);
|
||||
background: -webkit-gradient(linear, left top, left bottom, from(#9d9fc5), to(#7f82ac));
|
||||
}
|
||||
.point-of-sale .payment-button {
|
||||
font-size: 14px;
|
||||
}
|
||||
.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;
|
||||
|
@ -228,8 +280,8 @@
|
|||
left: 440px;
|
||||
right: 0;
|
||||
vertical-align: top;
|
||||
/*border-left: solid 1px #FFF;*/
|
||||
}
|
||||
|
||||
.point-of-sale #rightpane header {
|
||||
padding: 0;
|
||||
height: 32px;
|
||||
|
@ -238,9 +290,13 @@
|
|||
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{
|
||||
width:100%;
|
||||
height:100%;
|
||||
|
@ -252,8 +308,10 @@
|
|||
bottom:0px;
|
||||
left:0px;
|
||||
right:0px;
|
||||
//background:url('../img/bg_callout_gradient_scratched_stars.png');
|
||||
}
|
||||
|
||||
/* a) the product list navigation bar */
|
||||
|
||||
.point-of-sale .breadcrumb li {
|
||||
float: left;
|
||||
line-height: 32px;
|
||||
|
@ -279,6 +337,9 @@
|
|||
height: 19px;
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
/* b) the search box */
|
||||
|
||||
.point-of-sale .searchbox {
|
||||
position: absolute;
|
||||
right: 2px;
|
||||
|
@ -301,6 +362,9 @@
|
|||
cursor: pointer;
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* c) the categories list */
|
||||
|
||||
.point-of-sale #categories {
|
||||
background:#f0f0f0;
|
||||
border-bottom: 1px solid #cecbcb;
|
||||
|
@ -320,6 +384,9 @@
|
|||
margin: 4px 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* d) the product */
|
||||
|
||||
.point-of-sale .product {
|
||||
position:relative;
|
||||
vertical-align: top;
|
||||
|
@ -337,6 +404,7 @@
|
|||
-webkit-box-shadow: 0px 1px 8px rgba(0,0,0,0.2);
|
||||
-box-shadow: 0px 1px 8px rgba(0,0,0,0.9);
|
||||
}
|
||||
|
||||
.point-of-sale .product .product-img {
|
||||
position: relative;
|
||||
width: 120px;
|
||||
|
@ -345,6 +413,7 @@
|
|||
text-align: center;
|
||||
-webkit-filter: blur(3px);
|
||||
}
|
||||
|
||||
.point-of-sale .product .price-tag {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
|
@ -357,6 +426,7 @@
|
|||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.point-of-sale .product .price-subtag {
|
||||
position: absolute;
|
||||
top: 24px;
|
||||
|
@ -369,6 +439,7 @@
|
|||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.point-of-sale .product .product-name {
|
||||
position: absolute;
|
||||
-webkit-box-sizing: border-box;
|
||||
|
@ -380,26 +451,9 @@
|
|||
padding: 3px;
|
||||
padding-top:15px;
|
||||
}
|
||||
.point-of-sale #login-form label, .point-of-sale #login-form input {
|
||||
display: block;
|
||||
}
|
||||
.point-of-sale #login-form input {
|
||||
margin: 4px 0 12px;
|
||||
padding: 4px;
|
||||
width: 96%;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
|
||||
|
||||
/* ********* The Screens ********* */
|
||||
|
||||
.point-of-sale .screen {
|
||||
position:absolute;
|
||||
|
@ -416,6 +470,8 @@
|
|||
font-size: 18px;
|
||||
}
|
||||
|
||||
/* a) Layout for the Product Screen */
|
||||
|
||||
.point-of-sale .screen .layout-table {
|
||||
border:none;
|
||||
width:100%;
|
||||
|
@ -442,6 +498,8 @@
|
|||
position:relative;
|
||||
}
|
||||
|
||||
/* b) The payment screen */
|
||||
|
||||
.point-of-sale .pos-step-container {
|
||||
display: inline-block;
|
||||
font-size: 1.5em;
|
||||
|
@ -473,6 +531,13 @@
|
|||
font-size: 0.8em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
@ -488,25 +553,6 @@
|
|||
.point-of-sale .pos-sale-ticket table td {
|
||||
border: 0;
|
||||
}
|
||||
.point-of-sale .pos-receipt-container {
|
||||
font-size: 0.75em;
|
||||
}
|
||||
|
||||
.point-of-sale .oe_pos_synch-notification-button {
|
||||
color: white;
|
||||
border: 1px solid black;
|
||||
border-radius: 3px;
|
||||
padding: 2px 3px 2px 3px;
|
||||
background-color: #D92A2A;
|
||||
}
|
||||
|
||||
.receipt-buttons {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.pos-payment-buttons {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@media print {
|
||||
#oe_header, #oe_menu, .point-of-sale #topheader, .point-of-sale #leftpane {
|
||||
|
@ -519,7 +565,7 @@
|
|||
left: 0px;
|
||||
background-color: white;
|
||||
}
|
||||
#receipt-screen header, .receipt-buttons {
|
||||
#receipt-screen header {
|
||||
display: none;
|
||||
}
|
||||
#receipt-screen {
|
||||
|
@ -530,6 +576,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
/* ********* The OrderWidget ********* */
|
||||
|
||||
.point-of-sale .order-container{
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
|
@ -537,11 +585,13 @@
|
|||
width:100%;
|
||||
background: #F0EEEE;
|
||||
}
|
||||
|
||||
.point-of-sale .order-scroller{
|
||||
width:100%;
|
||||
height:100%;
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
.point-of-sale .order{
|
||||
background: #FFF;
|
||||
background: -webkit-linear-gradient(0deg,rgba(245,245,245,1),rgba(255,255,255,1), rgba(245,245,245,1));
|
||||
|
@ -555,6 +605,35 @@
|
|||
-webkit-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;
|
||||
|
@ -566,14 +645,6 @@
|
|||
-webkit-box-sizing: border-box;
|
||||
-webkit-transition: background 250ms ease-in-out;
|
||||
}
|
||||
.point-of-sale .order .empty{
|
||||
text-align:center;
|
||||
margin-top: 15px;
|
||||
margin-bottom: 5px;
|
||||
color:#999;
|
||||
font-weight: normal;
|
||||
|
||||
}
|
||||
.point-of-sale .order .orderline:hover{
|
||||
background: rgba(140,143,183,0.05);
|
||||
-webkit-transition: background 50ms ease-in-out;
|
||||
|
@ -605,25 +676,8 @@
|
|||
font-weight: bold;
|
||||
font-style: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;
|
||||
}
|
||||
|
||||
/* ----------------------- ACTION BAR ---------------------- */
|
||||
/* ********* The ActionBarWidget ********* */
|
||||
|
||||
.point-of-sale .pos-actionbar{
|
||||
position:absolute;
|
||||
|
@ -704,7 +758,7 @@
|
|||
float:right;
|
||||
}
|
||||
|
||||
/* ----------------------- POP-UPS ---------------------- */
|
||||
/* ********* The PopupWidgets ********* */
|
||||
|
||||
.point-of-sale .modal-dialog{
|
||||
position: absolute;
|
||||
|
@ -796,14 +850,14 @@
|
|||
line-height:180px;
|
||||
}
|
||||
|
||||
/* ----------------------- SCROLLBAR ---------------------- */
|
||||
/* ********* The ScrollBarWidget ********* */
|
||||
|
||||
.point-of-sale .scrollbar{
|
||||
position:absolute;
|
||||
top:4px;
|
||||
top:7px;
|
||||
right:7px;
|
||||
width:48px;
|
||||
bottom:4px;
|
||||
bottom:7px;
|
||||
background: rgba(0,0,0,0.1);
|
||||
|
||||
}
|
||||
|
@ -833,13 +887,6 @@
|
|||
color:rgba(255,255,255,0.5);
|
||||
-webkit-transition: all 250ms ease-in-out;
|
||||
}
|
||||
|
||||
/*
|
||||
.point-of-sale .scrollbar .button{
|
||||
background: -webkit-linear-gradient(-90deg,#efefef,#d8d8d8);
|
||||
border: 1px solid #ababab;
|
||||
-webkit-box-shadow: 0px 1px 4px rgba(0,0,0,0.2);
|
||||
}*/
|
||||
.point-of-sale .scrollbar .down-button{
|
||||
position:absolute;
|
||||
bottom:0px;
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 751 B |
Binary file not shown.
After Width: | Height: | Size: 830 B |
|
@ -34,6 +34,12 @@ function openerp_pos_basewidget(instance, module){ //module is instance.point_of
|
|||
}
|
||||
|
||||
},
|
||||
show: function(){
|
||||
this.$element.show();
|
||||
},
|
||||
hide: function(){
|
||||
this.$element.hide();
|
||||
},
|
||||
});
|
||||
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
'user': null,
|
||||
'user_list': null,
|
||||
'cashier': null,
|
||||
'customer': null,
|
||||
'client': null,
|
||||
|
||||
'orders': new module.OrderCollection(),
|
||||
//this is the product list as seen by the product list widgets, it will change based on the category filters
|
||||
|
@ -126,6 +126,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
[['pos_categ_id','!=', false]]
|
||||
).then(function(result){
|
||||
self.set({'product_list': result});
|
||||
console.log('PRODUCTS_DONE');
|
||||
});
|
||||
|
||||
var uom_def = fetch( //unit of measure
|
||||
|
@ -139,14 +140,16 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
units_by_id[result[i].id] = result[i];
|
||||
}
|
||||
self.set({'units_by_id':units_by_id});
|
||||
console.log('UOM_DONE');
|
||||
});
|
||||
|
||||
var user_def = fetch(
|
||||
'res.users',
|
||||
['name','ean13']
|
||||
['name','ean13'],
|
||||
[['ean13', '!=', false]]
|
||||
).then(function(result){
|
||||
self.set({'user_list':result});
|
||||
console.log('USERS_DONE');
|
||||
});
|
||||
|
||||
|
||||
|
@ -166,11 +169,13 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
for(var i = 0; i < product_list.length; i++){
|
||||
product_list[i].pos_category = cat_by_id[product_list[i].pos_categ_id[0]];
|
||||
}
|
||||
console.log('PROD_PROCESS_DONE');
|
||||
});
|
||||
|
||||
var tax_def = fetch('account.tax', ['amount','price_include','type'])
|
||||
.then(function(result){
|
||||
self.set({'taxes': result});
|
||||
console.log('TAX_DONE');
|
||||
});
|
||||
|
||||
var session_def = fetch( // loading the PoS Session.
|
||||
|
@ -204,6 +209,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
self.use_websql = result[0].iface_websql || false;
|
||||
self.use_barcode_scanner = result[0].iface_barscan || false;
|
||||
self.use_selfcheckout = result[0].iface_self_checkout || false;
|
||||
console.log('POS_CONFIG_DONE');
|
||||
});
|
||||
|
||||
var bank_def = fetch(
|
||||
|
@ -212,6 +218,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
[['state','=','open'],['pos_session_id', '=', pos_session.id]]
|
||||
).then(function(result){
|
||||
self.set({'bank_statements':result});
|
||||
console.log('BANK_DEF_DONE');
|
||||
});
|
||||
|
||||
var journal_def = fetch(
|
||||
|
@ -220,6 +227,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
[['user_id','=',pos_session.user_id[0]]]
|
||||
).then(function(result){
|
||||
self.set({'journals':result});
|
||||
console.log('JOURNALS_DONE');
|
||||
});
|
||||
|
||||
// associate the bank statements with their journals.
|
||||
|
@ -235,6 +243,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
}
|
||||
}
|
||||
}
|
||||
console.log('BANK_PROCESS_DONE');
|
||||
});
|
||||
|
||||
session_data_def = $.when(pos_config_def,bank_def,journal_def,bank_process_def);
|
||||
|
@ -251,9 +260,8 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
//self.build_tree();
|
||||
self.build_categories();
|
||||
self.set({'cashRegisters' : new module.CashRegisterCollection(self.get('bank_statements'))});
|
||||
console.log('cashRegisters:',self.get('cashRegisters'));
|
||||
self.ready.resolve();
|
||||
self.log_loaded_data();
|
||||
self.ready.resolve();
|
||||
},function(){
|
||||
//we failed to load some backend data, or the backend was badly configured.
|
||||
//the error messages will be displayed in PosWidget
|
||||
|
@ -277,10 +285,10 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
console.log('PosModel: company:',this.get('company'));
|
||||
console.log('PosModel: currency:',this.get('currency'));
|
||||
console.log('PosModel: user_list:',this.get('user_list'));
|
||||
console.log('PosModel: user:',this.get('user'));
|
||||
console.log('PosModel.session:',this.session);
|
||||
console.log('PosModel.categories:',this.categories);
|
||||
console.log('PosModel end of data log.');
|
||||
|
||||
},
|
||||
|
||||
// this is called when an order is removed from the order collection. It ensures that there is always an existing
|
||||
|
@ -316,7 +324,6 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
|
||||
push_order: function(record) {
|
||||
var self = this;
|
||||
console.log('push_order',record);
|
||||
return this.dao.add_operation(record).pipe(function(){
|
||||
return self.flush();
|
||||
});
|
||||
|
@ -334,7 +341,6 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
// it has been confirmed that they have been received.
|
||||
flush: function() {
|
||||
//this makes sure only one _int_flush is called at the same time
|
||||
console.log('flush operations');
|
||||
return this.flush_mutex.exec(_.bind(function() {
|
||||
return this._int_flush();
|
||||
}, this));
|
||||
|
@ -347,13 +353,11 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
// they are saved to disk and then we attempt to send them to the backend so that they can
|
||||
// be applied.
|
||||
// since the network is not reliable we potentially have many 'pending operations' that have not been sent.
|
||||
|
||||
self.set( {'nbr_pending_operations':operations.length} );
|
||||
if(operations.length === 0){
|
||||
return $.when();
|
||||
}
|
||||
var order = operations[0];
|
||||
console.log('Pushing Order:',order);
|
||||
|
||||
// we prevent the default error handler and assume errors
|
||||
// are a normal use case, except we stop the current iteration
|
||||
|
@ -439,8 +443,6 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
|
||||
this.root_category = root_category;
|
||||
|
||||
console.log('categories:',categories);
|
||||
|
||||
//we add the products to the categories.
|
||||
for(var i = 0, len = products.length; i < len; i++){
|
||||
var product = products[i];
|
||||
|
@ -509,56 +511,53 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
|
||||
// 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.
|
||||
// Currently there is a limitation in that there can only be once orderline by type
|
||||
// of product, but this will be subject to changes TODO
|
||||
//
|
||||
// An Order contains zero or more Orderlines.
|
||||
module.Orderline = Backbone.Model.extend({
|
||||
defaults: {
|
||||
quantity: 1,
|
||||
list_price: 0,
|
||||
discount: 0,
|
||||
weighted: false,
|
||||
product_type: 'unit',
|
||||
selected: false,
|
||||
initialize: function(options){
|
||||
this.pos = options.pos;
|
||||
this.order = options.order;
|
||||
this.product = options.product;
|
||||
this.price = options.product.get('list_price');
|
||||
this.quantity = 1;
|
||||
this.discount = 0;
|
||||
this.type = 'unit';
|
||||
this.selected = false;
|
||||
},
|
||||
initialize: function(attributes) {
|
||||
this.pos = attributes.pos;
|
||||
Backbone.Model.prototype.initialize.apply(this, arguments);
|
||||
|
||||
if(attributes.weight){
|
||||
this.setWeight(attributes.weight);
|
||||
this.set({weighted: true});
|
||||
this.set({product_type: 'weight'});
|
||||
}
|
||||
// sets a discount [0,100]%
|
||||
set_discount: function(discount){
|
||||
this.discount = Math.max(0,Math.min(100,discount));
|
||||
this.trigger('change');
|
||||
},
|
||||
|
||||
// we override the attributes set to prevent some out of range values
|
||||
// we also round the quantity according to the unit of measure rounding methods
|
||||
set: function(attributes, options){
|
||||
var attributes = _.clone(attributes); //so we don't modify the argument
|
||||
if(attributes.discount > 100){
|
||||
attributes.discount = 100;
|
||||
}else if(attributes.discount < 0){
|
||||
attributes.discount = 0;
|
||||
}
|
||||
if(_.isNaN(attributes.quantity)){
|
||||
console.log(this.get('order'));
|
||||
this.get('order').removeOrderline(this);
|
||||
return this;
|
||||
}else if(attributes.quantity !== undefined){
|
||||
attributes.quantity = Math.max(0,attributes.quantity);
|
||||
// returns the discount [0,100]%
|
||||
get_discount: function(){
|
||||
return this.discount;
|
||||
},
|
||||
// FIXME
|
||||
get_product_type: function(){
|
||||
return this.type;
|
||||
},
|
||||
// sets the quantity of the product. The quantity will be rounded according to the
|
||||
// product's unity of measure properties. Quantities greater than zero will not get
|
||||
// rounded to zero
|
||||
set_quantity: function(quantity){
|
||||
if(_.isNaN(quantity)){
|
||||
this.order.removeOrderline(this);
|
||||
}else if(quantity !== undefined){
|
||||
this.quantity = Math.max(0,quantity);
|
||||
var unit = this.get_unit();
|
||||
if(unit && attributes.quantity){
|
||||
attributes.quantity = Math.max(unit.rounding, Math.round( attributes.quantity / unit.rounding) * unit.rounding);
|
||||
if(unit && this.quantity > 0 ){
|
||||
this.quantity = Math.max(unit.rounding, Math.round(quantity / unit.rounding) * unit.rounding);
|
||||
}
|
||||
}
|
||||
Backbone.Model.prototype.set.call(this,attributes,options);
|
||||
return this;
|
||||
this.trigger('change');
|
||||
},
|
||||
// returns the unit of measure associated with the product if there is one, undefined otherwise
|
||||
// return the quantity of product
|
||||
get_quantity: function(){
|
||||
return this.quantity;
|
||||
},
|
||||
// return the unit of measure of the product
|
||||
get_unit: function(){
|
||||
var unit_id = (this.get('uos_id') || this.get('uom_id'));
|
||||
var unit_id = (this.product.get('uos_id') || this.product.get('uom_id'));
|
||||
if(!unit_id){
|
||||
return undefined;
|
||||
}
|
||||
|
@ -568,69 +567,77 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
}
|
||||
return this.pos.get('units_by_id')[unit_id];
|
||||
},
|
||||
|
||||
// return the product of this orderline
|
||||
get_product: function(){
|
||||
return this.product;
|
||||
},
|
||||
// return the base price of this product (for this orderline)
|
||||
get_list_price: function(){
|
||||
return this.price;
|
||||
},
|
||||
// changes the base price of the product for this orderline
|
||||
set_list_price: function(price){
|
||||
this.price = price;
|
||||
this.trigger('change');
|
||||
},
|
||||
// selects or deselects this orderline
|
||||
set_selected: function(selected){
|
||||
this.selected = selected;
|
||||
this.trigger('change');
|
||||
},
|
||||
// returns true if this orderline is selected
|
||||
is_selected: function(){
|
||||
return this.selected;
|
||||
},
|
||||
|
||||
// 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('id') !== orderline.get('id')){ //only orderline of the same product can be merged
|
||||
if( this.get_product().get('id') !== orderline.get_product().get('id')){ //only orderline of the same product can be merged
|
||||
return false;
|
||||
}else if(this.get('product_type') !== orderline.get('product_type')){
|
||||
}else if(this.get_product_type() !== orderline.get_product_type()){
|
||||
return false;
|
||||
}else if(this.get('discount') > 0){ // we don't merge discounted orderlines
|
||||
}else if(this.get_discount() > 0){ // we don't merge discounted orderlines
|
||||
return false;
|
||||
}else if(this.get('product_type') === 'unit'){
|
||||
}else if(this.get_product_type() === 'unit'){
|
||||
return true;
|
||||
}else if(this.get('product_type') === 'weight'){
|
||||
}else if(this.get_product_type() === 'weight'){
|
||||
return true;
|
||||
}else if(this.get('product_type') === 'price'){
|
||||
return this.get('list_price') === orderline.get('list_price');
|
||||
}else if(this.get_product_type() === 'price'){
|
||||
return this.get_product().get('list_price') === orderline.get_product().get('list_price');
|
||||
}else{
|
||||
console.error('point_of_sale/pos_models.js/Orderline.can_be_merged_with() : unknown product type:',this.get('product_type'));
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
// Modifies this orderline so that it also contains the contents of another orderline.
|
||||
// the two orderlines must be mergable ('can_be_merged_with()' === true)
|
||||
merge: function(orderline){
|
||||
this.set({quantity : this.get('quantity') + orderline.get('quantity') });
|
||||
this.set_quantity(this.get_quantity() + orderline.get_quantity());
|
||||
},
|
||||
setWeight: function(weight){
|
||||
return this.set({
|
||||
quantity: weight,
|
||||
});
|
||||
export_as_JSON: function() {
|
||||
return {
|
||||
qty: this.get_quantity(),
|
||||
price_unit: this.get_product().get('list_price'),
|
||||
discount: this.get_discount(),
|
||||
product_id: this.get_product().get('id')
|
||||
};
|
||||
},
|
||||
incrementQuantity: function() {
|
||||
return this.set({
|
||||
quantity: (this.get('quantity')) + 1
|
||||
});
|
||||
get_price_without_tax: function(){
|
||||
return this.get_all_prices().priceWithoutTax;
|
||||
},
|
||||
incrementWeight: function(weight){
|
||||
return this.set({
|
||||
quantity: (this.get('quantity')) + weight,
|
||||
});
|
||||
get_price_with_tax: function(){
|
||||
return this.get_all_prices().priceWithTax;
|
||||
},
|
||||
set_discount: function(discount){
|
||||
this.set({'discount': discount});
|
||||
get_tax: function(){
|
||||
return this.get_all_prices().tax;
|
||||
},
|
||||
getPriceWithoutTax: function() {
|
||||
return this.getAllPrices().priceWithoutTax;
|
||||
},
|
||||
getPriceWithTax: function() {
|
||||
return this.getAllPrices().priceWithTax;
|
||||
},
|
||||
getTax: function() {
|
||||
return this.getAllPrices().tax;
|
||||
},
|
||||
getAllPrices: function() {
|
||||
get_all_prices: function() {
|
||||
var self = this;
|
||||
var base = (this.get('quantity')) * (this.get('list_price')) * (1 - (this.get('discount')) / 100);
|
||||
var base = this.get_quantity() * this.price * (1 - (this.get_discount() / 100));
|
||||
var totalTax = base;
|
||||
var totalNoTax = base;
|
||||
|
||||
var product_list = self.pos.get('product_list');
|
||||
var product = _.detect(product_list, function(el) {return el.id === self.get('id');});
|
||||
var product_list = this.pos.get('product_list');
|
||||
var product = this.get_product();
|
||||
var taxes_ids = product.taxes_id;
|
||||
var taxes = self.pos.get('taxes');
|
||||
var taxtotal = 0;
|
||||
|
@ -641,7 +648,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
if (tax.type === "percent") {
|
||||
tmp = base - (base / (1 + tax.amount));
|
||||
} else if (tax.type === "fixed") {
|
||||
tmp = tax.amount * self.get('quantity');
|
||||
tmp = tax.amount * self.get_quantity();
|
||||
} else {
|
||||
throw "This type of tax is not supported by the point of sale: " + tax.type;
|
||||
}
|
||||
|
@ -652,7 +659,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
if (tax.type === "percent") {
|
||||
tmp = tax.amount * base;
|
||||
} else if (tax.type === "fixed") {
|
||||
tmp = tax.amount * self.get('quantity');
|
||||
tmp = tax.amount * self.get_quantity();
|
||||
} else {
|
||||
throw "This type of tax is not supported by the point of sale: " + tax.type;
|
||||
}
|
||||
|
@ -666,14 +673,6 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
"tax": taxtotal,
|
||||
};
|
||||
},
|
||||
exportAsJSON: function() {
|
||||
return {
|
||||
qty: this.get('quantity'),
|
||||
price_unit: this.get('list_price'),
|
||||
discount: this.get('discount'),
|
||||
product_id: this.get('id')
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
module.OrderlineCollection = Backbone.Collection.extend({
|
||||
|
@ -682,22 +681,31 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
|
||||
// Every PaymentLine has all the attributes of the corresponding CashRegister.
|
||||
module.Paymentline = Backbone.Model.extend({
|
||||
defaults: {
|
||||
amount: 0,
|
||||
initialize: function(cashRegister) {
|
||||
this.amount = 0;
|
||||
this.cashregister = cashRegister;
|
||||
},
|
||||
initialize: function(attributes) {
|
||||
Backbone.Model.prototype.initialize.apply(this, arguments);
|
||||
//sets the amount of money on this payment line
|
||||
set_amount: function(value){
|
||||
this.amount = value;
|
||||
this.trigger('change');
|
||||
},
|
||||
getAmount: function(){
|
||||
return this.get('amount');
|
||||
// returns the amount of money on this paymentline
|
||||
get_amount: function(){
|
||||
return this.amount;
|
||||
},
|
||||
exportAsJSON: function(){
|
||||
// returns the associated cashRegister
|
||||
get_cashregister: function(){
|
||||
return this.cashregister;
|
||||
},
|
||||
//exports as JSON for server communication
|
||||
export_as_JSON: function(){
|
||||
return {
|
||||
name: instance.web.datetime_to_str(new Date()),
|
||||
statement_id: this.get('id'),
|
||||
account_id: (this.get('account_id'))[0],
|
||||
journal_id: (this.get('journal_id'))[0],
|
||||
amount: this.getAmount()
|
||||
amount: this.get_amount()
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@ -706,12 +714,11 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
model: module.Paymentline,
|
||||
});
|
||||
|
||||
|
||||
// An order more or less represents the content of a client's shopping cart (the OrderLines)
|
||||
// plus the associated payment information (the PaymentLines)
|
||||
// there is always an active ('selected') order in the Pos, a new one is created
|
||||
// automaticaly once an order is completed and sent to the server.
|
||||
|
||||
|
||||
module.Order = Backbone.Model.extend({
|
||||
initialize: function(attributes){
|
||||
Backbone.Model.prototype.initialize.apply(this, arguments);
|
||||
|
@ -733,7 +740,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
var attr = product.toJSON();
|
||||
attr.pos = this.pos;
|
||||
attr.order = this;
|
||||
var line = new module.Orderline(attr);
|
||||
var line = new module.Orderline({pos: this.pos, order: this, product: product});
|
||||
var self = this;
|
||||
|
||||
var last_orderline = this.getLastOrderline();
|
||||
|
@ -753,14 +760,11 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
},
|
||||
addPaymentLine: function(cashRegister) {
|
||||
var newPaymentline;
|
||||
console.log('addPaymentLine:',cashRegister);
|
||||
newPaymentline = new module.Paymentline(cashRegister);
|
||||
/* TODO: Should be 0 for cash-like accounts */
|
||||
//FIXME the following 'set' call calls this method once again via callback
|
||||
// events. Are we sure that it's what we want ???
|
||||
newPaymentline.set({
|
||||
amount: this.getDueLeft()
|
||||
});
|
||||
newPaymentline.set_amount( this.getDueLeft() );
|
||||
this.get('paymentLines').add(newPaymentline);
|
||||
},
|
||||
getName: function() {
|
||||
|
@ -768,22 +772,22 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
},
|
||||
getTotal: function() {
|
||||
return (this.get('orderLines')).reduce((function(sum, orderLine) {
|
||||
return sum + orderLine.getPriceWithTax();
|
||||
return sum + orderLine.get_price_with_tax();
|
||||
}), 0);
|
||||
},
|
||||
getTotalTaxExcluded: function() {
|
||||
return (this.get('orderLines')).reduce((function(sum, orderLine) {
|
||||
return sum + orderLine.getPriceWithoutTax();
|
||||
return sum + orderLine.get_price_without_tax();
|
||||
}), 0);
|
||||
},
|
||||
getTax: function() {
|
||||
return (this.get('orderLines')).reduce((function(sum, orderLine) {
|
||||
return sum + orderLine.getTax();
|
||||
return sum + orderLine.get_tax();
|
||||
}), 0);
|
||||
},
|
||||
getPaidTotal: function() {
|
||||
return (this.get('paymentLines')).reduce((function(sum, paymentLine) {
|
||||
return sum + paymentLine.getAmount();
|
||||
return sum + paymentLine.get_amount();
|
||||
}), 0);
|
||||
},
|
||||
getChange: function() {
|
||||
|
@ -796,11 +800,11 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
var orderLines, paymentLines;
|
||||
orderLines = [];
|
||||
(this.get('orderLines')).each(_.bind( function(item) {
|
||||
return orderLines.push([0, 0, item.exportAsJSON()]);
|
||||
return orderLines.push([0, 0, item.export_as_JSON()]);
|
||||
}, this));
|
||||
paymentLines = [];
|
||||
(this.get('paymentLines')).each(_.bind( function(item) {
|
||||
return paymentLines.push([0, 0, item.exportAsJSON()]);
|
||||
return paymentLines.push([0, 0, item.export_as_JSON()]);
|
||||
}, this));
|
||||
return {
|
||||
name: this.getName(),
|
||||
|
@ -811,6 +815,8 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
lines: orderLines,
|
||||
statement_ids: paymentLines,
|
||||
pos_session_id: this.pos.get('pos_session').id,
|
||||
partner_id: this.pos.get('client') ? this.pos.get('client').id : undefined,
|
||||
user_id: this.pos.get('cashier') ? this.pos.get('cashier').id : this.pos.get('user').id,
|
||||
};
|
||||
},
|
||||
getSelectedLine: function(){
|
||||
|
@ -820,10 +826,10 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
if(line){
|
||||
if(line !== this.selected_orderline){
|
||||
if(this.selected_orderline){
|
||||
this.selected_orderline.set({'selected':false});
|
||||
this.selected_orderline.set_selected(false);
|
||||
}
|
||||
this.selected_orderline = line;
|
||||
this.selected_orderline.set({'selected':true});
|
||||
this.selected_orderline.set_selected(true);
|
||||
}
|
||||
}else{
|
||||
this.selected_orderline = undefined;
|
||||
|
|
|
@ -20,7 +20,6 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
|
||||
module.ScreenSelector = instance.web.Class.extend({
|
||||
init: function(options){
|
||||
console.log("ScreenSelector Initialized");
|
||||
this.pos = options.pos;
|
||||
|
||||
this.screen_set = options.screen_set || {};
|
||||
|
@ -120,21 +119,117 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
|
||||
module.ScreenWidget = module.PosBaseWidget.extend({
|
||||
|
||||
show_numpad: true,
|
||||
show_leftpane: true,
|
||||
|
||||
init: function(parent,options){
|
||||
this._super(parent,options);
|
||||
this.hidden = false;
|
||||
},
|
||||
|
||||
help_button_action: function(){
|
||||
this.pos_widget.screen_selector.show_popup('help');
|
||||
},
|
||||
|
||||
logout_button_action: function(){
|
||||
this.pos_widget.screen_selector.set_user_mode('client');
|
||||
},
|
||||
|
||||
barcode_product_screen: 'scan', //if defined, this screen will be loaded when a product is scanned
|
||||
barcode_product_error_popup: 'error', //if defined, this popup will be loaded when there's an error in the popup
|
||||
|
||||
// what happens when a product is scanned :
|
||||
// it will add the product to the order and go to barcode_product_screen. Or show barcode_product_error_popup if
|
||||
// there's an error.
|
||||
barcode_product_action: function(ean){
|
||||
if(this.pos_widget.scan_product(ean)){
|
||||
this.pos.proxy.scan_item_success();
|
||||
if(this.barcode_product_screen){
|
||||
this.pos_widget.screen_selector.set_current_screen(this.barcode_product_screen);
|
||||
}
|
||||
}else{
|
||||
if(this.barcode_product_error_popup){
|
||||
this.pos_widget.screen_selector.show_popup(this.barcode_product_error_popup);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// what happens when a cashier id barcode is scanned.
|
||||
// the default behavior is the following :
|
||||
// - if there's a user with a matching ean, put it as the active 'cashier', go to cashier mode, and return true
|
||||
// - else : do nothing and return false. You probably want to extend this to show and appropriate error popup...
|
||||
barcode_cashier_action: function(ean){
|
||||
var users = this.pos.get('user_list');
|
||||
for(var i = 0, len = users.length; i < len; i++){
|
||||
if(users[i].ean === ean.ean){
|
||||
this.pos.set('cashier',users[i]);
|
||||
this.pos_widget.username.refresh();
|
||||
this.pos.proxy.cashier_mode_activated();
|
||||
this.pos_widget.screen_selector.set_user_mode('cashier');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
// what happens when a client id barcode is scanned.
|
||||
// the default behavior is the following :
|
||||
// - if there's a user with a matching ean, put it as the active 'client' and return true
|
||||
// - else : return false.
|
||||
barcode_client_action: function(ean){
|
||||
var users = this.pos.get('user_list');
|
||||
for(var i = 0, len = users.length; i < len; i++){
|
||||
if(users[i].ean === ean.ean){
|
||||
this.pos.set('client',users[i]);
|
||||
this.pos_widget.username.refresh();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
//TODO start the transaction
|
||||
},
|
||||
|
||||
// what happens when a discount barcode is scanned : the default behavior
|
||||
// is to set the discount on the last order.
|
||||
barcode_discount_action: function(ean){
|
||||
var last_orderline = this.pos.get('selectedOrder').getLastOrderline();
|
||||
if(last_orderline){
|
||||
last_orderline.set_discount(ean.value)
|
||||
}
|
||||
},
|
||||
|
||||
// this method shows the screen and sets up all the widget related to this screen. Extend this method
|
||||
// if you want to alter the behavior of the screen.
|
||||
show: function(){
|
||||
this.hidden = false;
|
||||
if(this.$element){
|
||||
this.$element.show();
|
||||
}
|
||||
|
||||
var self = this;
|
||||
var cashier_mode = this.pos_widget.screen_selector.get_user_mode() === 'cashier';
|
||||
|
||||
this.pos_widget.set_numpad_visible(this.show_numpad && cashier_mode);
|
||||
this.pos_widget.set_leftpane_visible(this.show_leftpane);
|
||||
this.pos_widget.set_cashier_controls_visible(cashier_mode);
|
||||
this.pos_widget.action_bar.set_element_visible('help-button', !cashier_mode, function(){ self.help_button_action(); });
|
||||
this.pos_widget.action_bar.set_element_visible('logout-button', cashier_mode, function(){ self.logout_button_action(); });
|
||||
this.pos_widget.action_bar.set_element_visible('close-button', cashier_mode);
|
||||
|
||||
this.pos_widget.username.set_user_mode(this.pos_widget.screen_selector.get_user_mode());
|
||||
|
||||
this.pos.barcode_reader.set_action_callback({
|
||||
'cashier': self.barcode_cashier_action ? function(ean){ self.barcode_cashier_action(ean); } : undefined ,
|
||||
'product': self.barcode_product_action ? function(ean){ self.barcode_product_action(ean); } : undefined ,
|
||||
'client' : self.barcode_client_action ? function(ean){ self.barcode_client_action(ean); } : undefined ,
|
||||
'discount': self.barcode_discount_action ? function(ean){ self.barcode_discount_action(ean); } : undefined,
|
||||
});
|
||||
},
|
||||
hide: function(){
|
||||
this.hidden = true;
|
||||
if(this.$element){
|
||||
this.$element.hide();
|
||||
}
|
||||
|
||||
|
||||
// this method is called when the screen is closed to make place for a new screen. this is a good place
|
||||
// to put your cleanup stuff as it is guaranteed that for each show() there is one and only one close()
|
||||
close: function(){
|
||||
if(this.pos.barcode_reader){
|
||||
this.pos.barcode_reader.reset_action_callbacks();
|
||||
}
|
||||
|
@ -142,8 +237,16 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
this.pos_widget.action_bar.destroy_buttons();
|
||||
}
|
||||
},
|
||||
close: function(){
|
||||
|
||||
// this methods hides the screen. It's not a good place to put your cleanup stuff as it is called on the
|
||||
// POS initialization.
|
||||
hide: function(){
|
||||
this.hidden = true;
|
||||
if(this.$element){
|
||||
this.$element.hide();
|
||||
}
|
||||
},
|
||||
|
||||
// we need this because some screens re-render themselves when they are hidden
|
||||
// (due to some events, or magic, or both...) we must make sure they remain hidden.
|
||||
// the good solution would probably be to make them not re-render themselves when they
|
||||
|
@ -234,75 +337,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
template:'ErrorNoSessionPopupWidget',
|
||||
});
|
||||
|
||||
module.BaseScreenWidget = module.ScreenWidget.extend({
|
||||
|
||||
show_numpad: true,
|
||||
show_leftpane: true,
|
||||
|
||||
help_button_action: function(){
|
||||
this.pos_widget.screen_selector.show_popup('help');
|
||||
},
|
||||
|
||||
logout_button_action: function(){
|
||||
this.pos_widget.screen_selector.set_user_mode('client');
|
||||
},
|
||||
|
||||
barcode_cashier_action: function(ean){
|
||||
this.pos.proxy.cashier_mode_activated();
|
||||
this.pos_widget.screen_selector.set_user_mode('cashier');
|
||||
},
|
||||
|
||||
barcode_product_screen: 'scan',
|
||||
barcode_product_error_popup: 'error',
|
||||
barcode_product_action: function(ean){
|
||||
if(this.pos_widget.scan_product(ean)){
|
||||
this.pos.proxy.scan_item_success();
|
||||
if(this.barcode_product_screen){
|
||||
this.pos_widget.screen_selector.set_current_screen(this.barcode_product_screen);
|
||||
}
|
||||
}else{
|
||||
if(this.barcode_product_error_popup){
|
||||
this.pos_widget.screen_selector.show_popup(this.barcode_product_error_popup);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
barcode_client_action: function(ean){
|
||||
this.pos.proxy.transaction_start();
|
||||
//TODO 'log the client'
|
||||
this.pos_widget.screen_selector.show_popup('receipt');
|
||||
},
|
||||
|
||||
barcode_discount_action: function(ean){
|
||||
var currentOrder = this.pos.get('selectedOrder');
|
||||
var last_orderline = currentOrder.last_orderline;
|
||||
if(last_orderline){
|
||||
last_orderline.set_discount(ean.value)
|
||||
}
|
||||
},
|
||||
|
||||
show: function(){
|
||||
this._super();
|
||||
var self = this;
|
||||
var cashier_mode = this.pos_widget.screen_selector.get_user_mode() === 'cashier';
|
||||
|
||||
this.pos_widget.set_numpad_visible(this.show_numpad && cashier_mode);
|
||||
this.pos_widget.set_leftpane_visible(this.show_leftpane);
|
||||
this.pos_widget.set_cashier_controls_visible(cashier_mode);
|
||||
this.pos_widget.action_bar.set_element_visible('help-button', !cashier_mode, function(){ self.help_button_action(); });
|
||||
this.pos_widget.action_bar.set_element_visible('logout-button', cashier_mode, function(){ self.logout_button_action(); });
|
||||
this.pos_widget.action_bar.set_element_visible('close-button', cashier_mode);
|
||||
|
||||
this.pos.barcode_reader.set_action_callback({
|
||||
'cashier': self.barcode_cashier_action ? function(ean){ self.barcode_cashier_action(ean); } : undefined ,
|
||||
'product': self.barcode_product_action ? function(ean){ self.barcode_product_action(ean); } : undefined ,
|
||||
'client' : self.barcode_client_action ? function(ean){ self.barcode_client_action(ean); } : undefined ,
|
||||
'discount': self.barcode_discount_action ? function(ean){ self.barcode_discount_action(ean); } : undefined,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
module.ScaleInviteScreenWidget = module.BaseScreenWidget.extend({
|
||||
module.ScaleInviteScreenWidget = module.ScreenWidget.extend({
|
||||
template:'ScaleInviteScreenWidget',
|
||||
|
||||
show: function(){
|
||||
|
@ -341,7 +376,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
},
|
||||
});
|
||||
|
||||
module.ScaleProductScreenWidget = module.BaseScreenWidget.extend({
|
||||
module.ScaleProductScreenWidget = module.ScreenWidget.extend({
|
||||
template:'ScaleProductSelectionScreenWidget',
|
||||
start: function(){
|
||||
this.product_categories_widget = new module.ProductCategoriesWidget(this,{
|
||||
|
@ -401,7 +436,29 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
},
|
||||
});
|
||||
|
||||
module.ClientPaymentScreenWidget = module.BaseScreenWidget.extend({
|
||||
module.ScaleScreenWidget = module.ScreenWidget.extend({
|
||||
template:'ScaleScreenWidget',
|
||||
show: function(){
|
||||
this._super();
|
||||
var self = this;
|
||||
|
||||
this.pos.proxy.weighting_start();
|
||||
this.intervalID = setInterval(function(){
|
||||
var weight = self.pos.proxy.weighting_read_kg();
|
||||
if(weight != self.weight){
|
||||
self.weight = weight;
|
||||
self.renderElement();
|
||||
}
|
||||
},500);
|
||||
},
|
||||
close: function(){
|
||||
this._super();
|
||||
clearInterval(this.intervalID);
|
||||
this.pos.proxy.weighting_end();
|
||||
},
|
||||
});
|
||||
|
||||
module.ClientPaymentScreenWidget = module.ScreenWidget.extend({
|
||||
template:'ClientPaymentScreenWidget',
|
||||
show: function(){
|
||||
this._super();
|
||||
|
@ -457,7 +514,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
},
|
||||
});
|
||||
|
||||
module.WelcomeScreenWidget = module.BaseScreenWidget.extend({
|
||||
module.WelcomeScreenWidget = module.ScreenWidget.extend({
|
||||
template:'WelcomeScreenWidget',
|
||||
|
||||
show_numpad: false,
|
||||
|
@ -479,7 +536,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
},
|
||||
});
|
||||
|
||||
module.ScanProductScreenWidget = module.BaseScreenWidget.extend({
|
||||
module.ScanProductScreenWidget = module.ScreenWidget.extend({
|
||||
template:'ScanProductScreenWidget',
|
||||
|
||||
show_numpad: false,
|
||||
|
@ -509,7 +566,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
},
|
||||
});
|
||||
|
||||
module.SearchProductScreenWidget = module.BaseScreenWidget.extend({
|
||||
module.SearchProductScreenWidget = module.ScreenWidget.extend({
|
||||
template:'SearchProductScreenWidget',
|
||||
|
||||
show_numpad: true,
|
||||
|
@ -550,7 +607,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
|
||||
});
|
||||
|
||||
module.ReceiptScreenWidget = module.BaseScreenWidget.extend({
|
||||
module.ReceiptScreenWidget = module.ScreenWidget.extend({
|
||||
template: 'ReceiptScreenWidget',
|
||||
|
||||
show_numpad: true,
|
||||
|
@ -609,7 +666,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
},
|
||||
});
|
||||
|
||||
module.PaymentScreenWidget = module.BaseScreenWidget.extend({
|
||||
module.PaymentScreenWidget = module.ScreenWidget.extend({
|
||||
template: 'PaymentScreenWidget',
|
||||
init: function(parent, options) {
|
||||
this._super(parent,options);
|
||||
|
@ -682,7 +739,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
this.renderElement();
|
||||
},
|
||||
addPaymentLine: function(newPaymentLine) {
|
||||
console.log('addPaymentLine:',newPaymentLine);
|
||||
console.log('NEW PAYMENT LINE WIDGET',newPaymentLine);
|
||||
var x = new module.PaymentlineWidget(null, {
|
||||
payment_line: newPaymentLine
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
function openerp_pos_widgets(instance, module){ //module is instance.point_of_sale
|
||||
var QWeb = instance.web.qweb;
|
||||
|
||||
module.NumpadWidget = instance.web.Widget.extend({
|
||||
module.NumpadWidget = module.PosBaseWidget.extend({
|
||||
template:'NumpadWidget',
|
||||
init: function(parent, options) {
|
||||
this._super(parent);
|
||||
|
@ -44,7 +44,6 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
renderElement: function() {
|
||||
var self = this;
|
||||
this._super();
|
||||
console.log('PaypadWidget:',this);
|
||||
|
||||
this.pos.get('cashRegisters').each(function(cashRegister) {
|
||||
var button = new module.PaypadButtonWidget(self,{
|
||||
|
@ -97,7 +96,7 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
renderElement: function() {
|
||||
this._super();
|
||||
this.$element.click(_.bind(this.click_handler, this));
|
||||
if(this.model.get('selected')){
|
||||
if(this.model.is_selected()){
|
||||
this.$element.addClass('selected');
|
||||
}
|
||||
},
|
||||
|
@ -130,9 +129,14 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
set_value: function(val) {
|
||||
var order = this.pos.get('selectedOrder');
|
||||
if (order.get('orderLines').length !== 0) {
|
||||
var param = {};
|
||||
param[this.numpadState.get('mode')] = val;
|
||||
order.getSelectedLine().set(param);
|
||||
var mode = this.numpadState.get('mode');
|
||||
if( mode === 'quantity'){
|
||||
order.getSelectedLine().set_quantity(val);
|
||||
}else if( mode === 'discount'){
|
||||
order.getSelectedLine().set_discount(val);
|
||||
}else if( mode === 'list_price'){
|
||||
order.getSelectedLine().set_list_price(val);
|
||||
}
|
||||
} else {
|
||||
this.pos.get('selectedOrder').destroy();
|
||||
}
|
||||
|
@ -202,9 +206,6 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
},
|
||||
});
|
||||
|
||||
// ---------- Product Screen ----------
|
||||
|
||||
|
||||
module.ProductWidget = module.PosBaseWidget.extend({
|
||||
template: 'ProductWidget',
|
||||
init: function(parent, options) {
|
||||
|
@ -250,20 +251,18 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
newAmount = event.currentTarget.value;
|
||||
if (newAmount && !isNaN(newAmount)) {
|
||||
this.amount = parseFloat(newAmount);
|
||||
this.payment_line.set({
|
||||
amount: this.amount,
|
||||
});
|
||||
this.payment_line.set_amount(this.amount);
|
||||
}
|
||||
},
|
||||
changedAmount: function() {
|
||||
if (this.amount !== this.payment_line.get('amount'))
|
||||
if (this.amount !== this.payment_line.get_amount())
|
||||
this.renderElement();
|
||||
},
|
||||
renderElement: function() {
|
||||
this.name = this.payment_line.get('journal_id')[1];
|
||||
this.name = this.payment_line.get_cashregister().get('journal_id')[1];
|
||||
this._super();
|
||||
$('input', this.$element).keyup(_.bind(this.changeAmount, this));
|
||||
$('.delete-payment-line', this.$element).click(this.on_delete);
|
||||
this.$('input').keyup(_.bind(this.changeAmount, this));
|
||||
this.$('.delete-payment-line').click(this.on_delete);
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -385,7 +384,6 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
}else{
|
||||
this.category = category;
|
||||
}
|
||||
console.log('setting categories:',this.category);
|
||||
|
||||
this.breadcrumb = [];
|
||||
for(var i = 1; i < this.category.ancestors.length; i++){
|
||||
|
@ -534,24 +532,60 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
},
|
||||
});
|
||||
|
||||
module.UsernameWidget = module.PosBaseWidget.extend({
|
||||
template: 'UsernameWidget',
|
||||
init: function(parent, options){
|
||||
var options = options || {};
|
||||
this._super(parent,options);
|
||||
this.mode = options.mode || 'cashier';
|
||||
},
|
||||
set_user_mode: function(mode){
|
||||
this.mode = mode;
|
||||
this.refresh();
|
||||
},
|
||||
refresh: function(){
|
||||
this.renderElement();
|
||||
},
|
||||
get_name: function(){
|
||||
var user;
|
||||
if(this.mode === 'cashier'){
|
||||
user = this.pos.get('cashier') || this.pos.get('user');
|
||||
}else{
|
||||
user = this.pos.get('client') || this.pos.get('user');
|
||||
}
|
||||
if(user){
|
||||
return user.name;
|
||||
}else{
|
||||
return "";
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// ---------- Main Point of Sale Widget ----------
|
||||
|
||||
// this is used to notify the user that data is being synchronized on the network
|
||||
module.SynchNotificationWidget = instance.web.Widget.extend({
|
||||
module.SynchNotificationWidget = module.PosBaseWidget.extend({
|
||||
template: "SynchNotificationWidget",
|
||||
init: function(parent) {
|
||||
this._super(parent);
|
||||
this.nbr_pending = 0;
|
||||
init: function(parent,options) {
|
||||
options = options || {};
|
||||
this._super(parent,options);
|
||||
},
|
||||
renderElement: function() {
|
||||
var self = this;
|
||||
this._super();
|
||||
$('.oe_pos_synch-notification-button', this.$element).click(this.on_synch);
|
||||
this.$('.oe_pos_synch-notification-button').click(function(){
|
||||
self.pos.flush();
|
||||
});
|
||||
},
|
||||
on_change_nbr_pending: function(nbr_pending) {
|
||||
this.nbr_pending = nbr_pending;
|
||||
this.renderElement();
|
||||
start: function(){
|
||||
var self = this;
|
||||
this.pos.bind('change:nbr_pending_operations', function(){
|
||||
self.renderElement();
|
||||
});
|
||||
},
|
||||
get_nbr_pending: function(){
|
||||
return this.pos.get('nbr_pending_operations');
|
||||
},
|
||||
on_synch: function() {}
|
||||
});
|
||||
|
||||
// The PosWidget is the main widget that contains all other widgets in the PointOfSale.
|
||||
|
@ -567,7 +601,6 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
module.PosWidget = module.PosBaseWidget.extend({
|
||||
template: 'PosWidget',
|
||||
init: function() {
|
||||
console.log('PosArguments:',arguments);
|
||||
this._super(arguments[0],{});
|
||||
|
||||
this.pos = new module.PosModel(this.session);
|
||||
|
@ -586,16 +619,6 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
return self.pos.ready.then(function() {
|
||||
self.build_currency_template();
|
||||
self.renderElement();
|
||||
self.synch_notification = new module.SynchNotificationWidget(this);
|
||||
self.synch_notification.replace($('.placeholder-SynchNotificationWidget', self.$element));
|
||||
self.synch_notification.on_synch.add(_.bind(self.pos.flush, self.pos));
|
||||
|
||||
self.pos.bind('change:nbr_pending_operations', self.changed_pending_operations, self);
|
||||
self.changed_pending_operations();
|
||||
|
||||
self.$element.find("#loggedas button").click(function() {
|
||||
self.try_close();
|
||||
});
|
||||
|
||||
self.$('button#neworder-button').click(_.bind(self.create_new_order, self));
|
||||
|
||||
|
@ -616,21 +639,16 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
instance.webclient.set_content_full_screen(true);
|
||||
|
||||
if (!self.pos.get('pos_session')) {
|
||||
self.screen_selector.show_popup('error',
|
||||
'Sorry, we could not create a user session');
|
||||
//}else if (!self.pos.get('bank_statements') || self.pos.get('bank_statements').length === 0){
|
||||
// self.screen_selector.show_popup('error',
|
||||
// 'Sorry, we could not find any accounting journals in the configuration');
|
||||
self.screen_selector.show_popup('error', 'Sorry, we could not create a user session');
|
||||
}else if(!self.pos.get('pos_config')){
|
||||
self.screen_selector.show_popup('error',
|
||||
'Sorry, we could not find any PoS Configuration for this session');
|
||||
self.screen_selector.show_popup('error', 'Sorry, we could not find any PoS Configuration for this session');
|
||||
}
|
||||
|
||||
$('.loader').animate({opacity:0},3000,'swing',function(){$('.loader').hide();});
|
||||
$('.loader img').hide();
|
||||
self.$('.loader').animate({opacity:0},3000,'swing',function(){$('.loader').hide();});
|
||||
self.$('.loader img').hide();
|
||||
|
||||
},function(){ // error when loading models data from the backend
|
||||
$('.loader img').hide();
|
||||
self.$('.loader img').hide();
|
||||
return new instance.web.Model("ir.model.data").get_func("search_read")([['name', '=', 'action_pos_session_opening']], ['res_id'])
|
||||
.pipe( _.bind(function(res){
|
||||
return instance.connection.rpc('/web/action/load', {'action_id': res[0]['res_id']})
|
||||
|
@ -689,6 +707,12 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
|
||||
// -------- Misc ---------
|
||||
|
||||
this.notification = new module.SynchNotificationWidget(this,{});
|
||||
this.notification.replace(this.$('.placeholder-SynchNotificationWidget'));
|
||||
|
||||
this.username = new module.UsernameWidget(this,{});
|
||||
this.username.replace(this.$('.placeholder-UsernameWidget'));
|
||||
|
||||
this.action_bar = new module.ActionBarWidget(this);
|
||||
this.action_bar.appendTo($(".point-of-sale #content"));
|
||||
|
||||
|
@ -759,15 +783,12 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
|
||||
if (parsed_ean.type === 'price') {
|
||||
var itemCode = parsed_ean.id;
|
||||
console.log('price! id:',itemCode);
|
||||
var scannedPackaging = _.detect(allPackages, function(pack) {
|
||||
return pack.ean && pack.ean.substring(0,7) === itemCode;
|
||||
});
|
||||
if (scannedPackaging) {
|
||||
console.log('found matching package, finding matching product...');
|
||||
scannedProductModel = _.detect(allProducts, function(pc) { return pc.id === scannedPackaging.product_id[0];});
|
||||
}else{
|
||||
console.log('matching package not found, finding matching product...');
|
||||
scannedProductModel = _.detect(allProducts, function(pc) { return pc.ean13 && (pc.ean13.substring(0,7) === parsed_ean.id);});
|
||||
}
|
||||
if(scannedProductModel){
|
||||
|
@ -780,10 +801,8 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
return pack.ean && pack.ean.substring(0,7) === itemCode;
|
||||
});
|
||||
if (scannedPackaging){
|
||||
console.log('found matching package, finding matching product...');
|
||||
scannedProductModel = _.detect(allProducts, function(pc) { return pc.id === scannedPackaging.product_id[0];});
|
||||
}else{
|
||||
console.log('matching package not found, finding matching product...');
|
||||
scannedProductModel = _.detect(allProducts, function(pc) { return pc.ean13 && (pc.ean13.substring(0,7) === parsed_ean.id);});
|
||||
}
|
||||
if(scannedProductModel){
|
||||
|
@ -811,13 +830,13 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
if(visible != this.numpad_visible){
|
||||
this.numpad_visible = visible;
|
||||
if(visible){
|
||||
$('#numpad').show();
|
||||
$('#paypad').show();
|
||||
$('#current-order').css({'bottom':'271px'});
|
||||
this.numpad.show();
|
||||
this.paypad.show();
|
||||
$('.point-of-sale .order-container').css({'bottom':'232px'});
|
||||
}else{
|
||||
$('#numpad').hide();
|
||||
$('#paypad').hide();
|
||||
$('#current-order').css({'bottom':'0px'});
|
||||
this.numpad.hide();
|
||||
this.paypad.hide();
|
||||
$('.point-of-sale .order-container').css({'bottom':'0px'});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -8,15 +8,14 @@
|
|||
<div id="topheader">
|
||||
<div id="branding">
|
||||
<img src="/point_of_sale/static/src/img/logo.png" />
|
||||
</div>
|
||||
<div id="loggedas">
|
||||
<span class="placeholder-SynchNotificationWidget"></span>
|
||||
<span class="placeholder-UsernameWidget"></span>
|
||||
</div>
|
||||
<div id="rightheader">
|
||||
<div id="order-selector">
|
||||
<button id="neworder-button">+</button>
|
||||
<button class="neworder-button">+</button>
|
||||
<ol id="orders"></ol>
|
||||
</div>
|
||||
<span class="placeholder-SynchNotificationWidget"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
|
@ -39,11 +38,11 @@
|
|||
|
||||
|
||||
<t t-name="SynchNotificationWidget">
|
||||
<span>
|
||||
<a t-if="widget.nbr_pending > 0" href="javascript:void(0)" class="oe_pos_synch-notification-button">
|
||||
<t t-esc="widget.nbr_pending"/> pending orders
|
||||
</a>
|
||||
</span>
|
||||
<div class="oe_pos_synch-notification">
|
||||
<t t-if="widget.get_nbr_pending() > 0" t-esc="widget.get_nbr_pending()"/>
|
||||
<div t-if="widget.get_nbr_pending() > 0" class="oe_status_red"></div>
|
||||
<div t-if="widget.get_nbr_pending() === 0" class="oe_status_green"></div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="PosCloseWarning">
|
||||
|
@ -146,6 +145,16 @@
|
|||
</table>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="ScaleScreenWidget">
|
||||
<div class="scale-screen screen">
|
||||
<header><h2>Product Weighting</h2></header>
|
||||
<div class="display">
|
||||
<span class="weight">0.000Kg</span>
|
||||
<span class="product-name"></span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="PaymentScreenWidget">
|
||||
<div id="payment-screen" class="screen">
|
||||
|
@ -358,29 +367,29 @@
|
|||
<t t-name="OrderlineWidget">
|
||||
<li class="orderline">
|
||||
<span class="product-name">
|
||||
<t t-esc="widget.model.get('name')"/>
|
||||
<t t-esc="widget.model.get_product().get('name')"/>
|
||||
</span>
|
||||
<span class="price">
|
||||
<t t-esc="widget.format_currency(widget.model.getPriceWithTax())"/>
|
||||
<t t-esc="widget.format_currency(widget.model.get_price_with_tax())"/>
|
||||
</span>
|
||||
<ul class="info-list">
|
||||
<t t-if="widget.model.get('quantity') !== 1.0">
|
||||
<t t-if="widget.model.get_quantity() !== 1.0">
|
||||
<li class="info">
|
||||
<em>
|
||||
<t t-esc="widget.model.get('quantity')" />
|
||||
<t t-esc="widget.model.get_quantity()" />
|
||||
</em>
|
||||
<t t-esc="widget.model.get_unit().name" />
|
||||
at
|
||||
<t t-esc="widget.format_currency(widget.model.get('list_price'))" />
|
||||
<t t-esc="widget.format_currency(widget.model.get_list_price())" />
|
||||
/
|
||||
<t t-esc="widget.model.get_unit().name" />
|
||||
</li>
|
||||
</t>
|
||||
<t t-if="widget.model.get('discount') > 0">
|
||||
<t t-if="widget.model.get_discount() > 0">
|
||||
<li class="info">
|
||||
With a
|
||||
<em>
|
||||
<t t-esc="widget.model.get('discount')" />%
|
||||
<t t-esc="widget.model.get_discount()" />%
|
||||
</em>
|
||||
discount
|
||||
</li>
|
||||
|
@ -395,14 +404,14 @@
|
|||
<t t-esc="widget.name"/>
|
||||
</td>
|
||||
<td class="paymentline-amount pos-right-align">
|
||||
<input type="text" t-att-value="widget.payment_line.get('amount').toFixed(2)" />
|
||||
<input type="text" t-att-value="widget.payment_line.get_amount().toFixed(2)" />
|
||||
<a href='javascript:void(0)' class='delete-payment-line'><img src="/point_of_sale/static/src/img/search_reset.gif" /></a>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
|
||||
<t t-name="PaypadButtonWidget">
|
||||
<button class="payment-button" t-att-cash-register-id="widget.cashRegister.get('id')">
|
||||
<button class="paypad-button" t-att-cash-register-id="widget.cashRegister.get('id')">
|
||||
<t t-esc="widget.cashRegister.get('journal').name"/>
|
||||
</button>
|
||||
<br />
|
||||
|
@ -414,6 +423,12 @@
|
|||
</li>
|
||||
</t>
|
||||
|
||||
<t t-name="UsernameWidget">
|
||||
<span class="username">
|
||||
<t t-esc="widget.get_name()" />
|
||||
</span>
|
||||
</t>
|
||||
|
||||
<t t-name="PosTicket">
|
||||
<div class="pos-sale-ticket">
|
||||
<div class="pos-right-align"><t t-esc="new Date().toString(Date.CultureInfo.formatPatterns.shortDate + ' ' +
|
||||
|
@ -427,13 +442,13 @@
|
|||
<table>
|
||||
<tr t-foreach="widget.currentOrderLines.toArray()" t-as="order">
|
||||
<td>
|
||||
<t t-esc="order.get('name')"/>
|
||||
<t t-esc="order.get_product().get('name')"/>
|
||||
</td>
|
||||
<td class="pos-right-align">
|
||||
<t t-esc="order.get('quantity').toFixed(0)"/>
|
||||
<t t-esc="order.get_quantity().toFixed(0)"/>
|
||||
</td>
|
||||
<td class="pos-right-align">
|
||||
<t t-esc="widget.format_currency((order.get('list_price') * (1 - order.get('discount')/100) * order.get('quantity')).toFixed(2))"/>
|
||||
<t t-esc="widget.format_currency(order.get_list_price() * (1 - order.get_discount()/100) * order.get_quantity().toFixed(2))"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -453,7 +468,7 @@
|
|||
<t t-esc="pline.get('journal_id')[1]"/>
|
||||
</td>
|
||||
<td class="pos-right-align">
|
||||
<t t-esc="widget.format_currency((pline.getAmount()).toFixed(2))"/>
|
||||
<t t-esc="widget.format_currency((pline.get_amount()).toFixed(2))"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
Loading…
Reference in New Issue