253 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			253 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
	
	
| from datetime import timezone
 | |
| from typing import List
 | |
| from django.db import transaction
 | |
| from rest_framework import serializers
 | |
| from rest_framework.views import APIView
 | |
| from apps.em.models import Equipment
 | |
| from apps.em.serializers import EquipmentSerializer
 | |
| from apps.inm.models import MaterialBatch
 | |
| from apps.inm.serializers import MaterialBatchSerializer
 | |
| from apps.mtm.models import Step, SubProduction, SubprodctionMaterial, UsedStep
 | |
| from apps.pm.filters import PlanFilterSet, SubproductionProgressFilterSet
 | |
| from apps.system.mixins import CreateUpdateModelAMixin
 | |
| from apps.pm.serializers import GenSubPlanSerializer, PickNeedSerializer, PlanDestorySerializer, ProductionPlanCreateFromOrderSerializer, ProductionPlanSerializer, ResourceCalListSerializer, ResourceCalSerializer, SubProductionPlanListSerializer, SubProductionPlanUpdateSerializer, SubProductionProgressSerializer
 | |
| from rest_framework.mixins import CreateModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin
 | |
| from apps.pm.models import ProductionPlan, SubProductionProgress, SubProductionPlan
 | |
| from rest_framework.viewsets import GenericViewSet, ModelViewSet
 | |
| from django.shortcuts import render
 | |
| from apps.sam.models import Order
 | |
| from rest_framework.exceptions import APIException
 | |
| from rest_framework.response import Response
 | |
| from rest_framework.decorators import action
 | |
| from django.db.models import F
 | |
| from utils.tools import ranstr
 | |
| from django.db import transaction
 | |
| # Create your views here.
 | |
| 
 | |
| def updateOrderPlanedCount(order):
 | |
|     """
 | |
|     更新订单已排数量
 | |
|     """
 | |
|     planed_count = 0
 | |
|     plans = ProductionPlan.objects.filter(order=order)
 | |
|     for i in plans:
 | |
|         planed_count = planed_count + i.count
 | |
|     order.planed_count = planed_count
 | |
|     order.save()
 | |
| 
 | |
| class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModelMixin, RetrieveModelMixin, GenericViewSet):
 | |
|     """
 | |
|     生产计划
 | |
|     """
 | |
|     perms_map = {'*': '*'}
 | |
|     queryset = ProductionPlan.objects.select_related('order', 'order__contract', 'product')
 | |
|     serializer_class = ProductionPlanSerializer
 | |
|     search_fields = ['number', 'order__number', 'order__contract__number', 'product__number']
 | |
|     filterset_class = PlanFilterSet
 | |
|     ordering_fields = ['id']
 | |
|     ordering = ['-id']
 | |
| 
 | |
|     def get_serializer_class(self):
 | |
|         if self.action in ['create']:
 | |
|             return ProductionPlanCreateFromOrderSerializer
 | |
|         elif self.action == 'list':
 | |
|             return ProductionPlanSerializer
 | |
|         return super().get_serializer_class()
 | |
|         
 | |
|     @transaction.atomic()
 | |
|     def create(self, request, *args, **kwargs):
 | |
|         data = request.data
 | |
|         serializer = self.get_serializer(data=data)
 | |
|         serializer.is_valid(raise_exception=True)
 | |
|         if data.get('order', None):
 | |
|             order = Order.objects.get(pk=data['order'])
 | |
|             if order.planed_count >= data['count'] or data['count'] > 0:
 | |
|                 pass
 | |
|             else:
 | |
|                 raise APIException('排产数量错误')
 | |
|             instance = serializer.save(create_by=request.user, product=order.product, number='JH'+ranstr(7))
 | |
|             updateOrderPlanedCount(instance.order)
 | |
|         return Response()
 | |
|     
 | |
|     @action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=PlanDestorySerializer)
 | |
|     def deletes(self, request, pk=None):
 | |
|         """
 | |
|         批量物理删除
 | |
|         """
 | |
|         ProductionPlan.objects.filter(id__in=request.data.get('ids', [])).delete(soft=False)
 | |
|         return Response()
 | |
|     
 | |
|     @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=GenSubPlanSerializer)
 | |
|     @transaction.atomic
 | |
|     def gen_subplan(self, request, pk=None):
 | |
|         """
 | |
|         生成子计划
 | |
|         """
 | |
|         production_plan=self.get_object()
 | |
|         if production_plan.is_planed:
 | |
|             raise APIException('已生成子计划')
 | |
|         subps = SubProduction.objects.filter(product=production_plan.product).order_by('process__number')
 | |
