feat: 值班记录质量分析数据录入
This commit is contained in:
parent
07a8e5977f
commit
0145beb63f
|
@ -0,0 +1,27 @@
|
||||||
|
# Generated by Django 3.2.12 on 2023-06-26 07:59
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('mtm', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='material',
|
||||||
|
name='qitems',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='material',
|
||||||
|
name='testitems',
|
||||||
|
field=models.JSONField(blank=True, default=list, verbose_name='检测项目'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='material',
|
||||||
|
name='type',
|
||||||
|
field=models.PositiveSmallIntegerField(choices=[(0, '电/水/气'), (10, '成品'), (20, '半成品'), (30, '主要原料'), (40, '辅助材料'), (50, '加工工具'), (60, '辅助工装')], default=1, help_text="((0, '电/水/气'), (10, '成品'), (20, '半成品'), (30, '主要原料'), (40, '辅助材料'), (50, '加工工具'), (60, '辅助工装'))", verbose_name='物料类型'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -3,13 +3,16 @@ from apps.system.models import CommonAModel, Dictionary, CommonBModel, CommonADM
|
||||||
|
|
||||||
# Create your models here.
|
# Create your models here.
|
||||||
class Material(CommonAModel):
|
class Material(CommonAModel):
|
||||||
|
MA_TYPE_BASE = 0
|
||||||
MA_TYPE_GOOD = 10
|
MA_TYPE_GOOD = 10
|
||||||
MA_TYPE_HALFGOOD = 20
|
MA_TYPE_HALFGOOD = 20
|
||||||
MA_TYPE_MAINSO = 30
|
MA_TYPE_MAINSO = 30
|
||||||
MA_TYPE_HELPSO = 40
|
MA_TYPE_HELPSO = 40
|
||||||
MA_TYPE_TOOL = 50
|
MA_TYPE_TOOL = 50
|
||||||
MA_TYPE_HELPTOOL = 60
|
MA_TYPE_HELPTOOL = 60
|
||||||
|
|
||||||
type_choices=(
|
type_choices=(
|
||||||
|
(MA_TYPE_BASE, '电/水/气'),
|
||||||
(MA_TYPE_GOOD, '成品'),
|
(MA_TYPE_GOOD, '成品'),
|
||||||
(MA_TYPE_HALFGOOD, '半成品'),
|
(MA_TYPE_HALFGOOD, '半成品'),
|
||||||
(MA_TYPE_MAINSO, '主要原料'),
|
(MA_TYPE_MAINSO, '主要原料'),
|
||||||
|
@ -20,7 +23,7 @@ class Material(CommonAModel):
|
||||||
name = models.CharField('名称', max_length=50)
|
name = models.CharField('名称', max_length=50)
|
||||||
code = models.CharField('标识', max_length=50, null=True, blank=True)
|
code = models.CharField('标识', max_length=50, null=True, blank=True)
|
||||||
type = models.PositiveSmallIntegerField('物料类型', choices= type_choices, default=1, help_text=str(type_choices))
|
type = models.PositiveSmallIntegerField('物料类型', choices= type_choices, default=1, help_text=str(type_choices))
|
||||||
qitems = models.ManyToManyField(Dictionary, verbose_name='质检项目', blank=True)
|
testitems = models.JSONField('检测项目', default=list, blank=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = '物料表'
|
verbose_name = '物料表'
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
# Generated by Django 3.2.12 on 2023-06-26 07:59
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('wpm', '0002_auto_20230625_1709'),
|
||||||
|
('qm', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='quastat',
|
||||||
|
old_name='product',
|
||||||
|
new_name='material',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='quastat',
|
||||||
|
name='sflog',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='wpm.sflog', verbose_name='关联值班记录'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='quastat',
|
||||||
|
name='num_ok',
|
||||||
|
field=models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='合格次数'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='quastat',
|
||||||
|
name='num_test',
|
||||||
|
field=models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='检测次数'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='quastat',
|
||||||
|
name='type',
|
||||||
|
field=models.CharField(default='day', help_text='year/month/day/sflog', max_length=50, verbose_name='统计维度'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='quastat',
|
||||||
|
name='val_avg',
|
||||||
|
field=models.FloatField(blank=True, null=True, verbose_name='平均值'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='quastat',
|
||||||
|
name='year',
|
||||||
|
field=models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='年'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -2,6 +2,7 @@ from django.db import models
|
||||||
from apps.system.models import CommonAModel
|
from apps.system.models import CommonAModel
|
||||||
from apps.utils.models import CommonBDModel
|
from apps.utils.models import CommonBDModel
|
||||||
from apps.mtm.models import Material
|
from apps.mtm.models import Material
|
||||||
|
from apps.wpm.models import SfLog
|
||||||
|
|
||||||
class TestItem(CommonAModel):
|
class TestItem(CommonAModel):
|
||||||
"""
|
"""
|
||||||
|
@ -14,13 +15,14 @@ class QuaStat(CommonBDModel):
|
||||||
"""
|
"""
|
||||||
质量数据统计表 需要有belong_dept
|
质量数据统计表 需要有belong_dept
|
||||||
"""
|
"""
|
||||||
type = models.CharField('统计维度', max_length=50, default='day', help_text='year/month/day')
|
type = models.CharField('统计维度', max_length=50, default='day', help_text='year/month/day/sflog')
|
||||||
year = models.PositiveSmallIntegerField('年')
|
year = models.PositiveSmallIntegerField('年', null=True, blank=True)
|
||||||
month = models.PositiveSmallIntegerField('月', null=True, blank=True)
|
month = models.PositiveSmallIntegerField('月', null=True, blank=True)
|
||||||
day = models.PositiveSmallIntegerField('日', null=True, blank=True)
|
day = models.PositiveSmallIntegerField('日', null=True, blank=True)
|
||||||
product = models.ForeignKey(Material, 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)
|
testitem = models.ForeignKey(TestItem, verbose_name='质检项目', on_delete=models.CASCADE)
|
||||||
val_avg = models.FloatField('平均值')
|
val_avg = models.FloatField('平均值', null=True, blank=True)
|
||||||
num_test = models.PositiveSmallIntegerField('检测次数')
|
num_test = models.PositiveSmallIntegerField('检测次数', null=True, blank=True)
|
||||||
num_ok = models.PositiveSmallIntegerField('合格次数')
|
num_ok = models.PositiveSmallIntegerField('合格次数', null=True, blank=True)
|
||||||
rate_pass = models.FloatField('合格率')
|
rate_pass = models.FloatField('合格率')
|
|
@ -3,6 +3,7 @@ from apps.utils.constants import EXCLUDE_FIELDS
|
||||||
from apps.utils.serializers import CustomModelSerializer
|
from apps.utils.serializers import CustomModelSerializer
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from apps.system.models import Dept, Dictionary
|
from apps.system.models import Dept, Dictionary
|
||||||
|
from apps.wpm.models import SfLog
|
||||||
|
|
||||||
class TestItemSerializer(CustomModelSerializer):
|
class TestItemSerializer(CustomModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -16,9 +17,22 @@ class QuaStatSerializer(CustomModelSerializer):
|
||||||
day = serializers.IntegerField(label='天', required=True)
|
day = serializers.IntegerField(label='天', required=True)
|
||||||
belong_dept = serializers.PrimaryKeyRelatedField(label="所属部门", queryset=Dept.objects.all(), required=True)
|
belong_dept = serializers.PrimaryKeyRelatedField(label="所属部门", queryset=Dept.objects.all(), required=True)
|
||||||
belong_dept_name = serializers.CharField(source='belong_dept.name', read_only=True)
|
belong_dept_name = serializers.CharField(source='belong_dept.name', read_only=True)
|
||||||
product_name = serializers.CharField(source='product.name', read_only=True)
|
material_name = serializers.CharField(source='material.name', read_only=True)
|
||||||
qitem_name = serializers.CharField(source='qitem.name', read_only=True)
|
testitem_name = serializers.CharField(source='testitem.name', read_only=True)
|
||||||
class Meta:
|
class Meta:
|
||||||
model = QuaStat
|
model = QuaStat
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
read_only_fields = EXCLUDE_FIELDS + ['type', 'rate_pass']
|
read_only_fields = EXCLUDE_FIELDS + ['type', 'rate_pass']
|
||||||
|
extra_kwargs = {'val_avg': {'required': True}, 'num_test':{'required': True}, 'num_ok': {'required': True}}
|
||||||
|
|
||||||
|
|
||||||
|
class QuaStatSfLogSerializer(CustomModelSerializer):
|
||||||
|
sflog = serializers.PrimaryKeyRelatedField(label="值班记录", queryset=SfLog.objects.all(), required=True)
|
||||||
|
class Meta:
|
||||||
|
model = QuaStat
|
||||||
|
fields = '__all__'
|
||||||
|
read_only_fields = EXCLUDE_FIELDS + ['type', 'year', 'month', 'day']
|
||||||
|
|
||||||
|
def validate(self, attrs):
|
||||||
|
attrs['type'] = 'sflog'
|
||||||
|
return attrs
|
|
@ -1,13 +1,14 @@
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from rest_framework.routers import DefaultRouter
|
from rest_framework.routers import DefaultRouter
|
||||||
|
|
||||||
from apps.qm.views import QuaStatViewSet, TestItemViewSet
|
from apps.qm.views import QuaStatViewSet, TestItemViewSet, QuaStatSfLogViewSet
|
||||||
|
|
||||||
API_BASE_URL = 'api/qm/'
|
API_BASE_URL = 'api/qm/'
|
||||||
HTML_BASE_URL = 'qm/'
|
HTML_BASE_URL = 'qm/'
|
||||||
|
|
||||||
router = DefaultRouter()
|
router = DefaultRouter()
|
||||||
router.register('quastat', QuaStatViewSet, basename='quastat')
|
router.register('quastat', QuaStatViewSet, basename='quastat')
|
||||||
|
router.register('quastat_sflog', QuaStatSfLogViewSet, basename='quastat_sflog')
|
||||||
router.register('testitem', TestItemViewSet, basename='testitem')
|
router.register('testitem', TestItemViewSet, basename='testitem')
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path(API_BASE_URL, include(router.urls)),
|
path(API_BASE_URL, include(router.urls)),
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from rest_framework.mixins import ListModelMixin, CreateModelMixin
|
from rest_framework.mixins import ListModelMixin, CreateModelMixin
|
||||||
|
from rest_framework.decorators import action
|
||||||
from apps.qm.models import QuaStat, TestItem
|
from apps.qm.models import QuaStat, TestItem
|
||||||
from apps.qm.serializers import QuaStatSerializer, TestItemSerializer
|
from apps.qm.serializers import QuaStatSerializer, TestItemSerializer, QuaStatSfLogSerializer
|
||||||
from apps.qm.tasks import cal_quastat
|
from apps.qm.tasks import cal_quastat
|
||||||
|
from rest_framework.response import Response
|
||||||
|
|
||||||
from apps.utils.viewsets import CustomGenericViewSet
|
from apps.utils.viewsets import CustomGenericViewSet
|
||||||
|
|
||||||
|
@ -26,7 +28,7 @@ class QuaStatViewSet(ListModelMixin, CreateModelMixin, CustomGenericViewSet):
|
||||||
"""
|
"""
|
||||||
queryset = QuaStat.objects.all()
|
queryset = QuaStat.objects.all()
|
||||||
serializer_class = QuaStatSerializer
|
serializer_class = QuaStatSerializer
|
||||||
filterset_fields = ['type', 'year', 'month', 'day', 'product', 'testitem', 'belong_dept']
|
filterset_fields = ['type', 'year', 'month', 'day', 'product', 'testitem', 'belong_dept', 'sflog']
|
||||||
select_related_fields = ['belong_dept', 'product', 'testitem']
|
select_related_fields = ['belong_dept', 'product', 'testitem']
|
||||||
|
|
||||||
def perform_create(self, serializer):
|
def perform_create(self, serializer):
|
||||||
|
@ -35,3 +37,13 @@ class QuaStatViewSet(ListModelMixin, CreateModelMixin, CustomGenericViewSet):
|
||||||
ins.save()
|
ins.save()
|
||||||
# 计算月和年的统计
|
# 计算月和年的统计
|
||||||
cal_quastat.delay(ins.id)
|
cal_quastat.delay(ins.id)
|
||||||
|
|
||||||
|
|
||||||
|
class QuaStatSfLogViewSet(CreateModelMixin, CustomGenericViewSet):
|
||||||
|
"""
|
||||||
|
值班-质量分析
|
||||||
|
|
||||||
|
值班-质量分析
|
||||||
|
"""
|
||||||
|
queryset = QuaStat.objects.all()
|
||||||
|
serializer_class = QuaStatSfLogSerializer
|
|
@ -42,11 +42,3 @@ class StSfLogSerializer(CustomModelSerializer):
|
||||||
model = StSfLog
|
model = StSfLog
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
read_only_fields = EXCLUDE_FIELDS + ['stlog', 'sflog', 'is_current_down']
|
read_only_fields = EXCLUDE_FIELDS + ['stlog', 'sflog', 'is_current_down']
|
||||||
|
|
||||||
class QItemDataSerializer(serializers.Serializer):
|
|
||||||
qitem = serializers.PrimaryKeyRelatedField(label='检测项目', queryset=Dictionary.objects.filter(type__code='qitem'))
|
|
||||||
val = serializers.FloatField(label='值')
|
|
||||||
|
|
||||||
|
|
||||||
class SfLogQuaSerializer(serializers.Serializer):
|
|
||||||
qua_data = QItemDataSerializer(many=True)
|
|
|
@ -7,7 +7,7 @@ from rest_framework.exceptions import ParseError
|
||||||
|
|
||||||
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
|
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
|
||||||
from apps.wpm.models import SfLog, StLog, StSfLog
|
from apps.wpm.models import SfLog, StLog, StSfLog
|
||||||
from apps.wpm.serializers import SfLogQuaSerializer, SfLogSerializer, StLogSerializer, StSfLogSerializer
|
from apps.wpm.serializers import SfLogSerializer, StLogSerializer, StSfLogSerializer
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
class StLogViewSet(ListModelMixin, CustomGenericViewSet):
|
class StLogViewSet(ListModelMixin, CustomGenericViewSet):
|
||||||
|
@ -49,25 +49,9 @@ class SfLogViewSet(CustomModelViewSet):
|
||||||
if stsflog:
|
if stsflog:
|
||||||
stsflog.is_current_down = True
|
stsflog.is_current_down = True
|
||||||
stsflog.save()
|
stsflog.save()
|
||||||
|
# 计算能耗
|
||||||
@action(methods=['put'], detail=True, perms_map={'put': 'sflogqua.update'}, serializer_class=SfLogQuaSerializer)
|
from apps.enm.tasks import cal_sflog_en_val
|
||||||
def qua_data(self, request, pk=None):
|
cal_sflog_en_val.delay(ins.id)
|
||||||
"""
|
|
||||||
质量数据录入
|
|
||||||
|
|
||||||
质量数据录入
|
|
||||||
"""
|
|
||||||
sflog = self.get_object()
|
|
||||||
sr = SfLogQuaSerializer(data=request.data)
|
|
||||||
sr.is_valid(raise_exception=True)
|
|
||||||
vdata = sr.validated_data
|
|
||||||
qua_data = vdata['qua_data']
|
|
||||||
qua_data_new = []
|
|
||||||
for i in qua_data:
|
|
||||||
qua_data_new.append({'qitem': i['qitem'].id, 'qitem_name': i['qitem'].name, 'val': i['val']})
|
|
||||||
sflog.qua_data = qua_data_new
|
|
||||||
sflog.save()
|
|
||||||
return Response()
|
|
||||||
|
|
||||||
class StSfLogViewSet(ListModelMixin, UpdateModelMixin, CustomGenericViewSet):
|
class StSfLogViewSet(ListModelMixin, UpdateModelMixin, CustomGenericViewSet):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue