[FIX]stock_barcode_interface: add button to recompute pack_op when state of move...
authorCedric Snauwaert <csn@openerp.com>
Fri, 28 Mar 2014 10:49:06 +0000 (11:49 +0100)
committerCedric Snauwaert <csn@openerp.com>
Fri, 28 Mar 2014 10:49:06 +0000 (11:49 +0100)
bzr revid: csn@openerp.com-20140328104906-d8pebnlwlpdf4x10

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

index 756d3ca..8bb36bd 100644 (file)
@@ -534,7 +534,6 @@ function openerp_picking_widgets(instance){
             this.picking = null;
             this.pickings = [];
             this.packoplines = null;
-            this.operations = null;
             this.selected_operation = { id: null, picking_id: null};
             this.packages = null;
             this.barcode_scanner = new module.BarcodeScanner();
@@ -604,20 +603,22 @@ function openerp_picking_widgets(instance){
             }
 
             return loaded_picking.then(function(){
-                    new instance.web.Model('stock.location').call('search',[[['usage','=','internal']]]).then(function(locations_ids){
+                    return new instance.web.Model('stock.location').call('search',[[['usage','=','internal']]]).then(function(locations_ids){
                         return new instance.web.Model('stock.location').call('read',[locations_ids, []]).then(function(locations){
                             self.locations = locations;
                         });
                     });
                 }).then(function(){
-
-                    return new instance.web.Model('stock.pack.operation').call('read',[self.picking.pack_operation_ids, [], new instance.web.CompoundContext()]);
-                }).then(function(packoplines){
-                    self.packoplines = packoplines;
-
-                    return new instance.web.Model('stock.pack.operation').call('read',[self.picking.pack_operation_ids, [], new instance.web.CompoundContext()]);
+                    if (self.picking.pack_operation_exist === false){
+                        self.picking.recompute_pack_op = false;
+                        return new instance.web.Model('stock.picking').call('do_prepare_partial',[[self.picking.id]]);
+                    }
+                }).then(function(){
+                        return new instance.web.Model('stock.pack.operation').call('search',[[['picking_id','=',self.picking.id]]])
+                }).then(function(pack_op_ids){
+                        return new instance.web.Model('stock.pack.operation').call('read',[pack_op_ids, [], new instance.web.CompoundContext()])
                 }).then(function(operations){
-                    self.operations = operations;
+                    self.packoplines = operations;
                     var package_ids = [];
 
                     for(var i = 0; i < operations.length; i++){
@@ -627,7 +628,7 @@ function openerp_picking_widgets(instance){
                             }
                         }
                     }
-                    return new instance.web.Model('stock.quant.package').call('read',[package_ids, [], new instance.web.CompoundContext()]);
+                    return new instance.web.Model('stock.quant.package').call('read',[package_ids, [], new instance.web.CompoundContext()])
                 }).then(function(packages){
                     self.packages = packages;
                 });
@@ -644,6 +645,7 @@ function openerp_picking_widgets(instance){
             this.$('.js_pick_prev').click(function(){ self.picking_prev(); });
             this.$('.js_pick_next').click(function(){ self.picking_next(); });
             this.$('.js_pick_menu').click(function(){ self.menu(); });
+            this.$('.js_reload_op').click(function(){ self.reload_pack_operation();});
 
             this.hotkey_handler = function(event){
                 if(event.keyCode === 37 ){  // Left Arrow
@@ -670,6 +672,12 @@ function openerp_picking_widgets(instance){
                 }else{
                     self.$('.js_pick_next').removeClass('disabled');
                 }
+                if (self.picking.recompute_pack_op){
+                    self.$('.js_reload_op').removeClass('hidden');
+                }
+                else {
+                    self.$('.js_reload_op').addClass('hidden');
+                }
 
             }).fail(function(error) {console.log(error);});
 
@@ -691,6 +699,13 @@ function openerp_picking_widgets(instance){
                     self.picking_editor.remove_blink();
                     self.picking_editor.renderElement();
 
+                    if (self.picking.recompute_pack_op){
+                        self.$('.js_reload_op').removeClass('hidden');
+                    }
+                    else {
+                        self.$('.js_reload_op').addClass('hidden');
+                    }
+
                     if( self.picking.id === self.pickings[0]){
                         self.$('.js_pick_prev').addClass('disabled');
                     }else{
@@ -886,6 +901,14 @@ function openerp_picking_widgets(instance){
             }
 
         },
+        reload_pack_operation: function(){
+            var self = this;
+            new instance.web.Model('stock.picking')
+                .call('do_prepare_partial',[[self.picking.id]])
+                .then(function(){
+                    self.refresh_ui(self.picking.id);
+                });
+        },
         quit: function(){
             this.destroy();
             return new instance.web.Model("ir.model.data").get_func("search_read")([['name', '=', 'action_picking_type_form']], ['res_id']).pipe(function(res) {
index 0e2e865..9bdab1e 100644 (file)
@@ -1,51 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <templates id="template" xml:space="preserve">
 
-    <!-- <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()' />
-            </div>
-
-            <div class='oe_scrolltable js_height' t-att-style="'height:' + widget.get_height() + 'px'">
-                <div class='oe_scrolltable_scroll'>
-                    <div class='oe_scrolltable_header_container js_innerwidth' t-att-style="'width:' + widget.get_innerwidth() + 'px'">
-                        <table class='oe_scrolltable_header js_innerwidth' >
-                            <tbody>
-                                <tr>
-                                    <t t-foreach="widget.get_collumns()" t-as="col">
-                                        <td t-att-class="col.classes">
-                                            <t t-esc="col.header" />
-                                        </td>
-                                    </t>
-                                </tr>
-                            </tbody>
-                        </table>
-                    </div>
-                    <table class='oe_scrolltable_body js_innerwidth' t-att-style="'width:' + widget.get_innerwidth() + 'px'">
-                        <colgroup>
-                            <t t-foreach="widget.get_collumns()" t-as="col">
-                                <col t-att-class="col.classes"></col>
-                            </t>
-                        </colgroup>
-                        <tbody>
-                            <t t-foreach="widget.get_rows()" t-as="row">
-                                <tr t-att-class="row.classes">
-                                    <t t-foreach="row.cols" t-as="col">
-                                        <td><t t-esc="col" /></td> 
-                                    </t>
-                                </tr>
-                            </t>
-                        </tbody>
-                    </table>
-                </div>
-            </div>
-            <div class='oe_vresizer js_vresizer'>
-                <span class='oe_hresizer js_hresizer'>●</span>
-            </div>
-        </div>
-    </t> -->
-
     <t t-name='PickingEditorWidget'>
         
         <div class="modal fade" id="js_LocationChooseModal" tabindex="-1" role="dialog" aria-labelledby="LocationChooseModal" aria-hidden="true">
                                      <span class="caret"></span>
                                     </button>
                                     <ul class="dropdown-menu" role="menu">
-                                        <!-- <t t-if="!row.cols.lot &amp;&amp; row.cols.product_id">
+                                        <t t-if="!row.cols.lot &amp;&amp; row.cols.product_id">
                                             <li><a class="js_create_lot" href="#">Create Lot</a></li>
-                                        </t> -->
+                                        </t>
                                         <t t-if="!row.cols.head_container &amp;&amp; !row.cols.container">
                                             <li><a class="js_change_src" href="#">Change source location</a></li>
                                             <li><a class="js_change_dst" href="#">Change destination location</a></li>
 
         <div class="container">
             <div class='oe_placeholder_picking_editor'/>
+            <div class="text-center">
+                <button class="btn btn-default js_reload_op">Recompute operations</button>
+            </div>
         </div>
     </t>
 
index bd8f7be..546c71e 100644 (file)
@@ -329,6 +329,9 @@ class stock_quant(osv.osv):
         #reserve quants
         if toreserve:
             self.write(cr, SUPERUSER_ID, toreserve, {'reservation_id': move.id}, context=context)
+            #if move has a picking_id, write on that picking that pack_operation might have change and need to be recompute
+            if move.picking_id:
+                self.pool.get('stock.picking').write(cr, uid, [move.picking_id.id], {'recompute_pack_op':True}, context=context)
         #check if move'state needs to be set as 'assigned'
         if reserved_availability == move.product_qty and move.state in ('confirmed', 'waiting'):
             self.pool.get('stock.move').write(cr, uid, [move.id], {'state': 'assigned'}, context=context)
@@ -534,6 +537,9 @@ class stock_quant(osv.osv):
     def quants_unreserve(self, cr, uid, move, context=None):
         related_quants = [x.id for x in move.reserved_quant_ids]
         if related_quants:
+            #if move has a picking_id, write on that picking that pack_operation might have change and need to be recompute
+            if move.picking_id:
+                self.pool.get('stock.picking').write(cr, uid, [move.picking_id.id], {'recompute_pack_op':True}, context=context)
             if move.partially_available:
                 self.pool.get("stock.move").write(cr, uid, [move.id], {'partially_available': False}, context=context)
             return self.write(cr, SUPERUSER_ID, related_quants, {'reservation_id': False}, context=context)
@@ -774,6 +780,7 @@ class stock_picking(osv.osv):
         'owner_id': fields.many2one('res.partner', 'Owner', states={'done': [('readonly', True)], 'cancel': [('readonly', True)]}, help="Default Owner"),
         # Used to search on pickings
         'product_id': fields.related('move_lines', 'product_id', type='many2one', relation='product.product', string='Product'),
+        'recompute_pack_op': fields.boolean('Recompute pack operation?', help='True if quants has changed and we might need to recompute the package operations'),
         'location_id': fields.related('move_lines', 'location_id', type='many2one', relation='stock.location', string='Location', readonly=True),
         'location_dest_id': fields.related('move_lines', 'location_dest_id', type='many2one', relation='stock.location', string='Destination Location', readonly=True),
         'group_id': fields.related('move_lines', 'group_id', type='many2one', relation='procurement.group', string='Procurement Group', readonly=True,
@@ -789,7 +796,8 @@ class stock_picking(osv.osv):
         'move_type': 'one',
         'priority': '1',  # normal
         'date': fields.datetime.now,
-        'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.picking', context=c)
+        'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.picking', context=c),
+        'recompute_pack_op': True,
     }
     _sql_constraints = [
         ('name_uniq', 'unique(name, company_id)', 'Reference must be unique per company!'),
@@ -866,6 +874,8 @@ class stock_picking(osv.osv):
         for pick in self.browse(cr, uid, ids, context=context):
             move_ids = [x.id for x in pick.move_lines if x.state in ['confirmed', 'waiting']]
             self.pool.get('stock.move').force_assign(cr, uid, move_ids, context=context)
+        #pack_operation might have change and need to be recompute
+        self.write(cr, uid, ids, {'recompute_pack_op':True}, context=context)
         return True
 
     def action_cancel(self, cr, uid, ids, context=None):
@@ -1069,7 +1079,7 @@ class stock_picking(osv.osv):
                 'product_uom_id': self.pool.get("product.product").browse(cr, uid, key[0], context=context).uom_id.id,
             })
         return vals
-    
+
     def open_barcode_interface(self, cr, uid, picking_ids, context=None):
         final_url="/barcode/web/#action=stock.ui&picking_id="+str(picking_ids[0])
         return {'type': 'ir.actions.act_url', 'url':final_url, 'target': 'self',}
@@ -1109,6 +1119,7 @@ class stock_picking(osv.osv):
                 pack_operation_obj.create(cr, uid, vals, context=ctx)
         #recompute the remaining quantities all at once
         self.do_recompute_remaining_quantities(cr, uid, picking_ids, context=context)
+        self.write(cr, uid, picking_ids, {'recompute_pack_op':False}, context=context)
 
     def do_unreserve(self, cr, uid, picking_ids, context=None):
         """
@@ -1729,6 +1740,7 @@ class stock_move(osv.osv):
         default['reserved_quant_ids'] = []
         default['returned_move_ids'] = []
         default['linked_move_operation_ids'] = []
+        default['partially_available'] = False
         if not default.get('origin_returned_move_id'):
             default['origin_returned_move_id'] = False
         default['state'] = 'draft'
index 2a7673e..4260a6e 100644 (file)
                 <form string="Transfer" version="7.0">
                 <header>
                     <button name="action_confirm" states="draft" string="Mark as Todo" type="object" class="oe_highlight" groups="base.group_user"/>
-                    <button name="action_assign" states="confirmed" string="Check Availability" type="object" class="oe_highlight" groups="base.group_user"/>
+                    <button name="action_assign" states="confirmed,partially_available" string="Check Availability" type="object" class="oe_highlight" groups="base.group_user"/>
                     <button name="force_assign" states="confirmed,partially_available" string="Force Availability" type="object" class="oe_highlight" groups="base.group_user"/>
                     <button name="do_transfer" states="assigned" string="Transfer" groups="stock.group_stock_user" type="object" class="oe_highlight" attrs="{'invisible': ['|', ('pack_operation_exist', '=', True)]}"/>
                     <button name="do_partial_open_barcode" string="Enter Transfer Details" groups="stock.group_stock_user" type="object" class="oe_highlight" attrs="{'invisible': ['|',('pack_operation_exist', '=', True),('state','not in',('assigned', 'partially_available'))]}"/>