[IMP] stock: cleanup stock.partial.{picking,move} wizards and fix dependencies and tests

bzr revid: odo@openerp.com-20110926003612-0wa6sghmlwbezwzk
This commit is contained in:
Olivier Dony 2011-09-26 02:36:12 +02:00
parent 3b1196867b
commit e45e0b75d8
17 changed files with 391 additions and 950 deletions

View File

@ -205,9 +205,8 @@
I am checking Procurement orders. There are 3 orders generated for Oranges, Sugar and Water. I am checking Procurement orders. There are 3 orders generated for Oranges, Sugar and Water.
- -
!python {model: procurement.order}: | !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')])]) 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. The scheduler runs.
- -
@ -219,9 +218,8 @@
stock moves for Oranges, Sugar and Water made correctly. stock moves for Oranges, Sugar and Water made correctly.
- -
!python {model: stock.picking}: | !python {model: stock.picking}: |
from tools.translate import _
pick_ids = self.search(cr, uid, [('type','=','internal')]) 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 According to minimum stock rules. I have 2 purchase orders for
Sugar with 6 Kg from Axelor and Orange 60 Kg from ASUStek. Sugar with 6 Kg from Axelor and Orange 60 Kg from ASUStek.
@ -229,50 +227,24 @@
I confirm the purchase order of Sugar and Orange. I confirm the purchase order of Sugar and Orange.
- -
!python {model: purchase.order}: | !python {model: purchase.order}: |
from tools.translate import _
import netsvc import netsvc
purch_ids = self.search(cr, uid, [('state','=','draft')]) 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") wf_service = netsvc.LocalService("workflow")
for p_id in purch_ids: for p_id in purch_ids:
wf_service.trg_validate(uid, 'purchase.order', p_id, 'purchase_confirm', cr) 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}: | !python {model: stock.picking}: |
from tools.translate import _
pick_ids = self.search(cr, uid, [('type','=','in')]) pick_ids = self.search(cr, uid, [('type','=','in')])
assert pick_ids, _('No Incoming Shipments found!') assert pick_ids, 'No Incoming Shipments found!'
- stock_partial_picking = self.pool.get('stock.partial.picking')
I receive both the products. My incoming pickings are done. for pick_id in pick_ids:
- partial_id = stock_partial_picking.create(cr, uid, {},
I create record for the incoming picking wizard. context={'active_model': 'stock.picking',
- 'active_ids': [pick_id]})
!record {model: stock.partial.picking, id: stock_partial_picking0}: stock_partial_picking.do_partial(cr, uid, [partial_id])
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)
- -
Again the scheduler runs. Again the scheduler runs.
- -
@ -283,19 +255,15 @@
I check my internal picking of "Orange Juice" is done. I check my internal picking of "Orange Juice" is done.
- -
!python {model: stock.picking}: | !python {model: stock.picking}: |
from tools.translate import _
pick_ids = self.search(cr, uid, [('type','=','internal'),('state','=','done')]) 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. I check my manufacturing order for "Orange Juice" is ready or not.
- -
!python {model: mrp.production}: | !python {model: mrp.production}: |
from tools.translate import _ prod_ids = self.search(cr, uid, [('state','=','ready'),('id','=',ref('mrp_production_mo0'))])
pick_ids = self.search(cr, uid, [('state','=','ready'),('id','=',ref('mrp_production_mo0'))]) assert prod_ids, 'Manufacturing order is not ready!'
assert pick_ids, _('Manufacturing order is not ready!')
- -
I start the production order. I start the production order.
- -
!workflow {model: mrp.production, action: button_produce, ref: mrp_production_mo0} !workflow {model: mrp.production, action: button_produce, ref: mrp_production_mo0}

View File

@ -195,74 +195,26 @@
I Check incoming shipments for cloth. And receive products. I Check incoming shipments for cloth. And receive products.
- -
!python {model: stock.picking}: | !python {model: stock.picking}: |
from tools.translate import _
pick_ids = self.search(cr, uid, [('address_id.name','=','Wong'),('state','=','assigned')]) pick_ids = self.search(cr, uid, [('address_id.name','=','Wong'),('state','=','assigned')])
assert pick_ids, _('No Incoming Shipments found!') assert pick_ids, 'No Incoming Shipments found!'
- stock_partial_picking = self.pool.get('stock.partial.picking')
I create record for partial picking. for pick_id in pick_ids:
- partial_id = stock_partial_picking.create(cr, uid, {},
!record {model: stock.partial.picking, id: stock_partial_picking0}: context={'active_model': 'stock.picking',
date: !eval datetime.today().strftime("%Y-%m-%d %H:%M:%S") 'active_ids': [pick_id]})
stock_partial_picking.do_partial(cr, uid, [partial_id])
-
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)
- -
I Check incoming shipments for buttons and receive products. I Check incoming shipments for buttons and receive products.
- -
!python {model: stock.picking}: | !python {model: stock.picking}: |
from tools.translate import _
pick_ids = self.search(cr, uid, [('address_id.name','=','Tang'),('state','=','assigned')]) pick_ids = self.search(cr, uid, [('address_id.name','=','Tang'),('state','=','assigned')])
assert pick_ids, _('No Incoming Shipments found!') assert pick_ids, 'No Incoming Shipments found!'
- stock_partial_picking = self.pool.get('stock.partial.picking')
I create record for partial picking. for pick_id in pick_ids:
- partial_id = stock_partial_picking.create(cr, uid, {},
!record {model: stock.partial.picking, id: stock_partial_picking0}: context={'active_model': 'stock.picking',
date: !eval datetime.today().strftime("%Y-%m-%d %H:%M:%S") 'active_ids': [pick_id]})
stock_partial_picking.do_partial(cr, uid, [partial_id])
-
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)
- -
Run scheduler again. Run scheduler again.
- -
@ -297,7 +249,6 @@
I produce 2 products with 5.00 quantities each. I produce 2 products with 5.00 quantities each.
- -
!python {model: mrp.product.produce}: | !python {model: mrp.product.produce}: |
from tools.translate import _
prod_obj = self.pool.get('mrp.production') prod_obj = self.pool.get('mrp.production')
prod_ids = prod_obj.search(cr, uid, [('product_id.name','=','Shirt')]) 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}) self.do_produce(cr, uid, [ref('mrp_product_produce0')], context={'active_ids': prod_ids})
@ -321,8 +272,7 @@
And finally production order is done. And finally production order is done.
- -
!python {model: mrp.product.produce}: | !python {model: mrp.product.produce}: |
from tools.translate import _
prod_obj = self.pool.get('mrp.production') prod_obj = self.pool.get('mrp.production')
prod_ids = prod_obj.search(cr, uid, [('product_id.name','=','Shirt')]) 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})

