From 074e759c2908dfbadd40d98bcdc0e10999dbc0a3 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 30 Jul 2026 14:52:43 +0800 Subject: [PATCH] Allow clearing same-grade batch defects --- apps/wpm/serializers.py | 15 +++++++----- apps/wpm/tests.py | 52 ++++++++++++++++++++++++++++++++++------- 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/apps/wpm/serializers.py b/apps/wpm/serializers.py index c01dae8c..cae7fe3e 100644 --- a/apps/wpm/serializers.py +++ b/apps/wpm/serializers.py @@ -1398,6 +1398,7 @@ class HandoverSerializer(CustomModelSerializer): next_mat = None next_state = None next_defect = None + next_defect_grade = None if new_wm and attrs["type"] != Handover.H_CHANGE: next_mat = new_wm.material next_state = new_wm.state @@ -1418,13 +1419,15 @@ class HandoverSerializer(CustomModelSerializer): if clear_defect and new_wm is not None and new_wm.defect is not None: raise ParseError('清除批次缺陷时目标批次不能带缺陷') if clear_defect and tracking == Material.MA_TRACKING_BATCH: - if ( - wm.state != WMaterial.WM_OK - or wm.defect is None - or wm.defect.okcate != Defect.DEFECT_OK_B - ): + if wm.defect is None: raise ParseError( - f'第{ind+1}行-批次追踪物料仅合格B类可清除批次缺陷' + f'第{ind+1}行-批次追踪物料仅同缺陷等级可清除批次缺陷' + ) + if next_defect_grade is None: + next_defect_grade = wm.defect.okcate + elif next_defect_grade != wm.defect.okcate: + raise ParseError( + f'第{ind+1}行-批次追踪物料仅同缺陷等级可清除批次缺陷' ) if next_mat is None: next_mat = wm.material diff --git a/apps/wpm/tests.py b/apps/wpm/tests.py index 189faf9e..0ce84e2c 100644 --- a/apps/wpm/tests.py +++ b/apps/wpm/tests.py @@ -462,22 +462,58 @@ class WMaterialScopeTests(SimpleTestCase): self.assertTrue(validated["clear_defect"]) self.assertEqual(validated["count"], 2) - def test_batch_tracking_merge_cannot_clear_notok_defect(self): + def test_batch_tracking_merge_can_clear_same_grade_notok_defects(self): material = Material(tracking=Material.MA_TRACKING_BATCH) - defect = Defect(id="1", okcate=Defect.DEFECT_NOTOK) - wm = WMaterial( + defect_a = Defect(id="1", okcate=Defect.DEFECT_NOTOK) + defect_b = Defect(id="2", okcate=Defect.DEFECT_NOTOK) + wm_a = WMaterial( id="10", material=material, batch="N-001", count=1, - state=WMaterial.WM_NOTOK, defect=defect, + state=WMaterial.WM_NOTOK, defect=defect_a, + ) + wm_b = WMaterial( + id="20", material=material, batch="N-002", count=1, + state=WMaterial.WM_NOTOK, defect=defect_b, + ) + + validated = HandoverSerializer().validate({ + "wm": wm_a, + "handoverb": [ + {"wm": wm_a, "count": 1}, + {"wm": wm_b, "count": 1}, + ], + "new_batch": "N-MERGED", + "clear_defect": True, + "type": Handover.H_NORMAL, + "mtype": Handover.H_MERGE, + }) + + self.assertTrue(validated["clear_defect"]) + self.assertEqual(validated["count"], 2) + + def test_batch_tracking_merge_cannot_clear_mixed_defect_grades(self): + material = Material(tracking=Material.MA_TRACKING_BATCH) + defect_b = Defect(id="1", okcate=Defect.DEFECT_OK_B) + defect_notok = Defect(id="2", okcate=Defect.DEFECT_NOTOK) + wm_a = WMaterial( + id="10", material=material, batch="B-001", count=1, + state=WMaterial.WM_OK, defect=defect_b, + ) + wm_b = WMaterial( + id="20", material=material, batch="N-001", count=1, + state=WMaterial.WM_OK, defect=defect_notok, ) with self.assertRaisesMessage( ParseError, - "批次追踪物料仅合格B类可清除批次缺陷", + "批次追踪物料仅同缺陷等级可清除批次缺陷", ): HandoverSerializer().validate({ - "wm": wm, - "handoverb": [{"wm": wm, "count": 1}], - "new_batch": "N-MERGED", + "wm": wm_a, + "handoverb": [ + {"wm": wm_a, "count": 1}, + {"wm": wm_b, "count": 1}, + ], + "new_batch": "MIXED-MERGED", "clear_defect": True, "type": Handover.H_NORMAL, "mtype": Handover.H_MERGE,