[WIP]barcode interface, remove extra columns, rework interface, add functionality...
authorCedric Snauwaert <csn@openerp.com>
Fri, 7 Mar 2014 13:25:23 +0000 (14:25 +0100)
committerCedric Snauwaert <csn@openerp.com>
Fri, 7 Mar 2014 13:25:23 +0000 (14:25 +0100)
bzr revid: csn@openerp.com-20140307132523-z0eu9jlvi90baugu

addons/stock/static/src/js/widgets.js
addons/stock/static/src/xml/picking.xml
addons/stock/stock.py
addons/stock/stock_view.xml

index 6110e32..7e347b4 100644 (file)
@@ -54,6 +54,10 @@ function openerp_picking_widgets(instance){
                     });
                 }
             });
+
+            self.rows.sort(function (a,b) {
+                return (b.classes === '') - (a.classes === '');
+            });
             
             return self.rows;
         },
@@ -87,10 +91,10 @@ function openerp_picking_widgets(instance){
             if (query === '') {
                 this.$('.js_pack_op_line.warning').removeClass('warning');
                 this.$('.js_loc').removeClass('info');
-                this.$('.js_pack_op_line.hidden').removeClass('hidden');    
+                this.$('.js_pack_op_line.hidden').removeClass('hidden');
             }
         },
