diff --git a/apps/wpm/migrations/0097_auto_20250310_1746.py b/apps/wpm/migrations/0097_auto_20250310_1746.py new file mode 100644 index 00000000..440246aa --- /dev/null +++ b/apps/wpm/migrations/0097_auto_20250310_1746.py @@ -0,0 +1,24 @@ +# Generated by Django 3.2.12 on 2025-03-10 09:46 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('wpm', '0096_fmlog_enabled'), + ] + + operations = [ + migrations.AddField( + model_name='mlogbw', + name='mlogb_to', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='w_mlogb_to', to='wpm.mlogb', verbose_name='指向生产记录'), + ), + migrations.AlterField( + model_name='mlogbw', + name='mlogb', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='w_mlogb', to='wpm.mlogb', verbose_name='生产记录'), + ), + ] diff --git a/apps/wpm/models.py b/apps/wpm/models.py index f58e01b5..b0f1f24b 100644 --- a/apps/wpm/models.py +++ b/apps/wpm/models.py @@ -434,7 +434,8 @@ class Mlogbw(BaseModel): """TN: 单个产品生产/检验日志 """ number = models.TextField('单个编号') - mlogb = models.ForeignKey(Mlogb, verbose_name='生产记录', on_delete=models.CASCADE) + mlogb = models.ForeignKey(Mlogb, verbose_name='生产记录', on_delete=models.CASCADE, related_name="w_mlogb") + mlogb_to = models.ForeignKey(Mlogb, verbose_name='指向生产记录', on_delete=models.CASCADE, null=True, blank=True, related_name="w_mlogb_to") wpr = models.ForeignKey("wpmw.wpr", verbose_name='关联产品', on_delete=models.SET_NULL , related_name='wpr_mlogbw', null=True, blank=True) equip = models.ForeignKey(Equipment, verbose_name='设备', on_delete=models.SET_NULL, null=True, blank=True) diff --git a/apps/wpm/views.py b/apps/wpm/views.py index 09da570b..ed67b8c1 100644 --- a/apps/wpm/views.py +++ b/apps/wpm/views.py @@ -539,22 +539,25 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust ins: Mlogb = instance if ins.mlog.submit_time is not None: raise ParseError('生产日志已提交不可编辑') - qs = None + # if ins.mlogb_to: + # qs = Mlogb.objects.filter(id=ins.mlogb_to.id) + # ftestIds = list(Ftest.objects.filter(mlogbw_ftest__mlogb__in=qs).values_list('id', flat=True)) + # qs.delete() + # if ftestIds: + # Ftest.objects.filter(id__in=ftestIds).delete() + # elif ins.parent is None and ins.mtask: + # query_dict = {"material_out__isnull": False, "mlog": ins.mlog, "mtask": ins.mtask} + # route = ins.mtask.route + # if route.batch_bind: + # query_dict["batch__contains"] = ins.batch + # qs = Mlogb.objects.filter(**query_dict) + qs = Mlogbw.objects.filter(mlogb=ins, ftest__isnull=False) if ins.mlogb_to: - qs = Mlogb.objects.filter(id=ins.mlogb_to.id) - ftestIds = list(Ftest.objects.filter(mlogbw_ftest__mlogb__in=qs).values_list('id', flat=True)) - qs.delete() - if ftestIds: - Ftest.objects.filter(id__in=ftestIds).delete() - elif ins.parent is None and ins.mtask: - query_dict = {"material_out__isnull": False, "mlog": ins.mlog, "mtask": ins.mtask} - route = ins.mtask.route - if route.batch_bind: - query_dict["batch__contains"] = ins.batch - qs = Mlogb.objects.filter(**query_dict) + qs = qs|Mlogbw.objects.filter(mlogb=ins.mlogb_to, ftest__isnull=False) + qs = qs|Mlogbw.objects.filter(mlogb__id__in=list(Mlogbw.objects.filter(mlogb=ins).values_list("mlogb_to__id", flat=True)), ftest__isnull=False) # 需要删除子集ftest记录 if qs: - ftestIds = list(Ftest.objects.filter(mlogbw_ftest__mlogb__in=qs).values_list('id', flat=True)) + ftestIds = list(Ftest.objects.filter(mlogbw_ftest__in=qs).values_list('id', flat=True)) qs.delete() if ftestIds: Ftest.objects.filter(id__in=ftestIds).delete() @@ -599,21 +602,29 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust d_count_ok = mlogbin.count_use mlogbout, _ = Mlogb.objects.get_or_create(**m_dict, defaults= {"batch_ofrom": wm_in.batch_ofrom, "material_ofrom": wm_in.material_ofrom, "count_real": d_count_real, "count_ok": d_count_ok, "qct": qct}) + mlogbin.mlogb_to = mlogbout + mlogbin.save(update_fields = ["mlogb_to"]) elif mtype == Process.PRO_DIV: for mlogbwin in Mlogbw.objects.filter(mlogb=mlogbin).order_by("number"): mlogbout, _ = Mlogb.objects.get_or_create(**m_dict, defaults= {"batch_ofrom": wm_in.batch_ofrom, "material_ofrom": wm_in.material_ofrom, "count_real": d_count_real, "count_ok": d_count_ok, "qct": qct}) + mlogbwin.mlogb_to = mlogbout + mlogbwin.save(update_fields = ["mlogb_to"]) elif mtype == Process.PRO_MERGE: xcount = math.floor( mlogbin.count_use / route.div_number) d_count_real = xcount d_count_ok = xcount mlogbout, _ = Mlogb.objects.get_or_create(**m_dict, defaults= {"batch_ofrom": wm_in.batch_ofrom, "material_ofrom": wm_in.material_ofrom, "count_real": d_count_real, "count_ok": d_count_ok, "qct": qct}) + mlogbin.mlogb_to = mlogbout + mlogbin.save(update_fields = ["mlogb_to"]) elif is_fix: d_count_real = mlogbin.count_use d_count_ok = mlogbin.count_use mlogbout, _ = Mlogb.objects.get_or_create(**m_dict, defaults= {"batch_ofrom": wm_in.batch_ofrom, "material_ofrom": wm_in.material_ofrom, "count_real": d_count_real, "count_ok": d_count_ok, "qct": qct}) + mlogbin.mlogb_to = mlogbout + mlogbin.save(update_fields = ["mlogb_to"]) else: raise ParseError("不支持生成产出物料!") @@ -696,7 +707,24 @@ class MlogbwViewSet(CustomModelViewSet): if material_in is not None: mlogb_to = mlogb.mlogb_to material_out:Material = mlogb.mlog.material_out - if mlogb_to and material_out.tracking == Material.MA_TRACKING_SINGLE: + mtype = route.process.mtype if route.process else None + if material_in.tracking == Material.MA_TRACKING_SINGLE and mtype == Process.PRO_DIV: + mlogbin = ins.mlogb + wm_in = mlogbin.wm_in + mlog = mlogbin.mlog + m_dict = { + "mtask": mlogbin.mtask, + "mlog": mlog, + "material_out": material_out, + } + div_number = route.div_number + mlogbout, _ = Mlogb.objects.get_or_create(**m_dict, defaults= + {"batch_ofrom": wm_in.batch_ofrom, "material_ofrom": wm_in.material_ofrom, "count_real": div_number, "count_ok": div_number, "qct": mlog.qct}) + if material_out.tracking == Material.MA_TRACKING_SINGLE: + for i in range(div_number): + Mlogbw.objects.get_or_create(mlogb=mlogbout, defaults=f'{ins.number}-{i+1}') + Mlogbw.cal_count_notok(mlogb_to) + elif mlogb_to and material_out.tracking == Material.MA_TRACKING_SINGLE: if route.process.mtype == Process.PRO_NORMAL: Mlogbw.objects.get_or_create(mlogb=mlogb_to, wpr=ins.wpr, defaults={"number": ins.number}) elif route.process.mtype == Process.PRO_DIV: @@ -724,7 +752,14 @@ class MlogbwViewSet(CustomModelViewSet): if material_in is not None: mlogb_to = mlogb.mlogb_to material_out: Material = mlogb.mlog.material_out - if mlogb_to and material_out.tracking == Material.MA_TRACKING_SINGLE: + route:Route = mlogb.mlog.route + mtype = route.process.mtype if route.process else None + if material_in.tracking == Material.MA_TRACKING_SINGLE and mtype == Process.PRO_DIV: + mlogbout_qs = Mlogb.objects.filter(id__in=list(Mlogbw.objects.filter(mlogb=mlogb).values_list("mlogb_to__id", flat=True))) + Ftest.objects.filter(id__in=Mlogbw.objects.filter(mlogb__in=mlogbout_qs).values_list('ftest__id', flat=True)).delete() + mlogbout_qs.delete() + Mlogbw.cal_count_notok(mlogb) + elif mlogb_to and material_out.tracking == Material.MA_TRACKING_SINGLE: 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()