From 68ac031a962028003a2f8ce9c2ac5de4a24cc54f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Fri, 23 Jan 2015 17:14:47 +0100 Subject: [PATCH 1/8] [FIX] point_of_sale: fix crash from badly refactored code. --- addons/point_of_sale/static/src/js/chrome.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/point_of_sale/static/src/js/chrome.js b/addons/point_of_sale/static/src/js/chrome.js index 2e9d6f17885..69aa3c7f902 100644 --- a/addons/point_of_sale/static/src/js/chrome.js +++ b/addons/point_of_sale/static/src/js/chrome.js @@ -481,7 +481,7 @@ openerp.point_of_sale.load_chrome = function load_chrome(instance, module){ //mo } var popup = $(QWeb.render('ErrorTracebackPopupWidget',{ - widget: { title: title , body: body }, + widget: { options: {title: title , body: body }}, })); popup.find('.button').click(function(){ From cfb1a7e804209efe13ba8d6e202be2b9a36fcb78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Fri, 23 Jan 2015 17:15:57 +0100 Subject: [PATCH 2/8] [IMP] point_of_sale: the 'image' field is big and not used anymore ... --- addons/point_of_sale/static/src/js/models.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index 7441e25682b..8a95bc8fe8d 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -284,7 +284,7 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo }, },{ model: 'pos.category', - fields: ['id','name','parent_id','child_id','image'], + fields: ['id','name','parent_id','child_id'], domain: null, loaded: function(self, categories){ self.db.add_categories(categories); From 3aaf219c54923471459f9ec9214ac220329a2f17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Fri, 23 Jan 2015 17:16:52 +0100 Subject: [PATCH 3/8] [IMP] point_of_sale: add the possibility to highlight control buttons --- addons/point_of_sale/static/src/js/screens.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/addons/point_of_sale/static/src/js/screens.js b/addons/point_of_sale/static/src/js/screens.js index 9c9149b4fe3..e0a1f51711a 100644 --- a/addons/point_of_sale/static/src/js/screens.js +++ b/addons/point_of_sale/static/src/js/screens.js @@ -833,6 +833,9 @@ openerp.point_of_sale.load_screens = function load_screens(instance, module){ // }); }, button_click: function(){}, + highlight: function(highlight){ + this.$el.toggleClass('highlight',!!highlight); + }, }); /* -------- The Product Screen -------- */ From f517b8a54dc07a7a9eeabc5a6759b64119ffe589 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Fri, 23 Jan 2015 18:09:57 +0100 Subject: [PATCH 4/8] [FIX] point_of_sale: the open cashbox button was not working --- addons/point_of_sale/static/src/js/screens.js | 4 ++++ addons/point_of_sale/static/src/xml/pos.xml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/addons/point_of_sale/static/src/js/screens.js b/addons/point_of_sale/static/src/js/screens.js index e0a1f51711a..5885d942fd5 100644 --- a/addons/point_of_sale/static/src/js/screens.js +++ b/addons/point_of_sale/static/src/js/screens.js @@ -1575,6 +1575,10 @@ openerp.point_of_sale.load_screens = function load_screens(instance, module){ // self.click_invoice(); }); + this.$('.js_cashdrawer').click(function(){ + self.pos.proxy.open_cashbox(); + }); + }, show: function(){ this.pos.get_order().clean_empty_paymentlines(); diff --git a/addons/point_of_sale/static/src/xml/pos.xml b/addons/point_of_sale/static/src/xml/pos.xml index 5547a4c70f7..955cde86837 100644 --- a/addons/point_of_sale/static/src/xml/pos.xml +++ b/addons/point_of_sale/static/src/xml/pos.xml @@ -596,7 +596,7 @@ -
+
Open Cashbox
From dbc8912bc3da78d600d9a0b72cbc6f2c666e185a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Fri, 23 Jan 2015 18:45:58 +0100 Subject: [PATCH 5/8] [FIX] point_of_sale: this/self mismatch after refactor. --- addons/point_of_sale/static/src/js/popups.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/addons/point_of_sale/static/src/js/popups.js b/addons/point_of_sale/static/src/js/popups.js index e52d9be9669..f1d282f6c50 100644 --- a/addons/point_of_sale/static/src/js/popups.js +++ b/addons/point_of_sale/static/src/js/popups.js @@ -138,7 +138,7 @@ openerp.point_of_sale.load_popups = function load_popups(instance, module) { show: function(options){ options = options || {}; var self = this; - this._super(); + this._super(options); this.list = options.list || []; this.renderElement(); @@ -167,7 +167,7 @@ openerp.point_of_sale.load_popups = function load_popups(instance, module) { show: function(options){ options = options || {}; var self = this; - this._super(); + this._super(options); this.renderElement(); this.$('input,textarea').focus(); @@ -176,10 +176,10 @@ openerp.point_of_sale.load_popups = function load_popups(instance, module) { }); }, click_confirm: function(){ - var value = self.$('input,textarea').val(); - self.gui.close_popup(); + var value = this.$('input,textarea').val(); + this.gui.close_popup(); if( this.options.confirm ){ - this.options.confirm.call(self,value); + this.options.confirm.call(this,value); } }, }); @@ -197,7 +197,7 @@ openerp.point_of_sale.load_popups = function load_popups(instance, module) { show: function(options){ options = options || {}; var self = this; - this._super(); + this._super(options); this.inputbuffer = options.value || ''; this.renderElement(); From fcd3f4e9a54344e9e2b50a4b8152d8f1a576527c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Fri, 23 Jan 2015 18:47:32 +0100 Subject: [PATCH 6/8] [FIX] point_of_sale: correctly set popup title. --- addons/pos_restaurant/static/src/js/notes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/pos_restaurant/static/src/js/notes.js b/addons/pos_restaurant/static/src/js/notes.js index 2d60b66d62b..116f9c3709a 100644 --- a/addons/pos_restaurant/static/src/js/notes.js +++ b/addons/pos_restaurant/static/src/js/notes.js @@ -47,7 +47,7 @@ openerp.pos_restaurant.load_notes = function(instance,module){ var line = this.pos.get_order().get_selected_orderline(); if (line) { this.gui.show_popup('textarea',{ - message: _t('Orderline Note'), + title: _t('Add Note'), value: line.get_note(), confirm: function(note) { line.set_note(note); From 0db25ad1aa7a0c4ab40d8e094c498efcd112ca98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Mon, 26 Jan 2015 11:40:08 +0100 Subject: [PATCH 7/8] [FIX] pos_restaurant: splitbill would crash on reloaded orders due to not reloading orderline ids --- addons/point_of_sale/static/src/js/models.js | 3 +++ addons/pos_restaurant/static/src/js/splitbill.js | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index 8a95bc8fe8d..7cb613da86e 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -874,6 +874,8 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo this.price = json.price_unit; this.set_discount(json.discount); this.set_quantity(json.qty); + this.id = json.id; + orderline_id = Math.max(this.id+1,orderline_id) }, clone: function(){ var orderline = new module.Orderline({},{ @@ -997,6 +999,7 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo price_unit: this.get_unit_price(), discount: this.get_discount(), product_id: this.get_product().id, + id: this.id, }; }, //used to create a json of the ticket, to be sent to the printer diff --git a/addons/pos_restaurant/static/src/js/splitbill.js b/addons/pos_restaurant/static/src/js/splitbill.js index 70714418430..cc640599512 100644 --- a/addons/pos_restaurant/static/src/js/splitbill.js +++ b/addons/pos_restaurant/static/src/js/splitbill.js @@ -167,7 +167,7 @@ openerp.pos_restaurant.load_splitbill = function(instance, module){ template: 'SplitbillButton', button_click: function(){ if(this.pos.get_order().get_orderlines().length > 0){ - self.gui.show_screen('splitbill'); + this.gui.show_screen('splitbill'); } }, }); From 5a3d9ce9ce6d806c8433d27541673033ab13d905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Mon, 26 Jan 2015 18:21:09 +0100 Subject: [PATCH 8/8] [FIX] point_of_sale: prevent sneaky inputs: User drops something on the keyboard > Inputs very large number unnoticed > Bad things happen. - Limit input lengths to 12 - Ring bell when exceeding that length - Warn if the amount makes dubious business sense - Block screen inputs when popup is active. - Asserts to prevent edition of the order after validation. Just in case. --- addons/point_of_sale/static/src/js/gui.js | 26 +++++++++++++++++ addons/point_of_sale/static/src/js/models.js | 22 ++++++++++++-- addons/point_of_sale/static/src/js/popups.js | 7 +---- addons/point_of_sale/static/src/js/screens.js | 27 +++++++++++++++++- .../point_of_sale/static/src/sounds/bell.wav | Bin 0 -> 17684 bytes 5 files changed, 73 insertions(+), 9 deletions(-) create mode 100644 addons/point_of_sale/static/src/sounds/bell.wav diff --git a/addons/point_of_sale/static/src/js/gui.js b/addons/point_of_sale/static/src/js/gui.js index 4627abab60b..20e754b07e5 100644 --- a/addons/point_of_sale/static/src/js/gui.js +++ b/addons/point_of_sale/static/src/js/gui.js @@ -169,6 +169,11 @@ openerp.point_of_sale.load_gui = function load_gui(instance, module) { } }, + // is there an active popup ? + has_popup: function() { + return !!this.current_popup; + }, + /* ---- Gui: ACCESS CONTROL ---- */ // A Generic UI that allow to select a user from a list. @@ -280,6 +285,21 @@ openerp.point_of_sale.load_gui = function load_gui(instance, module) { }); }, + /* ---- Gui: SOUND ---- */ + + play_sound: function(sound) { + var src = ''; + if (sound === 'error') { + src = "/point_of_sale/static/src/sounds/error.wav"; + } else if (sound === 'bell') { + src = "/point_of_sale/static/src/sounds/bell.wav"; + } else { + console.error('Unknown sound: ',sound); + return; + } + $('body').append(''); + }, + /* ---- Gui: KEYBOARD INPUT ---- */ // This is a helper to handle numpad keyboard input. @@ -325,6 +345,12 @@ openerp.point_of_sale.load_gui = function load_gui(instance, module) { } } + // End of input buffer at 12 characters. + if (newbuf.length > buffer.length && newbuf.length > 12) { + this.play_sound('bell'); + return buffer.slice(0); + } + return newbuf; }, }); diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index 7cb613da86e..71d593961de 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -912,6 +912,7 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo // product's unity of measure properties. Quantities greater than zero will not get // rounded to zero set_quantity: function(quantity){ + this.order.assert_editable(); if(quantity === 'remove'){ this.order.remove_orderline(this); return; @@ -991,6 +992,7 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo } }, merge: function(orderline){ + this.order.assert_editable(); this.set_quantity(this.get_quantity() + orderline.get_quantity()); }, export_as_JSON: function() { @@ -1020,6 +1022,7 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo }, // changes the base price of the product for this orderline set_unit_price: function(price){ + this.order.assert_editable(); this.price = round_di(parseFloat(price) || 0, this.pos.dp['Product Price']); this.trigger('change',this); }, @@ -1148,6 +1151,7 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo module.Paymentline = Backbone.Model.extend({ initialize: function(attributes, options) { this.pos = options.pos; + this.order = options.order; this.amount = 0; this.selected = false; if (options.json) { @@ -1164,6 +1168,7 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo }, //sets the amount of money on this payment line set_amount: function(value){ + this.order.assert_editable(); this.amount = round_di(parseFloat(value) || 0, this.pos.currency.decimals); this.trigger('change',this); }, @@ -1228,6 +1233,7 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo this.orderlines = new module.OrderlineCollection(); this.paymentlines = new module.PaymentlineCollection(); this.pos_session_id = this.pos.pos_session.id; + this.finalized = false; // if true, cannot be modified. this.set({ client: null }); @@ -1285,7 +1291,7 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo var paymentlines = json.statement_ids; for (var i = 0; i < paymentlines.length; i++) { var paymentline = paymentlines[i][2]; - var newpaymentline = new module.Paymentline({},{pos: this.pos, json: paymentline}); + var newpaymentline = new module.Paymentline({},{pos: this.pos, order: this, json: paymentline}); this.paymentlines.add(newpaymentline); if (i === paymentlines.length - 1) { @@ -1434,8 +1440,14 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo get_name: function() { return this.name; }, + assert_editable: function() { + if (this.finalized) { + throw new Error('Finalized Order cannot be modified'); + } + }, /* ---- Order Lines --- */ add_orderline: function(line){ + this.assert_editable(); if(line.order){ line.order.remove_orderline(line); } @@ -1459,10 +1471,12 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo return this.orderlines.at(this.orderlines.length -1); }, remove_orderline: function( line ){ + this.assert_editable(); this.orderlines.remove(line); this.select_orderline(this.get_last_orderline()); }, add_product: function(product, options){ + this.assert_editable(); options = options || {}; var attr = JSON.parse(JSON.stringify(product)); attr.pos = this.pos; @@ -1517,7 +1531,8 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo }, /* ---- Payment Lines --- */ add_paymentline: function(cashregister) { - var newPaymentline = new module.Paymentline({},{cashregister:cashregister, pos: this.pos}); + this.assert_editable(); + var newPaymentline = new module.Paymentline({},{order: this, cashregister:cashregister, pos: this.pos}); if(cashregister.journal.type !== 'cash' || this.pos.config.iface_precompute_cash){ newPaymentline.set_amount( Math.max(this.get_due(),0) ); } @@ -1529,6 +1544,7 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo return this.paymentlines.models; }, remove_paymentline: function(line){ + this.assert_editable(); if(this.selected_paymentline === line){ this.select_paymentline(undefined); } @@ -1704,6 +1720,7 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo }, /* ---- Invoice --- */ set_to_invoice: function(to_invoice) { + this.assert_editable(); this.to_invoice = to_invoice; }, is_to_invoice: function(){ @@ -1712,6 +1729,7 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo /* ---- Client / Customer --- */ // the client related to the current order. set_client: function(client){ + this.assert_editable(); this.set('client',client); }, get_client: function(){ diff --git a/addons/point_of_sale/static/src/js/popups.js b/addons/point_of_sale/static/src/js/popups.js index f1d282f6c50..e0db66f5392 100644 --- a/addons/point_of_sale/static/src/js/popups.js +++ b/addons/point_of_sale/static/src/js/popups.js @@ -87,9 +87,7 @@ openerp.point_of_sale.load_popups = function load_popups(instance, module) { template:'ErrorPopupWidget', show: function(options){ this._super(options); - - $('body').append(''); - + this.gui.play_sound('error'); }, }); module.Gui.define_popup({name:'error', widget:module.ErrorPopupWidget}); @@ -171,9 +169,6 @@ openerp.point_of_sale.load_popups = function load_popups(instance, module) { this.renderElement(); this.$('input,textarea').focus(); - - this.$('.button.confirm').click(function(){ - }); }, click_confirm: function(){ var value = this.$('input,textarea').val(); diff --git a/addons/point_of_sale/static/src/js/screens.js b/addons/point_of_sale/static/src/js/screens.js index 5885d942fd5..0232fb6aebe 100644 --- a/addons/point_of_sale/static/src/js/screens.js +++ b/addons/point_of_sale/static/src/js/screens.js @@ -1442,6 +1442,11 @@ openerp.point_of_sale.load_screens = function load_screens(instance, module){ // var newbuf = this.gui.numpad_input(this.inputbuffer, input, {'firstinput': this.firstinput}); this.firstinput = (newbuf.length === 0); + + // popup block inputs to prevent sneak editing. + if (this.gui.has_popup()) { + return; + } if (newbuf !== this.inputbuffer) { this.inputbuffer = newbuf; @@ -1633,7 +1638,7 @@ openerp.point_of_sale.load_screens = function load_screens(instance, module){ // // Check if the order is paid, then sends it to the backend, // and complete the sale process - validate_order: function() { + validate_order: function(force_validation) { var self = this; var order = this.pos.get_order(); @@ -1678,6 +1683,26 @@ openerp.point_of_sale.load_screens = function load_screens(instance, module){ // } } + // if the change is too large, it's probably an input error, make the user confirm. + if (!force_validation && (order.get_total_with_tax() * 1000 < order.get_total_paid())) { + this.gui.show_popup('confirm',{ + title: _t('Please Confirm Large Amount'), + body: _t('Are you sure that the customer wants to pay') + + ' ' + + this.format_currency(order.get_total_paid()) + + ' ' + + _t('for an order of') + + ' ' + + this.format_currency(order.get_total_with_tax()) + + ' ' + + _t('? Clicking "Confirm" will validate the payment.'), + confirm: function() { + self.validate_order('confirm'); + }, + }); + return; + } + if (order.is_paid_with_cash() && this.pos.config.iface_cashdrawer) { this.pos.proxy.open_cashbox(); diff --git a/addons/point_of_sale/static/src/sounds/bell.wav b/addons/point_of_sale/static/src/sounds/bell.wav new file mode 100644 index 0000000000000000000000000000000000000000..660779c51f2390a0392026e4b49eada05a2cb190 GIT binary patch literal 17684 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 E2hmU1OaK4? literal 0 HcmV?d00001