[WIP] point_of_sale: more perf improvement, this time on the receipt and payment screen + lots of usability improvements and cleanups
bzr revid: fva@openerp.com-20131204172122-mzl4wg4uw51uzdfv
This commit is contained in:
parent
7d062a0b45
commit
d4e7b6eb96
|
@ -89,13 +89,11 @@ Main Features
|
|||
'installable': True,
|
||||
'application': True,
|
||||
'js': [
|
||||
'static/lib/mousewheel/jquery.mousewheel-3.0.6.js',
|
||||
'static/lib/fastclick.js',
|
||||
'static/src/js/db.js',
|
||||
'static/src/js/models.js',
|
||||
'static/src/js/widget_base.js',
|
||||
'static/src/js/widget_keyboard.js',
|
||||
'static/src/js/widget_scrollbar.js',
|
||||
'static/src/js/widgets.js',
|
||||
'static/src/js/devices.js',
|
||||
'static/src/js/screens.js',
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
|
||||
* Licensed under the MIT License (LICENSE.txt).
|
||||
*
|
||||
* Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
|
||||
* Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
|
||||
* Thanks to: Seamus Leahy for adding deltaX and deltaY
|
||||
*
|
||||
* Version: 3.0.6
|
||||
*
|
||||
* Requires: 1.2.2+
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
|
||||
var types = ['DOMMouseScroll', 'mousewheel'];
|
||||
|
||||
if ($.event.fixHooks) {
|
||||
for ( var i=types.length; i; ) {
|
||||
$.event.fixHooks[ types[--i] ] = $.event.mouseHooks;
|
||||
}
|
||||
}
|
||||
|
||||
$.event.special.mousewheel = {
|
||||
setup: function() {
|
||||
if ( this.addEventListener ) {
|
||||
for ( var i=types.length; i; ) {
|
||||
this.addEventListener( types[--i], handler, false );
|
||||
}
|
||||
} else {
|
||||
this.onmousewheel = handler;
|
||||
}
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
if ( this.removeEventListener ) {
|
||||
for ( var i=types.length; i; ) {
|
||||
this.removeEventListener( types[--i], handler, false );
|
||||
}
|
||||
} else {
|
||||
this.onmousewheel = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.extend({
|
||||
mousewheel: function(fn) {
|
||||
return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
|
||||
},
|
||||
|
||||
unmousewheel: function(fn) {
|
||||
return this.unbind("mousewheel", fn);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function handler(event) {
|
||||
var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0;
|
||||
event = $.event.fix(orgEvent);
|
||||
event.type = "mousewheel";
|
||||
|
||||
// Old school scrollwheel delta
|
||||
if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta/120; }
|
||||
if ( orgEvent.detail ) { delta = -orgEvent.detail/3; }
|
||||
|
||||
// New school multidimensional scroll (touchpads) deltas
|
||||
deltaY = delta;
|
||||
|
||||
// Gecko
|
||||
if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
|
||||
deltaY = 0;
|
||||
deltaX = -1*delta;
|
||||
}
|
||||
|
||||
// Webkit
|
||||
if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; }
|
||||
if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; }
|
||||
|
||||
// Add event and delta to the front of the arguments
|
||||
args.unshift(event, delta, deltaX, deltaY);
|
||||
|
||||
return ($.event.dispatch || $.event.handle).apply(this, args);
|
||||
}
|
||||
|
||||
})(jQuery);
|
|
@ -705,37 +705,60 @@
|
|||
|
||||
/* b) The payment screen */
|
||||
|
||||
.pos .pos-step-container {
|
||||
display: inline-block;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
.pos .greyed-out{
|
||||
color: #AAA;
|
||||
}
|
||||
.pos .pos-step-container input{
|
||||
font-size: 1em;
|
||||
outline: none;
|
||||
border: none;
|
||||
padding: 0px 8px;
|
||||
padding-top: 8px;
|
||||
margin-left: 16px;
|
||||
background: white;
|
||||
color: #4c4c4c;
|
||||
box-shadow: 0px 2px rgba(143, 143, 143, 0.3) inset;
|
||||
-webkit-animation: all 250ms linear;
|
||||
}
|
||||
|
||||
.pos .pos-step-container input:focus{
|
||||
color: rgb(130, 124, 255);
|
||||
box-shadow: 0px 2px rgba(130, 124, 255, 0.3) inset;
|
||||
-webkit-animation: all 250ms linear;
|
||||
}
|
||||
|
||||
.pos .pos-payment-container {
|
||||
display: inline-block;
|
||||
font-size: 16px;
|
||||
text-align: left;
|
||||
min-width: 320px;
|
||||
margin-top: 40px;
|
||||
width: 360px;
|
||||
}
|
||||
.pos .payment-due-total {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
font-size: 48px;
|
||||
margin: 27px;
|
||||
text-shadow: 0px 2px rgb(202, 202, 202);
|
||||
}
|
||||
.pos .paymentline{
|
||||
position: relative;
|
||||
padding: 8px;
|
||||
border-box: 3px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.pos .paymentline-input{
|
||||
font-size: 20px;
|
||||
font-family: Lato;
|
||||
display: block;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
outline: none;
|
||||
border: none;
|
||||
padding: 6px 8px;
|
||||
background: white;
|
||||
color: #484848;
|
||||
text-align: right;
|
||||
box-shadow: 0px 2px rgba(143, 143, 143, 0.3) inset;
|
||||
}
|
||||
|
||||
.pos .paymentline-input:focus{
|
||||
color: rgb(130, 124, 255);
|
||||
box-shadow: 0px 2px rgba(219, 219, 219, 0.3) inset;
|
||||
-webkit-animation: all 250ms linear;
|
||||
}
|
||||
|
||||
.paymentline-delete {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.pos .pos-payment-container .left-block{
|
||||
display: inline-block;
|
||||
width:49%;
|
||||
|
@ -743,14 +766,15 @@
|
|||
padding:0;
|
||||
text-align:left;
|
||||
}
|
||||
.pos .pos-payment-container .header{
|
||||
margin-top: 0px;
|
||||
margin-bottom:20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.pos .pos-payment-container .infoline{
|
||||
margin-top:5px;
|
||||
margin-bottom:5px;
|
||||
padding: 0px 8px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
.pos .pos-payment-container .infoline.bigger{
|
||||
opacity: 1;
|
||||
font-size: 20px;
|
||||
}
|
||||
.pos .pos-payment-container .right-block{
|
||||
display: inline-block;
|
||||
|
@ -759,17 +783,8 @@
|
|||
padding:0;
|
||||
text-align:right;
|
||||
}
|
||||
.pos .pos-payment-container table {
|
||||
width: 100%;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.pos .pos-payment-container td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.pos .pos-payment-container .paymentline-type {
|
||||
font-size: 1em;
|
||||
font-weight: bold;
|
||||
margin-right:10px;
|
||||
.pos .paymentline.selected{
|
||||
background: rgb(220,220,220);
|
||||
}
|
||||
|
||||
/* c) The receipt screen */
|
||||
|
@ -784,6 +799,7 @@
|
|||
background-color: white;
|
||||
margin: 20px;
|
||||
padding: 15px;
|
||||
font-size: 14px;
|
||||
padding-bottom:30px;
|
||||
display: inline-block;
|
||||
font-family: "Inconsolata";
|
||||
|
|
|
@ -13,8 +13,6 @@ openerp.point_of_sale = function(instance) {
|
|||
|
||||
openerp_pos_keyboard(instance,module); // import pos_keyboard_widget.js
|
||||
|
||||
openerp_pos_scrollbar(instance,module); // import pos_scrollbar_widget.js
|
||||
|
||||
openerp_pos_screens(instance,module); // import pos_screens.js
|
||||
|
||||
openerp_pos_devices(instance,module); // import pos_devices.js
|
||||
|
|
|
@ -669,25 +669,30 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
model: module.Orderline,
|
||||
});
|
||||
|
||||
// Every PaymentLine contains a cashregister and an amount of money.
|
||||
// Every Paymentline contains a cashregister and an amount of money.
|
||||
module.Paymentline = Backbone.Model.extend({
|
||||
initialize: function(attributes, options) {
|
||||
this.amount = 0;
|
||||
this.cashregister = options.cashRegister;
|
||||
this.name = this.cashregister.get('journal_id')[1];
|
||||
this.selected = false;
|
||||
},
|
||||
//sets the amount of money on this payment line
|
||||
set_amount: function(value){
|
||||
this.amount = parseFloat(value) || 0;
|
||||
this.trigger('change');
|
||||
this.amount = round_di(parseFloat(value) || 0, 2);
|
||||
this.trigger('change:amount',this);
|
||||
},
|
||||
// returns the amount of money on this paymentline
|
||||
get_amount: function(){
|
||||
return this.amount;
|
||||
},
|
||||
// returns the associated cashRegister
|
||||
get_cashregister: function(){
|
||||
return this.cashregister;
|
||||
set_selected: function(selected){
|
||||
if(this.selected !== selected){
|
||||
this.selected = selected;
|
||||
this.trigger('change:selected',this);
|
||||
}
|
||||
},
|
||||
// returns the associated cashRegister
|
||||
//exports as JSON for server communication
|
||||
export_as_JSON: function(){
|
||||
return {
|
||||
|
@ -713,7 +718,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
|
||||
|
||||
// An order more or less represents the content of a client's shopping cart (the OrderLines)
|
||||
// plus the associated payment information (the PaymentLines)
|
||||
// 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({
|
||||
|
@ -727,8 +732,9 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
name: "Order " + this.uid,
|
||||
client: null,
|
||||
});
|
||||
this.pos = attributes.pos;
|
||||
this.selected_orderline = undefined;
|
||||
this.pos = attributes.pos;
|
||||
this.selected_orderline = undefined;
|
||||
this.selected_paymentline = undefined;
|
||||
this.screen_data = {}; // see ScreenSelector
|
||||
this.receipt_type = 'receipt'; // 'receipt' || 'invoice'
|
||||
return this;
|
||||
|
@ -765,13 +771,21 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
getLastOrderline: function(){
|
||||
return this.get('orderLines').at(this.get('orderLines').length -1);
|
||||
},
|
||||
addPaymentLine: function(cashRegister) {
|
||||
addPaymentline: function(cashRegister) {
|
||||
var paymentLines = this.get('paymentLines');
|
||||
var newPaymentline = new module.Paymentline({},{cashRegister:cashRegister});
|
||||
if(cashRegister.get('journal').type !== 'cash'){
|
||||
newPaymentline.set_amount( this.getDueLeft() );
|
||||
newPaymentline.set_amount( Math.max(this.getDueLeft(),0) );
|
||||
}
|
||||
paymentLines.add(newPaymentline);
|
||||
this.selectPaymentline(newPaymentline);
|
||||
|
||||
},
|
||||
removePaymentline: function(line){
|
||||
if(this.selected_paymentline === line){
|
||||
this.selectPaymentline(undefined);
|
||||
}
|
||||
this.get('paymentLines').remove(line);
|
||||
},
|
||||
getName: function() {
|
||||
return this.get('name');
|
||||
|
@ -946,6 +960,19 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
this.selected_orderline = undefined;
|
||||
}
|
||||
},
|
||||
selectPaymentline: function(line){
|
||||
console.log("SELECT_PAYMENTLINE",line);
|
||||
if(line !== this.selected_paymentline){
|
||||
if(this.selected_paymentline){
|
||||
this.selected_paymentline.set_selected(false);
|
||||
}
|
||||
this.selected_paymentline = line;
|
||||
if(this.selected_paymentline){
|
||||
this.selected_paymentline.set_selected(true);
|
||||
}
|
||||
this.trigger('change:selected_paymentline',this.selected_paymentline);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
module.OrderCollection = Backbone.Collection.extend({
|
||||
|
|
|
@ -157,6 +157,8 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
barcode_product_screen: 'products', //if defined, this screen will be loaded when a product is scanned
|
||||
barcode_product_error_popup: 'error-product', //if defined, this popup will be loaded when there's an error in the popup
|
||||
|
||||
hotkeys_handlers: {},
|
||||
|
||||
// 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.
|
||||
|
@ -634,7 +636,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
}
|
||||
|
||||
var cashregister = selfCheckoutRegisters[0] || self.pos.get('cashRegisters').models[0];
|
||||
currentOrder.add_payment_line(cashregister);
|
||||
currentOrder.addPaymentline(cashregister);
|
||||
self.pos.push_order(currentOrder)
|
||||
currentOrder.destroy();
|
||||
self.pos.proxy.transaction_end();
|
||||
|
@ -802,15 +804,12 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
|
||||
init: function(parent, options) {
|
||||
this._super(parent,options);
|
||||
this.model = options.model;
|
||||
this.user = this.pos.get('user');
|
||||
this.company = this.pos.get('company');
|
||||
this.shop_obj = this.pos.get('shop');
|
||||
},
|
||||
renderElement: function() {
|
||||
this._super();
|
||||
this.pos.bind('change:selectedOrder', this.change_selected_order, this);
|
||||
this.change_selected_order();
|
||||
},
|
||||
show: function(){
|
||||
this._super();
|
||||
|
@ -828,6 +827,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
click: function() { self.finishOrder(); },
|
||||
});
|
||||
|
||||
this.refresh();
|
||||
this.print();
|
||||
|
||||
// THIS IS THE HACK OF THE CENTURY
|
||||
|
@ -859,22 +859,14 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
finishOrder: function() {
|
||||
this.pos.get('selectedOrder').destroy();
|
||||
},
|
||||
change_selected_order: function() {
|
||||
if (this.currentOrderLines)
|
||||
this.currentOrderLines.unbind();
|
||||
this.currentOrderLines = (this.pos.get('selectedOrder')).get('orderLines');
|
||||
this.currentOrderLines.bind('add', this.refresh, this);
|
||||
this.currentOrderLines.bind('change', this.refresh, this);
|
||||
this.currentOrderLines.bind('remove', this.refresh, this);
|
||||
if (this.currentPaymentLines)
|
||||
this.currentPaymentLines.unbind();
|
||||
this.currentPaymentLines = (this.pos.get('selectedOrder')).get('paymentLines');
|
||||
this.currentPaymentLines.bind('all', this.refresh, this);
|
||||
this.refresh();
|
||||
},
|
||||
refresh: function() {
|
||||
this.currentOrder = this.pos.get('selectedOrder');
|
||||
$('.pos-receipt-container', this.$el).html(QWeb.render('PosTicket',{widget:this}));
|
||||
var order = this.pos.get('selectedOrder');
|
||||
$('.pos-receipt-container', this.$el).html(QWeb.render('PosTicket',{
|
||||
widget:this,
|
||||
order: order,
|
||||
orderlines: order.get('orderLines').models,
|
||||
paymentlines: order.get('paymentLines').models,
|
||||
}));
|
||||
},
|
||||
close: function(){
|
||||
this._super();
|
||||
|
@ -886,17 +878,68 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
back_screen: 'products',
|
||||
next_screen: 'receipt',
|
||||
init: function(parent, options) {
|
||||
var self = this;
|
||||
this._super(parent,options);
|
||||
this.model = options.model;
|
||||
this.pos.bind('change:selectedOrder', this.change_selected_order, this);
|
||||
this.bind_payment_line_events();
|
||||
this.bind_orderline_events();
|
||||
this.paymentlinewidgets = [];
|
||||
this.focusedLine = null;
|
||||
|
||||
this.pos.bind('change:selectedOrder',function(){
|
||||
this.bind_events();
|
||||
this.renderElement();
|
||||
},this);
|
||||
|
||||
this.bind_events();
|
||||
|
||||
this.line_delete_handler = function(event){
|
||||
var node = this;
|
||||
while(node && !node.classList.contains('paymentline')){
|
||||
node = node.parentNode;
|
||||
}
|
||||
if(node){
|
||||
self.pos.get('selectedOrder').removePaymentline(node.line)
|
||||
}
|
||||
event.stopPropagation();
|
||||
};
|
||||
|
||||
this.line_change_handler = function(event){
|
||||
var node = this;
|
||||
while(node && !node.classList.contains('paymentline')){
|
||||
node = node.parentNode;
|
||||
}
|
||||
if(node){
|
||||
node.line.set_amount(this.value);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.line_click_handler = function(event){
|
||||
console.log('click');
|
||||
var node = this;
|
||||
while(node && !node.classList.contains('paymentline')){
|
||||
node = node.parentNode;
|
||||
}
|
||||
if(node){
|
||||
self.pos.get('selectedOrder').selectPaymentline(node.line);
|
||||
}
|
||||
};
|
||||
|
||||
},
|
||||
show: function(){
|
||||
this._super();
|
||||
var self = this;
|
||||
|
||||
this.enable_numpad();
|
||||
this.update_payment_summary();
|
||||
this.focus_selected_line();
|
||||
window.removeall = function(){
|
||||
self.remove_empty_lines();
|
||||
};
|
||||
window.listlines = function(){
|
||||
var lines = self.pos.get('selectedOrder').get('paymentLines').models;
|
||||
for(var i = 0; i < lines.length; i++){
|
||||
console.log('LINE:',lines[i]);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
this.hotkey_handler = function(event){
|
||||
if(event.which === 13){
|
||||
|
@ -907,13 +950,16 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
};
|
||||
|
||||
$('body').on('keyup',this.hotkey_handler);
|
||||
|
||||
*/
|
||||
|
||||
|
||||
if( this.pos.iface_cashdrawer && this.pos.get('selectedOrder').get('paymentLines').find( function(pl){ return pl.cashregister.get('journal').type === 'cash'; })){
|
||||
if( this.pos.iface_cashdrawer
|
||||
&& this.pos.get('selectedOrder').get('paymentLines').find( function(pl){
|
||||
return pl.cashregister.get('journal').type === 'cash';
|
||||
})){
|
||||
this.pos.proxy.open_cashbox();
|
||||
}
|
||||
|
||||
this.enable_numpad();
|
||||
|
||||
this.add_action_button({
|
||||
label: _t('Back'),
|
||||
|
@ -928,17 +974,17 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
name: 'validation',
|
||||
icon: '/point_of_sale/static/src/img/icons/png48/validate.png',
|
||||
click: function(){
|
||||
self.validate();
|
||||
self.validate_order();
|
||||
},
|
||||
});
|
||||
|
||||
if(this.pos.iface_invoicing){
|
||||
if( this.pos.iface_invoicing ){
|
||||
this.add_action_button({
|
||||
label: 'Invoice',
|
||||
name: 'invoice',
|
||||
icon: '/point_of_sale/static/src/img/icons/png48/invoice.png',
|
||||
click: function(){
|
||||
self.validate({invoice: true});
|
||||
self.validate_order({invoice: true});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -954,23 +1000,163 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
});
|
||||
}
|
||||
|
||||
this.update_payment_summary();
|
||||
this.line_refocus();
|
||||
},
|
||||
close: function(){
|
||||
this._super();
|
||||
this.disable_numpad();
|
||||
$('body').off('keyup',this.hotkey_handler);
|
||||
//$('body').off('keyup',this.hotkey_handler);
|
||||
},
|
||||
remove_empty_lines: function(){
|
||||
var order = this.pos.get('selectedOrder');
|
||||
var lines = order.get('paymentLines').models.slice(0);
|
||||
for(var i = 0; i < lines.length; i++){
|
||||
var line = lines[i];
|
||||
if(line.get_amount() === 0){
|
||||
order.removePaymentline(line);
|
||||
}
|
||||
}
|
||||
},
|
||||
back: function() {
|
||||
_.each(this.paymentlinewidgets, function(widget){
|
||||
if( widget.payment_line.get_amount() === 0 ){
|
||||
widget.payment_line.destroy();
|
||||
}
|
||||
});
|
||||
this.remove_empty_lines();
|
||||
this.pos_widget.screen_selector.set_current_screen(this.back_screen);
|
||||
},
|
||||
validate: function(options) {
|
||||
bind_events: function() {
|
||||
if(this.old_order){
|
||||
this.old_order.unbind(null,null,this);
|
||||
}
|
||||
var order = this.pos.get('selectedOrder');
|
||||
order.bind('change:selected_paymentline',this.focus_selected_line,this);
|
||||
|
||||
this.old_order = order;
|
||||
|
||||
if(this.old_paymentlines){
|
||||
this.old_paymentlines.unbind(null,null,this);
|
||||
}
|
||||
var paymentlines = order.get('paymentLines');
|
||||
paymentlines.bind('add', this.add_paymentline, this);
|
||||
paymentlines.bind('change:selected', this.rerender_paymentline, this);
|
||||
paymentlines.bind('change:amount', function(line){
|
||||
if(!line.selected && line.node){
|
||||
line.node.value = line.amount.toFixed(2);
|
||||
}
|
||||
this.update_payment_summary();
|
||||
},this);
|
||||
paymentlines.bind('remove', this.remove_paymentline, this);
|
||||
paymentlines.bind('all', this.update_payment_summary, this);
|
||||
|
||||
this.old_paymentlines = paymentlines;
|
||||
|
||||
if(this.old_orderlines){
|
||||
this.old_orderlines.unbind(null,null,this);
|
||||
}
|
||||
var orderlines = order.get('orderLines');
|
||||
orderlines.bind('all', this.update_payment_summary, this);
|
||||
|
||||
this.old_orderlines = orderlines;
|
||||
},
|
||||
focus_selected_line: function(){
|
||||
var line = this.pos.get('selectedOrder').selected_paymentline;
|
||||
if(line){
|
||||
debugger;
|
||||
if(!line.node){
|
||||
debugger;
|
||||
}
|
||||
var input = line.node.querySelector('input');
|
||||
if(!input){
|
||||
return;
|
||||
}
|
||||
var value = input.value;
|
||||
input.focus();
|
||||
|
||||
if(this.numpad_state){
|
||||
this.numpad_state.reset();
|
||||
}
|
||||
|
||||
if(Number(value) === 0){
|
||||
input.value = '';
|
||||
}else{
|
||||
input.value = value;
|
||||
input.select();
|
||||
}
|
||||
}
|
||||
},
|
||||
add_paymentline: function(line) {
|
||||
var list_container = this.el.querySelector('.payment-lines');
|
||||
list_container.appendChild(this.render_paymentline(line));
|
||||
|
||||
if(this.numpad_state){
|
||||
this.numpad_state.reset();
|
||||
}
|
||||
},
|
||||
render_paymentline: function(line){
|
||||
var el_html = openerp.qweb.render('Paymentline',{widget: this, line: line});
|
||||
el_html = _.str.trim(el_html);
|
||||
|
||||
var el_node = document.createElement('tbody');
|
||||
el_node.innerHTML = el_html;
|
||||
el_node = el_node.childNodes[0];
|
||||
el_node.line = line;
|
||||
el_node.querySelector('.paymentline-delete')
|
||||
.addEventListener('click', this.line_delete_handler);
|
||||
el_node.addEventListener('click', this.line_click_handler);
|
||||
el_node.querySelector('input')
|
||||
.addEventListener('keyup', this.line_change_handler);
|
||||
|
||||
line.node = el_node;
|
||||
|
||||
return el_node;
|
||||
},
|
||||
rerender_paymentline: function(line){
|
||||
var old_node = line.node;
|
||||
var new_node = this.render_paymentline(line);
|
||||
|
||||
old_node.parentNode.replaceChild(new_node,old_node);
|
||||
console.log('RERENDER',line);
|
||||
},
|
||||
remove_paymentline: function(line){
|
||||
console.log('Removing line from DOM:',line);
|
||||
line.node.parentNode.removeChild(line.node);
|
||||
line.node = undefined;
|
||||
},
|
||||
renderElement: function(){
|
||||
this._super();
|
||||
|
||||
var paymentlines = this.pos.get('selectedOrder').get('paymentLines').models;
|
||||
var list_container = this.el.querySelector('.payment-lines');
|
||||
|
||||
for(var i = 0; i < paymentlines.length; i++){
|
||||
list_container.appendChild(this.render_paymentline(paymentlines[i]));
|
||||
}
|
||||
|
||||
//this.update_payment_summary();
|
||||
},
|
||||
update_payment_summary: function() {
|
||||
var currentOrder = this.pos.get('selectedOrder');
|
||||
var paidTotal = currentOrder.getPaidTotal();
|
||||
var dueTotal = currentOrder.getTotalTaxIncluded();
|
||||
var remaining = dueTotal > paidTotal ? dueTotal - paidTotal : 0;
|
||||
var change = paidTotal > dueTotal ? paidTotal - dueTotal : 0;
|
||||
|
||||
this.$('.payment-due-total').html(this.format_currency(dueTotal));
|
||||
this.$('.payment-paid-total').html(this.format_currency(paidTotal));
|
||||
this.$('.payment-remaining').html(this.format_currency(remaining));
|
||||
this.$('.payment-change').html(this.format_currency(change));
|
||||
if(currentOrder.selected_orderline === undefined){
|
||||
remaining = 1; // What is this ?
|
||||
}
|
||||
|
||||
if(this.pos_widget.action_bar){
|
||||
this.pos_widget.action_bar.set_button_disabled('validation', !this.is_paid());
|
||||
this.pos_widget.action_bar.set_button_disabled('invoice', !this.is_paid());
|
||||
}
|
||||
},
|
||||
is_paid: function(){
|
||||
var currentOrder = this.pos.get('selectedOrder');
|
||||
return (currentOrder.getTotalTaxIncluded() >= 0.000001
|
||||
&& currentOrder.getPaidTotal() + 0.000001 >= currentOrder.getTotalTaxIncluded());
|
||||
|
||||
},
|
||||
validate_order: function(options) {
|
||||
var self = this;
|
||||
options = options || {};
|
||||
|
||||
|
@ -1012,97 +1198,13 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
this.pos_widget.screen_selector.set_current_screen(this.next_screen);
|
||||
}
|
||||
}
|
||||
|
||||
// hide onscreen (iOS) keyboard
|
||||
setTimeout(function(){
|
||||
document.activeElement.blur();
|
||||
$("input").blur();
|
||||
},250);
|
||||
},
|
||||
bind_payment_line_events: function() {
|
||||
this.currentPaymentLines = (this.pos.get('selectedOrder')).get('paymentLines');
|
||||
this.currentPaymentLines.bind('add', this.add_payment_line, this);
|
||||
this.currentPaymentLines.bind('remove', this.renderElement, 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.update_payment_summary, this);
|
||||
},
|
||||
change_selected_order: function() {
|
||||
this.currentPaymentLines.unbind();
|
||||
this.bind_payment_line_events();
|
||||
this.currentOrderLines.unbind();
|
||||
this.bind_orderline_events();
|
||||
this.renderElement();
|
||||
},
|
||||
line_refocus: function(lineWidget){
|
||||
if(lineWidget){
|
||||
if(this.focusedLine !== lineWidget){
|
||||
this.focusedLine = lineWidget;
|
||||
}
|
||||
}
|
||||
if(this.focusedLine){
|
||||
this.focusedLine.focus();
|
||||
}
|
||||
},
|
||||
add_payment_line: function(newPaymentLine) {
|
||||
var self = this;
|
||||
var l = new module.PaymentlineWidget(this, {
|
||||
payment_line: newPaymentLine,
|
||||
});
|
||||
l.on('delete_payment_line', self, function(r) {
|
||||
self.deleteLine(r);
|
||||
});
|
||||
l.appendTo(this.$('.paymentlines'));
|
||||
this.paymentlinewidgets.push(l);
|
||||
if(this.numpadState){
|
||||
this.numpadState.resetValue();
|
||||
}
|
||||
this.line_refocus(l);
|
||||
},
|
||||
renderElement: function() {
|
||||
this._super();
|
||||
this.$('.paymentlines').empty();
|
||||
for(var i = 0, len = this.paymentlinewidgets.length; i < len; i++){
|
||||
this.paymentlinewidgets[i].destroy();
|
||||
}
|
||||
this.paymentlinewidgets = [];
|
||||
|
||||
this.currentPaymentLines.each(_.bind( function(paymentLine) {
|
||||
this.add_payment_line(paymentLine);
|
||||
}, this));
|
||||
this.update_payment_summary();
|
||||
},
|
||||
deleteLine: function(lineWidget) {
|
||||
this.currentPaymentLines.remove([lineWidget.payment_line]);
|
||||
lineWidget.destroy();
|
||||
},
|
||||
is_paid: function(){
|
||||
var currentOrder = this.pos.get('selectedOrder');
|
||||
return (currentOrder.getTotalTaxIncluded() >= 0.000001
|
||||
&& currentOrder.getPaidTotal() + 0.000001 >= currentOrder.getTotalTaxIncluded());
|
||||
|
||||
},
|
||||
update_payment_summary: function() {
|
||||
var currentOrder = this.pos.get('selectedOrder');
|
||||
var paidTotal = currentOrder.getPaidTotal();
|
||||
var dueTotal = currentOrder.getTotalTaxIncluded();
|
||||
var remaining = dueTotal > paidTotal ? dueTotal - paidTotal : 0;
|
||||
var change = paidTotal > dueTotal ? paidTotal - dueTotal : 0;
|
||||
|
||||
this.$('.payment-due-total').html(this.format_currency(dueTotal));
|
||||
this.$('.payment-paid-total').html(this.format_currency(paidTotal));
|
||||
this.$('.payment-remaining').html(this.format_currency(remaining));
|
||||
this.$('.payment-change').html(this.format_currency(change));
|
||||
if(currentOrder.selected_orderline === undefined){
|
||||
remaining = 1; // What is this ?
|
||||
}
|
||||
|
||||
if(this.pos_widget.action_bar){
|
||||
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;
|
||||
|
@ -1124,7 +1226,11 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
this.numpad_state.set({mode: 'payment'});
|
||||
},
|
||||
set_value: function(val) {
|
||||
this.currentPaymentLines.last().set_amount(val);
|
||||
var selected_line =this.pos.get('selectedOrder').selected_paymentline;
|
||||
if(selected_line){
|
||||
selected_line.set_amount(val);
|
||||
selected_line.node.querySelector('input').value = selected_line.amount.toFixed(2);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -60,9 +60,6 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
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);
|
||||
|
@ -128,7 +125,7 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
console.warn('TODO should not get there...?');
|
||||
return;
|
||||
}
|
||||
self.pos.get('selectedOrder').addPaymentLine(self.cashRegister);
|
||||
self.pos.get('selectedOrder').addPaymentline(self.cashRegister);
|
||||
self.pos_widget.screen_selector.set_current_screen('payment');
|
||||
});
|
||||
},
|
||||
|
@ -208,11 +205,6 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
this.update_summary();
|
||||
},this);
|
||||
},
|
||||
update_numpad: function() {
|
||||
this.selected_line = this.pos.get('selectedOrder').getSelectedLine();
|
||||
if (this.numpadState)
|
||||
this.numpadState.reset();
|
||||
},
|
||||
render_orderline: function(orderline){
|
||||
var el_str = openerp.qweb.render('Orderline',{widget:this, line:orderline});
|
||||
var el_node = document.createElement('div');
|
||||
|
@ -236,6 +228,7 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
var replacement_line = this.render_orderline(order_line);
|
||||
node.parentNode.replaceChild(replacement_line,node);
|
||||
},
|
||||
// overriding the openerp framework replace method for performance reasons
|
||||
replace: function($target){
|
||||
this.renderElement();
|
||||
var target = $target[0];
|
||||
|
@ -278,58 +271,6 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
},
|
||||
});
|
||||
|
||||
module.PaymentlineWidget = module.PosBaseWidget.extend({
|
||||
template: 'PaymentlineWidget',
|
||||
init: function(parent, options) {
|
||||
this._super(parent,options);
|
||||
this.payment_line = options.payment_line;
|
||||
this.payment_line.bind('change', this.changedAmount, this);
|
||||
},
|
||||
changeAmount: function(event) {
|
||||
var newAmount = event.currentTarget.value;
|
||||
var amount = parseFloat(newAmount);
|
||||
if(!isNaN(amount)){
|
||||
this.amount = amount;
|
||||
this.payment_line.set_amount(amount);
|
||||
}
|
||||
},
|
||||
checkAmount: function(e){
|
||||
if (e.which !== 0 && e.charCode !== 0) {
|
||||
if(isNaN(String.fromCharCode(e.charCode))){
|
||||
return (String.fromCharCode(e.charCode) === "." && e.currentTarget.value.toString().split(".").length < 2)?true:false;
|
||||
}
|
||||
}
|
||||
return true
|
||||
},
|
||||
changedAmount: function() {
|
||||
if (this.amount !== this.payment_line.get_amount()){
|
||||
this.renderElement();
|
||||
}
|
||||
},
|
||||
renderElement: function() {
|
||||
var self = this;
|
||||
this.name = this.payment_line.get_cashregister().get('journal_id')[1];
|
||||
this._super();
|
||||
this.$('input').keypress(_.bind(this.checkAmount, this))
|
||||
.keyup(function(event){
|
||||
self.changeAmount(event);
|
||||
});
|
||||
this.$('.delete-payment-line').click(function() {
|
||||
self.trigger('delete_payment_line', self);
|
||||
});
|
||||
},
|
||||
focus: function(){
|
||||
var val = this.$('input')[0].value;
|
||||
this.$('input')[0].focus();
|
||||
if(Number(val) === 0){
|
||||
this.$('input')[0].value = '';
|
||||
}else{
|
||||
this.$('input')[0].value = val;
|
||||
this.$('input')[0].select();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
module.OrderButtonWidget = module.PosBaseWidget.extend({
|
||||
template:'OrderButtonWidget',
|
||||
init: function(parent, options) {
|
||||
|
@ -918,12 +859,6 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
self.pos.delete_current_order();
|
||||
});
|
||||
|
||||
$('body').on('keyup',function(event){
|
||||
if(event.which === 13){
|
||||
self.set_fullscreen();
|
||||
}
|
||||
});
|
||||
|
||||
//when a new order is created, add an order button widget
|
||||
self.pos.get('orders').bind('add', function(new_order){
|
||||
var new_order_button = new module.OrderButtonWidget(null, {
|
||||
|
|
|
@ -246,41 +246,32 @@
|
|||
<t t-name="PaymentScreenWidget">
|
||||
<div class="payment-screen screen">
|
||||
<header><h2>Payment</h2></header>
|
||||
<div class="pos-step-container">
|
||||
<div class="pos-payment-container">
|
||||
<br />
|
||||
<div class="header">
|
||||
<span class="left-block">
|
||||
Total:
|
||||
<div class="pos-payment-container">
|
||||
<div class='payment-due-total'></div>
|
||||
<div class='payment-lines'></div>
|
||||
<div class='payment-info'>
|
||||
<div class="infoline">
|
||||
<span class='left-block'>
|
||||
Paid:
|
||||
</span>
|
||||
<span class="right-block payment-due-total"></span>
|
||||
<span class="right-block payment-paid-total"></span>
|
||||
</div>
|
||||
<table class="paymentlines">
|
||||
</table>
|
||||
<div class="footer">
|
||||
<div class="infoline">
|
||||
<span class='left-block'>
|
||||
Paid:
|
||||
</span>
|
||||
<span class="right-block payment-paid-total"></span>
|
||||
</div>
|
||||
<div class="infoline">
|
||||
<span class='left-block'>
|
||||
Remaining:
|
||||
</span>
|
||||
<span class="right-block payment-remaining"></span>
|
||||
</div>
|
||||
<div class="infoline" >
|
||||
<span class='left-block'>
|
||||
Change:
|
||||
</span>
|
||||
<span class="right-block payment-change"></span>
|
||||
</div>
|
||||
<div class="infoline">
|
||||
<span class='left-block'>
|
||||
Remaining:
|
||||
</span>
|
||||
<span class="right-block payment-remaining"></span>
|
||||
</div>
|
||||
<div class="infoline bigger" >
|
||||
<span class='left-block'>
|
||||
Change:
|
||||
</span>
|
||||
<span class="right-block payment-change"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t> <!-- pos-payment-screen -->
|
||||
</t>
|
||||
|
||||
<t t-name="ReceiptScreenWidget">
|
||||
<div class="receipt-screen screen" >
|
||||
|
@ -556,14 +547,26 @@
|
|||
</li>
|
||||
</t>
|
||||
|
||||
<t t-name="PaymentlineWidget">
|
||||
<tr class="paymentline">
|
||||
<t t-name="Paymentline">
|
||||
<div t-attf-class="paymentline #{line.selected ? 'selected' : ''}">
|
||||
<div class='paymentline-name'>
|
||||
<t t-esc="line.name"/>
|
||||
</div>
|
||||
<input class='paymentline-input' type="number" step="0.01" t-att-value="line.get_amount().toFixed(2)" />
|
||||
<span class='paymentline-delete'>
|
||||
<img src="/point_of_sale/static/src/img/search_reset.gif" />
|
||||
</span>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="PaymentlineOld">
|
||||
<tr t-attf-class="paymentline #{line.selected ? 'selected' : ''}">
|
||||
<td class="paymentline-type">
|
||||
<t t-esc="widget.name"/>
|
||||
<t t-esc="line.name"/>
|
||||
</td>
|
||||
<td class="paymentline-amount pos-right-align">
|
||||
<input type="number" step="0.01" 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>
|
||||
<input type="number" step="0.01" t-att-value="line.get_amount().toFixed(2)" />
|
||||
<span class='delete-payment-line'><img src="/point_of_sale/static/src/img/search_reset.gif" /></span>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
|
@ -590,7 +593,7 @@
|
|||
<div class="pos-sale-ticket">
|
||||
|
||||
<div class="pos-center-align"><t t-esc="new Date().toString(Date.CultureInfo.formatPatterns.shortDate + ' ' +
|
||||
Date.CultureInfo.formatPatterns.longTime)"/> <t t-esc="widget.currentOrder.attributes.name"/></div>
|
||||
Date.CultureInfo.formatPatterns.longTime)"/> <t t-esc="order.get('name')"/></div>
|
||||
<br />
|
||||
<t t-esc="widget.company.name"/><br />
|
||||
Phone: <t t-esc="widget.company.phone || ''"/><br />
|
||||
|
@ -603,7 +606,7 @@
|
|||
<col width='25%' />
|
||||
<col width='25%' />
|
||||
</colgroup>
|
||||
<tr t-foreach="widget.currentOrderLines.toArray()" t-as="orderline">
|
||||
<tr t-foreach="orderlines" t-as="orderline">
|
||||
<td>
|
||||
<t t-esc="orderline.get_product().name"/>
|
||||
<t t-if="orderline.get_discount() > 0">
|
||||
|
@ -623,33 +626,33 @@
|
|||
<br />
|
||||
<table>
|
||||
<tr><td>Subtotal:</td><td class="pos-right-align">
|
||||
<t t-esc="widget.format_currency(widget.currentOrder.getSubtotal())"/>
|
||||
<t t-esc="widget.format_currency(order.getSubtotal())"/>
|
||||
</td></tr>
|
||||
<tr><td>Tax:</td><td class="pos-right-align">
|
||||
<t t-esc="widget.format_currency(widget.currentOrder.getTax())"/>
|
||||
<t t-esc="widget.format_currency(order.getTax())"/>
|
||||
</td></tr>
|
||||
<tr><td>Discount:</td><td class="pos-right-align">
|
||||
<t t-esc="widget.format_currency(widget.currentOrder.getDiscountTotal())"/>
|
||||
<t t-esc="widget.format_currency(order.getDiscountTotal())"/>
|
||||
</td></tr>
|
||||
<tr class="emph"><td>Total:</td><td class="pos-right-align">
|
||||
<t t-esc="widget.format_currency(widget.currentOrder.getTotalTaxIncluded())"/>
|
||||
<t t-esc="widget.format_currency(order.getTotalTaxIncluded())"/>
|
||||
</td></tr>
|
||||
</table>
|
||||
<br />
|
||||
<table>
|
||||
<tr t-foreach="widget.currentPaymentLines.toArray()" t-as="pline">
|
||||
<tr t-foreach="paymentlines" t-as="line">
|
||||
<td>
|
||||
<t t-esc="pline.get_cashregister().get('journal_id')[1]"/>
|
||||
<t t-esc="line.name"/>
|
||||
</td>
|
||||
<td class="pos-right-align">
|
||||
<t t-esc="widget.format_currency(pline.get_amount())"/>
|
||||
<t t-esc="widget.format_currency(line.get_amount())"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br />
|
||||
<table>
|
||||
<tr><td>Change:</td><td class="pos-right-align">
|
||||
<t t-esc="widget.format_currency(widget.currentOrder.getPaidTotal() - widget.currentOrder.getTotalTaxIncluded())"/>
|
||||
<t t-esc="widget.format_currency(order.getPaidTotal() - order.getTotalTaxIncluded())"/>
|
||||
</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue