[FIX] mrp: intermediate post inventory during a MO

When posting inventory during a manufacturing order,
all raw material and finished product moves are used,
also those done from a previous post inventory.

This is no problem for the moving of quants because
a filtering is done in the move_validate method,
but it is a problem for the price calculation in
mrp_account and for linking the consumed/produced_quant_ids
of the quants of the raw and finished moves.

Before this fix, it would calculate already consumed materials
a second time in the price of the finished products and would
link quants produced with previously consumed quants (and vice versa)
when doing a second post inventory.

We add a test to show the issue.
This commit is contained in:
Josse Colpaert
2017-01-19 16:21:27 +01:00
committed by Simon Lejeune
parent 640de0d22e
commit c453358c88
2 changed files with 85 additions and 4 deletions
+2 -3
View File
@@ -486,11 +486,10 @@ class MrpProduction(models.Model):
@api.multi
def post_inventory(self):
for order in self:
moves_to_do = order.move_raw_ids
moves_to_do = order.move_raw_ids.filtered(lambda x: x.state not in ('done', 'cancel'))
moves_to_do.action_done()
#order.move_finished_ids.filtered(lambda x: x.state not in ('done','cancel')).move_validate()
order._cal_price(moves_to_do)
moves_to_finish = order.move_finished_ids
moves_to_finish = order.move_finished_ids.filtered(lambda x: x.state not in ('done','cancel'))
moves_to_finish.action_done()
for move in moves_to_finish:
#Group quants by lots
+83 -1
View File
@@ -344,4 +344,86 @@ class TestMrpOrder(TestMrpCommon):
'bom_id': self.bom_3.id,
'product_uom_id': self.product_6.uom_id.id,})
self.assertEqual(production.routing_id.id, False, 'The routing field should be empty on the mo')
self.assertEqual(production.move_raw_ids[0].location_id.id, self.warehouse_1.wh_input_stock_loc_id.id, 'Raw moves start location should have altered.')
self.assertEqual(production.move_raw_ids[0].location_id.id, self.warehouse_1.wh_input_stock_loc_id.id, 'Raw moves start location should have altered.')
def test_multiple_post_inventory(self):
""" Check the consumed quants of the produced quants when intermediate calls to `post_inventory` during a MO."""
# create a bom for `custom_laptop` with components that aren't tracked
unit = self.ref("product.product_uom_unit")
custom_laptop = self.env.ref("product.product_product_27")
custom_laptop.tracking = 'none'
product_charger = self.env['product.product'].create({
'name': 'Charger',
'type': 'product',
'uom_id': unit,
'uom_po_id': unit})
product_keybord = self.env['product.product'].create({
'name': 'Usb Keybord',
'type': 'product',
'uom_id': unit,
'uom_po_id': unit})
bom_custom_laptop = self.env['mrp.bom'].create({
'product_tmpl_id': custom_laptop.product_tmpl_id.id,
'product_qty': 1,
'product_uom_id': unit,
'bom_line_ids': [(0, 0, {
'product_id': product_charger.id,
'product_qty': 1,
'product_uom_id': unit
}), (0, 0, {
'product_id': product_keybord.id,
'product_qty': 1,
'product_uom_id': unit
})]
})
# put the needed products in stock
source_location_id = self.ref('stock.stock_location_14')
inventory = self.env['stock.inventory'].create({
'name': 'Inventory Product Table',
'filter': 'partial',
'line_ids': [(0, 0, {
'product_id': product_charger.id,
'product_uom_id': product_charger.uom_id.id,
'product_qty': 2,
'location_id': source_location_id
}), (0, 0, {
'product_id': product_keybord.id,
'product_uom_id': product_keybord.uom_id.id,
'product_qty': 2,
'location_id': source_location_id
})]
})
inventory.action_done()
# create a mo for this bom
mo_custom_laptop = self.env['mrp.production'].create({
'product_id': custom_laptop.id,
'product_qty': 2,
'product_uom_id': unit,
'bom_id': bom_custom_laptop.id
})
mo_custom_laptop.action_assign()
self.assertEqual(mo_custom_laptop.availability, 'assigned')
# produce one item, call `post_inventory`
context = {"active_ids": [mo_custom_laptop.id], "active_id": mo_custom_laptop.id}
custom_laptop_produce = self.env['mrp.product.produce'].with_context(context).create({'product_qty': 1.00})
custom_laptop_produce.do_produce()
mo_custom_laptop.post_inventory()
# check the consumed quants of the produced quant
first_move = mo_custom_laptop.move_finished_ids.filtered(lambda mo: mo.state == 'done')
self.assertEquals(sum(first_move.quant_ids.mapped('consumed_quant_ids').mapped('qty')), 2)
second_move = mo_custom_laptop.move_finished_ids.filtered(lambda mo: mo.state == 'confirmed')
# produce the second item, call `post_inventory`
context = {"active_ids": [mo_custom_laptop.id], "active_id": mo_custom_laptop.id}
custom_laptop_produce = self.env['mrp.product.produce'].with_context(context).create({'product_qty': 1.00})
custom_laptop_produce.do_produce()
mo_custom_laptop.post_inventory()
# check the consumed quants of the newly produced quant
self.assertEquals(sum(second_move.quant_ids.mapped('consumed_quant_ids').mapped('qty')), 2)