This commit is contained in:
zty 2024-08-12 16:04:57 +08:00
commit 7664dfefa4
9 changed files with 237 additions and 6 deletions

View File

@ -0,0 +1,42 @@
# Generated by Django 3.2.12 on 2024-08-12 02:48
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('wpm', '0050_auto_20240701_0936'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('qm', '0017_alter_testitem_field_type'),
]
operations = [
migrations.AddField(
model_name='ftestwork',
name='count_notok_json',
field=models.JSONField(blank=True, default=dict, verbose_name='不合格项数量统计'),
),
migrations.AddField(
model_name='ftestwork',
name='submit_time',
field=models.DateTimeField(blank=True, null=True, verbose_name='提交时间'),
),
migrations.AddField(
model_name='ftestwork',
name='submit_user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='提交人'),
),
migrations.AddField(
model_name='ftestwork',
name='wm',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='wpm.wmaterial', verbose_name='关联车间库存'),
),
migrations.AlterField(
model_name='ftestwork',
name='count',
field=models.IntegerField(verbose_name='检验数量'),
),
]

View File

@ -2,7 +2,7 @@ from django.db import models
from apps.system.models import CommonAModel, CommonADModel, User from apps.system.models import CommonAModel, CommonADModel, User
from apps.utils.models import CommonBDModel, BaseModel from apps.utils.models import CommonBDModel, BaseModel
from apps.mtm.models import Material, Mgroup, Team from apps.mtm.models import Material, Mgroup, Team
from apps.wpm.models import SfLog from apps.wpm.models import SfLog, WMaterial
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
class NotOkOption(models.TextChoices): class NotOkOption(models.TextChoices):
@ -38,6 +38,19 @@ class NotOkOption(models.TextChoices):
md = "md", _("麻点") md = "md", _("麻点")
xh = "xh", _("线痕") xh = "xh", _("线痕")
b = "b", _("") b = "b", _("")
zb = "zb", _("棕边")
hqbx = "hqbx", _("黑圈变形")
dj = "dj", _("倒角")
ps = "ps", _("破损")
lq = "lq", _("蓝圈")
hqnj = "hqnj", _("黑圈内径")
hqnjyd = "hqnjyd", _("黑圈内径圆度")
hqwj = "hqwj", _("黑圈外径")
hqwjyd = "hqwjyd", _("黑圈外径圆度")
wj = "cpwj", _("外径")
yd = "cpyd", _("圆度")
txd = "cptxd", _("同心度")
hd = "hq", _("厚度")
wz = "wz", _("未知") wz = "wz", _("未知")
@ -90,14 +103,18 @@ class FtestWork(CommonBDModel):
""" """
type = models.CharField('检验类型', max_length=20, choices=FTEST_TYPE_CHOICES, default='prod') type = models.CharField('检验类型', max_length=20, choices=FTEST_TYPE_CHOICES, default='prod')
type2 = models.PositiveSmallIntegerField('检验类型2', choices=((10, '抽检'), (20, '全检')), default=10) type2 = models.PositiveSmallIntegerField('检验类型2', choices=((10, '抽检'), (20, '全检')), default=10)
wm = models.ForeignKey(WMaterial, verbose_name='关联车间库存', on_delete=models.SET_NULL, null=True, blank=True)
test_date = models.DateField('检验日期') test_date = models.DateField('检验日期')
material = models.ForeignKey( material = models.ForeignKey(
Material, verbose_name='产品', on_delete=models.CASCADE) Material, verbose_name='产品', on_delete=models.CASCADE)
batch = models.CharField('生产批次', max_length=20) batch = models.CharField('生产批次', max_length=20)
count = models.IntegerField('数量') count = models.IntegerField('检验数量')
count_sampling = models.IntegerField('抽检数量', default=0) count_sampling = models.IntegerField('抽检数量', default=0)
count_ok = models.IntegerField('合格数量', default=0) count_ok = models.IntegerField('合格数量', default=0)
count_notok = models.IntegerField('不合格数量', default=0) count_notok = models.IntegerField('不合格数量', default=0)
count_notok_json = models.JSONField('不合格项数量统计', default=dict, null=False, blank=True)
submit_time = models.DateTimeField('提交时间', null=True, blank=True)
submit_user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='提交人', null=True, blank=True)
class Ftest(CommonBDModel): class Ftest(CommonBDModel):

