fix: mlogb质检
This commit is contained in:
parent
95b98df8cf
commit
8eddeb4f70
|
@ -0,0 +1,43 @@
|
|||
# Generated by Django 3.2.12 on 2025-01-08 02:16
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('qm', '0033_alter_ftest_test_numer'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='ftest',
|
||||
name='qct',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='qm.qct', verbose_name='所用质检表'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ftestitem',
|
||||
name='test_user',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='操作人'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='FtestDefect',
|
||||
fields=[
|
||||
('id', models.CharField(editable=False, help_text='主键ID', max_length=20, primary_key=True, serialize=False, verbose_name='主键ID')),
|
||||
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
|
||||
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
|
||||
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
|
||||
('has', models.BooleanField(default=False, verbose_name='是否发现')),
|
||||
('defect', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='qm.defect', verbose_name='缺陷')),
|
||||
('ftest', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='qm.ftest', verbose_name='关联检验')),
|
||||
('test_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='操作人')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
]
|
|
@ -240,6 +240,7 @@ class Ftest(CommonBDModel):
|
|||
"""
|
||||
type = models.CharField('检验类型', max_length=20, choices=FTEST_TYPE_CHOICES)
|
||||
test_date = models.DateField('检验日期')
|
||||
qct = models.ForeignKey(Qct, verbose_name='所用质检表', on_delete=models.SET_NULL, null=True, blank=True)
|
||||
test_numer = models.TextField('检测编号', default='')
|
||||
test_group = models.CharField(
|
||||
'检验工序集', max_length=20, default='', blank=True)
|
||||
|
@ -256,6 +257,10 @@ class Ftest(CommonBDModel):
|
|||
def ftestitems(self):
|
||||
return FtestItem.objects.filter(ftest=self)
|
||||
|
||||
@property
|
||||
def ftestdefects(self):
|
||||
return FtestDefect.objects.filter(ftest=self)
|
||||
|
||||
|
||||
class FtestItem(BaseModel):
|
||||
"""
|
||||
|
@ -265,12 +270,24 @@ class FtestItem(BaseModel):
|
|||
Ftest, verbose_name='关联检验', on_delete=models.CASCADE)
|
||||
testitem = models.ForeignKey(
|
||||
TestItem, verbose_name='质检项目', on_delete=models.CASCADE)
|
||||
test_user = models.ForeignKey(User, verbose_name='操作人', on_delete=models.CASCADE, null=True, blank=True)
|
||||
test_val = models.FloatField('测量值', null=True, blank=True)
|
||||
check_val = models.FloatField('专检测量值', null=True, blank=True)
|
||||
test_val_json = models.JSONField('测量值', null=True, blank=True)
|
||||
check_val_json = models.JSONField('专检测量值', null=True, blank=True)
|
||||
|
||||
|
||||
class FtestDefect(BaseModel):
|
||||
"""
|
||||
缺陷明细
|
||||
"""
|
||||
ftest = models.ForeignKey(
|
||||
Ftest, verbose_name='关联检验', on_delete=models.CASCADE)
|
||||
test_user = models.ForeignKey(User, verbose_name='操作人', on_delete=models.CASCADE, null=True, blank=True)
|
||||
defect = models.ForeignKey(Defect, verbose_name='缺陷', on_delete=models.CASCADE)
|
||||
has = models.BooleanField('是否发现', default=False)
|
||||
|
||||
|
||||
class Ptest(CommonAModel):
|
||||
"""
|
||||
性能测试记录
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from apps.qm.models import (QuaStat, TestItem, Ftest, FtestItem, FtestWork, Ptest,
|
||||
NotOkOption, Defect, Qct, QctTestItem, QctMat, QctDefect)
|
||||
NotOkOption, Defect, Qct, QctTestItem, QctMat,
|
||||
QctDefect, FtestDefect, FTEST_TYPE_CHOICES)
|
||||
from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE
|
||||
from apps.utils.serializers import CustomModelSerializer
|
||||
from rest_framework import serializers
|
||||
|
@ -241,3 +242,80 @@ class PtestSerializer(CustomModelSerializer):
|
|||
if Ptest.objects.filter(sample_number=validated_data['sample_number']).exists():
|
||||
raise serializers.ValidationError('该样品编号已存在')
|
||||
return super().create(validated_data)
|
||||
|
||||
|
||||
class FtestDefectSerializer(CustomModelSerializer):
|
||||
defect_name = serializers.CharField(source='defect.name', read_only=True)
|
||||
class Meta:
|
||||
model = FtestDefect
|
||||
fields = '__all__'
|
||||
read_only_fields = EXCLUDE_FIELDS_BASE + ['ftest']
|
||||
|
||||
|
||||
class FtestItemProcessSerializer(CustomModelSerializer):
|
||||
testitem_name = serializers.CharField(
|
||||
source='testitem.name', read_only=True)
|
||||
testitem_description = serializers.CharField(
|
||||
source='testitem.description', read_only=True)
|
||||
class Meta:
|
||||
model = FtestItem
|
||||
fields = ["id", "testitem", "test_user", "test_val_json", "testitem_name", "testitem_description"]
|
||||
|
||||
class FtestProcessSerializer(CustomModelSerializer):
|
||||
test_user_name = serializers.CharField(
|
||||
source='test_user.name', read_only=True)
|
||||
ftestitems = FtestItemProcessSerializer(label='检验明细', many=True)
|
||||
ftestdefects = FtestDefectSerializer(label='缺陷明细', many=True)
|
||||
|
||||
class Meta:
|
||||
model = Ftest
|
||||
fields = ["id", "test_date",
|
||||
"test_user", "note", "ftestitems", "ftestdefects", "qct", "test_user_name"]
|
||||
extra_kwargs = {"qct": {"required": True}}
|
||||
|
||||
def validate(self, attrs):
|
||||
attrs["type"] = "process"
|
||||
return attrs
|
||||
|
||||
def create(self, validated_data):
|
||||
ftestitems = validated_data.pop('ftestitems', [])
|
||||
ftestdefects = validated_data.pop('ftestdefects', [])
|
||||
with transaction.atomic():
|
||||
instance = super().create(validated_data)
|
||||
for item in ftestitems:
|
||||
FtestItem.objects.create(ftest=instance, **item)
|
||||
is_ok = True
|
||||
for item2 in ftestdefects:
|
||||
defect:Defect = item["defect"]
|
||||
if defect.okcate in [Defect.DEFECT_NOTOK] and item["has"]:
|
||||
is_ok = False
|
||||
FtestDefect.objects.create(ftest=instance, **item2)
|
||||
instance.is_ok = is_ok
|
||||
instance.save()
|
||||
return instance
|
||||
|
||||
def update(self, instance, validated_data):
|
||||
ftestitems = validated_data.pop('ftestitems', [])
|
||||
ftestdefects = validated_data.pop('ftestdefects', [])
|
||||
with transaction.atomic():
|
||||
instance = super().update(instance, validated_data)
|
||||
for item in ftestitems:
|
||||
if "id" in item and item["id"]:
|
||||
FtestItem.objects.filter(id=item["id"]).update(
|
||||
test_user = item["test_user"],
|
||||
test_val_json = item["test_val_json"])
|
||||
else:
|
||||
FtestItem.objects.create(ftest=instance, **item)
|
||||
is_ok = True
|
||||
for item2 in ftestdefects:
|
||||
if "id" in item2 and item2["id"]:
|
||||
ins: FtestDefect = FtestDefect.objects.get(id=item2["id"])
|
||||
else:
|
||||
ins = FtestDefect.objects.create(ftest=instance, **item2)
|
||||
ins.has = item2["has"]
|
||||
ins.save()
|
||||
if ins.has and ins.defect.okcate in [Defect.DEFECT_NOTOK]:
|
||||
is_ok = False
|
||||
instance.is_ok = is_ok
|
||||
instance.save()
|
||||
return instance
|
|
@ -0,0 +1,20 @@
|
|||
# Generated by Django 3.2.12 on 2025-01-08 02:16
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('qm', '0034_auto_20250108_1016'),
|
||||
('wpm', '0082_mlogb_qct'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='mlogbw',
|
||||
name='ftest',
|
||||
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='qm.ftest', verbose_name='关联检验'),
|
||||
),
|
||||
]
|
|
@ -354,6 +354,7 @@ class Mlogbw(BaseModel):
|
|||
mlogb = models.ForeignKey(Mlogb, verbose_name='生产记录', on_delete=models.CASCADE)
|
||||
wpr = models.ForeignKey("wpmw.wpr", verbose_name='关联产品', on_delete=models.SET_NULL
|
||||
, related_name='wpr_mlogbw', null=True, blank=True)
|
||||
ftest = models.OneToOneField("qm.ftest", verbose_name='关联检验', on_delete=models.PROTECT, null=True, blank=True)
|
||||
note = models.TextField('备注', null=True, blank=True)
|
||||
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ from django.utils.timezone import localdate
|
|||
from apps.qm.models import NotOkOption
|
||||
from apps.wf.serializers import TicketSimpleSerializer
|
||||
from apps.wpmw.models import Wpr
|
||||
from apps.qm.serializers import FtestProcessSerializer
|
||||
import logging
|
||||
mylogger = logging.getLogger("log")
|
||||
|
||||
|
@ -572,9 +573,10 @@ class MlogbInUpdateSerializer(CustomModelSerializer):
|
|||
fields = ['id', 'count_use', 'count_break', 'count_pn_jgqbl', 'note']
|
||||
|
||||
class MlogbwCreateUpdateSerializer(CustomModelSerializer):
|
||||
ftest = FtestProcessSerializer(required=False)
|
||||
class Meta:
|
||||
model = Mlogbw
|
||||
fields = ["id", "number", "wpr", "note", "mlogb"]
|
||||
fields = ["id", "number", "wpr", "note", "mlogb", "ftest"]
|
||||
|
||||
def validate(self, attrs):
|
||||
mlogb:Mlogb = attrs["mlogb"]
|
||||
|
@ -588,8 +590,7 @@ class MlogbwCreateUpdateSerializer(CustomModelSerializer):
|
|||
|
||||
def update(self, instance, validated_data):
|
||||
validated_data.pop("mlogb")
|
||||
return super().update(instance, validated_data)
|
||||
|
||||
super().update(instance, validated_data)
|
||||
|
||||
class MlogbOutUpdateSerializer(CustomModelSerializer):
|
||||
class Meta:
|
||||
|
|
|
@ -521,8 +521,10 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust
|
|||
d_count_ok = xcount
|
||||
# 找寻质检表
|
||||
qctmat = QctMat.objects.filter(material=material_out).order_by("-create_time").first()
|
||||
qct = None
|
||||
if qctmat:
|
||||
mlogbout.qct = qctmat.qct
|
||||
qct = qctmat.qct
|
||||
mlogbout.qct = qct
|
||||
mlogbout.count_real = d_count_real
|
||||
mlogbout.count_ok = d_count_ok
|
||||
mlogbout.save()
|
||||
|
@ -614,11 +616,13 @@ class MlogbwViewSet(CustomModelViewSet):
|
|||
self.cal_mlogb_count(mlogb_to)
|
||||
|
||||
@transaction.atomic
|
||||
def perform_destroy(self, instance):
|
||||
def perform_destroy(self, instance:Mlogbw):
|
||||
mlogb = instance.mlogb
|
||||
if mlogb.mlog.submit_time is not None:
|
||||
raise ParseError('日志已提交不可修改')
|
||||
instance.delete()
|
||||
if instance.ftest:
|
||||
instance.ftest.delete()
|
||||
self.cal_mlogb_count(mlogb)
|
||||
# 如果是输入且输出追踪到个,需同步创建
|
||||
material_in: Material = mlogb.material_in
|
||||
|
|
Loading…
Reference in New Issue