164 lines
6.4 KiB
Python
164 lines
6.4 KiB
Python
|
|
from datetime import date, timedelta
|
|
from django.shortcuts import render
|
|
from idna import valid_contextj
|
|
from numpy import number
|
|
from rest_framework import serializers
|
|
from rest_framework.generics import ListAPIView, CreateAPIView
|
|
from rest_framework.views import APIView
|
|
from rest_framework.response import Response
|
|
from apps.hrm.models import ClockRecord
|
|
from apps.mtm.models import Process, Step
|
|
from apps.pm.models import ProductionPlan, SubProductionPlan
|
|
from apps.srm.serializers import AtWorkCountSerializer, PlanGanttSerializer, ProcessYieldSerializer, ProductCountSerializer, SrmCountSerializer
|
|
from apps.srm.services import SrmServices
|
|
from apps.wpm.models import WProduct, WproductFlow
|
|
from django.db.models import Count, F, Sum
|
|
# Create your views here.
|
|
|
|
class GanttPlan(ListAPIView):
|
|
"""
|
|
计划-子计划甘特图
|
|
"""
|
|
perms_map = {'get':'*'}
|
|
serializer_class = PlanGanttSerializer
|
|
queryset = ProductionPlan.objects.filter(is_deleted=False, is_planed=True).prefetch_related('subplan_plan', 'subplan_plan__process')
|
|
ordering = ['-id']
|
|
|
|
class ProductCountView(CreateAPIView):
|
|
"""
|
|
产品数量统计
|
|
"""
|
|
perms_map = {'post':'*'}
|
|
serializer_class = ProductCountSerializer
|
|
def create(self, request, *args, **kwargs):
|
|
serializer = self.get_serializer(data=request.data)
|
|
serializer.is_valid(raise_exception=True)
|
|
vdata = serializer.validated_data
|
|
res = SrmServices.get_product_count(**vdata)
|
|
return Response(res)
|
|
|
|
|
|
class PlanCountView(CreateAPIView):
|
|
"""
|
|
计划数量统计
|
|
"""
|
|
perms_map = {'post':'*'}
|
|
serializer_class = SrmCountSerializer
|
|
|
|
def create(self, request, *args, **kwargs):
|
|
serializer = self.get_serializer(data=request.data)
|
|
serializer.is_valid(raise_exception=True)
|
|
vdata = serializer.validated_data
|
|
res = SrmServices.get_plan_count(**vdata)
|
|
return Response(res)
|
|
|
|
class OrderCountView(CreateAPIView):
|
|
"""
|
|
订单数量统计
|
|
"""
|
|
perms_map = {'post':'*'}
|
|
serializer_class = SrmCountSerializer
|
|
|
|
def create(self, request, *args, **kwargs):
|
|
serializer = self.get_serializer(data=request.data)
|
|
serializer.is_valid(raise_exception=True)
|
|
vdata = serializer.validated_data
|
|
res = SrmServices.get_order_count(**vdata)
|
|
return Response(res)
|
|
|
|
class ProcessNowView(CreateAPIView):
|
|
"""
|
|
工序当前进度
|
|
"""
|
|
perms_map = {'post':'*'}
|
|
serializer_class = serializers.Serializer
|
|
|
|
def create(self, request, *args, **kwargs):
|
|
objs = SubProductionPlan.objects.filter(production_plan__state__in =[ProductionPlan.PLAN_STATE_WORKING,
|
|
ProductionPlan.PLAN_STATE_ASSGINED]).order_by('process__number').values('process',
|
|
'process__name').annotate(count_ok=Sum('count_ok'),
|
|
count=Sum('count'), count_real=Sum('count_real'), count_notok=Sum('count_notok'))
|
|
return Response(objs)
|
|
|
|
class ProcessYieldView(CreateAPIView):
|
|
"""
|
|
工序成品率统计
|
|
"""
|
|
perms_map = {'post':'*'}
|
|
serializer_class = ProcessYieldSerializer
|
|
|
|
|
|
def create(self, request, *args, **kwargs):
|
|
serializer = self.get_serializer(data=request.data)
|
|
serializer.is_valid(raise_exception=True)
|
|
vdata = serializer.validated_data
|
|
wpfs = WproductFlow.objects.filter(is_lastlog=True)
|
|
if vdata.get('datetime_start', None):
|
|
wpfs = wpfs.filter(update_time__gte = vdata.get('datetime_start'))
|
|
if vdata.get('datetime_end', None):
|
|
wpfs = wpfs.filter(update_time__lte = vdata.get('datetime_end'))
|
|
# 根据产品日志记录进行聚合
|
|
count_ok_g = list(wpfs.filter(act_state__in=[WProduct.WPR_ACT_STATE_INM,
|
|
WProduct.WPR_ACT_STATE_OK, WProduct.WPR_ACT_STATE_SELLED]).values('step__process__id').annotate(count_ok=Count('id')))
|
|
count_notok_g = list(
|
|
(
|
|
wpfs.filter(act_state__in=[WProduct.WPR_ACT_STATE_NOTOK, WProduct.WPR_ACT_STATE_SCRAP]).exclude(step__process__id=1)
|
|
| wpfs.filter(act_state__in=[WProduct.WPR_ACT_STATE_NOTOK, WProduct.WPR_ACT_STATE_SCRAP],
|
|
step__process__id=1).exclude(number=None)
|
|
)\
|
|
.values('step__process__id',
|
|
).annotate(count_notok=Count('id')))
|
|
ret = []
|
|
process_l = list(Process.objects.filter(is_deleted=False).order_by('number').values('id', 'name'))
|
|
for i in process_l:
|
|
ret_item = {'id':i['id'], 'name':i['name'], 'count_ok':0, 'count_notok':0, 'rate':1}
|
|
for m in count_ok_g:
|
|
if m['step__process__id'] == ret_item['id']:
|
|
ret_item['count_ok'] = m['count_ok']
|
|
for n in count_notok_g:
|
|
if n['step__process__id'] == ret_item['id']:
|
|
ret_item['count_notok'] = n['count_notok']
|
|
rate = (ret_item['count_ok']/(ret_item['count_ok']+ret_item['count_notok'])) \
|
|
if ret_item['count_ok']+ret_item['count_notok']>0 else 1
|
|
ret_item['rate'] = rate
|
|
ret.append(ret_item)
|
|
return Response(ret)
|
|
|
|
|
|
class AtWorkCountView(CreateAPIView):
|
|
"""
|
|
到岗天数统计
|
|
"""
|
|
perms_map = {'get':'*'}
|
|
serializer_class = AtWorkCountSerializer
|
|
|
|
def create(self, request, *args, **kwargs):
|
|
serializer = self.get_serializer(data=request.data)
|
|
serializer.is_valid(raise_exception=True)
|
|
vdata = serializer.validated_data
|
|
|
|
from workalendar.asia import China
|
|
cal = China()
|
|
count_workday = cal.get_working_days_delta(
|
|
date(vdata['year'], vdata['month'], 1),
|
|
(date(vdata['year'], vdata['month'], 1).replace(day=1)
|
|
+ timedelta(days=32)).replace(day=1) - timedelta(days=1)
|
|
)
|
|
ret = ClockRecord.objects.filter(
|
|
update_time__year = vdata['year'],
|
|
update_time__month = vdata['month'],
|
|
create_by__employee_user__show_atwork = True
|
|
).values(
|
|
user_id = F('create_by'),
|
|
number = F('create_by__employee_user__number'),
|
|
username = F('create_by__username'),
|
|
name = F('create_by__name'),
|
|
dept_name = F('create_by__dept__name')).annotate(
|
|
count = Count('id')
|
|
)
|
|
ret_list = list(ret)
|
|
for i in ret:
|
|
i['count_workday'] = count_workday
|
|
return Response(ret_list)
|