feat: 增加首件检验

This commit is contained in:
caoqianming 2023-11-02 18:50:26 +08:00
parent b2c201877f
commit 7def29d173
5 changed files with 215 additions and 38 deletions

View File

@ -0,0 +1,60 @@
# Generated by Django 3.2.12 on 2023-11-02 09:58
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 = [
('system', '0002_myschedule'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('qm', '0008_auto_20230725_1112'),
]
operations = [
migrations.CreateModel(
name='Ftest',
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='检验日期')),
('test_group', models.CharField(default='', max_length=20, verbose_name='检验工序集')),
('is_ok', models.BooleanField(default=False, verbose_name='是否合格')),
('note', models.TextField(blank=True, default='', verbose_name='备注')),
('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='ftest_belong_dept', to='system.dept', verbose_name='所属部门')),
('check_user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ftest_check_user', to=settings.AUTH_USER_MODEL, verbose_name='专检人')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='ftest_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('test_user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ftest_test_user', 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='ftest_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
],
options={
'abstract': False,
},
),
migrations.AddField(
model_name='testitem',
name='description',
field=models.TextField(default='', verbose_name='描述'),
),
migrations.CreateModel(
name='FtestItem',
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_val', models.FloatField(blank=True, default=0, verbose_name='测量值')),
('check_val', models.FloatField(blank=True, null=True, verbose_name='专检测量值')),
('ftest', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='qm.ftest', verbose_name='关联检验')),
('testitem', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='qm.testitem', verbose_name='质检项目')),
],
options={
'abstract': False,
},
),
]

View File

@ -1,28 +1,65 @@
from django.db import models
from apps.system.models import CommonAModel
from apps.utils.models import CommonBDModel
from apps.system.models import CommonAModel, User
from apps.utils.models import CommonBDModel, BaseModel
from apps.mtm.models import Material, Mgroup, Team
from apps.wpm.models import SfLog
class TestItem(CommonAModel):
"""
检验项目
"""
name = models.CharField('名称', max_length=100)
sort = models.PositiveSmallIntegerField('排序', default=1)
description = models.TextField('描述', default='')
class Meta:
ordering = ['sort', '-create_time']
# Create your models here.
class QuaStat(CommonBDModel):
"""
质量数据表
"""
material = models.ForeignKey(Material, verbose_name='关联产物', on_delete=models.CASCADE)
sflog = models.ForeignKey(SfLog, verbose_name='关联值班记录', on_delete=models.CASCADE, null=True, blank=True)
testitem = models.ForeignKey(TestItem, verbose_name='质检项目', on_delete=models.CASCADE)
material = models.ForeignKey(
Material, verbose_name='关联产物', on_delete=models.CASCADE)
sflog = models.ForeignKey(
SfLog, verbose_name='关联值班记录', on_delete=models.CASCADE, null=True, blank=True)
testitem = models.ForeignKey(
TestItem, verbose_name='质检项目', on_delete=models.CASCADE)
val_avg = models.FloatField('平均值', null=True, blank=True)
num_test = models.PositiveSmallIntegerField('检测次数', null=True, blank=True)
num_ok = models.PositiveSmallIntegerField('合格次数', null=True, blank=True)
rate_pass = models.FloatField('合格率', null=True, blank=True)
rate_pass = models.FloatField('合格率', null=True, blank=True)
class Ftest(CommonBDModel):
"""
首件检验
"""
test_date = models.DateField('检验日期')
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')
is_ok = models.BooleanField('是否合格', default=False)
note = models.TextField('备注', default='', blank=True)
@property
def ftestitems(self):
return FtestItem.objects.filter(ftest=self)
class FtestItem(BaseModel):
"""
检测明细
"""
ftest = models.ForeignKey(
Ftest, verbose_name='关联检验', on_delete=models.CASCADE)
testitem = models.ForeignKey(
TestItem, verbose_name='质检项目', on_delete=models.CASCADE)
test_val = models.FloatField('测量值', default=0, blank=True)
check_val = models.FloatField('专检测量值', null=True, blank=True)

