[IMP] stock_picking_ui: reworked the main menu: now has better ui and interactive...
authorFrédéric van der Essen <fva@openerp.com>
Wed, 13 Nov 2013 17:24:48 +0000 (18:24 +0100)
committerFrédéric van der Essen <fva@openerp.com>
Wed, 13 Nov 2013 17:24:48 +0000 (18:24 +0100)
bzr revid: fva@openerp.com-20131113172448-xbm8gx7t9x0a8x8z

addons/stock/static/src/css/picking.css
addons/stock/static/src/js/widgets.js
addons/stock/static/src/xml/picking.xml

index edf62fc..accc3b3 100644 (file)
@@ -15,6 +15,9 @@
     width: 100%;
     height: 100%;
 }
+.oe_pick_widget .oe_hidden{
+    display: none !important;
+}
 
 .oe_pick_widget .oe_pick_header{
     background: #454343;
 }
 
 
+/* ----------------------- *
+ *    MAIN PICKING MENU    *
+ * ----------------------- */
+
+.oe_pick_widget .oe_picking{
+    background: rgb(223, 226, 246);
+    padding: 10px;
+    margin-bottom: 3px;
+    border-radius: 3px;
+    border-bottom: solid 2px rgb(189, 189, 241);
+    cursor: pointer;
+}
+.oe_pick_widget .oe_picking.oe_empty {
+    border: solid 1px rgb(228, 226, 241);
+    background: white;
+    cursor: default;
+}
+.oe_pick_widget .oe_picking > .oe_picking_name{
+    display: inline-block;
+    min-width: 100px;
+    margin-right: 10px;
+}
+.oe_pick_widget .oe_search_empty{
+    padding: 10px;
+    border-radius: 3px;
+    background: rgb(228, 226, 241);
+    text-align: center;
+}
+
+/* ----------------------- *
+ *       SEARCH BOX        *
+ * ----------------------- */
+
+.oe_pick_widget .oe_searchbox{
+    float: right;
+}
+.oe_pick_widget .oe_searchbox input{
+    padding: 8px;
+}
+.oe_pick_widget .oe_picking_not_found{
+    padding: 8px;
+    margin: 24px 0px;
+    text-align: center;
+    background: rgb(239, 240, 247);
+    border-radius: 3px;
+    color: rgb(119, 77, 77);
+}
index 8244124..583bbf4 100644 (file)
@@ -1,7 +1,9 @@
 
 function openerp_picking_widgets(instance){
+
     var module = instance.stock;
-    var _t = instance.web._t;
+    var _t     = instance.web._t;
+    var QWeb   = instance.web.qweb;
 
     module.PickingEditorWidget = instance.web.Widget.extend({
         template: 'PickingEditorWidget',
@@ -108,7 +110,9 @@ function openerp_picking_widgets(instance){
             this.scanning_type = 0;
             this.barcode_scanner = new module.BarcodeScanner();
             this.pickings_by_type = {};
-
+            this.pickings_by_id = {};
+            this.picking_search_string = "";
+            
         },
         load: function(){
             var self = this;
@@ -129,7 +133,10 @@ function openerp_picking_widgets(instance){
                     for(var i = 0; i < pickings.length; i++){
                         var picking = pickings[i];
                         self.pickings_by_type[picking.picking_type_id[0]].push(picking);
+                        self.pickings_by_id[picking.id] = picking;
+                        self.picking_search_string += '' + picking.id + ':' + picking.name.toUpperCase() + '\n'
                     }
+
                 });
         },
         renderElement: function(){
@@ -137,7 +144,10 @@ function openerp_picking_widgets(instance){
             var self = this;
             this.$('.js_pick_quit').click(function(){ self.quit(); });
             this.$('.js_pick_scan').click(function(){ self.scan_picking($(this).data('id')); });
-            this.$('.js_pick_last').click(function(){ self.goto_picking($(this).data('id')); });
+            this.$('.js_pick_last').click(function(){ self.goto_last_picking_of_type($(this).data('id')); });
+            this.$('.oe_searchbox input').keyup(function(event){
+                self.on_searchbox($(this).val());
+            });
         },
         start: function(){
             var self = this;
@@ -148,7 +158,17 @@ function openerp_picking_widgets(instance){
                 self.renderElement();
             });
         },
-        goto_picking: function(type_id){
+        goto_picking: function(picking_id){
+            this.do_action({
+                type:   'ir.actions.client',
+                tag:    'stock.ui',
+                target: 'current',
+                context: { picking_id: picking_id },
+            },{
+                clear_breadcrumbs: true,
+            });
+        },
+        goto_last_picking_of_type: function(type_id){
             this.do_action({
                 type:   'ir.actions.client',
                 tag:    'stock.ui',
@@ -158,30 +178,60 @@ function openerp_picking_widgets(instance){
                 clear_breadcrumbs: true,
             });
         },
-        scan_picking: function(id){
-            this.$('.js_pick_scan.oe_active').text(_t('Scan')).removeClass('oe_active');
-            if(id !== this.scanning_type){
-                this.$('.js_pick_scan[data-id='+id+']').text(_t('Please scan a barcode ...')).addClass('oe_active');
-                this.scanning_type = id;
-            }else{
-                this.scanning_type = 0;
+        search_picking: function(barcode){
+            var re = RegExp("([0-9]+):.*?"+barcode.toUpperCase(),"gi");
+            var results = [];
+            for(var i = 0; i < 100; i++){
+                r = re.exec(this.picking_search_string);
+                if(r){
+                    var picking = this.pickings_by_id[Number(r[1])];
+                    if(picking){
+                        results.push(picking);
+                    }
+                }else{
+                    break;
+                }
             }
+            return results;
         },
         on_scan: function(barcode){
+            var self = this;
+
             for(var i = 0, len = this.pickings.length; i < len; i++){
                 var picking = this.pickings[i];
-                if(picking.picking_type_id[0] === this.scanning_type && picking.name.toUpperCase() === barcode.toUpperCase()){
-                    this.do_action({
-                        type:   'ir.actions.client',
-                        tag:    'stock.ui',
-                        target: 'current',
-                        context: { picking_id: picking.id },
-                    },{
-                        clear_breadcrumbs: true,
-                    });
+                if(picking.name.toUpperCase() === barcode.toUpperCase()){
+                    this.goto_picking(picking.id);
+                    break;
                 }
             }
-            this.$('.js_pick_scan.oe_active').text(_t('Scanned picking not found'));
+            this.$('.oe_picking_not_found').removeClass('oe_hidden');
+
+            clearTimeout(this.picking_not_found_timeout);
+            this.picking_not_found_timeout = setTimeout(function(){
+                self.$('.oe_picking_not_found').addClass('oe_hidden');
+            },2000);
+
+        },
+        on_searchbox: function(query){
+            var self = this;
+
+            clearTimeout(this.searchbox_timeout);
+            this.searchbox_timout = setTimeout(function(){
+                if(query){
+                    self.$('.oe_picking_not_found').addClass('oe_hidden');
+                    self.$('.oe_picking_categories').addClass('oe_hidden');
+                    self.$('.oe_picking_search_results').html(
+                        QWeb.render('PickingSearchResults',{results:self.search_picking(query)})
+                    );
+                    self.$('.oe_picking_search_results .oe_picking').click(function(){
+                        self.goto_picking($(this).data('id'));
+                    });
+                    self.$('.oe_picking_search_results').removeClass('oe_hidden');
+                }else{
+                    self.$('.oe_picking_categories').removeClass('oe_hidden');
+                    self.$('.oe_picking_search_results').addClass('oe_hidden');
+                }
+            },100);
         },
         quit: function(){
             instance.webclient.set_content_full_screen(false);
@@ -315,6 +365,16 @@ function openerp_picking_widgets(instance){
             this.$('.js_pick_next').click(function(){ self.picking_next(); });
             this.$('.js_pick_menu').click(function(){ self.menu(); });
 
+            this.hotkey_handler = function(event){
+                if(event.keyCode === 37 ){  // Left Arrow
+                    self.picking_prev();
+                }else if(event.keyCode === 39){ // Right Arrow
+                    self.picking_next();
+                }
+            };
+
+            $('body').on('keyup',this.hotkey_handler);
+
             $.when(this.loaded).done(function(){
                 self.picking_editor = new module.PickingEditorWidget(self);
                 self.picking_editor.replace(self.$('.oe_placeholder_picking_editor'));
@@ -548,6 +608,7 @@ function openerp_picking_widgets(instance){
             this._super();
             this.disconnect_numpad();
             this.barcode_scanner.disconnect();
+            $('body').off('keyup',this.hotkey_handler);
             instance.webclient.set_content_full_screen(false);
         },
     });
index 71c0b26..242aaf2 100644 (file)
             </table>
         </div>
     </t>
+    <t t-name="PickingSearchResults">
+        <t t-if="results.length === 0">
+            <div class='oe_search_empty'>
+                No picking found.
+            </div>
+        </t>
+        <t t-if="results.length > 0">
+            <t t-foreach="results" t-as="picking">
+                <div class="oe_picking" t-att-data-id="picking.id">
+                    <span class='oe_picking_name'><t t-esc="picking.name" /></span>
+                </div>
+            </t>
+        </t>
+    </t>
 
     <t t-name="PickingMenuWidget">
         <div class='oe_pick_widget'>
                     <td class='oe_pick_body_cont'> 
                         <div class='oe_pick_body'>
                             <div class='oe_pick_app'>
+
+                                <div class='oe_searchbox'>
+                                    <input type='text' placeholder='Search'/>
+                                </div>
+
                                 <h3 class='oe_pick_app_title'>Pickings</h3>
 
-                                <t t-foreach="widget.picking_types" t-as="type">
-                                    <h4 class='oe_pick_app_subtitle'> <t t-esc="type.name" /> </h4>
-                                    <t t-if="widget.pickings_by_type[type.id].length > 0">
-                                        <span class='oe_pick_button oe_medium js_pick_last' t-att-data-id="type.id">Last Picking</span>
-                                        <span class='oe_pick_button oe_medium js_pick_scan' t-att-data-id="type.id">Scan</span>
-                                    </t>
-                                    <t t-if="widget.pickings_by_type[type.id].length === 0">
-                                        <p class='oe_pick_app_info'>Nothing to process.</p>
+                                <div class='oe_picking_not_found oe_hidden'>
+                                    Scanned picking could not be found
+                                </div>
+
+                                <div class='oe_picking_search_results'>
+                                </div>
+
+                                <div class='oe_picking_categories'>
+                                    <p>
+                                        Select the picking category you want to process.
+                                    </p>
+                                    <t t-foreach="widget.picking_types" t-as="type">
+                                        <div t-att-class="'oe_picking ' + (widget.pickings_by_type[type.id].length === 0 ? 'oe_empty':'js_pick_last') " 
+                                             t-att-data-id="type.id">
+
+                                            <span class='oe_picking_name'><t t-esc="type.name" /></span>
+                                            <t t-if="widget.pickings_by_type[type.id].length === 0">
+                                                <span class='oe_pick_app_info'>Nothing to do</span>
+                                            </t>
+                                        </div>
                                     </t>
-                                </t>
+                                </div>
                             </div>
                         </div>
                     </td>