feat: 批次处理做兼容性处理

This commit is contained in:
caoqianming 2025-02-28 15:31:38 +08:00
parent 77f7a454a1
commit 286a5306e3
5 changed files with 89 additions and 73 deletions

View File

@ -151,7 +151,7 @@ QC_TRACE_CHOICES = (
class Qct(CommonAModel):
name = models.CharField(max_length=50, verbose_name="名称")
number = models.CharField(max_length=20, verbose_name="编号")
tags = models.JSONField('检测类型', default=list, blank=True)
tags = models.JSONField('检测类型', default=list, blank=True) # process 和 inm
testitems = models.ManyToManyField(TestItem, verbose_name="检测项", blank=True, through='qm.qcttestitem')
defects = models.ManyToManyField(Defect, verbose_name="缺陷项", blank=True, through='qm.qctdefect')
materials = models.ManyToManyField(Material, verbose_name="物料", blank=True, through='qm.qctmat')

View File

@ -382,6 +382,26 @@ class Mlogbw(BaseModel):
on_delete=models.PROTECT, null=True, blank=True, related_name="mlogbw_ftest")
note = models.TextField('备注', null=True, blank=True)
@classmethod
def cal_count_notok(mlogb: Mlog):
count = Mlogbw.objects.filter(mlogb=mlogb).count()
if mlogb.material_in:
mlogb.count_use = count
elif mlogb.material_out:
mlogb.count_real = count
count_notok = 0
tqs = Mlogbw.objects.filter(mlogb=mlogb, ftest__is_ok=False).values("defect_main").annotate(xcount=Count('id'))
md_ids = []
for t in tqs:
md, _ = MlogbDefect.objects.get_or_create(mlogb=mlogb, defect=t["defect_main"])
md.count = t["xcount"]
md.save()
md_ids.append(md.id)
count_notok += t["xcount"]
MlogbDefect.objects.filter(mlogb=mlogb).exclude(id__in=md_ids).delete()
mlogb.count_notok = count_notok
mlogb.count_ok = count - mlogb.count_notok
mlogb.save()
class Handover(CommonADModel):
"""

View File

@ -724,7 +724,7 @@ class MlogbOutUpdateSerializer(CustomModelSerializer):
return ins
def update(self, instance, validated_data):
material_out:Material = validated_data["material_out"]
material_out:Material = instance.material_out
mlogbdefect = validated_data.pop("mlogbdefect", [])
with transaction.atomic():
ins:Mlogb = super().update(instance, validated_data)

View File

@ -11,7 +11,7 @@ from apps.system.models import User
from apps.pm.models import Mtask
from apps.mtm.models import Mgroup, Shift, Material, Route, RoutePack, Team, Srule
from .models import SfLog, WMaterial, Mlog, Mlogb, Mlogbw, Handover, Handoverb, Handoverbw
from .models import SfLog, WMaterial, Mlog, Mlogb, Mlogbw, Handover, Handoverb, Handoverbw, MlogbDefect
from apps.mtm.services_2 import cal_material_count
from apps.wf.models import Ticket
from apps.utils.thread import MyThread
@ -233,29 +233,35 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]):
process = mgroup.process
into_wm_mgroup = process.into_wm_mgroup
need_store_notok = process.store_notok
m_outs = Mlogb.objects.filter(mlog=mlog, material_out__isnull=False)
mlogb_out_qs = Mlogb.objects.filter(mlog=mlog, material_out__isnull=False)
stored_notok = need_store_notok
stored_mgroup = need_store_notok
if m_outs.exists():
m_outs_list = [(mo.material_out, mo.batch if mo.batch else mlog.batch, mo.count_ok, mlog.count_real_eweight, None, mo) for mo in m_outs.all()]
if mlogb_out_qs.exists():
m_outs_list = [(mo.material_out, mo.batch if mo.batch else mlog.batch, mo.count_ok, mlog.count_real_eweight, None, mo) for mo in mlogb_out_qs.all()]
if need_store_notok:
for item in m_outs:
if item.material_out.tracking == Material.MA_TRACKING_SINGLE:
# 获取所有主要的不合格项
bw_qs = Mlogbw.objects.filter(mlogb=item)
defectIds= Ftest.objects.filter(mlogbw_ftest__in=bw_qs).exclude(defect_main=None).values_list("defect_main__id", flat=True).distinct()
defects_map = {d.id: d for d in Defect.objects.filter(id__in=defectIds)}
# 过滤并统计相关数据
filtered_bw_qs = bw_qs.filter(
ftest__defect_main__id__in=defects_map.keys()
).values('ftest__defect_main__id').annotate(xcount=Count('id'))
# 整理结果
for defect_data in filtered_bw_qs:
defect_id = defect_data['ftest__defect_main__id']
xcount = defect_data['xcount']
if xcount > 0:
defect = defects_map[defect_id]
m_outs_list.append((item.material_out, item.batch, xcount, 0, defect, item))
for item in mlogb_out_qs:
if item.qct is not None:
if MlogbDefect.objects.filter(mlogb=item).exists():
pass
else:
Mlogbw.cal_count_notok(item)
for itemx in MlogbDefect.objects.filter(mlogb=item):
m_outs_list.append((item.material_out, item.batch, itemx.count, 0, itemx.defect, item))
# # 获取所有主要的不合格项/先暂时保留
# bw_qs = Mlogbw.objects.filter(mlogb=item)
# defectIds= Ftest.objects.filter(mlogbw_ftest__in=bw_qs).exclude(defect_main=None).values_list("defect_main__id", flat=True).distinct()
# defects_map = {d.id: d for d in Defect.objects.filter(id__in=defectIds)}
# # 过滤并统计相关数据
# filtered_bw_qs = bw_qs.filter(
# ftest__defect_main__id__in=defects_map.keys()
# ).values('ftest__defect_main__id').annotate(xcount=Count('id'))
# # 整理结果
# for defect_data in filtered_bw_qs:
# defect_id = defect_data['ftest__defect_main__id']
# xcount = defect_data['xcount']
# if xcount > 0:
# defect = defects_map[defect_id]
# m_outs_list.append((item.material_out, item.batch, xcount, 0, defect, item))
else:
for f in Mlogb._meta.fields:
if 'count_n_' in f.name and getattr(item, f.name) > 0:
@ -358,29 +364,36 @@ def mlog_revert(mlog: Mlog, user: User, now: Union[datetime.datetime, None]):
if material_out or is_fix: # 产物退回
# 有多个产物的情况
# 需要考虑不合格品退回的情况
m_outs = Mlogb.objects.filter(mlog=mlog, material_out__isnull=False)
if m_outs.exists():
mlogb_out_qs = Mlogb.objects.filter(mlog=mlog, material_out__isnull=False)
if mlogb_out_qs.exists():
m_outs_list = [
(mo.material_out, mo.batch if mo.batch else mlog.batch, mo.count_ok, mlog.count_real_eweight, None, mo)
for mo in m_outs.all()]
for mo in mlogb_out_qs.all()]
if stored_notok:
for item in m_outs:
if item.material_out.tracking == Material.MA_TRACKING_SINGLE:
# 获取所有主要的不合格项
bw_qs = Mlogbw.objects.filter(mlogb=item)
defectIds= Ftest.objects.filter(mlogbw_ftest__in=bw_qs).exclude(defect_main=None).values_list("defect_main__id", flat=True).distinct()
defects_map = {d.id: d for d in Defect.objects.filter(id__in=defectIds)}
# 过滤并统计相关数据
filtered_bw_qs = bw_qs.filter(
ftest__defect_main__id__in=defects_map.keys()
).values('ftest__defect_main__id').annotate(xcount=Count('id'))
# 整理结果
for defect_data in filtered_bw_qs:
defect_id = defect_data['ftest__defect_main__id']
xcount = defect_data['xcount']
if xcount > 0:
defect = defects_map[defect_id]
m_outs_list.append((item.material_out, item.batch, xcount, 0, defect, item))
for item in mlogb_out_qs:
if item.qct is not None:
if MlogbDefect.objects.filter(mlogb=item).exists():
pass
else:
Mlogbw.cal_count_notok(item)
for itemx in MlogbDefect.objects.filter(mlogb=item):
m_outs_list.append((item.material_out, item.batch, itemx.count, 0, itemx.defect, item))
# if item.material_out.tracking == Material.MA_TRACKING_SINGLE:
# # 获取所有主要的不合格项
# bw_qs = Mlogbw.objects.filter(mlogb=item)
# defectIds= Ftest.objects.filter(mlogbw_ftest__in=bw_qs).exclude(defect_main=None).values_list("defect_main__id", flat=True).distinct()
# defects_map = {d.id: d for d in Defect.objects.filter(id__in=defectIds)}
# # 过滤并统计相关数据
# filtered_bw_qs = bw_qs.filter(
# ftest__defect_main__id__in=defects_map.keys()
# ).values('ftest__defect_main__id').annotate(xcount=Count('id'))
# # 整理结果
# for defect_data in filtered_bw_qs:
# defect_id = defect_data['ftest__defect_main__id']
# xcount = defect_data['xcount']
# if xcount > 0:
# defect = defects_map[defect_id]
# m_outs_list.append((item.material_out, item.batch, xcount, 0, defect, item))
else:
for f in Mlogb._meta.fields:
if 'count_n_' in f.name and getattr(item, f.name) > 0:

View File

@ -592,13 +592,17 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust
d_count_real = mlogbin.count_use
d_count_ok = mlogbin.count_use
# 找寻质检表
if material_out.tracking == Material.MA_TRACKING_SINGLE:
if is_fix and mgroup.process.type == Process.PRO_PROD:
# 如果是生产返修,则忽略质检
pass
else:
qctmat = QctMat.objects.filter(material=material_out, qct__is_deleted=False).order_by("-create_time").first()
mlogbout.qct = qctmat.qct if qctmat else None
if is_fix and mgroup.process.type == Process.PRO_PROD:
# 如果是生产返修,则忽略质检
pass
elif mlogbout.qct:
try:
qctmat = QctMat.objects.get(material=material_out, qct__is_deleted=False, qct__tags__contains="process").order_by("-create_time")
except QctMat.DoesNotExist:
qctmat = None
except QctMat.MultipleObjectsReturned:
raise ParseError("存在多个质检表,请手动选择")
mlogbout.qct = qctmat.qct if qctmat else None
mlogbout.count_real = d_count_real
mlogbout.count_ok = d_count_ok
mlogbout.save()
@ -672,27 +676,6 @@ class MlogbwViewSet(CustomModelViewSet):
raise ParseError('请指定所属消耗/产出明细')
return super().filter_queryset(queryset)
def cal_mlogb_count(self, mlogb):
count = Mlogbw.objects.filter(mlogb=mlogb).count()
# 此处先不管检验问题
if mlogb.material_in:
mlogb.count_use = count
elif mlogb.material_out:
mlogb.count_real = count
count_notok = 0
tqs = Mlogbw.objects.filter(mlogb=mlogb, ftest__is_ok=False).values("defect_main").annotate(xcount=Count('id'))
md_ids = []
for t in tqs:
md, _ = MlogbDefect.objects.get_or_create(mlogb=mlogb, defect=t["defect_main"])
md.count = t["xcount"]
md.save()
md_ids.append(md.id)
count_notok += t["xcount"]
MlogbDefect.objects.filter(mlogb=mlogb).exclude(id__in=md_ids).delete()
mlogb.count_notok = count_notok
mlogb.count_ok = count - mlogb.count_notok
mlogb.save()
@transaction.atomic
def perform_create(self, serializer):
ins:Mlogbw = serializer.save()
@ -715,7 +698,7 @@ class MlogbwViewSet(CustomModelViewSet):
@transaction.atomic
def perform_update(self, serializer):
mlogbw = serializer.save()
self.cal_mlogb_count(mlogbw.mlogb)
Mlogbw.cal_count_notok(mlogbw.mlogb)
@transaction.atomic
def perform_destroy(self, instance:Mlogbw):
@ -736,4 +719,4 @@ class MlogbwViewSet(CustomModelViewSet):
mbws = Mlogbw.objects.filter(Q(wpr=instance.wpr)|Q(number__contains=instance.number), mlogb=mlogb_to)
Ftest.objects.filter(id__in=mbws.values_list('ftest__id', flat=True)).delete()
mbws.delete()
self.cal_mlogb_count(mlogb_to)
Mlogbw.cal_count_notok(mlogb)