From 9a14216b781053927e6c51caaed35f9b0a11566a Mon Sep 17 00:00:00 2001 From: caoqianming Date: Tue, 17 Dec 2024 09:42:11 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20qm=E5=A2=9E=E5=8A=A0defect?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/qm/migrations/0028_defect.py | 35 +++++++++++++++++++++++++++++++ apps/qm/models.py | 20 ++++++++++++++++-- apps/qm/serializers.py | 8 +++++-- apps/qm/urls.py | 5 ++++- apps/qm/views.py | 27 +++++++++++++++++++----- 5 files changed, 85 insertions(+), 10 deletions(-) create mode 100644 apps/qm/migrations/0028_defect.py diff --git a/apps/qm/migrations/0028_defect.py b/apps/qm/migrations/0028_defect.py new file mode 100644 index 00000000..0ae84cd7 --- /dev/null +++ b/apps/qm/migrations/0028_defect.py @@ -0,0 +1,35 @@ +# Generated by Django 3.2.12 on 2024-12-17 01:38 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('qm', '0027_ftestwork_ticket'), + ] + + operations = [ + migrations.CreateModel( + name='Defect', + fields=[ + ('id', models.CharField(editable=False, help_text='主键ID', max_length=20, primary_key=True, serialize=False, verbose_name='主键ID')), + ('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')), + ('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')), + ('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')), + ('name', models.CharField(max_length=50, verbose_name='名称')), + ('code', models.CharField(max_length=50, verbose_name='标识')), + ('cate', models.CharField(choices=[('尺寸', '尺寸'), ('外观', '外观'), ('内质', '内质')], max_length=50, verbose_name='分类')), + ('okcate', models.PositiveSmallIntegerField(choices=[(10, '合格'), (20, '合格B类'), (30, '不合格')], default=30, verbose_name='不合格分类')), + ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='defect_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='defect_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/apps/qm/models.py b/apps/qm/models.py index 7be55065..931f183c 100644 --- a/apps/qm/models.py +++ b/apps/qm/models.py @@ -1,11 +1,26 @@ from django.db import models -from apps.system.models import CommonAModel, CommonADModel, User +from apps.system.models import CommonAModel, User from apps.utils.models import CommonBDModel, BaseModel -from apps.mtm.models import Material, Mgroup, Team, Shift +from apps.mtm.models import Material, Shift from apps.em.models import Equipment from apps.wpm.models import SfLog, WMaterial from django.utils.translation import gettext_lazy as _ +class Defect(CommonAModel): + # 缺陷项 + DEFECT_OK = 10 + DEFECT_OK_B = 20 + DEFECT_NOTOK = 30 + name = models.CharField(max_length=50, verbose_name="名称") + code = models.CharField(max_length=50, verbose_name="标识") + cate = models.CharField(max_length=50, verbose_name="分类", choices=(("尺寸", "尺寸"), ("外观", "外观"), ("内质", "内质"))) + okcate= models.PositiveSmallIntegerField(verbose_name="不合格分类", + choices=((DEFECT_OK, "合格"), (DEFECT_OK_B, "合格B类"), (DEFECT_NOTOK, "不合格")), + default=DEFECT_NOTOK) + + def __str__(self): + return self.name + class NotOkOption(models.TextChoices): # 不合格项 zw = "zw", _("炸纹") @@ -85,6 +100,7 @@ FTEST_TYPE_CHOICES = ( ('process', '过程检验'), ('prod', '成品检验') ) + class TestItem(CommonAModel): """ 检测项目 diff --git a/apps/qm/serializers.py b/apps/qm/serializers.py index 877ea786..e83b1903 100644 --- a/apps/qm/serializers.py +++ b/apps/qm/serializers.py @@ -1,13 +1,17 @@ -from apps.qm.models import QuaStat, TestItem, Ftest, FtestItem, FtestWork, Ptest, NotOkOption +from apps.qm.models import QuaStat, TestItem, Ftest, FtestItem, FtestWork, Ptest, NotOkOption, Defect 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 -from apps.system.models import Dept, Dictionary from apps.wpm.models import SfLog, WMaterial from django.db import transaction from apps.inm.serializers import MaterialBatchDetailSerializer +class DefectSerializer(CustomModelSerializer): + class Meta: + model = Defect + fields = '__all__' + read_only_fields = EXCLUDE_FIELDS class TestItemSerializer(CustomModelSerializer): class Meta: diff --git a/apps/qm/urls.py b/apps/qm/urls.py index ed5608c3..a0f5c777 100644 --- a/apps/qm/urls.py +++ b/apps/qm/urls.py @@ -1,7 +1,9 @@ from django.urls import path, include from rest_framework.routers import DefaultRouter -from apps.qm.views import QuaStatViewSet, TestItemViewSet, FtestWorkViewSet, FtestViewSet, PtestViewSet, NotOkOptionView +from apps.qm.views import (QuaStatViewSet, TestItemViewSet, + FtestWorkViewSet, FtestViewSet, PtestViewSet, + NotOkOptionView, DefectViewSet) API_BASE_URL = 'api/qm/' HTML_BASE_URL = 'qm/' @@ -12,6 +14,7 @@ router.register('testitem', TestItemViewSet, basename='testitem') router.register('ftest', FtestViewSet, basename='ftest') router.register('ftestwork', FtestWorkViewSet, basename='ftestwork') router.register('ptest', PtestViewSet, basename='ptest') +router.register("defect", DefectViewSet, basename="defect") urlpatterns = [ path(API_BASE_URL, include(router.urls)), path(API_BASE_URL + 'notok_option/', NotOkOptionView.as_view()), diff --git a/apps/qm/views.py b/apps/qm/views.py index 89370725..fa803a8c 100644 --- a/apps/qm/views.py +++ b/apps/qm/views.py @@ -1,27 +1,38 @@ -from django.shortcuts import render -from rest_framework.mixins import ListModelMixin, CreateModelMixin, UpdateModelMixin +from rest_framework.mixins import ListModelMixin from rest_framework.decorators import action from rest_framework.exceptions import ParseError from rest_framework.views import APIView from rest_framework.serializers import Serializer from apps.qm.models import QuaStat, TestItem, Ftest, Ptest, FtestWork from apps.qm.serializers import QuaStatSerializer, TestItemSerializer, QuaStatUpdateSerializer, FtestSerializer, PtestSerializer, \ - FtestWorkCreateUpdateSerializer, FtestWorkSerializer + FtestWorkCreateUpdateSerializer, FtestWorkSerializer, DefectSerializer from apps.qm.tasks import cal_quastat_sflog from rest_framework.response import Response -from apps.utils.mixins import BulkCreateModelMixin, BulkUpdateModelMixin +from apps.utils.mixins import BulkUpdateModelMixin import datetime from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet from apps.wpm.models import SfLog from apps.qm.filters import QuaStatFilter, TestItemFilter, FtestWorkFilter from django.db import transaction -from apps.qm.models import NotOkOption +from apps.qm.models import NotOkOption, Defect from apps.qm.services import ftestwork_submit from apps.utils.thread import MyThread from apps.wpm.services_2 import get_alldata_with_batch_and_store +from apps.wf.models import State # Create your views here. +class DefectViewSet(CustomModelViewSet): + """ + list:缺陷项 + + 缺陷项 + """ + queryset = Defect.objects.all() + serializer_class = DefectSerializer + filterset_fields = ["cate", "okcate"] + search_fields = ["name", "code"] + class NotOkOptionView(APIView): perms_map = {'get': '*'} @@ -146,6 +157,8 @@ class FtestWorkViewSet(CustomModelViewSet): ins:FtestWork = self.get_object() if ins.submit_time is not None: raise ParseError('已提交无法修改') + if ins.ticket and ins.ticket.state.type != State.STATE_TYPE_START: + raise ParseError('审批单已进行,无法修改') x = super().update(request, *args, **kwargs) # 触发批次统计分析 if ins.batch: @@ -156,6 +169,8 @@ class FtestWorkViewSet(CustomModelViewSet): ins:FtestWork = self.get_object() if ins.submit_time is not None: raise ParseError('已提交无法删除') + if ins.ticket: + raise ParseError('存在审批, 无法删除') x = super().destroy(request, *args, **kwargs) # 触发批次统计分析 if ins.batch: @@ -177,6 +192,8 @@ class FtestWorkViewSet(CustomModelViewSet): 提交检验工作 """ ins:FtestWork = self.get_object() + if ins.ticket: + raise ParseError('该检验工作存在审批!') if ins.wm is None: raise ParseError('该检验工作未关联车间库存') if ins.submit_time is None: