fix: mlogb质检

This commit is contained in:
caoqianming 2025-01-08 10:29:12 +08:00
parent 95b98df8cf
commit 8eddeb4f70
7 changed files with 170 additions and 6 deletions

View File

@ -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,
},
),
]

View File

@ -240,6 +240,7 @@ class Ftest(CommonBDModel):
""" """
type = models.CharField('检验类型', max_length=20, choices=FTEST_TYPE_CHOICES) type = models.CharField('检验类型', max_length=20, choices=FTEST_TYPE_CHOICES)
test_date = models.DateField('检验日期') 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_numer = models.TextField('检测编号', default='')
test_group = models.CharField( test_group = models.CharField(
'检验工序集', max_length=20, default='', blank=True) '检验工序集', max_length=20, default='', blank=True)
@ -256,6 +257,10 @@ class Ftest(CommonBDModel):
def ftestitems(self): def ftestitems(self):
return FtestItem.objects.filter(ftest=self) return FtestItem.objects.filter(ftest=self)
@property
def ftestdefects(self):
return FtestDefect.objects.filter(ftest=self)
class FtestItem(BaseModel): class FtestItem(BaseModel):
""" """
@ -265,12 +270,24 @@ class FtestItem(BaseModel):
Ftest, verbose_name='关联检验', on_delete=models.CASCADE) Ftest, verbose_name='关联检验', on_delete=models.CASCADE)
testitem = models.ForeignKey( testitem = models.ForeignKey(
TestItem, verbose_name='质检项目', on_delete=models.CASCADE) 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) test_val = models.FloatField('测量值', null=True, blank=True)
check_val = models.FloatField('专检测量值', null=True, blank=True) check_val = models.FloatField('专检测量值', null=True, blank=True)
test_val_json = models.JSONField('测量值', null=True, blank=True) test_val_json = models.JSONField('测量值', null=True, blank=True)
check_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): class Ptest(CommonAModel):
""" """
性能测试记录 性能测试记录

View File

@ -1,5 +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, QctDefect) NotOkOption, Defect, Qct, QctTestItem, QctMat,
QctDefect, FtestDefect, FTEST_TYPE_CHOICES)
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
@ -241,3 +242,80 @@ class PtestSerializer(CustomModelSerializer):
if Ptest.objects.filter(sample_number=validated_data['sample_number']).exists(): if Ptest.objects.filter(sample_number=validated_data['sample_number']).exists():
raise serializers.ValidationError('该样品编号已存在') raise serializers.ValidationError('该样品编号已存在')
return super().create(validated_data) 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

View File

@ -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='关联检验'),
),
]

View File

@ -354,6 +354,7 @@ class Mlogbw(BaseModel):
mlogb = models.ForeignKey(Mlogb, verbose_name='生产记录', on_delete=models.CASCADE) mlogb = models.ForeignKey(Mlogb, verbose_name='生产记录', on_delete=models.CASCADE)
wpr = models.ForeignKey("wpmw.wpr", verbose_name='关联产品', on_delete=models.SET_NULL wpr = models.ForeignKey("wpmw.wpr", verbose_name='关联产品', on_delete=models.SET_NULL
, related_name='wpr_mlogbw', null=True, blank=True) , 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) note = models.TextField('备注', null=True, blank=True)

View File

@ -21,6 +21,7 @@ from django.utils.timezone import localdate
from apps.qm.models import NotOkOption from apps.qm.models import NotOkOption
from apps.wf.serializers import TicketSimpleSerializer from apps.wf.serializers import TicketSimpleSerializer
from apps.wpmw.models import Wpr from apps.wpmw.models import Wpr
from apps.qm.serializers import FtestProcessSerializer
import logging import logging
mylogger = logging.getLogger("log") mylogger = logging.getLogger("log")
@ -572,9 +573,10 @@ class MlogbInUpdateSerializer(CustomModelSerializer):
fields = ['id', 'count_use', 'count_break', 'count_pn_jgqbl', 'note'] fields = ['id', 'count_use', 'count_break', 'count_pn_jgqbl', 'note']
class MlogbwCreateUpdateSerializer(CustomModelSerializer): class MlogbwCreateUpdateSerializer(CustomModelSerializer):
ftest = FtestProcessSerializer(required=False)
class Meta: class Meta:
model = Mlogbw model = Mlogbw
fields = ["id", "number", "wpr", "note", "mlogb"] fields = ["id", "number", "wpr", "note", "mlogb", "ftest"]
def validate(self, attrs): def validate(self, attrs):
mlogb:Mlogb = attrs["mlogb"] mlogb:Mlogb = attrs["mlogb"]
@ -588,8 +590,7 @@ class MlogbwCreateUpdateSerializer(CustomModelSerializer):
def update(self, instance, validated_data): def update(self, instance, validated_data):
validated_data.pop("mlogb") validated_data.pop("mlogb")
return super().update(instance, validated_data) super().update(instance, validated_data)
class MlogbOutUpdateSerializer(CustomModelSerializer): class MlogbOutUpdateSerializer(CustomModelSerializer):
class Meta: class Meta:

View File

@ -521,8 +521,10 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust
d_count_ok = xcount d_count_ok = xcount
# 找寻质检表 # 找寻质检表
qctmat = QctMat.objects.filter(material=material_out).order_by("-create_time").first() qctmat = QctMat.objects.filter(material=material_out).order_by("-create_time").first()
qct = None
if qctmat: if qctmat:
mlogbout.qct = qctmat.qct qct = qctmat.qct
mlogbout.qct = qct
mlogbout.count_real = d_count_real mlogbout.count_real = d_count_real
mlogbout.count_ok = d_count_ok mlogbout.count_ok = d_count_ok
mlogbout.save() mlogbout.save()
@ -614,11 +616,13 @@ class MlogbwViewSet(CustomModelViewSet):
self.cal_mlogb_count(mlogb_to) self.cal_mlogb_count(mlogb_to)
@transaction.atomic @transaction.atomic
def perform_destroy(self, instance): def perform_destroy(self, instance:Mlogbw):
mlogb = instance.mlogb mlogb = instance.mlogb
if mlogb.mlog.submit_time is not None: if mlogb.mlog.submit_time is not None:
raise ParseError('日志已提交不可修改') raise ParseError('日志已提交不可修改')
instance.delete() instance.delete()
if instance.ftest:
instance.ftest.delete()
self.cal_mlogb_count(mlogb) self.cal_mlogb_count(mlogb)
# 如果是输入且输出追踪到个,需同步创建 # 如果是输入且输出追踪到个,需同步创建
material_in: Material = mlogb.material_in material_in: Material = mlogb.material_in