feat: qctmat添加字段以支持消耗物料参数填写

This commit is contained in:
caoqianming 2025-07-18 16:01:32 +08:00
parent 3985401361
commit d732652c9f
7 changed files with 48 additions and 12 deletions

View File

@ -67,7 +67,7 @@ def daoru_mioitem_test(path:str, mioitem:MIOItem):
from openpyxl import load_workbook from openpyxl import load_workbook
from apps.qm.models import TestItem, Ftest, Qct, FtestItem, FtestDefect from apps.qm.models import TestItem, Ftest, Qct, FtestItem, FtestDefect
qct = Qct.get(mioitem.material, tag="inm") qct = Qct.get(mioitem.material, tag="inm", type="in")
if qct is None: if qct is None:
raise ParseError("未找到检验表") raise ParseError("未找到检验表")

View File

@ -0,0 +1,23 @@
# Generated by Django 3.2.12 on 2025-07-18 07:58
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('qm', '0051_alter_ftestwork_batch'),
]
operations = [
migrations.AddField(
model_name='qctmat',
name='use_for_in',
field=models.BooleanField(default=True, verbose_name='可用于消耗'),
),
migrations.AddField(
model_name='qctmat',
name='use_for_out',
field=models.BooleanField(default=True, verbose_name='可用于产出'),
),
]

View File

@ -172,9 +172,14 @@ class Qct(CommonAModel):
return QctMat.objects.filter(qct=self) return QctMat.objects.filter(qct=self)
@classmethod @classmethod
def get(cls, material:Material, tag:str): def get(cls, material:Material, tag:str, type:str=None):
try: try:
qct = Qct.objects.get(qctmat__material=material, tags__contains=tag) if type == "in":
qct = Qct.objects.get(qctmat__material=material, tags__contains=tag, qctmat__use_for_in=True)
elif type == "out":
qct = Qct.objects.get(qctmat__material=material, tags__contains=tag, qctmat__use_for_out=True)
else:
qct = Qct.objects.get(qctmat__material=material, tags__contains=tag)
except Qct.DoesNotExist: except Qct.DoesNotExist:
try: try:
qct = Qct.objects.get(name="默认检验表") qct = Qct.objects.get(name="默认检验表")
@ -195,8 +200,12 @@ class Qct(CommonAModel):
return None return None
@classmethod @classmethod
def get_qs(cls, materialId:str, tag:str): def get_qs(cls, materialId:str, tag:str, type:str):
qct_qs = Qct.objects.filter(qctmat__material__id=materialId, tags__contains=tag) qct_qs = Qct.objects.filter(qctmat__material__id=materialId, tags__contains=tag)
if type == "in":
qct_qs = qct_qs.filter(qctmat__use_for_in=True)
elif type == "out":
qct_qs = qct_qs.filter(qctmat__use_for_out=True)
if not qct_qs.exists(): if not qct_qs.exists():
qct_qs = Qct.objects.filter(name="默认检验表") qct_qs = Qct.objects.filter(name="默认检验表")
return qct_qs return qct_qs
@ -224,6 +233,8 @@ class QctMat(BaseModel):
material = models.ForeignKey(Material, verbose_name="物料", on_delete=models.CASCADE) material = models.ForeignKey(Material, verbose_name="物料", on_delete=models.CASCADE)
tracing = models.CharField('追溯层级', default=QC_T, choices=QC_TRACE_CHOICES, tracing = models.CharField('追溯层级', default=QC_T, choices=QC_TRACE_CHOICES,
max_length=20, help_text=str(QC_TRACE_CHOICES)) max_length=20, help_text=str(QC_TRACE_CHOICES))
use_for_in = models.BooleanField("可用于消耗", default=True)
use_for_out = models.BooleanField("可用于产出", default=True)
max_defect_rate = models.FloatField('最大不合格率', default=0.5, null=True, blank=True) max_defect_rate = models.FloatField('最大不合格率', default=0.5, null=True, blank=True)

View File

