diff --git a/apps/wpm/migrations/0071_auto_20241113_1555.py b/apps/wpm/migrations/0071_auto_20241113_1555.py new file mode 100644 index 00000000..152e58f7 --- /dev/null +++ b/apps/wpm/migrations/0071_auto_20241113_1555.py @@ -0,0 +1,25 @@ +# Generated by Django 3.2.12 on 2024-11-13 07:55 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('mtm', '0042_auto_20241010_1140'), + ('wpm', '0070_auto_20241112_1447'), + ] + + operations = [ + migrations.AddField( + model_name='mlogb', + name='batch_ofrom', + field=models.TextField(blank=True, null=True, verbose_name='原料批次号'), + ), + migrations.AddField( + model_name='mlogb', + name='material_ofrom', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='mlogb_mofrom', to='mtm.material', verbose_name='原料物料'), + ), + ] diff --git a/apps/wpm/models.py b/apps/wpm/models.py index af04f110..33718c65 100644 --- a/apps/wpm/models.py +++ b/apps/wpm/models.py @@ -283,11 +283,16 @@ class Mlogb(BaseModel): batch = models.TextField('批次号', null=True, blank=True) mtask = models.ForeignKey(Mtask, verbose_name='关联任务', 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) material_in = models.ForeignKey( Material, verbose_name='投入物料', on_delete=models.CASCADE, related_name='mlogb_material_in', null=True, blank=True) material_out = models.ForeignKey( Material, verbose_name='产物', on_delete=models.CASCADE, related_name='mlogb_material_out', null=True, blank=True) + + batch_ofrom = models.TextField('原料批次号', null=True, blank=True) + material_ofrom = models.ForeignKey(Material, verbose_name='原料物料', on_delete=models.SET_NULL, null=True, blank=True, related_name='mlogb_mofrom') + count_use = models.PositiveIntegerField('领用数量', default=0) count_break = models.PositiveIntegerField('加工破碎数', default=0) diff --git a/apps/wpm/serializers.py b/apps/wpm/serializers.py index 70eb2754..b13db479 100644 --- a/apps/wpm/serializers.py +++ b/apps/wpm/serializers.py @@ -294,14 +294,18 @@ class MlogSerializer(CustomModelSerializer): instance: Mlog = super().create(validated_data) # 自动生成mlogb batch_in = instance.batch - if instance.wm_in: - batch_in = instance.wm_in.batch + wm_in = instance.wm_in + if wm_in: + batch_in = wm_in.batch add_dict = { - 'mlog': instance, 'batch': batch_in, 'wm_in': instance.wm_in, + 'mlog': instance, 'batch': batch_in, 'wm_in': wm_in, 'mtask': instance.mtask, 'material_in': instance.material_in, 'count_use': instance.count_use, 'count_break': instance.count_break, 'count_pn_jgqbl': instance.count_pn_jgqbl } + if wm_in: + add_dict['batch_ofrom'] = wm_in.batch_ofrom + add_dict['material_ofrom'] = wm_in.material_ofrom Mlogb.objects.create(**add_dict) # mlogb只用于组合件输出物填写 @@ -331,7 +335,11 @@ class MlogSerializer(CustomModelSerializer): for f in Mlogb._meta.fields: if 'count_n_' in f.name: add_dict_2[f.name] = getattr(instance, f.name) - Mlogb.objects.create(**add_dict_2) + ddict = {} + if wm_in: + wm_in = instance.wm_in + ddict = {"batch_ofrom": wm_in.batch_ofrom, "material_ofrom": wm_in.material_ofrom} + Mlogb.objects.create(**add_dict_2, defaults=ddict) return instance def update(self, instance, validated_data): @@ -345,11 +353,12 @@ class MlogSerializer(CustomModelSerializer): with transaction.atomic(): mlogb = validated_data.pop('mlogb', []) instance: Mlog = super().update(instance, validated_data) + wm_in = instance.wm_in if instance.fill_way == Mlog.MLOG_12: # 自动生成mlogb batch_in = instance.batch - if instance.wm_in: - batch_in = instance.wm_in.batch + if wm_in: + batch_in = wm_in.batch minx, _ = Mlogb.objects.get_or_create( mlog=instance, batch=batch_in, @@ -357,6 +366,9 @@ class MlogSerializer(CustomModelSerializer): mtask=instance.mtask, material_in=instance.material_in ) + if wm_in: + minx.batch_ofrom = wm_in.batch_ofrom + minx.material_ofrom = wm_in.material_ofrom minx.count_use = instance.count_use minx.count_break = instance.count_break minx.count_pn_jgqbl = instance.count_pn_jgqbl @@ -380,6 +392,9 @@ class MlogSerializer(CustomModelSerializer): mox.count_ok = instance.count_ok mox.count_notok = instance.count_notok mox.count_break_t = instance.count_break_t + if wm_in: + mox.batch_ofrom = wm_in.batch + mox.material_ofrom = wm_in.material_ofrom for f in Mlogb._meta.fields: if 'count_n_' in f.name: setattr(mox, f.name, getattr(instance, f.name)) @@ -511,6 +526,8 @@ class MlogbInSerializer(CustomModelSerializer): route = mlog.route attrs['material_in'] = wm_in.material attrs['batch'] = wm_in.batch + attrs["batch_ofrom"] = wm_in.batch_ofrom + attrs["material_ofrom"] = wm_in.material_ofrom if route.batch_bind: if not WMaterial.mat_in_qs(mtask).filter(id=wm_in.id).exists(): raise ValidationError('该车间库存非本任务使用') diff --git a/apps/wpm/services.py b/apps/wpm/services.py index 94336a7a..34672ee8 100644 --- a/apps/wpm/services.py +++ b/apps/wpm/services.py @@ -8,7 +8,7 @@ from typing import Union from rest_framework.exceptions import ParseError from apps.system.models import User -from apps.inm.models import MIO, MIOItem, MIOItemA +from apps.inm.models import MIO, MIOItem, MIOItemA, MaterialBatch from apps.pm.models import Mtask from apps.mtm.models import Mgroup, Shift, Material, Route, RoutePack @@ -186,7 +186,12 @@ def do_in(mio: MIO): for al in action_list: xmaterial, xbatch, xcount = al # 优先从车间库存里拿 - wm_qs = WMaterial.objects.filter(batch=xbatch, material=xmaterial, belong_dept=belong_dept, mgroup=mgroup, state=WMaterial.WM_OK) + wm_qs = WMaterial.objects.filter( + batch=xbatch, + material=xmaterial, + belong_dept=belong_dept, + mgroup=mgroup, + state=WMaterial.WM_OK) # if not wm_qs.exists(): # wm_qs = WMaterial.objects.filter(batch=xbatch, material=xmaterial, belong_dept=belong_dept, mgroup__isnull=False, notok_sign=None, material_origin=None, count_xtest=None) @@ -227,6 +232,7 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): material_out = mlog.material_out material_in = mlog.material_in supplier = mlog.supplier # 外协 + m_ins_list = [] if material_in: # 需要进行车间库存管理 m_ins = Mlogb.objects.filter(mlog=mlog, material_in__isnull=False) if m_ins.exists(): @@ -287,7 +293,7 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): stored_notok = False stored_mgroup = False 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) for mo in m_outs.all()] + 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 need_store_notok: for item in m_outs: for f in Mlogb._meta.fields: @@ -296,11 +302,11 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): m_outs_list.append( (item.material_out, item.batch if item.batch else mlog.batch, getattr(item, f.name), mlog.count_real_eweight, notok_sign)) stored_notok = True else: - m_outs_list = [(material_out, mlog.batch, mlog.count_ok, mlog.count_real_eweight, None)] + m_outs_list = [(material_out, mlog.batch, mlog.count_ok, mlog.count_real_eweight, None, mlog)] # 一次填写的暂时不处理不合格品 for mo in m_outs_list: - mo_ma, mo_batch, mo_count, mo_count_eweight, notok_sign = mo + mo_ma, mo_batch, mo_count, mo_count_eweight, notok_sign, mlog_or_b = mo wm_state = WMaterial.WM_OK if notok_sign is None else WMaterial.WM_NOTOK lookup = {'batch': mo_batch, 'material': mo_ma, 'mgroup': None, 'notok_sign': notok_sign, 'state': wm_state} if into_wm_mgroup: @@ -309,12 +315,20 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): else: lookup['belong_dept'] = belong_dept if mo_count > 0: - wm, _ = WMaterial.objects.get_or_create(**lookup, defaults={**lookup, "belong_dept": belong_dept}) + wm, is_create2 = WMaterial.objects.get_or_create(**lookup, defaults={**lookup, "belong_dept": belong_dept}) wm.count = wm.count + mo_count wm.count_eweight = mo_count_eweight wm.update_by = user if supplier is not None: wm.supplier = supplier + if is_create2: + if isinstance(mlog_or_b, Mlog) and mlog_or_b.wm_in: + wm.batch_ofrom = mlog_or_b.wm_in.batch_ofrom + wm.material_ofrom = mlog_or_b.wm_in.material_ofrom + elif isinstance(mlog_or_b, Mlogb): + wm.batch_ofrom = mlog_or_b.batch_ofrom + wm.material_ofrom = mlog_or_b.material_ofrom + wm.batch_ofrom = mlog_or_b wm.save() mlog.submit_time = now @@ -600,7 +614,11 @@ def handover_submit(handover: Handover, user: User, now: Union[datetime.datetime material=material, mgroup=recive_mgroup, belong_dept=recive_dept, - state=WMaterial.WM_OK + state=WMaterial.WM_OK, + defaults={ + "batch_ofrom": wm_from.batch_ofrom, + "material_ofrom": wm_from.material_ofrom + } ) elif handover.type == Handover.H_REPAIR: if handover.recive_mgroup: @@ -611,7 +629,11 @@ def handover_submit(handover: Handover, user: User, now: Union[datetime.datetime belong_dept=recive_dept, notok_sign=wm_from.notok_sign, material_origin=material, - state=WMaterial.WM_REPAIR + state=WMaterial.WM_REPAIR, + defaults={ + "batch_ofrom": wm_from.batch_ofrom, + "material_ofrom": wm_from.material_ofrom + } ) else: raise ParseError("返工交接必须指定接收工段") @@ -624,6 +646,8 @@ def handover_submit(handover: Handover, user: User, now: Union[datetime.datetime belong_dept=recive_dept, defaults={ "count_xtest": 0, + "batch_ofrom": wm_from.batch_ofrom, + "material_ofrom": wm_from.material_ofrom }, ) elif handover.type == Handover.H_SCRAP: @@ -634,7 +658,11 @@ def handover_submit(handover: Handover, user: User, now: Union[datetime.datetime mgroup=recive_mgroup, belong_dept=recive_dept, notok_sign=wm_from.notok_sign, - state=WMaterial.WM_SCRAP + state=WMaterial.WM_SCRAP, + defaults={ + "batch_ofrom": wm_from.batch_ofrom, + "material_ofrom": wm_from.material_ofrom + } ) else: raise ParseError("不支持非工段报废") diff --git a/apps/wpm/views.py b/apps/wpm/views.py index 005d86a2..2fdb4457 100644 --- a/apps/wpm/views.py +++ b/apps/wpm/views.py @@ -488,7 +488,8 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust "material_out": ins.mlog.material_out } m_dict['batch'] = generate_new_batch(ins.batch, mlog) - Mlogb.objects.get_or_create(**m_dict, defaults=m_dict) + wm_in: WMaterial = ins.wm_in + Mlogb.objects.get_or_create(**m_dict, defaults={"batch_ofrom": wm_in.batch_ofrom, "material_ofrom": wm_in.material_ofrom}) class MlogbOutViewSet(UpdateModelMixin, CustomGenericViewSet):