[FIX]sale order, when in shipping exception, don't cancel procurement, re-run it instead. Also run of procurement should take into account previously done move for quantities
bzr revid: csn@openerp.com-20140123160638-4dgq1h1yugt6m6zt
This commit is contained in:
parent
e32b5bb6ae
commit
8c00eddd04
|
@ -676,14 +676,21 @@ class sale_order(osv.osv):
|
|||
for order in self.browse(cr, uid, ids, context=context):
|
||||
proc_ids = []
|
||||
vals = self._prepare_procurement_group(cr, uid, order, context=context)
|
||||
group_id = self.pool.get("procurement.group").create(cr, uid, vals, context=context)
|
||||
if not order.procurement_group_id:
|
||||
group_id = self.pool.get("procurement.group").create(cr, uid, vals, context=context)
|
||||
order.write({'procurement_group_id': group_id}, context=context)
|
||||
|
||||
order.write({'procurement_group_id': group_id}, context=context)
|
||||
fixed = True
|
||||
for line in order.order_line:
|
||||
#cancel existing procurements if any (possible when after a shipping exception the user choose to recreate), to avoid duplicates
|
||||
#Try to fix exception procurement (possible when after a shipping exception the user choose to recreate)
|
||||
if line.procurement_ids:
|
||||
procurement_obj.cancel(cr, uid, [x.id for x in line.procurement_ids if x.state != 'cancel'], context=context)
|
||||
if sale_line_obj.need_procurement(cr, uid, [line.id], context=context):
|
||||
#first check them to see if they are in exception or not
|
||||
procurement_obj.check(cr, uid, [x.id for x in line.procurement_ids if x.state not in ['cancel', 'done']])
|
||||
line.refresh()
|
||||
#run procurement that are in exception
|
||||
if not procurement_obj.run(cr, uid, [x.id for x in line.procurement_ids if x.state == 'exception'], context=context):
|
||||
fixed = False
|
||||
elif sale_line_obj.need_procurement(cr, uid, [line.id], context=context):
|
||||
if (line.state == 'done') or not line.product_id:
|
||||
continue
|
||||
vals = self._prepare_order_line_procurement(cr, uid, order, line, group_id=group_id, context=context)
|
||||
|
@ -691,10 +698,11 @@ class sale_order(osv.osv):
|
|||
proc_ids.append(proc_id)
|
||||
#Confirm procurement order such that rules will be applied on it
|
||||
#note that the workflow ensure proc_ids isn't an empty list
|
||||
procurement_obj.run(cr, uid, proc_ids, context=context)
|
||||
if proc_ids:
|
||||
procurement_obj.run(cr, uid, proc_ids, context=context)
|
||||
# FP NOTE: do we need this? isn't it the workflow that should set this
|
||||
val = {}
|
||||
if order.state == 'shipping_except':
|
||||
if order.state == 'shipping_except' and fixed:
|
||||
val['state'] = 'progress'
|
||||
val['shipped'] = False
|
||||
|
||||
|
|
|
@ -172,14 +172,23 @@ class procurement_order(osv.osv):
|
|||
group_id = procurement.group_id and procurement.group_id.id or False
|
||||
elif procurement.rule_id.group_propagation_option == 'fixed':
|
||||
group_id = procurement.rule_id.group_id and procurement.rule_id.group_id.id or False
|
||||
#it is possible that we've already got some move done, so check for the done qty and create
|
||||
#a new move with the correct qty
|
||||
already_done_qty = 0
|
||||
already_done_qty_uos = 0
|
||||
for move in procurement.move_ids:
|
||||
already_done_qty += move.product_uom_qty if move.state == 'done' else 0
|
||||
already_done_qty_uos += move.product_uos_qty if move.state == 'done' else 0
|
||||
qty_left = max(procurement.product_qty-already_done_qty, 0)
|
||||
qty_uos_left = max(procurement.product_uos_qty-already_done_qty_uos, 0)
|
||||
vals = {
|
||||
'name': procurement.name,
|
||||
'company_id': procurement.company_id.id,
|
||||
'product_id': procurement.product_id.id,
|
||||
'product_qty': procurement.product_qty,
|
||||
'product_qty': qty_left,
|
||||
'product_uom': procurement.product_uom.id,
|
||||
'product_uom_qty': procurement.product_qty,
|
||||
'product_uos_qty': (procurement.product_uos and procurement.product_uos_qty) or procurement.product_qty,
|
||||
'product_uom_qty': qty_left,
|
||||
'product_uos_qty': (procurement.product_uos and qty_uos_left) or qty_left,
|
||||
'product_uos': (procurement.product_uos and procurement.product_uos.id) or procurement.product_uom.id,
|
||||
'partner_id': procurement.group_id and procurement.group_id.partner_id and procurement.group_id.partner_id.id or False,
|
||||
'location_id': procurement.rule_id.location_src_id.id,
|
||||
|
@ -215,20 +224,25 @@ class procurement_order(osv.osv):
|
|||
if procurement.rule_id and procurement.rule_id.action == 'move':
|
||||
done_test_list = []
|
||||
done_cancel_test_list = []
|
||||
qty_done = 0
|
||||
for move in procurement.move_ids:
|
||||
done_test_list.append(move.state == 'done')
|
||||
done_cancel_test_list.append(move.state in ('done', 'cancel'))
|
||||
qty_done += move.product_uom_qty if move.state == 'done' else 0
|
||||
at_least_one_done = any(done_test_list)
|
||||
all_done_or_cancel = all(done_cancel_test_list)
|
||||
if not all_done_or_cancel:
|
||||
return False
|
||||
elif at_least_one_done and all_done_or_cancel:
|
||||
elif at_least_one_done and all_done_or_cancel and procurement.product_qty == qty_done:
|
||||
return True
|
||||
elif at_least_one_done:
|
||||
#some move cancelled and some validated
|
||||
self.message_post(cr, uid, [procurement.id], body=_('Some stock moves have been cancelled for this procurement.'), context=context)
|
||||
else:
|
||||
#all move are cancelled
|
||||
self.write(cr, uid, [procurement.id], {'state': 'exception'}, context=context)
|
||||
self.message_post(cr, uid, [procurement.id], body=_('All stock moves have been cancelled for this procurement.'), context=context)
|
||||
return False
|
||||
self.write(cr, uid, [procurement.id], {'state': 'exception'}, context=context)
|
||||
return False
|
||||
|
||||
return super(procurement_order, self)._check(cr, uid, procurement, context)
|
||||
|
||||
|
|
Loading…
Reference in New Issue