[IMP] stock: stock partial move wizard
authorHarry (Open ERP) <hmo@tinyerp.com>
Fri, 26 Mar 2010 14:52:01 +0000 (20:22 +0530)
committerHarry (Open ERP) <hmo@tinyerp.com>
Fri, 26 Mar 2010 14:52:01 +0000 (20:22 +0530)
bzr revid: hmo@tinyerp.com-20100326145201-3viwi4gcsujnvfhd

addons/stock/__terp__.py
addons/stock/stock.py
addons/stock/stock_view.xml
addons/stock/stock_wizard.xml
addons/stock/wizard/__init__.py
addons/stock/wizard/stock_partial_move.py [new file with mode: 0644]
addons/stock/wizard/stock_partial_move_view.xml [new file with mode: 0644]
addons/stock/wizard/stock_partial_picking.py
addons/stock/wizard/wizard_partial_move.py [deleted file]

index 4c379cc..5fa2722 100644 (file)
@@ -44,6 +44,7 @@ Thanks to the double entry management, the inventory controlling is powerful and
         "stock_data.xml",
         "wizard/stock_move_view.xml",
         "wizard/stock_partial_picking_view.xml",
+        "wizard/stock_partial_move_view.xml",
         "wizard/stock_inventory_set_stock_zero_view.xml",
         "wizard/stock_fill_inventory_view.xml",
         "wizard/stock_invoice_onshipping_view.xml",
index a801fe4..68450ed 100644 (file)
@@ -890,6 +890,8 @@ class stock_picking(osv.osv):
             complete, too_many, too_few = [], [], []
             move_product_qty = {}
             for move in pick.move_lines:
+                if move.state in ('done', 'cancel'):
+                    continue
                 partial_data = partial_datas.get('move%s'%(move.id), False)                
                 assert partial_data, _('Do not Found Partial data of Stock Move Line :%s' %(move.id))
                 product_qty = partial_data.get('product_qty',0.0)
@@ -1117,10 +1119,9 @@ class stock_delivery(osv.osv):
         'partner_id': fields.many2one('res.partner', 'Partner', required=True),
         'address_id': fields.many2one('res.partner.address', 'Address', required=True),
         'move_delivered':fields.one2many('stock.move', 'delivered_id', 'Move Delivered'),
-        'picking_id': fields.many2one('stock.picking', 'Picking list', required=True),
+        'picking_id': fields.many2one('stock.picking', 'Picking list'),
         
     }
-    
 stock_delivery()
 # ----------------------------------------------------
 # Move
@@ -1788,7 +1789,134 @@ class stock_move(osv.osv):
                     self.write(cr, uid, [move.id], update_val)
 
         self.action_done(cr, uid, res)          
-        return res    
+        return res   
+    
+    def do_partial(self, cr, uid, ids, partial_datas, context={}):
+        """
+        @ partial_datas : dict. contain details of partial picking 
+                          like partner_id, address_id, delivery_date, delivery moves with product_id, product_qty, uom
+        """
+        res = {}
+        picking_obj = self.pool.get('stock.picking')
+        delivery_obj = self.pool.get('stock.delivery')
+        product_obj = self.pool.get('product.product')
+        currency_obj = self.pool.get('res.currency')
+        users_obj = self.pool.get('res.users')
+        uom_obj = self.pool.get('product.uom')
+        price_type_obj = self.pool.get('product.price.type')
+        sequence_obj = self.pool.get('ir.sequence')
+        wf_service = netsvc.LocalService("workflow")
+        partner_id = partial_datas.get('partner_id', False)
+        address_id = partial_datas.get('address_id', False)
+        delivery_date = partial_datas.get('delivery_date', False)
+        
+        new_moves = []
+
+        complete, too_many, too_few = [], [], []
+        move_product_qty = {}
+        for move in self.browse(cr, uid, ids, context=context):
+            if move.state in ('done', 'cancel'):
+                continue
+            partial_data = partial_datas.get('move%s'%(move.id), False)                
+            assert partial_data, _('Do not Found Partial data of Stock Move Line :%s' %(move.id))
+            product_qty = partial_data.get('product_qty',0.0)
+            move_product_qty[move.id] = product_qty
+            product_uom = partial_data.get('product_uom',False)                
+            product_price = partial_data.get('product_price',0.0)
+            product_currency = partial_data.get('product_currency',False)
+            if move.product_qty == product_qty:
+                complete.append(move)
+            elif move.product_qty > product_qty:
+                too_few.append(move)
+            else:
+                too_many.append(move)
+
+            # Average price computation
+            if (move.picking_id.type == 'in') and (move.product_id.cost_method == 'average'):
+                product = product_obj.browse(cr, uid, move.product_id.id)
+                user = users_obj.browse(cr, uid, uid)                   
+                context['currency_id'] = move.company_id.currency_id.id                    
+                qty = uom_obj._compute_qty(cr, uid, product_uom, product_qty, product.uom_id.id)
+                pricetype = False
+                if user.company_id.property_valuation_price_type:
+                    pricetype = price_type_obj.browse(cr, uid, user.company_id.property_valuation_price_type.id)
+                if pricetype and qty > 0:
+                    new_price = currency_obj.compute(cr, uid, product_currency,
+                            user.company_id.currency_id.id, product_price)
+                    new_price = uom_obj._compute_price(cr, uid, product_uom, new_price,
+                            product.uom_id.id)                        
+                    if product.qty_available <= 0:
+                        new_std_price = new_price
+                    else:
+                        # Get the standard price
+                        amount_unit = product.price_get(pricetype.field, context)[product.id]
+                        new_std_price = ((amount_unit * product.qty_available)\
+                            + (new_price * qty))/(product.qty_available + qty)
+                            
+                    # Write the field according to price type field
+                    product_obj.write(cr, uid, [product.id],
+                            {pricetype.field: new_std_price})
+                    self.write(cr, uid, [move.id], {'price_unit': new_price})
+
+        for move in too_few:  
+            product_qty = move_product_qty[move.id]      
+            if product_qty != 0:
+                new_move = self.copy(cr, uid, move.id,
+                    {
+                        'product_qty' : product_qty,
+                        'product_uos_qty': product_qty,
+                        'picking_id' : move.picking_id.id,
+                        'state': 'assigned',
+                        'move_dest_id': False,
+                        'price_unit': move.price_unit,
+                    })
+                complete.append(self.browse(cr, uid, new_move))
+            self.write(cr, uid, move.id,
+                    {
+                        'product_qty' : move.product_qty - product_qty,
+                        'product_uos_qty':move.product_qty - product_qty,
+                    })
+
+        
+        for move in too_many:
+            self.write(cr, uid, move.id,
+                    {
+                        'product_qty': product_qty,
+                        'product_uos_qty': product_qty
+                    })
+            complete.append(move) 
+
+        for move in complete:
+            self.action_done(cr, uid, [move.id])
+
+            # TOCHECK : Done picking if all moves are done
+            cr.execute("""
+                SELECT move.id FROM stock_picking pick 
+                RIGHT JOIN stock_move move ON move.picking_id = pick.id AND move.state = %s 
+                WHERE pick.id = %s""",
+                        ('done', move.picking_id.id))
+            res = cr.fetchall()        
+            if len(res) == len(move.picking_id.move_lines):                       
+                picking_obj.action_move(cr, uid, [move.picking_id.id])            
+                wf_service.trg_validate(uid, 'stock.picking', move.picking_id.id, 'button_done', cr)       
+        
+        ref = {}        
+        done_move_ids = []
+        for move in complete: 
+            done_move_ids.append(move.id)              
+            if move.picking_id.id not in ref:                   
+                delivery_id = delivery_obj.create(cr, uid, {            
+                    'partner_id': partner_id,
+                    'address_id': address_id,
+                    'date': delivery_date,
+                    'name' : move.picking_id.name,
+                    'picking_id':  move.picking_id.id
+                }, context=context)
+                ref[move.picking_id.id] = delivery_id
+            delivery_obj.write(cr, uid, ref[move.picking_id.id], {
+                'move_delivered' : [(4,move.id)]
+            })
+        return done_move_ids
 
 stock_move()
 
index c32eddf..877ea31 100644 (file)
                     <field name="date_planned"/>
                     <field name="backorder_id"/>
                     <field name="state"/>
-                    <button name="%(partial_move)d" string="Partial" type="action" states="assigned" icon="gtk-justify-fill"/>
+                    <button name="%(action_partial_move)d" string="Partial" type="action" states="assigned" icon="gtk-justify-fill"/>
                     <button name="action_cancel" states="assigned,confirmed" string="Cancel" type="object" icon="gtk-cancel"/>
                 </tree>
             </field>
                                 <button name="action_confirm" states="draft" string="Confirm" type="object" icon="gtk-apply"/>
                                 <button name="action_assign" states="confirmed" string="Set Available" type="object" icon="gtk-yes"/>
                                 <button name="action_cancel" states="assigned,confirmed" string="Cancel" type="object" icon="gtk-cancel"/>
-                                <button name="%(partial_move)d" states="assigned" string="Partial" type="action" icon="gtk-justify-fill"/>
+                                <button name="%(action_partial_move)d" states="assigned" string="Partial" type="action" icon="gtk-justify-fill"/>
                                 <button name="action_done" states="assigned" string="Done" type="object" icon="gtk-jump-to"/>
                             </group>
                         </page>
index e966c27..f9a2dfc 100644 (file)
                menu="False"
                        keyword="client_action_multi"
                name="stock.return.picking"
-               string="Return picking"/>
-
-       <wizard
-            id="partial_move"
-            model="stock.move"
-            multi="True"
-            name="stock.partial_move"
-            string="Partial Move"/>
+               string="Return picking"/>       
 
     <wizard
         id="split_inventory_lots"
index 9088e95..6f5a83a 100644 (file)
@@ -22,7 +22,7 @@
 import stock_traceability
 import stock_move   
 import stock_partial_picking
-import wizard_partial_move
+import stock_partial_move
 import wizard_picking_make
 import wizard_replacement
 import wizard_return
diff --git a/addons/stock/wizard/stock_partial_move.py b/addons/stock/wizard/stock_partial_move.py
new file mode 100644 (file)
index 0000000..bf8d105
--- /dev/null
@@ -0,0 +1,217 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+from osv import fields, osv
+from service import web_services
+from tools.translate import _
+import netsvc
+import pooler
+import time
+
+class stock_partial_move(osv.osv_memory):
+    _name = "stock.partial.move"    
+    _description = "Partial Move"    
+    _columns = {
+                'date': fields.datetime('Date', required=True),
+                'partner_id': fields.many2one('res.partner',string="Partner", required=True),
+                'address_id': fields.many2one('res.partner.address', 'Delivery Address', help="Address where goods are to be delivered", required=True),
+                               
+     }
+
+    def view_init(self, cr, uid, fields_list, context=None):
+        res = super(stock_partial_move, self).view_init(cr, uid, fields_list, context=context)
+        move_obj = self.pool.get('stock.move')        
+        if not context:
+            context={}
+        moveids = []
+        for m in move_obj.browse(cr, uid, context.get('active_ids', [])):            
+            if m.state in ('done', 'cancel'):
+                continue
+            if 'move%s_product_id'%(m.id) not in self._columns:
+                self._columns['move%s_product_id'%(m.id)] = fields.many2one('product.product',string="Product")
+            if 'move%s_product_qty'%(m.id) not in self._columns:
+                self._columns['move%s_product_qty'%(m.id)] = fields.float("Quantity")
+            if 'move%s_product_uom'%(m.id) not in self._columns:
+                self._columns['move%s_product_uom'%(m.id)] = fields.many2one('product.uom',string="Product UOM")
+
+            if (m.picking_id.type == 'in') and (m.product_id.cost_method == 'average'):
+                if 'move%s_product_price'%(m.id) not in self._columns:
+                    self._columns['move%s_product_price'%(m.id)] = fields.float("Price")
+                if 'move%s_product_currency'%(m.id) not in self._columns:
+                    self._columns['move%s_product_currency'%(m.id)] = fields.many2one('res.currency',string="Currency")
+        return res   
+
+    def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False,submenu=False):
+        result = super(stock_partial_move, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar,submenu)        
+        move_obj = self.pool.get('stock.move')
+        move_ids = context.get('active_ids', False)                
+        move_ids = move_obj.search(cr, uid, [('id','in',move_ids)])
+        _moves_arch_lst = """<form string="Deliver Products">
+                        <separator colspan="4" string="Delivery Information"/>
+                       <field name="date" colspan="4" />
+                       <field name="partner_id"/>
+                       <field name="address_id"/>
+                       <newline/>
+                        <separator colspan="4" string="Move Detail"/>
+                       """
+        _moves_fields = result['fields']
+        if move_ids and view_type in ['form']:            
+            for m in move_obj.browse(cr, uid, move_ids, context):                
+                if m.state in ('done', 'cancel'):
+                    continue
+                _moves_fields.update({
+                    'move%s_product_id'%(m.id)  : {
+                                'string': _('Product'),
+                                'type' : 'many2one', 
+                                'relation': 'product.product', 
+                                'required' : True, 
+                                'readonly' : True,                                    
+                                },
+                    'move%s_product_qty'%(m.id) : {
+                                'string': _('Quantity'),
+                                'type' : 'float',
+                                'required': True,                                    
+                                },
+                    'move%s_product_uom'%(m.id) : {
+                                'string': _('Product UOM'),
+                                'type' : 'many2one', 
+                                'relation': 'product.uom', 
+                                'required' : True, 
+                                'readonly' : True,                                    
+                                }
+                })                
+                
+                _moves_arch_lst += """
+                    <group colspan="4" col="10">
+                    <field name="move%s_product_id" nolabel="1"/>
+                    <field name="move%s_product_qty" string="Qty" />
+                    <field name="move%s_product_uom" nolabel="1" />
+                """%(m.id, m.id, m.id)
+                if (m.picking_id.type == 'in') and (m.product_id.cost_method == 'average'):                        
+                    _moves_fields.update({
+                        'move%s_product_price'%(m.id) : {
+                                'string': _('Price'),
+                                'type' : 'float',
+                                },
+                        'move%s_product_currency'%(m.id): {
+                                'string': _('Currency'),
+                                'type' : 'float',      
+                                'type' : 'many2one', 
+                                'relation': 'res.currency',                                    
+                                }
+                    })
+                    _moves_arch_lst += """
+                        <field name="move%s_product_price" />
+                        <field name="move%s_product_currency" nolabel="1"/>
+                    """%(m.id, m.id)
+                _moves_arch_lst += """
+                    </group>
+                    """
+        _moves_arch_lst += """
+                <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="_Deliver"
+                               colspan="1" type="object" icon="gtk-apply" />
+               </group>                        
+        </form>"""
+        result['arch'] = _moves_arch_lst
+        result['fields'] = _moves_fields           
+        return result
+
+    def default_get(self, cr, uid, fields, context=None):
+        """ 
+             To get default values for the object.
+            
+             @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. 
+        
+        """ 
+
+        res = super(stock_partial_move, self).default_get(cr, uid, fields, context=context)
+        move_obj = self.pool.get('stock.move')        
+        if not context:
+            context={}
+        moveids = []
+        if 'date' in fields:
+            res.update({'date': time.strftime('%Y-%m-%d %H:%M:%S')})
+        for m in move_obj.browse(cr, uid, context.get('active_ids', [])):            
+            if m.state in ('done', 'cancel'):
+                continue
+            if 'move%s_product_id'%(m.id) in fields:
+                res['move%s_product_id'%(m.id)] = m.product_id.id
+            if 'move%s_product_qty'%(m.id) in fields:
+                res['move%s_product_qty'%(m.id)] = m.product_qty
+            if 'move%s_product_uom'%(m.id) in fields:
+                res['move%s_product_uom'%(m.id)] = m.product_uom.id
+
+            if (m.picking_id.type == 'in') and (m.product_id.cost_method == 'average'):
+                price = 0
+                if hasattr(m, 'purchase_line_id') and m.purchase_line_id:
+                    price = m.purchase_line_id.price_unit
+
+                currency = False
+                if hasattr(m.picking_id, 'purchase_id') and m.picking_id.purchase_id:
+                    currency = m.picking_id.purchase_id.pricelist_id.currency_id.id
+    
+                if 'move%s_product_price'%(m.id) in fields:
+                    res['move%s_product_price'%(m.id)] = price
+                if 'move%s_product_currency'%(m.id) in fields:
+                    res['move%s_product_currency'%(m.id)] = currency
+        return res   
+
+    def do_partial(self, cr, uid, ids, context):    
+        move_obj = self.pool.get('stock.move')    
+        move_ids = context.get('active_ids', False)
+        partial = self.browse(cr, uid, ids[0], context)
+        partial_datas = {
+            'partner_id' : partial.partner_id and partial.partner_id.id or False,
+            'address_id' : partial.address_id and partial.address_id.id or False,
+            'delivery_date' : partial.date         
+        }
+        for m in move_obj.browse(cr, uid, move_ids):            
+            if m.state in ('done', 'cancel'):
+                continue
+            partial_datas['move%s'%(m.id)] = {
+                'product_id' : getattr(partial, 'move%s_product_id'%(m.id)).id,
+                'product_qty' : getattr(partial, 'move%s_product_qty'%(m.id)),
+                'product_uom' : getattr(partial, 'move%s_product_uom'%(m.id)).id
+            }
+
+            if (m.picking_id.type == 'in') and (m.product_id.cost_method == 'average'):   
+                partial_datas['move%s'%(m.id)].update({             
+                    'product_price' : getattr(partial, 'move%s_product_price'%(m.id)),
+                    'product_currency': getattr(partial, 'move%s_product_currency'%(m.id)).id
+                })  
+        
+        res = move_obj.do_partial(cr, uid, move_ids, partial_datas, context=context)
+        return {}
+stock_partial_move()    
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
diff --git a/addons/stock/wizard/stock_partial_move_view.xml b/addons/stock/wizard/stock_partial_move_view.xml
new file mode 100644 (file)
index 0000000..30b7f3f
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>     
+
+        <record id="view_stock_partial_move" model="ir.ui.view">
+            <field name="name">Delivery Product</field>
+            <field name="model">stock.partial.move</field>
+            <field name="type">form</field>
+            <field name="arch" type="xml">
+              <form string="Delivery Product">
+                       
+             </form>
+            </field>
+               </record>
+
+        <act_window name="Delivery Product"                
+                   res_model="stock.partial.move"
+                   src_model="stock.move"
+                   view_mode="form"
+                   target="new"        
+            key2="client_action_multi"    
+                   id="action_partial_move"/>                                  
+
+    </data>
+</openerp>
index 494fb3b..eba0957 100644 (file)
@@ -62,11 +62,9 @@ class stock_partial_picking(osv.osv_memory):
     def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False,submenu=False):
         result = super(stock_partial_picking, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar,submenu)        
         pick_obj = self.pool.get('stock.picking')
-        picking_ids = context.get('active_ids', False)        
-        if not picking_ids:
-            return result
-        if view_type in ['form']:
-            _moves_arch_lst = """<form string="Deliver Products">
+        picking_ids = context.get('active_ids', False) 
+        picking_ids = pick_obj.search(cr, uid, [('id', 'in', picking_ids)])               
+        _moves_arch_lst = """<form string="Deliver Products">
                         <separator colspan="4" string="Delivery Information"/>
                        <field name="date" colspan="4" />
                        <field name="partner_id"/>
@@ -74,7 +72,8 @@ class stock_partial_picking(osv.osv_memory):
                        <newline/>
                         <separator colspan="4" string="Move Detail"/>
                        """
-            _moves_fields = result['fields']
+        _moves_fields = result['fields']
+        if picking_ids and view_type in ['form']:
             for pick in pick_obj.browse(cr, uid, picking_ids, context):
                 for m in pick.move_lines:
                     if m.state in ('done', 'cancel'):
@@ -127,18 +126,18 @@ class stock_partial_picking(osv.osv_memory):
                     _moves_arch_lst += """
                         </group>
                         """
-                _moves_arch_lst += """
-                        <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="_Deliver"
-                                       colspan="1" type="object" icon="gtk-apply" />
-                       </group>                        
-                </form>"""
-            result['arch'] = _moves_arch_lst
-            result['fields'] = _moves_fields           
+        _moves_arch_lst += """
+                <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="_Deliver"
+                               colspan="1" type="object" icon="gtk-apply" />
+               </group>                        
+        </form>"""
+        result['arch'] = _moves_arch_lst
+        result['fields'] = _moves_fields           
         return result
 
     def default_get(self, cr, uid, fields, context=None):
@@ -160,13 +159,13 @@ class stock_partial_picking(osv.osv_memory):
         if not context:
             context={}
         moveids = []
+        if 'date' in fields:
+            res.update({'date': time.strftime('%Y-%m-%d %H:%M:%S')})
         for pick in pick_obj.browse(cr, uid, context.get('active_ids', [])):
             if 'partner_id' in fields:
                 res.update({'partner_id': pick.address_id.partner_id.id})                
             if 'address_id' in fields:
-                res.update({'address_id': pick.address_id.id})                        
-            if 'date' in fields:
-                res.update({'date': pick.date})
+                res.update({'address_id': pick.address_id.id})            
             for m in pick.move_lines:
                 if m.state in ('done', 'cancel'):
                     continue
@@ -215,8 +214,7 @@ class stock_partial_picking(osv.osv_memory):
                     partial_datas['move%s'%(m.id)].update({             
                         'product_price' : getattr(partial, 'move%s_product_price'%(m.id)),
                         'product_currency': getattr(partial, 'move%s_product_currency'%(m.id)).id
-                    })  
-        
+                    })          
         res = pick_obj.do_partial(cr, uid, picking_ids, partial_datas, context=context)
         return {}
  
diff --git a/addons/stock/wizard/wizard_partial_move.py b/addons/stock/wizard/wizard_partial_move.py
deleted file mode 100644 (file)
index 928d964..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-#    OpenERP, Open Source Management Solution
-#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
-#
-#    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU Affero General Public License as
-#    published by the Free Software Foundation, either version 3 of the
-#    License, or (at your option) any later version.
-#
-#    This program is distributed in the hope that it will be useful,
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU Affero General Public License for more details.
-#
-#    You should have received a copy of the GNU Affero General Public License
-#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-##############################################################################
-
-import time
-import netsvc
-from tools.misc import UpdateableStr, UpdateableDict
-import pooler
-
-import wizard
-from osv import osv
-import tools
-from tools.translate import _
-
-_moves_arch = UpdateableStr()
-_moves_fields = UpdateableDict()
-
-_moves_arch_end = '''<?xml version="1.0"?>
-<form string="Picking result">
-    <label string="Move(s) have been successfully Done !" colspan="4"/>    
-</form>'''
-
-def make_default(val):
-    def fct(uid, data, state):
-        return val
-    return fct
-
-def _to_xml(s):
-    return (s or '').replace('&','&amp;').replace('<','&lt;').replace('>','&gt;')
-
-def _get_moves(self, cr, uid, data, context):
-    move_obj = pooler.get_pool(cr.dbname).get('stock.move')
-    move_lines = move_obj.browse(cr, uid, data['ids'], context)
-    res = {}
-
-    _moves_fields.clear()
-    _moves_arch_lst = ['<?xml version="1.0"?>', '<form string="Partial Stock Moves">']
-
-    for move in move_lines:
-        quantity = move.product_qty
-        if move.state != 'assigned':
-            quantity = 0
-
-        _moves_arch_lst.append('<field name="move%s" />' % (move.id,))
-        _moves_fields['move%s' % move.id] = {
-                'string': _to_xml(move.name),
-                'type' : 'float', 'required' : True, 'default' : make_default(quantity)}
-
-        if (move.picking_id.type == 'in') and (move.product_id.cost_method == 'average'):
-            price = 0
-            if hasattr(move, 'purchase_line_id') and move.purchase_line_id:
-                price = move.purchase_line_id.price_unit
-
-            currency = 0
-            if hasattr(move.picking_id, 'purchase_id') and move.picking_id.purchase_id:
-                currency = move.picking_id.purchase_id.pricelist_id.currency_id.id
-
-            _moves_arch_lst.append('<group col="6"><field name="uom%s" nolabel="1"/>\
-                    <field name="price%s"/>' % (move.id, move.id,))
-
-            _moves_fields['price%s' % move.id] = {'string': 'Unit Price',
-                    'type': 'float', 'required': True, 'default': make_default(price)}
-
-            _moves_fields['uom%s' % move.id] = {'string': 'UOM', 'type': 'many2one',
-                    'relation': 'product.uom', 'required': True,
-                    'default': make_default(move.product_uom.id)}
-
-            _moves_arch_lst.append('<field name="currency%d" nolabel="1"/></group>' % (move.id,))
-            _moves_fields['currency%s' % m.id] = {'string': 'Currency',
-                    'type': 'many2one', 'relation': 'res.currency',
-                    'required': True, 'default': make_default(currency)}
-
-        _moves_arch_lst.append('<newline/>')
-        res.setdefault('moves', []).append(move.id)
-
-    _moves_arch_lst.append('</form>')
-    _moves_arch.string = '\n'.join(_moves_arch_lst)
-    return res
-
-def _do_split(self, cr, uid, data, context):
-    pool = pooler.get_pool(cr.dbname)
-    move_obj = pool.get('stock.move')
-    pick_obj = pool.get('stock.picking')
-    product_obj = pool.get('product.product')
-    currency_obj = pool.get('res.currency')
-    users_obj = pool.get('res.users')
-    uom_obj = pool.get('product.uom')
-    move_lines = move_obj.browse(cr, uid, data['ids'])
-    wf_service = netsvc.LocalService("workflow")
-    complete, too_few, too_many = [], [], []
-    for move in move_lines:        
-        states = []
-    
-        if move.product_qty == data['form']['move%s' % move.id]:
-            complete.append(move)
-        elif move.product_qty > data['form']['move%s' % move.id]:
-            too_few.append(move)
-        else:
-            too_many.append(move)        
-        # Average price computation
-        if (move.picking_id.type == 'in') and (move.product_id.cost_method == 'average'):
-            product = move.product_id
-            user = users_obj.browse(cr, uid, uid)
-            qty = data['form']['move%s' % move.id]
-            uom = data['form']['uom%s' % move.id]
-            price = data['form']['price%s' % move.id]
-            currency = data['form']['currency%s' % move.id]
-
-            qty = uom_obj._compute_qty(cr, uid, uom, qty, product.uom_id.id)
-            pricetype=pool.get('product.price.type').browse(cr,uid,user.company_id.property_valuation_price_type.id)
-            
-            if (qty > 0):
-                new_price = currency_obj.compute(cr, uid, currency,
-                        user.company_id.currency_id.id, price)
-                new_price = uom_obj._compute_price(cr, uid, uom, new_price,
-                        product.uom_id.id)
-                if product.qty_available<=0:
-                    new_std_price = new_price
-                else:
-                    # Get the standard price
-                    amount_unit=product.price_get(pricetype.field, context)[product.id]
-                    new_std_price = ((amount_unit * product.qty_available)\
-                        + (new_price * qty))/(product.qty_available + qty)
-
-                product_obj.write(cr, uid, [product.id],
-                        {pricetype.field: new_std_price})
-                move_obj.write(cr, uid, move.id, {'price_unit': new_price})        
-
-    for move in too_few:        
-        if data['form']['move%s' % move.id] != 0:
-            new_move = move_obj.copy(cr, uid, move.id,
-                {
-                    'product_qty' : data['form']['move%s' % move.id],
-                    'product_uos_qty':data['form']['move%s' % move.id],
-                    'picking_id' : move.picking_id.id,
-                    'state': 'assigned',
-                    'move_dest_id': False,
-                    'price_unit': move.price_unit,
-                })
-            complete.append(move_obj.browse(cr, uid, new_move))
-        move_obj.write(cr, uid, move.id,
-                {
-                    'product_qty' : move.product_qty - data['form']['move%s' % move.id],
-                    'product_uos_qty':move.product_qty - data['form']['move%s' % move.id],
-                })
-        
-    
-    for move in too_many:
-        move_obj.write(cr, uid, move.id,
-                {
-                    'product_qty': data['form']['move%s' % move.id],
-                    'product_uos_qty': data['form']['move%s' % move.id]
-                })
-        complete.append(move) 
-
-    for move in complete:
-        move_obj.action_done(cr, uid, [move.id])
-
-        # TOCHECK : Done picking if all moves are done
-        cr.execute('select move.id from stock_picking pick \
-                    right join stock_move move on move.picking_id = pick.id and move.state = ''%s'' where pick.id = %s',
-                    ('done', move.picking_id.id))
-        res = cr.fetchall()        
-        if len(res) == len(move.picking_id.move_lines):                       
-            pick_obj.action_move(cr, uid, [move.picking_id.id])            
-            wf_service.trg_validate(uid, 'stock.picking', move.picking_id.id, 'button_done', cr)
-
-    return {}
-
-
-
-class partial_move(wizard.interface):
-
-    states = {
-        'init': {
-            'actions': [ _get_moves ],
-            'result': {'type': 'form', 'arch': _moves_arch, 'fields': _moves_fields,
-                'state' : (
-                    ('end', 'Cancel', 'gtk-cancel'),
-                    ('split', 'Partial', 'gtk-apply', True)
-                )
-            },
-        },
-        'split': {
-            'actions': [ _do_split ],
-            'result': {'type': 'state', 'state': 'end2'},
-        },
-        'end2': {
-            'actions': [],
-            'result': {'type': 'form', 'arch': _moves_arch_end,
-                'fields': {},
-                'state': (
-                    ('end', 'Close'),
-                )
-            },
-        },
-    }
-
-partial_move('stock.partial_move')
-
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-