feat: ftestwork支持ftestworkdefect

This commit is contained in:
caoqianming 2025-01-13 09:39:18 +08:00
parent 58b3863763
commit 942e54a7e4
2 changed files with 77 additions and 28 deletions

View File

@ -6,6 +6,8 @@ from apps.em.models import Equipment
from apps.wpm.models import SfLog, WMaterial
from django.utils.translation import gettext_lazy as _
from django.db import transaction
from django.db.models import Sum
from rest_framework.exceptions import ParseError
class Defect(CommonAModel):
# 缺陷项
@ -226,6 +228,7 @@ class FtestWork(CommonBDModel):
ticket = models.ForeignKey('wf.ticket', verbose_name='关联工单',
on_delete=models.SET_NULL, related_name='ftestwork_ticket', null=True, blank=True,
db_constraint=False)
qct = models.ForeignKey(Qct, verbose_name='关联质检表', on_delete=models.SET_NULL, null=True, blank=True)
@classmethod
def count_fields(cls):
@ -235,19 +238,26 @@ class FtestWork(CommonBDModel):
ftestwork_count_fields.append(f.name)
return ftestwork_count_fields
# def cal_count(self):
# self.count_notok = FtestworkDefect.objects.filter(
# mlogb=self, defect__okcate=30).aggregate(total=Sum("count"))["total"] or 0
# self.count_ok = self.count_real - self.count_notok
# if self.count_ok < 0:
# raise ParseError('合格数量不能小于0')
# self.save(update_fields=['count_ok', 'count_notok'])
def cal_count(self):
self.count_notok = FtestworkDefect.objects.filter(
mlogb=self, defect__okcate=30).aggregate(total=Sum("count"))["total"] or 0
self.count_ok = self.count - self.count_notok
if self.type2 == 20: #全检
self.count_sampling = self.count
self.count_sampling_ok = self.count_ok
if self.count_ok < 0:
raise ParseError('合格数量不能小于0')
self.save(update_fields=['count_ok', 'count_notok'])
# class FtestworkDefect(BaseModel):
# ftestwork = models.ForeignKey(FtestWork, verbose_name='关联检验工作', on_delete=models.CASCADE,
# related_name='ftestwork_defect')
# defect = models.ForeignKey(Defect, verbose_name='缺陷', on_delete=models.CASCADE)
# count = models.PositiveIntegerField('数量', default=0)
@property
def ftestworkdefect(self):
return FtestworkDefect.objects.filter(ftestwork=self)
class FtestworkDefect(BaseModel):
ftestwork = models.ForeignKey(FtestWork, verbose_name='关联检验工作', on_delete=models.CASCADE,
related_name='ftestwork_defect')
defect = models.ForeignKey(Defect, verbose_name='缺陷', on_delete=models.CASCADE)
count = models.PositiveIntegerField('数量', default=0)
class Ftest(CommonBDModel):
"""

View File

@ -1,6 +1,6 @@
from apps.qm.models import (QuaStat, TestItem, Ftest, FtestItem, FtestWork, Ptest,
NotOkOption, Defect, Qct, QctTestItem, QctMat,
QctDefect, FtestDefect, FTEST_TYPE_CHOICES)
QctDefect, FtestDefect, FtestworkDefect)
from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE
from apps.utils.serializers import CustomModelSerializer
from rest_framework import serializers
@ -8,6 +8,7 @@ from rest_framework.exceptions import ValidationError, ParseError
from apps.wpm.models import SfLog, WMaterial
from django.db import transaction
from apps.inm.serializers import MaterialBatchDetailSerializer
from apps.mtm.models import Material
class DefectSerializer(CustomModelSerializer):
class Meta:
@ -114,52 +115,90 @@ class QuaStatUpdateSerializer(CustomModelSerializer):
return super().validate(attrs)
class FtestworkdefectSerializer(CustomModelSerializer):
defect_name = serializers.CharField(source="defect.name", read_only=True)
class Meta:
model = FtestworkDefect
fields = "__all__"
read_only_fields = EXCLUDE_FIELDS_BASE + ["ftestwork"]
class FtestWorkCreateUpdateSerializer(CustomModelSerializer):
ftestworkdefect = FtestworkdefectSerializer(many=True)
class Meta:
model = FtestWork
fields = ['id', 'shift', 'wm', 'mb',
'type', 'type2', 'test_date', 'count', 'count_sampling',
'count_sampling_ok', 'count_ok', 'count_notok',
'count_notok_json', 'test_user', 'need_update_wm',
'equipment', 'note']
'equipment', 'note', "qct", "ftestworkdefect"]
extra_kwargs = {'test_user': {'required': True}, 'type': {'required': True}}
def validate(self, attrs):
qct = attrs.get("qct", None)
type2 = attrs.get('type2', 20)
if type2 == 20: # 如果是全检
attrs['count_sampling'] = attrs['count']
if 'wm' in attrs and attrs['wm']:
attrs['mb'] = None
wm:WMaterial = attrs['wm']
if wm.material.tracking != Material.MA_TRACKING_BATCH:
raise ParseError('只支持追踪批次的物料检验')
if wm.state not in [WMaterial.WM_OK, WMaterial.WM_TEST]:
raise ValidationError('不支持对该物料检验')
attrs['material'] = wm.material
attrs['batch'] = wm.batch
count_notok_json = attrs.get('count_notok_json', None)
if count_notok_json is None:
raise ValidationError('不合格项不能为空')
count_notok = 0
for k, v in count_notok_json.items():
k_2 = k.replace('count_n_', '')
if k_2 not in NotOkOption.values:
raise ValidationError(f'不支持的不合格项{k_2}')
if isinstance(v, int) and v >= 0:
count_notok = count_notok + v
else:
raise ValidationError(f'不合格项{k_2}必须为非负整数')
attrs['count_notok'] = count_notok
if type2 == 20 and attrs['count'] != attrs['count_ok'] + attrs['count_notok']:
raise ValidationError('全检时总数必须等于合格数+不合格数')
if qct is None: # 没有qct时按原有逻辑处理
if count_notok_json is None:
raise ValidationError('不合格项不能为空')
count_notok = 0
for k, v in count_notok_json.items():
k_2 = k.replace('count_n_', '')
if k_2 not in NotOkOption.values:
raise ValidationError(f'不支持的不合格项{k_2}')
if isinstance(v, int) and v >= 0:
count_notok = count_notok + v
else:
raise ValidationError(f'不合格项{k_2}必须为非负整数')
attrs['count_notok'] = count_notok
if type2 == 20 and attrs['count'] != attrs['count_ok'] + attrs['count_notok']:
raise ValidationError('全检时总数必须等于合格数+不合格数')
elif 'mb' in attrs and attrs['mb']:
attrs['wm'] = None
attrs['material'] = attrs['mb'].material
attrs['batch'] = attrs['mb'].batch
if attrs['material'].tracking != Material.MA_TRACKING_BATCH:
raise ParseError('只支持追踪批次的物料检验')
else:
raise ValidationError('请选择车间/仓库库存')
if attrs['test_user']:
attrs['belong_dept'] = attrs['test_user'].belong_dept
return attrs
def create(self, validated_data):
ftestworkdefect = validated_data.pop("ftestworkdefect", [])
with transaction.atomic():
ins: FtestWork = super().create(validated_data)
for ftestworkdefect in ftestworkdefect:
FtestworkDefect.objects.create(ftest=ins, **ftestworkdefect)
if ftestworkdefect:
ins.cal_count()
def update(self, instance, validated_data):
ftestworkdefect = validated_data.pop("ftestworkdefect", [])
ins = super().update(instance, validated_data)
with transaction.atomic():
for item in ftestworkdefect:
try:
ins = FtestworkDefect.objects.get(ftestwork=ins, defect=item["defect"])
except FtestworkDefect.DoesNotExist:
raise ParseError("新的缺陷项!")
ins.count = item["count"]
ins.save()
if ftestworkdefect:
ins.cal_count()
return ins
class FtestWorkSerializer(CustomModelSerializer):
material_name = serializers.StringRelatedField(