feat: ftestwork支持ftestworkdefect
This commit is contained in:
parent
58b3863763
commit
942e54a7e4
|
@ -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):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -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(
|
||||||
|
|
Loading…
Reference in New Issue