Expose independent material defect grades

This commit is contained in:
caoqianming 2026-07-30 11:15:29 +08:00
parent 298a32f744
commit 6068f2315d
3 changed files with 96 additions and 2 deletions

View File

@ -132,7 +132,8 @@ class WMaterialFilter(filters.FilterSet):
"notok_sign": ["exact", "in", "isnull"],
"count_xtest": ["gte", "isnull"],
"supplier": ["exact"],
"defect": ["exact", "isnull"]
"defect": ["exact", "isnull"],
"defect__okcate": ["exact", "in"],
}
class MlogFilter(filters.FilterSet):

View File

@ -190,12 +190,20 @@ class WMaterialSerializer(CustomModelSerializer):
notok_sign_name = serializers.SerializerMethodField()
defect_name = serializers.CharField(source="defect.name", read_only=True)
defect_okcate = serializers.IntegerField(source="defect.okcate", read_only=True)
defect_grade = serializers.SerializerMethodField()
defect_grade_name = serializers.SerializerMethodField()
count_working = serializers.SerializerMethodField(label='在制数量')
count_handovering = serializers.SerializerMethodField(label='正在交送的数量')
def get_notok_sign_name(self, obj):
return getattr(NotOkOption, obj.notok_sign, NotOkOption.qt).label if obj.notok_sign else None
def get_defect_grade(self, obj):
return obj.defect.okcate if obj.defect else None
def get_defect_grade_name(self, obj):
return obj.defect.get_okcate_display() if obj.defect else None
def get_count_working(self, obj):
# 列表接口 queryset 已注解(单次聚合); 嵌套等无注解场景回退模型属性
# 保留 decimal 精度(原 IntegerField 会截断在途量, 导致可用/可交接量偏大)

View File

@ -13,7 +13,11 @@ from apps.qm.models import Defect
from apps.system.models import Dept, User
from apps.wpm.filters import HandoverFilter, WMaterialFilter
from apps.wpm.models import Handover, WMaterial
from apps.wpm.serializers import HandoverSerializer, WMaterialCreateSerializer
from apps.wpm.serializers import (
HandoverSerializer,
WMaterialCreateSerializer,
WMaterialSerializer,
)
from apps.wpm.services import restore_mlog_wpr_defects, snapshot_mlog_wpr_defects
from apps.wpm.views import MlogbwViewSet
from apps.wpmw.models import Wpr, WprDefect
@ -100,6 +104,87 @@ class HandoverFilterTests(TestCase):
])
class WMaterialDefectGradeTests(TestCase):
@classmethod
def setUpTestData(cls):
cls.material = Material.objects.create(name="缺陷等级测试物料")
cls.defect_b = Defect.objects.create(
name="B类缺陷",
cate=Defect.cate_list[0],
okcate=Defect.DEFECT_OK_B,
)
cls.defect_notok = Defect.objects.create(
name="不合格缺陷",
cate=Defect.cate_list[0],
okcate=Defect.DEFECT_NOTOK,
)
cls.normal_with_notok_defect = WMaterial.objects.create(
material=cls.material,
batch="NORMAL-NOTOK",
count=1,
state=WMaterial.WM_OK,
defect=cls.defect_notok,
)
cls.notok_with_b_defect = WMaterial.objects.create(
material=cls.material,
batch="NOTOK-B",
count=1,
state=WMaterial.WM_NOTOK,
defect=cls.defect_b,
)
cls.normal_without_defect = WMaterial.objects.create(
material=cls.material,
batch="NORMAL-NONE",
count=1,
state=WMaterial.WM_OK,
)
def test_serializer_exposes_nullable_defect_grade_without_using_state(self):
normal_notok_data = WMaterialSerializer(
self.normal_with_notok_defect
).data
notok_b_data = WMaterialSerializer(self.notok_with_b_defect).data
no_defect_data = WMaterialSerializer(self.normal_without_defect).data
self.assertEqual(
normal_notok_data["defect_grade"], Defect.DEFECT_NOTOK
)
self.assertEqual(normal_notok_data["defect_grade_name"], "不合格")
self.assertEqual(
notok_b_data["defect_grade"], Defect.DEFECT_OK_B
)
self.assertEqual(notok_b_data["defect_grade_name"], "合格B类")
self.assertIsNone(no_defect_data["defect_grade"])
self.assertIsNone(no_defect_data["defect_grade_name"])
def test_filtering_state_and_defect_grade_are_independent(self):
normal_notok = WMaterialFilter(
{
"state": WMaterial.WM_OK,
"defect__okcate": Defect.DEFECT_NOTOK,
},
queryset=WMaterial.objects.all(),
).qs
notok_b = WMaterialFilter(
{
"state": WMaterial.WM_NOTOK,
"defect__okcate": Defect.DEFECT_OK_B,
},
queryset=WMaterial.objects.all(),
).qs
self.assertQuerySetEqual(
normal_notok,
[self.normal_with_notok_defect],
transform=lambda item: item,
)
self.assertQuerySetEqual(
notok_b,
[self.notok_with_b_defect],
transform=lambda item: item,
)
class MlogbwViewSetTests(SimpleTestCase):
@patch("apps.wpm.views.MlogViewSet.lock_and_check_can_update")
@patch("apps.wpm.views.Mlogbw.cal_count_notok")