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

View File

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