[FIX] mrp : replacing tracked part in repair fails uniqueness
Issue: When replacing a tracked part while doing a repair, we are changing the tracking number, but when checking for uniqueness, we don't take that change into consideration Steps to reproduce : 1) Manufacture product A with SN "A1" out of product B with SN "B2" 2) Make Repair Order for "A1" to replace "B2" with Product B (SN "B1"). 3) Create Manufacturing Order product A (A2), select product B with SN "B2" as one of the components. 4) Mark as done -> Bug : "The serial number <B2> used for component <B> has already been consumed". Why is that a bug: When checking for uniqueness we should take into consideration the parts being replaced opw-2625687 closes odoo/odoo#78407 X-original-commit: 79c673f9d15185be540dd535d7ebe10c8f138bf1 Signed-off-by: William Henrotin <Whenrow@users.noreply.github.com>
This commit is contained in:
committed by
Adrien Widart
parent
433f0c15bf
commit
04bb7005b7
@@ -1804,7 +1804,13 @@ class MrpProduction(models.Model):
|
||||
duplicates_unbuild = self.env['stock.move.line'].search_count(domain_unbuild + [
|
||||
('move_id.unbuild_id', '!=', False)
|
||||
])
|
||||
if not (duplicates_unbuild and duplicates - duplicates_unbuild == 0):
|
||||
removed = self.env['stock.move.line'].search_count([
|
||||
('lot_id', '=', move_line.lot_id.id),
|
||||
('state', '=', 'done'),
|
||||
('location_dest_id.scrap_location', '=', True)
|
||||
])
|
||||
# Either removed or unbuild
|
||||
if not ((duplicates_unbuild or removed) and duplicates - duplicates_unbuild - removed == 0):
|
||||
raise UserError(message)
|
||||
# Check presence of same sn in current production
|
||||
duplicates = co_prod_move_lines.filtered(lambda ml: ml.qty_done and ml.lot_id == move_line.lot_id) - move_line
|
||||
@@ -1840,7 +1846,13 @@ class MrpProduction(models.Model):
|
||||
duplicates_unbuild = self.env['stock.move.line'].search_count(domain_unbuild + [
|
||||
('move_id.unbuild_id', '!=', False)
|
||||
])
|
||||
if not (duplicates_unbuild and duplicates - duplicates_unbuild == 0):
|
||||
removed = self.env['stock.move.line'].search_count([
|
||||
('lot_id', '=', move_line.lot_id.id),
|
||||
('state', '=', 'done'),
|
||||
('location_dest_id.scrap_location', '=', True)
|
||||
])
|
||||
# Either removed or unbuild
|
||||
if not ((duplicates_unbuild or removed) and duplicates - duplicates_unbuild - removed == 0):
|
||||
raise UserError(message)
|
||||
# Check presence of same sn in current production
|
||||
duplicates = co_prod_move_lines.filtered(lambda ml: ml.qty_done and ml.lot_id == move_line.lot_id) - move_line
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import test_tracability
|
||||
@@ -0,0 +1,74 @@
|
||||
# -*- 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
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestRepairTraceability(TestMrpCommon):
|
||||
|
||||
def test_tracking_repair_production(self):
|
||||
"""
|
||||
Test that removing a tracked component with a repair does not block the flow of using that component in another
|
||||
bom
|
||||
"""
|
||||
product_to_repair = self.env['product.product'].create({
|
||||
'name': 'product first serial to act repair',
|
||||
'tracking': 'serial',
|
||||
})
|
||||
ptrepair_lot = self.env['stock.production.lot'].create({
|
||||
'name': 'A1',
|
||||
'product_id': product_to_repair.id,
|
||||
'company_id': self.env.user.company_id.id
|
||||
})
|
||||
product_to_remove = self.env['product.product'].create({
|
||||
'name': 'other first serial to remove with repair',
|
||||
'tracking': 'serial',
|
||||
})
|
||||
ptremove_lot = self.env['stock.production.lot'].create({
|
||||
'name': 'B2',
|
||||
'product_id': product_to_remove.id,
|
||||
'company_id': self.env.user.company_id.id
|
||||
})
|
||||
# Create a manufacturing order with product (with SN A1)
|
||||
mo_form = Form(self.env['mrp.production'])
|
||||
mo_form.product_id = product_to_repair
|
||||
with mo_form.move_raw_ids.new() as move:
|
||||
move.product_id = product_to_remove
|
||||
move.product_uom_qty = 1
|
||||
move.move_line_ids.lot_id = ptremove_lot # Set component serial to B2
|
||||
mo = mo_form.save()
|
||||
mo.action_confirm()
|
||||
# Set serial to A1
|
||||
mo.lot_producing_id = ptrepair_lot
|
||||
mo.button_mark_done()
|
||||
|
||||
with Form(self.env['repair.order']) as ro_form:
|
||||
ro_form.product_id = product_to_repair
|
||||
ro_form.lot_id = ptrepair_lot # Repair product Serial A1
|
||||
with ro_form.operations.new() as operation:
|
||||
operation.type = 'remove'
|
||||
operation.product_id = product_to_remove
|
||||
operation.lot_id = ptremove_lot # Remove product Serial B2 from the product
|
||||
ro = ro_form.save()
|
||||
ro.action_validate()
|
||||
ro.action_repair_start()
|
||||
ro.action_repair_end()
|
||||
|
||||
# Create a manufacturing order with product (with SN A2)
|
||||
mo2_form = Form(self.env['mrp.production'])
|
||||
mo2_form.product_id = product_to_repair
|
||||
with mo2_form.move_raw_ids.new() as move:
|
||||
move.product_id = product_to_remove
|
||||
move.product_uom_qty = 1
|
||||
move.move_line_ids.lot_id = ptremove_lot # Set component serial to B2 again, it is possible
|
||||
mo2 = mo2_form.save()
|
||||
mo2.action_confirm()
|
||||
# Set serial to A2
|
||||
mo2.lot_producing_id = self.env['stock.production.lot'].create({
|
||||
'name': 'A2',
|
||||
'product_id': product_to_repair.id,
|
||||
'company_id': self.env.user.company_id.id
|
||||
})
|
||||
# We are not forbidden to use that serial number, so nothing raised here
|
||||
mo2.button_mark_done()
|
||||
Reference in New Issue
Block a user