feat: 用于返修的mlog
This commit is contained in:
parent
af999467db
commit
0c5cc55b54
|
@ -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='状态'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -108,7 +108,7 @@ class WMaterial(CommonBDModel):
|
||||||
WM_REPAIR = 30
|
WM_REPAIR = 30
|
||||||
WM_TEST = 40
|
WM_TEST = 40
|
||||||
WM_SCRAP = 50
|
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 = models.ForeignKey(
|
||||||
Material, verbose_name='物料', on_delete=models.CASCADE, related_name='wm_m')
|
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)
|
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
|
material_out=mtask.material_in
|
||||||
).values_list('batch', flat=True)
|
).values_list('batch', flat=True)
|
||||||
),
|
),
|
||||||
state__in=[WMaterial.WM_OK, WMaterial.WM_REPAIR]
|
state__in=[WMaterial.WM_OK]
|
||||||
)
|
)
|
||||||
|
|
||||||
class Fmlog(CommonADModel):
|
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)
|
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:一二级')
|
fill_way = models.PositiveSmallIntegerField("填写方式", default=10, help_text='10:仅二级;20:二三级;30:一二级')
|
||||||
mtype = models.PositiveSmallIntegerField('生产类型', default=10, help_text='10:自生产;20:外协生产', choices=((10, '自生产'), (20, '外协生产')))
|
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)
|
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_start_time = models.DateTimeField('生产开始时间', null=True, blank=True)
|
||||||
work_end_time = models.DateTimeField('生产结束时间', null=True, blank=True)
|
work_end_time = models.DateTimeField('生产结束时间', null=True, blank=True)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE
|
from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE
|
||||||
from apps.utils.serializers import CustomModelSerializer
|
from apps.utils.serializers import CustomModelSerializer
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from rest_framework.exceptions import ValidationError, ParseError
|
from rest_framework.exceptions import ParseError
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from .models import (SfLog, StLog, SfLogExp, WMaterial, Mlog,
|
from .models import (SfLog, StLog, SfLogExp, WMaterial, Mlog,
|
||||||
|
@ -321,7 +321,7 @@ class MlogSerializer(CustomModelSerializer):
|
||||||
mlogbx.material_ofrom = wm_in.material_ofrom
|
mlogbx.material_ofrom = wm_in.material_ofrom
|
||||||
mlogbx.save(update_fields=["batch_ofrom", "material_ofrom"])
|
mlogbx.save(update_fields=["batch_ofrom", "material_ofrom"])
|
||||||
else:
|
else:
|
||||||
raise ValidationError('缺少产出物信息')
|
raise ParseError('缺少产出物信息')
|
||||||
else:
|
else:
|
||||||
# 生成产出物
|
# 生成产出物
|
||||||
batch_out = validated_data.get('batch', None)
|
batch_out = validated_data.get('batch', None)
|
||||||
|
@ -434,10 +434,10 @@ class MlogSerializer(CustomModelSerializer):
|
||||||
raise ParseError('子任务不能为空')
|
raise ParseError('子任务不能为空')
|
||||||
if mtaskb and mtaskb.mtask != fmlog.mtask:
|
if mtaskb and mtaskb.mtask != fmlog.mtask:
|
||||||
raise ParseError('子任务不一致')
|
raise ParseError('子任务不一致')
|
||||||
if wm_in.state in [WMaterial.WM_OK, WMaterial.WM_REPAIR]:
|
if wm_in.state in [WMaterial.WM_OK]:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
raise ValidationError('非合格/返修品不可使用')
|
raise ParseError('非合格品不可使用')
|
||||||
if wm_in.material != attrs['mtask'].material_in:
|
if wm_in.material != attrs['mtask'].material_in:
|
||||||
raise ParseError('消耗物料与任务不一致')
|
raise ParseError('消耗物料与任务不一致')
|
||||||
mtask = attrs.get('mtask', None)
|
mtask = attrs.get('mtask', None)
|
||||||
|
@ -449,7 +449,7 @@ class MlogSerializer(CustomModelSerializer):
|
||||||
if attrs['count_real'] >= attrs['count_ok'] + attrs['count_notok']:
|
if attrs['count_real'] >= attrs['count_ok'] + attrs['count_notok']:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
raise ValidationError('生产数量不能小于合格数量')
|
raise ParseError('生产数量不能小于合格数量')
|
||||||
if mtask:
|
if mtask:
|
||||||
if mtask.start_date == mtask.end_date:
|
if mtask.start_date == mtask.end_date:
|
||||||
attrs['handle_date'] = mtask.start_date
|
attrs['handle_date'] = mtask.start_date
|
||||||
|
@ -474,7 +474,7 @@ class MlogSerializer(CustomModelSerializer):
|
||||||
mgroup = attrs['mgroup']
|
mgroup = attrs['mgroup']
|
||||||
material_out = attrs['material_out']
|
material_out = attrs['material_out']
|
||||||
if not (mgroup and material_out):
|
if not (mgroup and material_out):
|
||||||
raise ValidationError('缺少工段或产物!')
|
raise ParseError('缺少工段或产物!')
|
||||||
handle_user = attrs.get('handle_user', None)
|
handle_user = attrs.get('handle_user', None)
|
||||||
if handle_user is None and hasattr(self, "request"):
|
if handle_user is None and hasattr(self, "request"):
|
||||||
handle_user = self.request.user
|
handle_user = self.request.user
|
||||||
|
@ -537,16 +537,16 @@ class MlogbInSerializer(CustomModelSerializer):
|
||||||
mlog: Mlog = attrs['mlog']
|
mlog: Mlog = attrs['mlog']
|
||||||
mtask: Mtask = attrs.get("mtask", None)
|
mtask: Mtask = attrs.get("mtask", None)
|
||||||
if mtask and mtask.state != Mtask.MTASK_ASSGINED:
|
if mtask and mtask.state != Mtask.MTASK_ASSGINED:
|
||||||
raise ValidationError('该任务非下达中不可选择')
|
raise ParseError('该任务非下达中不可选择')
|
||||||
wm_in: WMaterial = attrs['wm_in']
|
wm_in: WMaterial = attrs['wm_in']
|
||||||
if wm_in is None:
|
if wm_in is None:
|
||||||
raise ParseError("请选择相应车间库存!")
|
raise ParseError("请选择相应车间库存!")
|
||||||
if wm_in.state in [WMaterial.WM_OK, WMaterial.WM_REPAIR]:
|
if wm_in.state in [WMaterial.WM_OK, WMaterial.WM_REPAIR]:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
raise ValidationError('非合格/返修品不可使用')
|
raise ParseError('非合格/返修品不可使用')
|
||||||
if mtask and mlog.route != mtask.route:
|
if mtask and mlog.route != mtask.route:
|
||||||
raise ValidationError('工序不匹配')
|
raise ParseError('工序不匹配')
|
||||||
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
|
||||||
|
@ -554,13 +554,13 @@ class MlogbInSerializer(CustomModelSerializer):
|
||||||
attrs["material_ofrom"] = wm_in.material_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 ParseError('该车间库存非本任务使用')
|
||||||
return attrs
|
return attrs
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
mlog: Mlog = validated_data['mlog']
|
mlog: Mlog = validated_data['mlog']
|
||||||
if Mlogb.objects.filter(mlog=mlog, mtask=validated_data['mtask'], wm_in=validated_data['wm_in'], parent=None).exists():
|
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:
|
if mlog.submit_time is not None:
|
||||||
raise ParseError('生产日志已提交不可编辑')
|
raise ParseError('生产日志已提交不可编辑')
|
||||||
return super().create(validated_data)
|
return super().create(validated_data)
|
||||||
|
@ -568,7 +568,7 @@ class MlogbInSerializer(CustomModelSerializer):
|
||||||
def update(self, instance, validated_data):
|
def update(self, instance, validated_data):
|
||||||
mlog: Mlog = instance.mlog
|
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():
|
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:
|
if mlog.submit_time is not None:
|
||||||
raise ParseError('生产日志已提交不可编辑')
|
raise ParseError('生产日志已提交不可编辑')
|
||||||
return super().update(instance, validated_data)
|
return super().update(instance, validated_data)
|
||||||
|
@ -651,7 +651,7 @@ class MlogbOutUpdateSerializer(CustomModelSerializer):
|
||||||
count = item['count']
|
count = item['count']
|
||||||
full_notok = f'count_n_{notok}'
|
full_notok = f'count_n_{notok}'
|
||||||
if not hasattr(Mlogb, full_notok):
|
if not hasattr(Mlogb, full_notok):
|
||||||
raise ValidationError(f'{notok}-该不合格项不存在')
|
raise ParseError(f'{notok}-该不合格项不存在')
|
||||||
if full_notok in count_notok_dict:
|
if full_notok in count_notok_dict:
|
||||||
count_notok_dict[full_notok] = count_notok_dict[full_notok] + count
|
count_notok_dict[full_notok] = count_notok_dict[full_notok] + count
|
||||||
else:
|
else:
|
||||||
|
@ -663,13 +663,13 @@ class MlogbOutUpdateSerializer(CustomModelSerializer):
|
||||||
for i in attrs:
|
for i in attrs:
|
||||||
if 'count_n_' in i:
|
if 'count_n_' in i:
|
||||||
if not hasattr(Mlogb, i):
|
if not hasattr(Mlogb, i):
|
||||||
raise ValidationError(f'{i}不存在')
|
raise ParseError(f'{i}不存在')
|
||||||
count_notok = count_notok + attrs[i]
|
count_notok = count_notok + attrs[i]
|
||||||
attrs['count_notok'] = count_notok
|
attrs['count_notok'] = count_notok
|
||||||
if attrs['count_real'] >= attrs['count_ok'] + attrs['count_notok']:
|
if attrs['count_real'] >= attrs['count_ok'] + attrs['count_notok']:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
raise ValidationError('生产数量不能小于合格数量')
|
raise ParseError('生产数量不能小于合格数量')
|
||||||
return attrs
|
return attrs
|
||||||
|
|
||||||
class MlogRevertSerializer(serializers.Serializer):
|
class MlogRevertSerializer(serializers.Serializer):
|
||||||
|
@ -744,13 +744,13 @@ class HandoverSerializer(CustomModelSerializer):
|
||||||
if wm.mgroup:
|
if wm.mgroup:
|
||||||
attrs['send_mgroup'] = wm.mgroup
|
attrs['send_mgroup'] = wm.mgroup
|
||||||
if attrs['material'].process and attrs['material'].process.into_wm_mgroup and 'recive_mgroup' not in attrs:
|
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']:
|
if 'recive_mgroup' in attrs and attrs['recive_mgroup']:
|
||||||
attrs['recive_dept'] = attrs['recive_mgroup'].belong_dept
|
attrs['recive_dept'] = attrs['recive_mgroup'].belong_dept
|
||||||
if 'recive_dept' not in attrs and 'recive_mgroup' not in attrs:
|
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:
|
if 'send_dept' not in attrs and 'send_mgroup' not in attrs:
|
||||||
raise ValidationError('送料车间和送料工段必须有一个')
|
raise ParseError('送料车间和送料工段必须有一个')
|
||||||
t_count = 0
|
t_count = 0
|
||||||
for ind, item in enumerate(attrs['handoverb']):
|
for ind, item in enumerate(attrs['handoverb']):
|
||||||
wm = item["wm"]
|
wm = item["wm"]
|
||||||
|
@ -767,10 +767,10 @@ class HandoverSerializer(CustomModelSerializer):
|
||||||
raise ParseError(f'第{ind+1}物料检验中,不能进行交接')
|
raise ParseError(f'第{ind+1}物料检验中,不能进行交接')
|
||||||
attrs["count"] = t_count
|
attrs["count"] = t_count
|
||||||
if attrs['type'] == Handover.H_REPAIR:
|
if attrs['type'] == Handover.H_REPAIR:
|
||||||
|
# 返修时还是该物料
|
||||||
recive_mgroup = attrs.get("recive_mgroup", None)
|
recive_mgroup = attrs.get("recive_mgroup", None)
|
||||||
if recive_mgroup is None:
|
if recive_mgroup is None:
|
||||||
raise ParseError('返工交接需指定工段')
|
raise ParseError('返工交接需指定工段')
|
||||||
attrs['material_changed'] = find_material_can_change(attrs['material'], recive_mgroup)
|
|
||||||
return attrs
|
return attrs
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -881,7 +881,7 @@ class GenHandoverWmSerializer(serializers.Serializer):
|
||||||
|
|
||||||
def validate(self, attrs):
|
def validate(self, attrs):
|
||||||
if attrs['count'] <= 1:
|
if attrs['count'] <= 1:
|
||||||
raise ValidationError('交送数量必须大于1')
|
raise ParseError('交送数量必须大于1')
|
||||||
return attrs
|
return attrs
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -684,10 +684,11 @@ def handover_submit(handover:Handover, user: User, now: Union[datetime.datetime,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
elif handover.type == Handover.H_REPAIR:
|
elif handover.type == Handover.H_REPAIR:
|
||||||
|
# 返修交接
|
||||||
if handover.recive_mgroup:
|
if handover.recive_mgroup:
|
||||||
wm_to, _ = WMaterial.objects.get_or_create(
|
wm_to, _ = WMaterial.objects.get_or_create(
|
||||||
batch=batch,
|
batch=batch,
|
||||||
material=handover.material_changed,
|
material=material,
|
||||||
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,
|
||||||
|
|
Loading…
Reference in New Issue