feat: 用于返修的mlog

This commit is contained in:
caoqianming 2025-02-24 09:39:05 +08:00
parent af999467db
commit 0c5cc55b54
4 changed files with 48 additions and 23 deletions

View File

@ -0,0 +1,23 @@
# Generated by Django 3.2.12 on 2025-02-24 01:38
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('wpm', '0087_auto_20250212_1158'),
]
operations = [
migrations.AddField(
model_name='mlog',
name='is_fix',
field=models.BooleanField(default=False, verbose_name='是否用于返修'),
),
migrations.AlterField(
model_name='wmaterial',
name='state',
field=models.PositiveSmallIntegerField(choices=[(10, '合格'), (20, '不合格'), (30, '返修'), (32, '返修完成'), (40, '检验'), (50, '报废')], default=10, verbose_name='状态'),
),
]

View File

@ -108,7 +108,7 @@ class WMaterial(CommonBDModel):
WM_REPAIR = 30
WM_TEST = 40
WM_SCRAP = 50
state = models.PositiveSmallIntegerField('状态', default=10, choices=((10, '合格'), (20, '不合格'), (30, '返修'), (40, '检验'), (50, '报废')))
state = models.PositiveSmallIntegerField('状态', default=10, choices=((10, '合格'), (20, '不合格'), (30, '返修'), (32, '返修完成'), (40, '检验'), (50, '报废')))
material = models.ForeignKey(
Material, verbose_name='物料', on_delete=models.CASCADE, related_name='wm_m')
supplier = models.ForeignKey(Supplier, verbose_name='外协供应商', on_delete=models.SET_NULL, null=True, blank=True)
@ -144,7 +144,7 @@ class WMaterial(CommonBDModel):
material_out=mtask.material_in
).values_list('batch', flat=True)
),
state__in=[WMaterial.WM_OK, WMaterial.WM_REPAIR]
state__in=[WMaterial.WM_OK]
)
class Fmlog(CommonADModel):
@ -168,6 +168,7 @@ class Mlog(CommonADModel):
mtaskb = models.ForeignKey(Mtaskb, verbose_name='关联个人任务', on_delete=models.CASCADE, related_name='mlog_mtaskb', null=True, blank=True)
fill_way = models.PositiveSmallIntegerField("填写方式", default=10, help_text='10:仅二级;20:二三级;30:一二级')
mtype = models.PositiveSmallIntegerField('生产类型', default=10, help_text='10:自生产;20:外协生产', choices=((10, '自生产'), (20, '外协生产')))
is_fix = models.BooleanField('是否用于返修', default=False)
supplier = models.ForeignKey(Supplier, verbose_name='外协供应商', on_delete=models.SET_NULL, null=True, blank=True)
work_start_time = models.DateTimeField('生产开始时间', null=True, blank=True)
work_end_time = models.DateTimeField('生产结束时间', null=True, blank=True)

View File

@ -1,7 +1,7 @@
from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE
from apps.utils.serializers import CustomModelSerializer
from rest_framework import serializers
from rest_framework.exceptions import ValidationError, ParseError
from rest_framework.exceptions import ParseError
from datetime import datetime
from .models import (SfLog, StLog, SfLogExp, WMaterial, Mlog,
@ -321,7 +321,7 @@ class MlogSerializer(CustomModelSerializer):
mlogbx.material_ofrom = wm_in.material_ofrom
mlogbx.save(update_fields=["batch_ofrom", "material_ofrom"])
else:
raise ValidationError('缺少产出物信息')
raise ParseError('缺少产出物信息')
else:
# 生成产出物
batch_out = validated_data.get('batch', None)
@ -434,10 +434,10 @@ class MlogSerializer(CustomModelSerializer):
raise ParseError('子任务不能为空')
if mtaskb and mtaskb.mtask != fmlog.mtask:
raise ParseError('子任务不一致')
if wm_in.state in [WMaterial.WM_OK, WMaterial.WM_REPAIR]:
if wm_in.state in [WMaterial.WM_OK]:
pass
else:
raise ValidationError('非合格/返修品不可使用')
raise ParseError('非合格品不可使用')
if wm_in.material != attrs['mtask'].material_in:
raise ParseError('消耗物料与任务不一致')
mtask = attrs.get('mtask', None)
@ -449,7 +449,7 @@ class MlogSerializer(CustomModelSerializer):
if attrs['count_real'] >= attrs['count_ok'] + attrs['count_notok']:
pass
else:
raise ValidationError('生产数量不能小于合格数量')
raise ParseError('生产数量不能小于合格数量')
if mtask:
if mtask.start_date == mtask.end_date:
attrs['handle_date'] = mtask.start_date
@ -474,7 +474,7 @@ class MlogSerializer(CustomModelSerializer):
mgroup = attrs['mgroup']
material_out = attrs['material_out']
if not (mgroup and material_out):
raise ValidationError('缺少工段或产物!')
raise ParseError('缺少工段或产物!')
handle_user = attrs.get('handle_user', None)
if handle_user is None and hasattr(self, "request"):
handle_user = self.request.user
@ -537,16 +537,16 @@ class MlogbInSerializer(CustomModelSerializer):
mlog: Mlog = attrs['mlog']
mtask: Mtask = attrs.get("mtask", None)
if mtask and mtask.state != Mtask.MTASK_ASSGINED:
raise ValidationError('该任务非下达中不可选择')
raise ParseError('该任务非下达中不可选择')
wm_in: WMaterial = attrs['wm_in']
if wm_in is None:
raise ParseError("请选择相应车间库存!")
if wm_in.state in [WMaterial.WM_OK, WMaterial.WM_REPAIR]:
pass
else:
raise ValidationError('非合格/返修品不可使用')
raise ParseError('非合格/返修品不可使用')
if mtask and mlog.route != mtask.route:
raise ValidationError('工序不匹配')
raise ParseError('工序不匹配')
route = mlog.route
attrs['material_in'] = wm_in.material
attrs['batch'] = wm_in.batch
@ -554,13 +554,13 @@ class MlogbInSerializer(CustomModelSerializer):
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('该车间库存非本任务使用')
raise ParseError('该车间库存非本任务使用')
return attrs
def create(self, validated_data):
mlog: Mlog = validated_data['mlog']
if Mlogb.objects.filter(mlog=mlog, mtask=validated_data['mtask'], wm_in=validated_data['wm_in'], parent=None).exists():
raise ValidationError('该记录已存在')
raise ParseError('该记录已存在')
if mlog.submit_time is not None:
raise ParseError('生产日志已提交不可编辑')
return super().create(validated_data)
@ -568,7 +568,7 @@ class MlogbInSerializer(CustomModelSerializer):
def update(self, instance, validated_data):
mlog: Mlog = instance.mlog
if Mlogb.objects.filter(mlog=mlog, mtask=validated_data['mtask'], wm_in=validated_data['wm_in'], parent=None).exclude(id=instance.id).exists():
raise ValidationError('该记录已存在')
raise ParseError('该记录已存在')
if mlog.submit_time is not None:
raise ParseError('生产日志已提交不可编辑')
return super().update(instance, validated_data)
@ -651,7 +651,7 @@ class MlogbOutUpdateSerializer(CustomModelSerializer):
count = item['count']
full_notok = f'count_n_{notok}'
if not hasattr(Mlogb, full_notok):
raise ValidationError(f'{notok}-该不合格项不存在')
raise ParseError(f'{notok}-该不合格项不存在')
if full_notok in count_notok_dict:
count_notok_dict[full_notok] = count_notok_dict[full_notok] + count
else:
@ -663,13 +663,13 @@ class MlogbOutUpdateSerializer(CustomModelSerializer):
for i in attrs:
if 'count_n_' in i:
if not hasattr(Mlogb, i):
raise ValidationError(f'{i}不存在')
raise ParseError(f'{i}不存在')
count_notok = count_notok + attrs[i]
attrs['count_notok'] = count_notok
if attrs['count_real'] >= attrs['count_ok'] + attrs['count_notok']:
pass
else:
raise ValidationError('生产数量不能小于合格数量')
raise ParseError('生产数量不能小于合格数量')
return attrs
class MlogRevertSerializer(serializers.Serializer):
@ -744,13 +744,13 @@ class HandoverSerializer(CustomModelSerializer):
if wm.mgroup:
attrs['send_mgroup'] = wm.mgroup
if attrs['material'].process and attrs['material'].process.into_wm_mgroup and 'recive_mgroup' not in attrs:
raise ValidationError('必须指定交接工段')
raise ParseError('必须指定交接工段')
if 'recive_mgroup' in attrs and attrs['recive_mgroup']:
attrs['recive_dept'] = attrs['recive_mgroup'].belong_dept
if 'recive_dept' not in attrs and 'recive_mgroup' not in attrs:
raise ValidationError('收料车间和收料工段必须有一个')
raise ParseError('收料车间和收料工段必须有一个')
if 'send_dept' not in attrs and 'send_mgroup' not in attrs:
raise ValidationError('送料车间和送料工段必须有一个')
raise ParseError('送料车间和送料工段必须有一个')
t_count = 0
for ind, item in enumerate(attrs['handoverb']):
wm = item["wm"]
@ -767,10 +767,10 @@ class HandoverSerializer(CustomModelSerializer):
raise ParseError(f'{ind+1}物料检验中,不能进行交接')
attrs["count"] = t_count
if attrs['type'] == Handover.H_REPAIR:
# 返修时还是该物料
recive_mgroup = attrs.get("recive_mgroup", None)
if recive_mgroup is None:
raise ParseError('返工交接需指定工段')
attrs['material_changed'] = find_material_can_change(attrs['material'], recive_mgroup)
return attrs
class Meta:
@ -881,7 +881,7 @@ class GenHandoverWmSerializer(serializers.Serializer):
def validate(self, attrs):
if attrs['count'] <= 1:
raise ValidationError('交送数量必须大于1')
raise ParseError('交送数量必须大于1')
return attrs

View File

@ -684,10 +684,11 @@ def handover_submit(handover:Handover, user: User, now: Union[datetime.datetime,
}
)
elif handover.type == Handover.H_REPAIR:
# 返修交接
if handover.recive_mgroup:
wm_to, _ = WMaterial.objects.get_or_create(
batch=batch,
material=handover.material_changed,
material=material,
mgroup=recive_mgroup,
belong_dept=recive_dept,
notok_sign=wm_from.notok_sign,