|         for index, i in enumerate(subps):
 | |
|             steps = Step.objects.filter(usedstep__subproduction=i, usedstep__subproduction__is_deleted=False, 
 | |
|                                         usedstep__is_deleted=False, is_deleted=False).values('id', 'number', 'name', 'usedstep__remark')
 | |
|             instance = SubProductionPlan.objects.create(production_plan=production_plan, subproduction=i,
 | |
|                 start_date=production_plan.start_date, end_date=production_plan.end_date, 
 | |
|                 workshop=i.process.workshop, process=i.process, create_by=request.user,
 | |
|                 steps = list(steps), number=production_plan.number + '-' + str(index+1))
 | |
|             # 生成子计划物料需求/进度
 | |
|             for m in SubprodctionMaterial.objects.filter(subproduction=i, is_deleted=False).order_by('sort'):
 | |
|                 spro = SubProductionProgress.objects.create(material=m.material, type=m.type,
 | |
|                 is_main=m.is_main,
 | |
|                  count=m.count*production_plan.count, subproduction_plan=instance)
 | |
|         production_plan.is_planed=True
 | |
|         production_plan.state = ProductionPlan.PLAN_STATE_PLANING
 | |
|         production_plan.save()
 | |
|         return Response()
 | |
| 
 | |
| class SubProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, UpdateModelMixin, GenericViewSet):
 | |
|     """
 | |
|     子生产计划-列表/修改
 | |
|     """
 | |
|     perms_map = {'*': '*'}
 | |
|     queryset = SubProductionPlan.objects.select_related('process', 'workshop', 'subproduction', 'product', 'production_plan__product')
 | |
|     search_fields = []
 | |
|     serializer_class = SubProductionPlanListSerializer
 | |
|     filterset_fields = ['production_plan', 'process', 'state', 'product', 'workshop']
 | |
|     ordering_fields = ['process__number']
 | |
|     ordering = ['process__number']
 | |
| 
 | |
|     def get_serializer_class(self):
 | |
|         if self.action == 'list':
 | |
|             return SubProductionPlanListSerializer
 | |
|         elif self.action == 'update':
 | |
|             return SubProductionPlanUpdateSerializer
 | |
|         return super().get_serializer_class()
 | |
| 
 | |
|     @action(methods=['get'], detail=True, perms_map={'get':'*'}, serializer_class=SubProductionProgressSerializer)
 | |
|     def progress(self, request, pk=None):
 | |
|         """
 | |
|         生产进度详情
 | |
|         """
 | |
|         obj = self.get_object()
 | |
|         serializer = SubProductionProgressSerializer(instance=obj.progress_subplan, many=True)
 | |
|         return Response(serializer.data)
 | |
| 
 | |
|     @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=serializers.Serializer)
 | |
|     @transaction.atomic
 | |
|     def issue(self, request, pk=None):
 | |
|         """
 | |
|         下达任务
 | |
|         """
 | |
|         obj = self.get_object()
 | |
|         if obj.state == SubProductionPlan.SUBPLAN_STATE_PLANING:
 | |
|             obj.state = SubProductionPlan.SUBPLAN_STATE_ASSGINED
 | |
|             obj.save()
 | |
|             plan = obj.production_plan
 | |
|             if plan.state == ProductionPlan.PLAN_STATE_PLANING:
 | |
|                 plan.state = ProductionPlan.PLAN_STATE_ASSGINED
 | |
|                 plan.save()
 | |
|             return Response()
 | |
|         raise APIException('计划状态有误')
 | |
|     
 | |
|     @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=serializers.Serializer)
 | |
|     def start(self, request, pk=None):
 | |
|         """
 | |
|         开始生产
 | |
|         """
 | |
|         obj = self.get_object()
 | |
|         if obj.state in [SubProductionPlan.SUBPLAN_STATE_ASSGINED, SubProductionPlan.SUBPLAN_STATE_ACCEPTED]:
 | |
|             obj.state = SubProductionPlan.SUBPLAN_STATE_WORKING
 | |
|             obj.start_date_real = timezone.now()
 | |
|             obj.save()
 | |
|             plan = obj.production_plan
 | |
|             if plan.state in [ProductionPlan.PLAN_STATE_ASSGINED, ProductionPlan.PLAN_STATE_ACCEPTED]:
 | |
|                 plan.state = ProductionPlan.PLAN_STATE_WORKING
 | |
|                 plan.save()
 | |
|             return Response()
 | |
|         raise APIException('计划状态有误')
 | |
|     
 | |
|     @action(methods=['get'], detail=True, perms_map={'get':'*'}, serializer_class=serializers.Serializer)
 | |
|     def pick_need_(self, request, pk=None):
 | |
|         """
 | |
|         领料需求清单
 | |
|         """
 | |
|         obj = self.get_object()
 | |
|         instance = SubProductionProgress.objects.filter(subproduction_plan=obj, type=SubprodctionMaterial.SUB_MA_TYPE_IN)
 | |
|         serializer = SubProductionProgressSerializer(instance=instance, many=True)
 | |
|         return Response(serializer.data)
 | |
|     
 | |
|     @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=serializers.Serializer)
 | |
|     def pick_need(self, request, pk=None):
 | |
|         """
 | |
|         领料需求清单/库存数
 | |
|         """
 | |
|         obj = self.get_object()
 | |
|         instance = SubProductionProgress.objects.filter(subproduction_plan=obj, type=SubprodctionMaterial.SUB_MA_TYPE_IN)
 | |
|         serializer = SubProductionProgressSerializer(instance=instance, many=True)
 | |
|         need = serializer.data
 | |
|         materials = []
 | |
|         for i in need:
 | |
|             materials.append(i['material'])
 | |
|         objs = MaterialBatch.objects.filter(material__id__in=materials, count__gt=0).order_by('material__number')
 | |
|         have = MaterialBatchSerializer(instance=objs, many=True).data
 | |
|         return Response({'need':need, 'have':have})
 | |
| 
 | |
| class SubProductionProgressViewSet(ListModelMixin, GenericViewSet):
 | |
|     """
 | |
|     生产进度
 | |
|     """
 | |
|     perms_map = {'*': '*'}
 | |
|     queryset = SubProductionProgress.objects.select_related('material', 'subproduction_plan')
 | |
|     search_fields = []
 | |
|     serializer_class = SubProductionProgressSerializer
 | |
|     filterset_class = SubproductionProgressFilterSet
 | |
|     ordering_fields = ['id']
 | |
|     ordering = ['id']
 | |
| 
 | |
| class ResourceViewSet(GenericViewSet):
 | |
|     
 | |
|     perms_map = {'*': '*'}
 | |
|     @action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=ResourceCalListSerializer)
 | |
|     def cal(self, request, pk=None):
 | |
|         """
 | |
|         物料消耗计算
 | |
|         """
 | |
|         rdata = request.data
 | |
|         serializer = self.get_serializer(data=rdata)
 | |
|         serializer.is_valid(raise_exception=True)
 | |
|         res_d_list = []
 | |
|         res = []
 | |
|         for i in rdata:
 | |
|             # 计算输入物料
 | |
|             materials = SubprodctionMaterial.objects.filter(subproduction__product__id=i['id'], 
 | |
|             subproduction__is_deleted=False, is_deleted=False, material__type__in=[3,4], type=1).order_by('material__number')\
 | |
|                 .values('material__id', 'material__name', 'material__number', 'material__type', 'count', 'material__count')
 | |
|             l_m = list(materials)
 | |
|             for m in l_m:
 | |
|                 if m['material__id'] in res_d_list:
 | |
|                     index = res_d_list.index(m['material__id'])
 | |
|                     res[index]['count'] = res[index]['count'] + m['count']*i['count']
 | |
|                 else:
 | |
|                     res_d_list.append(m['material__id'])
 | |
|                     res.append({'id':m['material__id'], 'name':m['material__name'],
 | |
|                      'type':m['material__type'], 'number':m['material__number'], 
 | |
|                      'count':m['count']*i['count'], 'inv_count':m['material__count']})
 | |
|         return Response(res)
 | |
| 
 | |
|     @action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=ResourceCalListSerializer)
 | |
|     def cal_equip(self, request, pk=None):
 | |
|         """
 | |
|         设备状态查看
 | |
|         """
 | |
|         rdata = request.data
 | |
|         serializer = self.get_serializer(data=rdata)
 | |
|         serializer.is_valid(raise_exception=True)
 | |
|         rdata_l = []
 | |
|         for i in rdata:
 | |
|             rdata_l.append(i['id'])
 | |
|         subproductions = SubProduction.objects.filter(product__id__in=rdata_l, is_deleted=False)
 | |
|         steps = Step.objects.filter(usedstep__is_deleted=False, usedstep__subproduction__in=subproductions)
 | |
|         equips = Equipment.objects.filter(step_equips__in=steps, is_deleted=False).distinct()
 | |
|         serializer = EquipmentSerializer(instance=equips, many=True)
 | |
|         return Response(serializer.data)
 |