[IMP] point_of_sale: better feedback on network and proxy connectivity + removed...
authorFrédéric van der Essen <fva@openerp.com>
Fri, 17 Jan 2014 17:58:30 +0000 (18:58 +0100)
committerFrédéric van der Essen <fva@openerp.com>
Fri, 17 Jan 2014 17:58:30 +0000 (18:58 +0100)
bzr revid: fva@openerp.com-20140117175830-himux7xmaopw9yia

addons/point_of_sale/point_of_sale.py
addons/point_of_sale/point_of_sale_view.xml
addons/point_of_sale/static/src/css/pos.css
addons/point_of_sale/static/src/js/devices.js
addons/point_of_sale/static/src/js/models.js
addons/point_of_sale/static/src/js/widgets.js
addons/point_of_sale/static/src/xml/pos.xml

index e5047d8..6bd5b6b 100644 (file)
@@ -74,11 +74,12 @@ class pos_config(osv.osv):
         'iface_electronic_scale' : fields.boolean('Electronic Scale', help="Enables Electronic Scale integration"),
         'iface_vkeyboard' : fields.boolean('Virtual KeyBoard', help="Enables an integrated Virtual Keyboard"),
         'iface_print_via_proxy' : fields.boolean('Print via Proxy', help="Bypass browser printing and prints via the hardware proxy"),
+        'iface_scan_via_proxy' : fields.boolean('Scan via Proxy', help="Enable barcode scanning with a remotely connected barcode scanner"),
         'iface_invoicing': fields.boolean('Invoicing',help='Enables invoice generation from the Point of Sale'),
         'iface_big_scrollbars': fields.boolean('Large Scrollbars',help='For imprecise industrial touchscreens'),
         'receipt_header': fields.text('Receipt Header',help="A short text that will be inserted as a header in the printed receipt"),
         'receipt_footer': fields.text('Receipt Footer',help="A short text that will be inserted as a footer in the printed receipt"),
-        'proxy_ip':       fields.char('Hardware Proxy IP Address', size=45),
+        'proxy_ip':       fields.char('IP Address', help='The hostname or ip address of the hardware proxy, Will be autodetected if left empty', size=45),
 
         'state' : fields.selection(POS_CONFIG_STATE, 'Status', required=True, readonly=True),
         'sequence_id' : fields.many2one('ir.sequence', 'Order IDs Sequence', readonly=True,
index e6db84a..d7879f5 100644 (file)
                                 <field name="cash_control" />
                             </tree>
                         </field>
-                        <group string="Settings" >
+                        <group string="Features" >
                             <group>
-                                <field name="iface_self_checkout" />
                                 <field name="iface_cashdrawer" />
-                                <field name="iface_payment_terminal" />
                                 <field name="iface_invoicing" />
+                                <field name="iface_electronic_scale" />
                             </group>
                             <group>
-                                <field name="iface_electronic_scale" />
                                 <field name="iface_vkeyboard" />
                                 <field name="iface_big_scrollbars" />
-                                <field name="proxy_ip" />
                             </group>
                         </group>
-                        <group string="Receipt" >
+                        <group string="Hardware Proxy" >
+                            <field name="proxy_ip" />
                             <field name="iface_print_via_proxy" />
+                            <field name="iface_scan_via_proxy" />
+                        </group>
+                        <group string="Receipt" >
                             <field name="receipt_header" placeholder="A custom receipt header message"/>
                             <field name="receipt_footer" placeholder="A custom receipt header footage"/>
                         </group>
index 8980a01..41fc503 100644 (file)
@@ -360,7 +360,7 @@ td {
 
 /*  c) The notifications indicator */
 
-.pos .oe_pos_synch-notification{
+.pos .oe_status{
     float:right; 
     color: rgba(255,255,255,0.4);
     padding: 8px;
@@ -370,21 +370,24 @@ td {
     font-style: italic;
     cursor:pointer;
 }
-.pos .oe_pos_synch-notification.oe_inactive{
+.pos .oe_status.oe_inactive{
     cursor: default;
 }
-.pos .oe_pos_synch-notification .oe_status{
+.pos .oe_status .oe_icon{
     display:inline-block;
     cursor:pointer;
-    width:16px; height:16px;
+    width:20px; height:16px;
     color: white;
 }
-.pos .oe_pos_synch-notification .oe_red{
+.pos .oe_icon.oe_red{
     color: rgb(197, 52, 0);
 }
-.pos .oe_pos_synch-notification .oe_green{
+.pos .oe_icon.oe_green{
     color: rgb(94, 185, 55);
 }
+.pos .oe_icon.oe_orange{
+    color: rgb(239, 153, 65);
+}
 
 /*  ********* Contains everything below the  bar ********* */
 
index 6f8e6fe..e86bb7c 100644 (file)
@@ -698,6 +698,8 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
         // stops catching keyboard events 
         disconnect: function(){
             $('body').off('keypress', this.handler)
+        },
+        disconnect_from_proxy: function(){
             this.remote_scanning = false;
         },
         connect_to_proxy: function(){
@@ -712,11 +714,13 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
                         if(!self.remote_scanning){ 
                             return; 
                         }
+                        self.pos.set('proxy_status','connected');
                         self.scan(barcode);
                         waitforbarcode();
                     },
                     function(){
                         setTimeout(waitforbarcode,5000);
+                        self.pos.set('proxy_status','disconnected');
                     });
                 });
         },
index 961ebff..58f87b6 100644 (file)
@@ -25,7 +25,6 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
 
             this.proxy = new module.ProxyDevice();              // 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.barcode_reader.connect_to_proxy();
             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
             this.debug = jQuery.deparam(jQuery.param.querystring()).debug !== undefined;    //debug mode 
@@ -56,6 +55,7 @@ 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':     'connecting',
             });
 
             this.bind('change:synch',function(pos,synch){
@@ -76,7 +76,9 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
             // when all the data has loaded, we compute some stuff, and declare the Pos ready to be used. 
             this.ready = this.load_server_data()
                 .then(function(){
-                    return self.connect_to_posbox();
+                    if(self.config.use_proxy){
+                        return self.connect_to_proxy();
+                    }
                 });
             
         },
@@ -87,14 +89,18 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
             // this.flush();
             this.proxy.close();
             this.barcode_reader.disconnect();
+            this.barcode_reader.disconnect_from_proxy();
         },
 
-        connect_to_posbox: function(){
+        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();
+                    self.set('proxy_status', 'disconnected'); 
                 });
 
             return this.proxy.find_proxy({
@@ -105,6 +111,12 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
                 }).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');
                     }
                 });
         },
@@ -175,14 +187,20 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
                         'pos.config',
                         ['name','journal_ids','warehouse_id','journal_id','pricelist_id',
                          'iface_self_checkout', 'iface_led', 'iface_cashdrawer',
-                         'iface_payment_terminal', 'iface_electronic_scale', 'iface_barscan', 'iface_vkeyboard',
-                         'iface_print_via_proxy','iface_cashdrawer','iface_invoicing','iface_big_scrollbars',
+                         'iface_payment_terminal', 'iface_electronic_scale', 'iface_barscan', 
+                         'iface_vkeyboard','iface_print_via_proxy','iface_scan_via_proxy',
+                         'iface_cashdrawer','iface_invoicing','iface_big_scrollbars',
                          'receipt_header','receipt_footer','proxy_ip',
                          'state','sequence_id','session_ids'],
                         [['id','=', self.pos_session.config_id[0]]]
                     );
                 }).then(function(configs){
                     self.config = configs[0];
+                    self.config.use_proxy = self.config.iface_payment_terminal || 
+                                            self.config.iface_electronic_scale ||
+                                            self.config.iface_print_via_proxy  ||
+                                            self.config.iface_scan_via_proxy   ||
+                                            self.config.iface_cashdrawer;
 
                     return self.fetch('stock.warehouse',[],[['id','=', self.config.warehouse_id[0]]]);
                 }).then(function(shops){
index 9e671d5..393b0b2 100644 (file)
@@ -822,40 +822,51 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
 
 // ---------- Main Point of Sale Widget ----------
 
-    // this is used to notify the user that data is being synchronized on the network
-    module.SynchNotificationWidget = module.PosBaseWidget.extend({
-        template: "SynchNotificationWidget",
-        init: function(parent, options){
-            options = options || {};
-            this._super(parent, options);
-        },
-        renderElement: function() {
+    module.StatusWidget = module.PosBaseWidget.extend({
+        status: ['connected','connecting','disconnected','warning'],
+        set_status: function(status,msg){
             var self = this;
-            this._super();
+            for(var i = 0; i < this.status.length; i++){
+                this.$('.js_'+this.status[i]).addClass('oe_hidden');
+            }
+            this.$('.js_'+status).removeClass('oe_hidden');
             
-            var pending = this.pos.get('nbr_pending_orders');
-            this.set_status(pending ? 'disconnected' : 'connected',pending);
+            if(msg){
+                this.$('.js_msg').removeClass('oe_hidden').html(msg);
+            }else{
+                this.$('.js_msg').addClass('oe_hidden').html('');
+            }
+        },
+    });
 
+    // this is used to notify the user that data is being synchronized on the network
+    module.SynchNotificationWidget = module.StatusWidget.extend({
+        template: 'SynchNotificationWidget',
+        start: function(){
+            var self = this;
+            this.pos.bind('change:synch', function(pos,synch){
+                self.set_status(synch.state, synch.pending);
+            });
             this.$el.click(function(){
                 self.pos.flush();
             });
         },
-        set_status: function(state,pending){
-            var self = this;
-            this.$('.js_connected, .js_connecting, .js_disconnected, .js_pending').addClass('oe_hidden');
-            this.$('.js_pending').html(pending || '');
-            if(state === 'connected'){
-                this.$('.js_connected').removeClass('oe_hidden');
-            }else if(state === 'disconnected'){
-                this.$('.js_disconnected, .js_pending').removeClass('oe_hidden');
-            }else if(state === 'connecting'){
-                this.$('.js_connecting, .js_pending').removeClass('oe_hidden');
-            }
-        },
+    });
+
+    // this is used to notify the user if the pos is connected to the proxy
+    module.ProxyStatusWidget = module.StatusWidget.extend({
+        template: 'ProxyStatusWidget',
         start: function(){
             var self = this;
-            this.pos.bind('change:synch', function(pos,synch){
-                self.set_status(synch.state, synch.pending);
+            
+            this.set_status(this.pos.get('proxy_status'),'');
+
+            this.pos.bind('change:proxy_status', function(pos,status){
+                self.set_status(status,'');
+            });
+
+            this.$el.click(function(){
+                self.pos.connect_to_proxy();
             });
         },
     });
@@ -1051,9 +1062,20 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
 
             // --------  Misc ---------
 
+            this.close_button = new module.HeaderButtonWidget(this,{
+                label: _t('Close'),
+                action: function(){ self.close(); },
+            });
+            this.close_button.appendTo(this.$('.pos-rightheader'));
+
             this.notification = new module.SynchNotificationWidget(this,{});
             this.notification.appendTo(this.$('.pos-rightheader'));
 
+            if(this.pos.config.use_proxy){
+                this.proxy_status = new module.ProxyStatusWidget(this,{});
+                this.proxy_status.appendTo(this.$('.pos-rightheader'));
+            }
+
             this.username   = new module.UsernameWidget(this,{});
             this.username.replace(this.$('.placeholder-UsernameWidget'));
 
@@ -1077,12 +1099,6 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
             });
             this.onscreen_keyboard.replace(this.$('.placeholder-OnscreenKeyboardWidget'));
 
-            this.close_button = new module.HeaderButtonWidget(this,{
-                label: _t('Close'),
-                action: function(){ self.close(); },
-            });
-            this.close_button.appendTo(this.$('.pos-rightheader'));
-
             this.client_button = new module.HeaderButtonWidget(this,{
                 label: _t('Self-Checkout'),
                 action: function(){ self.screen_selector.set_user_mode('client'); },
index e268e62..179d4ac 100644 (file)
     </t>
 
     <t t-name="SynchNotificationWidget">
-        <div class="oe_pos_synch-notification">
-            <span class='js_pending oe_hidden'>0</span>
-            <div class="js_connected oe_status oe_green">
-                <i class='fa fa-fw fa-circle'></i>
+        <div class="oe_status js_synch">
+            <span class='js_msg oe_hidden'>0</span>
+            <div class="js_connected oe_icon oe_green">
+                <i class='fa fa-fw fa-rss'></i>
             </div>
-            <div class="js_connecting oe_status oe_hidden">
+            <div class="js_connecting oe_icon oe_hidden">
                 <i class='fa fa-fw fa-spin fa-spinner'></i>
             </div>
-            <div class="js_disconnected oe_status oe_red oe_hidden">
-                <i class='fa fa-fw fa-circle'></i>
+            <div class="js_disconnected oe_icon oe_red oe_hidden">
+                <i class='fa fa-fw fa-rss'></i>
+            </div>
+        </div>
+    </t>
+
+    <t t-name="ProxyStatusWidget">
+        <div class="oe_status js_proxy">
+            <span class='js_msg oe_hidden'></span>
+            <div class="js_connected oe_icon oe_green">
+                <i class='fa fa-fw fa-sitemap'></i>
+            </div>
+            <div class="js_connecting oe_icon oe_hidden">
+                <i class='fa fa-fw fa-spin fa-spinner'></i>
+            </div>
+            <div class="js_disconnected oe_icon oe_red oe_hidden">
+                <i class='fa fa-fw fa-sitemap'></i>
             </div>
         </div>
     </t>