diff --git a/apps/wpm/serializers.py b/apps/wpm/serializers.py index c5f1d29d..9b426aac 100644 --- a/apps/wpm/serializers.py +++ b/apps/wpm/serializers.py @@ -1305,3 +1305,8 @@ class BatchLogSerializer(CustomModelSerializer): model = BatchLog fields = "__all__" + +class BatchMgroupSerializer(serializers.Serializer): + # mgroup = serializers.PrimaryKeyRelatedField( + # label='工段', queryset=Mgroup.objects.all()) + mgroup_name = serializers.CharField(label="工段名") \ No newline at end of file diff --git a/apps/wpm/urls.py b/apps/wpm/urls.py index 1e49f18c..9dfb2fc4 100644 --- a/apps/wpm/urls.py +++ b/apps/wpm/urls.py @@ -7,6 +7,7 @@ from apps.wpm.views import (SfLogViewSet, StLogViewSet, SfLogExpViewSet, MlogbOutViewSet, FmlogViewSet, BatchStViewSet, MlogbwViewSet, MlogUserViewSet, BatchLogViewSet) from apps.wpm.datax import AnaViewSet +from apps.wpm.views_ana import BatchWorkView API_BASE_URL = 'api/wpm/' @@ -32,4 +33,5 @@ router.register('mloguser', MlogUserViewSet, basename='mloguser') router.register('batchlog', BatchLogViewSet, basename='batchlog') urlpatterns = [ path(API_BASE_URL, include(router.urls)), + path(API_BASE_URL + 'ana/batchwork/', BatchWorkView.as_view(), name='batchwork'), ] diff --git a/apps/wpm/views_ana.py b/apps/wpm/views_ana.py new file mode 100644 index 00000000..3688b3a6 --- /dev/null +++ b/apps/wpm/views_ana.py @@ -0,0 +1,90 @@ +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework.exceptions import ParseError +from drf_yasg.utils import swagger_auto_schema +from apps.mtm.models import Mgroup +from apps.wpm.serializers import BatchMgroupSerializer +from apps.wpm.models import WMaterial, Mlogb +from django.db.models import Q, Sum, F, ExpressionWrapper +from collections import defaultdict + + + +class BatchWorkView(APIView): + perms_map = {"post": "*"} + + @swagger_auto_schema( + operation_summary='工段批次加工进度', + request_body=BatchMgroupSerializer, + responses={200: []}, + ) + def post(self, request): + sr = BatchMgroupSerializer(data=request.data) + sr.is_valid(raise_exception=True) + vdata = sr.validated_data + try: + mgroup:Mgroup = Mgroup.objects.get(name=vdata['mgroup_name']) + except Exception: + raise ParseError(f"获取工段信息失败-{vdata['mgroup_name']}") + matoutIds = mgroup.process.get_canout_mat_ids() + + + # 待加工的批次 + wm_qs = WMaterial.objects.filter(mgroup=mgroup, count__gt=0) + wm_todo_qs = wm_qs.filter(state=WMaterial.WM_OK).exclude(material__id__in=matoutIds)|wm_qs.filter(state=WMaterial.WM_REPAIR) + wm_v = wm_todo_qs.order_by("batch").values("count", "batch", wmid=F("id")) + + # 对应的操作子日志投入 + mlogb_qs = Mlogb.objects.filter(mlog__mgroup=mgroup, wm_in__in=wm_todo_qs) + mlogb_qs_v = mlogb_qs.values("count_use", "mlog__submit_time", wmid=F("wm_in__id")) + + # 对应的操作子日志产出 + mlogb_qs2 = Mlogb.objects.filter(mlogb_from__in=mlogb_qs) + mlogb_qs2_v = mlogb_qs2.values("count_real", "count_ok", "mlog__submit_time", wmid=F("mlogb_from__wm_in__id")) + + # 1. 处理wm_v - 原始物料数据 + wm_dict = {item['wmid']: {'count': item['count'], 'batch': item['batch']} for item in wm_v} + + # 2. 处理mlogb_qs_v - 物料使用数据 + use_dict = defaultdict(lambda: {'count_use': 0, 'count_use_submit': 0, 'count_use_unsubmit': 0}) + for item in mlogb_qs_v: + wmid = item['wmid'] + if item['mlog__submit_time']: + use_dict[wmid]['count_use_submit'] += item['count_use'] + else: + use_dict[wmid]['count_use_unsubmit'] += item['count_use'] + use_dict[wmid]['count_use'] += item['count_use'] + + # 3. 处理mlogb_qs2_v - 物料产出数据 + output_dict = defaultdict(lambda: {'count_real': 0, 'count_ok': 0}) + for item in mlogb_qs2_v: + if item['mlog__submit_time']: # 只统计已提交的记录 + wmid = item['wmid'] + output_dict[wmid]['count_real'] += item['count_real'] + output_dict[wmid]['count_ok'] += item['count_ok'] + + # 合并所有数据 + result = [] + for wmid, wm_data in wm_dict.items(): + use_data = use_dict.get(wmid, {}) + output_data = output_dict.get(wmid, {}) + + count = wm_data['count'] + + row = { + 'wmid': wmid, + 'batch': wm_data['batch'], + 'count_todo': count - use_data.get('count_use_unsubmit', 0), + 'count_working': use_data.get('count_use_unsubmit', 0), + 'count_real': output_data.get('count_real', 0), + 'count_ok': output_data.get('count_ok', 0), + 'count': count + } + result.append(row) + return Response(result) + + + + + + \ No newline at end of file