X-Git-Url: http://git.inspyration.org/?a=blobdiff_plain;f=addons%2Fpoint_of_sale%2Fstatic%2Fsrc%2Fjs%2Fscreens.js;h=010e5073a59da4fbd2a87cab5854ccfa5c11c9fe;hb=1d3f8eba879f02da7fc0bb46c9801029eccbc8c8;hp=ed7110ceb14e887e6b1aec7dac60c843af64e40e;hpb=591e329bb0efe4997677a0bee2e6f3b558e35df8;p=odoo%2Fodoo.git diff --git a/addons/point_of_sale/static/src/js/screens.js b/addons/point_of_sale/static/src/js/screens.js index ed7110c..010e507 100644 --- a/addons/point_of_sale/static/src/js/screens.js +++ b/addons/point_of_sale/static/src/js/screens.js @@ -211,26 +211,6 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa barcode_error_action: function(code){ this.pos_widget.screen_selector.show_popup('error-barcode',code.code); }, - // shows an action bar on the screen. The actionbar is automatically shown when you add a button - // with add_action_button() - show_action_bar: function(){ - this.pos_widget.action_bar.show(); - }, - - // hides the action bar. The actionbar is automatically hidden when it is empty - hide_action_bar: function(){ - this.pos_widget.action_bar.hide(); - }, - - // adds a new button to the action bar. The button definition takes three parameters, all optional : - // - label: the text below the button - // - icon: a small icon that will be shown - // - click: a callback that will be executed when the button is clicked. - // the method returns a reference to the button widget, and automatically show the actionbar. - add_action_button: function(button_def){ - this.show_action_bar(); - return this.pos_widget.action_bar.add_new_button(button_def); - }, // 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. @@ -242,12 +222,6 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa this.$el.removeClass('oe_hidden'); } - if(this.pos_widget.action_bar.get_button_count() > 0){ - this.show_action_bar(); - }else{ - this.hide_action_bar(); - } - var self = this; this.pos_widget.set_numpad_visible(this.show_numpad); @@ -270,7 +244,6 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa if(this.pos.barcode_reader){ this.pos.barcode_reader.reset_action_callbacks(); } - this.pos_widget.action_bar.destroy_buttons(); }, // this methods hides the screen. It's not a good place to put your cleanup stuff as it is called on the @@ -314,6 +287,26 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa }, }); + module.FullscreenPopup = module.PopUpWidget.extend({ + template:'FullscreenPopupWidget', + show: function(){ + var self = this; + this._super(); + this.renderElement(); + this.$('.button.fullscreen').off('click').click(function(){ + window.document.body.webkitRequestFullscreen(); + self.pos_widget.screen_selector.close_popup(); + }); + this.$('.button.cancel').off('click').click(function(){ + self.pos_widget.screen_selector.close_popup(); + }); + }, + ismobile: function(){ + return typeof window.orientation !== 'undefined'; + } + }); + + module.ErrorPopupWidget = module.PopUpWidget.extend({ template:'ErrorPopupWidget', show: function(options){ @@ -382,10 +375,6 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa }, }); - module.ErrorNoClientPopupWidget = module.ErrorPopupWidget.extend({ - template: 'ErrorNoClientPopupWidget', - }); - module.ErrorInvoiceTransferPopupWidget = module.ErrorPopupWidget.extend({ template: 'ErrorInvoiceTransferPopupWidget', }); @@ -549,6 +538,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa init: function(parent, options){ this._super(parent, options); + this.partner_cache = new module.DomCache(); }, show_leftpane: false, @@ -645,17 +635,19 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa contents.innerHTML = ""; for(var i = 0, len = Math.min(partners.length,1000); i < len; i++){ var partner = partners[i]; - var clientline_html = QWeb.render('ClientLine',{widget: this, partner:partners[i]}); - var clientline = document.createElement('tbody'); - clientline.innerHTML = clientline_html; - clientline = clientline.childNodes[1]; - + var clientline = this.partner_cache.get_node(partner.id); + if(!clientline){ + var clientline_html = QWeb.render('ClientLine',{widget: this, partner:partners[i]}); + var clientline = document.createElement('tbody'); + clientline.innerHTML = clientline_html; + clientline = clientline.childNodes[1]; + this.partner_cache.cache_node(partner.id,clientline); + } if( partners === this.new_client ){ clientline.classList.add('highlight'); }else{ clientline.classList.remove('highlight'); } - contents.appendChild(clientline); } }, @@ -924,7 +916,6 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa module.ReceiptScreenWidget = module.ScreenWidget.extend({ template: 'ReceiptScreenWidget', - show_numpad: false, show_leftpane: false, @@ -932,25 +923,12 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa this._super(); var self = this; - var print_button = this.add_action_button({ - label: _t('Print'), - icon: '/point_of_sale/static/src/img/icons/png48/printer.png', - click: function(){ self.print(); }, - }); - - var finish_button = this.add_action_button({ - label: _t('Next Order'), - icon: '/point_of_sale/static/src/img/icons/png48/go-next.png', - click: function() { self.finishOrder(); }, - }); - this.refresh(); if (!this.pos.get('selectedOrder')._printed) { this.print(); } - // // The problem is that in chrome the print() is asynchronous and doesn't // execute until all rpc are finished. So it conflicts with the rpc used // to send the orders to the backend, and the user is able to go to the next @@ -967,295 +945,303 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa // 2 seconds is the same as the default timeout for sending orders and so the dialog // should have appeared before the timeout... so yeah that's not ultra reliable. - finish_button.set_disabled(true); + this.lock_screen(true); setTimeout(function(){ - finish_button.set_disabled(false); + self.lock_screen(false); }, 2000); }, + lock_screen: function(locked) { + this._locked = locked; + if (locked) { + this.$('.next').removeClass('highlight'); + } else { + this.$('.next').addClass('highlight'); + } + }, print: function() { this.pos.get('selectedOrder')._printed = true; window.print(); }, - finishOrder: function() { - this.pos.get('selectedOrder').destroy(); + finish_order: function() { + if (!this._locked) { + this.pos.get_order().finalize(); + } + }, + renderElement: function() { + var self = this; + this._super(); + this.$('.next').click(function(){ + self.finish_order(); + }); + this.$('.button.print').click(function(){ + self.print(); + }); }, refresh: function() { - var order = this.pos.get('selectedOrder'); - $('.pos-receipt-container', this.$el).html(QWeb.render('PosTicket',{ + var order = this.pos.get_order(); + this.$('.pos-receipt-container').html(QWeb.render('PosTicket',{ widget:this, order: order, orderlines: order.get('orderLines').models, paymentlines: order.get('paymentLines').models, })); }, - close: function(){ - this._super(); - } }); - module.PaymentScreenWidget = module.ScreenWidget.extend({ - template: 'PaymentScreenWidget', - back_screen: 'products', - next_screen: 'receipt', + template: 'PaymentScreenWidget', + back_screen: 'product', + next_screen: 'receipt', + show_leftpane: false, + show_numpad: false, init: function(parent, options) { var self = this; - this._super(parent,options); + this._super(parent, options); this.pos.bind('change:selectedOrder',function(){ - this.bind_events(); this.renderElement(); + this.watch_order_changes(); },this); + this.watch_order_changes(); - 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) + this.inputbuffer = ""; + this.firstinput = true; + this.keyboard_handler = function(event){ + var key = ''; + if ( event.keyCode === 13 ) { // Enter + self.validate_order(); + } else if ( event.keyCode === 190 ) { // Dot + key = '.'; + } else if ( event.keyCode === 46 ) { // Delete + key = 'CLEAR'; + } else if ( event.keyCode === 8 ) { // Backspace + key = 'BACKSPACE'; + event.preventDefault(); // Prevents history back nav + } else if ( event.keyCode >= 48 && event.keyCode <= 57 ){ // Numbers + key = '' + (event.keyCode - 48); + } else if ( event.keyCode >= 96 && event.keyCode <= 105 ){ // Numpad Numbers + key = '' + (event.keyCode - 96); + } else if ( event.keyCode === 189 || event.keyCode === 109 ) { // Minus + key = '-'; + } else if ( event.keyCode === 107 ) { // Plus + key = '+'; } - 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); - } - }; + self.payment_input(key); - this.line_click_handler = function(event){ - var node = this; - while(node && !node.classList.contains('paymentline')){ - node = node.parentNode; - } - if(node){ - self.pos.get('selectedOrder').selectPaymentline(node.line); - } }; - - this.hotkey_handler = function(event){ - if(event.which === 13){ - self.validate_order(); - }else if(event.which === 27){ - self.back(); - } - }; - }, - show: function(){ - this._super(); - var self = this; - - this.enable_numpad(); - this.focus_selected_line(); - - document.body.addEventListener('keyup', this.hotkey_handler); - - this.add_action_button({ - label: _t('Back'), - icon: '/point_of_sale/static/src/img/icons/png48/go-previous.png', - click: function(){ - self.back(); - }, - }); - - this.add_action_button({ - label: _t('Validate'), - name: 'validation', - icon: '/point_of_sale/static/src/img/icons/png48/validate.png', - click: function(){ - self.validate_order(); - }, - }); - - if( this.pos.config.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_order({invoice: true}); - }, - }); + // resets the current input buffer + reset_input: function(){ + var line = this.pos.get_order().selected_paymentline; + this.firstinput = true; + if (line) { + this.inputbuffer = this.format_currency_no_symbol(line.get_amount()); + } else { + this.inputbuffer = ""; } - - if( this.pos.config.iface_cashdrawer ){ - this.add_action_button({ - label: _t('Cash'), - name: 'cashbox', - icon: '/point_of_sale/static/src/img/open-cashbox.png', - click: function(){ - self.pos.proxy.open_cashbox(); - }, - }); + }, + // handle both keyboard and numpad input. Accepts + // a string that represents the key pressed. + payment_input: function(input) { + var oldbuf = this.inputbuffer.slice(0); + + if (input === '.') { + if (this.firstinput) { + this.inputbuffer = "0."; + }else if (!this.inputbuffer.length || this.inputbuffer === '-') { + this.inputbuffer += "0."; + } else if (this.inputbuffer.indexOf('.') < 0){ + this.inputbuffer = this.inputbuffer + '.'; + } + } else if (input === 'CLEAR') { + this.inputbuffer = ""; + } else if (input === 'BACKSPACE') { + this.inputbuffer = this.inputbuffer.substring(0,this.inputbuffer.length - 1); + } else if (input === '+') { + if ( this.inputbuffer[0] === '-' ) { + this.inputbuffer = this.inputbuffer.substring(1,this.inputbuffer.length); + } + } else if (input === '-') { + if ( this.inputbuffer[0] === '-' ) { + this.inputbuffer = this.inputbuffer.substring(1,this.inputbuffer.length); + } else { + this.inputbuffer = '-' + this.inputbuffer; + } + } else if (input[0] === '+' && !isNaN(parseFloat(input))) { + this.inputbuffer = '' + ((parseFloat(this.inputbuffer) || 0) + parseFloat(input)); + } else if (!isNaN(parseInt(input))) { + if (this.firstinput) { + this.inputbuffer = '' + input; + } else { + this.inputbuffer += input; + } } - this.update_payment_summary(); + this.firstinput = false; - }, - close: function(){ - this._super(); - this.disable_numpad(); - document.body.removeEventListener('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); + if (this.inputbuffer !== oldbuf) { + var order = this.pos.get_order(); + if (order.selected_paymentline) { + order.selected_paymentline.set_amount(parseFloat(this.inputbuffer)); + this.order_changes(); + this.render_paymentlines(); + this.$('.paymentline.selected .edit').text(this.inputbuffer); } } }, - back: function() { - this.remove_empty_lines(); - this.pos_widget.screen_selector.set_current_screen(this.back_screen); + click_numpad: function(button) { + this.payment_input(button.data('action')); }, - 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(this.pos.currency.decimals); - } - 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); + render_numpad: function() { + var self = this; + var numpad = $(QWeb.render('PaymentScreen-Numpad', { widget:this })); + numpad.on('click','button',function(){ + self.click_numpad($(this)); + }); + return numpad; + }, + click_delete_paymentline: function(cid){ + var lines = this.pos.get_order().get('paymentLines').models; + for ( var i = 0; i < lines.length; i++ ) { + if (lines[i].cid === cid) { + this.pos.get_order().removePaymentline(lines[i]); + this.reset_input(); + this.render_paymentlines(); + return; + } } - 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){ - var input = line.node.querySelector('input'); - if(!input){ + click_paymentline: function(cid){ + var lines = this.pos.get_order().get('paymentLines').models; + for ( var i = 0; i < lines.length; i++ ) { + if (lines[i].cid === cid) { + this.pos.get_order().selectPaymentline(lines[i]); + this.reset_input(); + this.render_paymentlines(); return; } - var value = input.value; - input.focus(); + } + }, + render_paymentlines: function() { + var self = this; + var order = this.pos.get_order(); + var lines = order.get('paymentLines').models; - if(this.numpad_state){ - this.numpad_state.reset(); - } + this.$('.paymentlines-container').empty(); + var lines = $(QWeb.render('PaymentScreen-Paymentlines', { + widget: this, + order: order, + paymentlines: lines, + })); - if(Number(value) === 0){ - input.value = ''; - }else{ - input.value = value; - input.select(); + lines.on('click','.delete-button',function(){ + self.click_delete_paymentline($(this).data('cid')); + }); + + lines.on('click','.paymentline',function(){ + self.click_paymentline($(this).data('cid')); + }); + + lines.appendTo(this.$('.paymentlines-container')); + }, + click_paymentmethods: function(id) { + var cashregister = null; + for ( var i = 0; i < this.pos.cashregisters.length; i++ ) { + if ( this.pos.cashregisters[i].journal_id[0] === id ){ + cashregister = this.pos.cashregisters[i]; + break; } } + this.pos.get_order().addPaymentline( cashregister ); + this.reset_input(); + this.render_paymentlines(); }, - 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_paymentmethods: function() { + var self = this; + var methods = $(QWeb.render('PaymentScreen-Paymentmethods', { widget:this })); + methods.on('click','.paymentmethod',function(){ + self.click_paymentmethods($(this).data('id')); + }); + return methods; + }, + click_invoice: function(){ + var order = this.pos.get_order(); + order.set_to_invoice(!order.is_to_invoice()); + if (order.is_to_invoice()) { + this.$('.js_invoice').addClass('highlight'); + } else { + this.$('.js_invoice').removeClass('highlight'); } }, - render_paymentline: function(line){ - var el_html = openerp.qweb.render('Paymentline',{widget: this, line: line}); - el_html = _.str.trim(el_html); + renderElement: function() { + var self = this; + this._super(); - 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); + var numpad = this.render_numpad(); + numpad.appendTo(this.$('.payment-numpad')); - line.node = el_node; + var methods = this.render_paymentmethods(); + methods.appendTo(this.$('.paymentmethods-container')); + + this.render_paymentlines(); + + this.$('.back').click(function(){ + self.pos_widget.screen_selector.back(); + }); + + this.$('.next').click(function(){ + self.validate_order(); + }); + + this.$('.js_invoice').click(function(){ + self.click_invoice(); + }); - 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); }, - remove_paymentline: function(line){ - line.node.parentNode.removeChild(line.node); - line.node = undefined; + show: function(){ + this.pos.get_order().clean_empty_paymentlines(); + this.reset_input(); + this.render_paymentlines(); + this.order_changes(); + window.document.body.addEventListener('keydown',this.keyboard_handler); + this._super(); }, - renderElement: function(){ + hide: function(){ + window.document.body.removeEventListener('keydown',this.keyboard_handler); 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()); + }, + // sets up listeners to watch for order changes + watch_order_changes: function() { + var self = this; + var order = this.pos.get_order(); + if(this.old_order){ + this.old_order.unbind(null,null,this); } + order.bind('all',function(){ + self.order_changes(); + }); + this.old_order = order; }, - is_paid: function(){ - var currentOrder = this.pos.get('selectedOrder'); - return (currentOrder.getTotalTaxIncluded() < 0.000001 - || currentOrder.getPaidTotal() + 0.000001 >= currentOrder.getTotalTaxIncluded()); - + // called when the order is changed, used to show if + // the order is paid or not + order_changes: function(){ + var self = this; + var order = this.pos.get_order(); + if (order.isPaid()) { + self.$('.next').addClass('highlight'); + }else{ + self.$('.next').removeClass('highlight'); + } }, - validate_order: function(options) { + // Check if the order is paid, then sends it to the backend, + // and complete the sale process + validate_order: function() { var self = this; - options = options || {}; - var currentOrder = this.pos.get('selectedOrder'); + var order = this.pos.get_order(); - if(currentOrder.get('orderLines').models.length === 0){ + if(order.get('orderLines').models.length === 0){ this.pos_widget.screen_selector.show_popup('error',{ 'message': _t('Empty Order'), 'comment': _t('There must be at least one product in your order before it can be validated'), @@ -1263,12 +1249,12 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa return; } - if(!this.is_paid()){ + if (!order.isPaid() || this.invoicing) { return; } // The exact amount must be paid if there is no cash payment method defined. - if (Math.abs(currentOrder.getTotalTaxIncluded() - currentOrder.getPaidTotal()) > 0.00001) { + if (Math.abs(order.getTotalTaxIncluded() - order.getPaidTotal()) > 0.00001) { var cash = false; for (var i = 0; i < this.pos.cashregisters.length; i++) { cash = cash || (this.pos.cashregisters[i].journal.type === 'cash'); @@ -1282,84 +1268,50 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa } } - if (this.pos.config.iface_cashdrawer) { + if (order.isPaidWithCash() && this.pos.config.iface_cashdrawer) { + this.pos.proxy.open_cashbox(); } - if(options.invoice){ - // deactivate the validation button while we try to send the order - this.pos_widget.action_bar.set_button_disabled('validation',true); - this.pos_widget.action_bar.set_button_disabled('invoice',true); - - var invoiced = this.pos.push_and_invoice_order(currentOrder); + if (order.is_to_invoice()) { + var invoiced = this.pos.push_and_invoice_order(order); + this.invoicing = true; invoiced.fail(function(error){ - if(error === 'error-no-client'){ - self.pos_widget.screen_selector.show_popup('error',{ - message: _t('An anonymous order cannot be invoiced'), - comment: _t('Please select a client for this order. This can be done by clicking the order tab'), + self.invoicing = false; + if (error === 'error-no-client') { + self.pos_widget.screen_selector.show_popup('confirm',{ + message: _t('Please select the Customer'), + comment: _t('You need to select the customer before you can invoice an order.'), + confirm: function(){ + self.pos_widget.screen_selector.set_current_screen('clientlist'); + }, }); - }else{ + } else { self.pos_widget.screen_selector.show_popup('error',{ message: _t('The order could not be sent'), comment: _t('Check your internet connection and try again.'), }); } - self.pos_widget.action_bar.set_button_disabled('validation',false); - self.pos_widget.action_bar.set_button_disabled('invoice',false); }); invoiced.done(function(){ - self.pos_widget.action_bar.set_button_disabled('validation',false); - self.pos_widget.action_bar.set_button_disabled('invoice',false); - self.pos.get('selectedOrder').destroy(); + self.invoicing = false; + order.finalize(); }); - - }else{ - this.pos.push_order(currentOrder) - if(this.pos.config.iface_print_via_proxy){ + } else { + this.pos.push_order(order) + if (this.pos.config.iface_print_via_proxy) { var receipt = currentOrder.export_for_printing(); this.pos.proxy.print_receipt(QWeb.render('XmlReceipt',{ receipt: receipt, widget: self, })); - this.pos.get('selectedOrder').destroy(); //finish order and go back to scan screen - }else{ + order.finalize(); //finish order and go back to scan screen + } else { this.pos_widget.screen_selector.set_current_screen(this.next_screen); } } - - // hide onscreen (iOS) keyboard - setTimeout(function(){ - document.activeElement.blur(); - $("input").blur(); - },250); - }, - enable_numpad: function(){ - this.disable_numpad(); //ensure we don't register the callbacks twice - this.numpad_state = this.pos_widget.numpad.state; - if(this.numpad_state){ - this.numpad_state.reset(); - this.numpad_state.changeMode('payment'); - this.numpad_state.bind('set_value', this.set_value, this); - this.numpad_state.bind('change:mode', this.set_mode_back_to_payment, this); - } - - }, - disable_numpad: function(){ - if(this.numpad_state){ - this.numpad_state.unbind('set_value', this.set_value); - this.numpad_state.unbind('change:mode',this.set_mode_back_to_payment); - } - }, - set_mode_back_to_payment: function() { - this.numpad_state.set({mode: 'payment'}); - }, - set_value: function(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); - } }, }); + }