[IMP] stock: cleanup stock.partial.{picking,move} wizards and fix dependencies and...
authorOlivier Dony <odo@openerp.com>
Mon, 26 Sep 2011 00:36:12 +0000 (02:36 +0200)
committerOlivier Dony <odo@openerp.com>
Mon, 26 Sep 2011 00:36:12 +0000 (02:36 +0200)
bzr revid: odo@openerp.com-20110926003612-0wa6sghmlwbezwzk

17 files changed:
addons/mrp/test/mrp_phantom_bom.yml
addons/mrp/test/mrp_procurement.yml
addons/purchase/stock.py
addons/sale/test/invoice_on_ordered_qty.yml
addons/sale/test/invoice_on_shipped_qty.yml
addons/sale/test/manual_order_policy.yml
addons/sale/test/picking_order_policy.yml
addons/sale/test/postpaid_order_policy.yml
addons/sale/test/prepaid_order_policy.yml
addons/stock/stock.py
addons/stock/test/stock_test.yml
addons/stock/wizard/stock_partial_move.py
addons/stock/wizard/stock_partial_move_view.xml
addons/stock/wizard/stock_partial_picking.py
addons/stock/wizard/stock_partial_picking_view.xml
addons/stock_invoice_directly/test/stock_invoice_directly.yml
addons/stock_invoice_directly/wizard/stock_invoice.py

index 7a4747e..1f499a5 100644 (file)
   I am checking Procurement orders. There are 3 orders generated for Oranges, Sugar and Water.
 -
   !python {model: procurement.order}: |
-    from tools.translate import _
     proc_ids = self.search(cr, uid, [('product_id','in',[ref('product_product_orange0'),ref('product_product_sugar0'),ref('product_product_water0')])])
-    assert proc_ids, _('No Procurements!')
+    assert proc_ids, 'No Procurements!'
 -
   The scheduler runs.
 -
   stock moves for Oranges, Sugar and Water made correctly.
 -
   !python {model: stock.picking}: |
-    from tools.translate import _
     pick_ids = self.search(cr, uid, [('type','=','internal')])
-    assert pick_ids, _('No Internal Pickings!')
+    assert pick_ids, 'No Internal Pickings!'
 -
   According to minimum stock rules. I have 2 purchase orders for
   Sugar with 6 Kg from Axelor and Orange 60 Kg from ASUStek.
   I confirm the purchase order of Sugar and Orange.
 -
   !python {model: purchase.order}: |
-    from tools.translate import _
     import netsvc
     purch_ids = self.search(cr, uid, [('state','=','draft')])
-    assert purch_ids, _('No Purchase Orders were made!')
+    assert purch_ids, 'No Purchase Orders were made!'
     wf_service = netsvc.LocalService("workflow")
     for p_id in purch_ids:
         wf_service.trg_validate(uid, 'purchase.order', p_id, 'purchase_confirm', cr)
 -
-  I see two incoming pickings for Orange and Sugar.
+  I see two incoming pickings for Orange and Sugar, and receive them.
 -
   !python {model: stock.picking}: |
-    from tools.translate import _
     pick_ids = self.search(cr, uid, [('type','=','in')])
-    assert pick_ids, _('No Incoming Shipments found!')
--
-  I receive both the products. My incoming pickings are done.
--
-  I create record for the incoming picking wizard.
--
-  !record {model: stock.partial.picking, id: stock_partial_picking0}:
-    date: !eval datetime.today().strftime("%Y-%m-%d %H:%M:%S")
--
-  I make my pickings done.
--
-  !python {model: stock.partial.picking}: |
-     pick_obj = self.pool.get('stock.picking')
-     picking_ids = pick_obj.search(cr, uid, [('type','=','in'),('state','=','assigned')])
-     partial = self.browse(cr, uid, ref('stock_partial_picking0'), context)
-     partial_datas = {
-            'delivery_date': partial.date
-     }
-     for pick in pick_obj.browse(cr, uid, picking_ids):
-        for m in pick.move_lines:
-           partial_datas['move%s'%(m.id)] = {
-                    'product_id': m.product_id.id,
-                    'product_qty': m.product_qty,
-                    'product_uom': m.product_uom.id
-           }
-           if (pick.type == 'in') and (m.product_id.cost_method == 'average'):
-                    partial_datas['move%s'%(m.id)].update({
-                        'product_price': m.product_price,
-                        'product_currency': m.product_currency
-                    })
-     pick_obj.do_partial(cr, uid, picking_ids, partial_datas, context=context)
+    assert pick_ids, 'No Incoming Shipments found!'
+    stock_partial_picking = self.pool.get('stock.partial.picking')
+    for pick_id in pick_ids:
+        partial_id = stock_partial_picking.create(cr, uid, {},
+                context={'active_model': 'stock.picking',
+                         'active_ids': [pick_id]})
+        stock_partial_picking.do_partial(cr, uid, [partial_id])
 -
   Again the scheduler runs.
 -
   I check my internal picking of "Orange Juice" is done.
 -
   !python {model: stock.picking}: |
-    from tools.translate import _
     pick_ids = self.search(cr, uid, [('type','=','internal'),('state','=','done')])
-    assert pick_ids, _('Internal Picking is not done yet!')
+    assert pick_ids, 'Internal Picking is not done yet!'
 -
   I check my manufacturing order for "Orange Juice" is ready or not.
 -
   !python {model: mrp.production}: |
-    from tools.translate import _
-    pick_ids = self.search(cr, uid, [('state','=','ready'),('id','=',ref('mrp_production_mo0'))])
-    assert pick_ids, _('Manufacturing order is not ready!')
+    prod_ids = self.search(cr, uid, [('state','=','ready'),('id','=',ref('mrp_production_mo0'))])
+    assert prod_ids, 'Manufacturing order is not ready!'
 -
   I start the production order.
 -
   !workflow {model: mrp.production, action: button_produce, ref: mrp_production_mo0}
-
-
index b716948..4aaf156 100644 (file)
   I Check incoming shipments for cloth. And receive products.
 -
   !python {model: stock.picking}: |
-    from tools.translate import _
     pick_ids = self.search(cr, uid, [('address_id.name','=','Wong'),('state','=','assigned')])
-    assert pick_ids, _('No Incoming Shipments found!')
--
-  I create record for partial picking.
--
-  !record {model: stock.partial.picking, id: stock_partial_picking0}:
-    date: !eval datetime.today().strftime("%Y-%m-%d %H:%M:%S")
-
--
-  I make my picking done.
--
-  !python {model: stock.partial.picking}: |
-     pick_obj = self.pool.get('stock.picking')
-     picking_ids = pick_obj.search(cr, uid, [('address_id.name','=','Wong'),('state','=','assigned')])
-     partial = self.browse(cr, uid, ref('stock_partial_picking0'), context)
-     partial_datas = {
-            'delivery_date' : partial.date
-     }
-     for pick in pick_obj.browse(cr, uid, picking_ids):
-        for m in pick.move_lines:
-           partial_datas['move%s'%(m.id)] = {
-                    'product_id' : m.product_id.id,
-                    'product_qty' : m.product_qty,
-                    'product_uom' : m.product_uom.id
-           }
-           if (pick.type == 'in') and (m.product_id.cost_method == 'average'):
-                    partial_datas['move%s'%(m.id)].update({
-                        'product_price' : m.product_price,
-                        'product_currency': m.product_currency
-                    })
-     pick_obj.do_partial(cr, uid, picking_ids, partial_datas, context=context)
+    assert pick_ids, 'No Incoming Shipments found!'
+    stock_partial_picking = self.pool.get('stock.partial.picking')
+    for pick_id in pick_ids:
+        partial_id = stock_partial_picking.create(cr, uid, {},
+                context={'active_model': 'stock.picking',
+                         'active_ids': [pick_id]})
+        stock_partial_picking.do_partial(cr, uid, [partial_id])
 -
   I Check incoming shipments for buttons and receive products.
 -
   !python {model: stock.picking}: |
-    from tools.translate import _
     pick_ids = self.search(cr, uid, [('address_id.name','=','Tang'),('state','=','assigned')])