View File

@ -1,9 +1,10 @@
from apps.qm.models import QuaStat, TestItem, Ftest, FtestItem, FtestWork, Ptest from apps.qm.models import QuaStat, TestItem, Ftest, FtestItem, FtestWork, Ptest, NotOkOption
from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE
from apps.utils.serializers import CustomModelSerializer from apps.utils.serializers import CustomModelSerializer
from rest_framework import serializers from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from apps.system.models import Dept, Dictionary from apps.system.models import Dept, Dictionary
from apps.wpm.models import SfLog from apps.wpm.models import SfLog, WMaterial
from django.db import transaction from django.db import transaction
@ -61,7 +62,29 @@ class QuaStatUpdateSerializer(CustomModelSerializer):
class FtestWorkCreateUpdateSerializer(CustomModelSerializer): class FtestWorkCreateUpdateSerializer(CustomModelSerializer):
class Meta: class Meta:
model = FtestWork model = FtestWork
fields = ['id', 'test_date', 'material', 'batch', 'count', 'count_sampling', 'count_ok', 'count_notok'] fields = ['id', 'wm', 'test_date', 'count', 'count_sampling', 'count_ok', 'count_notok', 'count_notok_json']
def validate(self, attrs):
if 'wm' not in attrs:
raise ValidationError('请选择车间库存')
wm:WMaterial = attrs['wm']
attrs['material'] = wm.material
attrs['batch'] = wm.batch
count_notok_json = attrs.get('count_notok_json', None)
if count_notok_json is None:
raise ValidationError('不合格项不能为Null')
count_notok = 0
for k, v in count_notok_json.items():
k_2 = k.replace('count_n_', '')
if k not in NotOkOption.values():
raise ValidationError(f'不支持的不合格项{k_2}')
if isinstance(v, int) and v >= 0:
count_notok = count_notok + v
else:
raise ValidationError(f'不合格项{k_2}必须为非负整数')
attrs['count_notok'] = count_notok
return attrs
class FtestWorkSerializer(CustomModelSerializer): class FtestWorkSerializer(CustomModelSerializer):
material_name = serializers.StringRelatedField( material_name = serializers.StringRelatedField(

42
apps/qm/services.py Normal file
View File

@ -0,0 +1,42 @@
from apps.qm.models import FtestWork
from apps.wpm.models import WMaterial
from apps.system.models import User
from rest_framework.exceptions import ParseError
from django.utils import timezone
def ftestwork_submit(ins:FtestWork, user: User):
wm:WMaterial = ins.wm
# 更新对应的车间库存
wm.count = wm.count - ins.count_notok
if wm.count >= 0:
# 已检测的数量
wm.count_xtest = wm.count_xtest + ins.count
wm.save()
else:
raise ParseError("车间库存不足")
# 生成合格的
count_ok = ins.count_ok
if count_ok > 0:
wm_ok = WMaterial()
wm_ok.material = wm.material
wm_ok.count = count_ok
wm_ok.batch = wm.batch
wm_ok.mgroup = wm.mgroup
wm_ok.belong_dept = wm.belong_dept
wm_ok.save()
# 生成不合格的
count_notok_json = ins.count_notok_json
for k, v in count_notok_json.items():
if v > 0:
wm_n = WMaterial()
wm_n.material = wm.material
wm_n.count = v
wm_n.batch = wm.batch
wm_n.mgroup = wm.mgroup
wm_n.belong_dept = wm.belong_dept
wm_n.notok_sign = k.replace('count_n_', '')
wm_n.save()
ins.submit_user = user
ins.submit_time = timezone.now()
ins.save()

View File

@ -1,7 +1,9 @@
from django.shortcuts import render from django.shortcuts import render
from rest_framework.mixins import ListModelMixin, CreateModelMixin, UpdateModelMixin from rest_framework.mixins import ListModelMixin, CreateModelMixin, UpdateModelMixin
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.exceptions import ParseError
from rest_framework.views import APIView 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.models import QuaStat, TestItem, Ftest, Ptest, FtestWork
from apps.qm.serializers import QuaStatSerializer, TestItemSerializer, QuaStatUpdateSerializer, FtestSerializer, PtestSerializer, \ from apps.qm.serializers import QuaStatSerializer, TestItemSerializer, QuaStatUpdateSerializer, FtestSerializer, PtestSerializer, \
FtestWorkCreateUpdateSerializer, FtestWorkSerializer FtestWorkCreateUpdateSerializer, FtestWorkSerializer
@ -15,6 +17,7 @@ from apps.wpm.models import SfLog
from apps.qm.filters import QuaStatFilter, TestItemFilter from apps.qm.filters import QuaStatFilter, TestItemFilter
from django.db import transaction from django.db import transaction
from apps.qm.models import NotOkOption from apps.qm.models import NotOkOption
from apps.qm.services import ftestwork_submit
# Create your views here. # Create your views here.
class NotOkOptionView(APIView): class NotOkOptionView(APIView):
@ -124,3 +127,27 @@ class FtestWorkViewSet(CustomModelViewSet):
update_serializer_class = FtestWorkCreateUpdateSerializer update_serializer_class = FtestWorkCreateUpdateSerializer
select_related_fields = ['material'] select_related_fields = ['material']
filterset_fields = ['material', 'batch'] filterset_fields = ['material', 'batch']
def update(self, request, *args, **kwargs):
ins:FtestWork = self.get_object()
if ins.submit_time is not None:
raise ParseError('已提交无法修改')
return super().update(request, *args, **kwargs)
def destroy(self, request, *args, **kwargs):
ins:FtestWork = self.get_object()
if ins.submit_time is not None:
raise ParseError('已提交无法删除')
return super().destroy(request, *args, **kwargs)
@action(methods=['post'], detail=True, perms_map={'post': 'ftestwork.submit'}, serializer_class=Serializer)
@transaction.atomic
def submit(self, request, *args, **kwargs):
"""提交检验工作
提交检验工作
"""
ins:FtestWork = self.get_object()
if ins.submit_time is not None:
ftestwork_submit(ins, request.user)
return Response()

View File

@ -48,7 +48,8 @@ class WMaterialFilter(filters.FilterSet):
"mgroup": ["exact", "in", "isnull"], "mgroup": ["exact", "in", "isnull"],
"mgroup__name": ["exact", "in"], "mgroup__name": ["exact", "in"],
"count": ["gte", "lte", "exact"], "count": ["gte", "lte", "exact"],
"notok_sign": ["exact", "in", "isnull"] "notok_sign": ["exact", "in", "isnull"],
"count_xtest": ["gte", "isnull"]
} }
class MlogFilter(filters.FilterSet): class MlogFilter(filters.FilterSet):
@ -86,12 +87,15 @@ class HandoverFilter(filters.FilterSet):
"recive_dept__name": ["exact"], "recive_dept__name": ["exact"],
"send_date": ["exact"], "send_date": ["exact"],
"material__type": ["exact", "in"], "material__type": ["exact", "in"],
"material__process": ["exact", "in"],
"material__process__name": ["exact", "contains", "in"],
"submit_time": ["isnull"], "submit_time": ["isnull"],
"mlog": ["isnull"], "mlog": ["isnull"],
"send_mgroup": ["exact"], "send_mgroup": ["exact"],
"send_mgroup__name": ["exact"], "send_mgroup__name": ["exact"],
"recive_mgroup": ["exact"], "recive_mgroup": ["exact"],
"recive_mgroup__name": ["exact"], "recive_mgroup__name": ["exact"],
"type": ["exact", "in"],
} }

