From e5ba779b003d6558d755c3ec46cd10ac9eaf69d8 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 17 Jan 2024 15:55:42 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E4=BA=A7=E5=93=81?= =?UTF-8?q?=E6=A3=80=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/qm/admin.py | 4 +- apps/qm/migrations/0012_auto_20240117_1554.py | 60 +++++++++++++++++++ apps/qm/models.py | 28 +++++++-- apps/qm/serializers.py | 28 +++++++-- apps/qm/urls.py | 3 +- apps/qm/views.py | 26 ++++++-- 6 files changed, 134 insertions(+), 15 deletions(-) create mode 100644 apps/qm/migrations/0012_auto_20240117_1554.py diff --git a/apps/qm/admin.py b/apps/qm/admin.py index 5b55e21b..6cefc524 100644 --- a/apps/qm/admin.py +++ b/apps/qm/admin.py @@ -1,7 +1,9 @@ from django.contrib import admin from apps.qm.models import TestItem # Register your models here. + + @admin.register(TestItem) class TestItemAdmin(admin.ModelAdmin): date_hierarchy = 'create_time' - list_display = ('id', 'name') \ No newline at end of file + list_display = ('id', 'name', 'tags') diff --git a/apps/qm/migrations/0012_auto_20240117_1554.py b/apps/qm/migrations/0012_auto_20240117_1554.py new file mode 100644 index 00000000..103da09b --- /dev/null +++ b/apps/qm/migrations/0012_auto_20240117_1554.py @@ -0,0 +1,60 @@ +# Generated by Django 3.2.12 on 2024-01-17 07:54 + +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 = [ + ('mtm', '0025_auto_20231120_1139'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('system', '0003_alter_permission_parent'), + ('qm', '0011_testitem_tags'), + ] + + operations = [ + migrations.AddField( + model_name='ftest', + name='test_numer', + field=models.CharField(default='', max_length=20, verbose_name='检测编号'), + ), + migrations.AddField( + model_name='ftest', + name='type', + field=models.CharField(choices=[('first', '首件检验'), ('prod', '成品检验')], default='first', max_length=20, verbose_name='检验类型'), + preserve_default=False, + ), + migrations.AlterField( + model_name='ftest', + name='check_user', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='ftest_check_user', to=settings.AUTH_USER_MODEL, verbose_name='专检人'), + ), + migrations.CreateModel( + name='FtestWork', + 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='删除标记')), + ('test_date', models.DateField(verbose_name='检验日期')), + ('batch', models.CharField(max_length=20, verbose_name='生产批次')), + ('count', models.IntegerField(verbose_name='总数量')), + ('count_sampling', models.IntegerField(verbose_name='抽检数量')), + ('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='ftestwork_belong_dept', to='system.dept', verbose_name='所属部门')), + ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='ftestwork_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ('material', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='产品')), + ('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='ftestwork_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ], + options={ + 'abstract': False, + }, + ), + migrations.AddField( + model_name='ftest', + name='ftest_work', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='qm.ftestwork', verbose_name='关联检验工作'), + ), + ] diff --git a/apps/qm/models.py b/apps/qm/models.py index 46824e09..aec286a2 100644 --- a/apps/qm/models.py +++ b/apps/qm/models.py @@ -1,5 +1,5 @@ from django.db import models -from apps.system.models import CommonAModel, User +from apps.system.models import CommonAModel, CommonADModel, User from apps.utils.models import CommonBDModel, BaseModel from apps.mtm.models import Material, Mgroup, Team from apps.wpm.models import SfLog @@ -37,18 +37,38 @@ class QuaStat(CommonBDModel): rate_pass = models.FloatField('合格率', null=True, blank=True) -class Ftest(CommonBDModel): +class FtestWork(CommonBDModel): """ - 首件检验 + 检验工作 """ test_date = models.DateField('检验日期') + material = models.ForeignKey( + Material, verbose_name='产品', on_delete=models.CASCADE) + batch = models.CharField('生产批次', max_length=20) + count = models.IntegerField('总数量') + count_sampling = models.IntegerField('抽检数量') + + +class Ftest(CommonBDModel): + """ + 检验记录 + """ + FTEST_TYPE_CHOICES = ( + ('first', '首件检验'), + ('prod', '成品检验') + ) + type = models.CharField('检验类型', max_length=20, choices=FTEST_TYPE_CHOICES) + test_date = models.DateField('检验日期') + test_numer = models.CharField('检测编号', max_length=20, default='') test_group = models.CharField('检验工序集', max_length=20, default='') test_user = models.ForeignKey( User, verbose_name='操作人', on_delete=models.CASCADE, related_name='ftest_test_user') check_user = models.ForeignKey( - User, verbose_name='专检人', on_delete=models.CASCADE, related_name='ftest_check_user') + User, verbose_name='专检人', on_delete=models.CASCADE, related_name='ftest_check_user', null=True, blank=True) is_ok = models.BooleanField('是否合格', default=False) note = models.TextField('备注', default='', blank=True) + ftest_work = models.ForeignKey( + FtestWork, verbose_name='关联检验工作', on_delete=models.CASCADE, null=True, blank=True) @property def ftestitems(self): diff --git a/apps/qm/serializers.py b/apps/qm/serializers.py index 80cee73f..509ca555 100644 --- a/apps/qm/serializers.py +++ b/apps/qm/serializers.py @@ -1,4 +1,4 @@ -from apps.qm.models import QuaStat, TestItem, Ftest, FtestItem, Ptest +from apps.qm.models import QuaStat, TestItem, Ftest, FtestItem, FtestWork, Ptest from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE from apps.utils.serializers import CustomModelSerializer from rest_framework import serializers @@ -58,6 +58,21 @@ class QuaStatUpdateSerializer(CustomModelSerializer): return super().validate(attrs) +class FtestWorkCreateUpdateSerializer(CustomModelSerializer): + class Meta: + model = FtestWork + fields = ['id', 'test_date', 'material', 'batch', 'count'] + + +class FtestWorkSerializer(CustomModelSerializer): + material_name = serializers.StringRelatedField( + source='material', read_only=True) + + class Meta: + model = FtestWork + fields = "__all__" + + class FtestItemSerializer(CustomModelSerializer): testitem_name = serializers.CharField( source='testitem.name', read_only=True) @@ -71,8 +86,6 @@ class FtestItemSerializer(CustomModelSerializer): class FtestSerializer(CustomModelSerializer): - belong_dept = serializers.PrimaryKeyRelatedField( - required=True, queryset=Dept.objects.all()) test_user_name = serializers.CharField( source='test_user.name', read_only=True) check_user_name = serializers.CharField( @@ -82,7 +95,13 @@ class FtestSerializer(CustomModelSerializer): class Meta: model = Ftest fields = '__all__' - read_only_fields = EXCLUDE_FIELDS + read_only_fields = EXCLUDE_FIELDS + ['type'] + + def validate(self, attrs): + ftest_work = attrs.get('ftest_work', None) + if ftest_work: + attrs['type'] = 'prod' # 带检验工作的标记为成品检验 + return attrs def create(self, validated_data): ftestitems = validated_data.pop('ftestitems', []) @@ -93,6 +112,7 @@ class FtestSerializer(CustomModelSerializer): return instance def update(self, instance, validated_data): + validated_data.pop('ftest_work', None) ftestitems = validated_data.pop('ftestitems', []) with transaction.atomic(): instance = super().update(instance, validated_data) diff --git a/apps/qm/urls.py b/apps/qm/urls.py index 1f6d0662..0e0b33a3 100644 --- a/apps/qm/urls.py +++ b/apps/qm/urls.py @@ -1,7 +1,7 @@ from django.urls import path, include from rest_framework.routers import DefaultRouter -from apps.qm.views import QuaStatViewSet, TestItemViewSet, FtestViewSet, PtestViewSet +from apps.qm.views import QuaStatViewSet, TestItemViewSet, FtestWorkViewSet, FtestViewSet, PtestViewSet API_BASE_URL = 'api/qm/' HTML_BASE_URL = 'qm/' @@ -10,6 +10,7 @@ router = DefaultRouter() router.register('quastat', QuaStatViewSet, basename='quastat') router.register('testitem', TestItemViewSet, basename='testitem') router.register('ftest', FtestViewSet, basename='ftest') +router.register('ftestwork', FtestWorkViewSet, basename='ftestwork') router.register('ptest', PtestViewSet, basename='ptest') urlpatterns = [ path(API_BASE_URL, include(router.urls)), diff --git a/apps/qm/views.py b/apps/qm/views.py index c028eedc..264cf9b3 100644 --- a/apps/qm/views.py +++ b/apps/qm/views.py @@ -1,8 +1,9 @@ from django.shortcuts import render from rest_framework.mixins import ListModelMixin, CreateModelMixin, UpdateModelMixin from rest_framework.decorators import action -from apps.qm.models import QuaStat, TestItem, Ftest, Ptest -from apps.qm.serializers import QuaStatSerializer, TestItemSerializer, QuaStatUpdateSerializer, FtestSerializer, PtestSerializer +from apps.qm.models import QuaStat, TestItem, Ftest, Ptest, FtestWork +from apps.qm.serializers import QuaStatSerializer, TestItemSerializer, QuaStatUpdateSerializer, FtestSerializer, PtestSerializer, \ + FtestWorkCreateUpdateSerializer, FtestWorkSerializer from apps.qm.tasks import cal_quastat_sflog from rest_framework.response import Response from apps.utils.mixins import BulkCreateModelMixin, BulkUpdateModelMixin @@ -55,13 +56,14 @@ class QuaStatViewSet(ListModelMixin, BulkUpdateModelMixin, CustomGenericViewSet) class FtestViewSet(CustomModelViewSet): """ - list:首件检验 + list:首件/成品检验 - 首件检验 + 首件/成品检验 """ queryset = Ftest.objects.all() serializer_class = FtestSerializer - select_related_fields = ['test_user', 'check_user'] + select_related_fields = ['test_user', 'check_user', 'ftest_work'] + filterset_fields = ['type', 'ftest_work'] class PtestViewSet(CustomModelViewSet): @@ -74,3 +76,17 @@ class PtestViewSet(CustomModelViewSet): serializer_class = PtestSerializer select_related_fields = ['testitem'] filterset_fields = ['testitem', 'test_date'] + + +class FtestWorkViewSet(CustomModelViewSet): + """ + list: 检验工作 + + 检验工作 + """ + queryset = FtestWork.objects.all() + serializer_class = FtestWorkSerializer + create_serializer_class = FtestWorkCreateUpdateSerializer + update_serializer_class = FtestWorkCreateUpdateSerializer + select_related_fields = ['material'] + filterset_fields = ['material', 'batch']