diff --git a/apps/wpm/migrations/0129_mlogbdefect_is_inherited.py b/apps/wpm/migrations/0129_mlogbdefect_is_inherited.py new file mode 100644 index 00000000..ca00cd77 --- /dev/null +++ b/apps/wpm/migrations/0129_mlogbdefect_is_inherited.py @@ -0,0 +1,16 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("wpm", "0128_add_is_manual_to_wmaterial"), + ] + + operations = [ + migrations.AddField( + model_name="mlogbdefect", + name="is_inherited", + field=models.BooleanField(default=False, verbose_name="是否继承"), + ), + ] diff --git a/apps/wpm/models.py b/apps/wpm/models.py index 0840bf6b..da22705f 100644 --- a/apps/wpm/models.py +++ b/apps/wpm/models.py @@ -535,12 +535,51 @@ class Mlogb(BaseModel): if mlog and cal_mlog: mlog.cal_mlog_count_from_mlogb() + def get_default_inherited_defect(self): + if self.material_out is None or self.material_out.tracking != Material.MA_TRACKING_BATCH: + return None + if self.mlogb_from_id and self.mlogb_from and self.mlogb_from.wm_in_id: + return self.mlogb_from.wm_in.defect + if self.wm_in_id and self.wm_in: + return self.wm_in.defect + if self.mlog and self.mlog.wm_in_id: + return self.mlog.wm_in.defect + return None + + def has_legacy_defect_count(self): + return any(getattr(self, f.name) > 0 for f in Mlogb._meta.fields if 'count_n_' in f.name) + + def sync_inherited_defect(self, cal_count=True): + inherited_qs = MlogbDefect.objects.filter(mlogb=self, is_inherited=True) + if MlogbDefect.objects.filter(mlogb=self, is_inherited=False).exists() or self.has_legacy_defect_count(): + inherited_qs.delete() + return + + defect = self.get_default_inherited_defect() + if defect is None: + inherited_qs.delete() + return + + count = self.count_real + inherited, _ = MlogbDefect.objects.get_or_create( + mlogb=self, + defect=defect, + is_inherited=True, + ) + inherited.count = count + inherited.count_has = count + inherited.save(update_fields=["count", "count_has"]) + inherited_qs.exclude(id=inherited.id).delete() + if cal_count: + self.cal_count_notok(cal_mlog=False) + class MlogbDefect(BaseModel): """TN: 生成记录的缺陷记录""" mlogb = models.ForeignKey(Mlogb, verbose_name='生产记录', on_delete=models.CASCADE) defect = models.ForeignKey("qm.Defect", verbose_name='缺陷', on_delete=models.CASCADE, null=True, blank=True) count = models.DecimalField('数量', default=0, max_digits=11, decimal_places=1) count_has = models.DecimalField('含有该缺陷的数量', default=0, max_digits=11, decimal_places=1) + is_inherited = models.BooleanField("是否继承", default=False) @classmethod def get_defect_qs(cls, ftype="all"): @@ -925,4 +964,4 @@ class BatchLog(BaseModel): "last_batch": last["batch"], } - \ No newline at end of file + diff --git a/apps/wpm/serializers.py b/apps/wpm/serializers.py index d3991f97..56ef3ef3 100644 --- a/apps/wpm/serializers.py +++ b/apps/wpm/serializers.py @@ -228,10 +228,11 @@ class MlogbDefectSerializer(CustomModelSerializer): defect_okcate = serializers.CharField(source="defect.okcate", read_only=True) class Meta: model = MlogbDefect - fields = ["id", "defect_name", "count", "mlogb", "defect", "defect_okcate", "count_has"] + fields = ["id", "defect_name", "count", "mlogb", "defect", "defect_okcate", "count_has", "is_inherited"] read_only_fields = EXCLUDE_FIELDS_BASE + ["mlogb"] extra_kwargs = { 'count_has': {'required': False}, + 'is_inherited': {'required': False}, } def validate(self, attrs): @@ -477,6 +478,8 @@ class MlogSerializer(CustomModelSerializer): if mlogb_defect_objects: MlogbDefect.objects.bulk_create(mlogb_defect_objects) mlogb.cal_count_notok(cal_mlog=False) + else: + mlogb.sync_inherited_defect(cal_count=True) instance.cal_mlog_count_from_mlogb() return instance @@ -575,6 +578,8 @@ class MlogSerializer(CustomModelSerializer): if mlogb_defect_objects: MlogbDefect.objects.bulk_create(mlogb_defect_objects) mox.cal_count_notok(cal_mlog=False) + else: + mox.sync_inherited_defect(cal_count=True) instance.cal_mlog_count_from_mlogb() return instance @@ -1111,6 +1116,8 @@ class MlogbOutUpdateSerializer(CustomModelSerializer): if mlogb_defect_objects: MlogbDefect.objects.bulk_create(mlogb_defect_objects) ins.cal_count_notok(cal_mlog=False) + elif ins.material_out.tracking == Material.MA_TRACKING_BATCH: + ins.sync_inherited_defect(cal_count=True) return ins def validate(self, attrs): @@ -1595,4 +1602,4 @@ class MlogQuickSerializer(serializers.Serializer): class BatchChangeSerializer(serializers.Serializer): old_batch = serializers.CharField(label="原批号") - new_batch = serializers.CharField(label="新批号") \ No newline at end of file + new_batch = serializers.CharField(label="新批号") diff --git a/apps/wpm/views.py b/apps/wpm/views.py index 2dc9145c..40cab89b 100644 --- a/apps/wpm/views.py +++ b/apps/wpm/views.py @@ -977,6 +977,8 @@ class MlogbInViewSet(BulkCreateModelMixin, BulkUpdateModelMixin, BulkDestroyMode Mlogbw.objects.get_or_create(number=numberx, mlogb=mlogbout) else: raise ParseError("不支持生成产出物料!") + for mlogbout in Mlogb.objects.filter(mlog=mlog, material_out__isnull=False): + mlogbout.sync_inherited_defect(cal_count=True) mlog.cal_mlog_count_from_mlogb() def perform_create(self, serializer):