[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:
commit
cba2365d95
|
@ -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
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
-
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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']
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue