823 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			823 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			Python
		
	
	
	
| from django.shortcuts import render
 | |
| from rest_framework.generics import CreateAPIView, GenericAPIView
 | |
| from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin
 | |
| from rest_framework.utils import serializer_helpers
 | |
| from rest_framework.utils.field_mapping import get_relation_kwargs
 | |
| from rest_framework.views import APIView
 | |
| from rest_framework.viewsets import GenericViewSet, ModelViewSet
 | |
| from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, WareHouse
 | |
| from apps.inm.signals import update_inm
 | |
| from apps.mtm.models import Material, RecordForm, RecordFormField, Step, SubprodctionMaterial, TechDoc
 | |
| from apps.mtm.serializers import RecordFormDetailSerializer, SubprodctionMaterialListSerializer, TechDocListSerializer
 | |
| from apps.pm.models import SubProductionPlan, SubProductionProgress
 | |
| from apps.pm.serializers import SubProductionPlanListSerializer, SubProductionPlanUpdateSerializer, SubProductionProgressSerializer
 | |
| from apps.qm.models import TestRecordItem
 | |
| 
 | |
| from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
 | |
| from rest_framework.decorators import action
 | |
| from apps.wpm.filters import WMaterialFilterSet
 | |
| from apps.wpm.models import OperationEquip, OperationWproduct, WMaterial, WProduct, Operation, OperationMaterial, OperationRecord, OperationRecordItem
 | |
| 
 | |
| from apps.wpm.serializers import OperationEquipListSerializer, OperationEquipUpdateSerializer, OperationMaterialCreate1Serailizer, OperationMaterialCreate2Serailizer, OperationMaterialCreate3Serializer, OperationMaterialListSerializer, OperationRecordListSerializer, OperationRecordSubmitSerializer, OperationUpdateSerializer, OperationWproductListSerializer, OperationCreateSerializer, OperationDetailSerializer, OperationListSerializer, PickHalfSerializer, PickSerializer, OperationInitSerializer, OperationSubmitSerializer, WMaterialListSerializer, WProductListSerializer, WplanPutInSerializer, WpmTestRecordCreateSerializer, WproductPutInSerializer
 | |
| from rest_framework.response import Response
 | |
| from django.db import transaction
 | |
| from rest_framework import exceptions, serializers
 | |
| 
 | |
| from apps.wpm.services import WpmServies
 | |
| from django.utils import timezone
 | |
| from utils.tools import ranstr
 | |
| from rest_framework import status
 | |
| # Create your views here.
 | |
| class WPlanViewSet(ListModelMixin, GenericViewSet):
 | |
|     """
 | |
|     车间生产计划
 | |
|     """
 | |
|     perms_map = {'*': '*'}
 | |
|     queryset = SubProductionPlan.objects.select_related('process', 'workshop', 'subproduction', 'main_product').exclude(state=0)
 | |
|     search_fields = []
 | |
|     serializer_class = SubProductionPlanListSerializer
 | |
|     filterset_fields = ['production_plan', 'process', 'state', 'main_product', 'workshop']
 | |
|     ordering_fields = []
 | |
|     ordering = ['-id']
 | |
| 
 | |
|     @action(methods=['post', 'get'], detail=True, perms_map={'post':'*', 'get':'*'}, serializer_class=PickHalfSerializer)
 | |
|     @transaction.atomic
 | |
|     def pick_half(self, request, pk=None):
 | |
|         """
 | |
|         领半成品
 | |
|         """
 | |
|         sp = self.get_object()
 | |
|         if request.method=='GET':
 | |
|             """
 | |
|             领半成品
 | |
|             """
 | |
|             spps = SubProductionProgress.objects.filter(type=SubprodctionMaterial.SUB_MA_TYPE_IN, 
 | |
|                 material__type=Material.MA_TYPE_HALFGOOD, subproduction_plan=sp).select_related('material')
 | |
|             return Response(SubProductionProgressSerializer(instance=spps, many=True).data)
 | |
|         elif request.method=='POST':
 | |
|             serializer= PickHalfSerializer(data=request.data, many=True)
 | |
|             serializer.is_valid(raise_exception=True)
 | |
|             vdata = serializer.data
 | |
|             first_step = Step.objects.get(pk=sp.steps[0]['id'])
 | |
|             for i in vdata:
 | |
|                 if 'wproducts' in i and len(i['wproducts'])>0:
 | |
|                     spp = SubProductionProgress.objects.get(pk=i['id'])
 | |
|                     spp.count_pick = spp.count_pick + len(i['wproducts'])
 | |
|                     if spp.count_pick > spp.count:
 | |
|                         raise exceptions.APIException('超过计划数')
 | |
|                     spp.save()
 | |
|                     wps = WProduct.objects.filter(pk__in=[x for x in i['wproducts']])
 | |
|                     wps.update(step=first_step, is_executed=False, 
 | |
|                     act_state=WProduct.WPR_ACT_STATE_DOING, is_hidden=False, warehouse=None,
 | |
|                     subproduction_plan=sp, update_by=request.user, update_time=timezone.now())
 | |
|             return Response()
 | |
|         
 | |
| 
 | |
|     @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=WplanPutInSerializer)
 | |
|     @transaction.atomic
 | |
|     def putin(self, request, pk=None):
 | |
|         """
 | |
|         半成品入库
 | |
|         """
 | |
|         serializer= WplanPutInSerializer(data=request.data)
 | |
|         serializer.is_valid(raise_exception=True)
 | |
|         vdata = serializer.data
 | |
|         subplan = self.get_object()
 | |
|         material = subplan.main_product
 | |
|         batch = subplan.number
 | |
|         warehouse = WareHouse.objects.get(id=vdata['warehouse'])
 | |
|         wproducts = WProduct.objects.filter(subproduction_plan=subplan, 
 | |
|             act_state=WProduct.WPR_ACT_STATE_OK, material=material, is_deleted=False)
 | |
|         if wproducts.exists():
 | |
|             # 创建入库记录
 | |
|             remark = vdata.get('remark', '')
 | |
|             fifo = FIFO.objects.create(type=FIFO.FIFO_TYPE_DO_IN,
 | |
|                 is_audited=True, auditor=request.user, inout_date=timezone.now(), create_by=request.user, remark=remark)
 | |
|             # 创建入库明细
 | |
|             fifoitem = FIFOItem()
 | |
|             fifoitem.is_tested = True
 | |
|             fifoitem.is_testok = True
 | |
|             fifoitem.warehouse = warehouse 
 | |
|             fifoitem.material = material
 | |
|             fifoitem.count = wproducts.count()
 | |
|             fifoitem.batch = batch
 | |
|             fifoitem.fifo = fifo
 | |
|             fifoitem.subproduction_plan = subplan
 | |
|             fifoitem.save()
 | |
|             # 创建入库明细半成品
 | |
|             ips = []
 | |
|             for i in wproducts:
 | |
|                 ip = {}
 | |
|                 ip['fifoitem'] = fifoitem
 | |
|                 ip['wproduct'] = i
 | |
|                 ip['number'] = i.number
 | |
|                 ip['material'] = material
 | |
|                 ips.append(FIFOItemProduct(**ip))
 | |
|             FIFOItemProduct.objects.bulk_create(ips)
 | |
|             # 创建IProduct
 | |
|             ips2 = []
 | |
|             for i in wproducts:
 | |
|                 ip = {}
 | |
|                 ip['warehouse'] = warehouse
 | |
|                 ip['batch'] = batch
 | |
|                 ip['wproduct'] = i
 | |
|                 ip['number'] = i.number
 | |
|                 ip['material'] = material
 | |
|                 ips2.append(IProduct(**ip))
 | |
|             IProduct.objects.bulk_create(ips2)
 | |
|             # 更新库存并修改半成品进行状态
 | |
|             update_inm(fifo)
 | |
|             wproducts.update(act_sate=WProduct.WPR_ACT_STATE_INM, warehouse=warehouse, update_by=request.user, update_time=timezone.now())
 | |
|             
 | |
|         return Response()
 | |
| 
 | |
| 
 | |
| class WMaterialViewSet(CreateUpdateModelAMixin, ListModelMixin, GenericViewSet):
 | |
|     """
 | |
|     车间物料表
 | |
|     """
 | |
|     perms_map={'*':'*'}
 | |
|     queryset = WMaterial.objects.select_related('material').all()
 | |
|     serializer_class = WMaterialListSerializer
 | |
|     filterset_class = WMaterialFilterSet
 | |
|     ordering_fields = ['material__number']
 | |
|     ordering = ['material__number']
 | |
| 
 | |
|     @action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=PickSerializer)
 | |
|     def pick(self, request, pk=None):
 | |
|         """
 | |
|         领料
 | |
|         """
 | |
|         serializer= PickSerializer(data=request.data, context={'request': request})
 | |
|         serializer.is_valid(raise_exception=True)
 | |
|         serializer.save()
 | |
|         return Response()
 | |
| 
 | |
| class WProductViewSet(ListModelMixin, GenericViewSet):
 | |
|     """
 | |
|     半成品
 | |
|     """
 | |
|     perms_map={'*':'*'}
 | |
|     queryset = WProduct.objects.select_related('step', 'material').filter(is_hidden=False).exclude(operation=None)
 | |
|     serializer_class = WProductListSerializer
 | |
|     filterset_fields = ['step', 'subproduction_plan', 'material', 'step__process', 'act_state']
 | |
|     search_fields = ['number']
 | |
|     ordering_fields = ['id']
 | |
|     ordering = ['id']
 | |
| 
 | |
|     @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, material=wproduct.material)
 | |
|         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 None
 | |
|             m['test_record'] = obj
 | |
|             tris.append(TestRecordItem(**m))
 | |
|         TestRecordItem.objects.bulk_create(tris)
 | |
| 
 | |
|         # 如果检测合格, 变更动态产品进行状态
 | |
| 
 | |
|         if obj.is_testok:
 | |
|             wproduct.act_state = WProduct.WPR_ACT_STATE_OK
 | |
|             if wproduct.number is None: # 产生半成品编号
 | |
|                 wproduct.number = 'WP'+ranstr(7)
 | |
|             wproduct.save()
 | |
|             # 更新子计划状态
 | |
|             # 更新子计划主产品数
 | |
|             instance = SubProductionProgress.objects.get(subproduction_plan=wproduct.subproduction_plan, 
 | |
|             is_main=True, type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
 | |
|             instance.count_ok = instance.count_ok + 1 # 这个地方可能会有问题
 | |
|             instance.save()
 | |
|         else:# 如果不合格
 | |
|             pass
 | |
|         
 | |
|         return Response()
 | |
| 
 | |
|     @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=WproductPutInSerializer)
 | |
|     @transaction.atomic
 | |
|     def putin(self, request, pk=None):
 | |
|         """
 | |
|         半成品入库
 | |
|         """
 | |
|         serializer= WproductPutInSerializer(data=request.data)
 | |
|         serializer.is_valid(raise_exception=True)
 | |
|         vdata = serializer.data
 | |
|         wproduct = self.get_object()
 | |
|         warehouse = WareHouse.objects.get(id=vdata['warehouse'])
 | |
|         if wproduct.act_state != WProduct.WPR_ACT_STATE_OK:
 | |
|             raise exceptions.APIException('半成品不可入库')
 | |
|         material = wproduct.material
 | |
|         batch = wproduct.subproduction_plan.number
 | |
|         # 创建入库记录
 | |
|         remark = vdata.get('remark', '')
 | |
|         fifo = FIFO.objects.create(type=FIFO.FIFO_TYPE_DO_IN,
 | |
|             is_audited=True, auditor=request.user, inout_date=timezone.now(), create_by=request.user, remark=remark)
 | |
|         # 创建入库明细
 | |
|         fifoitem = FIFOItem()
 | |
|         fifoitem.is_tested = True
 | |
|         fifoitem.is_testok = True
 | |
|         fifoitem.warehouse = warehouse
 | |
|         fifoitem.material = material
 | |
|         fifoitem.count = 1 # 单个半成品入库
 | |
|         fifoitem.batch = batch
 | |
|         fifoitem.fifo = fifo
 | |
|         fifoitem.subproduction_plan = wproduct.subproduction_plan
 | |
|         fifoitem.save()
 | |
|         # 创建入库明细半成品
 | |
|         ips = []
 | |
|         for i in [wproduct]:
 | |
|             ip = {}
 | |
|             ip['fifoitem'] = fifoitem
 | |
|             ip['wproduct'] = i
 | |
|             ip['number'] = i.number
 | |
|             ip['material'] = material
 | |
|             ips.append(FIFOItemProduct(**ip))
 | |
|         FIFOItemProduct.objects.bulk_create(ips)
 | |
|         # 更新库存并修改半成品进行状态
 | |
|         update_inm(fifo)
 | |
|         wproduct.act_state=WProduct.WPR_ACT_STATE_INM
 | |
|         wproduct.warehouse=warehouse
 | |
|         wproduct.save()
 | |
|         return Response()
 | |
| 
 | |
| class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, UpdateModelMixin, DestroyModelMixin, GenericViewSet):
 | |
|     """
 | |
|     生产操作记录
 | |
|     """
 | |
|     perms_map={'*':'*'}
 | |
|     queryset = Operation.objects.select_related('step').prefetch_related('ow_operation', 'oe_operation', 'or_operation').all()
 | |
|     serializer_class = OperationListSerializer
 | |
|     filterset_fields = ['step', 'step__process', 'is_submited']
 | |
|     ordering_fields = ['id']
 | |
|     ordering = ['-id']
 | |
| 
 | |
|     def get_queryset(self):
 | |
|         return self.queryset.filter(create_by=self.request.user)
 | |
| 
 | |
|     def get_serializer_class(self):
 | |
|         if self.action == 'retrieve':
 | |
|             return OperationDetailSerializer
 | |
|         elif self.action == 'create':
 | |
|             return OperationCreateSerializer
 | |
|         elif self.action == 'update':
 | |
|             return OperationUpdateSerializer
 | |
|         return super().get_serializer_class()
 | |
| 
 | |
|     def update(self, request, *args, **kwargs):
 | |
|         instance = self.get_object()
 | |
|         if instance.is_submited:
 | |
|             raise exceptions.APIException('该操作已提交')
 | |
|         return super().update(request, *args, **kwargs)
 | |
| 
 | |
|     def destroy(self, request, *args, **kwargs):
 | |
|         instance = self.get_object()
 | |
|         if instance.is_submited:
 | |
|             raise exceptions.APIException('该操作已提交')
 | |
|         self.perform_destroy(instance)
 | |
|         return Response(status=status.HTTP_204_NO_CONTENT)
 | |
| 
 | |
|     @transaction.atomic
 | |
|     def create(self, request, *args, **kwargs):
 | |
|         data = request.data
 | |
|         serializer = OperationCreateSerializer(data=data, context={'request':self.request})
 | |
|         serializer.is_valid(raise_exception=True)
 | |
|         vdata = serializer.validated_data #校验之后的数据
 | |
|         step = vdata['step']
 | |
|         op = Operation()
 | |
|         op.step = step
 | |
|         op.is_submited = False
 | |
|         op.create_by = request.user
 | |
|         op.save()
 | |
|         splans = []
 | |
|         # 创建操作所用半成品关联记录
 | |
|         if 'wproducts' in vdata:
 | |
|             owps = []
 | |
|             splans = WpmServies.get_subplans_queryset_from_wproducts(vdata['wproducts'])
 | |
|             for wpd in vdata['wproducts']:
 | |
|                 owp = {}
 | |
|                 owp['operation'] = op
 | |
|                 owp['wproduct'] = wpd
 | |
|                 owp['number'] = wpd.number
 | |
|                 owp['material'] = wpd.material
 | |
|                 owp['subproduction_plan'] = wpd.subproduction_plan
 | |
|                 owps.append(OperationWproduct(**owp))
 | |
|             OperationWproduct.objects.bulk_create(owps)
 | |
|         else:
 | |
|             splans = WpmServies.get_subplans_queryset_from_wproducts(vdata['wproducts'])
 | |
|         # 查询需要填写的自定义表格
 | |
|         forms = RecordForm.objects.filter(step=step, type=RecordForm.RF_TYPE_DO)
 | |
|         for i in forms:
 | |
|             opr = OperationRecord()
 | |
|             opr.operation = op
 | |
|             opr.form = i
 | |
|             opr.is_filled = False
 | |
|             opr.save()
 | |
|         # 查询需要使用的生产设备
 | |
|         for i in step.equipments.all():
 | |
|             ope = OperationEquip()
 | |
|             ope.operation = op
 | |
|             ope.equip = i
 | |
|             ope.save()
 | |
|         # 查询所需的工具工装
 | |
|         for i in SubprodctionMaterial.objects.filter(type=SubprodctionMaterial.SUB_MA_TYPE_TOOL,
 | |
|                         subproduction__subplan_subprod__in = splans, is_deleted=False).distinct():
 | |
|             opm = OperationMaterial()
 | |
|             opm.operation = op
 | |
|             opm.material = i.material
 | |
|             opm.type = SubprodctionMaterial.SUB_MA_TYPE_TOOL
 | |
|             opm.save()
 | |
|         return Response()
 | |
|     
 | |
|     @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=serializers.Serializer)
 | |
|     @transaction.atomic
 | |
|     def submit(self, request, pk=None):
 | |
|         """
 | |
|         提交车间操作重要
 | |
|         """
 | |
|         op = self.get_object()
 | |
|         step = op.step
 | |
|         # 检查自定义表单填写
 | |
|         if OperationRecord.objects.filter(operation=op, is_filled=False).exists():
 | |
|             raise exceptions.APIException('存在自定义表单未填写')
 | |
|         # 更新物料消耗进度
 | |
|         for i in OperationMaterial.objects.filter(operation=op, type=SubprodctionMaterial.SUB_MA_TYPE_IN):
 | |
|             # 更新车间物料
 | |
|             i_wmat = i.wmaterial
 | |
|             i_wmat.count = i_wmat.count- i['count']
 | |
|             i_wmat.save()
 | |
|             # 更新子计划物料消耗情况
 | |
|             sp = i_wmat.subproduction_plan
 | |
|             sp.count_real = sp.count_real + i['count']
 | |
|             sp.save()
 | |
|         # 更新产出
 | |
|         for i in OperationMaterial.objects.filter(operation=op, type=SubprodctionMaterial.SUB_MA_TYPE_OUT):
 | |
|             if not i.subproduction_progress.is_main:
 | |
|                 # 更新车间物料产出情况
 | |
|                 ins, _ = WMaterial.objects.get_or_create(subproduction_plan=i.subproduction_plan,
 | |
|                     material=i.material)
 | |
|                 ins.count = ins.count + i['count']
 | |
|                 ins.save()
 | |
|                 # 更新子计划物料产出情况
 | |
|                 sp = i.subproduction_progress
 | |
|                 sp.count_real = sp.count_real + i['count']
 | |
|                 sp.save()
 | |
|         # 更新动态产品表
 | |
|         if step.type == Step.STEP_TYPE_NOM:
 | |
|             for i in OperationWproduct.objects.filter(operation=op):
 | |
|                 wp = i.wproduct
 | |
|                 wsp = i.subproduction_plan
 | |
|                 # 获取下一步子工序
 | |
|                 newstep, hasNext = WpmServies.get_next_step(wsp, step)
 | |
|                 wp.step = newstep
 | |
|                 wp.pre_step = step
 | |
|                 if hasNext:
 | |
|                     wp.is_executed= False
 | |
|                 else:
 | |
|                     wp.is_executed = True
 | |
|                     wp.act_state = WProduct.WPR_ACT_STATE_TOTEST
 | |
|                     wp.material = wsp.main_product
 | |
|                     # 更新子计划进度
 | |
