feat:物料新增入库检验方式test_mode_in(免检/必检,默认必检),生产领料检验卡点支持物料级免检,明细过滤器支持material__test_mode_in

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
caoqianming 2026-07-22 16:20:18 +08:00
parent b0263bae32
commit ea0fe7c312
5 changed files with 32 additions and 5 deletions

View File

@ -188,9 +188,10 @@ class MIOItemCreateSerializer(CustomModelSerializer):
if mio.state != MIO.MIO_CREATE:
raise ParseError('出入库记录非创建中不可新增')
# 生产领料要校验是否进行检验
# 某些客户此处无需校验
# 某些客户此处无需校验(全局总开关); 免检物料单独放行
check_test_when_do_out = get_sysconfig('mes.check_test_when_do_out', True)
if check_test_when_do_out and mio.type == MIO.MIO_TYPE_DO_OUT:
if (check_test_when_do_out and mio.type == MIO.MIO_TYPE_DO_OUT
and material.test_mode_in != Material.MA_TEST_EXEMPT):
mis = MIOItem.objects.filter(batch=batch, material=material, mio__type__in=[MIO.MIO_TYPE_PUR_IN, MIO.MIO_TYPE_DO_IN, MIO.MIO_TYPE_OTHER_IN])
if mis.exists() and (not mis.exclude(test_date=None).exists()):
raise ParseError('该批次的物料未经检验')

View File

@ -379,6 +379,7 @@ class MIOItemViewSet(CustomListModelMixin, BulkCreateModelMixin, BulkDestroyMode
"mio__inout_date": ["gte", "lte", "exact"],
"material": ["exact"],
"material__type": ["exact"],
"material__test_mode_in": ["exact"],
"test_date": ["isnull", "exact"]
}
ordering = ['create_time']

View File

@ -0,0 +1,18 @@
# Generated by Django 4.2.27 on 2026-07-22 07:55
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mtm', '0066_alter_process_clear_defect'),
]
operations = [
migrations.AddField(
model_name='material',
name='test_mode_in',
field=models.PositiveSmallIntegerField(choices=[(10, '免检'), (20, '必检')], default=20, help_text='仓库入库后是否需要检验;免检物料生产领料时不校验', verbose_name='入库检验方式'),
),
]

View File

@ -79,6 +79,9 @@ class Material(CommonAModel):
MA_TRACKING_BATCH = 10
MA_TRACKING_SINGLE = 20
MA_TEST_EXEMPT = 10
MA_TEST_REQUIRED = 20
name = models.CharField('名称', max_length=50)
cate = models.CharField('大类', max_length=20, default='', blank=True)
number = models.CharField('编号', max_length=100, null=True, blank=True)
@ -95,6 +98,10 @@ class Material(CommonAModel):
tracking = models.PositiveSmallIntegerField("追踪方式", default=10,
choices=((MA_TRACKING_BATCH, '批次'),
(MA_TRACKING_SINGLE, '单件')))
test_mode_in = models.PositiveSmallIntegerField('入库检验方式', default=20,
choices=((MA_TEST_EXEMPT, '免检'),
(MA_TEST_REQUIRED, '必检')),
help_text='仓库入库后是否需要检验;免检物料生产领料时不校验')
# count = models.DecimalField('总库存', max_digits=14, decimal_places=3, default=0)
# count_mb = models.DecimalField('仓库库存', max_digits=14, decimal_places=3, default=0)
# count_wm = models.DecimalField('车间库存', max_digits=14, decimal_places=3, default=0)

View File

@ -24,7 +24,7 @@ class MaterialSimpleSerializer(CustomModelSerializer):
class Meta:
model = Material
fields = ['id', 'name', 'number', 'model',
'specification', 'type', 'cate', 'brothers', 'process_name', 'full_name', "tracking", "bin_number_main"]
'specification', 'type', 'cate', 'brothers', 'process_name', 'full_name', "tracking", "bin_number_main", "test_mode_in"]
def get_full_name(self, obj):
return f'{obj.name}|{obj.specification if obj.specification else ""}|{obj.model if obj.model else ""}|{obj.process.name if obj.process else ""}'