From 651f76e274093fb4b8a0a34fb7065896e20daa1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Thu, 12 Sep 2013 15:50:44 +0200 Subject: [PATCH 1/5] [IMP] point_of_sale: log pushed orders to the backend + disable proxy rpcs when the proxy is disconnected bzr revid: fva@openerp.com-20130912135044-93c6va8e8yttkir1 --- addons/point_of_sale/controllers/main.py | 21 +++++++------------ addons/point_of_sale/static/src/js/devices.js | 19 ++++++++++++++++- addons/point_of_sale/static/src/js/models.js | 1 + 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/addons/point_of_sale/controllers/main.py b/addons/point_of_sale/controllers/main.py index e0bd19545a6..de757238d6f 100644 --- a/addons/point_of_sale/controllers/main.py +++ b/addons/point_of_sale/controllers/main.py @@ -10,6 +10,8 @@ from openerp.addons.web import http from openerp.addons.web.http import request from openerp.addons.web.controllers.main import manifest_list, module_boot, html_template +_logger = logging.getLogger(__name__) + class PointOfSaleController(http.Controller): def __init__(self): self.scale = 'closed' @@ -71,7 +73,7 @@ class PointOfSaleController(http.Controller): @http.route('/pos/test_connection', type='json', auth='admin') def test_connection(self): - return + _logger.info('Received Connection Test from the Point of Sale'); @http.route('/pos/scan_item_success', type='json', auth='admin') def scan_item_success(self, ean): @@ -79,7 +81,6 @@ class PointOfSaleController(http.Controller): A product has been scanned with success """ print 'scan_item_success: ' + str(ean) - return @http.route('/pos/scan_item_error_unrecognized') def scan_item_error_unrecognized(self, ean): @@ -87,7 +88,6 @@ class PointOfSaleController(http.Controller): A product has been scanned without success """ print 'scan_item_error_unrecognized: ' + str(ean) - return @http.route('/pos/help_needed', type='json', auth='admin') def help_needed(self): @@ -95,7 +95,6 @@ class PointOfSaleController(http.Controller): The user wants an help (ex: light is on) """ print "help_needed" - return @http.route('/pos/help_canceled', type='json', auth='admin') def help_canceled(self): @@ -103,7 +102,6 @@ class PointOfSaleController(http.Controller): The user stops the help request """ print "help_canceled" - return @http.route('/pos/weighting_start', type='json', auth='admin') def weighting_start(self): @@ -115,7 +113,6 @@ class PointOfSaleController(http.Controller): print "... Scale Open." else: print "WARNING: Scale already Connected !!!" - return @http.route('/pos/weighting_read_kg', type='json', auth='admin') def weighting_read_kg(self): @@ -156,41 +153,37 @@ class PointOfSaleController(http.Controller): @http.route('/pos/payment_cancel', type='json', auth='admin') def payment_cancel(self): print "payment_cancel" - return @http.route('/pos/transaction_start', type='json', auth='admin') def transaction_start(self): print 'transaction_start' - return @http.route('/pos/transaction_end', type='json', auth='admin') def transaction_end(self): print 'transaction_end' - return @http.route('/pos/cashier_mode_activated', type='json', auth='admin') def cashier_mode_activated(self): print 'cashier_mode_activated' - return @http.route('/pos/cashier_mode_deactivated', type='json', auth='admin') def cashier_mode_deactivated(self): print 'cashier_mode_deactivated' - return @http.route('/pos/open_cashbox', type='json', auth='admin') def open_cashbox(self): print 'open_cashbox' - return @http.route('/pos/print_receipt', type='json', auth='admin') def print_receipt(self, receipt): print 'print_receipt' + str(receipt) - return + + @http.route('/pos/log', type='json', auth='admin') + def log(self, arguments): + _logger.info(' '.join(str(v) for v in arguments)) @http.route('/pos/print_pdf_invoice', type='json', auth='admin') def print_pdf_invoice(self, pdfinvoice): print 'print_pdf_invoice' + str(pdfinvoice) - return diff --git a/addons/point_of_sale/static/src/js/devices.js b/addons/point_of_sale/static/src/js/devices.js index 0c737ec1e1a..89f705d09bc 100644 --- a/addons/point_of_sale/static/src/js/devices.js +++ b/addons/point_of_sale/static/src/js/devices.js @@ -82,6 +82,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal module.ProxyDevice = instance.web.Class.extend({ init: function(options){ + var self = this; options = options || {}; url = options.url || 'http://localhost:8069'; @@ -101,8 +102,13 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal this.connection = new instance.web.Session(undefined,url); this.connection.session_id = _.uniqueId('posproxy'); + this.connected = true; this.bypass_proxy = false; this.notifications = {}; + this.message('test_connection').fail(function(){ + self.connected = false; + console.error('Could not connect to the OpenERP Device Proxy Server'); + }); }, close: function(){ @@ -113,7 +119,11 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal for(var i = 0; i < callbacks.length; i++){ callbacks[i](params); } - return this.connection.rpc('/pos/' + name, params || {}); + if(this.connected){ + return this.connection.rpc('/pos/' + name, params || {}); + }else{ + return (new $.Deferred()).reject(); + } }, // this allows the client to be notified when a proxy call is made. The notification @@ -124,6 +134,8 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal } this.notifications[name].push(callback); }, + + //a product has been scanned and recognized with success // ean is a parsed ean object @@ -316,6 +328,11 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal return this.message('print_receipt',{receipt: receipt}); }, + // asks the proxy to log some information, as with the debug.log you can provide several arguments. + log: function(){ + return this.message('log',{'arguments': _.toArray(arguments)}); + }, + // asks the proxy to print an invoice in pdf form ( used to print invoices generated by the server ) print_pdf_invoice: function(pdfinvoice){ return this.message('print_pdf_invoice',{pdfinvoice: pdfinvoice}); diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index fbbb15af9c7..55984d0032d 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -270,6 +270,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal // it returns a deferred that succeeds after having tried to send the order and all the other pending orders. push_order: function(order) { var self = this; + this.proxy.log('push_order',order.export_as_JSON()); var order_id = this.db.add_order(order.export_as_JSON()); var pushed = new $.Deferred(); From 65c70b85a701575a1a464e4d561f184cec018885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Tue, 17 Sep 2013 12:14:20 +0200 Subject: [PATCH 2/5] [IMP + FIX] point_of_sale: plugged the memory leaks - correctly call destroy on widgets - unbind backbone events on destroy - jquery show() hide() flooded jQuery.cache - introduced automated ui tests bzr revid: fva@openerp.com-20130917101420-g76gos2qjjaii3zf --- addons/point_of_sale/__openerp__.py | 1 + addons/point_of_sale/static/src/css/pos.css | 4 + addons/point_of_sale/static/src/js/devices.js | 21 +++-- addons/point_of_sale/static/src/js/main.js | 4 +- addons/point_of_sale/static/src/js/models.js | 1 - addons/point_of_sale/static/src/js/screens.js | 18 ++-- addons/point_of_sale/static/src/js/tests.js | 92 +++++++++++++++++++ .../static/src/js/widget_base.js | 4 +- .../static/src/js/widget_scrollbar.js | 22 ++--- addons/point_of_sale/static/src/js/widgets.js | 68 +++++++------- 10 files changed, 170 insertions(+), 65 deletions(-) create mode 100644 addons/point_of_sale/static/src/js/tests.js diff --git a/addons/point_of_sale/__openerp__.py b/addons/point_of_sale/__openerp__.py index cb05cef46c3..dfdc2c57cb9 100644 --- a/addons/point_of_sale/__openerp__.py +++ b/addons/point_of_sale/__openerp__.py @@ -98,6 +98,7 @@ Main Features 'static/src/js/widgets.js', 'static/src/js/devices.js', 'static/src/js/screens.js', + 'static/src/js/tests.js', 'static/src/js/main.js', ], 'css': [ diff --git a/addons/point_of_sale/static/src/css/pos.css b/addons/point_of_sale/static/src/css/pos.css index d78276b2b97..382dd95bce2 100644 --- a/addons/point_of_sale/static/src/css/pos.css +++ b/addons/point_of_sale/static/src/css/pos.css @@ -21,6 +21,10 @@ user-select: none; } +.point-of-sale .oe_hidden{ + display: none !important; +} + .point-of-sale ul, .point-of-sale li { margin: 0; padding: 0; diff --git a/addons/point_of_sale/static/src/js/devices.js b/addons/point_of_sale/static/src/js/devices.js index 89f705d09bc..bc697e96aca 100644 --- a/addons/point_of_sale/static/src/js/devices.js +++ b/addons/point_of_sale/static/src/js/devices.js @@ -40,6 +40,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal }); }else{ running = false; + scheduled_end_time = 0; end_of_queue.resolve(); } }; @@ -100,15 +101,13 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal }; this.custom_payment_status = this.default_payment_status; + this.notifications = {}; + this.bypass_proxy = false; + this.connection = new instance.web.Session(undefined,url); this.connection.session_id = _.uniqueId('posproxy'); - this.connected = true; - this.bypass_proxy = false; - this.notifications = {}; - this.message('test_connection').fail(function(){ - self.connected = false; - console.error('Could not connect to the OpenERP Device Proxy Server'); - }); + this.test_connection(); + window.proxy = this; }, close: function(){ @@ -125,6 +124,14 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal return (new $.Deferred()).reject(); } }, + test_connection: function(){ + var self = this; + this.connected = true; + return this.message('test_connection').fail(function(){ + self.connected = false; + console.error('Could not connect to the Proxy'); + }); + }, // this allows the client to be notified when a proxy call is made. The notification // callback will be executed with the same arguments as the proxy call diff --git a/addons/point_of_sale/static/src/js/main.js b/addons/point_of_sale/static/src/js/main.js index b9263b91314..55f0bbd1f61 100644 --- a/addons/point_of_sale/static/src/js/main.js +++ b/addons/point_of_sale/static/src/js/main.js @@ -16,10 +16,12 @@ openerp.point_of_sale = function(instance) { 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 openerp_pos_widgets(instance,module); // import pos_widgets.js - openerp_pos_devices(instance,module); // import pos_devices.js + openerp_pos_tests(instance,module); // import pos_tests.js instance.web.client_actions.add('pos.ui', 'instance.point_of_sale.PosWidget'); }; diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index 55984d0032d..11a3e6d4a68 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -263,7 +263,6 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal //removes the current order delete_current_order: function(){ this.get('selectedOrder').destroy({'reason':'abandon'}); - console.log('coucou!'); }, // saves the order locally and try to send it to the backend. diff --git a/addons/point_of_sale/static/src/js/screens.js b/addons/point_of_sale/static/src/js/screens.js index 854c1e1adec..e4cb33968b1 100644 --- a/addons/point_of_sale/static/src/js/screens.js +++ b/addons/point_of_sale/static/src/js/screens.js @@ -253,7 +253,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa this.hidden = false; if(this.$el){ - this.$el.show(); + this.$el.removeClass('oe_hidden'); } if(this.pos_widget.action_bar.get_button_count() > 0){ @@ -314,7 +314,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa hide: function(){ this.hidden = true; if(this.$el){ - this.$el.hide(); + this.$el.addClass('oe_hidden'); } }, @@ -326,7 +326,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa this._super(); if(this.hidden){ if(this.$el){ - this.$el.hide(); + this.$el.addClass('oe_hidden'); } } }, @@ -335,7 +335,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa module.PopUpWidget = module.PosBaseWidget.extend({ show: function(){ if(this.$el){ - this.$el.show(); + this.$el.removeClass('oe_hidden'); } }, /* called before hide, when a popup is closed */ @@ -345,7 +345,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa * pos instantiation, so you don't want to do anything fancy in here */ hide: function(){ if(this.$el){ - this.$el.hide(); + this.$el.addClass('oe_hidden'); } }, }); @@ -692,7 +692,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa barcode_client_action: function(ean){ this.pos.proxy.transaction_start(); this._super(ean); - $('.goodbye-message').hide(); + $('.goodbye-message').addClass('oe_hidden'); this.pos_widget.screen_selector.show_popup('choose-receipt'); }, @@ -704,14 +704,14 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa label: _t('Help'), icon: '/point_of_sale/static/src/img/icons/png48/help.png', click: function(){ - $('.goodbye-message').css({opacity:1}).hide(); + $('.goodbye-message').css({opacity:1}).addClass('oe_hidden'); self.help_button_action(); }, }); - $('.goodbye-message').css({opacity:1}).show(); + $('.goodbye-message').css({opacity:1}).removeClass('oe_hidden'); setTimeout(function(){ - $('.goodbye-message').animate({opacity:0},500,'swing',function(){$('.goodbye-message').hide();}); + $('.goodbye-message').animate({opacity:0},500,'swing',function(){$('.goodbye-message').addClass('oe_hidden');}); },5000); }, }); diff --git a/addons/point_of_sale/static/src/js/tests.js b/addons/point_of_sale/static/src/js/tests.js new file mode 100644 index 00000000000..3b1dbc14503 --- /dev/null +++ b/addons/point_of_sale/static/src/js/tests.js @@ -0,0 +1,92 @@ +function openerp_pos_tests(instance, module){ //module is instance.point_of_sale + + // Various UI Tests to measure performance and memory leaks. + module.UiTester = function(){ + var running = false; + var queue = new module.JobQueue(); + + // stop the currently running test + this.stop = function(){ + queue.clear(); + }; + + // randomly switch product categories + this.category_switch = function(interval){ + queue.schedule(function(){ + var breadcrumbs = $('.breadcrumb a'); + var categories = $('li.category-button'); + if(categories.length > 0){ + var rnd = Math.floor(Math.random()*categories.length); + categories.eq(rnd).click(); + }else{ + var rnd = Math.floor(Math.random()*breadcrumbs.length); + breadcrumbs.eq(rnd).click(); + } + },{repeat:true, duration:interval}); + }; + + // randomly order products then resets the order + this.order_products = function(interval){ + + queue.schedule(function(){ + var def = new $.Deferred(); + var order_queue = new module.JobQueue(); + var order_size = 1 + Math.floor(Math.random()*10); + + while(order_size--){ + order_queue.schedule(function(){ + var products = $('.product a'); + if(products.length > 0){ + var rnd = Math.floor(Math.random()*products.length); + products.eq(rnd).click(); + } + },{duration:250}); + } + order_queue.finished().then(function(){ + $('.deleteorder-button').click(); + def.resolve(); + }); + return def; + },{repeat:true, duration: interval}); + + }; + + // makes a complete product order cycle ( print via proxy must be activated, and scale deactivated ) + this.full_order_cycle = function(interval){ + queue.schedule(function(){ + var def = new $.Deferred(); + var order_queue = new module.JobQueue(); + var order_size = 1 + Math.floor(Math.random()*50); + + while(order_size--){ + order_queue.schedule(function(){ + var products = $('.product a'); + if(products.length > 0){ + var rnd = Math.floor(Math.random()*products.length); + products.eq(rnd).click(); + } + },{duration:250}); + } + order_queue.schedule(function(){ + $('.paypad-button:first').click(); + },{duration:250}); + order_queue.schedule(function(){ + $('.paymentline-amount input:first').val(10000); + $('.paymentline-amount input:first').keyup(); + },{duration:250}); + order_queue.schedule(function(){ + $('.pos-actionbar-button-list .button:eq(2)').click(); + },{duration:250}); + order_queue.schedule(function(){ + def.resolve(); + }); + return def; + },{repeat: true, duration: interval}); + }; + }; + + if(jQuery.deparam(jQuery.param.querystring()).debug !== undefined){ + window.pos_test_ui = new module.UiTester(); + } + +} diff --git a/addons/point_of_sale/static/src/js/widget_base.js b/addons/point_of_sale/static/src/js/widget_base.js index 124be4e9f82..30d85f2696a 100644 --- a/addons/point_of_sale/static/src/js/widget_base.js +++ b/addons/point_of_sale/static/src/js/widget_base.js @@ -41,10 +41,10 @@ function openerp_pos_basewidget(instance, module){ //module is instance.point_of }, show: function(){ - this.$el.show(); + this.$el.removeClass('oe_hidden'); }, hide: function(){ - this.$el.hide(); + this.$el.addClass('oe_hidden'); }, }); diff --git a/addons/point_of_sale/static/src/js/widget_scrollbar.js b/addons/point_of_sale/static/src/js/widget_scrollbar.js index e4660a9c458..001e96d0bb6 100644 --- a/addons/point_of_sale/static/src/js/widget_scrollbar.js +++ b/addons/point_of_sale/static/src/js/widget_scrollbar.js @@ -81,7 +81,7 @@ function openerp_pos_scrollbar(instance, module){ //module is instance.point_of_ $(window).unbind('resize',this.resize_handler); $(window).bind('resize',this.resize_handler); - this.target().unbind('mousewheel',this.target_mousweheel_handler); + this.target().unbind('mousewheel',this.target_mousewheel_handler); this.target().bind('mousewheel',this.target_mousewheel_handler); // because the rendering is asynchronous we must wait for the next javascript update @@ -93,22 +93,18 @@ function openerp_pos_scrollbar(instance, module){ //module is instance.point_of_ },0); }, - // binds the window resize and the target scrolling events. - // it is good advice not to bind these multiple_times - bind_events:function(){ - $(window).resize(function(){ - }); - this.target().bind('mousewheel',function(event,delta){ - self.scroll(delta*self.wheel_step); - }); + destroy: function(){ + $(window).unbind('resize',this.resize_handler); + this.target().unbind('mousewheel',this.target_mousewheel_handler); + this._super(); }, // shows the scrollbar. if animated is true, it will do it in an animated fashion show: function(animated){ //FIXME: animated show and hide don't work ... ? if(animated){ - this.$el.show().animate({'width':'48px'}, 500, 'swing'); + this.$el.removeClass('oe_hidden').animate({'width':'48px'}, 500, 'swing'); }else{ - this.$el.show().css('width','48px'); + this.$el.removeClass('oe_hidden').css('width','48px'); } this.on_show(this); }, @@ -117,9 +113,9 @@ function openerp_pos_scrollbar(instance, module){ //module is instance.point_of_ hide: function(animated){ var self = this; if(animated){ - this.$el.animate({'width':'0px'}, 500, 'swing', function(){ self.$el.hide();}); + this.$el.animate({'width':'0px'}, 500, 'swing', function(){ self.$el.addClass('oe_hidden');}); }else{ - this.$el.hide().css('width','0px'); + this.$el.addClass('oe_hidden').css('width','0px'); } this.on_hide(this); }, diff --git a/addons/point_of_sale/static/src/js/widgets.js b/addons/point_of_sale/static/src/js/widgets.js index 8afd3df6255..26f0159cb28 100644 --- a/addons/point_of_sale/static/src/js/widgets.js +++ b/addons/point_of_sale/static/src/js/widgets.js @@ -137,17 +137,15 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa this.model = options.model; this.order = options.order; - this.model.bind('change', _.bind( function() { - this.refresh(); - }, this)); - }, - click_handler: function() { - this.order.selectLine(this.model); - this.trigger('order_line_selected'); + this.model.bind('change', this.refresh, this); }, renderElement: function() { + var self = this; this._super(); - this.$el.click(_.bind(this.click_handler, this)); + this.$el.click(function(){ + self.order.selectLine(this.model); + self.trigger('order_line_selected'); + }); if(this.model.is_selected()){ this.$el.addClass('selected'); } @@ -156,6 +154,10 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa this.renderElement(); this.trigger('order_line_refreshed'); }, + destroy: function(){ + this.model.unbind('change',this.refresh,this); + this._super(); + }, }); module.OrderWidget = module.PosBaseWidget.extend({ @@ -358,16 +360,16 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa var self = this; this.order = options.order; - this.order.bind('destroy',function(){ self.destroy(); }); - this.order.bind('change', function(){ self.renderElement(); }); - this.pos.bind('change:selectedOrder', function() { - self.renderElement(); - }, this); + this.order.bind('destroy',this.destroy, this ); + this.order.bind('change', this.renderElement, this ); + this.pos.bind('change:selectedOrder', this.renderElement,this ); }, renderElement:function(){ this._super(); - this.$('button.select-order').off('click').click(_.bind(this.selectOrder, this)); - this.$('button.close-order').off('click').click(_.bind(this.closeOrder, this)); + var self = this; + this.$el.click(function(){ + self.selectOrder(); + }); if( this.order === this.pos.get('selectedOrder') ){ this.$el.addClass('selected-order'); } @@ -377,8 +379,11 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa selectedOrder: this.order }); }, - closeOrder: function(event) { - this.order.destroy(); + destroy: function(){ + this.order.unbind('destroy', this.destroy, this); + this.order.unbind('change', this.renderElement, this); + this.pos.unbind('change:selectedOrder', this.renderElement, this); + this._super(); }, }); @@ -422,9 +427,9 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa if(visible != this.visibility[element]){ this.visibility[element] = !!visible; if(visible){ - this.$('.'+element).show(); + this.$('.'+element).removeClass('oe_hidden'); }else{ - this.$('.'+element).hide(); + this.$('.'+element).addClass('oe_hidden'); } } if(visible && action){ @@ -459,10 +464,10 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa return button; }, show:function(){ - this.$el.show(); + this.$el.removeClass('oe_hidden'); }, hide:function(){ - this.$el.hide(); + this.$el.addClass('oe_hidden'); }, }); @@ -690,8 +695,8 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa this.$el.click(function(){ self.action(); }); } }, - show: function(){ this.$el.show(); }, - hide: function(){ this.$el.hide(); }, + show: function(){ this.$el.removeClass('oe_hidden'); }, + hide: function(){ this.$el.addClass('oe_hidden'); }, }); // The debug widget lets the user control and monitor the hardware and software status @@ -870,13 +875,12 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa new_order_button.selectOrder(); }, self); - self.pos.get('orders').add(new module.Order({ pos: self.pos })); + self.pos.add_new_order(); self.build_widgets(); self.screen_selector.set_default_screen(); - window.screen_selector = self.screen_selector; self.pos.barcode_reader.connect(); @@ -889,7 +893,7 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa } instance.web.unblockUI(); - self.$('.loader').animate({opacity:0},1500,'swing',function(){self.$('.loader').hide();}); + self.$('.loader').animate({opacity:0},1500,'swing',function(){self.$('.loader').addClass('oe_hidden');}); self.pos.flush(); @@ -1078,11 +1082,11 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa if(visible !== this.leftpane_visible){ this.leftpane_visible = visible; if(visible){ - $('#leftpane').show().animate({'width':this.leftpane_width},500,'swing'); + $('#leftpane').removeClass('oe_hidden').animate({'width':this.leftpane_width},500,'swing'); $('#rightpane').animate({'left':this.leftpane_width},500,'swing'); }else{ var leftpane = $('#leftpane'); - $('#leftpane').animate({'width':'0px'},500,'swing', function(){ leftpane.hide(); }); + $('#leftpane').animate({'width':'0px'},500,'swing', function(){ leftpane.addClass('oe_hidden'); }); $('#rightpane').animate({'left':'0px'},500,'swing'); } } @@ -1092,11 +1096,11 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa if(visible !== this.cashier_controls_visible){ this.cashier_controls_visible = visible; if(visible){ - $('#loggedas').show(); - $('#rightheader').show(); + $('#loggedas').removeClass('oe_hidden'); + $('#rightheader').removeClass('oe_hidden'); }else{ - $('#loggedas').hide(); - $('#rightheader').hide(); + $('#loggedas').addClass('oe_hidden'); + $('#rightheader').addClass('oe_hidden'); } } }, From 674054c97ee58dca677c18d075c62eefad3bce13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Tue, 17 Sep 2013 14:29:29 +0200 Subject: [PATCH 3/5] [IMP] point_of_sale: removed ProductWidget for faster product list updates bzr revid: fva@openerp.com-20130917122929-8pybdbvgrv8kbgru --- addons/point_of_sale/static/src/js/widgets.js | 43 ++++--------------- addons/point_of_sale/static/src/xml/pos.xml | 12 +++--- 2 files changed, 14 insertions(+), 41 deletions(-) diff --git a/addons/point_of_sale/static/src/js/widgets.js b/addons/point_of_sale/static/src/js/widgets.js index b0d1bb39aa5..cfec71be68d 100644 --- a/addons/point_of_sale/static/src/js/widgets.js +++ b/addons/point_of_sale/static/src/js/widgets.js @@ -283,27 +283,6 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa }, }); - module.ProductWidget = module.PosBaseWidget.extend({ - template: 'ProductWidget', - init: function(parent, options) { - this._super(parent,options); - this.model = options.model; - this.model.attributes.weight = options.weight; - this.next_screen = options.next_screen; //when a product is clicked, this screen is set - this.click_product_action = options.click_product_action; - }, - // returns the url of the product thumbnail - renderElement: function() { - this._super(); - this.$('img').replaceWith(this.pos_widget.image_cache.get_image(this.model.get_image_url())); - var self = this; - $("a", this.$el).click(function(e){ - if(self.click_product_action){ - self.click_product_action(self.model); - } - }); - }, - }); module.PaymentlineWidget = module.PosBaseWidget.extend({ template: 'PaymentlineWidget', @@ -619,25 +598,19 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa renderElement: function() { var self = this; this._super(); - - // free subwidgets memory from previous renders - for(var i = 0, len = this.productwidgets.length; i < len; i++){ - this.productwidgets[i].destroy(); - } - this.productwidgets = []; if(this.scrollbar){ this.scrollbar.destroy(); } var products = this.pos.get('products').models || []; - for(var i = 0, len = products.length; i < len; i++){ - var product = new module.ProductWidget(self, { - model: products[i], - click_product_action: this.click_product_action, - }); - this.productwidgets.push(product); - product.appendTo(this.$('.product-list')); - } + + _.each(products,function(product,i){ + var $product = $(QWeb.render('Product',{ widget:self, product: products[i] })); + $product.find('img').replaceWith(self.pos_widget.image_cache.get_image(products[i].get_image_url())); + $product.find('a').click(function(){ self.click_product_action(product); }); + $product.appendTo(self.$('.product-list')); + }); + this.scrollbar = new module.ScrollbarWidget(this,{ target_widget: this, target_selector: '.product-list-scroller', diff --git a/addons/point_of_sale/static/src/xml/pos.xml b/addons/point_of_sale/static/src/xml/pos.xml index e1ee84d78ea..7456c29b9e5 100644 --- a/addons/point_of_sale/static/src/xml/pos.xml +++ b/addons/point_of_sale/static/src/xml/pos.xml @@ -399,24 +399,24 @@ - +
  • - + - + - + - +
    - +
  • From ad6bbe490a204da0d57a453a9c519ccad04284b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Tue, 17 Sep 2013 14:34:46 +0200 Subject: [PATCH 4/5] [FIX] point_of_sale: scaled product weren't ordered with the correct weight bzr revid: fva@openerp.com-20130917123446-671ijt70i93p0w67 --- addons/point_of_sale/static/src/js/screens.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/point_of_sale/static/src/js/screens.js b/addons/point_of_sale/static/src/js/screens.js index 9f1b22f2a75..0c3e488d212 100644 --- a/addons/point_of_sale/static/src/js/screens.js +++ b/addons/point_of_sale/static/src/js/screens.js @@ -542,8 +542,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa } }, order_product: function(){ - var weight = this.pos.proxy.weighting_read_kg(); - this.pos.get('selectedOrder').addProduct(this.get_product(),{ quantity:weight }); + this.pos.get('selectedOrder').addProduct(this.get_product(),{ quantity: this.weight }); }, get_product_name: function(){ var product = this.get_product(); From 0d826f64ca6bf16eedffcb33325452252c244467 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Tue, 17 Sep 2013 14:46:15 +0200 Subject: [PATCH 5/5] [FIX] point_of_sale: missing renamings from the JobQueue refactor bzr revid: fva@openerp.com-20130917124615-kqtix2atp1xguszw --- addons/point_of_sale/static/src/js/screens.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/point_of_sale/static/src/js/screens.js b/addons/point_of_sale/static/src/js/screens.js index 0c3e488d212..a5017d517b7 100644 --- a/addons/point_of_sale/static/src/js/screens.js +++ b/addons/point_of_sale/static/src/js/screens.js @@ -455,7 +455,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa queue.schedule(function(){ return self.pos.proxy.weighting_start(); - },{ unclearable: true }); + },{ important: true }); queue.schedule(function(){ return self.pos.proxy.weighting_read_kg().then(function(weight){ @@ -479,7 +479,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa this.pos.proxy_queue.clear(); this.pos.proxy_queue.schedule(function(){ return self.pos.proxy.weighting_end(); - },{ unclearable: true }); + },{ important: true }); }, }); @@ -516,7 +516,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa queue.schedule(function(){ return self.pos.proxy.weighting_start() - },{ unclearable: true }); + },{ important: true }); queue.schedule(function(){ return self.pos.proxy.weighting_read_kg().then(function(weight){ @@ -566,7 +566,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa this.pos.proxy_queue.clear(); this.pos.proxy_queue.schedule(function(){ self.pos.proxy.weighting_end(); - },{ unclearable: true }); + },{ important: true }); }, });