View File

@ -124,68 +124,15 @@ class stock_picking(osv.osv):
purchase_obj.write(cursor, user, [picking.purchase_id.id], {'invoice_id': invoice_id,}) 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) return super(stock_picking, self)._invoice_hook(cursor, user, picking, invoice_id)
stock_picking()
class stock_partial_picking(osv.osv_memory): class stock_partial_picking(osv.osv_memory):
_inherit = 'stock.partial.picking' _inherit = 'stock.partial.picking'
def default_get(self, cr, uid, fields, context=None): # Overridden to inject the purchase price as true 'cost price' when processing
""" To get default values for the object. # incoming pickings.
@param self: The object pointer. def _product_cost_for_average_update(self, cr, uid, move):
@param cr: A database cursor if move.picking_id.purchase_id:
@param uid: ID of the user currently logged in return {'cost': move.purchase_line_id.price_unit,
@param fields: List of fields for which we want default values 'currency': move.picking_id.purchase_id.pricelist_id.currency_id.id}
@param context: A standard dictionary return super(stock_partial_picking, self)._product_cost_for_average_update(cr, uid, move)
@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: # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -31,39 +31,17 @@
- -
!workflow {model: sale.order, action: order_confirm, ref: sale_order_so9} !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}: | !python {model: sale.order}: |
so = self.browse(cr, uid, ref("sale_order_so9")) so = self.browse(cr, uid, ref("sale_order_so9"))
assert so.picking_ids,"Picking has not been generated for sale_order_so9" assert so.picking_ids,"Picking has not been generated for sale_order_so9"
- picking, = so.picking_ids
Then I confirm the picking stock_partial_picking = self.pool.get('stock.partial.picking')
- partial_id = stock_partial_picking.create(cr, uid, {},
!record {model: stock.partial.picking, id: stock_partial_picking_0}: context={'active_model': 'stock.picking',
date: !eval time.strftime('%Y-%m-%d %H:%M:%S') 'active_ids': [picking.id]})
- stock_partial_picking.do_partial(cr, uid, [partial_id])
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)
- -
I click on Create Invoice button to create the invoice. I click on Create Invoice button to create the invoice.
- -

View File

@ -30,41 +30,21 @@
- -
!workflow {model: sale.order, action: order_confirm, ref: sale_order_so6} !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}: | !python {model: sale.order}: |
so = self.browse(cr, uid, ref("sale_order_so6")) so = self.browse(cr, uid, ref("sale_order_so6"))
assert so.picking_ids,"Picking has not been generated for sale_order_so6" assert so.picking_ids,"Picking has not been generated for sale_order_so6"
- picking, = so.picking_ids
Then I click on the "Product Sent" button of Outgoing Shipments stock_partial_picking = self.pool.get('stock.partial.picking')
- partial_id = stock_partial_picking.create(cr, uid, {},
!record {model: stock.partial.picking, id: stock_partial_picking_0}: context={'active_model': 'stock.picking',
date: !eval time.strftime('%Y-%m-%d %H:%M:%S') 'active_ids': [picking.id]})
- # I change the qty to 100 for a partial delivery
I change the quantity on the picking to 199, and confirm partially 100 PCE. partial = stock_partial_picking.browse(cr,uid,partial_id)
- line_id = partial.move_ids[0].id
!python {model: stock.picking }: | partial.write({'move_ids': [(1,line_id,{'quantity':100})]})
import time partial.do_partial()
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)
- -
Then I click on 'Create Invoices' button Then I click on 'Create Invoices' button
- -
@ -72,7 +52,7 @@
import time import time
sale_obj = self.pool.get('sale.order') sale_obj = self.pool.get('sale.order')
sale_id = sale_obj.browse(cr, uid, ref("sale_order_so6")) 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')}, 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'}) {'active_ids': ids, 'active_model': 'stock.picking'})
self.create_invoice(cr, uid, [wiz_id], {"active_ids": ids, "active_id": ids[0]}) 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] inv_brw = self.browse(cr,uid,inv_id)[0]
for inv_lines in inv_brw.invoice_line: for inv_lines in inv_brw.invoice_line:
qty1=inv_lines.quantity 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. I open the Invoice for the SO.
- -

View File

@ -136,15 +136,10 @@
I verify that a procurement state is "running" I verify that a procurement state is "running"
- -
!python {model: procurement.order}: | !python {model: procurement.order}: |
from tools.translate import _ sale_order_obj = self.pool.get('sale.order')
modules = self.pool.get('ir.module.module') so = sale_order_obj.browse(cr, uid, ref("sale_order_so0"))
mod_pur = modules.search(cr, uid, [('name','=','purchase')]) proc_ids = self.search(cr, uid, [('origin','=',so.name),('state','=','running')])
mod_brw = modules.browse(cr,uid,mod_pur)[0] assert(proc_ids),"Procurement is not in the running state!"
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!"
- -
I verify that a purchase order has been generated I verify that a purchase order has been generated
- -
@ -192,7 +187,7 @@
for pur in pur_ids: for pur in pur_ids:
wf_service.trg_validate(uid, 'purchase.order',pur,'purchase_approve', cr) 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}: | !python {model: sale.order}: |
modules = self.pool.get('ir.module.module') modules = self.pool.get('ir.module.module')
@ -204,29 +199,12 @@
pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)]) pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)])
po = pur_obj.browse(cr, uid, pur_id)[0] po = pur_obj.browse(cr, uid, pur_id)[0]
assert(po.picking_ids),"Picking for purchase order has not been generated" assert(po.picking_ids),"Picking for purchase order has not been generated"
- picking, = po.picking_ids
Then I click on the "Products Received" button of Incoming Shipments stock_partial_picking = self.pool.get('stock.partial.picking')
- partial_id = stock_partial_picking.create(cr, uid, {},
!record {model: stock.partial.picking, id: stock_partial_picking_0}: context={'active_model': 'stock.picking',
date: !eval time.strftime('%Y-%m-%d %H:%M:%S') 'active_ids': [picking.id]})
- stock_partial_picking.do_partial(cr, uid, [partial_id])
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)
- -
I verify that picking for purchase order has been done. I verify that picking for purchase order has been done.
- -
@ -244,7 +222,7 @@
ids = picking_obj.search(cr, uid, [('purchase_id', '=', po.id ),('state', '=', 'done')]) ids = picking_obj.search(cr, uid, [('purchase_id', '=', po.id ),('state', '=', 'done')])
assert(ids),"Picking is not in the done state!" assert(ids),"Picking is not in the done state!"
- -
Then I done the picking Then I process the picking
- -
!python {model: stock.picking }: | !python {model: stock.picking }: |
import time import time
@ -254,18 +232,11 @@
if picking_id: if picking_id:
pick=self.browse(cr,uid,picking_id[0]) pick=self.browse(cr,uid,picking_id[0])
pick.force_assign(cr, uid) pick.force_assign(cr, uid)
partial_datas = { stock_partial_picking = self.pool.get('stock.partial.picking')
'partner_id':pick.address_id.partner_id.id, partial_id = stock_partial_picking.create(cr, uid, {},
'address_id': pick.address_id.id, context={'active_model': 'stock.picking',
'delivery_date' : time.strftime('%Y-%m-%d'), 'active_ids': [pick.id]})
} stock_partial_picking.do_partial(cr, uid, [partial_id])
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 picking for sale order is in done state. I verify that picking for sale order is in done state.
- -
@ -275,38 +246,6 @@
picking_id = self.search(cr, uid, [('origin','=',so.name),('type','=','out')]) picking_id = self.search(cr, uid, [('origin','=',so.name),('type','=','out')])
pick = self.browse(cr,uid,picking_id[0]) pick = self.browse(cr,uid,picking_id[0])
assert (pick.state) =='done', "Picking for SO is not in done state." 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 I verify that a "Picked" has been set to true
- -

View File

@ -46,18 +46,11 @@
if picking_id: if picking_id:
pick=self.browse(cr,uid,picking_id[0]) pick=self.browse(cr,uid,picking_id[0])
pick.force_assign(cr, uid) pick.force_assign(cr, uid)
partial_datas = { stock_partial_picking = self.pool.get('stock.partial.picking')
'partner_id':pick.address_id.partner_id.id, partial_id = stock_partial_picking.create(cr, uid, {},
'address_id': pick.address_id.id, context={'active_model': 'stock.picking',
'delivery_date' : time.strftime('%Y-%m-%d'), 'active_ids': [pick.id]})
} stock_partial_picking.do_partial(cr, uid, [partial_id])
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)
- -
Then I click on 'Create Invoices' button Then I click on 'Create Invoices' button
- -
@ -197,7 +190,7 @@
for pur in pur_ids: for pur in pur_ids:
wf_service.trg_validate(uid, 'purchase.order',pur,'purchase_approve', cr) 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}: | !python {model: sale.order}: |
modules = self.pool.get('ir.module.module') modules = self.pool.get('ir.module.module')
@ -209,29 +202,12 @@
pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)]) pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)])
po = pur_obj.browse(cr, uid, pur_id)[0] po = pur_obj.browse(cr, uid, pur_id)[0]
assert(po.picking_ids),"Picking for purchase order has not been generated" assert(po.picking_ids),"Picking for purchase order has not been generated"
- picking, = po.picking_ids
Then I click on the "Products Received" button of Incoming Shipments stock_partial_picking = self.pool.get('stock.partial.picking')
- partial_id = stock_partial_picking.create(cr, uid, {},
!record {model: stock.partial.picking, id: stock_partial_picking_0}: context={'active_model': 'stock.picking',
date: !eval time.strftime('%Y-%m-%d %H:%M:%S') 'active_ids': [picking.id]})
- stock_partial_picking.do_partial(cr, uid, [partial_id])
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)
- -
I verify that picking for purchase order has been done. I verify that picking for purchase order has been done.
- -
@ -249,36 +225,20 @@
ids = picking_obj.search(cr, uid, [('purchase_id', '=', po.id ),('state', '=', 'done')]) ids = picking_obj.search(cr, uid, [('purchase_id', '=', po.id ),('state', '=', 'done')])
assert ids, _('Picking is not in the done state!') 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 }: | !python {model: stock.picking }: |
sale_order_obj = self.pool.get('sale.order') sale_order_obj = self.pool.get('sale.order')
so = sale_order_obj.browse(cr, uid, ref("sale_order_so7")) so = sale_order_obj.browse(cr, uid, ref("sale_order_so7"))
picking_id = self.search(cr, uid, [('origin','=',so.name)]) picking_id = self.search(cr, uid, [('origin','=',so.name)])
assert (picking_id),"Delivery order has not been generated" assert (picking_id),"Delivery order has not been generated"
- pick=self.browse(cr,uid,picking_id[0])
I verify that delivery has been done pick.force_assign(cr, uid)
- stock_partial_picking = self.pool.get('stock.partial.picking')
!python {model: stock.picking }: | partial_id = stock_partial_picking.create(cr, uid, {},
import time context={'active_model': 'stock.picking',
sale_order_obj = self.pool.get('sale.order') 'active_ids': [pick.id]})
so = sale_order_obj.browse(cr, uid, ref("sale_order_so7")) stock_partial_picking.do_partial(cr, uid, [partial_id])
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 I verify that delivery state is done
- -
@ -290,7 +250,7 @@
pick = self.browse(cr,uid,picking_id[0]) pick = self.browse(cr,uid,picking_id[0])
assert (pick.state) =='done', "Picking for SO is not in done state." 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}: | !python {model: sale.order}: |
so = self.browse(cr, uid, ref("sale_order_so7")) so = self.browse(cr, uid, ref("sale_order_so7"))

View File

@ -45,18 +45,11 @@
if picking_id: if picking_id:
pick=self.browse(cr,uid,picking_id[0]) pick=self.browse(cr,uid,picking_id[0])
pick.force_assign(cr, uid) pick.force_assign(cr, uid)
partial_datas = { stock_partial_picking = self.pool.get('stock.partial.picking')
'partner_id':pick.address_id.partner_id.id, partial_id = stock_partial_picking.create(cr, uid, {},
'address_id': pick.address_id.id, context={'active_model': 'stock.picking',
'delivery_date' : time.strftime('%Y-%m-%d'), 'active_ids': [pick.id]})
} stock_partial_picking.do_partial(cr, uid, [partial_id])
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 picking order is in done state. I verify that picking order is in done state.
- -
@ -76,7 +69,7 @@
picking_id = self.search(cr, uid, [('origin','=',so.name)]) picking_id = self.search(cr, uid, [('origin','=',so.name)])
assert (picking_id),"Delivery order has not been generated" 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 }: | !python {model: stock.picking }: |
import time import time
@ -86,20 +79,13 @@
if picking_id: if picking_id:
pick=self.browse(cr,uid,picking_id[0]) pick=self.browse(cr,uid,picking_id[0])
pick.force_assign(cr, uid) pick.force_assign(cr, uid)
partial_datas = { stock_partial_picking = self.pool.get('stock.partial.picking')
'partner_id':pick.address_id.partner_id.id, partial_id = stock_partial_picking.create(cr, uid, {},
'address_id': pick.address_id.id, context={'active_model': 'stock.picking',
'delivery_date' : time.strftime('%Y-%m-%d'), 'active_ids': [pick.id]})
} stock_partial_picking.do_partial(cr, uid, [partial_id])
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 I verify that delivery order is marked done
- -
!python {model: stock.picking }: | !python {model: stock.picking }: |
sale_order_obj = self.pool.get('sale.order') sale_order_obj = self.pool.get('sale.order')
@ -187,7 +173,7 @@
for pur in pur_ids: for pur in pur_ids:
wf_service.trg_validate(uid, 'purchase.order',pur,'purchase_approve', cr) 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}: | !python {model: sale.order}: |
modules = self.pool.get('ir.module.module') modules = self.pool.get('ir.module.module')
@ -199,31 +185,14 @@
pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)]) pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)])
po = pur_obj.browse(cr, uid, pur_id)[0] po = pur_obj.browse(cr, uid, pur_id)[0]
assert(po.picking_ids),"Picking for purchase order has not been generated" 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 I verify that picking for purchase order has been marked done.
-
!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.
- -
!python {model: sale.order}: | !python {model: sale.order}: |
from tools.translate import _ from tools.translate import _
@ -239,7 +208,7 @@
ids = picking_obj.search(cr, uid, [('purchase_id', '=', po.id ),('state', '=', 'done')]) ids = picking_obj.search(cr, uid, [('purchase_id', '=', po.id ),('state', '=', 'done')])
assert ids, _('Picking is not in the done state!') 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}: | !python {model: sale.order}: |
so = self.browse(cr, uid, ref("sale_order_so8")) so = self.browse(cr, uid, ref("sale_order_so8"))

View File

@ -101,18 +101,11 @@
if picking_id: if picking_id:
pick=self.browse(cr,uid,picking_id[0]) pick=self.browse(cr,uid,picking_id[0])
pick.force_assign(cr, uid) pick.force_assign(cr, uid)
partial_datas = { stock_partial_picking = self.pool.get('stock.partial.picking')
'partner_id':pick.address_id.partner_id.id, partial_id = stock_partial_picking.create(cr, uid, {},
'address_id': pick.address_id.id, context={'active_model': 'stock.picking',
'delivery_date' : time.strftime('%Y-%m-%d'), 'active_ids': [pick.id]})
} stock_partial_picking.do_partial(cr, uid, [partial_id])
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 picking order is in done state. I verify that picking order is in done state.
- -
@ -201,7 +194,7 @@
for pur in pur_ids: for pur in pur_ids:
wf_service.trg_validate(uid, 'purchase.order',pur,'purchase_approve', cr) 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}: | !python {model: sale.order}: |
modules = self.pool.get('ir.module.module') modules = self.pool.get('ir.module.module')
@ -213,51 +206,21 @@
pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)]) pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)])
po = pur_obj.browse(cr, uid, pur_id)[0] po = pur_obj.browse(cr, uid, pur_id)[0]
assert(po.picking_ids),"Picking for purchase order has not been generated" assert(po.picking_ids),"Picking for purchase order has not been generated"
- picking, = po.picking_ids
Then I click on the "Products Received" button of Incoming Shipments stock_partial_picking = self.pool.get('stock.partial.picking')
- partial_id = stock_partial_picking.create(cr, uid, {},
!record {model: stock.partial.picking, id: stock_partial_picking_0}: context={'active_model': 'stock.picking',
date: !eval time.strftime('%Y-%m-%d %H:%M:%S') 'active_ids': [picking.id]})
- stock_partial_picking.do_partial(cr, uid, [partial_id])
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_obj = self.pool.get('stock.picking') picking_obj = self.pool.get('stock.picking')
ids = picking_obj.search(cr, uid, [('purchase_id', '=', po.id ),('state', '=', 'done')]) ids = picking_obj.search(cr, uid, [('purchase_id', '=', po.id),('state', '=', 'done')])
assert ids, _('Picking is not in the done state!') 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}: | !python {model: sale.order}: |
so = self.browse(cr, uid, ref("sale_order_so1")) 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 I verify that a sale order is in done state
- -

View File

@ -664,8 +664,8 @@ class stock_picking(osv.osv):
def action_process(self, cr, uid, ids, context=None): def action_process(self, cr, uid, ids, context=None):
if context is None: context = {} if context is None: context = {}
partial_id = self.pool.get("stock.partial.picking").create( context = dict(context, active_ids=ids, active_model=self._name)
cr, uid, {}, context=dict(context, active_ids=ids)) partial_id = self.pool.get("stock.partial.picking").create(cr, uid, {}, context=context)
return { return {
'name':_("Products to Process"), 'name':_("Products to Process"),
'view_mode': 'form', 'view_mode': 'form',
@ -677,7 +677,7 @@ class stock_picking(osv.osv):
'nodestroy': True, 'nodestroy': True,
'target': 'new', 'target': 'new',
'domain': '[]', 'domain': '[]',
'context': dict(context, active_ids=ids) 'context': context,
} }
def copy(self, cr, uid, id, default=None, context=None): 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): def action_partial_move(self, cr, uid, ids, context=None):
if context is None: context = {} 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( partial_id = self.pool.get("stock.partial.move").create(
cr, uid, {}, context=context) cr, uid, {}, context=context)
return { 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. """ Makes the move done and if all moves are done, it will finish the picking.
@return: @return:
""" """
partial_datas=''
picking_ids = [] picking_ids = []
move_ids = [] move_ids = []
partial_obj=self.pool.get('stock.partial.picking')
wf_service = netsvc.LocalService("workflow") 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: if context is None:
context = {} context = {}
@ -2160,9 +2157,6 @@ class stock_move(osv.osv):
self.action_done(cr, uid, [move.move_dest_id.id], context=context) self.action_done(cr, uid, [move.move_dest_id.id], context=context)
self._create_product_valuation_moves(cr, uid, move, 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'): if move.state not in ('confirmed','done','assigned'):
todo.append(move.id) todo.append(move.id)

View File

@ -287,16 +287,9 @@
- -
!python {model: stock.picking }: | !python {model: stock.picking }: |
import time import time
pick=self.browse(cr,uid,ref('stock_picking_0')) pick = self.browse(cr,uid,ref('stock_picking_0'))
move =pick.move_lines[0] stock_partial_picking = self.pool.get('stock.partial.picking')
partial_datas = { partial_id = stock_partial_picking.create(cr, uid, {},
'partner_id':pick.address_id.partner_id.id, context={'active_model': 'stock.picking',
'address_id': pick.address_id.id, 'active_ids': [pick.id]})
'delivery_date' : time.strftime('%Y-%m-%d') stock_partial_picking.do_partial(cr, uid, [partial_id])
}
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)

View File

@ -2,7 +2,7 @@
############################################################################## ##############################################################################
# #
# OpenERP, Open Source Management Solution # 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 # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -20,204 +20,65 @@
############################################################################## ##############################################################################
from osv import fields, osv from osv import fields, osv
from tools.translate import _ from tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
import time import time
import decimal_precision as dp
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", ondelete='CASCADE'),
}
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"
_columns = {
'wizard_id' : fields.many2one('stock.partial.move', string="Wizard"),
}
class stock_partial_move(osv.osv_memory): class stock_partial_move(osv.osv_memory):
_name = "stock.partial.move" _name = "stock.partial.move"
_description = "Partial Move" _inherit = 'stock.partial.picking'
_description = "Partial Move Processing Wizard"
_columns = { _columns = {
'date': fields.datetime('Date', required=True), 'date': fields.datetime('Date', required=True),
'type': fields.char("Type", size=3), 'move_ids' : fields.one2many('stock.partial.move.line', 'wizard_id', 'Moves'),
'product_moves_out' : fields.one2many('stock.move.memory.out', 'wizard_id', 'Moves'),
'product_moves_in' : fields.one2many('stock.move.memory.in', 'wizard_id', 'Moves'),
}
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): # picking_id is not used for move processing, so we remove the required attribute
move_obj = self.pool.get('stock.move') # from the inherited column, and ignore it
if context is None: 'picking_id': fields.many2one('stock.picking', 'Picking'),
context = {} }
res = [] def default_get(self, cr, uid, fields, context=None):
for move in move_obj.browse(cr, uid, context.get('active_ids', []), context=context): if context is None: context = {}
if move.state in ('done', 'cancel'): # no call to super!
continue res = {}
res.append(self.__create_partial_move_memory(move)) 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 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): def do_partial(self, cr, uid, ids, context=None):
""" Makes partial moves and pickings done. # no call to super!
@param self: The object pointer. assert len(ids) == 1, 'Partial move processing may only be done one form at a time'
@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)
partial = self.browse(cr, uid, ids[0], context=context) partial = self.browse(cr, uid, ids[0], context=context)
partial_datas = { partial_data = {
'delivery_date' : partial.date 'delivery_date' : partial.date
} }
moves_ids = []
p_moves = {} for move in partial.move_ids:
picking_type = self.__get_picking_type(cr, uid, move_ids) move_id = move.move_id.id
partial_data['move%s' % (move_id)] = {
moves_list = picking_type == 'product_moves_in' and partial.product_moves_in or partial.product_moves_out 'product_id': move.product_id.id,
for product_move in moves_list: 'product_qty': move.quantity,
p_moves[product_move.move_id.id] = product_move 'product_uom': move.product_uom.id,
'prodlot_id': move.prodlot_id.id,
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.append(move_id)
moves_ids_final.append(move.id) if (move.move_id.picking_id.type == 'in') and (move.product_id.cost_method == 'average'):
if (move.picking_id.type == 'in') and (move.product_id.cost_method == 'average'): partial_data['move%s' % (move_id)].update(product_price=move.cost,
partial_datas['move%s' % (move.id)].update({ product_currency=move.currency.id)
'product_price' : p_moves[move.id].cost, self.pool.get('stock.move').do_partial(cr, uid, moves_ids, partial_data, context=context)
'product_currency': p_moves[move.id].currency.id,
})
move_obj.do_partial(cr, uid, moves_ids_final, partial_datas, context=context)
return {'type': 'ir.actions.act_window_close'} return {'type': 'ir.actions.act_window_close'}
stock_partial_move() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
stock_partial_move_memory_out()
stock_partial_move_memory_in()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,16 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<openerp> <openerp>
<data> <data>
<record id="action_partial_move_server" model="ir.actions.server"> <record id="action_partial_move_server" model="ir.actions.server">
<field name="name">Deliver/Receive Products</field> <field name="name">Deliver/Receive Products</field>
<field name="model_id" ref="model_stock_move"/> <field name="model_id" ref="model_stock_move"/>
<field name="state">code</field> <field name="state">code</field>
<field name="code">action = obj.action_partial_move(context=context)</field> <field name="code">action = obj.action_partial_move(context=context)</field>
</record> </record>
<record id="ir_open_partial_move_wizard" model="ir.values"> <record id="ir_open_partial_move_wizard" model="ir.values">
<field eval="'client_action_multi'" name="key2"/> <field eval="'client_action_multi'" name="key2"/>
<field eval="'stock.move'" name="model"/> <field eval="'stock.move'" name="model"/>
@ -19,75 +16,60 @@
<field eval="True" name="object"/> <field eval="True" name="object"/>
</record> </record>
<record id="stock_partial_move_form" model="ir.ui.view">
<field name="name">stock.partial.move.form</field>
<record id="stock_move_memory_tree_in" model="ir.ui.view"> <field name="model">stock.partial.move</field>
<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>
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form> <form>
<field name="product_id" /> <separator colspan="4" string="Products"/>
<field name="quantity" /> <field name="move_ids" colspan="4" nolabel="1" mode="tree,form" width="550" height="200"/>
<field name="product_uom" /> <separator string="" colspan="4" />
<field name="location_id" /> <label string="" colspan="2"/>
<field name="location_dest_id" /> <group col="2" colspan="2">
<field name="prodlot_id" domain="[('product_id', '=', product_id)]" groups="base.group_extended" /> <button icon='gtk-cancel' special="cancel" string="_Cancel" />
<field name="cost" /> <button name="do_partial" string="_Validate" colspan="1" type="object" icon="gtk-go-forward" />
<field name="currency" /> </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>
<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" />
</tree>
</field>
</record>
<record id="stock_move_memory_form_out" model="ir.ui.view">
<field name="name">stock.move.memory.form</field>
<field name="model">stock.move.memory.out</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form>
<field name="product_id" />
<field name="quantity" />
<field name="product_uom" />
<field name="location_id" />
<field name="location_dest_id" />
<field name="prodlot_id" domain="[('product_id', '=', product_id)]" groups="base.group_extended" />
</form> </form>
</field> </field>
</record> </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_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_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="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> </data>
</openerp> </openerp>

View File

@ -1,9 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
############################################################################## ##############################################################################
# #
# OpenERP, Open Source Management Solution # 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 # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -20,191 +19,119 @@
# #
############################################################################## ##############################################################################
from osv import fields, osv
from tools.translate import _
import time import time
from osv import fields, osv
from tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
class stock_partial_picking_memory_out(osv.osv_memory): class stock_partial_picking_line(osv.TransientModel):
_name = "stock.picking.memory.out" _name = "stock.partial.picking.line"
_rec_name = 'product_id' _rec_name = 'product_id'
_columns = { _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), 'quantity' : fields.float("Quantity", required=True),
'product_uom': fields.many2one('product.uom', 'Unit of Measure', required=True), 'product_uom': fields.many2one('product.uom', 'Unit of Measure', required=True, ondelete='CASCADE'),
'prodlot_id' : fields.many2one('stock.production.lot', 'Production Lot'), 'prodlot_id' : fields.many2one('stock.production.lot', 'Production Lot', ondelete='CASCADE'),
'location_id': fields.many2one('stock.location', 'Location', required=True), 'location_id': fields.many2one('stock.location', 'Location', required=True, ondelete='CASCADE'),
'location_dest_id': fields.many2one('stock.location', 'Dest. Location', required=True), 'location_dest_id': fields.many2one('stock.location', 'Dest. Location', required=True, ondelete='CASCADE'),
'move_id' : fields.many2one('stock.move', "Move"), 'move_id' : fields.many2one('stock.move', "Move", ondelete='CASCADE'),
'wizard_id' : fields.many2one('stock.partial.picking', string="Wizard"), '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"), '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): class stock_partial_picking(osv.osv_memory):
_name = "stock.partial.picking" _name = "stock.partial.picking"
_description = "Partial Picking" _description = "Partial Picking Processing Wizard"
_columns = { _columns = {
'date': fields.datetime('Date', required=True), 'date': fields.datetime('Date', required=True),
'product_moves_out' : fields.one2many('stock.picking.memory.out', 'wizard_id', 'Moves'), 'move_ids' : fields.one2many('stock.partial.picking.line', 'wizard_id', 'Product Moves'),
'product_moves_in' : fields.one2many('stock.picking.memory.in', 'wizard_id', '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): def default_get(self, cr, uid, fields, context=None):
""" To get default values for the object. if context is None: context = {}
@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) res = super(stock_partial_picking, self).default_get(cr, uid, fields, context=context)
picking_ids = context.get('active_ids', []) 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 return res
picking_id, = picking_ids
result = [] if 'picking_id' in fields:
for pick in pick_obj.browse(cr, uid, picking_ids, context=context): res.update(picking_id=picking_id)
pick_type = self.get_picking_type(cr, uid, pick, context=context) if 'move_ids' in fields:
for m in pick.move_lines: picking = self.pool.get('stock.picking').browse(cr, uid, picking_id, context=context)
if m.state in ('done', 'cancel'): moves = [self._partial_move_for(cr, uid, m) for m in picking.move_lines if m.state not in ('done','cancel')]
continue res.update(move_ids=moves)
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})
if 'date' in fields: 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 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: def _product_cost_for_average_update(self, cr, uid, move):
# not called through an action (e.g. buildbot), return the default. """Returns product cost and currency ID for the given move, suited for re-computing
return result the average product cost.
for pick in pick_obj.browse(cr, uid, picking_ids, context=context):
picking_type = self.get_picking_type(cr, uid, pick, context=context)
_moves_arch_lst = """<form string="%s"> :return: map of the form::
<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 {'cost': 123.34,
_moves_fields.update({ 'currency': 42}
'product_moves_' + picking_type: {'relation': 'stock.move.memory.'+picking_type, 'type' : 'one2many', 'string' : 'Product Moves'}, """
}) # 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}
_moves_arch_lst += """ def _partial_move_for(self, cr, uid, move):
<separator string="" colspan="4" /> partial_move = {
<label string="" colspan="2"/> 'product_id' : move.product_id.id,
<group col="2" colspan="2"> 'quantity' : move.product_qty,
<button icon='gtk-cancel' special="cancel" 'product_uom' : move.product_uom.id,
string="_Cancel" /> 'prodlot_id' : move.prodlot_id.id,
<button name="do_partial" string="_Validate" 'move_id' : move.id,
colspan="1" type="object" icon="gtk-go-forward" /> 'location_id' : move.location_id.id,
</group> 'location_dest_id' : move.location_dest_id.id,
</form>"""
result['arch'] = _moves_arch_lst
result['fields'] = _moves_fields
return result
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,
} }
if move.picking_id.type == 'in' and move.product_id.cost_method == 'average':
if pick_type == 'in': partial_move.update(update_cost=True, **self._product_cost_for_average_update(cr, uid, move))
move_memory.update({ return partial_move
'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
def do_partial(self, cr, uid, ids, context=None): def do_partial(self, cr, uid, ids, context=None):
""" Makes partial moves and pickings done. assert len(ids) == 1, 'Partial picking processing may only be done one at a time'
@param self: The object pointer. stock_picking = self.pool.get('stock.picking')
@param cr: A database cursor stock_move = self.pool.get('stock.move')
@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)
partial = self.browse(cr, uid, ids[0], context=context) partial = self.browse(cr, uid, ids[0], context=context)
partial_datas = { partial_data = {
'delivery_date' : partial.date 'delivery_date' : partial.date
} }
for pick in pick_obj.browse(cr, uid, picking_ids, context=context): picking_type = partial.picking_id.type
picking_type = self.get_picking_type(cr, uid, pick, context=context) for move in partial.move_ids:
moves_list = picking_type == 'in' and partial.product_moves_in or partial.product_moves_out move_id = move.move_id.id
for move in moves_list: if not move_id:
if not move.move_id.id: seq_obj_name = 'stock.picking.' + picking_type
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),
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_id': move.product_id.id, 'product_qty': move.quantity,
'product_qty': move.quantity, 'product_uom': move.product_uom.id,
'product_uom': move.product_uom.id, 'prodlot_id': move.prodlot_id.id,
'prodlot_id': move.prodlot_id.id, 'location_id' : move.location_id.id,
'location_id' : move.location_id.id, 'location_dest_id' : move.location_dest_id.id,
'location_dest_id' : move.location_dest_id.id, 'picking_id': partial.picking_id.id
'picking_id': pick.id },context=context)
},context=context) stock_move.action_done(cr, uid, [move_id], context)
stock_move_obj.action_done(cr, uid, [move_id], context) partial_data['move%s' % (move_id)] = {
else: 'product_id': move.product_id.id,
move_id = move.move_id.id 'product_qty': move.quantity,
'product_uom': move.product_uom.id,
partial_datas['move%s' % (move_id)] = { 'prodlot_id': move.prodlot_id.id,
'product_id': move.product_id.id, }
'product_qty': move.quantity, if (picking_type == 'in') and (move.product_id.cost_method == 'average'):
'product_uom': move.product_uom.id, partial_data['move%s' % (move.move_id.id)].update(product_price=move.cost,
'prodlot_id': move.prodlot_id.id, product_currency=move.currency.id)
} stock_picking.do_partial(cr, uid, [partial.picking_id.id], partial_data, context=context)
if (picking_type == 'in') and (move.product_id.cost_method == 'average'):
partial_datas['move%s' % (move.move_id.id)].update({
'product_price' : move.cost,
'product_currency': move.currency.id,
})
pick_obj.do_partial(cr, uid, picking_ids, partial_datas, context=context)
return {'type': 'ir.actions.act_window_close'} return {'type': 'ir.actions.act_window_close'}
stock_partial_picking() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
stock_partial_picking_memory_out()
stock_partial_picking_memory_in()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -9,5 +9,59 @@
<field name="target">new</field> <field name="target">new</field>
</record> </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> </data>
</openerp> </openerp>

View File

@ -38,27 +38,12 @@
"active_ids": [ref("stock.menu_action_picking_tree")], "active_id": ref("stock.menu_action_picking_tree"), "active_ids": [ref("stock.menu_action_picking_tree")], "active_id": ref("stock.menu_action_picking_tree"),
}) })
- -
I create a record for partial picking. I process the delivery
-
!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.
- -
!python {model: stock.partial.picking}: | !python {model: stock.partial.picking}: |
pick_obj = self.pool.get('stock.picking') partial_id = self.create(cr, uid, {}, context={'active_model':'stock.picking',
partial = self.browse(cr, uid, ref('stock_partial_picking_0'), context) 'active_ids':[ref('stock_picking_out0')]})
partial_datas = { self.do_partial(cr, uid, [partial_id])
'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)
- -
As the Invoice state of the picking order is To be invoiced. I create invoice for my outgoing picking order. As the Invoice state of the picking order is To be invoiced. I create invoice for my outgoing picking order.
- -

View File

@ -25,24 +25,15 @@ class invoice_directly(osv.osv_memory):
_inherit = 'stock.partial.picking' _inherit = 'stock.partial.picking'
def do_partial(self, cr, uid, ids, context=None): def do_partial(self, cr, uid, ids, context=None):
""" Makes partial moves and pickings done and """Launch Create invoice wizard if invoice state is To be Invoiced,
launches Create invoice wizard if invoice state is To be Invoiced. after processing the partial picking.
@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:
""" """
if context is None: if context is None: context = {}
context = {}
result = super(invoice_directly, self).do_partial(cr, uid, ids, context) result = super(invoice_directly, self).do_partial(cr, uid, ids, context)
pick_obj = self.pool.get('stock.picking') partial = self.browse(cr, uid, ids[0], context)
context.update({'active_model':'stock.picking'}) context.update(active_model='stock.picking',
picking_ids = context.get('active_ids', False) active_ids=[partial.picking_id.id])
if picking_ids: if partial.picking_id.invoice_state == '2binvoiced':
context.update({'active_id':picking_ids[0]})
pick = pick_obj.browse(cr, uid, picking_ids, context=context)[0]
if pick.invoice_state == '2binvoiced':
return { return {
'name': 'Create Invoice', 'name': 'Create Invoice',
'view_type': 'form', 'view_type': 'form',
@ -55,5 +46,5 @@ class invoice_directly(osv.osv_memory):
return {'type': 'ir.actions.act_window_close'} return {'type': 'ir.actions.act_window_close'}
invoice_directly() invoice_directly()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: