diff --git a/apps/inm/migrations/0024_mioitemw_wpr.py b/apps/inm/migrations/0024_mioitemw_wpr.py new file mode 100644 index 00000000..4a31e98b --- /dev/null +++ b/apps/inm/migrations/0024_mioitemw_wpr.py @@ -0,0 +1,20 @@ +# Generated by Django 3.2.12 on 2025-01-03 08:52 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('wpmw', '0001_initial'), + ('inm', '0023_auto_20250102_0858'), + ] + + operations = [ + migrations.AddField( + model_name='mioitemw', + name='wpr', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='wpr_mioitemw', to='wpmw.wpr', verbose_name='关联产品'), + ), + ] diff --git a/apps/inm/models.py b/apps/inm/models.py index 5e099c14..4d077670 100644 --- a/apps/inm/models.py +++ b/apps/inm/models.py @@ -178,6 +178,8 @@ class MIOItemw(BaseModel): 单件记录 """ number = models.TextField('编号') + wpr = models.ForeignKey("wpmw.wpr", verbose_name='关联产品', on_delete=models.SET_NULL, related_name='wpr_mioitemw' + , null=True, blank=True) mioitem = models.ForeignKey(MIOItem, verbose_name='关联出入库明细', on_delete=models.CASCADE, related_name='w_mioitem') note = models.TextField('备注', null=True, blank=True) \ No newline at end of file diff --git a/apps/inm/serializers.py b/apps/inm/serializers.py index 520a8f60..9777248f 100644 --- a/apps/inm/serializers.py +++ b/apps/inm/serializers.py @@ -153,15 +153,18 @@ class MIOItemCreateSerializer(CustomModelSerializer): else: raise ParseError('缺少组合件') if material.tracking == Material.MA_TRACKING_SINGLE: - if count == 1 and len(mioitemw) == 0: - MIOItemw.objects.create(mioitem=instance, number=batch) - elif count == 1 and len(mioitemw) >= 1: - MIOItemw.objects.create(mioitem=instance, number=mioitemw[0]['number'], note=mioitemw[0]['note']) - elif count > 1 and len(mioitemw) == count: - for item in mioitemw: - MIOItemw.objects.create(mioitem=instance, number=item['number'], note=item['note']) + if mio.type == MIO.MIO_TYPE_PUR_IN: + if count == 1 and len(mioitemw) == 0: + MIOItemw.objects.create(mioitem=instance, number=batch) + elif count == 1 and len(mioitemw) >= 1: + MIOItemw.objects.create(mioitem=instance, number=mioitemw[0]['number'], note=mioitemw[0]['note']) + elif count > 1 and len(mioitemw) == count: + for item in mioitemw: + MIOItemw.objects.create(mioitem=instance, number=item['number'], note=item['note']) + else: + raise ParseError('单个明细信息不匹配') else: - raise ParseError('单个明细信息不匹配') + raise ParseError("暂只支持采购入库") return instance diff --git a/apps/inm/services.py b/apps/inm/services.py index 55cc5b98..a20df501 100644 --- a/apps/inm/services.py +++ b/apps/inm/services.py @@ -94,7 +94,7 @@ def do_out(item: MIOItem): if mioitemws.count() != item.count: raise ParseError("出入库与明细数量不一致,操作失败") for mioitemw in mioitemws: - Wpr.change_or_new(mioitemw.number, mb=None, wm=wm, old_mb=mb) + Wpr.change_or_new(wpr=mioitemw.wpr, wm=wm, old_mb=mb) # 触发批次统计分析 xbatches = list(set(xbatches)) @@ -291,7 +291,12 @@ class InmService: if mioitemws.count() != mb.count: raise ParseError("出入库与明细数量不一致,操作失败") for mioitemw in mioitemws: - Wpr.change_or_new(number=mioitemw.number, mb=mb) + if mioitemw.wpr: + Wpr.change_or_new(wpr=mioitemw.wpr, mb=mb) + else: + wpr = Wpr.change_or_new(number=mioitemw.number, mb=mb) + mioitemw.wpr = wpr + mioitemw.save() elif in_or_out == -1: mb.count = mb.count - getattr(i, field) @@ -304,7 +309,7 @@ class InmService: if mioitemws.count() != mb.count: raise ParseError("出入库与明细数量不一致,操作失败") for mioitemw in mioitemws: - Wpr.change_or_new(number=mioitemw.number, old_mb=mb) + Wpr.change_or_new(wpr=mioitemw.wpr, old_mb=mb) else: raise ParseError("不支持的操作") diff --git a/apps/wpm/migrations/0079_auto_20250103_1652.py b/apps/wpm/migrations/0079_auto_20250103_1652.py new file mode 100644 index 00000000..0d0f01cb --- /dev/null +++ b/apps/wpm/migrations/0079_auto_20250103_1652.py @@ -0,0 +1,25 @@ +# Generated by Django 3.2.12 on 2025-01-03 08:52 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('wpmw', '0001_initial'), + ('wpm', '0078_auto_20250102_0958'), + ] + + operations = [ + migrations.AddField( + model_name='handoverbw', + name='wpr', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='wpr_handoverbw', to='wpmw.wpr', verbose_name='关联产品'), + ), + migrations.AddField( + model_name='mlogbw', + name='wpr', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='wpr_mlogbw', to='wpmw.wpr', verbose_name='关联产品'), + ), + ] diff --git a/apps/wpm/models.py b/apps/wpm/models.py index 169571df..7c31b936 100644 --- a/apps/wpm/models.py +++ b/apps/wpm/models.py @@ -338,6 +338,8 @@ class Mlogb(BaseModel): class Mlogbw(BaseModel): number = models.TextField('单个编号') mlogb = models.ForeignKey(Mlogb, verbose_name='生产记录', on_delete=models.CASCADE) + wpr = models.ForeignKey("wpmw.wpr", verbose_name='关联产品', on_delete=models.SET_NULL + , related_name='wpr_mlogbw', null=True, blank=True) note = models.TextField('备注', null=True, blank=True) @@ -397,6 +399,8 @@ class Handoverb(BaseModel): class Handoverbw(BaseModel): handoverb = models.ForeignKey(Handoverb, verbose_name='关联交接记录', on_delete=models.CASCADE) number = models.TextField('单个编号') + wpr = models.ForeignKey("wpmw.wpr", verbose_name='关联产品', on_delete=models.CASCADE + , related_name='wpr_handoverbw', null=True, blank=True) note = models.TextField('备注', null=True, blank=True) class AttLog(CommonADModel): diff --git a/apps/wpm/services.py b/apps/wpm/services.py index 4f6ff39f..1bd1bf05 100644 --- a/apps/wpm/services.py +++ b/apps/wpm/services.py @@ -201,7 +201,7 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): if mlogbws.count() != mi_count: raise ParseError("日志与明细数量不一致,操作失败") for item in mlogbws: - Wpr.change_or_new(number=item.number, old_wm=wm) + Wpr.change_or_new(wpr=item.wpr, old_wm=wm) # 针对加工前不良的暂时额外处理 for item in m_ins_bl_list: @@ -271,7 +271,10 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): if mlogbws.count() != mo_count: raise ParseError("日志与明细数量不一致,操作失败") for item in mlogbws: - Wpr.change_or_new(number=item.number, wm=wm) + if item.wpr: + Wpr.change_or_new(wpr=item.wpr, wm=wm) + else: + Wpr.change_or_new(number=item.number, wm=wm) mlog.submit_time = now mlog.submit_user = user @@ -356,7 +359,7 @@ def mlog_revert(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): if mlogbws.count() != mo_count: raise ParseError("日志与明细数量不一致,操作失败") for item in mlogbws: - Wpr.change_or_new(number=item.number, old_wm=wm) + Wpr.change_or_new(wpr=item.wpr, old_wm=wm) # 再生成消耗 if material_in: # 领用数退回 @@ -393,7 +396,10 @@ def mlog_revert(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): if mlogbws.count() != mi_count: raise ParseError("日志与明细数量不一致,操作失败") for item in mlogbws: - Wpr.change_or_new(number=item.number, wm=wm) + if item.wpr: + Wpr.change_or_new(wpr=item.wpr, wm=wm) + else: + Wpr.change_or_new(number=item.number, wm=wm) # 针对加工前不良的暂时额外处理 for item in m_ins_bl_list: diff --git a/apps/wpmw/models.py b/apps/wpmw/models.py index 995fef43..67cfccc5 100644 --- a/apps/wpmw/models.py +++ b/apps/wpmw/models.py @@ -18,14 +18,14 @@ class Wpr(BaseModel): mb = models.ForeignKey("inm.materialbatch", verbose_name="仓库物料", on_delete=models.CASCADE, null=True, blank=True) wm = models.ForeignKey("wpm.wmaterial", verbose_name="车间物料", on_delete=models.CASCADE, null=True, blank=True) - @classmethod - def change_or_new(cls, number, mb=None, wm=None, old_mb=None, old_wm=None): + def change_or_new(cls, wpr=None, number=None, mb=None, wm=None, old_mb=None, old_wm=None): + if wpr is None and number is None: + raise ParseError("id和number不能同时为空") if mb and wm: raise ParseError("所属仓库批次和车间批次不可同时存在") - ins = cls.objects.filter(number=number).first() - + ins = wpr if wpr else cls.objects.filter(number=number).first() if ins is None: ins = cls(number=number) @@ -41,6 +41,7 @@ class Wpr(BaseModel): if wm: ins.material = wm.material ins.save() + return ins @classmethod def clear(cls, number_list):