feat: 添加mlogbdefect
This commit is contained in:
parent
d69d4568f6
commit
b2f801deda
|
@ -0,0 +1,31 @@
|
||||||
|
# Generated by Django 3.2.12 on 2025-02-28 01:11
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import django.utils.timezone
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('qm', '0044_testitem_cd_expr'),
|
||||||
|
('wpm', '0088_auto_20250224_0938'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='MlogbDefect',
|
||||||
|
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='删除标记')),
|
||||||
|
('count', models.PositiveIntegerField(default=0, verbose_name='数量')),
|
||||||
|
('defect', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='qm.defect', verbose_name='缺陷')),
|
||||||
|
('mlogb', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='wpm.mlogb', verbose_name='生产记录')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -357,6 +357,16 @@ class Mlogb(BaseModel):
|
||||||
return "in", self.material_in.tracking
|
return "in", self.material_in.tracking
|
||||||
elif self.material_out:
|
elif self.material_out:
|
||||||
return "out", self.material_out.tracking
|
return "out", self.material_out.tracking
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mlogbdefect(self):
|
||||||
|
return MlogbDefect.objects.filter(mlogb=self)
|
||||||
|
|
||||||
|
|
||||||
|
class MlogbDefect(BaseModel):
|
||||||
|
mlogb = models.ForeignKey(Mlogb, verbose_name='生产记录', on_delete=models.CASCADE)
|
||||||
|
defect = models.ForeignKey("qm.Defect", verbose_name='缺陷', on_delete=models.CASCADE)
|
||||||
|
count = models.PositiveIntegerField('数量', default=0)
|
||||||
|
|
||||||
class Mlogbw(BaseModel):
|
class Mlogbw(BaseModel):
|
||||||
"""TN: 单个产品生产/检验日志
|
"""TN: 单个产品生产/检验日志
|
||||||
|
|
|
@ -6,7 +6,7 @@ from datetime import datetime
|
||||||
|
|
||||||
from .models import (SfLog, StLog, SfLogExp, WMaterial, Mlog,
|
from .models import (SfLog, StLog, SfLogExp, WMaterial, Mlog,
|
||||||
Handover, Handoverb, Mlogb, AttLog,
|
Handover, Handoverb, Mlogb, AttLog,
|
||||||
OtherLog, Fmlog, BatchSt, Mlogbw, Handoverbw)
|
OtherLog, Fmlog, BatchSt, Mlogbw, Handoverbw, MlogbDefect)
|
||||||
from apps.system.models import Dept, User
|
from apps.system.models import Dept, User
|
||||||
from apps.system.serializers import UserSimpleSerializer
|
from apps.system.serializers import UserSimpleSerializer
|
||||||
from apps.pm.models import Mtask, Mtaskb
|
from apps.pm.models import Mtask, Mtaskb
|
||||||
|
@ -23,6 +23,7 @@ from apps.wf.serializers import TicketSimpleSerializer
|
||||||
from apps.wpmw.models import Wpr
|
from apps.wpmw.models import Wpr
|
||||||
from apps.qm.serializers import FtestProcessSerializer
|
from apps.qm.serializers import FtestProcessSerializer
|
||||||
import logging
|
import logging
|
||||||
|
from apps.qm.models import Defect
|
||||||
mylogger = logging.getLogger("log")
|
mylogger = logging.getLogger("log")
|
||||||
|
|
||||||
class OtherLogSerializer(CustomModelSerializer):
|
class OtherLogSerializer(CustomModelSerializer):
|
||||||
|
@ -687,42 +688,99 @@ class MlogbwCreateUpdateSerializer(CustomModelSerializer):
|
||||||
mlogbw = self.save_ftest(mlogbw, ftest_data)
|
mlogbw = self.save_ftest(mlogbw, ftest_data)
|
||||||
return mlogbw
|
return mlogbw
|
||||||
|
|
||||||
|
class MlogbDefectSerializer(CustomModelSerializer):
|
||||||
|
defect_name = serializers.CharField(source="defect.name", read_only=True)
|
||||||
|
class Meta:
|
||||||
|
model = Mlogb
|
||||||
|
fields = ["id", "defect_name", "count", "mlogb", "defect"]
|
||||||
|
|
||||||
class MlogbOutUpdateSerializer(CustomModelSerializer):
|
class MlogbOutUpdateSerializer(CustomModelSerializer):
|
||||||
|
mlogbdefect = MlogbDefectSerializer(many=True, required=False)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Mlogb
|
model = Mlogb
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
read_only_fields = EXCLUDE_FIELDS_BASE + ['mlog', 'mtask', 'wm_in', 'material_in', 'material_out',
|
read_only_fields = EXCLUDE_FIELDS_BASE + ['mlog', 'mtask', 'wm_in', 'material_in', 'material_out',
|
||||||
'count_use', 'count_break', 'count_pn_jgqbl']
|
'count_use', 'count_break', 'count_pn_jgqbl', 'mlogbdefect']
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
material_out:Material = validated_data["material_out"]
|
||||||
|
mlogbdefect = validated_data.pop("mlogbdefect", [])
|
||||||
|
with transaction.atomic():
|
||||||
|
ins = super().create(validated_data)
|
||||||
|
if mlogbdefect and material_out.tracking == Material.MA_TRACKING_BATCH:
|
||||||
|
count_notok = 0
|
||||||
|
mlogbdefect_new = [item for item in mlogbdefect if item["count"] > 0]
|
||||||
|
for item in mlogbdefect_new:
|
||||||
|
defect:Defect = item["defect"]
|
||||||
|
Mlogb.objects.create(mlogb=ins, defect=defect, count=item["count"])
|
||||||
|
if defect.cate == Defect.DEFECT_NOTOK:
|
||||||
|
count_notok +=1
|
||||||
|
ins.count_notok = count_notok
|
||||||
|
ins.count_ok = ins.count_real - ins.count_notok
|
||||||
|
ins.save()
|
||||||
|
else:
|
||||||
|
raise ParseError("mlogbdefect仅支持批次件")
|
||||||
|
return ins
|
||||||
|
|
||||||
|
def update(self, instance, validated_data):
|
||||||
|
material_out:Material = validated_data["material_out"]
|
||||||
|
mlogbdefect = validated_data.pop("mlogbdefect", [])
|
||||||
|
with transaction.atomic():
|
||||||
|
ins:Mlogb = super().update(instance, validated_data)
|
||||||
|
if mlogbdefect and material_out.tracking == Material.MA_TRACKING_BATCH:
|
||||||
|
defectIds = [item["defect"].id for item in mlogbdefect if item["count"] > 0]
|
||||||
|
Mlogb.objects.filter(mlogb=ins).exclude(defect_id__in=defectIds).delete()
|
||||||
|
count_notok = 0
|
||||||
|
for item in mlogbdefect:
|
||||||
|
defect = item["defect"]
|
||||||
|
insb = MlogbDefect.objects.get(mlogb=ins, defect=defect)
|
||||||
|
insb.count = item["count"]
|
||||||
|
insb.save(update_fields=["count"])
|
||||||
|
if defect.cate == Defect.DEFECT_NOTOK:
|
||||||
|
count_notok +=1
|
||||||
|
ins.count_notok = count_notok
|
||||||
|
ins.count_ok = ins.count_real
|
||||||
|
ins.save()
|
||||||
|
return ins
|
||||||
|
|
||||||
def validate(self, attrs):
|
def validate(self, attrs):
|
||||||
count_notok_json = attrs.get('count_notok_json', [])
|
mlogbdefect = attrs.get("mlogbdefect", [])
|
||||||
# count_notok_json字段处理
|
if mlogbdefect:
|
||||||
if count_notok_json:
|
pass
|
||||||
# 先置0字段
|
# attrs.pop("count_notok_json")
|
||||||
|
# for i in attrs:
|
||||||
|
# if 'count_n_' in i:
|
||||||
|
# attrs.pop(i, None)
|
||||||
|
else:
|
||||||
|
count_notok_json = attrs.get('count_notok_json', [])
|
||||||
|
# count_notok_json字段处理
|
||||||
|
if count_notok_json:
|
||||||
|
# 先置0字段
|
||||||
|
for i in attrs:
|
||||||
|
if 'count_n_' in i:
|
||||||
|
i = 0
|
||||||
|
count_notok_dict = {}
|
||||||
|
for item in count_notok_json:
|
||||||
|
notok = item['notok']
|
||||||
|
count = item['count']
|
||||||
|
full_notok = f'count_n_{notok}'
|
||||||
|
if not hasattr(Mlogb, full_notok):
|
||||||
|
raise ParseError(f'{notok}-该不合格项不存在')
|
||||||
|
if full_notok in count_notok_dict:
|
||||||
|
count_notok_dict[full_notok] = count_notok_dict[full_notok] + count
|
||||||
|
else:
|
||||||
|
count_notok_dict[full_notok] = count
|
||||||
|
for k, v in count_notok_dict.items():
|
||||||
|
attrs[k] = v
|
||||||
|
|
||||||
|
count_notok = 0
|
||||||
for i in attrs:
|
for i in attrs:
|
||||||
if 'count_n_' in i:
|
if 'count_n_' in i:
|
||||||
i = 0
|
if not hasattr(Mlogb, i):
|
||||||
count_notok_dict = {}
|
raise ParseError(f'{i}不存在')
|
||||||
for item in count_notok_json:
|
count_notok = count_notok + attrs[i]
|
||||||
notok = item['notok']
|
attrs['count_notok'] = count_notok
|
||||||
count = item['count']
|
|
||||||
full_notok = f'count_n_{notok}'
|
|
||||||
if not hasattr(Mlogb, full_notok):
|
|
||||||
raise ParseError(f'{notok}-该不合格项不存在')
|
|
||||||
if full_notok in count_notok_dict:
|
|
||||||
count_notok_dict[full_notok] = count_notok_dict[full_notok] + count
|
|
||||||
else:
|
|
||||||
count_notok_dict[full_notok] = count
|
|
||||||
for k, v in count_notok_dict.items():
|
|
||||||
attrs[k] = v
|
|
||||||
|
|
||||||
count_notok = 0
|
|
||||||
for i in attrs:
|
|
||||||
if 'count_n_' in i:
|
|
||||||
if not hasattr(Mlogb, i):
|
|
||||||
raise ParseError(f'{i}不存在')
|
|
||||||
count_notok = count_notok + attrs[i]
|
|
||||||
attrs['count_notok'] = count_notok
|
|
||||||
if attrs['count_real'] >= attrs['count_ok'] + attrs['count_notok']:
|
if attrs['count_real'] >= attrs['count_ok'] + attrs['count_notok']:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -170,6 +170,7 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]):
|
||||||
for mi in m_ins.all():
|
for mi in m_ins.all():
|
||||||
m_ins_list.append((mi.material_in, mi.batch, mi.count_use, mi))
|
m_ins_list.append((mi.material_in, mi.batch, mi.count_use, mi))
|
||||||
if mi.count_pn_jgqbl > 0:
|
if mi.count_pn_jgqbl > 0:
|
||||||
|
raise ParseError("暂不支持加工前不良")
|
||||||
m_ins_bl_list.append((mi.material_in, mi.batch, mi.count_pn_jgqbl, mi))
|
m_ins_bl_list.append((mi.material_in, mi.batch, mi.count_pn_jgqbl, mi))
|
||||||
else:
|
else:
|
||||||
m_ins_list = [(material_in, mlog.batch, mlog.count_use, mlog)]
|
m_ins_list = [(material_in, mlog.batch, mlog.count_use, mlog)]
|
||||||
|
@ -446,6 +447,7 @@ def mlog_revert(mlog: Mlog, user: User, now: Union[datetime.datetime, None]):
|
||||||
for mi in m_ins.all():
|
for mi in m_ins.all():
|
||||||
m_ins_list.append((mi.material_in, mi.batch, mi.count_use, mi.wm_in, mi))
|
m_ins_list.append((mi.material_in, mi.batch, mi.count_use, mi.wm_in, mi))
|
||||||
if mi.count_pn_jgqbl > 0:
|
if mi.count_pn_jgqbl > 0:
|
||||||
|
raise ParseError("暂不支持加工前不良")
|
||||||
m_ins_bl_list.append((mi.material_in, mi.batch, mi.count_pn_jgqbl, mi))
|
m_ins_bl_list.append((mi.material_in, mi.batch, mi.count_pn_jgqbl, mi))
|
||||||
else:
|
else:
|
||||||
m_ins_list = [(material_in, mlog.batch, mlog.count_use, mlog.wm_in, mlog)]
|
m_ins_list = [(material_in, mlog.batch, mlog.count_use, mlog.wm_in, mlog)]
|
||||||
|
|
Loading…
Reference in New Issue