@ -37,6 +37,7 @@ class DefectSerializer(CustomModelSerializer):
class QctGetSerializer(serializers.Serializer): class QctGetSerializer(serializers.Serializer):
material = serializers.CharField(label="物料ID") material = serializers.CharField(label="物料ID")
tag = serializers.CharField(label="标签") tag = serializers.CharField(label="标签")
type = serializers.CharField(label="类型(in/out)", required=False)
class TestItemSerializer(CustomModelSerializer): class TestItemSerializer(CustomModelSerializer):
process_name = serializers.CharField(source="process.name", read_only=True) process_name = serializers.CharField(source="process.name", read_only=True)
@ -53,6 +54,7 @@ class QctSerializer(CustomModelSerializer):
class QctTestItemSerializer(CustomModelSerializer): class QctTestItemSerializer(CustomModelSerializer):
testitem_name = serializers.CharField(source='testitem.name', read_only=True) testitem_name = serializers.CharField(source='testitem.name', read_only=True)
testitem_type = serializers.CharField(source='testitem.type', read_only=True)
testitem_description = serializers.CharField(source='testitem.description', read_only=True) testitem_description = serializers.CharField(source='testitem.description', read_only=True)
testitem_field_type = serializers.CharField(source='testitem.field_type', read_only=True) testitem_field_type = serializers.CharField(source='testitem.field_type', read_only=True)
testitem_choices = serializers.CharField(source='testitem.choices', read_only=True) testitem_choices = serializers.CharField(source='testitem.choices', read_only=True)
@ -61,11 +63,11 @@ class QctTestItemSerializer(CustomModelSerializer):
model = QctTestItem model = QctTestItem
fields = '__all__' fields = '__all__'
def validate(self, attrs): # def validate(self, attrs):
testitem:TestItem = attrs.get("testitem") # testitem:TestItem = attrs.get("testitem")
if testitem.type != TestItem.T_TEST: # if testitem.type != TestItem.T_TEST:
raise ParseError("只可选择检测项") # raise ParseError("只可选择检测项")
return attrs # return attrs
class QctDefectSerializer(CustomModelSerializer): class QctDefectSerializer(CustomModelSerializer):
defect_name = serializers.CharField(source='defect.name', read_only=True) defect_name = serializers.CharField(source='defect.name', read_only=True)

View File

@ -63,7 +63,7 @@ class QctViewSet(CustomModelViewSet):
sr = QctGetSerializer(data=request.data) sr = QctGetSerializer(data=request.data)
sr.is_valid(raise_exception=True) sr.is_valid(raise_exception=True)
vdata = sr.validated_data vdata = sr.validated_data
qct = Qct.get(vdata["material"], vdata["tag"]) qct = Qct.get(vdata["material"], vdata["tag"], vdata.get("tag", None))
return Response(QctDetailSerializer(instance=qct).data) return Response(QctDetailSerializer(instance=qct).data)

View File

@ -678,7 +678,7 @@ class MlogInitSerializer(CustomModelSerializer):
attrs['handle_date'] = localdate(attrs['work_end_time']) attrs['handle_date'] = localdate(attrs['work_end_time'])
# 如果已经确定产出则自动获取qct # 如果已经确定产出则自动获取qct
if attrs.get("material_out", None): if attrs.get("material_out", None):
attrs["qct"] = Qct.get(attrs["material_out"], "process") attrs["qct"] = Qct.get(attrs["material_out"], "process", "out")
return attrs return attrs
class MlogChangeSerializer(CustomModelSerializer): class MlogChangeSerializer(CustomModelSerializer):

View File

@ -623,7 +623,7 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust
"material_out": material_out, "material_out": material_out,
"batch": mlogbin.batch, "batch": mlogbin.batch,
"batch_ofrom": wm_in.batch_ofrom, "material_ofrom": wm_in.material_ofrom, "batch_ofrom": wm_in.batch_ofrom, "material_ofrom": wm_in.material_ofrom,
"qct": Qct.get(material_out, "process") "qct": Qct.get(material_out, "process", "out")
} }
if mtype == Process.PRO_DIV and material_in.tracking == Material.MA_TRACKING_SINGLE: if mtype == Process.PRO_DIV and material_in.tracking == Material.MA_TRACKING_SINGLE:
pass pass