[MERGE] branch of jco fixing shipping exception in mrp + cancellation in chained moves

bzr revid: qdp-launchpad@openerp.com-20140425132449-s7e8duh884rirrqz
This commit is contained in:
Quentin (OpenERP) 2014-04-25 15:24:49 +02:00
commit cba2365d95
10 changed files with 47 additions and 51 deletions

View File

@ -493,7 +493,7 @@ class mrp_production(osv.osv):
'workcenter_lines': fields.one2many('mrp.production.workcenter.line', 'production_id', 'Work Centers Utilisation',
readonly=True, states={'draft': [('readonly', False)]}),
'state': fields.selection(
[('draft', 'New'), ('cancel', 'Cancelled'), ('picking_except', 'Picking Exception'), ('confirmed', 'Awaiting Raw Materials'),
[('draft', 'New'), ('cancel', 'Cancelled'), ('confirmed', 'Awaiting Raw Materials'),
('ready', 'Ready to Produce'), ('in_production', 'Production Started'), ('done', 'Done')],
string='Status', readonly=True,
track_visibility='onchange',
@ -614,12 +614,6 @@ class mrp_production(osv.osv):
}
return {'value': result}
def action_picking_except(self, cr, uid, ids):
""" Changes the state to Exception.
@return: True
"""
self.write(cr, uid, ids, {'state': 'picking_except'})
return True
def _action_compute_lines(self, cr, uid, ids, properties=None, context=None):
""" Compute product_lines and workcenter_lines from BoM structure
@ -685,6 +679,11 @@ class mrp_production(osv.osv):
move_obj.action_cancel(cr, uid, [x.id for x in production.move_created_ids])
move_obj.action_cancel(cr, uid, [x.id for x in production.move_lines])
self.write(cr, uid, ids, {'state': 'cancel'})
# Put related procurements in exception
proc_obj = self.pool.get("procurement.order")
procs = proc_obj.search(cr, uid, [('production_id', 'in', ids)], context=context)
if procs:
proc_obj.write(cr, uid, procs, {'state': 'exception'}, context=context)
return True
def action_ready(self, cr, uid, ids, context=None):
@ -697,8 +696,6 @@ class mrp_production(osv.osv):
for production in self.browse(cr, uid, ids, context=context):
if not production.move_created_ids:
self._make_production_produce_line(cr, uid, production, context=context)
for scheduled in production.product_lines:
self._make_production_line_procurement(cr, uid, scheduled, False, context=context)
if production.move_prod_id and production.move_prod_id.location_id.id != production.location_dest_id.id:
move_obj.write(cr, uid, [production.move_prod_id.id],
@ -712,6 +709,10 @@ class mrp_production(osv.osv):
for production in self.browse(cr, uid, ids):
self._costs_generate(cr, uid, production)
write_res = self.write(cr, uid, ids, {'state': 'done', 'date_finished': time.strftime('%Y-%m-%d %H:%M:%S')})
# Check related procurements
proc_obj = self.pool.get("procurement.order")
procs = proc_obj.search(cr, uid, [('production_id', 'in', ids)], context=context)
proc_obj.check(cr, uid, procs, context=context)
return write_res
def test_production_done(self, cr, uid, ids):
@ -965,29 +966,8 @@ class mrp_production(osv.osv):
if production.ready_production:
res = True
return res
def _make_production_line_procurement(self, cr, uid, production_line, shipment_move_id, context=None):
procurement_order = self.pool.get('procurement.order')
production = production_line.production_id
location_id = production.location_src_id.id
date_planned = production.date_planned
procurement_name = (production.origin or '').split(':')[0] + ':' + production.name
procurement_id = procurement_order.create(cr, uid, {
'name': procurement_name,
'origin': procurement_name,
'date_planned': date_planned,
'product_id': production_line.product_id.id,
'product_qty': production_line.product_qty,
'product_uom': production_line.product_uom.id,
'product_uos_qty': production_line.product_uos and production_line.product_qty or False,
'product_uos': production_line.product_uos and production_line.product_uos.id or False,
'location_id': location_id,
'move_id': shipment_move_id,
'company_id': production.company_id.id,
})
procurement_order.signal_button_confirm(cr, uid, [procurement_id])
return procurement_id
def _make_production_produce_line(self, cr, uid, production, context=None):
stock_move = self.pool.get('stock.move')
source_location_id = production.product_id.property_stock_production.id

View File

@ -675,12 +675,10 @@
<button name="%(act_mrp_product_produce)d" states="ready,in_production" string="Produce" type="action" class="oe_highlight"/>
<button name="action_assign" states="confirmed,picking_except" string="Check Availability" type="object" class="oe_highlight"/>
<button name="force_production" states="confirmed" string="Force Reservation" type="object"/>
<button name="force_production" states="picking_except" string="Force Reservation" type="object"/>
<button name="button_produce" states="ready" string="Mark as Started"/>
<button name="button_recreate" states="picking_except" string="Recreate Picking"/>
<button name="button_cancel" states="draft,ready,in_production,picking_except" string="Cancel Production"/>
<button name="button_cancel" states="draft,ready,in_production" string="Cancel Production"/>
<button name="action_cancel" type="object" states="confirmed" string="Cancel Production"/>
<field name="state" widget="statusbar" statusbar_visible="draft,ready,in_production,done" statusbar_colors='{"picking_except":"red","confirmed":"blue"}'/>
<field name="state" widget="statusbar" statusbar_visible="draft,ready,in_production,done" statusbar_colors='{"confirmed":"blue"}'/>
</header>
<sheet>
<div class="oe_title">
@ -721,7 +719,7 @@
<group>
<group string="Products to Consume">
<field name="move_lines" nolabel="1" options="{'reload_on_button': true}">
<tree colors="blue:state == 'draft';black:state in ('ready','assigned','in_production');gray:state in ('cancel','done');red:state in ('confirmed','picking_except','waiting')" string="Products to Consume">
<tree colors="blue:state == 'draft';black:state in ('ready','assigned','in_production');gray:state in ('cancel','done');red:state in ('confirmed','waiting')" string="Products to Consume">
<field name="product_id"/>
<field name="product_qty" string="Quantity"/>
<field name="product_uom" string="Unit of Measure" groups="product.group_uom"/>
@ -740,7 +738,7 @@
</group>
<group string="Consumed Products">
<field name="move_lines2" nolabel="1" options="{'reload_on_button': true}">
<tree colors="red:scrapped==True;blue:state == 'draft';black:state in('picking_except','confirmed','ready','in_production');gray:state == 'cancel' " string="Consumed Products" editable="bottom">
<tree colors="red:scrapped==True;blue:state == 'draft';black:state in ('confirmed','ready','in_production');gray:state == 'cancel' " string="Consumed Products" editable="bottom">
<field name="product_id" readonly="1"/>
<field name="restrict_lot_id" context="{'product_id': product_id}" groups="stock.group_tracking_lot"/>
<field name="product_qty" readonly="1"/>
@ -767,7 +765,7 @@
</group>
<group string="Produced Products">
<field name="move_created_ids2" nolabel="1" options="{'reload_on_button': true}">
<tree colors="red:scrapped==True;blue:state == 'draft';black:state in('picking_except','confirmed','ready','in_production');gray:state in('cancel','done') " string="Finished Products">
<tree colors="red:scrapped==True;blue:state == 'draft';black:state in('confirmed','ready','in_production');gray:state in('cancel','done') " string="Finished Products">
<field name="product_id" readonly="1"/>
<field name="product_qty" readonly="1"/>
<field name="restrict_lot_id" groups="stock.group_tracking_lot"/>

View File

@ -228,7 +228,7 @@ class stock_warehouse(osv.osv):
'route_id': manufacture_route_id,
'action': 'manufacture',
'picking_type_id': warehouse.int_type_id.id,
'procure_method': 'make_to_order',
'propagate': False,
'warehouse_id': warehouse.id,
}

View File

@ -97,7 +97,7 @@ class mrp_production_workcenter_line(osv.osv):
'delay': fields.float('Working Hours',help="The elapsed time between operation start and stop in this Work Center",readonly=True),
'production_state':fields.related('production_id','state',
type='selection',
selection=[('draft','Draft'),('picking_except', 'Picking Exception'),('confirmed','Waiting Goods'),('ready','Ready to Produce'),('in_production','In Production'),('cancel','Canceled'),('done','Done')],
selection=[('draft','Draft'),('confirmed','Waiting Goods'),('ready','Ready to Produce'),('in_production','In Production'),('cancel','Canceled'),('done','Done')],
string='Production Status', readonly=True),
'product':fields.related('production_id','product_id',type='many2one',relation='product.product',string='Product',
readonly=True),

View File

@ -112,7 +112,7 @@ class stock_warehouse(osv.osv):
'route_id': buy_route_id,
'action': 'buy',
'picking_type_id': warehouse.in_type_id.id,
'procure_method': 'make_to_order',
'propagate': False,
'warehouse_id': warehouse.id,
}

View File

@ -51,12 +51,17 @@
Confirm sales order
-
!workflow {model: sale.order, action: order_confirm, ref: sale_order_product_manu}
-
I run scheduler.
-
!python {model: procurement.order}: |
self.run_scheduler(cr, uid)
-
Check the propagation when we cancel the main procurement
* Retrieve related procurements and check that there are all running
* Check that the purchase order has been well created
* Cancel the main procurement
* Check that all procurements related and the purchase order has been well cancelled
* Check that all procurements related and the purchase order has been well cancelled
-
!python {model: procurement.order}: |
# Retrieve related procu
@ -65,7 +70,7 @@
assert len(procu_ids)>0, 'No procurements are found for sale order "%s" (with id : %d)' %(so.name, so.id)
# Check that all procurements are running
for procu in self.browse(cr, uid, procu_ids, context=context):
for procu in self.browse(cr, uid, procu_ids, context=context):
assert procu.state == u'running', 'Procurement with id %d should be "running" but is with a state : %s!' %(procu.id, procu.state)
# Check that one production order exist

View File

@ -100,7 +100,7 @@
!python {model: procurement.order}: |
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)])
proc_ids = self.search(cr, uid, [('origin','like',so.name)])
self.run(cr, uid, proc_ids)
-
I verify that a procurement state is "running"
@ -108,8 +108,8 @@
!python {model: procurement.order}: |
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','like',so.name), ('state','=','running')])
# Check that all procurement are running
proc_ids = self.search(cr, uid, [('origin','like',so.name)])
# Check that all procurement are running
for procu in self.browse(cr,uid,proc_ids,context=context):
assert procu.state == u'running', 'Procurement with id %d should be with a state "running" but is with a state : %s!' %(procu.id,procu.state)
-

View File

@ -99,8 +99,7 @@ class procurement_order(osv.osv):
#set the context for the propagation of the procurement cancelation
ctx['cancel_procurement'] = True
for procurement in self.browse(cr, uid, to_cancel_ids, context=ctx):
if procurement.rule_id and procurement.rule_id.propagate:
self.propagate_cancel(cr, uid, procurement, context=ctx)
self.propagate_cancel(cr, uid, procurement, context=ctx)
return super(procurement_order, self).cancel(cr, uid, to_cancel_ids, context=ctx)
def _find_parent_locations(self, cr, uid, procurement, context=None):

View File

@ -2120,7 +2120,7 @@ class stock_move(osv.osv):
quants = quant_obj.quants_get_prefered_domain(cr, uid, move.location_id, move.product_id, qty, domain=main_domain[move.id], prefered_domain_list=[], restrict_lot_id=move.restrict_lot_id.id, restrict_partner_id=move.restrict_partner_id.id, context=context)
quant_obj.quants_reserve(cr, uid, quants, move, context=context)
#force assignation of consumable products and incoming from supplier/inventory/production
#force assignation of consumable products and incoming from supplier/inventory/production
if to_assign_moves:
self.force_assign(cr, uid, to_assign_moves, context=context)
@ -2144,6 +2144,14 @@ class stock_move(osv.osv):
#cancel chained moves
if move.propagate:
self.action_cancel(cr, uid, [move.move_dest_id.id], context=context)
# If we have a long chain of moves to be cancelled, it is easier for the user to handle
# only the last procurement which will go into exception, instead of all procurements
# along the chain going into exception. We need to check if there are no split moves not cancelled however
if move.procurement_id:
proc = move.procurement_id
if all([x.state == 'cancel' for x in proc.move_ids if x.id != move.id]):
procurement_obj.write(cr, uid, [proc.id], {'state': 'cancel'})
elif move.move_dest_id.state == 'waiting':
self.write(cr, uid, [move.move_dest_id.id], {'state': 'confirmed'}, context=context)
return self.write(cr, uid, ids, {'state': 'cancel', 'move_dest_id': False}, context=context)
@ -2360,6 +2368,7 @@ class stock_move(osv.osv):
'restrict_lot_id': restrict_lot_id,
'restrict_partner_id': restrict_partner_id,
'split_from': move.id,
'move_dest_id': move.move_dest_id.id,
}
if context.get('source_location_id'):
defaults['location_id'] = context['source_location_id']

View File

@ -40,6 +40,11 @@
Confirm the sale order
-
!workflow {model: sale.order, action: order_confirm, ref: sale_order_product_mto}
-
I run scheduler.
-
!python {model: procurement.order}: |
self.run_scheduler(cr, uid)
-
Check the propagation when we cancel the main procurement
* Retrieve related procurements and check that there are all running
@ -64,7 +69,7 @@
# Cancel the main procurement
main_procu_id = self.search(cr, uid, [('origin', '=', so.name)])
assert len(main_procu_id) == 1, 'Main procurement not identified !'
self.cancel(cr, uid, main_procu_id, context=context)
self.cancel(cr, uid, main_procu_id, context=context)
assert self.browse(cr, uid, main_procu_id[0]).state == u'cancel', 'Main procurement should be cancelled !'
# Check that all procurements related are cancelled