feat: mlogb添加字段以追踪原料批次
This commit is contained in:
parent
c1d140a082
commit
7d9582fe34
|
@ -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='原料物料'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -283,11 +283,16 @@ class Mlogb(BaseModel):
|
||||||
batch = models.TextField('批次号', null=True, blank=True)
|
batch = models.TextField('批次号', null=True, blank=True)
|
||||||
mtask = models.ForeignKey(Mtask, verbose_name='关联任务',
|
mtask = models.ForeignKey(Mtask, verbose_name='关联任务',
|
||||||
on_delete=models.CASCADE, related_name='mlogb_mtask', null=True, blank=True)
|
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_in = models.ForeignKey(WMaterial, verbose_name='投入物料所在库存', on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
material_in = models.ForeignKey(
|
material_in = models.ForeignKey(
|
||||||
Material, verbose_name='投入物料', on_delete=models.CASCADE, related_name='mlogb_material_in', null=True, blank=True)
|
Material, verbose_name='投入物料', on_delete=models.CASCADE, related_name='mlogb_material_in', null=True, blank=True)
|
||||||
material_out = models.ForeignKey(
|
material_out = models.ForeignKey(
|
||||||
Material, verbose_name='产物', on_delete=models.CASCADE, related_name='mlogb_material_out', null=True, blank=True)
|
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_use = models.PositiveIntegerField('领用数量', default=0)
|
||||||
count_break = models.PositiveIntegerField('加工破碎数', default=0)
|
count_break = models.PositiveIntegerField('加工破碎数', default=0)
|
||||||
|
|
||||||
|
|
|
@ -294,14 +294,18 @@ class MlogSerializer(CustomModelSerializer):
|
||||||
instance: Mlog = super().create(validated_data)
|
instance: Mlog = super().create(validated_data)
|
||||||
# 自动生成mlogb
|
# 自动生成mlogb
|
||||||
batch_in = instance.batch
|
batch_in = instance.batch
|
||||||
if instance.wm_in:
|
wm_in = instance.wm_in
|
||||||
batch_in = instance.wm_in.batch
|
if wm_in:
|
||||||
|
batch_in = wm_in.batch
|
||||||
add_dict = {
|
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,
|
'mtask': instance.mtask, 'material_in': instance.material_in,
|
||||||
'count_use': instance.count_use, 'count_break': instance.count_break,
|
'count_use': instance.count_use, 'count_break': instance.count_break,
|
||||||
'count_pn_jgqbl': instance.count_pn_jgqbl
|
'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.objects.create(**add_dict)
|
||||||
|
|
||||||
# mlogb只用于组合件输出物填写
|
# mlogb只用于组合件输出物填写
|
||||||
|
@ -331,7 +335,11 @@ class MlogSerializer(CustomModelSerializer):
|
||||||
for f in Mlogb._meta.fields:
|
for f in Mlogb._meta.fields:
|
||||||
if 'count_n_' in f.name:
|
if 'count_n_' in f.name:
|
||||||
add_dict_2[f.name] = getattr(instance, 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
|
return instance
|
||||||
|
|
||||||
def update(self, instance, validated_data):
|
def update(self, instance, validated_data):
|
||||||
|
@ -345,11 +353,12 @@ class MlogSerializer(CustomModelSerializer):
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
mlogb = validated_data.pop('mlogb', [])
|
mlogb = validated_data.pop('mlogb', [])
|
||||||
instance: Mlog = super().update(instance, validated_data)
|
instance: Mlog = super().update(instance, validated_data)
|
||||||
|
wm_in = instance.wm_in
|
||||||
if instance.fill_way == Mlog.MLOG_12:
|
if instance.fill_way == Mlog.MLOG_12:
|
||||||
# 自动生成mlogb
|
# 自动生成mlogb
|
||||||
batch_in = instance.batch
|
batch_in = instance.batch
|
||||||
if instance.wm_in:
|
if wm_in:
|
||||||
batch_in = instance.wm_in.batch
|
batch_in = wm_in.batch
|
||||||
minx, _ = Mlogb.objects.get_or_create(
|
minx, _ = Mlogb.objects.get_or_create(
|
||||||
mlog=instance,
|
mlog=instance,
|
||||||
batch=batch_in,
|
batch=batch_in,
|
||||||
|
@ -357,6 +366,9 @@ class MlogSerializer(CustomModelSerializer):
|
||||||
mtask=instance.mtask,
|
mtask=instance.mtask,
|
||||||
material_in=instance.material_in
|
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_use = instance.count_use
|
||||||
minx.count_break = instance.count_break
|
minx.count_break = instance.count_break
|
||||||
minx.count_pn_jgqbl = instance.count_pn_jgqbl
|
minx.count_pn_jgqbl = instance.count_pn_jgqbl
|
||||||
|
@ -380,6 +392,9 @@ class MlogSerializer(CustomModelSerializer):
|
||||||
mox.count_ok = instance.count_ok
|
mox.count_ok = instance.count_ok
|
||||||
mox.count_notok = instance.count_notok
|
mox.count_notok = instance.count_notok
|
||||||
mox.count_break_t = instance.count_break_t
|
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:
|
for f in Mlogb._meta.fields:
|
||||||
if 'count_n_' in f.name:
|
if 'count_n_' in f.name:
|
||||||
setattr(mox, f.name, getattr(instance, f.name))
|
setattr(mox, f.name, getattr(instance, f.name))
|
||||||
|
@ -511,6 +526,8 @@ class MlogbInSerializer(CustomModelSerializer):
|
||||||
route = mlog.route
|
route = mlog.route
|
||||||
attrs['material_in'] = wm_in.material
|
attrs['material_in'] = wm_in.material
|
||||||
attrs['batch'] = wm_in.batch
|
attrs['batch'] = wm_in.batch
|
||||||
|
attrs["batch_ofrom"] = wm_in.batch_ofrom
|
||||||
|
attrs["material_ofrom"] = wm_in.material_ofrom
|
||||||
if route.batch_bind:
|
if route.batch_bind:
|
||||||
if not WMaterial.mat_in_qs(mtask).filter(id=wm_in.id).exists():
|
if not WMaterial.mat_in_qs(mtask).filter(id=wm_in.id).exists():
|
||||||
raise ValidationError('该车间库存非本任务使用')
|
raise ValidationError('该车间库存非本任务使用')
|
||||||
|
|
|
@ -8,7 +8,7 @@ from typing import Union
|
||||||
from rest_framework.exceptions import ParseError
|
from rest_framework.exceptions import ParseError
|
||||||
|
|
||||||
from apps.system.models import User
|
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.pm.models import Mtask
|
||||||
from apps.mtm.models import Mgroup, Shift, Material, Route, RoutePack
|
from apps.mtm.models import Mgroup, Shift, Material, Route, RoutePack
|
||||||
|
|
||||||
|
@ -186,7 +186,12 @@ def do_in(mio: MIO):
|
||||||
for al in action_list:
|
for al in action_list:
|
||||||
xmaterial, xbatch, xcount = al
|
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():
|
# 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)
|
# 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_out = mlog.material_out
|
||||||
material_in = mlog.material_in
|
material_in = mlog.material_in
|
||||||
supplier = mlog.supplier # 外协
|
supplier = mlog.supplier # 外协
|
||||||
|
m_ins_list = []
|
||||||
if material_in: # 需要进行车间库存管理
|
if material_in: # 需要进行车间库存管理
|
||||||
m_ins = Mlogb.objects.filter(mlog=mlog, material_in__isnull=False)
|
m_ins = Mlogb.objects.filter(mlog=mlog, material_in__isnull=False)
|
||||||
if m_ins.exists():
|
if m_ins.exists():
|
||||||
|
@ -287,7 +293,7 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]):
|
||||||
stored_notok = False
|
stored_notok = False
|
||||||
stored_mgroup = False
|
stored_mgroup = False
|
||||||
if m_outs.exists():
|
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:
|
if need_store_notok:
|
||||||
for item in m_outs:
|
for item in m_outs:
|
||||||
for f in Mlogb._meta.fields:
|
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))
|
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
|
stored_notok = True
|
||||||
else:
|
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:
|
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
|
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}
|
lookup = {'batch': mo_batch, 'material': mo_ma, 'mgroup': None, 'notok_sign': notok_sign, 'state': wm_state}
|
||||||
if into_wm_mgroup:
|
if into_wm_mgroup:
|
||||||
|
@ -309,12 +315,20 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]):
|
||||||
else:
|
else:
|
||||||
lookup['belong_dept'] = belong_dept
|
lookup['belong_dept'] = belong_dept
|
||||||
if mo_count > 0:
|
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 = wm.count + mo_count
|
||||||
wm.count_eweight = mo_count_eweight
|
wm.count_eweight = mo_count_eweight
|
||||||
wm.update_by = user
|
wm.update_by = user
|
||||||
if supplier is not None:
|
if supplier is not None:
|
||||||
wm.supplier = supplier
|
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()
|
wm.save()
|
||||||
|
|
||||||
mlog.submit_time = now
|
mlog.submit_time = now
|
||||||
|
@ -600,7 +614,11 @@ def handover_submit(handover: Handover, user: User, now: Union[datetime.datetime
|
||||||
material=material,
|
material=material,
|
||||||
mgroup=recive_mgroup,
|
mgroup=recive_mgroup,
|
||||||
belong_dept=recive_dept,
|
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:
|
elif handover.type == Handover.H_REPAIR:
|
||||||
if handover.recive_mgroup:
|
if handover.recive_mgroup:
|
||||||
|
@ -611,7 +629,11 @@ def handover_submit(handover: Handover, user: User, now: Union[datetime.datetime
|
||||||
belong_dept=recive_dept,
|
belong_dept=recive_dept,
|
||||||
notok_sign=wm_from.notok_sign,
|
notok_sign=wm_from.notok_sign,
|
||||||
material_origin=material,
|
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:
|
else:
|
||||||
raise ParseError("返工交接必须指定接收工段")
|
raise ParseError("返工交接必须指定接收工段")
|
||||||
|
@ -624,6 +646,8 @@ def handover_submit(handover: Handover, user: User, now: Union[datetime.datetime
|
||||||
belong_dept=recive_dept,
|
belong_dept=recive_dept,
|
||||||
defaults={
|
defaults={
|
||||||
"count_xtest": 0,
|
"count_xtest": 0,
|
||||||
|
"batch_ofrom": wm_from.batch_ofrom,
|
||||||
|
"material_ofrom": wm_from.material_ofrom
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
elif handover.type == Handover.H_SCRAP:
|
elif handover.type == Handover.H_SCRAP:
|
||||||
|
@ -634,7 +658,11 @@ def handover_submit(handover: Handover, user: User, now: Union[datetime.datetime
|
||||||
mgroup=recive_mgroup,
|
mgroup=recive_mgroup,
|
||||||
belong_dept=recive_dept,
|
belong_dept=recive_dept,
|
||||||
notok_sign=wm_from.notok_sign,
|
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:
|
else:
|
||||||
raise ParseError("不支持非工段报废")
|
raise ParseError("不支持非工段报废")
|
||||||
|
|
|
@ -488,7 +488,8 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust
|
||||||
"material_out": ins.mlog.material_out
|
"material_out": ins.mlog.material_out
|
||||||
}
|
}
|
||||||
m_dict['batch'] = generate_new_batch(ins.batch, mlog)
|
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):
|
class MlogbOutViewSet(UpdateModelMixin, CustomGenericViewSet):
|
||||||
|
|
Loading…
Reference in New Issue