-    assert pick_ids, _('No Incoming Shipments found!')
--
-  I create record for partial picking.
--
-  !record {model: stock.partial.picking, id: stock_partial_picking0}:
-    date: !eval datetime.today().strftime("%Y-%m-%d %H:%M:%S")
-
--
-  I make my picking done.
--
-  !python {model: stock.partial.picking}: |
-     pick_obj = self.pool.get('stock.picking')
-     picking_ids = pick_obj.search(cr, uid, [('address_id.name','=','Tang'),('state','=','assigned')])
-     partial = self.browse(cr, uid, ref('stock_partial_picking0'), context)
-     partial_datas = {
-            'delivery_date': partial.date
-     }
-     for pick in pick_obj.browse(cr, uid, picking_ids):
-        for m in pick.move_lines:
-           partial_datas['move%s'%(m.id)] = {
-                    'product_id': m.product_id.id,
-                    'product_qty': m.product_qty,
-                    'product_uom': m.product_uom.id
-           }
-           if (pick.type == 'in') and (m.product_id.cost_method == 'average'):
-                    partial_datas['move%s'%(m.id)].update({
-                        'product_price': m.product_price,
-                        'product_currency': m.product_currency
-                    })
-     pick_obj.do_partial(cr, uid, picking_ids, partial_datas, context=context)
+    assert pick_ids, 'No Incoming Shipments found!'
+    stock_partial_picking = self.pool.get('stock.partial.picking')
+    for pick_id in pick_ids:
+        partial_id = stock_partial_picking.create(cr, uid, {},
+                context={'active_model': 'stock.picking',
+                         'active_ids': [pick_id]})
+        stock_partial_picking.do_partial(cr, uid, [partial_id])
 -
   Run scheduler again.
 -
   I produce 2 products with 5.00 quantities each.
 -
   !python {model: mrp.product.produce}: |
-    from tools.translate import _
     prod_obj = self.pool.get('mrp.production')
     prod_ids = prod_obj.search(cr, uid, [('product_id.name','=','Shirt')])
     self.do_produce(cr, uid, [ref('mrp_product_produce0')], context={'active_ids': prod_ids})
   And finally production order is done.
 -
   !python {model: mrp.product.produce}: |
-    from tools.translate import _
     prod_obj = self.pool.get('mrp.production')
     prod_ids = prod_obj.search(cr, uid, [('product_id.name','=','Shirt')])
-    self.do_produce(cr, uid, [1], context={'active_ids': prod_ids})
+    self.do_produce(cr, uid, [ref('mrp_product_produce0')], context={'active_ids': prod_ids})
 
index 696c4d7..29b4aa2 100644 (file)
@@ -124,68 +124,15 @@ class stock_picking(osv.osv):
             purchase_obj.write(cursor, user, [picking.purchase_id.id], {'invoice_id': invoice_id,})
         return super(stock_picking, self)._invoice_hook(cursor, user, picking, invoice_id)
 
-stock_picking()
-
 class stock_partial_picking(osv.osv_memory):
     _inherit = 'stock.partial.picking'
 
-    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.
-        """
-        if context is None:
-            context = {}
-        pick_obj = self.pool.get('stock.picking')
-        res = super(stock_partial_picking, self).default_get(cr, uid, fields, context=context)
-        for pick in pick_obj.browse(cr, uid, context.get('active_ids', []), context=context):
-            has_product_cost = (pick.type == 'in' and pick.purchase_id)
-            for m in pick.move_lines:
-                if m.state in ('done','cancel') :
-                    continue
-                if has_product_cost and m.product_id.cost_method == 'average' and m.purchase_line_id:
-                    # We use the original PO unit purchase price as the basis for the cost, expressed
-                    # in the currency of the PO (i.e the PO's pricelist currency)
-                    list_index = 0
-                    for item in res['product_moves_in']:
-                        if item['move_id'] == m.id:
-                            res['product_moves_in'][list_index]['cost'] = m.purchase_line_id.price_unit
-                            res['product_moves_in'][list_index]['currency'] = m.picking_id.purchase_id.pricelist_id.currency_id.id
-                        list_index += 1
-        return res
-stock_partial_picking()
-
-class stock_partial_move(osv.osv_memory):
-    _inherit = "stock.partial.move"
-    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.
-        """
-        if context is None:
-            context = {}
-        res = super(stock_partial_move, self).default_get(cr, uid, fields, context=context)
-        move_obj = self.pool.get('stock.move')
-        for m in move_obj.browse(cr, uid, context.get('active_ids', []), context=context):
-            if m.picking_id.type == 'in' and m.product_id.cost_method == 'average' \
-                and m.purchase_line_id and m.picking_id.purchase_id:
-                    # We use the original PO unit purchase price as the basis for the cost, expressed
-                    # in the currency of the PO (i.e the PO's pricelist currency)
-                    list_index = 0
-                    for item in res['product_moves_in']:
-                        if item['move_id'] == m.id:
-                            res['product_moves_in'][list_index]['cost'] = m.purchase_line_id.price_unit
-                            res['product_moves_in'][list_index]['currency'] = m.picking_id.purchase_id.pricelist_id.currency_id.id
-                        list_index += 1
-        return res
-stock_partial_move()
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+    # Overridden to inject the purchase price as true 'cost price' when processing
+    # incoming pickings.
+    def _product_cost_for_average_update(self, cr, uid, move):
+        if move.picking_id.purchase_id:
+            return {'cost': move.purchase_line_id.price_unit,
+                    'currency': move.picking_id.purchase_id.pricelist_id.currency_id.id}
+        return super(stock_partial_picking, self)._product_cost_for_average_update(cr, uid, move)
 
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
index 785b2d8..313aa3a 100644 (file)
 -
   !workflow {model: sale.order, action: order_confirm, ref: sale_order_so9}
 -
-  I verify that the picking has been generated for the sale order
+  I verify that the picking has been generated for the sale order and I process it
 -
   !python {model: sale.order}: |
     so = self.browse(cr, uid, ref("sale_order_so9"))
     assert so.picking_ids,"Picking has not been generated for sale_order_so9"
--
-  Then I confirm the picking
--
-  !record {model: stock.partial.picking, id: stock_partial_picking_0}:
-    date: !eval time.strftime('%Y-%m-%d %H:%M:%S')
--
-  Then I done the picking
--
-  !python {model: stock.picking }: |
-    import time
-    sale_order_obj = self.pool.get('sale.order')
-    so = sale_order_obj.browse(cr, uid, ref("sale_order_so9"))
-    picking_id = self.search(cr, uid, [('origin','=',so.name),('type','=','out')])
-    if picking_id:
-       pick=self.browse(cr,uid,picking_id[0])
-       pick.force_assign(cr, uid)
-       partial_datas = {
-            'partner_id':pick.address_id.partner_id.id,
-             'address_id': pick.address_id.id,
-             'delivery_date' : time.strftime('%Y-%m-%d'),
-            }
-       move = pick.move_lines[0]
-       partial_datas['move%s'%(move.id)]= {
-           'product_id': move.product_id.id,
-           'product_qty': '100',
-           'product_uom': move.product_uom.id,
-       }
-       self.do_partial(cr, uid, [pick.id],partial_datas)
+    picking, = so.picking_ids
+    stock_partial_picking = self.pool.get('stock.partial.picking')
+    partial_id = stock_partial_picking.create(cr, uid, {},
+            context={'active_model': 'stock.picking',
+                     'active_ids': [picking.id]})
+    stock_partial_picking.do_partial(cr, uid, [partial_id])
 -
   I click on Create Invoice button to create the invoice.
 -
index c9acf4a..c6ac864 100644 (file)
 -
   !workflow {model: sale.order, action: order_confirm, ref: sale_order_so6}
 -
-  I verify that the picking has been generated for the sale order
+  I verify that the picking has been generated for the sale order and I process it
 -
   !python {model: sale.order}: |
     so = self.browse(cr, uid, ref("sale_order_so6"))
     assert so.picking_ids,"Picking has not been generated for sale_order_so6"
--
-  Then I click on the "Product Sent" button of Outgoing Shipments
--
-  !record {model: stock.partial.picking, id: stock_partial_picking_0}:
-    date: !eval time.strftime('%Y-%m-%d %H:%M:%S')
--
-  I change the quantity on the picking to 199, and confirm partially 100 PCE.
--
-  !python {model: stock.picking }: |
-    import time
-    sale_order_obj = self.pool.get('sale.order')
-    so = sale_order_obj.browse(cr, uid, ref("sale_order_so6"))
-    picking_id = self.search(cr, uid, [('origin','=',so.name),('type','=','out')])
-    if picking_id:
-       pick=self.browse(cr,uid,picking_id[0])
-       self.pool.get('stock.move').write(cr, uid, [pick.move_lines[0].id], {'product_qty': 199, 'product_uos_qty': 199})
-       pick=self.browse(cr,uid,picking_id[0])
-       pick.force_assign(cr, uid)
-       partial_datas = {
-           'partner_id':pick.address_id.partner_id.id,
-           'address_id': pick.address_id.id,
-           'delivery_date' : time.strftime('%Y-%m-%d'),
-       }
-       move = pick.move_lines[0]
-       partial_datas['move%s'%(move.id)]= {
-           'product_id': move.product_id.id,
-           'product_qty': '100',
-           'product_uom': move.product_uom.id,
-       }
-       self.do_partial(cr, uid, [pick.id],partial_datas)
+    picking, = so.picking_ids
+    stock_partial_picking = self.pool.get('stock.partial.picking')
+    partial_id = stock_partial_picking.create(cr, uid, {},
+            context={'active_model': 'stock.picking',
+                     'active_ids': [picking.id]})
+    # I change the qty to 100 for a partial delivery
+    partial = stock_partial_picking.browse(cr,uid,partial_id)
+    line_id = partial.move_ids[0].id
+    partial.write({'move_ids': [(1,line_id,{'quantity':100})]})
+    partial.do_partial()
 -
   Then I click on 'Create Invoices' button
 -
@@ -72,7 +52,7 @@
     import time
     sale_obj = self.pool.get('sale.order')
     sale_id = sale_obj.browse(cr, uid, ref("sale_order_so6"))
-    ids = [x.id for x in sale_id.picking_ids]
+    ids = [x.id for x in sale_id.picking_ids if x.state == 'done']
     wiz_id = self.create(cr, uid, {'invoice_date': time.strftime('%Y-%m-%d'), 'journal_id': ref('account.sales_journal')},
       {'active_ids': ids, 'active_model': 'stock.picking'})
     self.create_invoice(cr, uid, [wiz_id], {"active_ids": ids, "active_id": ids[0]})
@@ -98,7 +78,7 @@
     inv_brw = self.browse(cr,uid,inv_id)[0]
     for inv_lines in inv_brw.invoice_line:
         qty1=inv_lines.quantity
-    assert (qty1 == qty), "Quantities are not the same"
+    assert (qty1 == qty), "Quantities are not the same: invoiced: %s, shipped: %s" % (qty1,qty)
 -
   I open the Invoice for the SO.
 -
index c153540..35f38e8 100644 (file)
   I verify that a procurement state is "running"
 -
   !python {model: procurement.order}: |
-    from tools.translate import _
-    modules = self.pool.get('ir.module.module')
-    mod_pur = modules.search(cr, uid, [('name','=','purchase')])
-    mod_brw = modules.browse(cr,uid,mod_pur)[0]
-    if (mod_brw.state == 'installed'):
-        sale_order_obj = self.pool.get('sale.order')
-        so = sale_order_obj.browse(cr, uid, ref("sale_order_so0"))
-        proc_ids = self.search(cr, uid, [('origin','=',so.name),('state','=','running')])
-        assert(proc_ids),"Procurement is not in the running state!"
+    sale_order_obj = self.pool.get('sale.order')
+    so = sale_order_obj.browse(cr, uid, ref("sale_order_so0"))
+    proc_ids = self.search(cr, uid, [('origin','=',so.name),('state','=','running')])
+    assert(proc_ids),"Procurement is not in the running state!"
 -
   I verify that a purchase order has been generated
 -
         for pur in pur_ids:
           wf_service.trg_validate(uid, 'purchase.order',pur,'purchase_approve', cr)
 -
-  I verify that a picking related to purchase order has been generated.
+  I verify that a picking related to purchase order has been generated and I process it
 -
   !python {model: sale.order}: |
     modules = self.pool.get('ir.module.module')
         pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)])
         po = pur_obj.browse(cr, uid, pur_id)[0]
         assert(po.picking_ids),"Picking for purchase order has not been generated"
--
-  Then I click on the "Products Received" button of Incoming Shipments
--
-  !record {model: stock.partial.picking, id: stock_partial_picking_0}:
-    date: !eval time.strftime('%Y-%m-%d %H:%M:%S')
--
-  I click on the "Validate" button
--
-  !python {model: stock.picking}: |
-    modules = self.pool.get('ir.module.module')
-    sale_order_obj = self.pool.get('sale.order')
-    pur_obj = self.pool.get('purchase.order')
-    mod_pur = modules.search(cr, uid, [('name','=','purchase')])
-    mod_brw = modules.browse(cr,uid,mod_pur)[0]
-    if (mod_brw.state == 'installed'):
-        so = sale_order_obj.browse(cr, uid, ref("sale_order_so0"))
-        pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)])
-        po = pur_obj.browse(cr, uid, pur_id)[0]
-        pick_ser_id = self.search(cr, uid, [('purchase_id', '=', po.id )])
-        import netsvc
-        wf_service = netsvc.LocalService("workflow")
-        for pick in pick_ser_id:
-          wf_service.trg_validate(uid, 'stock.picking',pick,'button_done', cr)
+        picking, = po.picking_ids
+        stock_partial_picking = self.pool.get('stock.partial.picking')
+        partial_id = stock_partial_picking.create(cr, uid, {},
+                context={'active_model': 'stock.picking',
+                         'active_ids': [picking.id]})
+        stock_partial_picking.do_partial(cr, uid, [partial_id])
 -
   I verify that picking for purchase order has been done.
 -
         ids = picking_obj.search(cr, uid, [('purchase_id', '=', po.id ),('state', '=', 'done')])
         assert(ids),"Picking is not in the done state!"
 -
-  Then I done the picking
+  Then I process the picking
 -
   !python {model: stock.picking }: |
    import time
    if picking_id:
       pick=self.browse(cr,uid,picking_id[0])
       pick.force_assign(cr, uid)
-      partial_datas = {
-           'partner_id':pick.address_id.partner_id.id,
-            'address_id': pick.address_id.id,
-            'delivery_date' : time.strftime('%Y-%m-%d'),
-           }
-      move = pick.move_lines[0]
-      partial_datas['move%s'%(move.id)]= {
-          'product_id': move.product_id.id,
-          'product_qty': move.product_qty,
-          'product_uom': move.product_uom.id,
-      }
-      self.do_partial(cr, uid, [pick.id],partial_datas)
+      stock_partial_picking = self.pool.get('stock.partial.picking')
+      partial_id = stock_partial_picking.create(cr, uid, {},
+              context={'active_model': 'stock.picking',
+                       'active_ids': [pick.id]})
+      stock_partial_picking.do_partial(cr, uid, [partial_id])
 -
   I verify that picking for sale order is in done state.
 -
    pick = self.browse(cr,uid,picking_id[0])
    assert (pick.state) =='done', "Picking for SO is not in done state."
 -
-  Then I done the delivery order
--
-  !python {model: stock.picking }: |
-   import time
-   sale_order_obj = self.pool.get('sale.order')
-   so = sale_order_obj.browse(cr, uid, ref("sale_order_so0"))
-   picking_id = self.search(cr, uid, [('origin','=',so.name)])
-   if picking_id:
-      pick=self.browse(cr,uid,picking_id[0])
-      pick.force_assign(cr, uid)
-      partial_datas = {
-           'partner_id':pick.address_id.partner_id.id,
-            'address_id': pick.address_id.id,
-            'delivery_date' : time.strftime('%Y-%m-%d'),
-           }
-      move = pick.move_lines[0]
-      partial_datas['move%s'%(move.id)]= {
-          'product_id': move.product_id.id,
-          'product_qty': move.product_qty,
-          'product_uom': move.product_uom.id,
-      }
-      self.do_partial(cr, uid, [pick.id],partial_datas)
--
-  I verify that delivery state is done
--
-  !python {model: stock.picking }: |
-   sale_order_obj = self.pool.get('sale.order')
-   so = sale_order_obj.browse(cr, uid, ref("sale_order_so0"))
-   picking_id = self.search(cr, uid, [('origin','=',so.name)])
-   pick = self.browse(cr,uid,picking_id[0])
-   assert (pick.state) =='done', "Picking for SO is not in done state."
--
   I verify that a "Picked" has been set to true
 -
   !python {model: sale.order}: |