View File

@ -1,9 +1,11 @@
from apps.qm.models import QuaStat, TestItem
from apps.utils.constants import EXCLUDE_FIELDS
from apps.qm.models import QuaStat, TestItem, Ftest, FtestItem
from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE
from apps.utils.serializers import CustomModelSerializer
from rest_framework import serializers
from apps.system.models import Dept, Dictionary
from apps.wpm.models import SfLog
from django.db import transaction
class TestItemSerializer(CustomModelSerializer):
class Meta:
@ -11,33 +13,94 @@ class TestItemSerializer(CustomModelSerializer):
fields = '__all__'
read_only_fields = EXCLUDE_FIELDS
class QuaStatSerializer(CustomModelSerializer):
sflog = serializers.PrimaryKeyRelatedField(label="值班记录", queryset=SfLog.objects.all(), required=True)
belong_dept_name = serializers.CharField(source='belong_dept.name', read_only=True)
material_name = serializers.CharField(source='material.name', read_only=True)
testitem_name = serializers.CharField(source='testitem.name', read_only=True)
class Meta:
model = QuaStat
fields = '__all__'
read_only_fields = EXCLUDE_FIELDS + ['belong_dept']
extra_kwargs = {'val_avg': {'required': True, 'allow_null': False}, 'num_test':{'required': True, 'allow_null': False}, 'num_ok': {'required': True, 'allow_null': False}}
def validate(self, attrs):
attrs['rate_pass'] = attrs['num_ok']/attrs['num_test']
attrs['belong_dept'] = attrs['sflog'].mgroup.belong_dept
return attrs
class QuaStatUpdateSerializer(CustomModelSerializer):
belong_dept_name = serializers.CharField(source='belong_dept.name', read_only=True)
material_name = serializers.CharField(source='material.name', read_only=True)
testitem_name = serializers.CharField(source='testitem.name', read_only=True)
sflog = serializers.PrimaryKeyRelatedField(
label="值班记录", queryset=SfLog.objects.all(), required=True)
belong_dept_name = serializers.CharField(
source='belong_dept.name', read_only=True)
material_name = serializers.CharField(
source='material.name', read_only=True)
testitem_name = serializers.CharField(
source='testitem.name', read_only=True)
class Meta:
model = QuaStat
fields = '__all__'
read_only_fields = EXCLUDE_FIELDS + ['belong_dept', 'sflog', 'material', 'testitem']
extra_kwargs = {'val_avg': {'required': True, 'allow_null': False}, 'num_test':{'required': True, 'allow_null': False}, 'num_ok': {'required': True, 'allow_null': False}}
read_only_fields = EXCLUDE_FIELDS + ['belong_dept']
extra_kwargs = {'val_avg': {'required': True, 'allow_null': False}, 'num_test': {
'required': True, 'allow_null': False}, 'num_ok': {'required': True, 'allow_null': False}}
def validate(self, attrs):
attrs['rate_pass'] = attrs['num_ok']/attrs['num_test']
return super().validate(attrs)
attrs['belong_dept'] = attrs['sflog'].mgroup.belong_dept
return attrs
class QuaStatUpdateSerializer(CustomModelSerializer):
belong_dept_name = serializers.CharField(
source='belong_dept.name', read_only=True)
material_name = serializers.CharField(
source='material.name', read_only=True)
testitem_name = serializers.CharField(
source='testitem.name', read_only=True)
class Meta:
model = QuaStat
fields = '__all__'
read_only_fields = EXCLUDE_FIELDS + \
['belong_dept', 'sflog', 'material', 'testitem']
extra_kwargs = {'val_avg': {'required': True, 'allow_null': False}, 'num_test': {
'required': True, 'allow_null': False}, 'num_ok': {'required': True, 'allow_null': False}}
def validate(self, attrs):
attrs['rate_pass'] = attrs['num_ok']/attrs['num_test']
return super().validate(attrs)
class FtestItemSerializer(CustomModelSerializer):
testitem_name = serializers.CharField(
source='testitem.name', read_only=True)
testitem_description = serializers.CharField(
source='testitem.description', read_only=True)
class Meta:
model = FtestItem
fields = '__all__'
read_only_fields = EXCLUDE_FIELDS_BASE
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(
source='check_user.name', read_only=True)
ftestitems = FtestItemSerializer(label='检验明细', many=True)
class Meta:
model = Ftest
fields = '__all__'
read_only_fields = EXCLUDE_FIELDS
def create(self, validated_data):
ftestitems = validated_data.pop('ftestitems', [])
with transaction.atomic():
instance = super().create(validated_data)
for item in ftestitems:
FtestItem.objects.create(ftest=instance, **item)
return instance
def update(self, instance, validated_data):
ftestitems = validated_data.pop('ftestitems', [])
with transaction.atomic():
instance = super().update(instance, validated_data)
for item in ftestitems:
id = item.get('id', None)
if id:
ftestitem = FtestItem.objects.get(id=id)
ftestitem.test_val = item['test_val']
ftestitem.check_val = item['check_val']
ftestitem.save()
return instance

View File

@ -1,7 +1,7 @@
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from apps.qm.views import QuaStatViewSet, TestItemViewSet
from apps.qm.views import QuaStatViewSet, TestItemViewSet, FtestViewSet
API_BASE_URL = 'api/qm/'
HTML_BASE_URL = 'qm/'
@ -9,6 +9,8 @@ HTML_BASE_URL = 'qm/'
router = DefaultRouter()
router.register('quastat', QuaStatViewSet, basename='quastat')
router.register('testitem', TestItemViewSet, basename='testitem')
router.register('ftest', FtestViewSet, basename='Ftest')
urlpatterns = [
path(API_BASE_URL, include(router.urls)),
]
]

View File

@ -1,17 +1,19 @@
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
from apps.qm.serializers import QuaStatSerializer, TestItemSerializer, QuaStatUpdateSerializer
from apps.qm.models import QuaStat, TestItem, Ftest
from apps.qm.serializers import QuaStatSerializer, TestItemSerializer, QuaStatUpdateSerializer, FtestSerializer
from apps.qm.tasks import cal_quastat_sflog
from rest_framework.response import Response
from apps.utils.mixins import BulkCreateModelMixin, BulkUpdateModelMixin
import datetime
from apps.utils.viewsets import CustomGenericViewSet
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
from apps.wpm.models import SfLog
from apps.qm.filters import QuaStatFilter
# Create your views here.
class TestItemViewSet(ListModelMixin, CustomGenericViewSet):
"""
list:质检项目
@ -24,6 +26,7 @@ class TestItemViewSet(ListModelMixin, CustomGenericViewSet):
filterset_fields = []
ordering = ['id']
class QuaStatViewSet(ListModelMixin, BulkUpdateModelMixin, CustomGenericViewSet):
"""
list:质量数据统计
@ -44,6 +47,18 @@ class QuaStatViewSet(ListModelMixin, BulkUpdateModelMixin, CustomGenericViewSet)
for i in objs:
sflogIds.append(i['sflog'])
sflogIds = list(set(sflogIds))
SfLog.objects.filter(id__in=sflogIds).update(last_test_time=now) # 更新质检记录时间
SfLog.objects.filter(id__in=sflogIds).update(
last_test_time=now) # 更新质检记录时间
for sflogId in sflogIds:
cal_quastat_sflog.delay(sflogId)
cal_quastat_sflog.delay(sflogId)
class FtestViewSet(CustomModelViewSet):
"""
list:首件检验
首件检验
"""
queryset = Ftest.objects.all()
serializer_class = FtestSerializer
select_related_fields = ['test_user', 'check_user']