From e2fbc63293a4e4ab539fbe126cf2297ffe319419 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 6 Mar 2025 18:51:18 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E4=BC=A0=E5=85=A5?= =?UTF-8?q?=E5=8A=A0=E5=B7=A5=E5=89=8D=E4=B8=8D=E8=89=AF=E7=9A=84=E6=95=B0?= =?UTF-8?q?=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wpm/models.py | 30 +++++++++++++++++---- apps/wpm/serializers.py | 60 ++++++++++++++++++++++++++++++++++------- 2 files changed, 76 insertions(+), 14 deletions(-) diff --git a/apps/wpm/models.py b/apps/wpm/models.py index 4ac03abb..1d13c02c 100644 --- a/apps/wpm/models.py +++ b/apps/wpm/models.py @@ -293,7 +293,11 @@ class Mlog(CommonADModel): @property def mlogdefect(self): - return MlogbDefect.objects.filter(mlogb__mlog=self) + return MlogbDefect.objects.filter(mlogb__mlog=self, mlogb__material_out__isnull=False) + + @property + def mlogindefect(self): + return MlogbDefect.objects.filter(mlogb__mlog=self, mlogb__material_in__isnull=False) @classmethod def count_fields(cls): @@ -317,6 +321,7 @@ class Mlogb(BaseModel): on_delete=models.CASCADE, related_name='mlogb_mtask', null=True, blank=True) wm_in = models.ForeignKey(WMaterial, verbose_name='投入物料所在库存', on_delete=models.SET_NULL, null=True, blank=True) + wm_to = models.ForeignKey(WMaterial, verbose_name='产出物料所在库存', on_delete=models.SET_NULL, null=True, blank=True) material_in = models.ForeignKey( Material, verbose_name='投入物料', on_delete=models.CASCADE, related_name='mlogb_material_in', null=True, blank=True) @@ -370,17 +375,32 @@ class Mlogb(BaseModel): def mlogbdefect(self): return MlogbDefect.objects.filter(mlogb=self) + @property + def cal_count_pn_jgqbl(self): + mqs = MlogbDefect.objects.filter(mlogb=self, material_in___isnull=False) + count_pn_jgqbl = mqs.aggregate(total=Sum("count"))["total"] or 0 + self.count_pn_jgqbl = count_pn_jgqbl + self.count_real = self.count_use - self.count_pn_jgqbl + self.save(update_fields=["count_pn_jgqbl", "count_real"]) + mlog = self.mlog + if mlog: + count_pn_jgqbl = MlogbDefect.objects.filter(mlogb__mlog=mlog, material_in___isnull=False).aggregate(total=Sum("count"))["total"] or 0 + mlog.count_pn_jgqbl = count_pn_jgqbl + mlog.count_real = self.count_use - count_pn_jgqbl + mlog.save(update_fields=["count_pn_jgqbl", "count_real"]) + def cal_count_notok(self): - count_notok = MlogbDefect.objects.filter(defect__okcate=30, mlogb=self).aggregate(total=Sum("count"))["total"] or 0 - count_notok_full = MlogbDefect.objects.filter(mlogb=self).exclude(defect__okcate=10).aggregate(total=Sum("count"))["total"] or 0 + mqs = MlogbDefect.objects.filter(mlogb=self, material_out___isnull=False) + count_notok = mqs.filter(defect__okcate=30).aggregate(total=Sum("count"))["total"] or 0 + count_notok_full = mqs.exclude(defect__okcate=10).aggregate(total=Sum("count"))["total"] or 0 self.count_notok = count_notok self.count_ok = self.count_real - count_notok self.count_ok_full = self.count_real - count_notok_full self.save(update_fields=["count_ok", "count_notok", "count_ok_full"]) mlog = self.mlog if mlog: - count_notok = MlogbDefect.objects.filter(defect__okcate=30, mlogb__mlog=mlog).aggregate(total=Sum("count"))["total"] or 0 - count_notok_full = MlogbDefect.objects.filter(mlogb__mlog=mlog).exclude(defect__okcate=10).aggregate(total=Sum("count"))["total"] or 0 + count_notok = MlogbDefect.objects.filter(defect__okcate=30, mlogb__mlog=mlog, material_out___isnull=False).aggregate(total=Sum("count"))["total"] or 0 + count_notok_full = MlogbDefect.objects.filter(mlogb__mlog=mlog, material_out___isnull=False).exclude(defect__okcate=10).aggregate(total=Sum("count"))["total"] or 0 mlog.count_ok_full = self.count_real - count_notok_full mlog.count_notok = count_notok mlog.count_ok = self.count_real - count_notok diff --git a/apps/wpm/serializers.py b/apps/wpm/serializers.py index 2bb5bf7d..86c991e8 100644 --- a/apps/wpm/serializers.py +++ b/apps/wpm/serializers.py @@ -326,6 +326,7 @@ class MlogSerializer(CustomModelSerializer): test_user_name = serializers.CharField(source='test_user.name', read_only=True) mlogdefect = MlogbDefectSerializer(many=True) + mlogindefect = MlogbDefectSerializer(many=True, label="前道不良") class Meta: model = Mlog fields = '__all__' @@ -340,7 +341,8 @@ class MlogSerializer(CustomModelSerializer): def create(self, validated_data): material_out = validated_data['material_out'] mtask:Mtask = validated_data.get('mtask', None) - mlogdefect = validated_data.pop('mlogdefect', []) + mlogdefect = validated_data.pop('mlogdefect', None) + mlogbindefect = validated_data.pop('mlogindefect', None) if mtask and mtask.state != Mtask.MTASK_ASSGINED: raise ParseError('该任务非下达中不可选择') with transaction.atomic(): @@ -361,7 +363,15 @@ class MlogSerializer(CustomModelSerializer): if wm_in: add_dict['batch_ofrom'] = wm_in.batch_ofrom add_dict['material_ofrom'] = wm_in.material_ofrom - Mlogb.objects.create(**add_dict) + mlogbin = Mlogb.objects.create(**add_dict) + if mlogbindefect is not None: + mlogbin_defect_objects = [ + MlogbDefect(**{**item, "mlogb": mlogbin, "id": idWorker.get_id()}) + for item in mlogdefect if item["count"] > 0 + ] + if mlogbin_defect_objects: + MlogbDefect.objects.bulk_create(mlogbin_defect_objects) + mlogbin.cal_count_pn_jgqbl() # mlogb只用于组合件输出物填写 brotherId_should_list = material_out.brothers @@ -398,7 +408,7 @@ class MlogSerializer(CustomModelSerializer): 'qct': instance.qct } need_mdfect = False - if instance.qct or mlogdefect: + if mlogdefect is not None: need_mdfect = True else: for f in Mlogb._meta.fields: @@ -423,7 +433,8 @@ class MlogSerializer(CustomModelSerializer): raise ParseError('不支持的填写类型') validated_data.pop('mtask', None) validated_data.pop('mgroup', None) - mlogdefect = validated_data.pop('mlogdefect', []) + mlogdefect = validated_data.pop('mlogdefect', None) + mlogbindefect = validated_data.pop('mlogindefect', None) if instance.mtask: validated_data.pop('handle_date', None) # validated_data.pop('handle_user', None) @@ -454,6 +465,14 @@ class MlogSerializer(CustomModelSerializer): minx.qct = instance.qct minx.save() Mlogb.objects.filter(mlog=instance, material_in__isnull=False).exclude(id=minx.id).delete() + if mlogbindefect is not None: + mlogbin_defect_objects = [ + MlogbDefect(**{**item, "mlogb": minx, "id": idWorker.get_id()}) + for item in mlogdefect if item["count"] > 0 + ] + if mlogbin_defect_objects: + MlogbDefect.objects.bulk_create(mlogbin_defect_objects) + minx.cal_count_pn_jgqbl() # 修改产出 if instance.fill_way == Mlog.MLOG_2 and instance.material_out.brothers: @@ -482,7 +501,7 @@ class MlogSerializer(CustomModelSerializer): mox.batch_ofrom = wm_in.batch mox.material_ofrom = wm_in.material_ofrom need_mdefect=False - if instance.qct or mlogdefect: + if mlogdefect is not None: need_mdefect = True else: for f in Mlogb._meta.fields: @@ -623,6 +642,7 @@ class MlogChangeSerializer(CustomModelSerializer): class MlogbInSerializer(CustomModelSerializer): + mlogbdefect = MlogbDefectSerializer(many=True, required=False) class Meta: model = Mlogb fields = ['id', 'mlog', 'mtask', 'wm_in', 'count_use', 'count_pn_jgqbl', @@ -659,20 +679,42 @@ class MlogbInSerializer(CustomModelSerializer): def create(self, validated_data): mlog: Mlog = validated_data['mlog'] mtask: Mtask = validated_data.get("mtask", None) + mlogbdefect = validated_data.pop("mlogbdefect", None) if Mlogb.objects.filter(mlog=mlog, mtask=mtask, wm_in=validated_data['wm_in'], parent=None).exists(): raise ParseError('该记录已存在') if mlog.submit_time is not None: raise ParseError('生产日志已提交不可编辑') - return super().create(validated_data) + with transaction.atomic(): + ins:Mlogb = super().create(validated_data) + if mlogbdefect is not None and ins.material_in.tracking == Material.MA_TRACKING_BATCH: + mlogb_defect_objects = [ + MlogbDefect(**{**item, "mlogb": ins, "id": idWorker.get_id()}) + for item in mlogbdefect if item["count"] > 0 + ] + if mlogb_defect_objects: + MlogbDefect.objects.bulk_create(mlogb_defect_objects) + ins.cal_count_pn_jgqbl() + return ins def update(self, instance, validated_data): mlog: Mlog = instance.mlog mtask: Mtask = instance.mtask + mlogbdefect = validated_data.pop("mlogbdefect", None) if Mlogb.objects.filter(mlog=mlog, mtask=mtask, wm_in=validated_data['wm_in'], parent=None).exclude(id=instance.id).exists(): raise ParseError('该记录已存在') if mlog.submit_time is not None: raise ParseError('生产日志已提交不可编辑') - return super().update(instance, validated_data) + ins = super().update(instance, validated_data) + if mlogbdefect is not None and ins.material_out.tracking == Material.MA_TRACKING_BATCH: + MlogbDefect.objects.filter(mlogb=ins).delete() + mlogb_defect_objects = [ + MlogbDefect(**{**item, "mlogb": ins, "id": idWorker.get_id()}) + for item in mlogbdefect if item["count"] > 0 + ] + if mlogb_defect_objects: + MlogbDefect.objects.bulk_create(mlogb_defect_objects) + ins.cal_count_notok() + return ins class MlogbInUpdateSerializer(CustomModelSerializer): class Meta: @@ -761,10 +803,10 @@ class MlogbOutUpdateSerializer(CustomModelSerializer): # return ins @transaction.atomic def update(self, instance, validated_data): - mlogbdefect = validated_data.pop("mlogbdefect", []) + mlogbdefect = validated_data.pop("mlogbdefect", None) with transaction.atomic(): ins:Mlogb = super().update(instance, validated_data) - if (ins.qct or mlogbdefect) and ins.material_out.tracking == Material.MA_TRACKING_BATCH: + if mlogbdefect is not None and ins.material_out.tracking == Material.MA_TRACKING_BATCH: MlogbDefect.objects.filter(mlogb=ins).delete() mlogb_defect_objects = [ MlogbDefect(**{**item, "mlogb": ins, "id": idWorker.get_id()})