|                     instance = SubProductionProgress.objects.get(subproduction_plan=wsp, 
 | |
|                     is_main=True, type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
 | |
|                     instance.count_real = instance.count_real + 1 # 这个地方可能会有问题,不够严谨
 | |
|                     instance.save()
 | |
|                 wp.operation = None
 | |
|                 wp.save()
 | |
|         elif step.type == Step.STEP_TYPE_DIV:
 | |
|             # 更新物料产出情况
 | |
|             for i in OperationMaterial.objects.filter(operation=op, type=SubprodctionMaterial.SUB_MA_TYPE_OUT):
 | |
|                 if i.subproduction_progress.is_main:
 | |
|                     newstep, _ = WpmServies.get_next_step(i.subproduction_plan, step)
 | |
|                     wpr = dict(material=i.material, step=newstep,
 | |
|                         act_state=WProduct.WPR_ACT_STATE_DOING, is_executed=False, remark='', 
 | |
|                         subproduction_plan=i.subproduction_plan)
 | |
|                     for x in range(i.count):
 | |
|                         WProduct.objects.create(**wpr)              
 | |
|         elif step.type == Step.STEP_TYPE_COMB:
 | |
|             # 隐藏原半成品
 | |
|             ows = OperationWproduct.objects.filter(operation=op)
 | |
|             ows.update(is_hidden=True)
 | |
|             if i.subproduction_progress.is_main:
 | |
|                 newstep, hasNext = WpmServies.get_next_step(i.subproduction_plan, step)
 | |
|                 wproduct = WProduct()
 | |
|                 wproduct.material = i.material
 | |
|                 wproduct.step = newstep
 | |
|                 wproduct.subproduction_plan = i.subproduction_plan
 | |
|                 wproduct.parent = ows.values_list('wproduct', flat=True)
 | |
|                 if hasNext:
 | |
|                     wproduct.act_state = WProduct.WPR_ACT_STATE_DOING
 | |
|                     wproduct.is_executed = False
 | |
|                 else:
 | |
|                     wproduct.act_state = WProduct.WPR_ACT_STATE_TOTEST
 | |
|                     wproduct.is_executed = True
 | |
|                 wproduct.save()
 | |
|         
 | |
| 
 | |
| 
 | |
| class OperationWproductViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
 | |
|     """
 | |
|     操作使用的半成品
 | |
|     """
 | |
|     perms_map={'*':'*'}
 | |
|     queryset = OperationWproduct.objects.select_related('subproduction_plan', 'material').all()
 | |
|     serializer_class = OperationWproductListSerializer
 | |
|     filterset_fields = ['material', 'subproduction_plan', 'operation']
 | |
|     ordering_fields = ['id']
 | |
|     ordering = ['-id']
 | |
| 
 | |
|     @transaction.atomic()
 | |
|     def destroy(self, request, *args, **kwargs):
 | |
|         instance = self.get_object()
 | |
|         if instance.operation.is_submited:
 | |
|             raise exceptions.APIException('该操作已提交')
 | |
|         instance.delete()
 | |
|         wp = instance.wproduct
 | |
|         wp.operation = None
 | |
|         wp.save()
 | |
|         return Response()
 | |
| 
 | |
| class OperationEquipViewSet(ListModelMixin, DestroyModelMixin, UpdateModelMixin, GenericViewSet):
 | |
|     """
 | |
|     操作使用的设备
 | |
|     """
 | |
|     perms_map={'*':'*'}
 | |
|     queryset = OperationEquip.objects.select_related('operation', 'equip').all()
 | |
|     serializer_class = OperationEquipListSerializer
 | |
|     filterset_fields = ['operation', 'equip']
 | |
|     ordering_fields = ['id']
 | |
|     ordering = ['-id']
 | |
| 
 | |
|     def get_serializer_class(self):
 | |
|         if self.action == 'update':
 | |
|             return OperationEquipUpdateSerializer
 | |
|         return super().get_serializer_class()
 | |
|     
 | |
|     def update(self, request, *args, **kwargs):
 | |
|         instance = self.get_object()
 | |
|         if instance.operation.is_submited:
 | |
|             raise exceptions.APIException('该操作已提交')
 | |
|         return super().update(request, *args, **kwargs)
 | |
| 
 | |
|     @transaction.atomic()
 | |
|     def destroy(self, request, *args, **kwargs):
 | |
|         instance = self.get_object()
 | |
|         if instance.operation.is_submited:
 | |
|             raise exceptions.APIException('该操作已提交')
 | |
|         instance.delete()
 | |
|         return Response()
 | |
| 
 | |
| class OperationRecordViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
 | |
|     """
 | |
|     操作使用的自定义表格
 | |
|     """
 | |
|     perms_map={'*':'*'}
 | |
|     queryset = OperationRecord.objects.select_related('operation', 'form').all()
 | |
|     serializer_class = OperationRecordListSerializer
 | |
|     filterset_fields = ['operation', 'form']
 | |
|     ordering_fields = ['id']
 | |
|     ordering = ['-id']
 | |
| 
 | |
|     @transaction.atomic()
 | |
|     def destroy(self, request, *args, **kwargs):
 | |
|         instance = self.get_object()
 | |
|         if instance.operation.is_submited:
 | |
|             raise exceptions.APIException('该操作已提交')
 | |
|         instance.delete()
 | |
|         return Response()
 | |
| 
 | |
|     @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=OperationRecordSubmitSerializer)
 | |
|     def submit(self, request, pk=None):
 | |
|         serializer = OperationRecordSubmitSerializer(data=request.data, context={'request':self.request})
 | |
|         serializer.is_valid(raise_exception=True)
 | |
|         vdata = serializer.data
 | |
|         opr = self.get_object()
 | |
|         wrds = []
 | |
|         for m in vdata['record_data']: # 保存记录详情
 | |
|             form_field = RecordFormField.objects.get(pk=m['form_field'])
 | |
|             m['form_field'] = 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['operation_record'] = opr
 | |
|             wrds.append(OperationRecordItem(**m))
 | |
|         OperationRecordItem.objects.bulk_create(wrds)
 | |
|         opr.is_filled = True
 | |
|         opr.save()
 | |
|         return Response()
 | |
| 
 | |
| 
 | |
| class OperationMaterialInputViewSet(ListModelMixin, CreateModelMixin, DestroyModelMixin, GenericViewSet):
 | |
|     """
 | |
|     消耗物料
 | |
|     """
 | |
|     perms_map={'*':'*'}
 | |
|     queryset = OperationMaterial.objects.select_related('operation', 'subproduction_plan').filter(type=SubprodctionMaterial.SUB_MA_TYPE_IN)
 | |
|     serializer_class = OperationMaterialListSerializer
 | |
|     filterset_fields = ['operation', 'subproduction_plan']
 | |
|     ordering_fields = ['id']
 | |
|     ordering = ['-id']
 | |
| 
 | |
|     def get_serializer_class(self):
 | |
|         if self.action == 'create':
 | |
|             return OperationMaterialCreate1Serailizer
 | |
|         return super().get_serializer_class()
 | |
|     
 | |
|     def create(self, request, *args, **kwargs):
 | |
|         instance = self.get_object()
 | |
|         if instance.operation.is_submited:
 | |
|             raise exceptions.APIException('该操作已提交')
 | |
|         return super().create(request, *args, **kwargs)
 | |
|         
 | |
|     @transaction.atomic()
 | |
|     def destroy(self, request, *args, **kwargs):
 | |
|         instance = self.get_object()
 | |
|         if instance.operation.is_submited:
 | |
|             raise exceptions.APIException('该操作已提交')
 | |
|         instance.delete()
 | |
|         return Response()
 | |
| 
 | |
| class OperationMaterialOutputViewSet(ListModelMixin, CreateModelMixin, DestroyModelMixin, GenericViewSet):
 | |
|     """
 | |
|     产出物料
 | |
|     """
 | |
|     perms_map={'*':'*'}
 | |
|     queryset = OperationMaterial.objects.select_related('operation', 'subproduction_plan').filter(type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
 | |
|     serializer_class = OperationMaterialListSerializer
 | |
|     filterset_fields = ['operation', 'subproduction_plan']
 | |
|     ordering_fields = ['id']
 | |
|     ordering = ['-id']
 | |
| 
 | |
|     def get_serializer_class(self):
 | |
|         if self.action == 'create':
 | |
|             return OperationMaterialCreate2Serailizer
 | |
|         return super().get_serializer_class()
 | |
|     
 | |
|     def create(self, request, *args, **kwargs):
 | |
|         instance = self.get_object()
 | |
|         if instance.operation.is_submited:
 | |
|             raise exceptions.APIException('该操作已提交')
 | |
|         return super().create(request, *args, **kwargs)
 | |
|         
 | |
|     @transaction.atomic()
 | |
|     def destroy(self, request, *args, **kwargs):
 | |
|         instance = self.get_object()
 | |
|         if instance.operation.is_submited:
 | |
|             raise exceptions.APIException('该操作已提交')
 | |
|         instance.delete()
 | |
|         return Response()
 | |
| 
 | |
| class OperationMaterialToolViewSet(ListModelMixin, CreateModelMixin, DestroyModelMixin, GenericViewSet):
 | |
|     """
 | |
|     工具工装
 | |
|     """
 | |
|     perms_map={'*':'*'}
 | |
|     queryset = OperationMaterial.objects.select_related('operation', 'subproduction_plan').filter(type=SubprodctionMaterial.SUB_MA_TYPE_TOOL)
 | |
|     serializer_class = OperationMaterialListSerializer
 | |
|     filterset_fields = ['operation', 'subproduction_plan']
 | |
|     ordering_fields = ['id']
 | |
|     ordering = ['-id']
 | |
| 
 | |
|     def get_serializer_class(self):
 | |
|         if self.action == 'create':
 | |
|             return OperationMaterialCreate3Serializer
 | |
|         return super().get_serializer_class()
 | |
| 
 | |
|     def create(self, request, *args, **kwargs):
 | |
|         instance = self.get_object()
 | |
|         if instance.operation.is_submited:
 | |
|             raise exceptions.APIException('该操作已提交')
 | |
|         return super().create(request, *args, **kwargs)
 | |
|         
 | |
|     @transaction.atomic()
 | |
|     def destroy(self, request, *args, **kwargs):
 | |
|         instance = self.get_object()
 | |
|         if instance.operation.is_submited:
 | |
|             raise exceptions.APIException('该操作已提交')
 | |
|         instance.delete()
 | |
|         return Response()
 | |
| 
 | |
| class DoFormInit(CreateAPIView, GenericAPIView):
 | |
|     perms_map={'*':'*'}
 | |
|     serializer_class=OperationInitSerializer
 | |
|     def post(self, request, format=None):
 | |
|         """
 | |
|         调用操作表单
 | |
|         """
 | |
|         data = request.data
 | |
|         serializer = OperationInitSerializer(data=data)
 | |
|         serializer.is_valid(raise_exception=True)
 | |
|         vdata = serializer.validated_data
 | |
|         ret = {}
 | |
|         ret_0 = {}
 | |
|         ret_0['step'] = data['step']
 | |
|         splans =[]
 | |
|         ret_0['input'] = []
 | |
|         # ret_0['subproduction_plan'] = data['subproduction_plan']
 | |
|         if 'wproducts' in data and data['wproducts']:
 | |
|             ret_0['wproducts'] = data['wproducts']
 | |
|             splans = WProduct.objects.filter(id__in=data['wproducts']).values_list('subproduction_plan', flat=True)
 | |
|             # 调出所属子计划现有物料
 | |
|             ret_0['input'] = WMaterialListSerializer(instance=WMaterial.objects.filter(subproduction_plan__in=splans), many=True).data
 | |
|         else:
 | |
|             if 'subproduction_plan' in vdata:
 | |
|                 splans = [vdata['subproduction_plan']]
 | |
|             else:
 | |
|                 splans = SubProductionPlan.objects.filter(is_deleted=False, 
 | |
|                 subproduction__usedstep_subproduction__step=vdata['step'], state=3)
 | |
|             ret_0['wproducts'] = []
 | |
|             ret_0['input'] = WMaterialListSerializer(instance=WMaterial.objects.filter(subproduction_plan__in=splans), many=True).data
 | |
| 
 | |
|         
 | |
|         for i in ret_0['input']:
 | |
|             i['count_input'] = 0
 | |
|         # 需要输出的物料
 | |
|         if ret_0['wproducts']:
 | |
|             # 排除主要产物, 因为已经放到半成品里了, 由半成品进行处理, 夹层可能需要特殊处理
 | |
|             o_objs = SubProductionProgress.objects.filter(
 | |
|                 subproduction_plan__in=splans, type=SubprodctionMaterial.SUB_MA_TYPE_OUT).exclude(is_main=True)
 | |
|             
 | |
|         else:
 | |
|             # 此时显示所有子计划需要输出的物料
 | |
|             o_objs = SubProductionProgress.objects.filter(
 | |
|                 subproduction_plan__in=splans, type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
 | |
|         ret_0['output'] = list(o_objs.values('subproduction_plan', 'material', 'material__name', 'material__number'))
 | |
|         for i in ret_0['output']:
 | |
|             i['count_output']=0
 | |
|         ret['forms'] = []
 | |
|         ret_0['id'] = 0
 | |
|         ret_0['name'] = '基本信息'
 | |
|         # 查询工具工装
 | |
|         ret_0['tools'] = SubprodctionMaterialListSerializer(instance=
 | |
|                         SubprodctionMaterial.objects.filter(type=SubprodctionMaterial.SUB_MA_TYPE_TOOL,
 | |
|                         subproduction__subplan_subprod__in = splans), many=True).data
 | |
|         # 查询技术文档
 | |
|         ret_0['techdocs'] = TechDocListSerializer(instance = 
 | |
|                 TechDoc.objects.filter(subproduction__subplan_subprod__in = splans, enabled=True)\
 | |
|             .distinct(), many=True).data
 | |
| 
 | |
|         ret['forms'].append(ret_0)
 | |
|         forms = RecordForm.objects.filter(step=vdata['step'], type=RecordForm.RF_TYPE_DO)
 | |
|         if forms.exists():
 | |
|             ret['forms'].extend(RecordFormDetailSerializer(instance=forms, many=True).data) 
 | |
|         return Response(ret)
 | |
| 
 | |
| 
 | |
| class DoFormSubmit(CreateAPIView, GenericAPIView):
 | |
|     perms_map={'*':'*'}
 | |
|     serializer_class = OperationSubmitSerializer
 | |
| 
 | |
|     @transaction.atomic
 | |
|     def post(self, request, format=None):
 | |
|         """
 | |
|         提交操作表单
 | |
|         """
 | |
|         data = request.data
 | |
|         serializer = OperationSubmitSerializer(data=data, context={'request':self.request})
 | |
|         serializer.is_valid(raise_exception=True)
 | |
|         vdata = serializer.validated_data #校验之后的数据
 | |
| 
 | |
|         # 创建一个生产操作记录
 | |
|         action_obj = Operation()
 | |
|         action_obj.step = vdata['step']
 | |
|         action_obj.remark = vdata.get('remark', '') # 操作备注
 | |
|         action_obj.create_by = request.user
 | |
|         action_obj.use_scrap = vdata.get('use_scrap', False)
 | |
|         action_obj.save()
 | |
|         
 | |
|         # 保存关联半成品
 | |
|         if 'wproducts' in data and data['wproducts']:
 | |
|             owps = []
 | |
|             for i in data['wproducts']:
 | |
|                 owp = {}
 | |
|                 owp['operation'] = action_obj
 | |
|                 wp = WProduct.objects.get(pk=i)
 | |
|                 owp['wproduct'] = wp
 | |
|                 owp['number'] = wp.number
 | |
|                 owp['material'] = wp.material
 | |
|                 owp['subproduction_plan'] = wp.subproduction_plan
 | |
|                 owps.append(OperationWproduct(**owp))
 | |
|             OperationWproduct.objects.bulk_create(owps)
 | |
| 
 | |
|         # 保存物料消耗
 | |
|         for i in vdata['input']:
 | |
|             if i['count_input']: #如果有消耗
 | |
|                 i_wmat = i['id']
 | |
|                 OperationMaterial.objects.create(type=1, operation=action_obj,
 | |
|                     wmaterial= i_wmat, count=i['count_input'])
 | |
|                 # 更新车间物料
 | |
|                 i_wmat.count = i_wmat.count- i['count_input']
 | |
|                 i_wmat.save()
 | |
|                 # 更新子计划物料消耗情况
 | |
|                 sp = SubProductionProgress.objects.get(subproduction_plan=i_wmat.subproduction_plan,
 | |
|                     material=i_wmat.material)
 | |
|                 sp.count_real = sp.count_real + i['count_input']
 | |
|                 sp.save()
 | |
|         
 | |
|         # 物料产出
 | |
|         if 'output' in data and data['output']:
 | |
|             for i in vdata['output']: # 已经序列化好的数据
 | |
|                 ma = i['material']
 | |
|                 if i['subproduction_plan'].main_product == ma: # 如果是该计划主产物
 | |
|                     # 如果是切割
 | |
|                     # 获取下一步子工序
 | |
|                     if vdata['step'].type == Step.STEP_TYPE_DIV:
 | |
|                         newstep, _ = WpmServies.get_next_step(i['subproduction_plan'], vdata['step'])
 | |
|                         wpr = dict(material=ma, step=newstep,
 | |
|                             act_state=WProduct.WPR_ACT_STATE_DOING, is_executed=False, remark='', 
 | |
|                             subproduction_plan=i['subproduction_plan'])
 | |
|                         for x in range(i['count_output']):
 | |
|                             WProduct.objects.create(**wpr)
 | |
|                 else:
 | |
|                     # 更新操作产出物料表
 | |
|                     OperationMaterial.objects.create(type=2, operation=action_obj,
 | |
|                     material= ma, count=i['count_output'])
 | |
|                     # 更新车间物料表
 | |
|                     ins, _ = WMaterial.objects.get_or_create(subproduction_plan=i['subproduction_plan'],
 | |
|                         material=ma)
 | |
|                     ins.count = ins.count + i['count_output']
 | |
|                     ins.save()
 | |
|                     # 更新子计划进度表
 | |
|                     sp = SubProductionProgress.objects.get(subproduction_plan=i['subproduction_plan'],
 | |
|                     material=ma)
 | |
|                     sp.count_real = sp.count_real + i['count_input']
 | |
|                     sp.save()
 | |
| 
 | |
|         # 更新动态产品表
 | |
|         if 'wproducts' in vdata and vdata['wproducts']:
 | |
|             if vdata['step'].type == Step.STEP_TYPE_COMB:
 | |
|                 wproducts = vdata['wproducts']
 | |
|                 if 'suproduction_plan' in vdata:
 | |
|                     wproducts.update(is_hidden=True) # 隐藏
 | |
|                     newstep, hasNext = WpmServies.get_next_step(i['subproduction_plan'], vdata['step'])
 | |
|                     wproduct = WProduct()
 | |
|                     wproduct.material = vdata['subproduction_plan'].main_product
 | |
|                     wproduct.step = newstep
 | |
|                     wproduct.subproduction_plan=vdata['subproduction_plan']
 | |
|                     wproduct.parent = data['wproducts']
 | |
|                     if hasNext:
 | |
|                         wproduct.act_state=WProduct.WPR_ACT_STATE_DOING
 | |
|                         wproduct.is_executed=False
 | |
|                     else:
 | |
|                         wproduct.act_state=WProduct.WPR_ACT_STATE_TOTEST
 | |
|                         wproduct.is_executed=True
 | |
|                     wproduct.save()
 | |
|                 else:
 | |
|                     raise exceptions.APIException('请指定子计划')
 | |
|             else:
 | |
|                 for wproduct in vdata['wproducts']:
 | |
|                     # 获取下一步子工序
 | |
|                     newstep, hasNext = WpmServies.get_next_step(wproduct.subproduction_plan, vdata['step'])
 | |
|                     wproduct.step = newstep
 | |
|                     wproduct.pre_step=vdata['step']
 | |
|                     if hasNext:
 | |
|                         wproduct.is_executed= False
 | |
|                     else:
 | |
|                         wproduct.is_executed= True
 | |
|                         wproduct.act_state=WProduct.WPR_ACT_STATE_TOTEST
 | |
|                         wproduct.material=wproduct.subproduction_plan.main_product
 | |
|                     wproduct.save()
 | |
| 
 | |
|         # 保存自定义表单结果
 | |
|         for i in vdata['forms']:
 | |
|             wr = OperationRecord()
 | |
|             wr.form = i['form']
 | |
|             wr.create_by = request.user
 | |
|             wr.operation = action_obj
 | |
|             wr.save()
 | |
|             wrds = []
 | |
|             for m in i['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['operation_record'] = wr
 | |
|                 wrds.append(OperationRecordItem(**m))
 | |
|             OperationRecordItem.objects.bulk_create(wrds)
 | |
|         return Response()
 | |
| 
 | |
|          |