feat: 单日志支持多工艺步骤

This commit is contained in:
caoqianming 2025-06-30 16:17:09 +08:00
parent a3b0455fb4
commit 620e547da5
4 changed files with 71 additions and 33 deletions

View File

@ -0,0 +1,20 @@
# Generated by Django 3.2.12 on 2025-06-30 08:16
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('mtm', '0059_material_bin_number_main'),
('wpm', '0118_batchst_mioitem'),
]
operations = [
migrations.AddField(
model_name='mlogb',
name='route',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='mtm.route', verbose_name='生产步骤'),
),
]

View File

@ -368,7 +368,7 @@ class Mlogb(BaseModel):
batch = models.TextField('批次号', null=True, blank=True, db_index=True)
mtask = models.ForeignKey(Mtask, verbose_name='关联任务',
on_delete=models.CASCADE, related_name='mlogb_mtask', null=True, blank=True)
route = models.ForeignKey(Route, 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(

View File

@ -378,6 +378,7 @@ class MlogSerializer(CustomModelSerializer):
add_dict = {
'mlog': instance, 'batch': batch_in, 'wm_in': wm_in,
'mtask': instance.mtask, 'material_in': instance.material_in,
'route': instance.route,
'count_use': instance.count_use, 'count_break': instance.count_break,
'count_pn_jgqbl': instance.count_pn_jgqbl
}
@ -402,7 +403,8 @@ class MlogSerializer(CustomModelSerializer):
if item['material_out'].id in brotherId_should_list:
mlogbx = Mlogb.objects.create(
mlog=instance,
batch=instance.batch,
batch=instance.batch,
route=instance.route,
mtask=instance.mtask,
material_out=item['material_out'],
count_ok=item['count_ok'])
@ -423,7 +425,7 @@ class MlogSerializer(CustomModelSerializer):
add_dict_2 = {
'mlog': instance, 'batch': batch_out,
'mtask': instance.mtask, 'material_out': instance.material_out,
'count_real': instance.count_real,
'count_real': instance.count_real, 'route': instance.route,
'count_ok': instance.count_ok, 'count_notok': instance.count_notok,
'count_break_t': instance.count_break_t,
'qct': instance.qct
@ -657,13 +659,14 @@ class MlogInitSerializer(CustomModelSerializer):
attrs['material_out'] = None
else:
route: Route = attrs.get('route', None)
if not route:
raise ParseError('缺少工艺路线')
if route and route.process != mgroup.process:
raise ParseError('工序不匹配')
attrs['hour_work'] = route.hour_work
attrs['material_in'] = route.material_in
attrs['material_out'] = route.material_out
# if not route:
# raise ParseError('缺少工艺路线')
if route:
if route and route.process != mgroup.process:
raise ParseError('工序不匹配')
attrs['hour_work'] = route.hour_work
attrs['material_in'] = route.material_in
attrs['material_out'] = route.material_out
attrs['fill_way'] = Mlog.MLOG_23
if attrs['mtype'] == Mlog.MTYPE_OUT:
supplier = attrs.get('supplier', None)
@ -671,7 +674,8 @@ class MlogInitSerializer(CustomModelSerializer):
raise ParseError('外协必须选择外协单位')
if attrs.get('work_end_time', None):
attrs['handle_date'] = localdate(attrs['work_end_time'])
if attrs["material_out"]:
# 如果已经确定产出则自动获取qct
if attrs.get("material_out", None):
attrs["qct"] = Qct.get(attrs["material_out"], "process")
return attrs
@ -703,7 +707,7 @@ class MlogbInSerializer(CustomModelSerializer):
class Meta:
model = Mlogb
fields = ['id', 'mlog', 'mtask', 'wm_in', 'count_use', 'count_pn_jgqbl',
fields = ['id', 'mlog', 'mtask', 'route', 'wm_in', 'count_use', 'count_pn_jgqbl',
'count_break', 'note', "parent", "mlogbdefect", "count_json_from"]
extra_kwargs = {'count_use': {'required': True}, 'mtask': {'required': False},
'wm_in': {'required': True, "allow_empty": False}}
@ -726,9 +730,19 @@ class MlogbInSerializer(CustomModelSerializer):
raise ParseError('返修或复检需使用返修品/不合格品')
elif wm_in.state != WMaterial.WM_OK:
raise ParseError('非合格品不可使用')
if mtask and mlog.route != mtask.route:
raise ParseError('工序不匹配')
route = mlog.route
mlog_route = mlog.route
if mlog_route is None:
if is_fix is False:
route = attrs.get("route", None)
if not route:
raise ParseError("缺少工艺步骤")
else:
route = mlog_route
attrs["route"] = route
if mtask and route != mtask.route:
raise ParseError('工艺步骤与任务不匹配')
attrs['material_in'] = wm_in.material
attrs['batch'] = wm_in.batch
attrs["batch_ofrom"] = wm_in.batch_ofrom

View File

@ -586,15 +586,18 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust
def perform_create(self, serializer):
mlogbin: Mlogb = serializer.save()
mlog:Mlog = mlogbin.mlog
route:Route = mlog.route
process: Process = route.process if route else None
mtype = route.process.mtype if route else None
mgroup:Mgroup = mlog.mgroup
route:Route = mlogbin.route
is_fix = mlog.is_fix
qct = mlog.qct
if route is None and is_fix is False:
raise ParseError('消耗物料缺失工艺步骤')
process: Process = mgroup.process if route else None
mtype = process.mtype if process else None
# qct = mlog.qct
# 以及mlogbw
material_in:Material = mlogbin.material_in
# 如果是返修,则输出和输入相同
material_out:Material = mlog.material_out if is_fix is False else material_in
material_out:Material = material_in if is_fix else route.material_out
if material_out is None:
raise ParseError('产物不可为空')
# 如果是主要输入物料且是主批次,才需生成输出
@ -608,24 +611,33 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust
for wpr in Wpr.objects.filter(wm=wm_in).order_by("number"):
Mlogbw.objects.get_or_create(wpr=wpr, mlogb=mlogbin, defaults={"number": wpr.number})
if qct is None:
mlog.qct = Qct.get(material_out, "process")
mlog.save(update_fields = ["qct"])
# if qct is None:
# mlog.qct = Qct.get(material_out, "process")
# mlog.save(update_fields = ["qct"])
m_dict = {
"mtask": mlogbin.mtask,
"route": route,
"mlog": mlog,
"material_out": material_out,
"batch": mlogbin.batch,
"batch_ofrom": wm_in.batch_ofrom, "material_ofrom": wm_in.material_ofrom,
"qct": qct
"qct": Qct.get(material_out, "process")
}
if mtype == Process.PRO_DIV and material_in.tracking == Material.MA_TRACKING_SINGLE:
pass
else:
m_dict['batch'] = generate_new_batch(mlogbin.batch, mlog)
if mtype == Process.PRO_NORMAL: # 正常 支持批到批, 个到个
if is_fix:# 支持批到批,个到个
d_count_real = mlogbin.count_use-mlogbin.count_pn_jgqbl
d_count_ok = d_count_real
mlogbout, _ = Mlogb.objects.get_or_create(mlogb_from=mlogbin, defaults=update_dict(m_dict,{"count_real": d_count_real, "count_ok": d_count_ok, "count_ok_full": d_count_ok}))
if material_in.tracking == Material.MA_TRACKING_SINGLE and material_out.tracking == Material.MA_TRACKING_SINGLE:
for mlogbwin in Mlogbw.objects.filter(mlogb=mlogbin).order_by("number"):
wpr_ = mlogbwin.wpr
Mlogbw.objects.get_or_create(wpr=wpr_, mlogb=mlogbout, defaults={"number": wpr_.number, "mlogbw_from": mlogbwin})
elif mtype == Process.PRO_NORMAL: # 正常 支持批到批, 个到个
d_count_real = mlogbin.count_use - mlogbin.count_pn_jgqbl
d_count_ok = d_count_real
mlogbout, _ = Mlogb.objects.get_or_create(mlogb_from=mlogbin, defaults=
@ -701,14 +713,6 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust
else:
numberx = f'{number}-{i+1}'
Mlogbw.objects.get_or_create(number=numberx, mlogb=mlogbout)
elif is_fix:# 支持批到批,个到个
d_count_real = mlogbin.count_use-mlogbin.count_pn_jgqbl
d_count_ok = d_count_real
mlogbout, _ = Mlogb.objects.get_or_create(mlogb_from=mlogbin, defaults=update_dict(m_dict,{"count_real": d_count_real, "count_ok": d_count_ok, "count_ok_full": d_count_ok}))
if material_in.tracking == Material.MA_TRACKING_SINGLE and material_out.tracking == Material.MA_TRACKING_SINGLE:
for mlogbwin in Mlogbw.objects.filter(mlogb=mlogbin).order_by("number"):
wpr_ = mlogbwin.wpr
Mlogbw.objects.get_or_create(wpr=wpr_, mlogb=mlogbout, defaults={"number": wpr_.number, "mlogbw_from": mlogbwin})
else:
raise ParseError("不支持生成产出物料!")
mlog.cal_mlog_count_from_mlogb()