View File

@ -0,0 +1,63 @@
# Generated by Django 3.2.12 on 2024-08-12 02:48
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('wpm', '0059_auto_20240809_1508'),
]
operations = [
migrations.AddField(
model_name='mlog',
name='count_n_hd',
field=models.PositiveIntegerField(default=0, verbose_name='厚度'),
),
migrations.AddField(
model_name='mlog',
name='count_n_ps',
field=models.PositiveIntegerField(default=0, verbose_name='破损'),
),
migrations.AddField(
model_name='mlog',
name='count_n_txd',
field=models.PositiveIntegerField(default=0, verbose_name='同心度'),
),
migrations.AddField(
model_name='mlog',
name='count_n_wj',
field=models.PositiveIntegerField(default=0, verbose_name='外经'),
),
migrations.AddField(
model_name='mlog',
name='count_n_yd',
field=models.PositiveIntegerField(default=0, verbose_name='圆度'),
),
migrations.AddField(
model_name='mlogb',
name='count_n_hd',
field=models.PositiveIntegerField(default=0, verbose_name='厚度'),
),
migrations.AddField(
model_name='mlogb',
name='count_n_ps',
field=models.PositiveIntegerField(default=0, verbose_name='破损'),
),
migrations.AddField(
model_name='mlogb',
name='count_n_txd',
field=models.PositiveIntegerField(default=0, verbose_name='同心度'),
),
migrations.AddField(
model_name='mlogb',
name='count_n_wj',
field=models.PositiveIntegerField(default=0, verbose_name='外经'),
),
migrations.AddField(
model_name='mlogb',
name='count_n_yd',
field=models.PositiveIntegerField(default=0, verbose_name='圆度'),
),
]

View File

@ -179,7 +179,13 @@ class Mlog(CommonADModel):
count_n_wm = models.PositiveIntegerField('雾面', default=0) count_n_wm = models.PositiveIntegerField('雾面', default=0)
count_n_md = models.PositiveIntegerField('麻点', default=0) count_n_md = models.PositiveIntegerField('麻点', default=0)
count_n_xh = models.PositiveIntegerField('线痕', default=0) count_n_xh = models.PositiveIntegerField('线痕', default=0)
count_n_ps = models.PositiveIntegerField('破损', default=0)
count_n_wj = models.PositiveIntegerField('外经', default=0)
count_n_yd = models.PositiveIntegerField('圆度', default=0)
count_n_txd = models.PositiveIntegerField('同心度', default=0)
count_n_hd = models.PositiveIntegerField('厚度', default=0)
count_n_qt = models.PositiveIntegerField('其他', default=0) count_n_qt = models.PositiveIntegerField('其他', default=0)
handle_date = models.DateField('操作日期', null=True, blank=True) handle_date = models.DateField('操作日期', null=True, blank=True)
@ -240,6 +246,11 @@ class Mlogb(BaseModel):
count_n_wm = models.PositiveIntegerField('雾面', default=0) count_n_wm = models.PositiveIntegerField('雾面', default=0)
count_n_md = models.PositiveIntegerField('麻点', default=0) count_n_md = models.PositiveIntegerField('麻点', default=0)
count_n_xh = models.PositiveIntegerField('线痕', default=0) count_n_xh = models.PositiveIntegerField('线痕', default=0)
count_n_ps = models.PositiveIntegerField('破损', default=0)
count_n_wj = models.PositiveIntegerField('外经', default=0)
count_n_yd = models.PositiveIntegerField('圆度', default=0)
count_n_txd = models.PositiveIntegerField('同心度', default=0)
count_n_hd = models.PositiveIntegerField('厚度', default=0)
class Handover(CommonADModel): class Handover(CommonADModel):
""" """

View File

@ -472,6 +472,8 @@ class HandoverSerializer(CustomModelSerializer):
raise ValidationError('送料车间和送料工段必须有一个') raise ValidationError('送料车间和送料工段必须有一个')
if wm.notok_sign is not None and attrs['type'] in [Handover.H_NORMAL, Handover.H_TEST]: if wm.notok_sign is not None and attrs['type'] in [Handover.H_NORMAL, Handover.H_TEST]:
raise ValidationError('物料不合格,不能进行正常/检验交接') raise ValidationError('物料不合格,不能进行正常/检验交接')
if wm.count_xtest is not None:
raise ValidationError('物料检验中,不能进行交接')
return attrs return attrs
class Meta: class Meta: