Files
odoo_source/addons/mrp/tests/test_traceability.py
T
William Henrotin 5ef46664a2 [IMP] mrp: add production lines
To record a production via a manufacturing order, the user can either
use the produce wizard or the workorders views. Those two objects was
technically different but act more or less the same. This commit aims to
merge the similar behaviors in common code

We introduce two new abstract models :
 1. Abstract workorder to share workorders and the produce wizard
 2. Abstract workorder lines to share active_move_line on workorder and
    product_produce_line on the wizard. Those abstract line keep the information
    about the quantities and lot number to put on component move lines and
    finished product move lines

Task : 1891864
2019-02-01 08:13:25 +00:00

116 lines
5.5 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.tests import Form, tagged
from odoo.addons.mrp.tests.common import TestMrpCommon
import uuid
class TestTraceability(TestMrpCommon):
TRACKING_TYPES = ['none', 'serial', 'lot']
def _create_product(self, tracking):
return self.env['product.product'].create({
'name': 'Product %s' % tracking,
'type': 'product',
'tracking': tracking,
'categ_id': self.env.ref('product.product_category_all').id,
})
def test_tracking_types_on_mo(self):
finished_no_track = self._create_product('none')
finished_lot = self._create_product('lot')
finished_serial = self._create_product('serial')
consumed_no_track = self._create_product('none')
consumed_lot = self._create_product('lot')
consumed_serial = self._create_product('serial')
stock_id = self.env.ref('stock.stock_location_stock').id
inventory_adjustment = self.env['stock.inventory'].create({
'name': 'Initial Inventory',
'location_id': stock_id,
'filter': 'partial',
})
inventory_adjustment.action_start()
inventory_adjustment.write({
'line_ids': [
(0,0, {'product_id': consumed_no_track.id, 'product_qty': 3, 'location_id': stock_id}),
(0,0, {'product_id': consumed_lot.id, 'product_qty': 3, 'prod_lot_id': self.env['stock.production.lot'].create({'name': 'L1', 'product_id': consumed_lot.id}).id, 'location_id': stock_id}),
(0,0, {'product_id': consumed_serial.id, 'product_qty': 1, 'prod_lot_id': self.env['stock.production.lot'].create({'name': 'S1', 'product_id': consumed_serial.id}).id, 'location_id': stock_id}),
(0,0, {'product_id': consumed_serial.id, 'product_qty': 1, 'prod_lot_id': self.env['stock.production.lot'].create({'name': 'S2', 'product_id': consumed_serial.id}).id, 'location_id': stock_id}),
(0,0, {'product_id': consumed_serial.id, 'product_qty': 1, 'prod_lot_id': self.env['stock.production.lot'].create({'name': 'S3', 'product_id': consumed_serial.id}).id, 'location_id': stock_id}),
]
})
inventory_adjustment.action_validate()
for finished_product in [finished_no_track, finished_lot, finished_serial]:
bom = self.env['mrp.bom'].create({
'product_id': finished_product.id,
'product_tmpl_id': finished_product.product_tmpl_id.id,
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
'product_qty': 1.0,
'type': 'normal',
'bom_line_ids': [
(0, 0, {'product_id': consumed_no_track.id, 'product_qty': 1}),
(0, 0, {'product_id': consumed_lot.id, 'product_qty': 1}),
(0, 0, {'product_id': consumed_serial.id, 'product_qty': 1}),
],
})
mo_form = Form(self.env['mrp.production'])
mo_form.product_id = finished_product
mo_form.bom_id = bom
mo_form.product_uom_id = self.env.ref('uom.product_uom_unit')
mo_form.product_qty = 1
mo = mo_form.save()
mo.action_confirm()
mo.action_assign()
# Start MO production
produce_form = Form(self.env['mrp.product.produce'].with_context({
'active_id': mo.id,
'active_ids': [mo.id],
}))
if finished_product.tracking != 'serial':
produce_form.qty_producing = 1
if finished_product.tracking != 'none':
produce_form.final_lot_id = self.env['stock.production.lot'].create({'name': 'Serial or Lot finished', 'product_id': finished_product.id})
produce_wizard = produce_form.save()
produce_wizard.do_produce()
mo.button_mark_done()
self.assertEqual(mo.state, 'done', "Production order should be in done state.")
# Check results of traceability
context = ({
'active_id': mo.id,
'model': 'mrp.production',
})
lines = self.env['stock.traceability.report'].with_context(context).get_lines()
self.assertEqual(len(lines), 1, "Should always return 1 line : the final product")
final_product = lines[0]
self.assertEqual(final_product['unfoldable'], True, "Final product should always be unfoldable")
# Find parts of the final products
lines = self.env['stock.traceability.report'].get_lines(final_product['id'], **{
'level': final_product['level'],
'model_id': final_product['model_id'],
'model_name': final_product['model'],
})
self.assertEqual(len(lines), 3, "There should be 3 lines. 1 for untracked, 1 for lot, and 1 for serial")
for line in lines:
tracking = line['columns'][1].split(' ')[1]
self.assertEqual(
line['columns'][-1], "1.000 Unit(s)", 'Part with tracking type "%s", should have quantity = 1' % (tracking)
)
unfoldable = False if tracking == 'none' else True
self.assertEqual(
line['unfoldable'],
unfoldable,
'Parts with tracking type "%s", should have be unfoldable : %s' % (tracking, unfoldable)
)