-        get_current_op_selection: function(){
+        get_current_op_selection: function(ignore_container){
             //get ids of visible on the screen
             pack_op_ids = []
             if (this.$('.js_pack_op_line.warning:not(.js_pack_op_line.hidden)').length > 0){
@@ -110,7 +114,7 @@ function openerp_picking_widgets(instance){
             //get list of element in this.rows where rem > 0 and container is empty
             list = []
             _.each(this.rows, function(row){
-                if (row.cols.rem > 0 && row.cols.container === undefined){
+                if (row.cols.rem > 0 && (ignore_container || row.cols.container === undefined)){
                     list.push(row.cols.id);
                 }
             });
@@ -309,11 +313,11 @@ function openerp_picking_widgets(instance){
                     break;
                 }
             }
-            this.$('.oe_picking_not_found').removeClass('hidden');
+            this.$('.js_picking_not_found').removeClass('hidden');
 
             clearTimeout(this.picking_not_found_timeout);
             this.picking_not_found_timeout = setTimeout(function(){
-                self.$('.oe_picking_not_found').addClass('hidden');
+                self.$('.js_picking_not_found').addClass('hidden');
             },2000);
 
         },
@@ -323,19 +327,19 @@ function openerp_picking_widgets(instance){
             clearTimeout(this.searchbox_timeout);
             this.searchbox_timout = setTimeout(function(){
                 if(query){
-                    self.$('.oe_picking_not_found').addClass('hidden');
-                    self.$('.oe_picking_categories').addClass('hidden');
-                    self.$('.oe_picking_search_results').html(
+                    self.$('.js_picking_not_found').addClass('hidden');
+                    self.$('.js_picking_categories').addClass('hidden');
+                    self.$('.js_picking_search_results').html(
                         QWeb.render('PickingSearchResults',{results:self.search_picking(query)})
                     );
-                    self.$('.oe_picking_search_results .oe_picking').click(function(){
+                    self.$('.js_picking_search_results .oe_picking').click(function(){
                         self.goto_picking($(this).data('id'));
                     });
-                    self.$('.oe_picking_search_results').removeClass('hidden');
+                    self.$('.js_picking_search_results').removeClass('hidden');
                 }else{
-                    self.$('.oe_title_label').removeClass('hidden');
-                    self.$('.oe_picking_categories').removeClass('hidden');
-                    self.$('.oe_picking_search_results').addClass('hidden');
+                    self.$('.js_title_label').removeClass('hidden');
+                    self.$('.js_picking_categories').removeClass('hidden');
+                    self.$('.js_picking_search_results').addClass('hidden');
                 }
             },100);
         },
@@ -467,6 +471,7 @@ function openerp_picking_widgets(instance){
 
             this.$('.js_pick_quit').click(function(){ self.quit(); });
             this.$('.js_pick_pack').click(function(){ self.pack(); });
+            this.$('.js_pick_drop_down').click(function(){ self.drop_down();});
             this.$('.js_pick_done').click(function(){ self.done(); });
             this.$('.js_pick_print').click(function(){ self.print_picking(); });
             this.$('.js_pick_prev').click(function(){ self.picking_prev(); });
@@ -479,10 +484,6 @@ function openerp_picking_widgets(instance){
                 self.on_searchbox(''); 
                 self.$('.oe_searchbox').val('');
             });
-            this.$('.js_pack_op_line').click(function(){
-                console.log("click line");
-                $(this).addClass('warning');
-            });
 
             this.hotkey_handler = function(event){
                 if(event.keyCode === 37 ){  // Left Arrow
@@ -497,12 +498,6 @@ function openerp_picking_widgets(instance){
             $.when(this.loaded).done(function(){
                 self.picking_editor = new module.PickingEditorWidget(self);
                 self.picking_editor.replace(self.$('.oe_placeholder_picking_editor'));
-
-                // self.package_editor = new module.PackageEditorWidget(self);
-                // self.package_editor.replace(self.$('.oe_placeholder_package_editor'));
-
-                // self.package_selector = new module.PackageSelectorWidget(self);
-                // self.package_selector.replace(self.$('.oe_placeholder_package_selector'));
                 
                 if( self.picking.id === self.pickings[0]){
                     self.$('.js_pick_prev').addClass('disabled');
@@ -536,8 +531,6 @@ function openerp_picking_widgets(instance){
             return this.load(picking_id)
                 .then(function(){
                     self.picking_editor.renderElement();
-                    // self.package_editor.renderElement();
-                    // self.package_selector.renderElement();
 
                     if( self.picking.id === self.pickings[0]){
                         self.$('.js_pick_prev').addClass('disabled');
@@ -597,7 +590,7 @@ function openerp_picking_widgets(instance){
         },
         pack: function(){
             var self = this;
-            var pack_op_ids = self.picking_editor.get_current_op_selection();
+            var pack_op_ids = self.picking_editor.get_current_op_selection(false);
             if (pack_op_ids.length !== 0){
                 new instance.web.Model('stock.picking')
                     .call('action_pack',[[[self.picking.id]], pack_op_ids])
@@ -607,6 +600,17 @@ function openerp_picking_widgets(instance){
                     });
             }
         },
+        drop_down: function(){
+            var self = this;
+            var pack_op_ids = self.picking_editor.get_current_op_selection(true);
+            if (pack_op_ids.length !== 0){
+                new instance.web.Model('stock.pack.operation')
+                    .call('action_drop_down', [pack_op_ids])
+                    .then(function(){
+                        return self.refresh_ui(self.picking.id);
+                    });
+            }
+        },
         done: function(){
             var self = this;
             new instance.web.Model('stock.picking')
index ad48c70..65c6716 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <templates id="template" xml:space="preserve">
 
-    <t t-name="TactileListWidget">
+    <!-- <t t-name="TactileListWidget">
         <div class='oe_tactlist js_width' t-att-style="'width:' + widget.get_width() + 'px'">
             <div class='oe_tactlist_header'>
                 <t t-esc='widget.get_title()' />
@@ -44,7 +44,7 @@
                 <span class='oe_hresizer js_hresizer'>●</span>
             </div>
         </div>
-    </t>
+    </t> -->
 
     <t t-name='PickingEditorWidget'>
         <div class='oe_pick_list'>
             <table class='table table-condensed'>
                 <thead>
                     <tr>
-                        <th>Product</th> 
-                        <th class='text-center'>Total Qty</th> 
-                        <th class='text-center'>Qty done</th> 
-                        <th>Source Location</th>
-                        <th>Destination Location</th>
-                        <th>Lot</th>
-                        <th>Pack</th> 
-                        <th>Container</th>
-                        <th>Scan</th>
+                        <th class="text-center">Product</th> 
+                        <th class='text-center'>Quantity</th> 
+                        <th>From</th>
+                        <th>To</th>
                     </tr>
                 </thead>
 
                 <tbody>
                     <t t-foreach="widget.get_rows()" t-as="row">
                         <tr t-att-class="row.classes + ' js_pack_op_line'" t-att-data-id="row.cols.id">
-                            <td> <t t-esc="row.cols.product" /> </td>
-                            <td class='text-center'> <t t-esc="row.cols.qty" /> <t t-esc="row.cols.uom" /> </td>
-                            <td class='js_qty_rem text-center'> <t t-esc="row.cols.rem" /> </td>
-                            <td class="js_loc"> <t t-esc="row.cols.loc" /> </td>
+                            <td> <span class='btn btn-default js_pack_scan' t-att-op-id='row.cols.product_id'>➔</span> <t t-esc="row.cols.product" /> </td>
+                            <td class='text-center'><t t-esc="row.cols.rem" /> / <t t-esc="row.cols.qty" /> <t t-esc="row.cols.uom" /></td>
+                            <td class="js_loc"> <t t-esc="row.cols.loc" />
+                            <t t-if="row.cols.lot" ><span> : <t t-esc="row.cols.lot" /></span></t>
+                            <t t-if="row.cols.pack" ><span> : <t t-esc="row.cols.pack" /></span></t>
+                             </td>
                             <td class="js_loc"> <t t-esc="row.cols.dest" /> </td>
-                            <td> <t t-esc="row.cols.lot" /> </td>
-                            <td> <t t-esc="row.cols.pack" /> </td>
-                            <td class="js_container"> <t t-esc="row.cols.container" /> </td>
-                            <td><span class='btn btn-default js_pack_scan' t-att-op-id='row.cols.product_id'>➔</span></td>
                         </tr>
                     </t>
                 </tbody>
         </div>
     </t>
 
-    <t t-name='PackageEditorWidget'>
-        <div class='oe_pick_list'>
-            <h2><strong><div class='oe_pick_list_header'> <t t-esc="widget.get_header()" /> </div></strong></h2>
-            <table class='table table-striped'>
-
-                <thead>
-                    <tr>
-                        <th>Product</th> 
-                        <th class='text-center'>Qty</th> 
-                        <th class='text-center'>UoM</th> 
-                    </tr>
-                </thead>
-
-                <tbody>
-                    <t t-foreach="widget.get_rows()" t-as="row">
-                        <tr t-att-class="row.classes" t-att-op-id="row.att_op_id">
-                            <td> <t t-esc="row.cols.product" /> </td>
-                            <td class='qty text-center'> <t t-esc="row.cols.qty" /> </td>
-                            <td class='text-center'> <t t-esc="row.cols.uom" /> </td>
-                        </tr>
-                    </t>
-                </tbody>
-
-            </table>
-        </div>
-    </t>
-
-    <t t-name='PackageSelectorWidget'>
-        <div class='oe_pick_list'>
-            <h2><strong><div class='oe_pick_list_header'><t t-esc="widget.get_header()" /></div></strong></h2>
-            <table class='table table-striped'>
-
-                <thead>
-                    <tr>
-                        <th>Package</th> <th></th>
-                    </tr>
-                </thead>
-
-                <tbody>
-                    <t t-foreach="widget.get_rows()" t-as="row">
-                        <tr t-att-class="'js_pack_row' + row.classes" t-att-pack-id="row.id">
-                            <td class='js_pack_select col-md-8'> <t t-esc="row.cols.pack" /> </td>
-                            <td class='text-right col-md-4'> 
-                                <div class='btn btn-default js_pack_print'>Print</div>
-                                <div class='btn btn-default js_pack_plus'>Copy</div>
-                                <div class='btn btn-default js_pack_minus'>Delete</div>
-
-                            </td>
-                        </tr>
-                    </t>
-                </tbody>
-
-            </table>
-        </div>
-    </t>
     <t t-name="PickingSearchResults">
         <div class="panel-heading">
             <h3 class="panel-title">Search Results</h3>
         <div class="navbar navbar-inverse navbar-static-top" role="navigation">
             <div class="container">
                 <!-- <div class="navbar-header navbar-form"> -->
-                    <div class="navbar-header navbar-form navbar-left">
+                <div class="navbar-header navbar-form navbar-left">
                     <input type='text' class="oe_searchbox form-control pull-left" placeholder='Search'/>
                 </div>
                 <div class="navbar-header navbar-form navbar-right">
                     <!-- <div class='form-group'> -->
                         <button type="button" class="btn btn-danger js_pick_quit pull-right">Quit</button>
-                    </div>
-                    
                 </div>
+                    
+            </div>
             <!-- </div> -->
         </div>
         <div class="container">
-            <div class="row">
-                <div class="col-md-12">
-                    <h2 class="oe_title_label">Pickings</h2>
-                    <div class='oe_picking_not_found alert alert-warning hidden'>
-                        Scanned picking could not be found
-                    </div>
-
-                    <div class='oe_picking_search_results panel panel-info'>
-                    </div>
+            
+            <h1 class="js_title_label">Select your operation</h1>
+            <div class='js_picking_not_found alert alert-warning hidden'>
+                Scanned picking could not be found
+            </div>
 
-                    <div class='oe_picking_categories'>
-                        <p>
-                            Select the type of picking you want to process.
-                        </p>
-                    </div>
-                </div>
+            <div class='js_picking_search_results panel panel-info hidden'>
             </div>
-            <div class="row oe_picking_categories">
+            
+            <div class="row js_picking_categories">
                 <t t-foreach="widget.picking_types" t-as="type">
                     <div class="col-lg-3 col-md-4">
                         <div t-att-class="'oe_kanban oe_picking oe_kanban_color_' + type.color + ' ' + (widget.pickings_by_type[type.id].length === 0 ? 'oe_empty':'js_pick_last') " 
                             <button type="button" class='btn btn-info js_pick_print'> Print </button>
                     </div>
                     <h2 class="oe_pick_app_header" t-esc='widget.get_header()' />
-                    <input type='text' class="oe_searchbox align-left" placeholder='Filter by location...'/>
-                    <button type='button' class='btn btn-default js_clear_search'>Clear</button>
+                    <div class="input-group col-md-2">
+                        <input type="text" class="form-control oe_searchbox" placeholder="Filter by location..."/>
+                        <span class="input-group-btn">
+                            <button class="btn btn-danger js_clear_search" type="button">x</button>
+                        </span>
+                    </div>
                     <button type="button" class='btn btn-default js_pick_pack pull-right'> Put in Pack </button>
+                    <button type="button" class="btn btn-default js_pick_drop_down pull-right"> Drop Down </button>
                     <div class='oe_placeholder_picking_editor'/>
-                    
-                    <!-- <div class='oe_placeholder_package_editor'></div> -->
                 </div>
-                <!-- <div class="col-md-4">
-                    <div class='oe_placeholder_package_selector'></div>
-                </div> -->
             </div>
         </div>
     </t>
index 1f0803b..82879e8 100644 (file)
@@ -3600,6 +3600,21 @@ class stock_pack_operation(osv.osv):
                     if qty > 0:
                         _create_link_for_product(product_id, qty)
 
+    def action_drop_down(self, cr, uid, ids, context=None):
+        ''' Used by barcode interface to say that pack_operation has been moved from src location 
+            to destination location, if qty_done is less than product_qty than we have to split the
+            operation in two to process the one with the qty moved
+        '''
+        processed_ids = []
+        for pack_op in self.browse(cr, uid, ids, context=None):
+            op = pack_op.id
+            if pack_op.qty_done < pack_op.product_qty:
+                # we split the operation in two
+                op = self.copy(cr, uid, pack_op.id, {'product_qty': pack_op.qty_done, 'qty_done': pack_op.qty_done}, context=context)
+                self.write(cr, uid, ids, {'product_qty': pack_op.product_qty - pack_op.qty_done, 'qty_done': 0}, context=context)
+            processed_ids.append(op)      
+        self.write(cr, uid, processed_ids, {'processed': 'true'}, context=context)
+
     def process_packaging(self, cr, uid, operation, quants, context=None):
         ''' Process the packaging of a given operation, after the quants have been moved. If there was not enough quants found
         a quant already has been with the good package information so we don't consider that case in this method'''
index 61002d8..ffa3d6d 100644 (file)
                                 </group>
                             </group>
                             <field name="pack_operation_ids" attrs="{'invisible': [('pack_operation_exist', '=', False)]}" context="{'default_owner_id': owner_id}">
-                                <tree editable="top">   
+                                <tree editable="top" colors="grey:processed=='true'">
+                                    <field name="processed" invisible="1"/>   
                                     <field name="location_id"/>
                                     <field name="product_id" on_change='product_id_change(product_id, product_uom_id, product_qty, context)'/>
                                     <field name="product_uom_id" groups="product.group_uom" on_change='on_change_tests(product_id, product_uom_id, product_qty, context)'/>
                                     <field name="package_id" groups="stock.group_tracking_lot"/>
                                     <field name="owner_id" groups="stock.group_tracking_owner"/>
                                     <field name="product_qty" attrs="{'required': [('product_id', '!=', False)]}" on_change='on_change_tests(product_id, product_uom_id, product_qty, context)'/>
+                                    <field name="qty_done"/>
                                     <field name="location_dest_id"/>
                                     <field name="result_package_id" groups="stock.group_tracking_lot"/>
                                 </tree>