From c9879fcd1ee5ac3bda28e64a5617cd30318c73f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Mon, 27 Jan 2014 01:22:03 +0100 Subject: [PATCH] [IMP] point_of_sale: refactor proxy to use event based status notifications bzr revid: fva@openerp.com-20140127002203-y2qnhwf0z708gbrx --- addons/point_of_sale/static/src/js/devices.js | 81 ++++++++++++------- addons/point_of_sale/static/src/js/models.js | 29 ++----- addons/point_of_sale/static/src/js/widgets.js | 6 +- 3 files changed, 61 insertions(+), 55 deletions(-) diff --git a/addons/point_of_sale/static/src/js/devices.js b/addons/point_of_sale/static/src/js/devices.js index f31fb89cf0e..926fc3f91b6 100644 --- a/addons/point_of_sale/static/src/js/devices.js +++ b/addons/point_of_sale/static/src/js/devices.js @@ -81,8 +81,9 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal // connected to the Point of Sale. As the communication only goes from the POS to the proxy, // methods are used both to signal an event, and to fetch information. - module.ProxyDevice = instance.web.Class.extend({ - init: function(options){ + module.ProxyDevice = instance.web.Class.extend(openerp.PropertiesMixin,{ + init: function(parent,options){ + openerp.PropertiesMixin.init.call(this,parent); var self = this; options = options || {}; url = options.url || 'http://localhost:8069'; @@ -105,57 +106,68 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal this.bypass_proxy = false; this.connection = null; - this.connected = null; this.host = ''; this.keptalive = false; - this.status = {}; - this.status_callback = options.status_callback || null; + this.set('status',{}); + this.set_connection_status('disconnected'); window.hw_proxy = this; }, set_connection_status: function(status,drivers){ - this.status.status = status; - this.status.drivers = status === 'disconnected' ? {} : this.status.drivers; - this.status.drivers = drivers ? drivers : this.status.drivers; - if(this.status_callback){ - this.status_callback(status,drivers); - } + oldstatus = this.get('status'); + newstatus = {}; + newstatus.status = status; + newstatus.drivers = status === 'disconnected' ? {} : oldstatus.drivers; + newstatus.drivers = drivers ? drivers : newstatus.drivers; + this.set('status',newstatus); }, disconnect: function(){ - if(this.status.status !== 'disconnected'){ + if(this.get('status').status !== 'disconnected'){ this.connection.destroy(); this.set_connection_status('disconnected'); } }, - connect : function(url){ + connect: function(url){ var self = this; this.connection = new instance.web.Session(undefined,url); this.host = url; this.set_connection_status('connecting',{}); - if(this.connected){ - this.connected.reject(); - } - this.connected = new $.Deferred(); return this.message('handshake').then(function(response){ if(response){ self.set_connection_status('connected'); localStorage['hw_proxy_url'] = url; - self.connected.resolve(); self.keepalive(); }else{ self.set_connection_status('disconnected'); - self.connected.reject(); console.error('Connection refused by the Proxy'); } },function(){ self.set_connection_status('disconnected'); - self.connected.reject(); console.error('Could not connect to the Proxy'); }); }, + autoconnect: function(opts){ + var self = this; + this.set_connection_status('connecting',{}); + var success = new $.Deferred(); + this.find_proxy(opts) + .then(function(proxies){ + if(proxies.length > 0){ + self.connect(proxies[0]) + .then(function(){ + success.resolve(); + },function(){ + success.reject(); + }); + }else{ + success.reject(); + } + }); + return success; + }, keepalive: function(){ var self = this; if(!this.keptalive){ @@ -178,7 +190,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal for(var i = 0; i < callbacks.length; i++){ callbacks[i](params); } - if(this.status.status !== 'disconnected'){ + if(this.get('status').status !== 'disconnected'){ return this.connection.rpc('/hw_proxy/' + name, params || {}); }else{ return (new $.Deferred()).reject(); @@ -205,6 +217,8 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal var threads = []; var progress = 0; + this.set_connection_status('connecting'); + if(options.force_ip){ urls.push(options.force_ip); }else{ @@ -277,6 +291,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal stop_searching: function(){ this.searching_for_proxy = false; + this.set_connection_status('disconnected'); }, // this allows the client to be notified when a proxy call is made. The notification @@ -505,6 +520,8 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal this.pos = attributes.pos; this.action_callback = {}; this.proxy = attributes.proxy; + this.remote_scanning = false; + this.remote_active = 0; this.action_callback_stack = []; @@ -513,6 +530,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal this.price_prefix_set = attributes.price_prefix_set || {'23':''}; this.cashier_prefix_set = attributes.cashier_prefix_set || {'041':''}; this.client_prefix_set = attributes.client_prefix_set || {'042':''}; + }, save_callbacks: function(){ @@ -742,25 +760,32 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal disconnect_from_proxy: function(){ this.remote_scanning = false; }, - connect_to_proxy: function(){ //FIXME prevent double connections + connect_to_proxy: function(){ //FIXME prevent connection losses var self = this; this.remote_scanning = true; + if(this.remote_active >= 1){ + return; + } + this.remote_active = 1; - this.proxy.connected.then(function waitforbarcode(){ - if(!self.remote_scanning){ - return; - } + function waitforbarcode(){ return self.proxy.connection.rpc('/hw_proxy/scanner',{}).then(function(barcode){ + self.scan(barcode); if(!self.remote_scanning){ + this.remote_active = 0; return; } - self.scan(barcode); waitforbarcode(); }, function(){ + if(!self.remote_scanning){ + this.remote_active = 0; + return; + } setTimeout(waitforbarcode,5000); }); - }); + } + waitforbarcode(); }, }); diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index aae0263de7b..f623b21374c 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -23,7 +23,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal this.flush_mutex = new $.Mutex(); // used to make sure the orders are sent to the server once at time this.pos_widget = attributes.pos_widget; - this.proxy = new module.ProxyDevice(); // used to communicate to the hardware devices via a local proxy + this.proxy = new module.ProxyDevice(this); // used to communicate to the hardware devices via a local proxy this.barcode_reader = new module.BarcodeReader({'pos': this, proxy:this.proxy}); // used to read barcodes this.proxy_queue = new module.JobQueue(); // used to prevent parallels communications to the proxy this.db = new module.PosDB(); // a local database used to search trough products and categories & store pending orders @@ -55,7 +55,6 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal 'synch': { state:'connected', pending:0 }, 'orders': new module.OrderCollection(), 'selectedOrder': null, - 'proxy_status': {status: 'connecting', drivers: {}}, }); this.bind('change:synch',function(pos,synch){ @@ -91,39 +90,21 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal this.barcode_reader.disconnect(); this.barcode_reader.disconnect_from_proxy(); }, - - set_proxy_status: function(status,drivers){ - this.set('proxy_status',{status:status,drivers:drivers || {}}); - }, connect_to_proxy: function(){ var self = this; this.barcode_reader.disconnect_from_proxy(); this.pos_widget.loading_message(_t('Connecting to the PosBox'),0); - this.set_proxy_status('connecting'); - this.pos_widget.loading_skip(function(){ self.proxy.stop_searching(); - this.set_proxy_status('disconnected'); }); - - this.proxy.status_callback = function(status,driver_status){ - self.set_proxy_status(status,driver_status); - }; - - return this.proxy.find_proxy({ + this.proxy.autoconnect({ force_ip: self.config.proxy_ip || undefined, progress: function(prog){ self.pos_widget.loading_progress(prog); }, - }).then(function(proxies){ - if(proxies.length > 0){ - self.proxy.connect(proxies[0]); - if(self.config.iface_scan_via_proxy){ - self.barcode_reader.connect_to_proxy(); - } - self.set_proxy_status('connected'); - }else{ - self.set_proxy_status('disconnected'); + }).then(function(){ + if(self.config.iface_scan_via_proxy){ + self.barcode_reader.connect_to_proxy(); } }); }, diff --git a/addons/point_of_sale/static/src/js/widgets.js b/addons/point_of_sale/static/src/js/widgets.js index 1bfda516578..f887a537d39 100644 --- a/addons/point_of_sale/static/src/js/widgets.js +++ b/addons/point_of_sale/static/src/js/widgets.js @@ -885,10 +885,10 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa start: function(){ var self = this; - this.set_smart_status(this.pos.get('proxy_status')); + this.set_smart_status(this.pos.proxy.get('status')); - this.pos.bind('change:proxy_status', function(pos,status){ - self.set_smart_status(status); + this.pos.proxy.on('change:status',this,function(eh,status){ //FIXME remove duplicate changes + self.set_smart_status(status.newValue); }); this.$el.click(function(){