修改提交检测记录路由

This commit is contained in:
caoqianming 2021-11-11 14:08:28 +08:00
parent 206df9c85c
commit 9236200cf3
10 changed files with 237 additions and 63 deletions

View File

@ -1,6 +1,7 @@
from rest_framework import serializers
from apps.inm.models import FIFO, FIFOItem, IProduct, MaterialBatch, WareHouse,Inventory
from apps.qm.models import TestRecord, TestRecordItem
from apps.system.serializers import UserSimpleSerializer
from apps.mtm.serializers import MaterialSimpleSerializer
@ -119,3 +120,16 @@ class FIFOInPurSerializer(serializers.ModelSerializer):
FIFOItem.objects.create(**i)
return obj
class InmTestRecordItemCreateSerializer(serializers.ModelSerializer):
class Meta:
model = TestRecordItem
fields = ['form_field', 'field_value', 'is_testok']
class InmTestRecordCreateSerializer(serializers.ModelSerializer):
record_data = InmTestRecordItemCreateSerializer(many=True)
fifo_item = serializers.PrimaryKeyRelatedField(queryset=FIFOItem.objects.all(), required=True)
class Meta:
model = TestRecord
fields = ['form', 'record_data', 'is_testok', 'fifo_item']

View File

@ -9,7 +9,7 @@ router.register('warehouse', WarehouseViewSet, basename='warehouse')
router.register('inventory', InventoryViewSet, basename='inventory')
router.register('materialbatch', MaterialBatchViewSet, basename='materialbatch')
router.register('fifo', FIFOViewSet, basename='fifo'),
router.register('fifodetail', FIFOItemViewSet, basename='fifodetail')
router.register('fifoitem', FIFOItemViewSet, basename='fifoitem')
urlpatterns = [
path('', include(router.urls)),
]

View File

@ -6,8 +6,9 @@ from rest_framework.viewsets import GenericViewSet, ModelViewSet
from apps.inm.filters import MbFilterSet
from apps.inm.models import FIFO, FIFOItem, MaterialBatch, WareHouse,Inventory
from apps.inm.serializers import FIFOItemSerializer, FIFOInPurSerializer, FIFOListSerializer, MaterialBatchQuerySerializer, MaterialBatchSerializer, WareHouseSerializer, WareHouseCreateUpdateSerializer,InventorySerializer
from apps.inm.serializers import FIFOItemSerializer, FIFOInPurSerializer, FIFOListSerializer, InmTestRecordCreateSerializer, MaterialBatchQuerySerializer, MaterialBatchSerializer, WareHouseSerializer, WareHouseCreateUpdateSerializer,InventorySerializer
from apps.inm.signals import update_inm
from apps.qm.models import TestRecordItem
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
from rest_framework.decorators import action
from rest_framework.response import Response
@ -81,6 +82,40 @@ class FIFOItemViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
raise APIException('该出入库记录已通过审核, 无法删除')
return super().perform_destroy(instance)
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=InmTestRecordCreateSerializer)
def test(self, request, pk=None):
"""
检测
"""
serializer = InmTestRecordCreateSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
vdata = serializer.validated_data
record_data = vdata.pop('record_data')
if 'is_testok' not in vdata:
raise APIException('未填写检测结论')
with transaction.atomic():
obj = serializer.save(create_by = self.request.user)
tris = []
for m in record_data: # 保存记录详情
form_field = m['form_field']
m['field_name'] = form_field.field_name
m['field_key'] = form_field.field_key
m['field_type'] = form_field.field_type
m['field_value'] = m['field_value']
m['sort'] = form_field.sort
m['need_judge'] = form_field.need_judge
m['is_testok'] = m['is_testok'] if 'is_testok' in m else True
m['test_record'] = obj
tris.append(TestRecordItem(**m))
TestRecordItem.objects.bulk_create(tris)
# 如果检测合格
if obj.fifo_item:
obj.fifo_item.is_testok = True if obj.is_testok else False
obj.fifo_item.is_tested = True
obj.fifo_item.save()
return Response()
class FIFOViewSet(ListModelMixin, GenericViewSet):
"""
出入库记录

View File

@ -0,0 +1,31 @@
# Generated by Django 3.2.6 on 2021-11-11 06:05
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('mtm', '0029_step_type'),
('wpm', '0012_auto_20211111_1056'),
('qm', '0007_alter_testrecorditem_field_type'),
]
operations = [
migrations.AddField(
model_name='testrecord',
name='m_state',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='关联的物料状态'),
),
migrations.AddField(
model_name='testrecord',
name='remark',
field=models.TextField(default='', verbose_name='备注'),
),
migrations.AddField(
model_name='testrecord',
name='wproduct',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='wpm.wproduct', verbose_name='关联的动态产品'),
),
]

View File

@ -49,7 +49,10 @@ class TestRecord(CommonAModel):
"""
form = models.ForeignKey('mtm.recordform', verbose_name='所用表格', on_delete=models.CASCADE)
is_testok = models.BooleanField('是否合格', default=True)
wproduct = models.ForeignKey('wpm.wproduct', verbose_name='关联的动态产品', on_delete=models.CASCADE, null=True, blank=True)
m_state = models.ForeignKey('mtm.material', verbose_name='关联的物料状态', on_delete=models.CASCADE, null=True, blank=True)
fifo_item = models.ForeignKey('inm.fifoitem', verbose_name='关联的出入库批次', on_delete=models.CASCADE, null=True, blank=True)
remark = models.TextField('备注', default='')
class TestRecordItem(BaseModel):

View File

@ -1,7 +1,8 @@
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin
from apps.qm.serializers import StandardCreateUpdateSerializer, StandardSerializer, TestItemCreateUpdateSerializer, TestItemSerializer, TestRecordCreateSerializer, TestRecordDetailSerializer, TestRecordListSerializer
from apps.qm.models import Standard, TestItem, TestRecord, TestRecordItem
from django.shortcuts import render
from rest_framework.viewsets import ModelViewSet
from rest_framework.viewsets import GenericViewSet, ModelViewSet
from apps.system.mixins import CreateUpdateModelAMixin
from rest_framework.exceptions import APIException
from rest_framework.response import Response
@ -42,7 +43,7 @@ class TestItemViewSet(CreateUpdateModelAMixin, ModelViewSet):
return TestItemCreateUpdateSerializer
return TestItemSerializer
class TestRecordViewSet(ModelViewSet):
class TestRecordViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
"""
检测记录
"""
@ -52,41 +53,39 @@ class TestRecordViewSet(ModelViewSet):
ordering = ['-id']
def get_serializer_class(self):
if self.action == 'create':
return TestRecordCreateSerializer
elif self.action == 'list':
if self.action == 'list':
return TestRecordListSerializer
elif self.action == 'retrieve':
return TestRecordDetailSerializer
return super().get_serializer_class()
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
vdata = serializer.validated_data
record_data = vdata.pop('record_data')
if 'is_testok' not in vdata:
raise APIException('未填写检测结论')
with transaction.atomic():
obj = serializer.save(create_by = self.request.user)
tris = []
for m in record_data: # 保存记录详情
form_field = m['form_field']
m['field_name'] = form_field.field_name
m['field_key'] = form_field.field_key
m['field_type'] = form_field.field_type
m['field_value'] = m['field_value']
m['sort'] = form_field.sort
m['need_judge'] = form_field.need_judge
m['is_testok'] = m['is_testok'] if 'is_testok' in m else True
m['test_record'] = obj
tris.append(TestRecordItem(**m))
TestRecordItem.objects.bulk_create(tris)
# def create(self, request, *args, **kwargs):
# serializer = self.get_serializer(data=request.data)
# serializer.is_valid(raise_exception=True)
# vdata = serializer.validated_data
# record_data = vdata.pop('record_data')
# if 'is_testok' not in vdata:
# raise APIException('未填写检测结论')
# with transaction.atomic():
# obj = serializer.save(create_by = self.request.user)
# tris = []
# for m in record_data: # 保存记录详情
# form_field = m['form_field']
# m['field_name'] = form_field.field_name
# m['field_key'] = form_field.field_key
# m['field_type'] = form_field.field_type
# m['field_value'] = m['field_value']
# m['sort'] = form_field.sort
# m['need_judge'] = form_field.need_judge
# m['is_testok'] = m['is_testok'] if 'is_testok' in m else True
# m['test_record'] = obj
# tris.append(TestRecordItem(**m))
# TestRecordItem.objects.bulk_create(tris)
# 如果检测合格
if obj.fifo_item:
obj.fifo_item.is_testok = True if obj.is_testok else False
obj.fifo_item.is_tested = True
obj.fifo_item.save()
# # 如果检测合格
# if obj.fifo_item:
# obj.fifo_item.is_testok = True if obj.is_testok else False
# obj.fifo_item.is_tested = True
# obj.fifo_item.save()
return Response(status=status.HTTP_201_CREATED)
# return Response(status=status.HTTP_201_CREATED)

View File

@ -0,0 +1,41 @@
# Generated by Django 3.2.6 on 2021-11-11 02:56
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('mtm', '0029_step_type'),
('wpm', '0011_alter_operationrecorditem_operation_record'),
]
operations = [
migrations.AddField(
model_name='operation',
name='use_scrap',
field=models.BooleanField(default=False, verbose_name='是否使用的边角料'),
),
migrations.AddField(
model_name='wproduct',
name='pre_pstate',
field=models.ForeignKey(blank=True, help_text='已执行完的步骤', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='w_pre_pstate', to='mtm.step', verbose_name='已执行到'),
),
migrations.AlterField(
model_name='operationmaterial',
name='count',
field=models.IntegerField(validators=[django.core.validators.MinValueValidator(0)], verbose_name='消耗或产出数量'),
),
migrations.AlterField(
model_name='wmaterial',
name='count',
field=models.IntegerField(default=0, validators=[django.core.validators.MinValueValidator(0)], verbose_name='当前数量'),
),
migrations.AlterField(
model_name='wproduct',
name='p_state',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='w_ptate', to='mtm.step', verbose_name='所在步骤'),
),
]

View File

@ -7,7 +7,7 @@ from apps.system.models import CommonAModel, CommonBModel, Organization, User, D
from utils.model import SoftModel, BaseModel
from simple_history.models import HistoricalRecords
from apps.mtm.models import Material, Process, RecordFormField, Step, RecordForm
from django.core.validators import MinValueValidator
class WMaterial(BaseModel):
"""
车间生产物料
@ -15,7 +15,7 @@ class WMaterial(BaseModel):
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子计划', on_delete=models.CASCADE)
material = models.ForeignKey(Material, verbose_name='关联物料', on_delete=models.CASCADE)
batch = models.CharField('批次号', max_length=100, null=True, blank=True)
count = models.IntegerField('当前数量', default=0)
count = models.IntegerField('当前数量', default=0, validators=[MinValueValidator(0)])
class WProduct(CommonAModel):
"""
@ -31,7 +31,8 @@ class WProduct(CommonAModel):
)
number = models.CharField('物品编号', unique=True, null=True, blank=True, max_length=50)
m_state = models.ForeignKey(Material, verbose_name='所属物料状态', on_delete=models.CASCADE)
p_state = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True)
pre_pstate = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True, on_delete=models.CASCADE, related_name='w_pre_pstate')
p_state = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True, related_name='w_ptate')
act_state = models.IntegerField('进行状态', default=0, choices=act_state_choices)
is_executed = models.BooleanField('子工序是否已执行', default=False)
is_hidden = models.BooleanField('是否隐藏', default=False)
@ -48,11 +49,12 @@ class Operation(CommonAModel):
wproducts = models.JSONField('关联产品ID列表', default=list, blank=True)
m_state = models.ForeignKey(Material, verbose_name='操作时的物料状态', on_delete=models.CASCADE, null=True, blank=True)
p_state = models.ForeignKey(Step, verbose_name='操作步骤', on_delete=models.CASCADE, null=True, blank=True)
use_scrap = models.BooleanField('是否使用的边角料', default=False)
remark = models.CharField('操作备注', max_length=200, null=True, blank=True)
class OperationMaterial(BaseModel):
"""
车间生产物料消耗产出表
生产操作物料消耗产出表
"""
type_choices=(
(1, '消耗'),
@ -62,7 +64,7 @@ class OperationMaterial(BaseModel):
operation = models.ForeignKey(Operation, verbose_name='关联的生产操作', on_delete=models.CASCADE)
wmaterial = models.ForeignKey(WMaterial, verbose_name='关联的车间物料', on_delete=models.CASCADE, null=True, blank=True)
material = models.ForeignKey(Material, verbose_name='可能产出的副产品', on_delete=models.CASCADE, null=True, blank=True)
count = models.IntegerField('消耗或产出数量')
count = models.IntegerField('消耗或产出数量', validators=[MinValueValidator(0)])
class OperationRecord(CommonAModel):
"""

View File

@ -1,4 +1,4 @@
from rest_framework import serializers
from rest_framework import serializers, exceptions
from rest_framework.serializers import ModelSerializer
from apps.inm.models import FIFO, FIFOItem, MaterialBatch, WareHouse
from apps.inm.signals import update_inm
@ -8,6 +8,7 @@ from apps.mtm.serializers import MaterialSimpleSerializer, StepSimpleSerializer
from apps.pm.models import SubProductionPlan, SubProductionProgress
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from apps.qm.models import TestRecord, TestRecordItem
from apps.system.serializers import UserSimpleSerializer
from apps.wpm.models import Operation, WMaterial, WProduct, OperationRecord, OperationRecordItem
from django.db import transaction
@ -26,16 +27,16 @@ class PickSerializer(serializers.Serializer):
picks = validated_data.pop('picks')
sp = validated_data['subproduction_plan']
if sp.state not in [1,2]:
raise serializers.ValidationError('该子计划状态错误')
raise exceptions.ValidationError('该子计划状态错误')
if sp.is_picked:
raise serializers.ValidationError('该子计划已领料')
for i in picks:
try:
instance = MaterialBatch.objects.get(material=i['material'], batch=i['batch'])
if instance.count < i['pick_count']:
raise serializers.ValidationError('物料不足')
except:
raise serializers.ValidationError('物料不存在')
raise exceptions.ValidationError('该子计划已领料')
# for i in picks:
# try:
# instance = MaterialBatch.objects.get(material=i['material'], batch=i['batch'])
# if instance.count < i['pick_count']:
# raise exceptions.ValidationError('物料不足')
# except:
# raise exceptions.ValidationError('物料不存在')
# 创建出库记录
with transaction.atomic():
validated_data['create_by'] = self.context['request'].user
@ -124,21 +125,21 @@ class OperationInitSerializer(serializers.Serializer):
stepIds=[i['id'] for i in subproduction_plan.steps]
if step.id not in stepIds:
raise serializers.ValidationError('请选择正确的子工序操作')
raise exceptions.ValidationError('请选择正确的子工序操作')
if 'wproducts' in data and data['wproducts']:
if step.type == Step.STEP_TYPE_DIV:
raise serializers.ValidationError(_('不可进行此操作'))
raise exceptions.ValidationError(_('不可进行此操作'))
for i in data['wproducts']:
if i.is_executed:
raise serializers.ValidationError('不可进行操作')
raise exceptions.ValidationError('不可进行操作')
if i.subproduction_plan != subproduction_plan:
raise serializers.ValidationError('半成品所属子计划不一致')
raise exceptions.ValidationError('半成品所属子计划不一致')
if i.p_state != step:
raise serializers.ValidationError('半成品所属子工序不一致')
raise exceptions.ValidationError('半成品所属子工序不一致')
else:
if step.type != Step.STEP_TYPE_DIV:
raise serializers.ValidationError(_('请选择半成品进行操作'))
raise exceptions.ValidationError(_('请选择半成品进行操作'))
return data
@ -172,6 +173,19 @@ class OperationSubmitSerializer(serializers.Serializer):
output = DoOutputSerializer(many=True, required=False)
forms = OperationRecordSerializer(many=True, required=False)
remark = serializers.CharField(required=False, label='操作备注', allow_blank=True, allow_null=True)
use_scrap = serializers.BooleanField(required=False, default=False)
class WpmTestRecordItemCreateSerializer(serializers.ModelSerializer):
class Meta:
model = TestRecordItem
fields = ['form_field', 'field_value', 'is_testok']
class WpmTestRecordCreateSerializer(serializers.ModelSerializer):
record_data = WpmTestRecordItemCreateSerializer(many=True)
wproduct = serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all(), required=True)
class Meta:
model = TestRecord
fields = ['form', 'record_data', 'is_testok', 'wproduct']

View File

@ -9,14 +9,16 @@ from apps.mtm.models import Material, RecordForm, Step, SubprodctionMaterial
from apps.mtm.serializers import RecordFormDetailSerializer
from apps.pm.models import SubProductionPlan, SubProductionProgress
from apps.pm.serializers import SubProductionPlanListSerializer, SubProductionPlanUpdateSerializer
from apps.qm.models import TestRecordItem
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
from rest_framework.decorators import action
from apps.wpm.models import WMaterial, WProduct, Operation, OperationMaterial, OperationRecord, OperationRecordItem
from apps.wpm.serializers import OperationDetailSerializer, OperationListSerializer, PickSerializer, OperationInitSerializer, OperationSubmitSerializer, WMaterialListSerializer, WProductListSerializer
from apps.wpm.serializers import OperationDetailSerializer, OperationListSerializer, PickSerializer, OperationInitSerializer, OperationSubmitSerializer, WMaterialListSerializer, WProductListSerializer, WpmTestRecordCreateSerializer
from rest_framework.response import Response
from django.db import transaction
from rest_framework import exceptions
# Create your views here.
class WPlanViewSet(ListModelMixin, GenericViewSet):
"""
@ -63,9 +65,40 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
ordering_fields = ['id']
ordering = ['id']
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=PickSerializer)
def test():
pass
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=WpmTestRecordCreateSerializer)
@transaction.atomic
def test(self, request, pk=None):
"""
检测
"""
serializer = WpmTestRecordCreateSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
vdata = serializer.validated_data
record_data = vdata.pop('record_data')
wproduct = vdata['wproduct']
if wproduct.act_state != WProduct.WPR_ACT_STATE_TOTEST:
raise exceptions.APIException('该半成品无需检测')
if 'is_testok' not in vdata:
raise exceptions.APIException('未填写检测结论')
obj = serializer.save(create_by = self.request.user, m_state=vdata['wproduct'].m_state)
tris = []
for m in record_data: # 保存记录详情
form_field = m['form_field']
m['field_name'] = form_field.field_name
m['field_key'] = form_field.field_key
m['field_type'] = form_field.field_type
m['field_value'] = m['field_value']
m['sort'] = form_field.sort
m['need_judge'] = form_field.need_judge
m['is_testok'] = m['is_testok'] if 'is_testok' in m else True
m['test_record'] = obj
tris.append(TestRecordItem(**m))
TestRecordItem.objects.bulk_create(tris)
# 如果检测合格
return Response()
class OperationViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
"""
@ -151,6 +184,7 @@ class DoFormSubmit(CreateAPIView, GenericAPIView):
action_obj.m_state = vdata['wproducts'][0].m_state
action_obj.remark = vdata.get('remark', '') # 操作备注
action_obj.create_by = request.user
action_obj.use_scrap = vdata.get('use_scrap', False)
action_obj.save()
# 保存物料消耗
@ -207,7 +241,7 @@ class DoFormSubmit(CreateAPIView, GenericAPIView):
pindex = stepIds.index(vdata['step'].id)
if pindex + 1 < len(stepIds): # 如果不是最后一步
newstep = Step.objects.get(pk=stepIds[pindex+1])
wproducts.update(p_state=newstep, is_executed=False)
wproducts.update(p_state=newstep, is_executed=False, pre_pstate=vdata['step'])
# 特殊情况如果是夹层结合
if vdata['step'].type == Step.STEP_TYPE_COMB:
@ -221,9 +255,10 @@ class DoFormSubmit(CreateAPIView, GenericAPIView):
parent = data['wproducts']
)
else: # 如果是最后一步, 此时需要转序并更新状态为待检测
else: # 如果是最后一步, 此时需要转序并更新状态为待检测, 此时物料状态需变成当前子计划的主产物状态
newstep = vdata['step']
wproducts.update(p_state=newstep, is_executed=True, act_state=WProduct.WPR_ACT_STATE_TOTEST)
wproducts.update(p_state=newstep, is_executed=True,
act_state=WProduct.WPR_ACT_STATE_TOTEST, pre_pstate=newstep, m_state=vdata['subproduction_plan'].main_product)
# 特殊情况如果是夹层结合
if vdata['step'].type == Step.STEP_TYPE_COMB: