mirror of
https://github.com/bringout/oca-ocb-mrp.git
synced 2026-04-22 19:12:07 +02:00
19.0 vanilla
This commit is contained in:
parent
accf5918df
commit
6e65e8c877
688 changed files with 225434 additions and 199401 deletions
|
|
@ -1,12 +1,14 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import Command
|
||||
from odoo.tests import Form
|
||||
from odoo.addons.mrp.tests.common import TestMrpCommon
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
from datetime import datetime
|
||||
import logging
|
||||
from freezegun import freeze_time
|
||||
from datetime import datetime
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -22,9 +24,8 @@ class TestTraceability(TestMrpCommon):
|
|||
def _create_product(self, tracking):
|
||||
return self.env['product.product'].create({
|
||||
'name': 'Product %s' % tracking,
|
||||
'type': 'product',
|
||||
'is_storable': True,
|
||||
'tracking': tracking,
|
||||
'categ_id': self.env.ref('product.product_category_all').id,
|
||||
})
|
||||
|
||||
def test_tracking_types_on_mo(self):
|
||||
|
|
@ -34,37 +35,36 @@ class TestTraceability(TestMrpCommon):
|
|||
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
|
||||
Lot = self.env['stock.lot']
|
||||
# create inventory
|
||||
quants = self.env['stock.quant'].create({
|
||||
'location_id': stock_id,
|
||||
'location_id': self.stock_location.id,
|
||||
'product_id': consumed_no_track.id,
|
||||
'inventory_quantity': 3
|
||||
})
|
||||
quants |= self.env['stock.quant'].create({
|
||||
'location_id': stock_id,
|
||||
'location_id': self.stock_location.id,
|
||||
'product_id': consumed_lot.id,
|
||||
'inventory_quantity': 3,
|
||||
'lot_id': Lot.create({'name': 'L1', 'product_id': consumed_lot.id, 'company_id': self.env.company.id}).id
|
||||
'lot_id': Lot.create({'name': 'L1', 'product_id': consumed_lot.id}).id
|
||||
})
|
||||
quants |= self.env['stock.quant'].create({
|
||||
'location_id': stock_id,
|
||||
'location_id': self.stock_location.id,
|
||||
'product_id': consumed_serial.id,
|
||||
'inventory_quantity': 1,
|
||||
'lot_id': Lot.create({'name': 'S1', 'product_id': consumed_serial.id, 'company_id': self.env.company.id}).id
|
||||
'lot_id': Lot.create({'name': 'S1', 'product_id': consumed_serial.id}).id
|
||||
})
|
||||
quants |= self.env['stock.quant'].create({
|
||||
'location_id': stock_id,
|
||||
'location_id': self.stock_location.id,
|
||||
'product_id': consumed_serial.id,
|
||||
'inventory_quantity': 1,
|
||||
'lot_id': Lot.create({'name': 'S2', 'product_id': consumed_serial.id, 'company_id': self.env.company.id}).id
|
||||
'lot_id': Lot.create({'name': 'S2', 'product_id': consumed_serial.id}).id
|
||||
})
|
||||
quants |= self.env['stock.quant'].create({
|
||||
'location_id': stock_id,
|
||||
'location_id': self.stock_location.id,
|
||||
'product_id': consumed_serial.id,
|
||||
'inventory_quantity': 1,
|
||||
'lot_id': Lot.create({'name': 'S3', 'product_id': consumed_serial.id, 'company_id': self.env.company.id}).id
|
||||
'lot_id': Lot.create({'name': 'S3', 'product_id': consumed_serial.id}).id
|
||||
})
|
||||
quants.action_apply_inventory()
|
||||
|
||||
|
|
@ -72,20 +72,20 @@ class TestTraceability(TestMrpCommon):
|
|||
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_uom_id': self.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}),
|
||||
Command.create({'product_id': consumed_no_track.id, 'product_qty': 1}),
|
||||
Command.create({'product_id': consumed_lot.id, 'product_qty': 1}),
|
||||
Command.create({'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_uom_id = self.uom_unit
|
||||
mo_form.product_qty = 1
|
||||
mo = mo_form.save()
|
||||
mo.action_confirm()
|
||||
|
|
@ -93,19 +93,19 @@ class TestTraceability(TestMrpCommon):
|
|||
|
||||
# Start MO production
|
||||
mo_form = Form(mo)
|
||||
mo_form.qty_producing = 1
|
||||
if finished_product.tracking != 'none':
|
||||
mo_form.lot_producing_id = self.env['stock.lot'].create({'name': 'Serial or Lot finished', 'product_id': finished_product.id, 'company_id': self.env.company.id})
|
||||
mo_form.lot_producing_ids.set(self.env['stock.lot'].create({'name': 'Serial or Lot finished', 'product_id': finished_product.id}))
|
||||
mo = mo_form.save()
|
||||
|
||||
details_operation_form = Form(mo.move_raw_ids[1], view=self.env.ref('stock.view_stock_move_operations'))
|
||||
with details_operation_form.move_line_ids.edit(0) as ml:
|
||||
ml.qty_done = 1
|
||||
ml.quantity = 1
|
||||
details_operation_form.save()
|
||||
details_operation_form = Form(mo.move_raw_ids[2], view=self.env.ref('stock.view_stock_move_operations'))
|
||||
with details_operation_form.move_line_ids.edit(0) as ml:
|
||||
ml.qty_done = 1
|
||||
ml.quantity = 1
|
||||
details_operation_form.save()
|
||||
mo.move_raw_ids.picked = True
|
||||
|
||||
mo.button_mark_done()
|
||||
self.assertEqual(mo.state, 'done', "Production order should be in done state.")
|
||||
|
|
@ -143,27 +143,27 @@ class TestTraceability(TestMrpCommon):
|
|||
def test_tracking_on_byproducts(self):
|
||||
product_final = self.env['product.product'].create({
|
||||
'name': 'Finished Product',
|
||||
'type': 'product',
|
||||
'is_storable': True,
|
||||
'tracking': 'serial',
|
||||
})
|
||||
product_1 = self.env['product.product'].create({
|
||||
'name': 'Raw 1',
|
||||
'type': 'product',
|
||||
'is_storable': True,
|
||||
'tracking': 'serial',
|
||||
})
|
||||
product_2 = self.env['product.product'].create({
|
||||
'name': 'Raw 2',
|
||||
'type': 'product',
|
||||
'is_storable': True,
|
||||
'tracking': 'serial',
|
||||
})
|
||||
byproduct_1 = self.env['product.product'].create({
|
||||
'name': 'Byproduct 1',
|
||||
'type': 'product',
|
||||
'is_storable': True,
|
||||
'tracking': 'serial',
|
||||
})
|
||||
byproduct_2 = self.env['product.product'].create({
|
||||
'name': 'Byproduct 2',
|
||||
'type': 'product',
|
||||
'is_storable': True,
|
||||
'tracking': 'serial',
|
||||
})
|
||||
bom_1 = self.env['mrp.bom'].create({
|
||||
|
|
@ -174,12 +174,12 @@ class TestTraceability(TestMrpCommon):
|
|||
'consumption': 'flexible',
|
||||
'type': 'normal',
|
||||
'bom_line_ids': [
|
||||
(0, 0, {'product_id': product_1.id, 'product_qty': 1}),
|
||||
(0, 0, {'product_id': product_2.id, 'product_qty': 1})
|
||||
Command.create({'product_id': product_1.id, 'product_qty': 1}),
|
||||
Command.create({'product_id': product_2.id, 'product_qty': 1}),
|
||||
],
|
||||
'byproduct_ids': [
|
||||
(0, 0, {'product_id': byproduct_1.id, 'product_qty': 1, 'product_uom_id': byproduct_1.uom_id.id}),
|
||||
(0, 0, {'product_id': byproduct_2.id, 'product_qty': 1, 'product_uom_id': byproduct_2.uom_id.id})
|
||||
Command.create({'product_id': byproduct_1.id, 'product_qty': 1, 'product_uom_id': byproduct_1.uom_id.id}),
|
||||
Command.create({'product_id': byproduct_2.id, 'product_qty': 1, 'product_uom_id': byproduct_2.uom_id.id}),
|
||||
]})
|
||||
mo_form = Form(self.env['mrp.production'])
|
||||
mo_form.product_id = product_final
|
||||
|
|
@ -188,124 +188,104 @@ class TestTraceability(TestMrpCommon):
|
|||
mo = mo_form.save()
|
||||
mo.action_confirm()
|
||||
|
||||
mo_form = Form(mo)
|
||||
mo_form.lot_producing_id = self.env['stock.lot'].create({
|
||||
mo.lot_producing_ids = self.env['stock.lot'].create({
|
||||
'product_id': product_final.id,
|
||||
'name': 'Final_lot_1',
|
||||
'company_id': self.env.company.id,
|
||||
})
|
||||
mo = mo_form.save()
|
||||
mo.qty_producing = 1
|
||||
mo.set_qty_producing()
|
||||
|
||||
details_operation_form = Form(mo.move_raw_ids[0], view=self.env.ref('stock.view_stock_move_operations'))
|
||||
with details_operation_form.move_line_ids.new() as ml:
|
||||
with details_operation_form.move_line_ids.edit(0) as ml:
|
||||
ml.lot_id = self.env['stock.lot'].create({
|
||||
'product_id': product_1.id,
|
||||
'name': 'Raw_1_lot_1',
|
||||
'company_id': self.env.company.id,
|
||||
})
|
||||
ml.qty_done = 1
|
||||
details_operation_form.save()
|
||||
details_operation_form = Form(mo.move_raw_ids[1], view=self.env.ref('stock.view_stock_move_operations'))
|
||||
with details_operation_form.move_line_ids.new() as ml:
|
||||
with details_operation_form.move_line_ids.edit(0) as ml:
|
||||
ml.lot_id = self.env['stock.lot'].create({
|
||||
'product_id': product_2.id,
|
||||
'name': 'Raw_2_lot_1',
|
||||
'company_id': self.env.company.id,
|
||||
})
|
||||
ml.qty_done = 1
|
||||
details_operation_form.save()
|
||||
details_operation_form = Form(
|
||||
mo.move_finished_ids.filtered(lambda m: m.product_id == byproduct_1),
|
||||
view=self.env.ref('stock.view_stock_move_operations')
|
||||
)
|
||||
with details_operation_form.move_line_ids.new() as ml:
|
||||
with details_operation_form.move_line_ids.edit(0) as ml:
|
||||
ml.lot_id = self.env['stock.lot'].create({
|
||||
'product_id': byproduct_1.id,
|
||||
'name': 'Byproduct_1_lot_1',
|
||||
'company_id': self.env.company.id,
|
||||
})
|
||||
ml.qty_done = 1
|
||||
details_operation_form.save()
|
||||
details_operation_form = Form(
|
||||
mo.move_finished_ids.filtered(lambda m: m.product_id == byproduct_2),
|
||||
view=self.env.ref('stock.view_stock_move_operations')
|
||||
)
|
||||
with details_operation_form.move_line_ids.new() as ml:
|
||||
with details_operation_form.move_line_ids.edit(0) as ml:
|
||||
ml.lot_id = self.env['stock.lot'].create({
|
||||
'product_id': byproduct_2.id,
|
||||
'name': 'Byproduct_2_lot_1',
|
||||
'company_id': self.env.company.id,
|
||||
})
|
||||
ml.qty_done = 1
|
||||
details_operation_form.save()
|
||||
|
||||
mo.move_raw_ids.picked = True
|
||||
action = mo.button_mark_done()
|
||||
backorder = Form(self.env['mrp.production.backorder'].with_context(**action['context']))
|
||||
backorder.save().action_backorder()
|
||||
mo_backorder = mo.procurement_group_id.mrp_production_ids[-1]
|
||||
mo_backorder = mo.production_group_id.production_ids[-1]
|
||||
mo_form = Form(mo_backorder)
|
||||
mo_form.lot_producing_id = self.env['stock.lot'].create({
|
||||
mo_form.lot_producing_ids.set(self.env['stock.lot'].create({
|
||||
'product_id': product_final.id,
|
||||
'name': 'Final_lot_2',
|
||||
'company_id': self.env.company.id,
|
||||
})
|
||||
mo_form.qty_producing = 1
|
||||
}))
|
||||
mo_backorder = mo_form.save()
|
||||
|
||||
details_operation_form = Form(
|
||||
mo_backorder.move_raw_ids.filtered(lambda m: m.product_id == product_1),
|
||||
view=self.env.ref('stock.view_stock_move_operations')
|
||||
)
|
||||
with details_operation_form.move_line_ids.new() as ml:
|
||||
with details_operation_form.move_line_ids.edit(0) as ml:
|
||||
ml.lot_id = self.env['stock.lot'].create({
|
||||
'product_id': product_1.id,
|
||||
'name': 'Raw_1_lot_2',
|
||||
'company_id': self.env.company.id,
|
||||
})
|
||||
ml.qty_done = 1
|
||||
details_operation_form.save()
|
||||
details_operation_form = Form(
|
||||
mo_backorder.move_raw_ids.filtered(lambda m: m.product_id == product_2),
|
||||
view=self.env.ref('stock.view_stock_move_operations')
|
||||
)
|
||||
with details_operation_form.move_line_ids.new() as ml:
|
||||
with details_operation_form.move_line_ids.edit(0) as ml:
|
||||
ml.lot_id = self.env['stock.lot'].create({
|
||||
'product_id': product_2.id,
|
||||
'name': 'Raw_2_lot_2',
|
||||
'company_id': self.env.company.id,
|
||||
})
|
||||
ml.qty_done = 1
|
||||
details_operation_form.save()
|
||||
details_operation_form = Form(
|
||||
mo_backorder.move_finished_ids.filtered(lambda m: m.product_id == byproduct_1),
|
||||
view=self.env.ref('stock.view_stock_move_operations')
|
||||
)
|
||||
with details_operation_form.move_line_ids.new() as ml:
|
||||
with details_operation_form.move_line_ids.edit(0) as ml:
|
||||
ml.lot_id = self.env['stock.lot'].create({
|
||||
'product_id': byproduct_1.id,
|
||||
'name': 'Byproduct_1_lot_2',
|
||||
'company_id': self.env.company.id,
|
||||
})
|
||||
ml.qty_done = 1
|
||||
details_operation_form.save()
|
||||
details_operation_form = Form(
|
||||
mo_backorder.move_finished_ids.filtered(lambda m: m.product_id == byproduct_2),
|
||||
view=self.env.ref('stock.view_stock_move_operations')
|
||||
)
|
||||
with details_operation_form.move_line_ids.new() as ml:
|
||||
with details_operation_form.move_line_ids.edit(0) as ml:
|
||||
ml.lot_id = self.env['stock.lot'].create({
|
||||
'product_id': byproduct_2.id,
|
||||
'name': 'Byproduct_2_lot_2',
|
||||
'company_id': self.env.company.id,
|
||||
})
|
||||
ml.qty_done = 1
|
||||
details_operation_form.save()
|
||||
|
||||
mo_backorder.move_raw_ids.picked = True
|
||||
mo_backorder.button_mark_done()
|
||||
|
||||
# self.assertEqual(len(mo.move_raw_ids.mapped('move_line_ids')), 4)
|
||||
# self.assertEqual(len(mo.move_finished_ids.mapped('move_line_ids')), 6)
|
||||
|
||||
mo = mo | mo_backorder
|
||||
raw_move_lines = mo.move_raw_ids.mapped('move_line_ids')
|
||||
raw_line_raw_1_lot_1 = raw_move_lines.filtered(lambda ml: ml.lot_id.name == 'Raw_1_lot_1')
|
||||
|
|
@ -315,19 +295,19 @@ class TestTraceability(TestMrpCommon):
|
|||
|
||||
finished_move_lines = mo.move_finished_ids.mapped('move_line_ids')
|
||||
finished_move_line_lot_1 = finished_move_lines.filtered(lambda ml: ml.lot_id.name == 'Final_lot_1')
|
||||
self.assertEqual(finished_move_line_lot_1.consume_line_ids.filtered(lambda l: l.qty_done), raw_line_raw_1_lot_1 | raw_line_raw_2_lot_1)
|
||||
self.assertEqual(finished_move_line_lot_1.consume_line_ids.filtered(lambda l: l.quantity), raw_line_raw_1_lot_1 | raw_line_raw_2_lot_1)
|
||||
finished_move_line_lot_2 = finished_move_lines.filtered(lambda ml: ml.lot_id.name == 'Final_lot_2')
|
||||
raw_line_raw_1_lot_2 = raw_move_lines.filtered(lambda ml: ml.lot_id.name == 'Raw_1_lot_2')
|
||||
raw_line_raw_2_lot_2 = raw_move_lines.filtered(lambda ml: ml.lot_id.name == 'Raw_2_lot_2')
|
||||
self.assertEqual(finished_move_line_lot_2.consume_line_ids, raw_line_raw_1_lot_2 | raw_line_raw_2_lot_2)
|
||||
|
||||
byproduct_move_line_1_lot_1 = finished_move_lines.filtered(lambda ml: ml.lot_id.name == 'Byproduct_1_lot_1')
|
||||
self.assertEqual(byproduct_move_line_1_lot_1.consume_line_ids.filtered(lambda l: l.qty_done), raw_line_raw_1_lot_1 | raw_line_raw_2_lot_1)
|
||||
self.assertEqual(byproduct_move_line_1_lot_1.consume_line_ids.filtered(lambda l: l.quantity), raw_line_raw_1_lot_1 | raw_line_raw_2_lot_1)
|
||||
byproduct_move_line_1_lot_2 = finished_move_lines.filtered(lambda ml: ml.lot_id.name == 'Byproduct_1_lot_2')
|
||||
self.assertEqual(byproduct_move_line_1_lot_2.consume_line_ids, raw_line_raw_1_lot_2 | raw_line_raw_2_lot_2)
|
||||
|
||||
byproduct_move_line_2_lot_1 = finished_move_lines.filtered(lambda ml: ml.lot_id.name == 'Byproduct_2_lot_1')
|
||||
self.assertEqual(byproduct_move_line_2_lot_1.consume_line_ids.filtered(lambda l: l.qty_done), raw_line_raw_1_lot_1 | raw_line_raw_2_lot_1)
|
||||
self.assertEqual(byproduct_move_line_2_lot_1.consume_line_ids.filtered(lambda l: l.quantity), raw_line_raw_1_lot_1 | raw_line_raw_2_lot_1)
|
||||
byproduct_move_line_2_lot_2 = finished_move_lines.filtered(lambda ml: ml.lot_id.name == 'Byproduct_2_lot_2')
|
||||
self.assertEqual(byproduct_move_line_2_lot_2.consume_line_ids, raw_line_raw_1_lot_2 | raw_line_raw_2_lot_2)
|
||||
|
||||
|
|
@ -338,25 +318,24 @@ class TestTraceability(TestMrpCommon):
|
|||
Produce a new SN product with same lot
|
||||
"""
|
||||
mo, bom, p_final, p1, p2 = self.generate_mo(qty_base_1=1, qty_base_2=1, qty_final=1, tracking_final='serial')
|
||||
stock_location = self.env.ref('stock.stock_location_stock')
|
||||
self.env['stock.quant']._update_available_quantity(p1, stock_location, 1)
|
||||
self.env['stock.quant']._update_available_quantity(p2, stock_location, 1)
|
||||
self.env['stock.quant']._update_available_quantity(p1, self.stock_location, 1)
|
||||
self.env['stock.quant']._update_available_quantity(p2, self.stock_location, 1)
|
||||
mo.action_assign()
|
||||
|
||||
lot = self.env['stock.lot'].create({
|
||||
'name': 'lot1',
|
||||
'product_id': p_final.id,
|
||||
'company_id': self.env.company.id,
|
||||
})
|
||||
|
||||
mo_form = Form(mo)
|
||||
mo_form.qty_producing = 1.0
|
||||
mo_form.lot_producing_id = lot
|
||||
mo_form.lot_producing_ids.set(lot)
|
||||
mo = mo_form.save()
|
||||
mo.move_raw_ids.picked = True
|
||||
mo.button_mark_done()
|
||||
|
||||
unbuild_form = Form(self.env['mrp.unbuild'])
|
||||
unbuild_form.mo_id = mo
|
||||
unbuild_form.lot_id = lot
|
||||
unbuild_form.save().action_unbuild()
|
||||
|
||||
mo_form = Form(self.env['mrp.production'])
|
||||
|
|
@ -366,33 +345,28 @@ class TestTraceability(TestMrpCommon):
|
|||
|
||||
with self.assertLogs(level="WARNING") as log_catcher:
|
||||
mo_form = Form(mo)
|
||||
mo_form.qty_producing = 1.0
|
||||
mo_form.lot_producing_id = lot
|
||||
mo_form.lot_producing_ids.set(lot)
|
||||
mo = mo_form.save()
|
||||
_logger.warning('Dummy')
|
||||
self.assertEqual(len(log_catcher.output), 1, "Useless warnings: \n%s" % "\n".join(log_catcher.output[:-1]))
|
||||
|
||||
mo.move_raw_ids.picked = True
|
||||
mo.button_mark_done()
|
||||
self.assertEqual(mo.state, 'done')
|
||||
|
||||
def test_tracked_and_manufactured_component(self):
|
||||
"""
|
||||
Suppose this structure:
|
||||
""" Suppose this structure:
|
||||
productA --|- 1 x productB --|- 1 x productC
|
||||
with productB tracked by lot
|
||||
Ensure that, when we already have some qty of productB (with different lots),
|
||||
the user can produce several productA and can then produce some productB again
|
||||
"""
|
||||
stock_location = self.env.ref('stock.stock_location_stock')
|
||||
picking_type = self.env['stock.picking.type'].search([('code', '=', 'mrp_operation')])[0]
|
||||
picking_type.use_auto_consume_components_lots = True
|
||||
|
||||
productA, productB, productC = self.env['product.product'].create([{
|
||||
'name': 'Product A',
|
||||
'type': 'product',
|
||||
'is_storable': True,
|
||||
}, {
|
||||
'name': 'Product B',
|
||||
'type': 'product',
|
||||
'is_storable': True,
|
||||
'tracking': 'lot',
|
||||
}, {
|
||||
'name': 'Product C',
|
||||
|
|
@ -402,7 +376,6 @@ class TestTraceability(TestMrpCommon):
|
|||
lot_B01, lot_B02, lot_B03 = self.env['stock.lot'].create([{
|
||||
'name': 'lot %s' % i,
|
||||
'product_id': productB.id,
|
||||
'company_id': self.env.company.id,
|
||||
} for i in [1, 2, 3]])
|
||||
|
||||
self.env['mrp.bom'].create([{
|
||||
|
|
@ -411,11 +384,11 @@ class TestTraceability(TestMrpCommon):
|
|||
'product_uom_id': self.uom_unit.id,
|
||||
'product_qty': 1.0,
|
||||
'type': 'normal',
|
||||
'bom_line_ids': [(0, 0, {'product_id': component.id, 'product_qty': 1})],
|
||||
'bom_line_ids': [Command.create({'product_id': component.id, 'product_qty': 1})],
|
||||
} for finished, component in [(productA, productB), (productB, productC)]])
|
||||
|
||||
self.env['stock.quant']._update_available_quantity(productB, stock_location, 10, lot_id=lot_B01)
|
||||
self.env['stock.quant']._update_available_quantity(productB, stock_location, 5, lot_id=lot_B02)
|
||||
self.env['stock.quant']._update_available_quantity(productB, self.stock_location, 10, lot_id=lot_B01)
|
||||
self.env['stock.quant']._update_available_quantity(productB, self.stock_location, 5, lot_id=lot_B02)
|
||||
|
||||
# Produce 15 x productA
|
||||
mo_form = Form(self.env['mrp.production'])
|
||||
|
|
@ -423,10 +396,7 @@ class TestTraceability(TestMrpCommon):
|
|||
mo_form.product_qty = 15
|
||||
mo = mo_form.save()
|
||||
mo.action_confirm()
|
||||
|
||||
action = mo.button_mark_done()
|
||||
wizard = Form(self.env[action['res_model']].with_context(action['context'])).save()
|
||||
wizard.process()
|
||||
mo.button_mark_done()
|
||||
|
||||
# Produce 15 x productB
|
||||
mo_form = Form(self.env['mrp.production'])
|
||||
|
|
@ -436,8 +406,9 @@ class TestTraceability(TestMrpCommon):
|
|||
mo.action_confirm()
|
||||
mo_form = Form(mo)
|
||||
mo_form.qty_producing = 15
|
||||
mo_form.lot_producing_id = lot_B03
|
||||
mo_form.lot_producing_ids.set(lot_B03)
|
||||
mo = mo_form.save()
|
||||
mo.lot_producing_ids = lot_B03
|
||||
mo.button_mark_done()
|
||||
|
||||
self.assertEqual(lot_B01.product_qty, 0)
|
||||
|
|
@ -453,10 +424,6 @@ class TestTraceability(TestMrpCommon):
|
|||
for EndProduct A, all three lots' delivery_ids are set to
|
||||
Picking A.
|
||||
"""
|
||||
|
||||
stock_location = self.env.ref('stock.stock_location_stock')
|
||||
customer_location = self.env.ref('stock.stock_location_customers')
|
||||
|
||||
# Create the three lot-tracked products.
|
||||
subcomponentA = self._create_product('lot')
|
||||
componentA = self._create_product('lot')
|
||||
|
|
@ -466,7 +433,6 @@ class TestTraceability(TestMrpCommon):
|
|||
lot_subcomponentA, lot_componentA, lot_endProductA = self.env['stock.lot'].create([{
|
||||
'name': 'lot %s' % product,
|
||||
'product_id': product.id,
|
||||
'company_id': self.env.company.id,
|
||||
} for product in (subcomponentA, componentA, endproductA)])
|
||||
|
||||
# Create two boms, one for Component A and one for EndProduct A
|
||||
|
|
@ -476,10 +442,10 @@ class TestTraceability(TestMrpCommon):
|
|||
'product_uom_id': self.uom_unit.id,
|
||||
'product_qty': 1.0,
|
||||
'type': 'normal',
|
||||
'bom_line_ids': [(0, 0, {'product_id': component.id, 'product_qty': 1})],
|
||||
'bom_line_ids': [Command.create({'product_id': component.id, 'product_qty': 1})],
|
||||
} for finished, component in [(endproductA, componentA), (componentA, subcomponentA)]])
|
||||
|
||||
self.env['stock.quant']._update_available_quantity(subcomponentA, stock_location, 1, lot_id=lot_subcomponentA)
|
||||
self.env['stock.quant']._update_available_quantity(subcomponentA, self.stock_location, 1, lot_id=lot_subcomponentA)
|
||||
|
||||
# Produce 1 component A
|
||||
mo_form = Form(self.env['mrp.production'])
|
||||
|
|
@ -488,10 +454,9 @@ class TestTraceability(TestMrpCommon):
|
|||
mo = mo_form.save()
|
||||
mo.action_confirm()
|
||||
mo_form = Form(mo)
|
||||
mo_form.qty_producing = 1
|
||||
mo_form.lot_producing_id = lot_componentA
|
||||
mo_form.lot_producing_ids.set(lot_componentA)
|
||||
mo = mo_form.save()
|
||||
mo.move_raw_ids[0].quantity_done = 1.0
|
||||
mo.move_raw_ids.picked = True
|
||||
mo.button_mark_done()
|
||||
|
||||
# Produce 1 endProduct A
|
||||
|
|
@ -501,37 +466,34 @@ class TestTraceability(TestMrpCommon):
|
|||
mo = mo_form.save()
|
||||
mo.action_confirm()
|
||||
mo_form = Form(mo)
|
||||
mo_form.qty_producing = 1
|
||||
mo_form.lot_producing_id = lot_endProductA
|
||||
mo_form.lot_producing_ids.set(lot_endProductA)
|
||||
mo = mo_form.save()
|
||||
mo.move_raw_ids[0].quantity_done = 1.0
|
||||
mo.move_raw_ids[0].write({'quantity': 1.0, 'picked': True})
|
||||
mo.button_mark_done()
|
||||
|
||||
# Create out picking for EndProduct A
|
||||
pickingA_out = self.env['stock.picking'].create({
|
||||
'picking_type_id': self.env.ref('stock.picking_type_out').id,
|
||||
'location_id': stock_location.id,
|
||||
'location_dest_id': customer_location.id})
|
||||
'picking_type_id': self.picking_type_out.id,
|
||||
'location_id': self.stock_location.id,
|
||||
'location_dest_id': self.customer_location.id,
|
||||
})
|
||||
|
||||
moveA = self.env['stock.move'].create({
|
||||
'name': 'Picking A move',
|
||||
'product_id': endproductA.id,
|
||||
'product_uom_qty': 1,
|
||||
'quantity': 1,
|
||||
'product_uom': endproductA.uom_id.id,
|
||||
'picking_id': pickingA_out.id,
|
||||
'location_id': stock_location.id,
|
||||
'location_dest_id': customer_location.id})
|
||||
|
||||
# Confirm and assign pickingA
|
||||
pickingA_out.action_confirm()
|
||||
pickingA_out.action_assign()
|
||||
'location_id': self.stock_location.id,
|
||||
'location_dest_id': self.customer_location.id,
|
||||
})
|
||||
|
||||
# Set move_line lot_id to the mrp.production lot_producing_id
|
||||
moveA.move_line_ids[0].write({
|
||||
'qty_done': 1.0,
|
||||
'quantity': 1.0,
|
||||
'lot_id': lot_endProductA.id,
|
||||
})
|
||||
# Transfer picking
|
||||
moveA.picked = True
|
||||
pickingA_out._action_done()
|
||||
|
||||
# Use concat so that delivery_ids is computed in batch.
|
||||
|
|
@ -544,20 +506,16 @@ class TestTraceability(TestMrpCommon):
|
|||
Build a product P that uses C with SN, unbuild P, scrap SN, unscrap SN
|
||||
and rebuild a product with SN in the components
|
||||
"""
|
||||
warehouse = self.env['stock.warehouse'].search([('company_id', '=', self.env.company.id)], limit=1)
|
||||
stock_location = warehouse.lot_stock_id
|
||||
|
||||
component = self.bom_4.bom_line_ids.product_id
|
||||
component.write({
|
||||
'type': 'product',
|
||||
'is_storable': True,
|
||||
'tracking': 'serial',
|
||||
})
|
||||
serial_number = self.env['stock.lot'].create({
|
||||
'product_id': component.id,
|
||||
'name': 'Super Serial',
|
||||
'company_id': self.env.company.id,
|
||||
})
|
||||
self.env['stock.quant']._update_available_quantity(component, stock_location, 1, lot_id=serial_number)
|
||||
self.env['stock.quant']._update_available_quantity(component, self.stock_location, 1, lot_id=serial_number)
|
||||
|
||||
# produce 1
|
||||
mo_form = Form(self.env['mrp.production'])
|
||||
|
|
@ -569,18 +527,17 @@ class TestTraceability(TestMrpCommon):
|
|||
|
||||
with Form(mo) as mo_form:
|
||||
mo_form.qty_producing = 1
|
||||
mo.move_raw_ids.move_line_ids.qty_done = 1
|
||||
mo.move_raw_ids.move_line_ids.quantity = 1
|
||||
mo.button_mark_done()
|
||||
|
||||
# unbuild
|
||||
action = mo.button_unbuild()
|
||||
wizard = Form(self.env[action['res_model']].with_context(action['context'])).save()
|
||||
wizard.action_validate()
|
||||
Form.from_action(self.env, mo.button_unbuild()).save().action_validate()
|
||||
|
||||
# scrap the component
|
||||
scrap = self.env['stock.scrap'].create({
|
||||
'product_id': component.id,
|
||||
'product_uom_id': component.uom_id.id,
|
||||
'location_id': self.stock_location.id,
|
||||
'scrap_qty': 1,
|
||||
'lot_id': serial_number.id,
|
||||
})
|
||||
|
|
@ -589,18 +546,18 @@ class TestTraceability(TestMrpCommon):
|
|||
|
||||
# unscrap the component
|
||||
internal_move = self.env['stock.move'].create({
|
||||
'name': component.name,
|
||||
'location_id': scrap_location.id,
|
||||
'location_dest_id': stock_location.id,
|
||||
'location_dest_id': self.stock_location.id,
|
||||
'product_id': component.id,
|
||||
'product_uom': component.uom_id.id,
|
||||
'product_uom_qty': 1.0,
|
||||
'move_line_ids': [(0, 0, {
|
||||
'picked': True,
|
||||
'move_line_ids': [Command.create({
|
||||
'product_id': component.id,
|
||||
'location_id': scrap_location.id,
|
||||
'location_dest_id': stock_location.id,
|
||||
'location_dest_id': self.stock_location.id,
|
||||
'product_uom_id': component.uom_id.id,
|
||||
'qty_done': 1.0,
|
||||
'quantity': 1.0,
|
||||
'lot_id': serial_number.id,
|
||||
})],
|
||||
})
|
||||
|
|
@ -617,12 +574,13 @@ class TestTraceability(TestMrpCommon):
|
|||
|
||||
with Form(mo) as mo_form:
|
||||
mo_form.qty_producing = 1
|
||||
mo.move_raw_ids.move_line_ids.qty_done = 1
|
||||
mo.move_raw_ids.move_line_ids.quantity = 1
|
||||
mo.move_raw_ids.picked = True
|
||||
mo.button_mark_done()
|
||||
|
||||
self.assertRecordValues((mo.move_finished_ids + mo.move_raw_ids).move_line_ids, [
|
||||
{'product_id': self.bom_4.product_id.id, 'lot_id': False, 'qty_done': 1},
|
||||
{'product_id': component.id, 'lot_id': serial_number.id, 'qty_done': 1},
|
||||
{'product_id': self.bom_4.product_id.id, 'lot_id': False, 'quantity': 1},
|
||||
{'product_id': component.id, 'lot_id': serial_number.id, 'quantity': 1},
|
||||
])
|
||||
|
||||
def test_generate_serial_button(self):
|
||||
|
|
@ -633,30 +591,150 @@ class TestTraceability(TestMrpCommon):
|
|||
|
||||
# generate lot lot_0 on MO
|
||||
mo.action_generate_serial()
|
||||
lot_0 = mo.lot_producing_id.name
|
||||
lot_0 = mo.lot_producing_ids[:1].name
|
||||
# manually create lot_1 (lot_0 + 1)
|
||||
lot_1 = self.env['stock.lot'].create({
|
||||
'name': str(int(lot_0) + 1).zfill(7),
|
||||
'product_id': p_final.id,
|
||||
'company_id': self.env.company.id,
|
||||
}).name
|
||||
# generate lot lot_2 on a new MO
|
||||
mo = mo.copy()
|
||||
mo.action_confirm()
|
||||
mo.action_generate_serial()
|
||||
lot_2 = mo.lot_producing_id.name
|
||||
lot_2 = mo.lot_producing_ids.name
|
||||
self.assertEqual(lot_2, str(int(lot_1) + 1).zfill(7))
|
||||
|
||||
def test_generate_serial_button_sequence(self):
|
||||
"""Test if serial in form "00000dd" is manually created, the generate serial
|
||||
correctly create new serial from sequence.
|
||||
"""
|
||||
mo, _bom, p_final, _p1, _p2 = self.generate_mo(qty_base_1=1, qty_base_2=1, qty_final=1, tracking_final='serial')
|
||||
p_final.serial_prefix_format = 'TEST/'
|
||||
|
||||
# manually create lot_1
|
||||
self.env['stock.lot'].create({
|
||||
'name': 'TEST/0000001',
|
||||
'product_id': p_final.id,
|
||||
})
|
||||
|
||||
# generate serial lot_2 from the MO (next_serial)
|
||||
mo.action_generate_serial()
|
||||
self.assertEqual(mo.lot_producing_ids[:1].name, "TEST/0000002")
|
||||
|
||||
p_final.lot_sequence_id.prefix = 'xx%(doy)sxx'
|
||||
# generate serial lot_3 from the MO (next from sequence)
|
||||
mo.lot_producing_ids = self.env['stock.lot']
|
||||
mo.action_generate_serial()
|
||||
self.assertIn(datetime.now().strftime('%j'), mo.lot_producing_ids.name)
|
||||
|
||||
def test_use_customized_serial_sequence(self):
|
||||
"""
|
||||
Test that serial numbers are generated with the correct prefix and sequence,
|
||||
that manually provided serial numbers are correctly applied, and that
|
||||
serial numbering remains consistent across multiple manufacturing orders.
|
||||
"""
|
||||
mo, bom, final_product, _comp_1, _comp_2 = self.generate_mo(
|
||||
tracking_final='serial',
|
||||
qty_base_1=1,
|
||||
qty_base_2=1,
|
||||
qty_final=2,
|
||||
)
|
||||
final_product.lot_sequence_id.prefix = 'TEST'
|
||||
final_product.lot_sequence_id.number_next_actual = 1
|
||||
serials_wizard = Form.from_action(self.env, mo.action_generate_serial())
|
||||
self.assertEqual(serials_wizard.lot_name, 'TEST0000001')
|
||||
serials_wizard.save().action_generate_serial_numbers()
|
||||
serials_wizard.save().action_apply()
|
||||
self.assertRecordValues(mo.lot_producing_ids.sorted('name'), [
|
||||
{'name': 'TEST0000001'},
|
||||
{'name': 'TEST0000002'},
|
||||
])
|
||||
mo.button_mark_done()
|
||||
self.assertEqual(self.env['stock.quant']._get_available_quantity(final_product, self.stock_location), 2)
|
||||
self.assertRecordValues(self.env['stock.lot'].search([('product_id', '=', final_product.id)]).sorted('name'), [
|
||||
{'name': 'TEST0000001'},
|
||||
{'name': 'TEST0000002'},
|
||||
])
|
||||
self.assertEqual(final_product.serial_prefix_format + final_product.next_serial, 'TEST0000003')
|
||||
|
||||
second_mo = self.env['mrp.production'].create({
|
||||
'product_id': final_product.id,
|
||||
'bom_id': bom.id,
|
||||
'product_qty': 5,
|
||||
})
|
||||
second_mo.action_confirm()
|
||||
second_serials_wizard = Form.from_action(self.env, second_mo.action_generate_serial())
|
||||
self.assertEqual(second_serials_wizard.lot_name, 'TEST0000003')
|
||||
second_serials_wizard.serial_numbers = 'TEST0000005\nLOREM002\nTEST0000003\nIPSUM101\nTEST0000004'
|
||||
second_serials_wizard.save().action_apply()
|
||||
self.assertRecordValues(second_mo.lot_producing_ids.sorted('name'), [
|
||||
{'name': 'IPSUM101'},
|
||||
{'name': 'LOREM002'},
|
||||
{'name': 'TEST0000003'},
|
||||
{'name': 'TEST0000004'},
|
||||
{'name': 'TEST0000005'},
|
||||
])
|
||||
second_mo.button_mark_done()
|
||||
self.assertEqual(self.env['stock.quant']._get_available_quantity(final_product, self.stock_location), 2 + 5)
|
||||
self.assertRecordValues(self.env['stock.lot'].search([('product_id', '=', final_product.id)]).sorted('name'), [
|
||||
{'name': 'IPSUM101'},
|
||||
{'name': 'LOREM002'},
|
||||
{'name': 'TEST0000001'},
|
||||
{'name': 'TEST0000002'},
|
||||
{'name': 'TEST0000003'},
|
||||
{'name': 'TEST0000004'},
|
||||
{'name': 'TEST0000005'},
|
||||
])
|
||||
|
||||
third_mo = self.env['mrp.production'].create({
|
||||
'product_id': final_product.id,
|
||||
'bom_id': bom.id,
|
||||
'product_qty': 2,
|
||||
})
|
||||
third_mo.action_confirm()
|
||||
third_serials_wizard = Form.from_action(self.env, third_mo.action_generate_serial())
|
||||
self.assertEqual(third_serials_wizard.lot_name, 'TEST0000006')
|
||||
|
||||
@freeze_time('2024-02-03')
|
||||
def test_interpolation_in_batch_serials(self):
|
||||
"""
|
||||
Test that prefixes are correctly interpolated when
|
||||
generating multiple serial numbers in one MO
|
||||
"""
|
||||
mo, _bom, final_product, _comp_1, _comp_2 = self.generate_mo(
|
||||
tracking_final='serial',
|
||||
qty_base_1=1,
|
||||
qty_base_2=1,
|
||||
qty_final=2,
|
||||
)
|
||||
final_product.lot_sequence_id.prefix = '%(day)s-%(month)s-'
|
||||
final_product.lot_sequence_id.number_next_actual = 1
|
||||
serials_wizard = Form.from_action(self.env, mo.action_generate_serial())
|
||||
self.assertEqual(serials_wizard.lot_name, '03-02-0000001')
|
||||
serials_wizard.save().action_generate_serial_numbers()
|
||||
serials_wizard.save().action_apply()
|
||||
self.assertRecordValues(mo.lot_producing_ids.sorted('name'), [
|
||||
{'name': '03-02-0000001'},
|
||||
{'name': '03-02-0000002'},
|
||||
])
|
||||
mo.button_mark_done()
|
||||
self.assertEqual(self.env['stock.quant']._get_available_quantity(final_product, self.stock_location), 2)
|
||||
self.assertRecordValues(self.env['stock.lot'].search([('product_id', '=', final_product.id)]).sorted('name'), [
|
||||
{'name': '03-02-0000001'},
|
||||
{'name': '03-02-0000002'},
|
||||
])
|
||||
self.assertEqual(final_product.next_serial, '0000003')
|
||||
|
||||
def test_assign_stock_move_date_on_mark_done(self):
|
||||
product_final = self.env['product.product'].create({
|
||||
'name': 'Finished Product',
|
||||
'type': 'product',
|
||||
'is_storable': True,
|
||||
})
|
||||
with freeze_time('2024-01-15'):
|
||||
production = self.env['mrp.production'].create({
|
||||
'product_id': product_final.id,
|
||||
'product_qty': 1,
|
||||
'date_planned_start': datetime(2024, 1, 10)
|
||||
'date_start': datetime(2024, 1, 10)
|
||||
})
|
||||
production.action_confirm()
|
||||
production.qty_producing = 1
|
||||
|
|
@ -670,10 +748,9 @@ class TestTraceability(TestMrpCommon):
|
|||
Consume SN
|
||||
Consume SN -> Should raise an error as it has already been consumed
|
||||
"""
|
||||
stock_location = self.env.ref('stock.stock_location_stock')
|
||||
component = self.bom_4.bom_line_ids.product_id
|
||||
component.write({
|
||||
'type': 'product',
|
||||
'is_storable': True,
|
||||
'tracking': 'serial',
|
||||
})
|
||||
|
||||
|
|
@ -682,7 +759,7 @@ class TestTraceability(TestMrpCommon):
|
|||
'name': name,
|
||||
'company_id': self.env.company.id,
|
||||
} for name in ['SN01', 'SN02']])
|
||||
self.env['stock.quant']._update_available_quantity(component, stock_location, 1, lot_id=sn_lot02)
|
||||
self.env['stock.quant']._update_available_quantity(component, self.stock_location, 1, lot_id=sn_lot02)
|
||||
|
||||
mo = self.env['mrp.production'].create({
|
||||
'product_id': component.id,
|
||||
|
|
@ -691,11 +768,10 @@ class TestTraceability(TestMrpCommon):
|
|||
'company_id': self.env.company.id,
|
||||
})
|
||||
mo.action_confirm()
|
||||
mo.qty_producing = 1
|
||||
mo.lot_producing_id = sn_lot01
|
||||
mo.lot_producing_ids = sn_lot01
|
||||
mo.button_mark_done()
|
||||
self.assertRecordValues(mo.move_finished_ids.move_line_ids, [
|
||||
{'product_id': component.id, 'lot_id': sn_lot01.id, 'qty_done': 1.0, 'state': 'done'},
|
||||
{'product_id': component.id, 'lot_id': sn_lot01.id, 'quantity': 1.0, 'state': 'done'},
|
||||
])
|
||||
|
||||
mo_form = Form(self.env['mrp.production'])
|
||||
|
|
@ -703,11 +779,12 @@ class TestTraceability(TestMrpCommon):
|
|||
mo = mo_form.save()
|
||||
mo.action_confirm()
|
||||
mo.qty_producing = 1
|
||||
mo.move_raw_ids.move_line_ids.qty_done = 1
|
||||
mo.move_raw_ids.move_line_ids.quantity = 1
|
||||
mo.move_raw_ids.move_line_ids.lot_id = sn_lot01
|
||||
mo.move_raw_ids.move_line_ids.picked = True
|
||||
mo.button_mark_done()
|
||||
self.assertRecordValues(mo.move_raw_ids.move_line_ids, [
|
||||
{'product_id': component.id, 'lot_id': sn_lot01.id, 'qty_done': 1.0, 'state': 'done'},
|
||||
{'product_id': component.id, 'lot_id': sn_lot01.id, 'quantity': 1.0, 'state': 'done'},
|
||||
])
|
||||
|
||||
mo_form = Form(self.env['mrp.production'])
|
||||
|
|
@ -715,8 +792,9 @@ class TestTraceability(TestMrpCommon):
|
|||
mo = mo_form.save()
|
||||
mo.action_confirm()
|
||||
mo.qty_producing = 1
|
||||
mo.move_raw_ids.move_line_ids.qty_done = 1
|
||||
mo.move_raw_ids.move_line_ids.quantity = 1
|
||||
mo.move_raw_ids.move_line_ids.lot_id = sn_lot01
|
||||
mo.move_raw_ids.move_line_ids.picked = True
|
||||
with self.assertRaises(UserError):
|
||||
mo.button_mark_done()
|
||||
|
||||
|
|
@ -730,7 +808,7 @@ class TestTraceability(TestMrpCommon):
|
|||
"""
|
||||
component = self.bom_4.bom_line_ids.product_id
|
||||
component.write({
|
||||
'type': 'product',
|
||||
'is_storable': True,
|
||||
'tracking': 'serial',
|
||||
})
|
||||
|
||||
|
|
@ -747,8 +825,7 @@ class TestTraceability(TestMrpCommon):
|
|||
'company_id': self.env.company.id,
|
||||
})
|
||||
mo_produce_sn.action_confirm()
|
||||
mo_produce_sn.qty_producing = 1
|
||||
mo_produce_sn.lot_producing_id = sn
|
||||
mo_produce_sn.lot_producing_ids = sn
|
||||
mo_produce_sn.button_mark_done()
|
||||
|
||||
mo_consume_sn_form = Form(self.env['mrp.production'])
|
||||
|
|
@ -756,11 +833,12 @@ class TestTraceability(TestMrpCommon):
|
|||
mo_consume_sn = mo_consume_sn_form.save()
|
||||
mo_consume_sn.action_confirm()
|
||||
mo_consume_sn.qty_producing = 1
|
||||
mo_consume_sn.move_raw_ids.move_line_ids.qty_done = 1
|
||||
mo_consume_sn.move_raw_ids.move_line_ids.quantity = 1
|
||||
mo_consume_sn.move_raw_ids.move_line_ids.lot_id = sn
|
||||
mo_consume_sn.move_raw_ids.move_line_ids.picked = True
|
||||
mo_consume_sn.button_mark_done()
|
||||
self.assertRecordValues(mo_consume_sn.move_raw_ids.move_line_ids, [
|
||||
{'product_id': component.id, 'lot_id': sn.id, 'qty_done': 1.0, 'state': 'done'},
|
||||
{'product_id': component.id, 'lot_id': sn.id, 'quantity': 1.0, 'state': 'done'},
|
||||
])
|
||||
|
||||
unbuild_form = Form(self.env['mrp.unbuild'])
|
||||
|
|
@ -772,11 +850,12 @@ class TestTraceability(TestMrpCommon):
|
|||
mo_consume_sn = mo_consume_sn_form.save()
|
||||
mo_consume_sn.action_confirm()
|
||||
mo_consume_sn.qty_producing = 1
|
||||
mo_consume_sn.move_raw_ids.move_line_ids.qty_done = 1
|
||||
mo_consume_sn.move_raw_ids.move_line_ids.quantity = 1
|
||||
mo_consume_sn.move_raw_ids.move_line_ids.lot_id = sn
|
||||
mo_consume_sn.move_raw_ids.move_line_ids.picked = True
|
||||
mo_consume_sn.button_mark_done()
|
||||
self.assertRecordValues(mo_consume_sn.move_raw_ids.move_line_ids, [
|
||||
{'product_id': component.id, 'lot_id': sn.id, 'qty_done': 1.0, 'state': 'done'},
|
||||
{'product_id': component.id, 'lot_id': sn.id, 'quantity': 1.0, 'state': 'done'},
|
||||
])
|
||||
|
||||
def test_produce_consume_unbuild_all_and_consume(self):
|
||||
|
|
@ -789,10 +868,9 @@ class TestTraceability(TestMrpCommon):
|
|||
Consume SN
|
||||
-> We should not raise any UserError
|
||||
"""
|
||||
stock_location = self.env.ref('stock.stock_location_stock')
|
||||
component = self.bom_4.bom_line_ids.product_id
|
||||
component.write({
|
||||
'type': 'product',
|
||||
'is_storable': True,
|
||||
'tracking': 'serial',
|
||||
})
|
||||
|
||||
|
|
@ -809,8 +887,7 @@ class TestTraceability(TestMrpCommon):
|
|||
'company_id': self.env.company.id,
|
||||
})
|
||||
mo_produce_sn.action_confirm()
|
||||
mo_produce_sn.qty_producing = 1
|
||||
mo_produce_sn.lot_producing_id = sn
|
||||
mo_produce_sn.lot_producing_ids = sn
|
||||
mo_produce_sn.button_mark_done()
|
||||
|
||||
mo_consume_sn_form = Form(self.env['mrp.production'])
|
||||
|
|
@ -818,11 +895,12 @@ class TestTraceability(TestMrpCommon):
|
|||
mo_consume_sn = mo_consume_sn_form.save()
|
||||
mo_consume_sn.action_confirm()
|
||||
mo_consume_sn.qty_producing = 1
|
||||
mo_consume_sn.move_raw_ids.move_line_ids.qty_done = 1
|
||||
mo_consume_sn.move_raw_ids.move_line_ids.quantity = 1
|
||||
mo_consume_sn.move_raw_ids.move_line_ids.lot_id = sn
|
||||
mo_consume_sn.move_raw_ids.move_line_ids.picked = True
|
||||
mo_consume_sn.button_mark_done()
|
||||
self.assertRecordValues(mo_consume_sn.move_raw_ids.move_line_ids, [
|
||||
{'product_id': component.id, 'lot_id': sn.id, 'qty_done': 1.0, 'state': 'done'},
|
||||
{'product_id': component.id, 'lot_id': sn.id, 'quantity': 1.0, 'state': 'done'},
|
||||
])
|
||||
|
||||
unbuild_form = Form(self.env['mrp.unbuild'])
|
||||
|
|
@ -831,18 +909,20 @@ class TestTraceability(TestMrpCommon):
|
|||
|
||||
unbuild_form = Form(self.env['mrp.unbuild'])
|
||||
unbuild_form.mo_id = mo_produce_sn
|
||||
unbuild_form.lot_id = sn
|
||||
unbuild_form.save().action_unbuild()
|
||||
|
||||
self.env['stock.quant']._update_available_quantity(component, stock_location, 1, lot_id=sn)
|
||||
self.env['stock.quant']._update_available_quantity(component, self.stock_location, 1, lot_id=sn)
|
||||
|
||||
mo_consume_sn_form = Form(self.env['mrp.production'])
|
||||
mo_consume_sn_form.bom_id = self.bom_4
|
||||
mo_consume_sn = mo_consume_sn_form.save()
|
||||
mo_consume_sn.action_confirm()
|
||||
mo_consume_sn.qty_producing = 1
|
||||
mo_consume_sn.move_raw_ids.move_line_ids.qty_done = 1
|
||||
mo_consume_sn.move_raw_ids.move_line_ids.quantity = 1
|
||||
mo_consume_sn.move_raw_ids.move_line_ids.lot_id = sn
|
||||
mo_consume_sn.move_raw_ids.move_line_ids.picked = True
|
||||
mo_consume_sn.button_mark_done()
|
||||
self.assertRecordValues(mo_consume_sn.move_raw_ids.move_line_ids, [
|
||||
{'product_id': component.id, 'lot_id': sn.id, 'qty_done': 1.0, 'state': 'done'},
|
||||
{'product_id': component.id, 'lot_id': sn.id, 'quantity': 1.0, 'state': 'done'},
|
||||
])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue