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)