from datetime import date, timedelta from django.shortcuts import render 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 from apps.wpm.models import WProduct, WproductFlow from django.db.models import Count, F # 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 ProcessYieldView(CreateAPIView): """ 工序成品率统计 """ perms_map = {'get':'*'} 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'] ).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)