index 1aa8b89..1dcbf98 100644 (file)
    if picking_id:
       pick=self.browse(cr,uid,picking_id[0])
       pick.force_assign(cr, uid)
-      partial_datas = {
-           'partner_id':pick.address_id.partner_id.id,
-            'address_id': pick.address_id.id,
-            'delivery_date' : time.strftime('%Y-%m-%d'),
-           }
-      move = pick.move_lines[0]
-      partial_datas['move%s'%(move.id)]= {
-          'product_id': move.product_id.id,
-          'product_qty': move.product_qty,
-          'product_uom': move.product_uom.id,
-      }
-      self.do_partial(cr, uid, [pick.id],partial_datas)
+      stock_partial_picking = self.pool.get('stock.partial.picking')
+      partial_id = stock_partial_picking.create(cr, uid, {},
+              context={'active_model': 'stock.picking',
+                       'active_ids': [pick.id]})
+      stock_partial_picking.do_partial(cr, uid, [partial_id])
 -
   Then I click on 'Create Invoices' button
 -
         for pur in pur_ids:
           wf_service.trg_validate(uid, 'purchase.order',pur,'purchase_approve', cr)
 -
-  I verify that a picking related to purchase order has been generated.
+  I verify that a picking related to purchase order has been generated and I process it
 -
   !python {model: sale.order}: |
     modules = self.pool.get('ir.module.module')
         pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)])
         po = pur_obj.browse(cr, uid, pur_id)[0]
         assert(po.picking_ids),"Picking for purchase order has not been generated"
--
-  Then I click on the "Products Received" button of Incoming Shipments
--
-  !record {model: stock.partial.picking, id: stock_partial_picking_0}:
-    date: !eval time.strftime('%Y-%m-%d %H:%M:%S')
--
-  I click on the "Validate" button
--
-  !python {model: stock.picking}: |
-    modules = self.pool.get('ir.module.module')
-    mod_pur = modules.search(cr, uid, [('name','=','purchase')])
-    mod_brw = modules.browse(cr,uid,mod_pur)[0]
-    if (mod_brw.state == 'installed'):
-        sale_order_obj = self.pool.get('sale.order')
-        pur_obj = self.pool.get('purchase.order')
-        so = sale_order_obj.browse(cr, uid, ref("sale_order_so7"))
-        pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)])
-        po = pur_obj.browse(cr, uid, pur_id)[0]
-        pick_ser_id = self.search(cr, uid, [('purchase_id', '=', po.id )])
-        import netsvc
-        wf_service = netsvc.LocalService("workflow")
-        for pick in pick_ser_id:
-          wf_service.trg_validate(uid, 'stock.picking',pick,'button_done', cr)
+        picking, = po.picking_ids
+        stock_partial_picking = self.pool.get('stock.partial.picking')
+        partial_id = stock_partial_picking.create(cr, uid, {},
+                context={'active_model': 'stock.picking',
+                         'active_ids': [picking.id]})
+        stock_partial_picking.do_partial(cr, uid, [partial_id])
 -
   I verify that picking for purchase order has been done.
 -
         ids = picking_obj.search(cr, uid, [('purchase_id', '=', po.id ),('state', '=', 'done')])
         assert ids, _('Picking is not in the done state!')
 -
-  I verify that delivery order has been generated for sale order
+  I verify that delivery order has been generated for sale order, and process it
 -
   !python {model: stock.picking }: |
    sale_order_obj = self.pool.get('sale.order')
    so = sale_order_obj.browse(cr, uid, ref("sale_order_so7"))
    picking_id = self.search(cr, uid, [('origin','=',so.name)])
    assert (picking_id),"Delivery order has not been generated"
--
-  I verify that delivery has been done
--
-  !python {model: stock.picking }: |
-   import time
-   sale_order_obj = self.pool.get('sale.order')
-   so = sale_order_obj.browse(cr, uid, ref("sale_order_so7"))
-   picking_id = self.search(cr, uid, [('origin','=',so.name)])
-   if picking_id:
-      pick=self.browse(cr,uid,picking_id[0])
-      pick.force_assign(cr, uid)
-      partial_datas = {
-           'partner_id':pick.address_id.partner_id.id,
-            'address_id': pick.address_id.id,
-            'delivery_date' : time.strftime('%Y-%m-%d'),
-           }
-      move = pick.move_lines[0]
-      partial_datas['move%s'%(move.id)]= {
-          'product_id': move.product_id.id,
-          'product_qty': move.product_qty,
-          'product_uom': move.product_uom.id,
-      }
-      self.do_partial(cr, uid, [pick.id],partial_datas)
+   pick=self.browse(cr,uid,picking_id[0])
+   pick.force_assign(cr, uid)
+   stock_partial_picking = self.pool.get('stock.partial.picking')
+   partial_id = stock_partial_picking.create(cr, uid, {},
+           context={'active_model': 'stock.picking',
+                    'active_ids': [pick.id]})
+   stock_partial_picking.do_partial(cr, uid, [partial_id])
 -
   I verify that delivery state is done
 -
      pick = self.browse(cr,uid,picking_id[0])
      assert (pick.state) =='done', "Picking for SO is not in done state."
 -
-  I verify that a "Picked" has been set to true
+  I verify that the sale order is marked as delivered
 -
   !python {model: sale.order}: |
     so = self.browse(cr, uid, ref("sale_order_so7"))
index 330c6d1..a0d5a8e 100644 (file)
    if picking_id:
       pick=self.browse(cr,uid,picking_id[0])
       pick.force_assign(cr, uid)
-      partial_datas = {
-           'partner_id':pick.address_id.partner_id.id,
-            'address_id': pick.address_id.id,
-            'delivery_date' : time.strftime('%Y-%m-%d'),
-           }
-      move = pick.move_lines[0]
-      partial_datas['move%s'%(move.id)]= {
-          'product_id': move.product_id.id,
-          'product_qty': move.product_qty,
-          'product_uom': move.product_uom.id,
-      }
-      self.do_partial(cr, uid, [pick.id],partial_datas)
+      stock_partial_picking = self.pool.get('stock.partial.picking')
+      partial_id = stock_partial_picking.create(cr, uid, {},
+              context={'active_model': 'stock.picking',
+                       'active_ids': [pick.id]})
+      stock_partial_picking.do_partial(cr, uid, [partial_id])
 -
   I verify that picking order is in done state.
 -
@@ -76,7 +69,7 @@
    picking_id = self.search(cr, uid, [('origin','=',so.name)])
    assert (picking_id),"Delivery order has not been generated"
 -
-  I click on the Products Sent button and then on the Validate button
+  I process the delivery order
 -
   !python {model: stock.picking }: |
    import time
    if picking_id:
       pick=self.browse(cr,uid,picking_id[0])
       pick.force_assign(cr, uid)
-      partial_datas = {
-           'partner_id':pick.address_id.partner_id.id,
-            'address_id': pick.address_id.id,
-            'delivery_date' : time.strftime('%Y-%m-%d'),
-           }
-      move = pick.move_lines[0]
-      partial_datas['move%s'%(move.id)]= {
-          'product_id': move.product_id.id,
-          'product_qty': move.product_qty,
-          'product_uom': move.product_uom.id,
-      }
-      self.do_partial(cr, uid, [pick.id],partial_datas)
--
-  I verify that delivery state is done
+      stock_partial_picking = self.pool.get('stock.partial.picking')
+      partial_id = stock_partial_picking.create(cr, uid, {},
+              context={'active_model': 'stock.picking',
+                       'active_ids': [pick.id]})
+      stock_partial_picking.do_partial(cr, uid, [partial_id])
+-
+  I verify that delivery order is marked done
 -
   !python {model: stock.picking }: |
    sale_order_obj = self.pool.get('sale.order')
         for pur in pur_ids:
           wf_service.trg_validate(uid, 'purchase.order',pur,'purchase_approve', cr)
 -
-  I verify that a picking related to purchase order has been generated.
+  I verify that a picking related to purchase order has been generated and I process it
 -
   !python {model: sale.order}: |
     modules = self.pool.get('ir.module.module')
         pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)])
         po = pur_obj.browse(cr, uid, pur_id)[0]
         assert(po.picking_ids),"Picking for purchase order has not been generated"
+        picking, = po.picking_ids
+        stock_partial_picking = self.pool.get('stock.partial.picking')
+        partial_id = stock_partial_picking.create(cr, uid, {},
+                context={'active_model': 'stock.picking',
+                         'active_ids': [picking.id]})
+        stock_partial_picking.do_partial(cr, uid, [partial_id])
 -
-  Then I click on the "Products Received" button of Incoming Shipments
--
-  !record {model: stock.partial.picking, id: stock_partial_picking_0}:
-    date: !eval time.strftime('%Y-%m-%d %H:%M:%S')
--
-  I click on the "Validate" button
--
-  !python {model: stock.picking}: |
-    modules = self.pool.get('ir.module.module')
-    mod_pur = modules.search(cr, uid, [('name','=','purchase')])
-    mod_brw = modules.browse(cr,uid,mod_pur)[0]
-    if (mod_brw.state == 'installed'):
-        sale_order_obj = self.pool.get('sale.order')
-        pur_obj = self.pool.get('purchase.order')
-        so = sale_order_obj.browse(cr, uid, ref("sale_order_so8"))
-        pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)])
-        po = pur_obj.browse(cr, uid, pur_id)[0]
-        pick_ser_id = self.search(cr, uid, [('purchase_id', '=', po.id )])
-        import netsvc
-        wf_service = netsvc.LocalService("workflow")
-        for pick in pick_ser_id:
-          wf_service.trg_validate(uid, 'stock.picking',pick,'button_done', cr)
--
-  I verify that picking for purchase order has been done.
+  I verify that picking for purchase order has been marked done.
 -
   !python {model: sale.order}: |
     from tools.translate import _
         ids = picking_obj.search(cr, uid, [('purchase_id', '=', po.id ),('state', '=', 'done')])
         assert ids, _('Picking is not in the done state!')
 -
-  I verify that a "Picked" has been set to true
+  I verify that the sale order is marked as delivered
 -
   !python {model: sale.order}: |
     so = self.browse(cr, uid, ref("sale_order_so8"))
index 4bf132e..d6f3da6 100644 (file)
    if picking_id:
       pick=self.browse(cr,uid,picking_id[0])
       pick.force_assign(cr, uid)
-      partial_datas = {
-           'partner_id':pick.address_id.partner_id.id,
-            'address_id': pick.address_id.id,
-            'delivery_date' : time.strftime('%Y-%m-%d'),
-           }
-      move = pick.move_lines[0]
-      partial_datas['move%s'%(move.id)]= {
-          'product_id': move.product_id.id,
-          'product_qty': move.product_qty,
-          'product_uom': move.product_uom.id,
-      }
-      self.do_partial(cr, uid, [pick.id],partial_datas)
+      stock_partial_picking = self.pool.get('stock.partial.picking')
+      partial_id = stock_partial_picking.create(cr, uid, {},
+              context={'active_model': 'stock.picking',
+                       'active_ids': [pick.id]})
+      stock_partial_picking.do_partial(cr, uid, [partial_id])
 -
   I verify that picking order is in done state.
 -
         for pur in pur_ids:
           wf_service.trg_validate(uid, 'purchase.order',pur,'purchase_approve', cr)
 -
-  I verify that a picking related to purchase order has been generated.
+  I verify that a picking related to purchase order has been generated and I process it
 -
   !python {model: sale.order}: |
     modules = self.pool.get('ir.module.module')
         pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)])
         po = pur_obj.browse(cr, uid, pur_id)[0]
         assert(po.picking_ids),"Picking for purchase order has not been generated"
--
-  Then I click on the "Products Received" button of Incoming Shipments
--
-  !record {model: stock.partial.picking, id: stock_partial_picking_0}:
-    date: !eval time.strftime('%Y-%m-%d %H:%M:%S')
--
-  I click on the "Validate" button
--
-  !python {model: stock.picking}: |
-    modules = self.pool.get('ir.module.module')
-    sale_order_obj = self.pool.get('sale.order')
-    pur_obj = self.pool.get('purchase.order')
-    mod_pur = modules.search(cr, uid, [('name','=','purchase')])
-    mod_brw = modules.browse(cr,uid,mod_pur)[0]
-    if (mod_brw.state == 'installed'):
-        so = sale_order_obj.browse(cr, uid, ref("sale_order_so1"))
-        pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)])
-        po = pur_obj.browse(cr, uid, pur_id)[0]
-        pick_ser_id = self.search(cr, uid, [('purchase_id', '=', po.id )])
-        import netsvc
-        wf_service = netsvc.LocalService("workflow")
-        for pick in pick_ser_id:
-          wf_service.trg_validate(uid, 'stock.picking',pick,'button_done', cr)
--
-  I verify that picking for purchase order has been done.
--
-  !python {model: sale.order}: |
-    from tools.translate import _
-    modules = self.pool.get('ir.module.module')
-    mod_pur = modules.search(cr, uid, [('name','=','purchase')])
-    mod_brw = modules.browse(cr,uid,mod_pur)[0]
-    if(mod_brw.state == 'installed'):
-        pur_obj = self.pool.get('purchase.order')
-        so = self.browse(cr, uid, ref("sale_order_so1"))
-        pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)])
-        po = pur_obj.browse(cr, uid, pur_id)[0]
+        picking, = po.picking_ids
+        stock_partial_picking = self.pool.get('stock.partial.picking')
+        partial_id = stock_partial_picking.create(cr, uid, {},
+                context={'active_model': 'stock.picking',
+                         'active_ids': [picking.id]})
+        stock_partial_picking.do_partial(cr, uid, [partial_id])
         picking_obj = self.pool.get('stock.picking')
-        ids = picking_obj.search(cr, uid, [('purchase_id', '=', po.id ),('state', '=', 'done')])
-        assert ids, _('Picking is not in the done state!')
+        ids = picking_obj.search(cr, uid, [('purchase_id', '=', po.id),('state', '=', 'done')])
+        assert ids, 'Picking should be marked done!'
 -
-  I verify that a "Picked" has been set to true
+  I verify that the sale order is marked as delivered
 -
   !python {model: sale.order}: |
     so = self.browse(cr, uid, ref("sale_order_so1"))
-    assert (so.shipped == True), "Picking is not done."
+    assert (so.shipped == True), "Sale order is not marked as delivered"
 -
   I verify that a sale order is in done state
 -
index 283b924..6d86efa 100644 (file)
@@ -664,8 +664,8 @@ class stock_picking(osv.osv):
 
     def action_process(self, cr, uid, ids, context=None):
         if context is None: context = {}
-        partial_id = self.pool.get("stock.partial.picking").create(
-            cr, uid, {}, context=dict(context, active_ids=ids))
+        context = dict(context, active_ids=ids, active_model=self._name)
+        partial_id = self.pool.get("stock.partial.picking").create(cr, uid, {}, context=context)
         return {
             'name':_("Products to Process"),
             'view_mode': 'form',
@@ -677,7 +677,7 @@ class stock_picking(osv.osv):
             'nodestroy': True,
             'target': 'new',
             'domain': '[]',
-            'context': dict(context, active_ids=ids)
+            'context': context,
         }
 
     def copy(self, cr, uid, id, default=None, context=None):
@@ -1470,6 +1470,8 @@ class stock_move(osv.osv):
 
     def action_partial_move(self, cr, uid, ids, context=None):
         if context is None: context = {}
+        if context.get('active_model') != self._name:
+            context.update(active_ids=ids, active_model=self._name)
         partial_id = self.pool.get("stock.partial.move").create(
             cr, uid, {}, context=context)
         return {
@@ -2123,14 +2125,9 @@ class stock_move(osv.osv):
         """ Makes the move done and if all moves are done, it will finish the picking.
         @return:
         """
-        partial_datas=''
         picking_ids = []
         move_ids = []
-        partial_obj=self.pool.get('stock.partial.picking')
         wf_service = netsvc.LocalService("workflow")
-        partial_id=partial_obj.search(cr,uid,[])
-        if partial_id:
-            partial_datas = partial_obj.read(cr, uid, partial_id, context=context)[0]
         if context is None:
             context = {}
 
@@ -2160,9 +2157,6 @@ class stock_move(osv.osv):
                         self.action_done(cr, uid, [move.move_dest_id.id], context=context)
 
             self._create_product_valuation_moves(cr, uid, move, context=context)
-            prodlot_id = partial_datas and partial_datas.get('move%s_prodlot_id' % (move.id), False)
-            if prodlot_id:
-                self.write(cr, uid, [move.id], {'prodlot_id': prodlot_id}, context=context)
             if move.state not in ('confirmed','done','assigned'):
                 todo.append(move.id)
 
index 6a82846..66029a6 100644 (file)
 -
   !python {model: stock.picking }: |
    import time
-   pick=self.browse(cr,uid,ref('stock_picking_0'))
-   move =pick.move_lines[0]
-   partial_datas = {
-          'partner_id':pick.address_id.partner_id.id,
-           'address_id': pick.address_id.id,
-           'delivery_date' : time.strftime('%Y-%m-%d')
-            }
-   partial_datas['move%s'%(move.id)]= {
-          'product_id': move.product_id,
-          'product_qty': move.product_qty,
-          'product_uom': move.product_uom.id,
-      }
-   self.do_partial(cr, uid, [ref('stock_picking_0')],partial_datas)
+   pick = self.browse(cr,uid,ref('stock_picking_0'))
+   stock_partial_picking = self.pool.get('stock.partial.picking')
+   partial_id = stock_partial_picking.create(cr, uid, {},
+           context={'active_model': 'stock.picking',
+                    'active_ids': [pick.id]})
+   stock_partial_picking.do_partial(cr, uid, [partial_id])
index 0f72003..ec34865 100644 (file)
@@ -2,7 +2,7 @@
 ##############################################################################
 #
 #    OpenERP, Open Source Management Solution
-#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
+#    Copyright (C) 2004-TODAY OpenERP SA (<http://openerp.com>).
 #
 #    This program is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU Affero General Public License as
 ##############################################################################
 
 from osv import fields, osv
-from tools.translate import _
+from tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
 import time
-import decimal_precision as dp
 
-
-class stock_partial_move_memory_out(osv.osv_memory):
-    _inherit = "stock.picking.memory.out"
-    _name = "stock.move.memory.out"
-    _columns = {
-        'wizard_id' : fields.many2one('stock.partial.move', string="Wizard"),
-    }
-    
-class stock_partial_move_memory_in(osv.osv_memory):
-    _inherit = "stock.picking.memory.in"
-    _name = "stock.move.memory.in"
+class stock_partial_move_line(osv.osv_memory):
+    _inherit = "stock.partial.picking.line"
+    _name = "stock.partial.move.line"
     _columns = {
-        'wizard_id' : fields.many2one('stock.partial.move', string="Wizard"),
+        'wizard_id' : fields.many2one('stock.partial.move', string="Wizard", ondelete='CASCADE'),
     }
-    
+
 class stock_partial_move(osv.osv_memory):
     _name = "stock.partial.move"
-    _description = "Partial Move"
+    _inherit = 'stock.partial.picking'
+    _description = "Partial Move Processing Wizard"
     _columns = {
         'date': fields.datetime('Date', required=True),
-        'type': fields.char("Type", size=3),
-        'product_moves_out' : fields.one2many('stock.move.memory.out', 'wizard_id', 'Moves'),
-        'product_moves_in' : fields.one2many('stock.move.memory.in', 'wizard_id', 'Moves'),
+        'move_ids' : fields.one2many('stock.partial.move.line', 'wizard_id', 'Moves'),
+
+        # picking_id is not used for move processing, so we remove the required attribute
+        # from the inherited column, and ignore it
+        'picking_id': fields.many2one('stock.picking', 'Picking'),
      }
-    
-    
-    def __is_in(self,cr, uid, move_ids):
-        """
-            @return: True if one of the moves has as picking type 'in'
-        """
-        if not move_ids:
-            return False
-       
-        move_obj = self.pool.get('stock.move')
-        move_ids = move_obj.search(cr, uid, [('id','in',move_ids)])
-       
-        for move in move_obj.browse(cr, uid, move_ids):
-            if move.picking_id.type == 'in' and move.product_id.cost_method == 'average':
-                return True
-        return False
-    
-    def __get_picking_type(self, cr, uid, move_ids):
-        if self.__is_in(cr, uid, move_ids):
-            return "product_moves_in"
-        else:
-            return "product_moves_out"
-    
-    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 context is None:
-            context = {}
-        for move in move_obj.browse(cr, uid, context.get('active_ids', []), context=context):
-            if move.state in ('done', 'cancel'):
-                raise osv.except_osv(_('Invalid action !'), _('Cannot deliver products which are already delivered !'))
-            
-        return res
-    
-    
-    def __create_partial_move_memory(self, move):
-        move_memory = {
-            'product_id' : move.product_id.id,
-            'quantity' : move.product_qty,
-            'product_uom' : move.product_uom.id,
-            'prodlot_id' : move.prodlot_id.id,
-            'move_id' : move.id,
-        }
-    
-        if move.picking_id.type == 'in':
-            move_memory.update({
-                'cost' : move.product_id.standard_price,
-                'currency' : move.product_id.company_id and move.product_id.company_id.currency_id and move.product_id.company_id.currency_id.id or False,
-            })
-        return move_memory
 
-    def __get_active_stock_moves(self, cr, uid, context=None):
-        move_obj = self.pool.get('stock.move')
-        if context is None:
-            context = {}
-               
-        res = []
-        for move in move_obj.browse(cr, uid, context.get('active_ids', []), context=context):
-            if move.state in ('done', 'cancel'):
-                continue           
-            res.append(self.__create_partial_move_memory(move))
-            
+    def default_get(self, cr, uid, fields, context=None):
+        if context is None: context = {}
+        # no call to super!
+        res = {}
+        move_ids = context.get('active_ids', [])
+        if not move_ids or not context.get('active_model') == 'stock.move':
+            return res
+        if 'move_ids' in fields:
+            move_ids = self.pool.get('stock.move').browse(cr, uid, move_ids, context=context)
+            moves = [self._partial_move_for(cr, uid, m) for m in move_ids if m.state not in ('done','cancel')]
+            res.update(move_ids=moves)
+        if 'date' in fields:
+            res.update(date=time.strftime(DEFAULT_SERVER_DATETIME_FORMAT))
         return res
-    
-    _defaults = {
-        'product_moves_in' : __get_active_stock_moves,
-        'product_moves_out' : __get_active_stock_moves,
-        'date' : lambda *a : time.strftime('%Y-%m-%d %H:%M:%S'),
-    }
-    
-    
-    def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
-        if not context:
-            context = {}
-        
-        message = {
-                'title' : _('Deliver Products'),
-                'info' : _('Delivery Information'),
-                'button' : _('Deliver'),
-                }
-        if context:            
-            if context.get('product_receive', False):
-                message = {
-                    'title' : _('Receive Products'),
-                    'info' : _('Receive Information'),
-                    'button' : _('Receive'),
-                }   
-         
-        move_ids = context.get('active_ids', False)    
-        message['picking_type'] = self.__get_picking_type(cr, uid, move_ids)
-        result = super(stock_partial_move, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar, submenu)
-        _moves_fields = result['fields']
-        _moves_fields.update({
-                            'product_moves_in' : {'relation': 'stock.move.memory.in', 'type' : 'one2many', 'string' : 'Product Moves'},
-                            'product_moves_out' : {'relation': 'stock.move.memory.out', 'type' : 'one2many', 'string' : 'Product Moves'}
-                            })
-        
-        _moves_arch_lst = """
-                <form string="%(title)s">
-                    <separator colspan="4" string="%(info)s"/>
-                    <field name="date" colspan="2"/>
-                    <separator colspan="4" string="Move Detail"/>
-                    <field name="%(picking_type)s" colspan="4" nolabel="1" mode="tree,form" width="550" height="200" ></field>      
-                    <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="%(button)s"
-                            colspan="1" type="object" icon="gtk-apply" />
-                    </group>
-                </form> """ % message
-        
-        result['arch'] = _moves_arch_lst
-        result['fields'] = _moves_fields
-        return result
-   
+
     def do_partial(self, cr, uid, ids, context=None):
-        """ 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.
-        """
-    
-        if context is None:
-            context = {}
-        move_obj = self.pool.get('stock.move')
-        
-        move_ids = context.get('active_ids', False)
+        # no call to super!
+        assert len(ids) == 1, 'Partial move processing may only be done one form at a time'
         partial = self.browse(cr, uid, ids[0], context=context)
-        partial_datas = {
+        partial_data = {
             'delivery_date' : partial.date
         }
-        
-        p_moves = {}
-        picking_type = self.__get_picking_type(cr, uid, move_ids)
-        
-        moves_list = picking_type == 'product_moves_in' and partial.product_moves_in  or partial.product_moves_out
-        for product_move in moves_list:
-            p_moves[product_move.move_id.id] = product_move
-            
-        moves_ids_final = []
-        for move in move_obj.browse(cr, uid, move_ids, context=context):
-            if move.state in ('done', 'cancel'):
-                continue
-            if not p_moves.get(move.id):
-                continue
-            partial_datas['move%s' % (move.id)] = {
-                'product_id' : p_moves[move.id].product_id.id,
-                'product_qty' : p_moves[move.id].quantity,
-                'product_uom' :p_moves[move.id].product_uom.id,
-                'prodlot_id' : p_moves[move.id].prodlot_id.id,
+        moves_ids = []
+        for move in partial.move_ids:
+            move_id = move.move_id.id
+            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,
             }
-            
-            moves_ids_final.append(move.id)
-            if (move.picking_id.type == 'in') and (move.product_id.cost_method == 'average'):
-                partial_datas['move%s' % (move.id)].update({
-                    'product_price' : p_moves[move.id].cost,
-                    'product_currency': p_moves[move.id].currency.id,
-                })
-                
-            
-        move_obj.do_partial(cr, uid, moves_ids_final, partial_datas, context=context)
+            moves_ids.append(move_id)
+            if (move.move_id.picking_id.type == 'in') and (move.product_id.cost_method == 'average'):
+                partial_data['move%s' % (move_id)].update(product_price=move.cost,
+                                                          product_currency=move.currency.id)
+        self.pool.get('stock.move').do_partial(cr, uid, moves_ids, partial_data, context=context)
         return {'type': 'ir.actions.act_window_close'}
 
-stock_partial_move()
-stock_partial_move_memory_out()
-stock_partial_move_memory_in()
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
index 8d4be66..2df6adc 100644 (file)
@@ -1,16 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <openerp>
     <data>
-
-      
-        
         <record id="action_partial_move_server" model="ir.actions.server">
             <field name="name">Deliver/Receive Products</field>
             <field name="model_id" ref="model_stock_move"/>
             <field name="state">code</field>
             <field name="code">action = obj.action_partial_move(context=context)</field>
         </record>
-        
+
         <record id="ir_open_partial_move_wizard" model="ir.values">
             <field eval="'client_action_multi'" name="key2"/>
             <field eval="'stock.move'" name="model"/>
             <field eval="True" name="object"/>
         </record>
 
-        
-            
-        <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="cost" />
-                    <field name="currency" />
-                </tree>
-            </field>
-        </record>
-        
-        <record id="stock_move_memory_form_in" model="ir.ui.view">
-            <field name="name">stock.move.memory.form</field>
-            <field name="model">stock.move.memory.in</field>
+        <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>
-                    <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="cost" />
-                    <field name="currency" />
-                 </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_move_memory_tree_out" model="ir.ui.view">
-            <field name="name">stock.move.memory.tree</field>
-            <field name="model">stock.move.memory.out</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>
             <field name="type">tree</field>
             <field name="arch" type="xml">
                 <tree editable="bottom" string="Product Moves">
                     <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="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)]}"/>
                 </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>
+
+        <record id="stock_partial_move_line_form" model="ir.ui.view">
+            <field name="name">stock.partial.move.line.form</field>
+            <field name="model">stock.partial.move.line</field>
             <field name="type">form</field>
             <field name="arch" type="xml">
                 <form>
                     <field name="location_id" />
                     <field name="location_dest_id" />
                     <field name="prodlot_id" domain="[('product_id', '=', product_id)]" groups="base.group_extended" />
-                </form>
+                    <field name="update_cost" invisible="1"/>
+                    <field name="cost" attrs="{'invisible': [('update_cost','=', False)]}"/>
+                    <field name="currency" attrs="{'invisible': [('update_cost','=', False)]}"/>
+                 </form>
             </field>
-        </record>  
-        
+        </record>
     </data>
 </openerp>
index b31d9c6..3580b21 100644 (file)
@@ -1,9 +1,8 @@
-
 # -*- coding: utf-8 -*-
 ##############################################################################
 #
 #    OpenERP, Open Source Management Solution
-#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
+#    Copyright (C) 2004-TODAY OpenERP SA (<http://openerp.com>).
 #
 #    This program is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU Affero General Public License as
 #
 ##############################################################################
 
-from osv import fields, osv
-from tools.translate import _
 import time
+from osv import fields, osv
+from tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
 
-class stock_partial_picking_memory_out(osv.osv_memory):
-    _name = "stock.picking.memory.out"
+class stock_partial_picking_line(osv.TransientModel):
+    _name = "stock.partial.picking.line"
     _rec_name = 'product_id'
     _columns = {
-        'product_id' : fields.many2one('product.product', string="Product", required=True),
+        'product_id' : fields.many2one('product.product', string="Product", required=True, ondelete='CASCADE'),
         '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'),
-        'location_id': fields.many2one('stock.location', 'Location', required=True),
-        'location_dest_id': fields.many2one('stock.location', 'Dest. Location', required=True),
-        'move_id' : fields.many2one('stock.move', "Move"),
-        'wizard_id' : fields.many2one('stock.partial.picking', string="Wizard"),
+        'product_uom': fields.many2one('product.uom', 'Unit of Measure', required=True, ondelete='CASCADE'),
+        'prodlot_id' : fields.many2one('stock.production.lot', 'Production Lot', ondelete='CASCADE'),
+        'location_id': fields.many2one('stock.location', 'Location', required=True, ondelete='CASCADE'),
+        'location_dest_id': fields.many2one('stock.location', 'Dest. Location', required=True, ondelete='CASCADE'),
+        'move_id' : fields.many2one('stock.move', "Move", ondelete='CASCADE'),
+        'wizard_id' : fields.many2one('stock.partial.picking', string="Wizard", ondelete='CASCADE'),
+        'update_cost': fields.boolean('Need cost update'),
         'cost' : fields.float("Cost", help="Unit Cost for this product line"),
-        'currency' : fields.many2one('res.currency', string="Currency", help="Currency in which Unit cost is expressed"),
+        'currency' : fields.many2one('res.currency', string="Currency", help="Currency in which Unit cost is expressed", ondelete='CASCADE'),
     }
 
-class stock_partial_picking_memory_in(osv.osv_memory):
-    _inherit = "stock.picking.memory.out"
-    _name = "stock.picking.memory.in"
-
 class stock_partial_picking(osv.osv_memory):
     _name = "stock.partial.picking"
-    _description = "Partial Picking"
+    _description = "Partial Picking Processing Wizard"
     _columns = {
         'date': fields.datetime('Date', required=True),
-        'product_moves_out' : fields.one2many('stock.picking.memory.out', 'wizard_id', 'Moves'),
-        'product_moves_in' : fields.one2many('stock.picking.memory.in', 'wizard_id', 'Moves'),
+        'move_ids' : fields.one2many('stock.partial.picking.line', 'wizard_id', 'Product Moves'),
+        'picking_id': fields.many2one('stock.picking', 'Picking', required=True, ondelete='CASCADE'),
      }
 
-    def get_picking_type(self, cr, uid, picking, context=None):
-        picking_type = picking.type
-        for move in picking.move_lines:
-            if picking.type == 'in' and move.product_id.cost_method == 'average':
-                picking_type = 'in'
-                break
-            else:
-                picking_type = 'out'
-        return picking_type
-    
     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.
-        """
-        if context is None:
-            context = {}
-            
-        pick_obj = self.pool.get('stock.picking')
+        if context is None: context = {}
         res = super(stock_partial_picking, self).default_get(cr, uid, fields, context=context)
         picking_ids = context.get('active_ids', [])
-        if not picking_ids:
+        if not picking_ids or (not context.get('active_model') == 'stock.picking') \
+            or len(picking_ids) != 1:
+            # Partial Picking Processing may only be done for one picking at a time
             return res
-
-        result = []
-        for pick in pick_obj.browse(cr, uid, picking_ids, context=context):
-            pick_type = self.get_picking_type(cr, uid, pick, context=context)
-            for m in pick.move_lines:
-                if m.state in ('done', 'cancel'):
-                    continue
-                result.append(self.__create_partial_picking_memory(m, pick_type))
-                
-        if 'product_moves_in' in fields:
-            res.update({'product_moves_in': result})
-        if 'product_moves_out' in fields:
-            res.update({'product_moves_out': result})
+        picking_id, = picking_ids
+        if 'picking_id' in fields:
+            res.update(picking_id=picking_id)
+        if 'move_ids' in fields:
+            picking = self.pool.get('stock.picking').browse(cr, uid, picking_id, context=context)
+            moves = [self._partial_move_for(cr, uid, m) for m in picking.move_lines if m.state not in ('done','cancel')]
+            res.update(move_ids=moves)
         if 'date' in fields:
-            res.update({'date': time.strftime('%Y-%m-%d %H:%M:%S')})
+            res.update(date=time.strftime(DEFAULT_SERVER_DATETIME_FORMAT))
         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_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:
-            # not called through an action (e.g. buildbot), return the default.
-            return result
-
-        for pick in pick_obj.browse(cr, uid, picking_ids, context=context):
-            picking_type = self.get_picking_type(cr, uid, pick, context=context)
+    def _product_cost_for_average_update(self, cr, uid, move):
+        """Returns product cost and currency ID for the given move, suited for re-computing
+           the average product cost.
         
-        _moves_arch_lst = """<form string="%s">
-                        <field name="date" invisible="1"/>
-                        <separator colspan="4" string="%s"/>
-                        <field name="%s" colspan="4" nolabel="1" mode="tree,form" width="550" height="200" ></field>
-                        """ % (_('Process Document'), _('Products'), "product_moves_" + picking_type)
-        _moves_fields = result['fields']
-
-        # add field related to picking type only
-        _moves_fields.update({
-                            'product_moves_' + picking_type: {'relation': 'stock.move.memory.'+picking_type, 'type' : 'one2many', 'string' : 'Product Moves'}, 
-                            })
+           :return: map of the form::
 
-        _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="_Validate"
-                    colspan="1" type="object" icon="gtk-go-forward" />
-            </group>
-        </form>"""
-        result['arch'] = _moves_arch_lst
-        result['fields'] = _moves_fields
-        return result
+                {'cost': 123.34,
+                 'currency': 42}
+        """
+        # Currently, the cost on the product form is supposed to be expressed in the currency
+        # of the company owning the product. If not set, we fall back to the picking's company,
+        # which should work in simple cases.
+        return {'cost': move.product_id.standard_price,
+                'currency': move.product_id.company_id.currency_id.id \
+                                or move.picking_id.company_id.currency_id.id \
+                                or False}
 
-    def __create_partial_picking_memory(self, picking, pick_type):
-        move_memory = {
-            'product_id' : picking.product_id.id, 
-            'quantity' : picking.product_qty, 
-            'product_uom' : picking.product_uom.id, 
-            'prodlot_id' : picking.prodlot_id.id, 
-            'move_id' : picking.id,
-            'location_id' : picking.location_id.id, 
-            'location_dest_id' : picking.location_dest_id.id,  
+    def _partial_move_for(self, cr, uid, move):
+        partial_move = {
+            'product_id' : move.product_id.id,
+            'quantity' : move.product_qty,
+            'product_uom' : move.product_uom.id,
+            'prodlot_id' : move.prodlot_id.id,
+            'move_id' : move.id,
+            'location_id' : move.location_id.id,
+            'location_dest_id' : move.location_dest_id.id,
         }
-    
-        if pick_type == 'in':
-            move_memory.update({
-                'cost' : picking.product_id.standard_price, 
-                'currency' : picking.product_id.company_id and picking.product_id.company_id.currency_id and picking.product_id.company_id.currency_id.id or False, 
-            })
-        return move_memory
+        if move.picking_id.type == 'in' and move.product_id.cost_method == 'average':
+            partial_move.update(update_cost=True, **self._product_cost_for_average_update(cr, uid, move))
+        return partial_move
 
     def do_partial(self, cr, uid, ids, context=None):
-        """ 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')
-        stock_move_obj = self.pool.get('stock.move')
-        picking_ids = context.get('active_ids', False)
+        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')
         partial = self.browse(cr, uid, ids[0], context=context)
-        partial_datas = {
+        partial_data = {
             'delivery_date' : partial.date
         }
-        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:
-                if not move.move_id.id:
-                    seq_obj_name =  'stock.picking.' + picking_type
-                    move_id = stock_move_obj.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': pick.id
-                                                            },context=context)
-                    stock_move_obj.action_done(cr, uid, [move_id], context)
-                else:
-                    move_id = move.move_id.id
-                
-                partial_datas['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_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)
+        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)
         return {'type': 'ir.actions.act_window_close'}
 
-stock_partial_picking()
-stock_partial_picking_memory_out()
-stock_partial_picking_memory_in()
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
index 4887c1e..be85d26 100644 (file)
@@ -9,5 +9,59 @@
             <field name="target">new</field>
         </record>
 
+        <record id="stock_partial_picking_form" model="ir.ui.view">
+            <field name="name">stock.partial.picking.form</field>
+            <field name="model">stock.partial.picking</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_picking_line_list" model="ir.ui.view">
+            <field name="name">stock.partial.picking.line.list</field>
+            <field name="model">stock.partial.picking.line</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)]}"/>
+                </tree>
+            </field>
+        </record>
+        <record id="stock_partial_picking_line_form" model="ir.ui.view">
+            <field name="name">stock.partial.picking.line.form</field>
+            <field name="model">stock.partial.picking.line</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="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)]}"/>
+                 </form>
+            </field>
+        </record>
     </data>
 </openerp>
index eca6f38..2e9e6d2 100644 (file)
       "active_ids": [ref("stock.menu_action_picking_tree")], "active_id": ref("stock.menu_action_picking_tree"),
       })
 -
-  I create a record for partial picking.
--
-  !record {model: stock.partial.picking, id: stock_partial_picking_0}:
-    date: !eval time.strftime('%Y-%m-%d %H:%M:%S')
--
-  I make picking order Done.
+  I process the delivery
 -
   !python {model: stock.partial.picking}: |
-     pick_obj = self.pool.get('stock.picking')
-     partial = self.browse(cr, uid, ref('stock_partial_picking_0'), context)
-     partial_datas = {
-            'delivery_date' : partial.date
-     }
-     for pick in pick_obj.browse(cr, uid, [ref('stock_picking_out0')]):
-        for m in pick.move_lines:
-           partial_datas['move%s'%(m.id)] = {
-                    'product_id' : m.product_id.id,
-                    'product_qty' : m.product_qty,
-                    'product_uom' : m.product_uom.id
-           }
-     pick_obj.do_partial(cr, uid, [ref('stock_picking_out0')], partial_datas, context=context)
+    partial_id = self.create(cr, uid, {}, context={'active_model':'stock.picking',
+                                                   'active_ids':[ref('stock_picking_out0')]})
+    self.do_partial(cr, uid, [partial_id])
 -
   As the Invoice state of the picking order is To be invoiced. I create invoice for my outgoing picking order.
 -
index 11b3172..3725d9b 100644 (file)
@@ -25,24 +25,15 @@ class invoice_directly(osv.osv_memory):
     _inherit = 'stock.partial.picking'
 
     def do_partial(self, cr, uid, ids, context=None):
-        """ Makes partial moves and pickings done and 
-            launches Create invoice wizard if invoice state is To be Invoiced.
-        @param self: The object pointer.
-        @param cr: A database cursor
-        @param uid: ID of the user currently logged in
-        @param context: A standard dictionary
-        @return:
+        """Launch Create invoice wizard if invoice state is To be Invoiced,
+           after processing the partial picking.
         """
-        if context is None:
-            context = {}
+        if context is None: context = {}
         result = super(invoice_directly, self).do_partial(cr, uid, ids, context)
-        pick_obj = self.pool.get('stock.picking')
-        context.update({'active_model':'stock.picking'})
-        picking_ids = context.get('active_ids', False)
-        if picking_ids:
-            context.update({'active_id':picking_ids[0]})
-        pick = pick_obj.browse(cr, uid, picking_ids, context=context)[0]
-        if pick.invoice_state == '2binvoiced':
+        partial = self.browse(cr, uid, ids[0], context)
+        context.update(active_model='stock.picking',
+                       active_ids=[partial.picking_id.id])
+        if partial.picking_id.invoice_state == '2binvoiced':
             return {
                 'name': 'Create Invoice',
                 'view_type': 'form',
@@ -55,5 +46,5 @@ class invoice_directly(osv.osv_memory):
         return {'type': 'ir.actions.act_window_close'}
 
 invoice_directly()
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
 
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file