From 0c5cc55b549b9b983030491bf55fb3c59c1ef8cc Mon Sep 17 00:00:00 2001 From: caoqianming Date: Mon, 24 Feb 2025 09:39:05 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=94=A8=E4=BA=8E=E8=BF=94=E4=BF=AE?= =?UTF-8?q?=E7=9A=84mlog?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wpm/migrations/0088_auto_20250224_0938.py | 23 +++++++++++ apps/wpm/models.py | 5 ++- apps/wpm/serializers.py | 40 +++++++++---------- apps/wpm/services.py | 3 +- 4 files changed, 48 insertions(+), 23 deletions(-) create mode 100644 apps/wpm/migrations/0088_auto_20250224_0938.py diff --git a/apps/wpm/migrations/0088_auto_20250224_0938.py b/apps/wpm/migrations/0088_auto_20250224_0938.py new file mode 100644 index 00000000..8df074ac --- /dev/null +++ b/apps/wpm/migrations/0088_auto_20250224_0938.py @@ -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='状态'), + ), + ] diff --git a/apps/wpm/models.py b/apps/wpm/models.py index ffe485a1..4d2de745 100644 --- a/apps/wpm/models.py +++ b/apps/wpm/models.py @@ -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) diff --git a/apps/wpm/serializers.py b/apps/wpm/serializers.py index e914e925..6c88d994 100644 --- a/apps/wpm/serializers.py +++ b/apps/wpm/serializers.py @@ -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 diff --git a/apps/wpm/services.py b/apps/wpm/services.py index 2979be13..5ca47106 100644 --- a/apps/wpm/services.py +++ b/apps/wpm/services.py @@ -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,