Rohan Nayani(Open ERP) has proposed merging 
lp:~openerp-dev/openobject-addons/trunk-bug-751222-ron into 
lp:openobject-addons.

Requested reviews:
  Rohan Nayani(Open ERP) (ron-tinyerp)
  qdp (OpenERP) (qdp)
  Rucha (Open ERP) (rpa-openerp)
Related bugs:
  Bug #751222 in OpenERP Addons: "[6.0 - trunk] partial stock move wizard bugs 
: uom, new lines, production lot attrs"
  https://bugs.launchpad.net/openobject-addons/+bug/751222

For more details, see:
https://code.launchpad.net/~openerp-dev/openobject-addons/trunk-bug-751222-ron/+merge/57112

https://bugs.launchpad.net/openobject-addons/+bug/751222
-- 
https://code.launchpad.net/~openerp-dev/openobject-addons/trunk-bug-751222-ron/+merge/57112
Your team OpenERP R&D Team is subscribed to branch 
lp:~openerp-dev/openobject-addons/trunk-bug-751222-ron.
=== modified file 'stock/stock.py'
--- stock/stock.py	2011-10-11 14:03:35 +0000
+++ stock/stock.py	2011-11-08 13:52:58 +0000
@@ -1167,10 +1167,8 @@
         wf_service = netsvc.LocalService("workflow")
         for pick in self.browse(cr, uid, ids, context=context):
             new_picking = None
-            complete, too_many, too_few = [], [], []
-            move_product_qty = {}
-            prodlot_ids = {}
-            product_avail = {}
+            complete, too_few = [], []
+            move_product_qty,prodlot_ids, product_uoms, product_avail, partial_qty = {}, {}, {}, {}, {}
             for move in pick.move_lines:
                 if move.state in ('done', 'cancel'):
                     continue
@@ -1182,13 +1180,12 @@
                 product_currency = partial_data.get('product_currency',False)
                 prodlot_id = partial_data.get('prodlot_id')
                 prodlot_ids[move.id] = prodlot_id
-                if move.product_qty == product_qty:
+                product_uoms[move.id] = product_uom
+                partial_qty[move.id] = uom_obj._compute_qty(cr, uid, product_uoms[move.id], product_qty, move.product_uom.id)
+                if move.product_qty == partial_qty[move.id]:
                     complete.append(move)
-                elif move.product_qty > product_qty:
+                else:
                     too_few.append(move)
-                else:
-                    too_many.append(move)
-
                 # Average price computation
                 if (pick.type == 'in') and (move.product_id.cost_method == 'average'):
                     product = product_obj.browse(cr, uid, move.product_id.id)
@@ -1224,8 +1221,9 @@
 
 
             for move in too_few:
+                if move.product_qty < partial_qty[move.id]:
+                    raise osv.except_osv(_('Error !'), _('You cannot select Quantity %s  more then Picking Quantity %s.') % (partial_qty[move.id],move.product_qty,))
                 product_qty = move_product_qty[move.id]
-
                 if not new_picking:
                     new_picking = self.copy(cr, uid, pick.id,
                             {
@@ -1241,36 +1239,26 @@
                             'state': 'assigned',
                             'move_dest_id': False,
                             'price_unit': move.price_unit,
+                            'product_uom':product_uoms[move.id],
                     }
                     prodlot_id = prodlot_ids[move.id]
                     if prodlot_id:
                         defaults.update(prodlot_id=prodlot_id)
                     move_obj.copy(cr, uid, move.id, defaults)
-
                 move_obj.write(cr, uid, [move.id],
                         {
-                            'product_qty' : move.product_qty - product_qty,
-                            'product_uos_qty':move.product_qty - product_qty, #TODO: put correct uos_qty
+                            'product_qty' : move.product_qty - partial_qty[move.id],
+                            'product_uos_qty':move.product_qty - partial_qty[move.id], #TODO: put correct uos_qty
                         })
 
             if new_picking:
                 move_obj.write(cr, uid, [c.id for c in complete], {'picking_id': new_picking})
             for move in complete:
-                if prodlot_ids.get(move.id):
-                    move_obj.write(cr, uid, [move.id], {'prodlot_id': prodlot_ids[move.id]})
-            for move in too_many:
                 product_qty = move_product_qty[move.id]
-                defaults = {
-                    'product_qty' : product_qty,
-                    'product_uos_qty': product_qty, #TODO: put correct uos_qty
-                }
-                prodlot_id = prodlot_ids.get(move.id)
+                defaults = {'product_uom': product_uoms[move.id],'product_qty': product_qty}
                 if prodlot_ids.get(move.id):
-                    defaults.update(prodlot_id=prodlot_id)
-                if new_picking:
-                    defaults.update(picking_id=new_picking)
-                move_obj.write(cr, uid, [move.id], defaults)
-
+                    defaults.update({'prodlot_id': prodlot_ids[move.id]})
+                move_obj.write(cr, uid, move.id, defaults)
 
             # At first we confirm the new picking (if necessary)
             if new_picking:

=== modified file 'stock/wizard/stock_partial_move.py'
--- stock/wizard/stock_partial_move.py	2011-10-02 17:31:16 +0000
+++ stock/wizard/stock_partial_move.py	2011-11-08 13:52:58 +0000
@@ -23,11 +23,30 @@
 from tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
 import time
 
-class stock_partial_move_line(osv.osv_memory):
-    _inherit = "stock.partial.picking.line"
-    _name = "stock.partial.move.line"
+class stock_partial_move_memory_out(osv.osv_memory):
+
+    def _tracking(self, cursor, user, ids, name, arg, context=None):
+        res = {}
+        for tracklot in self.browse(cursor, user, ids, context=context):
+            tracking = False
+            if (tracklot.move_id.picking_id.type == 'in' and tracklot.product_id.track_incoming == True) or \
+                (tracklot.move_id.picking_id.type == 'out' and tracklot.product_id.track_outgoing == True):
+                tracking = True
+            res[tracklot.id] = tracking
+        return res
+    
+    _name = "stock.move.memory.out"
+    _rec_name = 'product_id'
     _columns = {
-        'wizard_id' : fields.many2one('stock.partial.move', string="Wizard", ondelete='CASCADE'),
+        'product_id' : fields.many2one('product.product', string="Product", required=True, readonly=True),
+        'quantity' : fields.float("Quantity", required=True),
+        'product_uom': fields.many2one('product.uom', 'Unit of Measure', required=True),
+        'prodlot_id' : fields.many2one('stock.production.lot', 'Production Lot'),
+        'move_id' : fields.many2one('stock.move', "Move"),
+        'wizard_id' : fields.many2one('stock.partial.move', string="Wizard"),
+        'cost' : fields.float("Cost", help="Unit Cost for this product line per Unit of Measure"),
+        'currency' : fields.many2one('res.currency', string="Currency", help="Currency in which Unit cost is expressed"),
+        'tracking': fields.function(_tracking, method=True, string='Tracking', type='boolean'), 
     }
 
 class stock_partial_move(osv.osv_memory):

=== modified file 'stock/wizard/stock_partial_move_view.xml'
--- stock/wizard/stock_partial_move_view.xml	2011-10-02 17:31:16 +0000
+++ stock/wizard/stock_partial_move_view.xml	2011-11-08 13:52:58 +0000
@@ -16,39 +16,20 @@
             <field eval="True" name="object"/>
         </record>
 
-        <record id="stock_partial_move_form" model="ir.ui.view">
-            <field name="name">stock.partial.move.form</field>
-            <field name="model">stock.partial.move</field>
-            <field name="type">form</field>
-            <field name="arch" type="xml">
-                <form>
-                    <separator colspan="4" string="Products"/>
-                    <field name="move_ids" colspan="4" nolabel="1" mode="tree,form" width="550" height="200"/>
-                    <separator string="" colspan="4" />
-                    <label string="" colspan="2"/>
-                    <group col="2" colspan="2">
-                        <button icon='gtk-cancel' special="cancel" string="_Cancel" />
-                        <button name="do_partial" string="_Validate" colspan="1" type="object" icon="gtk-go-forward" />
-                    </group>
-                </form>
-            </field>
-        </record>
-
-        <record id="stock_partial_move_line_list" model="ir.ui.view">
-            <field name="name">stock.partial.move.line.list</field>
-            <field name="model">stock.partial.move.line</field>
+        
+        <record id="stock_move_memory_tree_in" model="ir.ui.view">
+            <field name="name">stock.move.memory.tree</field>
+            <field name="model">stock.move.memory.in</field>
             <field name="type">tree</field>
             <field name="arch" type="xml">
                 <tree editable="bottom" string="Product Moves">
                     <field name="product_id" />
                     <field name="quantity" />
                     <field name="product_uom" />
-                    <field name="location_id" />
-                    <field name="location_dest_id" />
-                    <field name="prodlot_id" domain="[('product_id', '=', product_id)]" groups="base.group_extended" />
-                    <field name="update_cost" invisible="1"/>
-                    <field name="cost" attrs="{'invisible': [('update_cost','=', False)]}"/>
-                    <field name="currency" attrs="{'invisible': [('update_cost','=', False)]}"/>
+                    <field name="prodlot_id" domain="[('product_id', '=', product_id)]" groups="base.group_extended" attrs="{'required':[('tracking','=',True)]}"/>
+                    <field name="tracking" invisible="1"/>
+                    <field name="cost" />
+                    <field name="currency" />
                 </tree>
             </field>
         </record>
@@ -62,14 +43,43 @@
                     <field name="product_id" />
                     <field name="quantity" />
                     <field name="product_uom" />
-                    <field name="location_id" />
-                    <field name="location_dest_id" />
-                    <field name="prodlot_id" domain="[('product_id', '=', product_id)]" groups="base.group_extended" />
-                    <field name="update_cost" invisible="1"/>
-                    <field name="cost" attrs="{'invisible': [('update_cost','=', False)]}"/>
-                    <field name="currency" attrs="{'invisible': [('update_cost','=', False)]}"/>
+                    <field name="prodlot_id" domain="[('product_id', '=', product_id)]" attrs="{'required':[('tracking','=',True)]}" groups="base.group_extended" />
+                    <field name="tracking" invisible="1"/>
+                    <field name="cost" />
+                    <field name="currency" />
                  </form>
             </field>
+        </record>   
+        
+        <record id="stock_move_memory_tree_out" model="ir.ui.view">
+            <field name="name">stock.move.memory.tree</field>
+            <field name="model">stock.move.memory.out</field>
+            <field name="type">tree</field>
+            <field name="arch" type="xml">
+                <tree editable="bottom" string="Product Moves">
+                    <field name="product_id" />
+                    <field name="quantity" />
+                    <field name="product_uom" />
+                    <field name="prodlot_id" domain="[('product_id', '=', product_id)]" groups="base.group_extended" attrs="{'required':[('tracking','=',True)]}"/>
+                    <field name="tracking" invisible="1"/>
+                </tree>
+            </field>
         </record>
+        
+        <record id="stock_move_memory_form_out" model="ir.ui.view">
+            <field name="name">stock.move.memory.form</field>
+            <field name="model">stock.move.memory.out</field>
+            <field name="type">form</field>
+            <field name="arch" type="xml">
+                <form>
+                    <field name="product_id" />
+                    <field name="quantity" />
+                    <field name="product_uom" />
+                    <field name="prodlot_id" domain="[('product_id', '=', product_id)]" attrs="{'required':[('tracking','=',True)]}" groups="base.group_extended" />
+                    <field name="tracking" invisible="1"/>
+                </form>
+            </field>
+        </record>  
+        
     </data>
 </openerp>

=== modified file 'stock/wizard/stock_partial_picking.py'
--- stock/wizard/stock_partial_picking.py	2011-10-20 10:21:26 +0000
+++ stock/wizard/stock_partial_picking.py	2011-11-08 13:52:58 +0000
@@ -100,38 +100,59 @@
         return partial_move
 
     def do_partial(self, cr, uid, ids, context=None):
-        assert len(ids) == 1, 'Partial picking processing may only be done one at a time'
-        stock_picking = self.pool.get('stock.picking')
-        stock_move = self.pool.get('stock.move')
+        """ Makes partial moves and pickings done.
+        @param self: The object pointer.
+        @param cr: A database cursor
+        @param uid: ID of the user currently logged in
+        @param fields: List of fields for which we want default values
+        @param context: A standard dictionary
+        @return: A dictionary which of fields with values.
+        """
+        pick_obj = self.pool.get('stock.picking')
+        uom_obj = self.pool.get('product.uom')
+        
+        picking_ids = context.get('active_ids', False)
         partial = self.browse(cr, uid, ids[0], context=context)
         partial_data = {
             'delivery_date' : partial.date
         }
-        picking_type = partial.picking_id.type
-        for move in partial.move_ids:
-            move_id = move.move_id.id
-            if not move_id:
-                seq_obj_name =  'stock.picking.' + picking_type
-                move_id = stock_move.create(cr,uid,{'name' : self.pool.get('ir.sequence').get(cr, uid, seq_obj_name),
-                                                    'product_id': move.product_id.id,
-                                                    'product_qty': move.quantity,
-                                                    'product_uom': move.product_uom.id,
-                                                    'prodlot_id': move.prodlot_id.id,
-                                                    'location_id' : move.location_id.id,
-                                                    'location_dest_id' : move.location_dest_id.id,
-                                                    'picking_id': partial.picking_id.id
-                                                    },context=context)
-                stock_move.action_done(cr, uid, [move_id], context)
-            partial_data['move%s' % (move_id)] = {
-                'product_id': move.product_id.id,
-                'product_qty': move.quantity,
-                'product_uom': move.product_uom.id,
-                'prodlot_id': move.prodlot_id.id,
-            }
-            if (picking_type == 'in') and (move.product_id.cost_method == 'average'):
-                partial_data['move%s' % (move.move_id.id)].update(product_price=move.cost,
-                                                                  product_currency=move.currency.id)
-        stock_picking.do_partial(cr, uid, [partial.picking_id.id], partial_data, context=context)
+
+        for pick in pick_obj.browse(cr, uid, picking_ids, context=context):
+            picking_type = self.get_picking_type(cr, uid, pick, context=context)
+            moves_list = picking_type == 'in' and partial.product_moves_in or partial.product_moves_out
+            for move in moves_list:
+                move_uom = move.move_id.product_uom
+                process_uom = move.product_uom
+                #Quantiny must be Positive
+                if move.quantity <= 0:
+                    raise osv.except_osv(_('Warning!'), _('Please provide Proper Quantity !'))
+
+                #category id must be same for respective move
+                if move_uom.category_id.id != process_uom.category_id.id:
+                    raise osv.except_osv(_('Warning'), _('You can not process %s %s as it\'s category is different than category of %s of this move!') % (move.quantity, process_uom.name, move_uom.name))
+
+                #Pikcing move product UOM factor must be bigger with respective wizard move product uom factor
+                if move_uom.factor < process_uom.factor:
+                    raise osv.except_osv(_('Warning'), _('You can not process in UOM "%s" which is smaller than UOM "%s" of the current move.') % (process_uom.name, move_uom.name))
+
+                #Compute the wizard Quantity for respective move. 
+                toprocess = uom_obj._compute_qty(cr, uid, move.product_uom.id, move.quantity, move.move_id.product_uom.id)
+
+                #Compare wizard Quantity with respective picking move quantity if wizard move quantity bigger then it's giving warning.
+                if toprocess > move.move_id.product_qty:
+                    raise osv.except_osv(_('Warning'), _('You can not process "%s %s" as the qty is more than "%s %s" of respective move.') % (move.quantity, process_uom.name, move.move_id.product_qty, move_uom.name))
+                partial_datas['move%s' % (move.move_id.id)] = {
+                    'product_id': move.id, 
+                    'product_qty': move.quantity, 
+                    'product_uom': move.product_uom.id, 
+                    'prodlot_id': move.prodlot_id.id, 
+                }
+                if (picking_type == 'in') and (move.product_id.cost_method == 'average'):
+                    partial_datas['move%s' % (move.move_id.id)].update({
+                                                    'product_price' : move.cost, 
+                                                    'product_currency': move.currency.id, 
+                                                    })
+        pick_obj.do_partial(cr, uid, picking_ids, partial_datas, context=context)
         return {'type': 'ir.actions.act_window_close'}
 
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file

_______________________________________________
Mailing list: https://launchpad.net/~openerp-dev-gtk
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~openerp-dev-gtk
More help   : https://help.launchpad.net/ListHelp

Reply via email to