package com.ximai.mes.pro.service.impl.task;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.StopWatch;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ximai.common.constant.UserConstants;
import com.ximai.common.exception.ServiceException;
import com.ximai.common.utils.SecurityUtils;
import com.ximai.common.utils.data.DataUtil;
import com.ximai.common.utils.data.DateUtils;
import com.ximai.common.utils.data.ExceptionUtil;
import com.ximai.common.utils.data.StringUtils;
import com.ximai.mes.constant.*;
import com.ximai.mes.face.sap.SapService;
import com.ximai.mes.md.domain.MdItem;
import com.ximai.mes.md.domain.MdWorkstation;
import com.ximai.mes.md.domain.MdWorkunit;
import com.ximai.mes.md.mapper.MdItemMapper;
import com.ximai.mes.md.mapper.MdWorkstationMapper;
import com.ximai.mes.md.mapper.MdWorkunitMapper;
import com.ximai.mes.md.service.IMdWorkstationService;
import com.ximai.mes.md.service.IMdWorkunitService;
import com.ximai.mes.md.vo.MdItemVo;
import com.ximai.mes.pro.domain.*;
import com.ximai.mes.pro.domain.proWorkOrder.ProWorkOrderProcess;
import com.ximai.mes.pro.domain.proWorkOrder.ProWorkOrderProcessTool;
import com.ximai.mes.pro.domain.proWorkOrder.ProWorkorder;
import com.ximai.mes.pro.domain.task.*;
import com.ximai.mes.pro.domain.vo.*;
import com.ximai.mes.pro.domain.vo.proWorkOrder.BuildPackageParams2;
import com.ximai.mes.pro.domain.vo.proWorkOrder.WorkorderPackage;
import com.ximai.mes.pro.domain.vo.proWorkOrder.WorkorderPackagePrint;
import com.ximai.mes.pro.domain.vo.proWorkOrder.WorkorderPackageResult;
import com.ximai.mes.pro.domain.vo.task.FeedbackPackageAddParams;
import com.ximai.mes.pro.domain.vo.task.FeedbackPackageInfo;
import com.ximai.mes.pro.domain.vo.task.FeedbackPackageQueryParams;
import com.ximai.mes.pro.mapper.ProProcessMapper;
import com.ximai.mes.pro.mapper.ProProductionLogMapper;
import com.ximai.mes.pro.mapper.ProRouteMapper;
import com.ximai.mes.pro.mapper.proWorkOrder.ProWorkOrderProcessMapper;
import com.ximai.mes.pro.mapper.proWorkOrder.ProWorkOrderProcessToolMapper;
import com.ximai.mes.pro.mapper.proWorkOrder.ProWorkorderMapper;
import com.ximai.mes.pro.mapper.task.ProTaskAssistProcessMapper;
import com.ximai.mes.pro.mapper.task.ProTaskMapper;
import com.ximai.mes.pro.mapper.task.ProTaskWorkorderMapper;
import com.ximai.mes.pro.mapper.task.ProTaskWorkunitMapper;
import com.ximai.mes.pro.schedule.AlgorithmDataSource;
import com.ximai.mes.pro.schedule.AlgorithmExtendDataSource;
import com.ximai.mes.pro.schedule.AlgorithmResultProcess;
import com.ximai.mes.pro.schedule.impl.BaoshenScheduleAlgorithmAdapter;
import com.ximai.mes.pro.schedule.impl.ScheduledResult;
import com.ximai.mes.pro.schedule.strategy.EquipmentSelectionStrategyImpl;
import com.ximai.mes.pro.schedule.strategy.EvaluateEquipment;
import com.ximai.mes.pro.schedule.strategy.EvaluateEquipmentFunction;
import com.ximai.mes.pro.service.*;
import com.ximai.mes.pro.service.proWorkOrder.IProWorkorderService;
import com.ximai.mes.pro.service.task.IProPackagePrintRecordService;
import com.ximai.mes.pro.service.task.IProTaskService;
import com.ximai.mes.pro.service.task.IProTaskWorkunitService;
import com.ximai.mes.qc.service.IQcIpqcService;
import com.ximai.mes.tm.domain.vo.TmToolRequestItemVo;
import com.ximai.mes.tm.service.ITmToolMachinesService;
import com.ximai.mes.tm.service.ITmToolRequestService;
import com.ximai.mes.wm.domain.WmProductRecpt;
import com.ximai.mes.wm.domain.WmProductRecptLine;
import com.ximai.mes.wm.service.IWmProductRecptLineService;
import com.ximai.mes.wm.service.IWmProductRecptService;
import com.ximai.system.mapper.SysUserMapper;
import com.ximai.system.strategy.AutoCodeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import static com.ximai.mes.constant.TaskWorkunitStatusEnum.BEGINNING;
import static com.ximai.mes.constant.TaskWorkunitStatusEnum.FINISHED;

/**
 * 生产任务Service业务层处理
 *
 * @date 2022-05-14
 */
@Service
public class ProTaskServiceImpl implements IProTaskService {
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Resource
    ProTaskAssistProcessMapper proTaskAssistProcessMapper;
    @Resource
    private ProTaskMapper proTaskMapper;
    @Autowired
    private ProTaskWorkorderMapper proTaskWorkorderMapper;
    @Autowired
    private IQcIpqcService qcIpqcService;
    @Resource
    private MdWorkunitMapper mdWorkunitMapper;
    @Autowired
    private IProTaskWorkunitService proTaskWorkunitService;
    @Autowired
    private ITmToolMachinesService tmToolMachinesService;
    @Autowired
    private ITmToolRequestService tmToolRequestService;
    @Autowired
    private IProMaterialRequestService iProMaterialRequestService;
    @Autowired
    private ProWorkorderMapper proWorkorderMapper;
    @Autowired
    private ProWorkOrderProcessMapper proWorkOrderProcessMapper;
    @Autowired
    private ProTaskWorkunitMapper proTaskWorkunitMapper;
    @Autowired
    private ProRouteMapper proRouteMapper;
    @Autowired
    private IWmProductRecptService wmProductRecptService;
    @Autowired
    private ProProcessMapper proProcessMapper;
    @Autowired
    private IProWorkorderService proWorkorderService;
    @Autowired
    private IWmProductRecptLineService wmProductRecptLineService;
    @Autowired
    private IProProcessService iProProcessService;
    @Autowired
    private AutoCodeUtil autoCodeUtil;
    @Autowired
    private MdItemMapper itemMapper;
    @Autowired
    private MdWorkstationMapper workstationMapper;
    @Autowired
    private IMdWorkstationService mdWorkstationService;
    @Autowired
    private ProProductionLogMapper proProductionLogMapper;
    @Autowired
    private ProWorkOrderProcessToolMapper proWorkOrderProcessToolMapper;
    @Autowired
    private IProFeedbackService proFeedbackService;
    @Resource
    private SysUserMapper sysUserMapper;
    @Autowired
    private IProStartWorkService proStartWorkService;
    @Autowired
    private SapService sapService;
    @Autowired
    private ProFdQrcodePrintRecordServiceImpl proFdQrcodePrintRecordService;
    @Autowired
    private AlgorithmResultProcess algorithmResultProcess;
    @Autowired
    private AlgorithmDataSource algorithmDataSource;
    @Autowired
    private AlgorithmExtendDataSource equipmentNewestTaskAlgorithmData;
    @Autowired
    private AlgorithmExtendDataSource scheduleSetupRuleAlgorithmData;
    @Autowired
    private EvaluateEquipment evaluateEquipmentChangeOver;
    @Autowired
    private IProPackagePrintRecordService proPackagePrintRecordService;
    @Autowired
    private IProRecoilMaterialService proRecoilMaterialService;
    @Autowired
    private IProMaterialRequestService proMaterialRequestService;

    @Resource
    private IMdWorkunitService iMdWorkunitService;


    /**
     * 查询生产任务
     *
     * @param taskId 生产任务主键
     * @return 生产任务
     */
    @Override
    public ProTask selectProTaskByTaskId(Long taskId) {
        return proTaskMapper.selectProTaskByTaskId(taskId);
    }

    @Override
    public ProTask getIpqcInsertInfo(String arrangeCode, Long workorderId, Long processId) {
        QueryWrapper<ProWorkOrderProcess> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotEmpty(workorderId), "t3.workorder_id", workorderId);
        queryWrapper.eq(StringUtils.isNotEmpty(arrangeCode), "t3.arrange_code", arrangeCode);
        queryWrapper.eq(StringUtils.isNotEmpty(processId), "t1.process_id", processId);
        List<ProWorkOrderProcess> proWorkOrderProcesses = proWorkOrderProcessMapper.selectListByQw(queryWrapper);
        ProWorkOrderProcess proWorkOrderProcess = proWorkOrderProcesses.get(0);

        ProTask queryObj = new ProTask();
        queryObj.setWorkorderId(proWorkOrderProcess.getWorkorderId());
        queryObj.setProcessId(proWorkOrderProcess.getProcessId());
        queryObj.setProcessId(proWorkOrderProcess.getProcessId());
        QueryWrapper<ProTask> proTaskQueryWrapper = new QueryWrapper<>();
        proTaskQueryWrapper.eq(StringUtils.isNotEmpty(arrangeCode), "arrange_code", arrangeCode);
        proTaskQueryWrapper.eq(StringUtils.isNotEmpty(processId), "process_id", processId);
        List<ProTask> proTaskList = proTaskMapper.selectListByQw(proTaskQueryWrapper);
        ProTask task = proTaskList.get(0);
        task.setWorkorderId(proWorkOrderProcess.getWorkorderId());
        return task;
    }

    @Override
    public List<TmToolRequestItemVo> getToolOnProcessTemplate(ProTaskWorkunit proTaskWorkunit) {
        List<TmToolRequestItemVo> result = new ArrayList<>();
        ProTaskVo proTaskVo = new ProTaskVo();
        ProTask queryObj = new ProTask();
        queryObj.setTaskId(proTaskWorkunit.getTaskId());
        queryObj.setTaskWorkunitId(proTaskWorkunit.getTaskWorkunitId());
        List<ProTask> proTaskList = proTaskMapper.selectProTaskDetailList(queryObj);
        if (CollectionUtil.isEmpty(proTaskList)) {
            return result;
        }

        proTaskVo = proTaskList.get(0).deepCopyObj(ProTaskVo.class);

        Long taskId = proTaskVo.getTaskId();
        Long processId = proTaskVo.getProcessId();
        Long taskWorkunitId = proTaskVo.getTaskWorkunitId();
        ProTaskWorkunit taskWorkunit = proTaskWorkunitService.selectProTaskWorkunitByTaskWorkunitId(taskWorkunitId);
//        int i = 0;
//        int requestNum = 0;
        //如果生产工单的工艺下没有设置工装夹具则不生成申请单
        Long workorderProcessId;


        //同过任务单id查询所有工单
        ProTaskWorkorder proTaskWorkorder = new ProTaskWorkorder();
        proTaskWorkorder.setTaskId(taskId);
        List<ProTaskWorkorder> proTaskWorkorders = proTaskWorkorderMapper.selectProTaskWorkorderList(proTaskWorkorder);
        if (CollectionUtil.isEmpty(proTaskWorkorders)) {
            return result;
        }

        List<Long> workOrderIdList = proTaskWorkorders.stream().map(ProTaskWorkorder::getWorkorderId).collect(Collectors.toList());
        List<ProWorkOrderProcess> proWorkOrderProcessVoList = new ArrayList<>();
        for (Long workOrderId : workOrderIdList) {
//            ProWorkOrderProcess proWorkOrderProcessVo = proWorkOrderProcessMapper.selectProWorkOrderProcessByProcessId(workOrderId, processId);//找到工单工序
            QueryWrapper<ProWorkOrderProcess> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("t1.workorder_id", workOrderId);
            queryWrapper.eq("t1.process_id", processId);
            List<ProWorkOrderProcess> proWorkOrderProcesses = proWorkOrderProcessMapper.selectListByQw(queryWrapper);
            ProWorkOrderProcess proWorkOrderProcess = proWorkOrderProcesses.get(0);

            if (proWorkOrderProcess != null) {
                proWorkOrderProcessVoList.add(proWorkOrderProcess);
            }
        }

        if (CollectionUtil.isEmpty(proWorkOrderProcessVoList)) {
            return result;
        }

        if (CollectionUtil.isEmpty(proWorkOrderProcessVoList)) {
            return result;
        }

        List<ProWorkOrderProcessTool> proWorkOrderProcessTools = new ArrayList<>();
        for (ProWorkOrderProcess proWorkOrderProcessVo : proWorkOrderProcessVoList) {
            workorderProcessId = proWorkOrderProcessVo.getWorkorderProcessId();
            List<ProWorkOrderProcessTool> proWorkOrderProcessToolsList = proWorkOrderProcessToolMapper.selectProWorkOrderProcessToolByWorkorderProcessId(workorderProcessId);
            proWorkOrderProcessTools.addAll(proWorkOrderProcessToolsList);
        }

        if (CollectionUtil.isNotEmpty(proWorkOrderProcessTools)) {
            //根据tool_id进行判重，只保留要求数量最大的
            Map<Long, ProWorkOrderProcessTool> toolIdAndProcessToolMap = new HashMap<>();//tool_id,工装对象
            for (ProWorkOrderProcessTool proWorkOrderProcessTool : proWorkOrderProcessTools) {
                if (BeanUtil.isEmpty(toolIdAndProcessToolMap.get(proWorkOrderProcessTool.getToolId()))) {
                    toolIdAndProcessToolMap.put(proWorkOrderProcessTool.getToolId(), proWorkOrderProcessTool);
                } else {
                    ProWorkOrderProcessTool proWorkOrderProcessToolMap = toolIdAndProcessToolMap.get(proWorkOrderProcessTool.getToolId());
                    if (proWorkOrderProcessToolMap.getQuantity().compareTo(proWorkOrderProcessTool.getQuantity()) < 0) {//当map中的数量小于时，将新的替换
                        toolIdAndProcessToolMap.put(proWorkOrderProcessTool.getToolId(), proWorkOrderProcessTool);
                    }
                }
            }


            Set<Long> toolIds = toolIdAndProcessToolMap.keySet();
            for (Long toolId : toolIds) {
                ProWorkOrderProcessTool proWorkOrderProcessTool = toolIdAndProcessToolMap.get(toolId);
                TmToolRequestItemVo tmToolRequestItemVo = new TmToolRequestItemVo();
                tmToolRequestItemVo.setItemName(proWorkOrderProcessTool.getItemName());
                tmToolRequestItemVo.setItemId(proWorkOrderProcessTool.getToolId());
                tmToolRequestItemVo.setAllQuantity(proWorkOrderProcessTool.getQuantity().intValue());
                tmToolRequestItemVo.setNextMaintenPeriod(taskWorkunit.getQuantity().intValue());
                result.add(tmToolRequestItemVo);
            }
            return result;
        } else {
            return result;
        }
    }


    @Override
    public List<Map<String, String>> listMdItemByWorkUnit(Long id) {
        ArrayList<Map<String, String>> result = new ArrayList<>();
        ProTask proTask = this.selectProTaskByTaskId(id);
        if (proTask == null) {
            return result;
        }

        ProTaskVo proTaskVo = new ProTaskVo();
        if (StringUtils.isNotNull(proTask)) {
            BeanUtils.copyProperties(proTask, proTaskVo);
        }

        Long taskId = proTaskVo.getTaskId();
        Long processId = proTaskVo.getProcessId();

//        int i = 0;
//        int requestNum = 0;
        //如果生产工单的工艺下没有设置工装夹具则不生成申请单
        Long workorderProcessId;
        //同过任务单id查询所有工单
        ProTaskWorkorder proTaskWorkorder = new ProTaskWorkorder();
        proTaskWorkorder.setTaskId(taskId);
        List<ProTaskWorkorder> proTaskWorkorders = proTaskWorkorderMapper.selectProTaskWorkorderList(proTaskWorkorder);
        if (CollectionUtil.isEmpty(proTaskWorkorders)) {
            return result;
        }
        List<Long> workOrderIdList = proTaskWorkorders.stream().map(ProTaskWorkorder::getWorkorderId).collect(Collectors.toList());
        List<ProWorkOrderProcess> proWorkOrderProcessVoList = new ArrayList<>();
        for (Long workOrderId : workOrderIdList) {
            QueryWrapper<ProWorkOrderProcess> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("t1.workorder_id", workOrderId);
            queryWrapper.eq("t1.process_id", processId);
            List<ProWorkOrderProcess> proWorkOrderProcesses = proWorkOrderProcessMapper.selectListByQw(queryWrapper);
            ProWorkOrderProcess proWorkOrderProcess = proWorkOrderProcesses.get(0);
            proWorkOrderProcessVoList.add(proWorkOrderProcess);
        }
        if (CollectionUtil.isEmpty(proWorkOrderProcessVoList)) {
            return result;
        }

        List<ProWorkOrderProcessTool> proWorkOrderProcessTools = new ArrayList<>();
        for (ProWorkOrderProcess proWorkOrderProcessVo : proWorkOrderProcessVoList) {
            workorderProcessId = proWorkOrderProcessVo.getWorkorderProcessId();
            List<ProWorkOrderProcessTool> proWorkOrderProcessToolsList = proWorkOrderProcessToolMapper.selectProWorkOrderProcessToolByWorkorderProcessId(workorderProcessId);
            proWorkOrderProcessTools.addAll(proWorkOrderProcessToolsList);
        }

        if (CollectionUtil.isNotEmpty(proWorkOrderProcessTools)) {
            //根据tool_id进行判重，只保留要求数量最大的
            Map<Long, ProWorkOrderProcessTool> toolIdAndProcessToolMap = new HashMap<>();//tool_id,工装对象
            for (ProWorkOrderProcessTool proWorkOrderProcessTool : proWorkOrderProcessTools) {
                if (BeanUtil.isEmpty(toolIdAndProcessToolMap.get(proWorkOrderProcessTool.getToolId()))) {
                    toolIdAndProcessToolMap.put(proWorkOrderProcessTool.getToolId(), proWorkOrderProcessTool);
                } else {
                    ProWorkOrderProcessTool proWorkOrderProcessToolMap = toolIdAndProcessToolMap.get(proWorkOrderProcessTool.getToolId());
                    if (proWorkOrderProcessToolMap.getQuantity().compareTo(proWorkOrderProcessTool.getQuantity()) < 0) {//当map中的数量小于时，将新的替换
                        toolIdAndProcessToolMap.put(proWorkOrderProcessTool.getToolId(), proWorkOrderProcessTool);
                    }
                }
            }


            Set<Long> toolIds = toolIdAndProcessToolMap.keySet();
            for (Long toolId : toolIds) {
                MdItem mdItem = new MdItem();
                ProWorkOrderProcessTool proWorkOrderProcessTool = toolIdAndProcessToolMap.get(toolId);

                mdItem.setItemId(toolId);
                List<MdItemVo> list = itemMapper.selectMdItemList(mdItem);
                MdItemVo mdItemVo = list.get(0);
                Map<String, String> map = new HashMap<>();
                map.put("itemId", proWorkOrderProcessTool.getToolId().toString());
                map.put("itemName", mdItemVo.getItemName());
                map.put("AllQuantity", "1");
                map.put("nextMaintenPeriod", proWorkOrderProcessTool.getQuantity().toString());
                result.add(map);
//                ProWorkOrderProcessTool proWorkOrderProcessTool = toolIdAndProcessToolMap.get(toolId);
//                proWorkOrderProcessToolsNew.add(proWorkOrderProcessTool);
//                requestNum = requestNum + proWorkOrderProcessTool.getQuantity().intValue();
            }
            return result;
//            proWorkOrderProcessTools = proWorkOrderProcessToolsNew;
        } else {
            return result;
        }
    }

    @Override
    public ProTask selectProTaskByTaskCode(String taskCode) {
        return proTaskMapper.selectProTaskByTaskCode(taskCode);
    }


    /**
     * 查询生产任务列表
     *
     * @param proTask 生产任务
     * @return 生产任务
     */
    @Override
    public List<ProTask> selectProTaskList(ProTask proTask) {
        return proTaskMapper.selectProTaskList(proTask);
    }

    @Override
    public ProTask selectByArrangeCodeAndProcessId(String arrangeCode, Long processId) {
        return proTaskMapper.selectByArrangeCodeAndProcessId(arrangeCode, processId);
    }


    /**
     * 查询生产任务列表
     *
     * @param proTask 生产任务
     * @return 生产任务
     */
    @Override
    public List<ProTask> selectProTaskDetailList(ProTask proTask) {

        List<ProTask> proTasks1 = proTaskMapper.selectProTaskDetailList(proTask);
        List<ProTask> proTasks = proTasks1.stream().filter(s -> !s.getStatus().equals("FINISHED")).collect(Collectors.toList());

        List<ProTask> objects = null;
        if (StringUtils.isNotEmpty(proTask.getWorkorderCode())) {
            Set<String> arrangeCodes = proTasks.stream().map(ProTask::getArrangeCode).filter(Objects::nonNull).collect(Collectors.toSet());
            QueryWrapper<ProWorkorder> proWorkorderQueryWrapper = new QueryWrapper<>();
            proWorkorderQueryWrapper.in("arrange_code", arrangeCodes);
            proWorkorderQueryWrapper.eq("workorder_code", proTask.getWorkorderCode());
            List<ProWorkorder> proWorkorders = proWorkorderMapper.selectListByQw(proWorkorderQueryWrapper);
            objects = new ArrayList<>();
            if (CollectionUtil.isNotEmpty(proWorkorders)) {
                ProWorkorder proWorkorder = proWorkorders.get(0);
                String arrangeCode = proWorkorder.getArrangeCode();
                String workorderCode = proWorkorder.getWorkorderCode();
                for (ProTask task : proTasks) {
                    if (Objects.equals(task.getArrangeCode(), arrangeCode)) {
                        task.setWorkorderCode(workorderCode);
                        objects.add(task);
                    }
                }
            }
        }
        return objects != null ? objects : proTasks;
    }

    @Override
    public List<ProTask> selectProTaskJoinTaskWorkUnit(QueryWrapper<ProTask> proTask) {
        return proTaskMapper.selectProTaskJoinTaskWorkUnit(proTask);
    }

    @Override
    public List<ProTaskVo> selectProTaskJoinWorkorder(QueryWrapper<ProTask> proTask) {
        return proTaskMapper.selectProTaskJoinWorkorder(proTask);
    }

    /**
     * 新增生产任务
     *
     * @param proTask 生产任务
     * @return 结果
     */
    @Override
    public int insertProTask(ProTask proTask) {
        proTask.createAction();
        proTask.setTaskCode(autoCodeUtil.genSerialCode(UserConstants.TASK_CODE, null));
        return proTaskMapper.insertProTask(proTask);
    }

    @Override
    public int createProTask(ProTask proTask) {
        if (proTask.getQuantity().compareTo(BigDecimal.ZERO) != 1) {
            throw new RuntimeException("排产数量必须大于0！");
        }

        if (!StringUtils.isNotNull(proTask.getWorkstationId())) {
            throw new RuntimeException("请选择工作站！");
        }

        if (proTask.getDuration() <= 0) {
            throw new RuntimeException("生产时长必须大于0！");
        }

        //生产工单
        ProWorkorderQuery proWorkorderQuery = new ProWorkorderQuery();
        proWorkorderQuery.setArrangeCode(proTask.getArrangeCode());
        List<ProWorkorder> workorders = proWorkorderService.selectProWorkorderList(proWorkorderQuery);
        ProWorkorder order = workorders.get(0);
        proTask.setItemId(order.getProductId());
        proTask.setItemCode(order.getProductCode());
        proTask.setItemName(order.getProductName());
        proTask.setSpecification(order.getProductSpc());
        proTask.setUnitOfMeasure(order.getUnitOfMeasure());
        proTask.setClientId(order.getClientId());
        proTask.setClientCode(order.getClientCode());
        proTask.setClientName(order.getClientName());

        //工序信息
        ProProcess process = iProProcessService.selectProProcessByProcessId(proTask.getProcessId());
        if (StringUtils.isNotNull(process)) {
            proTask.setProcessId(process.getProcessId());
            proTask.setProcessCode(process.getProcessCode());
            proTask.setProcessName(process.getProcessName());
        } else {
            throw new RuntimeException("当前生产任务对应的工序信息无效！" + proTask.getProcessId());
        }

        //自动生成任务编号和名称
        proTask.setTaskName(proTask.getItemName() + "【" + proTask.getQuantity().toString() + "】" + proTask.getUnitOfMeasure());
        return this.insertProTask(proTask);
    }

    /**
     * 修改生产任务
     *
     * @param proTask 生产任务
     * @return 结果
     */
    @Override
    public int updateProTask(ProTask proTask) {
        ProTask proTaskInfo = this.selectProTaskByTaskId(proTask.getTaskId());
        ProProductionLog proProductionLog = new ProProductionLog();
        proProductionLog.setTaskId(proTaskInfo.getTaskId());
        proProductionLog.setWorkstationId(proTaskInfo.getWorkstationId());
        proProductionLog.setOperatorId(SecurityUtils.getUserId());
        proProductionLog.setOperatorName(SecurityUtils.getUsername());
        proProductionLog.setOperatorTime(DateUtils.getNowDate());
        proProductionLog.setStatus(proTaskInfo.getStatus());
        proProductionLog.setFaultDescription(proTaskInfo.getAttr1());
        proProductionLog.createAction();
        proProductionLogMapper.insertProProductionLog(proProductionLog);

        proTask.updateAction();
        return proTaskMapper.updateProTask(proTask);
    }

    /**
     * 批量删除生产任务
     *
     * @param taskIds 需要删除的生产任务主键
     * @return 结果
     */
    @Override
    public int deleteProTaskByTaskIds(Long[] taskIds) {
        return proTaskMapper.deleteProTaskByTaskIds(taskIds);
    }

    /**
     * 删除生产任务信息
     *
     * @param taskId 生产任务主键
     * @return 结果
     */
    @Override
    public int deleteProTaskByTaskId(Long taskId) {
        return proTaskMapper.deleteProTaskByTaskId(taskId);
    }

    /**
     * 新增任务单/合并任务单
     */
    @Override
    public List<ProTask> generateTask(List<ProWorkorderVo> proWorkorderList) {
        List<ProTask> resultTasks = new ArrayList<>();

        //工单按编排单分组
        Map<Object, List<ProWorkorderVo>> workordersGroupedByArrangeCode = proWorkorderList.stream()
                .collect(Collectors.groupingBy(ProWorkorderVo::getArrangeCode));
        for (Map.Entry<Object, List<ProWorkorderVo>> entry : workordersGroupedByArrangeCode.entrySet()) {
            BigDecimal quantity = BigDecimal.valueOf(0);
            List<ProWorkorderVo> workorderList = entry.getValue();
            for (ProWorkorderVo proWorkorder : workorderList) {
                if (!StringUtils.isNotNull(proWorkorder)) {
                    throw new RuntimeException("生产工单不存在!");
                }
                if (proWorkorder.getQuantity().compareTo(BigDecimal.ZERO) != 1) {
                    throw new RuntimeException("工单生产数量必须大于0！");
                }
                if (!StringUtils.isNotNull(proWorkorder.getRequestDate()) && proWorkorder.getRequestDate().before(DateUtils.getNowDate())) {
                    throw new RuntimeException("需求时间不能为空或小于当前时间");
                }
                if (!WorkorderStatusEnum.ORCHESTRATED.getValue().equals(proWorkorder.getStatus())) {
                    throw new ServiceException(String.format("%s工单未编排，请先执行编排操作", proWorkorder.getWorkorderCode()));
                }
                quantity = quantity.add(proWorkorder.getQuantity());
            }

            if (quantity.compareTo(BigDecimal.ZERO) != 1) {
                throw new RuntimeException("排产数量必须大于0！");
            }

            // 判断工艺路线是否一致、工艺路线是否存在
            Long routeId = workorderList.get(0).getRouteId();
            if (StringUtils.isEmpty(routeId.toString())) {
                throw new RuntimeException("请指定工艺路线!");
            }
            ProRoute proRoute = proRouteMapper.selectProRouteByRouteId(routeId);
            if (!StringUtils.isNotNull(proRoute)) {
                throw new RuntimeException("当前生产任务对应的工艺路线信息无效！");
            }
            for (ProWorkorderVo proWorkorder : workorderList) {
                Long id = proWorkorder.getRouteId();

                if (routeId.longValue() != id.longValue()) {
                    throw new RuntimeException("所选工单工艺路线不同! 不能合并!");
                }
            }

            // 获取第一个作为模板数据
            ProWorkorderVo proWorkorder = workorderList.get(0);
            Long workorderId = proWorkorder.getWorkorderId();

            // 获取工序列表
            QueryWrapper<ProWorkOrderProcessVo> query = new QueryWrapper<>();
            query.eq("pwop.workorder_id", workorderId);
            List<ProWorkOrderProcessVo> proWorkOrderProcessVoList = proWorkOrderProcessMapper.selectProWorkOrderProcess(query);
            if (proWorkOrderProcessVoList.isEmpty()) {
                throw new RuntimeException("当前生产任务对应的工艺路线不存在工序!");
            }


            String arrangeCode = proWorkorder.getArrangeCode();
            // 根据工序创建任务单
            int i = 1;
            for (ProWorkOrderProcessVo proWorkOrderProcessVo : proWorkOrderProcessVoList) {
                // 验证工序
                ProProcess proProcess = proProcessMapper.selectProProcessByProcessId(proWorkOrderProcessVo.getProcessId());
                if (!StringUtils.isNotNull(proProcess)) {
                    throw new RuntimeException("当前生产任务对应的工序信息无效！");
                }


                // 封装
                ProTask proTask = new ProTask();
                proTask.setWorkstationId(proWorkOrderProcessVo.getWorkstationId());
                proTask.setProcessId(proWorkOrderProcessVo.getProcessId());
                proTask.setItemId(proWorkorder.getProductId());
                proTask.setSpecification(proWorkorder.getProductSpc());
                proTask.setUnitOfMeasure(proWorkorder.getUnitOfMeasure());
                proTask.setQuantity(quantity);
                proTask.setOrdinal(i);
                //首工序，待加工数等于排产数
                if (i == 1) {
                    proTask.setQuantityWait(quantity);
                } else {
                    proTask.setQuantityWait(BigDecimal.ZERO);
                }

                //末道工序
                if (i == proWorkOrderProcessVoList.size()) {
                    proTask.setIsLastProcess(1);
                } else {
                    proTask.setIsLastProcess(0);
                }
                proTask.setColorCode(proWorkOrderProcessVo.getColorCode());
                proTask.setStatus(TaskStatusEnum.PREPARE.getStatus()); // 设置状态为草稿(待确认)
                proTask.setArrangeCode(arrangeCode);

                String prefix = arrangeCode + "-001" + "-";
                ProTask q = new ProTask();
                q.setTaskBatchStr(prefix);
                q.setProcessId(proWorkOrderProcessVo.getProcessId());
                List<ProTask> proTasks = this.selectProTaskList(q);
                Optional<String> max = proTasks.stream().filter(x -> x.getTaskBatch() != null && x.getTaskBatch() != "").map(x -> {
                    String[] split = x.getTaskBatch().split("-");
                    return split[split.length - 1];
                }).max(Comparator.comparing(String::valueOf));
                if (max.isPresent()) {
                    String maxNum = max.get() + 1;
                    proTask.setTaskBatch(prefix + maxNum);
                } else {
                    proTask.setTaskBatch(prefix + 1);
                }

                //自动生成任务编号和名称
                MdItem mdItem = itemMapper.selectMdItemById(proWorkorder.getProductId());
                proTask.setTaskName(mdItem.getItemName() + "【" + proTask.getQuantity().toString() + "】" + proTask.getUnitOfMeasure());

                // 保存
                this.insertProTask(proTask);
                resultTasks.add(proTask);
                Long taskId = proTask.getTaskId();

                // 保存到合并表
                for (ProWorkorderVo workorder : workorderList) {
                    ProTaskWorkorder proTaskWorkorder = new ProTaskWorkorder();
                    proTaskWorkorder.setTaskId(taskId);
                    proTaskWorkorder.setIdx((long) i);
                    proTaskWorkorder.setWorkorderId(workorder.getWorkorderId());
                    // 保存
                    proTaskWorkorderMapper.insertProTaskWorkorder(proTaskWorkorder);
                }
                i++;
            }

            long[] workorderIdArr = workorderList.stream()
                    .mapToLong(ProWorkorderVo::getWorkorderId)
                    .toArray();

            // 修改工单状态 -- 已生成任务单
            for (Long id : workorderIdArr) {
                //生成编排单号
                ProWorkorder proWorkorderUpdate = new ProWorkorder();
                proWorkorderUpdate.setStatus(WorkorderStatusEnum.ISSUED.getValue());
                proWorkorderUpdate.setArrangeCode(arrangeCode);
                proWorkorderUpdate.setWorkorderId(id);
                proWorkorderMapper.updateProWorkorder(proWorkorderUpdate);
            }
        }


        return resultTasks;
    }

    /**
     * 新增任务单/合并任务单
     */
    @Override
    public int insertProTasks(Long[] workorderIds) {
        List<ProWorkorder> proWorkorderList = proWorkorderMapper.selectProWorkorderGorupArrangeByWorkorderIds(workorderIds);

        //工单按编排单分组
        Map<Object, List<ProWorkorder>> workordersGroupedByArrangeCode = proWorkorderList.stream()
                .collect(Collectors.groupingBy(ProWorkorder::getArrangeCode));
        for (Map.Entry<Object, List<ProWorkorder>> entry : workordersGroupedByArrangeCode.entrySet()) {
            BigDecimal quantity = BigDecimal.valueOf(0);
            List<ProWorkorder> workorderList = entry.getValue();

            for (ProWorkorder proWorkorder : workorderList) {
                if (!StringUtils.isNotNull(proWorkorder)) {
                    return 4;
                }
                if (proWorkorder.getQuantity().compareTo(BigDecimal.ZERO) != 1) {
                    return 5;
                }
                if (!StringUtils.isNotNull(proWorkorder.getRequestDate()) && proWorkorder.getRequestDate().before(DateUtils.getNowDate())) {
                    return 9;
                }
                if (!WorkorderStatusEnum.ORCHESTRATED.getValue().equals(proWorkorder.getStatus())) {
                    throw new ServiceException(String.format("%s工单未编排，请先执行编排操作", proWorkorder.getWorkorderCode()));
                }
                quantity = quantity.add(proWorkorder.getQuantity());
            }

            if (quantity.compareTo(BigDecimal.ZERO) != 1) {
                return 6;
            }

            // 获取第一个作为模板数据
            ProWorkorder proWorkorder = workorderList.get(0);
            Long workorderId = proWorkorder.getWorkorderId();
            String arrangeCode = proWorkorder.getArrangeCode();

            // 获取工序列表
            QueryWrapper<ProWorkOrderProcessVo> query = new QueryWrapper<>();
            query.eq("pwop.workorder_id", workorderId);
            List<ProWorkOrderProcessVo> proWorkOrderProcessVoList = proWorkOrderProcessMapper.selectProWorkOrderProcess(query);
            if (proWorkOrderProcessVoList.isEmpty()) {
                return 7;
            }

//            String arrangeCode = autoCodeUtil.genSerialCode(UserConstants.ARRANGE_CODE, null);
            // 根据工序创建任务单
            int i = 1;
            for (ProWorkOrderProcessVo proWorkOrderProcessVo : proWorkOrderProcessVoList) {
                // 验证工序
                ProProcess proProcess = proProcessMapper.selectProProcessByProcessId(proWorkOrderProcessVo.getProcessId());
                if (!StringUtils.isNotNull(proProcess)) {
                    return 8;
                }

                ProTask proTask = new ProTask();
                // 封装
                proTask.setWorkstationId(proWorkOrderProcessVo.getWorkstationId());
                proTask.setProcessId(proWorkOrderProcessVo.getProcessId());
                proTask.setItemId(proWorkorder.getProductId());
                proTask.setSpecification(proWorkorder.getProductSpc());
                proTask.setUnitOfMeasure(proWorkorder.getUnitOfMeasure());
                proTask.setQuantity(quantity);
                proTask.setOrdinal(i);
                //首工序，待加工数等于排产数
                if (i == 1) {
                    proTask.setQuantityWait(quantity);
                } else {
                    proTask.setQuantityWait(BigDecimal.ZERO);
                }

                //末道工序
                if (i == proWorkOrderProcessVoList.size()) {
                    proTask.setIsLastProcess(1);
                } else {
                    proTask.setIsLastProcess(0);
                }
                proTask.setColorCode(proWorkOrderProcessVo.getColorCode());
                proTask.setStatus(TaskStatusEnum.PREPARE.getStatus()); // 设置状态为草稿(待确认)
                proTask.setArrangeCode(arrangeCode);
                proTask.setTaskBatch(arrangeCode + "-001");
                //自动生成任务编号和名称
                MdItem mdItem = itemMapper.selectMdItemById(proWorkorder.getProductId());
                proTask.setTaskName(mdItem.getItemName() + "【" + proTask.getQuantity().toString() + "】" + proTask.getUnitOfMeasure());

                // 保存
                this.insertProTask(proTask);
                Long taskId = proTask.getTaskId();

                // 保存到合并表
                for (ProWorkorder workorder : workorderList) {
                    ProTaskWorkorder proTaskWorkorder = new ProTaskWorkorder();
                    proTaskWorkorder.setTaskId(taskId);
                    proTaskWorkorder.setIdx((long) i);
                    proTaskWorkorder.setWorkorderId(workorder.getWorkorderId());
                    // 保存
                    proTaskWorkorderMapper.insertProTaskWorkorder(proTaskWorkorder);
                }
                i++;
            }

            long[] workorderIdArr = workorderList.stream()
                    .mapToLong(ProWorkorder::getWorkorderId)
                    .toArray();

            // 修改工单状态 -- 已生成任务单
            for (Long id : workorderIdArr) {
                //生成编排单号
                ProWorkorder proWorkorderUpdate = new ProWorkorder();
                proWorkorderUpdate.setStatus(WorkorderStatusEnum.ISSUED.getValue());
                proWorkorderUpdate.setArrangeCode(arrangeCode);
                proWorkorderUpdate.setWorkorderId(id);
                proWorkorderMapper.updateProWorkorder(proWorkorderUpdate);
            }
        }

        return 1;
    }

    /**
     * 返回甘特图对象
     *
     * @return
     */
    @Override
    public GanttTask getGanttTaskList() {
        GanttTask ganttTask = new GanttTask();
        List<GanttData> ganttData = new ArrayList<GanttData>();
        List<GanttLink> ganttLinks = new ArrayList<GanttLink>();

        // 当前时间
        Date nowDate = DateUtils.getNowDate();

        // 获取所有工作站信息
        MdWorkstation workstationQ = new MdWorkstation();
        workstationQ.setEnableFlag("Y");
        List<MdWorkstation> workstationList = workstationMapper.selectMdWorkstationList(workstationQ);
        if (!StringUtils.isNotNull(workstationList)) {
            return null;
        }

        // 遍历工作站信息
        for (MdWorkstation workstation : workstationList) {

            GanttData workstationData = new GanttData();
            workstationData.setId("MD" + workstation.getWorkstationId());
            workstationData.setType(UserConstants.GANTT_TASK_TYPE_PROJECT);
            workstationData.setText(workstation.getWorkstationName());

            // 查询工作站下的所有任务单
            ProTask proTask = new ProTask();
            proTask.setWorkstationId(workstation.getWorkstationId());
            BigDecimal quantity = BigDecimal.valueOf(0); // 工作站的生产数量
            BigDecimal quantityProduced = BigDecimal.valueOf(0); // 工作站已生产数量
            Date endDate = nowDate; // 工作站的最晚结束时间
            Date startDate = nowDate; // 工作站的最早开始时间
            Date date = new Date();

            // 基于时间查询--结束时间晚于当前时间
            proTask.setEndTime(new Date());
            proTask.setStatus(TaskStatusEnum.PREPARE.getStatus());
            List<ProTask> proTaskList = proTaskMapper.selectProTaskList(proTask);
            if (proTaskList.size() == 0) {
                continue;
            }

            for (ProTask task : proTaskList) {
                GanttData taskData = new GanttData();
                taskData.setId("MD" + task.getTaskId());
                taskData.setParent("MD" + workstation.getWorkstationId()); // 将工作站id设置为父id
                taskData.setColor(task.getColorCode()); // 设置甘特图颜色
                taskData.setType(UserConstants.GANTT_TASK_TYPE_TASK);
                BigDecimal taskQuantity = task.getQuantity();
                BigDecimal taskQuantityProduced = task.getQuantityProduced();
                quantity = quantity.add(taskQuantity); // 添加到工作站总排产数量中
                quantityProduced = quantityProduced.add(taskQuantityProduced); // 添加到工作站总已生产数量中
                taskData.setProgress(taskQuantityProduced.divide(taskQuantity, RoundingMode.HALF_UP).floatValue()); // 设置生产进度
                Date end_date = task.getEndTime();
                // 比较结束时间
                if (endDate.before(end_date)) {
                    endDate = end_date;
                }
                taskData.setText(task.getItemName() + taskQuantity.stripTrailingZeros().toPlainString() + task.getUnitOfMeasure()); // 默认使用“[产品]+[数量]+[单位]”格式。
                taskData.setWorkstation(taskData.getWorkstation());
                taskData.setQuantity(taskQuantity);
                Date startTime = task.getStartTime();
                // 比较开始时间
                if (startTime.before(startDate)) {
                    startDate = startTime;
                }
                taskData.setStart_date(startTime);
                taskData.setDuration(task.getDuration());
                taskData.setEnd_date(end_date);
                taskData.setProcess(task.getProcessName());
                taskData.setProduct(task.getItemName());

                ganttData.add(taskData);
            }
            // 计算工作站的生产时长及生产进度
            Long duration = (endDate.getTime() - nowDate.getTime()) / 1000 / 60 / 60; // 单位小时
            workstationData.setDuration(duration);
            workstationData.setProgress(quantityProduced.divide(quantity, RoundingMode.HALF_UP).floatValue());
            workstationData.setQuantity(quantity);
            workstationData.setEnd_date(endDate);
            workstationData.setStart_date(startDate);
            workstationData.setWorkstation(workstation.getWorkstationName());
            ganttData.add(workstationData);
        }

        ganttTask.setData(ganttData);
        ganttTask.setLinks(ganttLinks);
        return ganttTask;
    }

    @Override
    public void setStatus(Long taskId, String issuegenerated) {
        proTaskMapper.updateProTaskStatus(taskId, issuegenerated);
    }

    @Override
    public List<String> getWorkorderNos(Long taskId) {
        QueryWrapper<ProTask> query = new QueryWrapper<>();
        query.eq("t1.task_id", taskId);
        List<ProTaskVo> list = proTaskMapper.selectProTaskJoinWorkorder(query);
        return list.stream().map(s -> s.getWorkorderCode()).collect(Collectors.toList());
    }

    @Override
    @Transactional
    public List<ProPackagePrintResult> feedBack(ProFeedback feedback) {
        List<ProPackagePrintResult> response = new ArrayList<>();
        BigDecimal feedbackQualifyConst = feedback.getQuantityQualify();
        ExceptionUtil.checkTrueThrowException(feedbackQualifyConst.compareTo(BigDecimal.ZERO) <= 0, "报工数量不能小于等于0");

        ProTaskWorkunit taskWorkunit = proTaskWorkunitService.selectProTaskWorkunitByTaskWorkunitId(feedback.getTaskWorkunitId());
        ExceptionUtil.checkTrueThrowException(!taskWorkunit.getStatus().equals(TaskStatusEnum.BEGINNING.getStatus()), "请先进行开始作业操作");

        //更新派工表数量
        double execQuantityQualifySumConst = proFeedbackService.selectQuantityQualifySum(new ProFeedback(null, null, null, taskWorkunit.getTaskWorkunitId()));

        ProTask task = this.selectProTaskByTaskId(feedback.getTaskId());
        BigDecimal taskQuantityWaitConst = task.getQuantityWait();

        double taskQuantityWaitDouConst = taskQuantityWaitConst.doubleValue();
        double feedbackQualityDouConst = feedbackQualifyConst.doubleValue();
//        if (Objects.equals(taskWorkunit.getTaskType(), TaskConst.SPLIT_TASK)) {
//            BigDecimal canBeReportQuantity = taskWorkunit.getQuantity().subtract(taskWorkunit.getQuantityProduced());
//            ExceptionUtil.checkTrueThrowException(canBeReportQuantity.doubleValue() <= 0d, "可报工数量不够");
//            double min = Math.min(taskQuantityWaitDouConst, canBeReportQuantity.doubleValue());
//            ExceptionUtil.checkTrueThrowException(feedbackQualityDouConst > min, "可报工数量不够");
//            if (feedbackQualityDouConst >= min) {
//                taskWorkunit.setStatus(FINISHED.getStatus());
//            }
//        }


        BigDecimal quantityWaitVal = BigDecimal.ZERO;
        BigDecimal feedbackQualityVal = BigDecimal.valueOf(feedbackQualityDouConst);
        Long workorderId = feedback.getWorkorderId();

        QueryWrapper<ProWorkorder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("t1.arrange_code", task.getArrangeCode());
        queryWrapper.notIn("t1.status", Arrays.asList(WorkorderStatusEnum.CLOSE.getValue(), WorkorderStatusEnum.CANCEL.getValue(), WorkorderStatusEnum.CANCELED.getValue()));
        List<ProWorkorder> proWorkorders = proWorkorderService.selectListByQw(queryWrapper);
        double maxWorkunitQuantityConst = taskWorkunit.getQuantity().doubleValue();
        if (workorderId != null && workorderId != 0) {
            // 查看当前工单已报工数量
            if (proWorkorders.size() == 1) {
                if (feedbackQualityDouConst >= task.getQuantity().doubleValue() || taskQuantityWaitDouConst == 0) {
                    taskWorkunit.setStatus(FINISHED.getStatus());
                }

                // 判断已经报工数和未报工数
                if (execQuantityQualifySumConst >= 0) {
                    // 第一次进入
                    if (maxWorkunitQuantityConst > execQuantityQualifySumConst) {
                        // 工单大于已报工数量 工单减去已报工数量
                        feedbackQualityVal = new BigDecimal(maxWorkunitQuantityConst - execQuantityQualifySumConst);
                        // 报工数量大于可报工数量取报工数量
                        if (feedbackQualityVal.doubleValue() > feedbackQualityDouConst) {
                            feedbackQualityVal = feedbackQualifyConst;
                        }
                    } else {
                        feedbackQualityVal = BigDecimal.valueOf(Math.min(maxWorkunitQuantityConst, feedbackQualityDouConst));
                    }
                }
//                else {
//
//                    // 第一次进入
//                    feedbackQuantitySwap = feedbackQuantity;
//                }

                quantityWaitVal = taskQuantityWaitConst.subtract(feedbackQualityVal);
            } else {

                // 无报工记录第一次报工 判断可报工数和工单数
                if (execQuantityQualifySumConst == 0) {
                    if (maxWorkunitQuantityConst > feedbackQualityDouConst) {
                        // 工单大于已报工数量 工单减去已报工数量
                        feedbackQualityVal = feedbackQualifyConst;
                    } else {
                        feedbackQualityVal = BigDecimal.valueOf(maxWorkunitQuantityConst);
                    }
                } else {
                    // 有报工记录 判断报工数和可报工数和工单数
                    double execTotle = execQuantityQualifySumConst + feedbackQualityDouConst;
                    if (maxWorkunitQuantityConst > execTotle) {
                        feedbackQualityVal = BigDecimal.valueOf(Math.min(maxWorkunitQuantityConst, feedbackQualityDouConst));
                        // 工单大于已报工数量 工单减去已报工数量
                    } else {
                        if (maxWorkunitQuantityConst > execQuantityQualifySumConst) {
                            feedbackQualityVal = BigDecimal.valueOf(maxWorkunitQuantityConst - execQuantityQualifySumConst);
                        } else {
                            feedbackQualityVal = BigDecimal.ZERO;
                        }
                    }
                }

                if (feedbackQualityDouConst >= taskQuantityWaitDouConst) {
                    taskWorkunit.setStatus(FINISHED.getStatus());
                }

                quantityWaitVal = taskQuantityWaitConst.subtract(feedbackQualityVal);
            }
        } else {
            // 工单数量数量小于或者等于已报工数量 报工数量 大于等待数量 否则

            double v1 = maxWorkunitQuantityConst - execQuantityQualifySumConst;
            if (feedbackQualityDouConst >= v1) {
                taskWorkunit.setStatus(FINISHED.getStatus());
                feedbackQualityVal = BigDecimal.valueOf(v1);

            }

            if (feedbackQualityDouConst > taskQuantityWaitDouConst) {
                feedbackQualityVal = taskQuantityWaitConst;
            }

            quantityWaitVal = taskQuantityWaitConst.subtract(feedbackQualityVal);
        }


        task.setQuantityWait(quantityWaitVal.doubleValue() < 0D ? BigDecimal.ZERO : quantityWaitVal);
        task.setQuantityProduced(DataUtil.getNormalData(task.getQuantityProduced()).add(feedbackQualityVal));
        task.setQuantityQualify(DataUtil.getNormalData(task.getQuantityQualify()).add(feedbackQualityVal));

        taskWorkunit.setQuantityProduced(DataUtil.getNormalData(taskWorkunit.getQuantityProduced()).add(feedbackQualityVal));
        taskWorkunit.setQuantityQualify(DataUtil.getNormalData(taskWorkunit.getQuantityQualify()).add(feedbackQualityVal));


        task.setQuantityUnqualify(DataUtil.getNormalData(task.getQuantityUnqualify()).add(feedback.getQuantityUnqualify()));
        taskWorkunit.setQuantityUnqualify(DataUtil.getNormalData(taskWorkunit.getQuantityUnqualify()).add(feedback.getQuantityUnqualify()));

        List<MdWorkstation> mdWorkstations = workstationMapper.selectListByQw(new QueryWrapper<MdWorkstation>().eq("workstation_id", feedback.getWorkstationId()));
        ExceptionUtil.checkTrueThrowException(CollectionUtil.isEmpty(mdWorkstations), "报工工站不存在");

        MdWorkstation workstation = mdWorkstations.get(0);
        feedback.setWorkstationCode(workstation.getWorkstationCode());
        feedback.setWorkstationName(workstation.getWorkstationName());
        feedback.setWorkstationId(DataUtil.repliceData(feedback.getWorkstationId(), workstation.getWorkstationId()));
        feedback.setFeedbackType("SELF");
        feedback.setWorkunitId(taskWorkunit.getWorkunitId());
        feedback.setNickName(sysUserMapper.selectUserById(SecurityUtils.getUserId()).getNickName());


        //暂停更新记录
        if (Objects.equals(taskWorkunit.getStatus(), FINISHED.getStatus())) {
            proStartWorkService.closeObj(feedback);
        } else {
            proStartWorkService.updateObj(feedback);
        }

        //按派工表保存报工记录
        LinkedHashMap<String, ProFeedbackSplitInfo> feedbackWorkorder = proFeedbackService.taskFeedback(task, feedback);


        //查询关联下道工序
        ProTask nextTask = this.getNextTaskByTaskId(feedback.getTaskId());
        if (nextTask != null) {

            // 下道任务待加工数累加合格数量
            nextTask.setQuantityWait(DataUtil.getNormalData(nextTask.getQuantityWait()).add(feedbackQualifyConst));
            List<ProTaskWorkunit> proTaskWorkunits = proTaskWorkunitMapper.selectListByQw(new QueryWrapper<ProTaskWorkunit>().eq("task_id", nextTask.getTaskId()));
            proTaskWorkunits.stream().filter(x -> Objects.equals(x.getStatus(), FINISHED.getStatus())).forEach(x -> {
                x.setStatus(BEGINNING.getStatus());
                proTaskWorkunitMapper.updateProTaskWorkunit(x);
            });

            this.updateProTask(nextTask);
        }


        this.updateProTask(task);


        if (feedbackQualityVal.doubleValue() > 0) {
            //查询关联下道工序
            //如果为最后一道工序，回写工单数量
            if (StringUtils.isEmpty(nextTask)) {
                feedbackWorkorder.forEach((k, v) -> {
                    ProWorkorder workorder = v.getWorkorder();
                    workorder.setQuantityQualify(workorder.getQuantityQualify().add(v.getQuantityQualify()));
                    workorder.setQuantityUnqualify(workorder.getQuantityUnqualify().add(v.getQuantityUnqualify()));
                    workorder.setQuantityProduced(DataUtil.getNormalData(workorder.getQuantityProduced()).add(v.getQuantityQualify()));
                    proWorkorderService.updateProWorkorder(workorder);
                });
            }
        }


        proTaskWorkunitService.updateProTaskWorkunit(taskWorkunit);


        //打印记录
        if ("1".equals(feedback.getPrintContents())) {
            proFdQrcodePrintRecordService.insertProFdQrcodePrintRecordfeedback(feedback);
        }

        //扣减刀具寿命
        proTaskWorkunitService.updateProTaskWorkunitlife(feedback);


        //报工满足条件下架刀模版具
        tmToolMachinesService.feedbackToolDismount(taskWorkunit);


        return response;
    }

    @Override
    @Transactional
    public List<WorkorderPackagePrint> feedBackPackage(FeedbackPackageAddParams feedbackAddParams) {
        feedbackAddParams.initPackageValue();
        List<WorkorderPackagePrint> response = new ArrayList<WorkorderPackagePrint>();
        ProWorkorder workorder = proWorkorderService.selectWorkorderById(feedbackAddParams.getWorkorderId());
        if (feedbackAddParams.getReportData().getReportQuantity().compareTo(BigDecimal.ZERO) <= 0) {
            throw new ServiceException("报工数量不能低于0");
        }
        Long taskWorkunitId = feedbackAddParams.getTaskWorkunitId();
        ProTask task = this.selectProTaskByTaskId(feedbackAddParams.getTaskId());
        ProTaskWorkunit taskWorkunit = proTaskWorkunitService.selectProTaskWorkunitByTaskWorkunitId(taskWorkunitId);
        if (!taskWorkunit.getStatus().equals(TaskStatusEnum.BEGINNING.getStatus())) {
            throw new ServiceException("请先进行开始作业操作");
        }
        //包装标签未传时为超报标签，初始编码为空字符串、包装数量无限大
        if (StringUtils.isBlank(feedbackAddParams.getReportData().getQrcode())) {
            feedbackAddParams.getReportData().setQrcode("SL" + UUID.randomUUID());
            feedbackAddParams.getReportData().setPackageNum(Integer.MAX_VALUE);
        }
        //如果为该订单首次报工，保存是否混合包装、包装数量、装箱数量到工单表
        QueryWrapper<ProFeedback> feedbackQuery = new QueryWrapper<ProFeedback>();
        feedbackQuery.eq("task_id", feedbackAddParams.getTaskId());
        feedbackQuery.eq("workorder_id", feedbackAddParams.getWorkorderId());
        List<ProFeedback> feedbackList = proFeedbackService.selectProFeedbackList(feedbackQuery);
        //包装标签报工合格数量不允许超过包装数
        Integer reportedNum = feedbackList.stream().filter(s -> feedbackAddParams.getReportData().getQrcode().equals(s.getQrcode()))
                .mapToInt(s -> s.getQuantityQualify().intValue()).sum();
        BigDecimal netWeight = feedbackList.stream().filter(s -> feedbackAddParams.getReportData().getQrcode().equals(s.getQrcode()))
                .map(s -> s.getNetWeight() == null ? BigDecimal.ZERO : s.getNetWeight()).reduce(BigDecimal.ZERO, BigDecimal::add);
        netWeight = netWeight.add(feedbackAddParams.getReportData().getNetWeight() == null ? BigDecimal.ZERO : feedbackAddParams.getReportData().getNetWeight());
        Integer allReportNum = reportedNum + feedbackAddParams.getReportData().getReportQuantity().intValue();//已报工数
        if (feedbackAddParams.getReportData().getPackageNum() < allReportNum) {
            throw new ServiceException("报工合格数量不能大于包装数量");
        }
        if (feedbackList.isEmpty()) {
            workorder.setUsageEncasementNum(feedbackAddParams.getEncasementNum());
            workorder.setUsagePackNum(feedbackAddParams.getPackNum());
            workorder.setMergePack(feedbackAddParams.getMergePack());
            proWorkorderService.updateProWorkorder(workorder);
        } else {
            if (!ObjectUtil.equals(feedbackAddParams.getEncasementNum(), workorder.getUsageEncasementNum())) {
                throw new ServiceException("报工后装箱数量不允许再次修改");
            }
            if (workorder.getUsagePackNum() != null && !ObjectUtil.equals(feedbackAddParams.getPackNum(), workorder.getUsagePackNum())) {
                throw new ServiceException("报工后包装数量不允许再次修改");
            }
            if (workorder.getMergePack() != null && !ObjectUtil.equals(feedbackAddParams.getMergePack(), workorder.getMergePack())) {
                throw new ServiceException("报工后合并包装不允许再次修改");
            }
        }

        //更新派工表
        task.setQuantityWait(task.getQuantityWait().subtract(feedbackAddParams.getReportData().getReportQuantity()));
        task.setQuantityProduced(task.getQuantityProduced().add(feedbackAddParams.getReportData().getReportQuantity()).add(feedbackAddParams.getQuantityUnqualify()));
        task.setQuantityQualify(task.getQuantityQualify().add(feedbackAddParams.getReportData().getReportQuantity()));
        task.setQuantityUnqualify(task.getQuantityUnqualify().add(feedbackAddParams.getQuantityUnqualify()));
        proTaskMapper.updateProTask(task);
        //更新派工表数量
        taskWorkunit.setQuantityProduced(taskWorkunit.getQuantityProduced().add(feedbackAddParams.getReportData().getReportQuantity()).add(feedbackAddParams.getQuantityUnqualify()));
        taskWorkunit.setQuantityQualify(taskWorkunit.getQuantityQualify().add(feedbackAddParams.getReportData().getReportQuantity()));
        taskWorkunit.setQuantityUnqualify(taskWorkunit.getQuantityUnqualify().add(feedbackAddParams.getQuantityUnqualify()));

        proTaskWorkunitService.updateProTaskWorkunit(taskWorkunit);
        //查询关联下道工序
        QueryWrapper<ProTask> query = new QueryWrapper<>();
        query.notIn("task_id", feedbackAddParams.getTaskId());
        query.eq("task_batch", task.getTaskBatch());
        query.ge("ordinal", task.getOrdinal());
        query.orderByAsc("ordinal");
        List<ProTask> nextTaskList = proTaskMapper.selectProTaskJoinProcess(query);
        if (nextTaskList.size() > 0) {
            ProTask nextTask = nextTaskList.get(0);
            nextTask.setQuantityWait(nextTask.getQuantityWait() == null ? BigDecimal.ZERO : nextTask.getQuantityWait());
            //下道任务待加工数累加合格数量
            nextTask.setQuantityWait(nextTask.getQuantityWait().add(feedbackAddParams.getReportData().getReportQuantity()));
            this.updateProTask(nextTask);
        }

        //报工表记录
        ProFeedback feedback = new ProFeedback();
        BeanUtil.copyProperties(feedbackAddParams, feedback);
        MdWorkstation workstation = mdWorkstationService.selectMdWorkstationByWorkstationId(task.getWorkstationId());
        if (workstation == null) {
            throw new ServiceException("报工工站不存在");
        }
        feedback.initValue(workstation);
        ProProcess process = iProProcessService.selectProProcessByProcessId(task.getProcessId());
        feedback.initValue(process);
        feedback.setWorkunitId(taskWorkunitId);
        feedback.initValue(workorder);
        MdItem mdItem = itemMapper.selectMdItemById(workorder.getProductId());
        feedback.initValue(mdItem);
        feedback.setFeedbackType("SELF");
        feedback.setQuantityFeedback(feedbackAddParams.getReportData().getReportQuantity().add(feedback.getQuantityUnqualify()));
        feedback.setQuantityQualify(feedbackAddParams.getReportData().getReportQuantity());
        feedback.setQuantityUnqualify(feedback.getQuantityUnqualify());
        feedback.setQrcode(feedbackAddParams.getReportData().getQrcode());
        feedback.setNetWeight(feedbackAddParams.getReportData().getNetWeight());
        feedback.setWorkorderSoDirectiveId(feedbackAddParams.getReportData().getWorkorderSoDirectiveId());
        feedback.setWorkorderSoSizeItemId(feedbackAddParams.getReportData().getWorkorderSoSizeItemId());
        feedback.setUserName(feedbackAddParams.getUserName());
        feedback.setNickName(feedbackAddParams.getNickName());
        feedback.setTaskCode(task.getTaskCode());
        //回写工单数量
        //如果为最后一道工序，回写工单数量
        if (nextTaskList.size() == 0) {//最后一道工序
            if (workorder.getQuantityProduced() == null) {
                workorder.setQuantityProduced(BigDecimal.ZERO);
            }
            workorder.setQuantityQualify(workorder.getQuantityQualify().add(feedbackAddParams.getReportData().getReportQuantity()));
            workorder.setQuantityUnqualify(workorder.getQuantityUnqualify().add(feedbackAddParams.getQuantityUnqualify()));
            workorder.setQuantityProduced(workorder.getQuantityProduced().add(feedbackAddParams.getQuantityUnqualify()).add(feedbackAddParams.getReportData().getReportQuantity()));
            proWorkorderService.updateProWorkorder(workorder);
        }
        //保存包装标签
        ProPackagePrintRecord proFdPackagePrintRecord = proPackagePrintRecordService.insertProPackagePrintRecordByFeedback(taskWorkunit, workorder,
                feedbackAddParams, allReportNum, netWeight);
        if(StringUtils.isNotEmpty(proFdPackagePrintRecord.getWorkorderSoSizeItemIds())){
            feedback.setWorkorderSoSizeItemIds(proFdPackagePrintRecord.getWorkorderSoSizeItemIds());
        }else if(proFdPackagePrintRecord.getWorkorderSoSizeItemId()!=null){
            feedback.setWorkorderSoSizeItemIds(proFdPackagePrintRecord.getWorkorderSoSizeItemId()+"");
        }
        feedback.setWorkorderSoSizes(proFdPackagePrintRecord.getWorkorderSoSizes());
        //SAP接口报工
//        proStartWorkService.updateObj(feedback);
//        proFeedbackService.packageSendSapService(feedback);
        proFeedbackService.insertProFeedback(feedback);
        //返回包装标签打印信息
        if (StringUtils.isNotEmpty(feedback.getPrintTemplate())) {
            List<ProPackagePrintRecord> packagePrintRecords = new ArrayList<>();
            packagePrintRecords.add(proFdPackagePrintRecord);
            response = proPackagePrintRecordService.recordPackagePrintInfo(workorder.getWorkorderId(), packagePrintRecords);

        }
        return response;
    }


    @Override
    public FeedbackPackageInfo listFeedBackPackage(FeedbackPackageQueryParams query) {
        query.initPackageValue();
        FeedbackPackageInfo rst = new FeedbackPackageInfo();
        ProWorkorder workorder = proWorkorderService.selectWorkorderById(query.getWorkorderId());
        //如果报过工，且本次包装数量发生变化
        if (workorder.getUsagePackNum() != null && !ObjectUtil.equal(workorder.getUsagePackNum(), query.getPackNum())) {
            throw new ServiceException("已生成包装标签/工单已报工，包装数量不允许修改");
        }
        if (workorder.getUsageEncasementNum() != null && !ObjectUtil.equal(workorder.getUsageEncasementNum(), query.getEncasementNum())) {
            throw new ServiceException("已生成包装标签/工单已报工，装箱数量不允许修改");
        }
        if (workorder.getMergePack() != null && !ObjectUtil.equal(workorder.getMergePack(), query.getMergePack())) {
            throw new ServiceException("已生成包装标签/工单已报工，混合包装不允许修改");
        }
        if (query.getPackNum() == 0) {
            query.setPackNum(Integer.MAX_VALUE);
        }
        BuildPackageParams2 buildPackageParams2 = new BuildPackageParams2();
        buildPackageParams2.setQuantity(workorder.getQuantity().intValue());
        buildPackageParams2.setWorkorderId(query.getWorkorderId());
        buildPackageParams2.setPackNum(query.getPackNum());
        buildPackageParams2.setEncasementNum(query.getEncasementNum());
        buildPackageParams2.setMergePack(query.getMergePack() == 1);
        WorkorderPackageResult packageResult = proWorkorderService.buildPackagePrintInfo(buildPackageParams2);
        List<FeedbackPackageInfo.FeedbackPackageDetail> detailRst = new ArrayList<FeedbackPackageInfo.FeedbackPackageDetail>();
        //查询已报工
        QueryWrapper<ProFeedback> feedbackQuery = new QueryWrapper<ProFeedback>();
        feedbackQuery.eq("workorder_id", query.getWorkorderId());
        feedbackQuery.orderByAsc("create_time");
        List<ProFeedback> feedbackList = proFeedbackService.selectProFeedbackList(feedbackQuery);
        //查询报工首次填写净值
        AtomicReference<BigDecimal> defNetWeight = new AtomicReference<BigDecimal>(BigDecimal.ZERO);
        feedbackList.stream().filter(s -> s.getNetWeight() != null && s.getNetWeight().compareTo(BigDecimal.ZERO) > 0)
                .findFirst().ifPresent(s -> {
                    defNetWeight.set(s.getNetWeight());
                });

        List<WorkorderPackage> packageList = packageResult.getPackageList();

        packageList.forEach(s -> {
            FeedbackPackageInfo.FeedbackPackageDetail detail = new FeedbackPackageInfo.FeedbackPackageDetail();
            BeanUtil.copyProperties(s, detail);
            if (s.getQrcode().startsWith(IProPackagePrintRecordService.BL)) {
                detail.setDistributes(null);
            }
            if (!packageResult.getSizeList().isEmpty()) {
                String standardSize = packageResult.getStandardSize(s);
                detail.setStandardSizeIdx(s.getSheetCount() + "");
                detail.setStandardSize(standardSize);
                if(!packageResult.getDirectiveList().isEmpty()){
                    detail.setWorkorderSoDirectiveId(packageResult.getDirectiveList().get(0).getWorkorderSoDirectiveId());
                }
                if (s.getWorkorderSoSizeItemId() == null) {
                    if (detail.getDistributes() != null && detail.getDistributes().size() > 0) {
                        detail.getDistributes().stream().filter(t -> t.getSizeId() != null).forEach(t -> {
                            packageResult.getSizeList().stream().filter(temp -> temp.getWorkorderSoSizeItemId().equals(t.getSizeId())).findFirst().ifPresent(temp -> {
                                t.setStandardSize(temp.getStandardSize());
                                t.setQuantity(temp.getQuantity());
                            });
                        });
                    }
                } else {
                    packageResult.getSizeList().stream().filter(temp -> temp.getWorkorderSoSizeItemId().equals(s.getWorkorderSoSizeItemId())).findFirst().ifPresent(temp -> {
                        detail.setQuantity(temp.getQuantity());
                        String standardSizeType = temp.getStandardSizeType();
                        if (standardSizeType != null) {
                            rst.setSizeColumnName(String.format("标准SIZE(%s)", standardSizeType));
                        }
                    });
                }
            } else if (!packageResult.getDirectiveList().isEmpty()) {
                packageResult.getDirectiveList().stream().filter(temp -> temp.getWorkorderSoDirectiveId().equals(s.getWorkorderSoDirectiveId())).findFirst().ifPresent(temp -> {
                    detail.setClientCmd(temp.getClientCmd());
                    detail.setQuantity(temp.getQuantity());
                });
            }else{
                detail.setQuantity(workorder.getQuantity());
            }
            feedbackList.stream().filter(temp -> s.getQrcode().equals(temp.getQrcode())).forEach(temp -> {
                detail.setFeedbackQuantity(detail.getFeedbackQuantity().add(temp.getQuantityQualify()));
            });
            detail.setPackageNum(detail.getPackageNum() + detail.getLossNum());
            if (s.getQrcode().startsWith(ProPackagePrintRecordServiceImpl.BL)) {
                detail.setIsEncase(1);
            }
            detailRst.add(detail);
        });
        //加载超报标签
        QueryWrapper<ProPackagePrintRecord> qp = new QueryWrapper<ProPackagePrintRecord>();
        qp.eq("workorder_id", query.getWorkorderId());
        List<ProPackagePrintRecord> printRecordList = proPackagePrintRecordService.selectProPackagePrintRecordList(qp);
        printRecordList.stream().filter(s -> s.getIsSurplus() == 1).forEach(s -> {
            FeedbackPackageInfo.FeedbackPackageDetail detail = new FeedbackPackageInfo.FeedbackPackageDetail();
            detail.setPackageNum(s.getPackageNum());
            detail.setFeedbackQuantity(new BigDecimal(s.getPackageNum()));
            detail.setQrcode(s.getQrcode());
            detail.setNetWeight(s.getNetWeight());
            detail.setClientCmd(packageResult.getDirectiveList().get(0).getClientCmd());
            detailRst.add(detail);
        });
        detailRst.stream().filter(s -> s.getQrcode().startsWith(IProPackagePrintRecordService.BL)).forEach(s -> {
            printRecordList.stream().filter(s2 -> s2.getQrcode().equals(s.getQrcode())).findFirst().ifPresent(s3 -> {
                s.setGrossWeight(s3.getGrossWeight());
                s.setNetWeight(s3.getNetWeight());
                s.setPackageStandard(s3.getPackageStandard());
            });
        });
        //加载默认净重
        detailRst.stream().filter(s -> s.getQrcode().startsWith(IProPackagePrintRecordService.PL)).forEach(s -> {
            Optional<ProPackagePrintRecord> recordOp = printRecordList.stream().filter(s2 -> s2.getQrcode().equals(s.getQrcode())).findFirst();
            if (recordOp.isPresent()&&recordOp.get().getTaskWorkunitId()!=null) {
                s.setNetWeight(recordOp.get().getNetWeight());
            } else {
                s.setNetWeight(defNetWeight.get());
            }
        });


        if (!packageResult.getSizeList().isEmpty()) {
            rst.setSizeList(detailRst);
        } else if (!packageResult.getDirectiveList().isEmpty()) {
            rst.setDirectiveList(detailRst);
        } else {
            rst.setOrderPackageList(detailRst);
        }
        return rst;
    }

    @Transactional
    @Override
    public void changeStatus(ProTask proTask) {
        Long taskWorkunitId = proTask.getTaskWorkunitId();

        // 更新派工单状态
        ProTaskWorkunit proTaskWorkunit = proTaskWorkunitMapper.selectProTaskWorkunitByTaskWorkunitId(taskWorkunitId);
        ExceptionUtil.checkTrueThrowException(
                (Objects.equals(proTask.getStatus(), TaskStatusEnum.FINISHED.getStatus()) && !Objects.equals(proTaskWorkunit.getStatus(), TaskStatusEnum.BEGINNING.getStatus()))
                        || Objects.equals(proTask.getStatus(), TaskStatusEnum.CLOSE.getStatus()), "非法完成作业,请先操作开始作业");

        ExceptionUtil.checkTrueThrowException(Objects.equals(proTask.getStatus(), proTaskWorkunit.getStatus()) && Objects.equals(proTaskWorkunit.getStatus(), TaskStatusEnum.BEGINNING.getStatus()), "不可重复开工");

        ExceptionUtil.checkTrueThrowException(Objects.equals(proTask.getStatus(), proTaskWorkunit.getStatus()) && Objects.equals(proTaskWorkunit.getStatus(), TaskStatusEnum.PAUSE.getStatus()), "当前订单已经暂停");


        List<ProTask> proTasks = proTaskMapper.selectListJoinByQw(new QueryWrapper<ProTask>().eq("t1.task_id", proTask.getTaskId()));
        ProTask task = proTasks.get(0);


        proTasks = proTaskMapper.selectProTaskVoList(taskWorkunitId, task.getArrangeCode());
        task = proTasks.get(0);
        if (proTask.getStatus().equals(TaskStatusEnum.BEGINNING.getStatus())) {
            if (task.getWorkunitId() != AssistProcessConst.WORKUNIT_ID) {
                iMdWorkunitService.checkTaskWorkunitUnique(task.getTaskWorkunitId());
            }
        }


        proTaskWorkunit.setStatus(proTask.getStatus());
        proTaskWorkunitService.updateProTaskWorkunit(proTaskWorkunit);

        // 排产任务结束,下机刀模版具
        tmToolMachinesService.taskComplateToolDismount(proTaskWorkunit);


        if (proTask.getStatus().equals(TaskStatusEnum.BEGINNING.getStatus())) {
            //设置工单状态为生产中
            List<ProWorkorder> orderList = proWorkorderMapper.selectProWorkorderJoinTask(new QueryWrapper<ProWorkorder>().eq("t2.task_id", proTask.getTaskId()));
            for (ProWorkorder proWorkorder : orderList) {
                if (WorkorderStatusEnum.ISSUED.getValue().equals(proWorkorder.getStatus())) {
                    proWorkorder.setStatus(WorkorderStatusEnum.PRODUCING.getValue());
                    Long workorderId = proWorkorder.getWorkorderId();
                    proWorkorderService.updateProWorkorderStatus(Collections.singletonList(workorderId), WorkorderStatusEnum.PRODUCING);
                }
            }

            // inspectionOrders
            //首次开工增加首检单
            if (orderList.size() == 1 && Objects.equals(orderList.get(0).getWorkorderType(), WorkorderConst.WORK_ORDER_PROTO_TYPE)) {
            } else {
                qcIpqcService.insertInspectionOrder(task, QcConst.FIRST);
            }

            proRecoilMaterialService.checkRecoilMaterial(task);
            proMaterialRequestService.checkMaterialRequest(task);

            TmToolMachineCheckEnum tmToolMachineCheckEnum = tmToolMachinesService.checkWhetherTheToolTemplateIsSatisfied(taskWorkunitId);
            ExceptionUtil.checkTrueThrowException(!Arrays.asList(TmToolMachineCheckEnum.ERROR_06.getStatus(), TmToolMachineCheckEnum.NOMAL_00.getStatus()).contains(tmToolMachineCheckEnum.getStatus()), tmToolMachineCheckEnum.getMsg());

        }

        if (proTask.getStatus().equals(TaskStatusEnum.FINISHED.getStatus())) {
            ProWorkorder proWorkorder = new ProWorkorder();
            proWorkorder.setTaskId(proTask.getTaskId());
            List<ProWorkorder> proWorkorders = proWorkorderService.selectProWorkorderByTaskId(proWorkorder);

            List<ProStartWork> proStartWorks = proStartWorkService.selectListByTwId(taskWorkunitId);
            proStartWorks.stream().filter(x -> Objects.equals(x.getRecordType(), ProStartWorkEnum.START.getType())).findFirst().ifPresent(
                    x -> {
                        x.setRecordType(ProStartWorkEnum.CLOSE.getType());
                        proStartWorkService.updateProStartWork(x);
                    }
            );


            //最后一道工序完工
            if (proTask.getIsLastProcess() != null && proTask.getIsLastProcess() == 1) {
                //最后一个批次，回写关联订单状态为已完成
                QueryWrapper<ProTaskWorkunit> taskWorkuniQuery = new QueryWrapper<>();
                taskWorkuniQuery.eq("task_id", proTask.getTaskId());
                taskWorkuniQuery.notIn("status", TaskStatusEnum.FINISHED.getStatus());//存在未完工状态数据
                List<ProTaskWorkunit> tempList = proTaskWorkunitService.selectListByQw(taskWorkuniQuery);
                if (CollectionUtil.isEmpty(tempList)) {
                    for (ProWorkorder workorder : proWorkorders) {
                        workorder.setStatus(WorkorderStatusEnum.FINISHED.getValue());
                        proWorkorderService.updateProWorkorder(workorder);
                    }
                }


                //创建入库单
                for (ProWorkorder workorder : proWorkorders) {
                    WmProductRecpt insertProduct = new WmProductRecpt();

                    insertProduct.setWorkorderId(workorder.getWorkorderId());
                    insertProduct.setWorkorderCode(workorder.getWorkorderCode());
                    insertProduct.setWorkorderName(workorder.getWorkorderName());
                    insertProduct.setItemId(task.getItemId());
                    insertProduct.setItemCode(task.getItemCode());
                    insertProduct.setItemName(task.getItemName());
                    insertProduct.setUnitOfMeasure(task.getUnitOfMeasure());
                    insertProduct.setRecptDate(DateUtils.getNowDate());
                    insertProduct.setStatus(TaskStatusEnum.FINISHED.getStatus());
                    insertProduct.setRecptName(workorder.getWorkorderName());
                    int recptId = wmProductRecptService.insertWmProductRecpt(insertProduct);

                    if (recptId > 0) {
                        WmProductRecptLine wmProductRecptLine = new WmProductRecptLine();
                        wmProductRecptLine.setRecptId(insertProduct.getRecptId());
                        wmProductRecptLine.setCreateTime(DateUtils.getNowDate());
                        wmProductRecptLine.setItemId(task.getItemId());
                        wmProductRecptLine.setItemCode(task.getItemCode());
                        wmProductRecptLine.setItemName(task.getItemName());
                        wmProductRecptLine.setSpecification(task.getSpecification());
                        wmProductRecptLine.setUnitOfMeasure(task.getUnitOfMeasure());
                        wmProductRecptLine.setQuantityRecived(workorder.getQuantityProduced());
                        wmProductRecptLine.setBatchCode(workorder.getBatchCode());
                        wmProductRecptLineService.insertWmProductRecptLine(wmProductRecptLine);
                    }

                }
            }
        }

        //新增更新记录
        if (proTask.getStatus().equals(TaskStatusEnum.BEGINNING.getStatus())) {
            proStartWorkService.insertObj(proTask);
        }

        //暂停更新记录
        if (proTask.getStatus().equals(TaskStatusEnum.PAUSE.getStatus())) {
            proTask.setPurseType(ProStartWorkEnum.SUSPENDED.getType());
            proStartWorkService.updateObj(proTask);
        }

        this.updateProTask(proTask);
    }


    @Override
    @Transactional
    public void manualSchedule(ProTaskVo proTaskVo) {
        // 封装保存
        ProTask dbTask = this.selectProTaskByTaskId(proTaskVo.getTaskId());
        Long taskId = dbTask.getTaskId();
        dbTask.setStartTime(proTaskVo.getStartTime());
        dbTask.setDuration(proTaskVo.getDuration());
        Date endTime = proTaskVo.getStartTime();
        dbTask.setStatus(TaskStatusEnum.PREPARE.getStatus());

        this.updateProTask(dbTask);

        // 封装任务-工作单元
        ProTaskWorkunit proTaskWorkunit = new ProTaskWorkunit();
        proTaskWorkunit.setTaskId(taskId);
        proTaskWorkunit.setIdx(1L);
        proTaskWorkunit.setQuantityProduced(BigDecimal.ZERO);
        proTaskWorkunit.setQuantityQualify(BigDecimal.ZERO);
        proTaskWorkunit.setQuantityUnqualify(BigDecimal.ZERO);
        proTaskWorkunit.setStatus(TaskStatusEnum.PREPARE.getStatus());
        proTaskWorkunit.setQuantity(proTaskVo.getQuantity());
        proTaskWorkunit.setWorkunitId(proTaskVo.getWorkunitId());
        proTaskWorkunit.setScheduleStartDate(proTaskVo.getStartTime());
        if (proTaskVo.getEndTime() != null) {
            proTaskWorkunit.setScheduleEndDate(proTaskVo.getEndTime());
        } else {
            proTaskWorkunit.setScheduleEndDate(endTime);
        }
        proTaskWorkunitService.insertProTaskWorkunit(proTaskWorkunit);

        // 自动生产物料领用单
        proTaskVo.setTaskWorkunitId(proTaskWorkunit.getTaskWorkunitId());
        iProMaterialRequestService.insertProMaterialRequestItem(proTaskVo);

        //自动生成刀模版申请单
        proTaskVo.setTaskWorkunitId(proTaskWorkunit.getTaskWorkunitId());
        proTaskVo.setTaskId(taskId);
        tmToolRequestService.addedToolRequestAppForm(Collections.singletonList(proTaskWorkunit));

        // 更新工单状态
        String arrangeCode = dbTask.getArrangeCode();
        ProWorkorder proWorkorder = new ProWorkorder();
        proWorkorder.setArrangeCode(arrangeCode);
        proWorkorder.setStatus(WorkorderStatusEnum.SCHEDULED.getValue());
        proWorkorder.updateAction();
        proWorkorderService.updateWoStatusByArrangeCode(proWorkorder);
    }

    private void sortDeduction(List<ProTaskWorkunit> proTaskWorkunits, AtomicReference<Double> splitQuantity, String status) {
        List<ProTaskWorkunit> preTaskWorkunits = proTaskWorkunits.stream().filter(x -> Objects.equals(x.getStatus(), status)).collect(Collectors.toList());
        preTaskWorkunits.forEach(x -> {
            BigDecimal quantityProduced = x.getQuantityProduced();

            BigDecimal quantity = x.getQuantity();

            BigDecimal waitSize = quantity.subtract(quantityProduced);
            Double v = splitQuantity.get();
            double waitSizeDouble = waitSize.doubleValue();
            if (waitSizeDouble > 0) {
                if (v > 0) {

//                    10 - 3 = 7   3 - 10 = -7
                    double newValue = v - waitSizeDouble;
                    if (newValue > 0) {
                        splitQuantity.set(newValue);
                        x.setQuantity(quantity.subtract(new BigDecimal(waitSizeDouble)));
                    } else {
                        splitQuantity.set(0D);
                        x.setQuantity(quantity.subtract(new BigDecimal(v)));
                    }
                }

//                    if (quantityProduced.doubleValue() == quantity.doubleValue()) {
//                        x.setStatus(TaskWorkunitStatusEnum.CLOSE.getStatus());
//                    } else {
//                        x.setStatus(TaskWorkunitStatusEnum.CANCEL.getStatus());
//                    }
            }

        });

        for (ProTaskWorkunit proTaskWorkunit : proTaskWorkunits) {
            proTaskWorkunit.setApiFlag(true);
            proTaskWorkunitService.updateProTaskWorkunit(proTaskWorkunit);
        }

    }

    @Override
    public ProTaskWorkunit splitTask(ProTaskVo proTaskVo, Integer type) {
        QueryWrapper<ProTaskWorkunit> proTaskWorkunitQueryWrapper = new QueryWrapper<>();
        Long taskId = proTaskVo.getTaskId();
        proTaskWorkunitQueryWrapper.eq("task_id", taskId);
        proTaskWorkunitQueryWrapper.in("task_type", TaskConst.NORMAL_TASK_LIST);
        List<ProTaskWorkunit> proTaskWorkunits = proTaskWorkunitMapper.selectListByQw(proTaskWorkunitQueryWrapper);
        ExceptionUtil.checkTrueThrowException(CollectionUtil.isEmpty(proTaskWorkunits), "没有查到主要排产任务");

        ProTask proTask = this.selectBaseById(taskId);
        ProTaskWorkunit taskWorkunitSplitConst = proTaskVo.getTaskWorkunit();
        BigDecimal splitQuantityConst = taskWorkunitSplitConst.getQuantity();
        ExceptionUtil.checkTrueThrowException(
                splitQuantityConst.doubleValue() > proTask.getQuantityWait().doubleValue(),
                "作业分派的的数量大于能排产的数量");


        ProTaskWorkunit mainTaskWorkunitVal = null;
        if (TaskConst.ASSIST_TASK.equals(type)) {
            DoubleSummaryStatistics summaryStatistics = proTaskWorkunits.stream().map(x -> x.getQuantity().subtract(x.getQuantityProduced()).doubleValue()).filter(x -> x > 0).collect(Collectors.summarizingDouble(x -> x));
            double sum = summaryStatistics.getSum();

            ExceptionUtil.checkTrueThrowException(sum <= 0, "数量不够无法外发");
            ExceptionUtil.checkTrueThrowException(sum <= 1, "最小单位不可再分");
            ExceptionUtil.checkTrueThrowException(
                    sum < splitQuantityConst.doubleValue(),
                    "作业分派的的数量大于能排产的数量");


            AtomicReference<Double> splitQuantity = new AtomicReference<>(splitQuantityConst.doubleValue());

            sortDeduction(proTaskWorkunits, splitQuantity, TaskWorkunitStatusEnum.PREPARE.getStatus());
            sortDeduction(proTaskWorkunits, splitQuantity, TaskWorkunitStatusEnum.BEGINNING.getStatus());
            sortDeduction(proTaskWorkunits, splitQuantity, TaskWorkunitStatusEnum.PAUSE.getStatus());
            sortDeduction(proTaskWorkunits, splitQuantity, TaskWorkunitStatusEnum.ERROR_STOP.getStatus());


        } else {
            mainTaskWorkunitVal = proTaskWorkunits.get(0);
            BigDecimal mainQuantity = mainTaskWorkunitVal.getQuantity();
            BigDecimal subWaitQuantity = mainQuantity.subtract(mainTaskWorkunitVal.getQuantityProduced());

            ExceptionUtil.checkTrueThrowException(subWaitQuantity.doubleValue() <= 0, "数量不够无法外发");
            ExceptionUtil.checkTrueThrowException(subWaitQuantity.doubleValue() <= 1, "最小单位不可再分");


            ExceptionUtil.checkTrueThrowException(
                    subWaitQuantity.doubleValue() < splitQuantityConst.doubleValue(),
                    "作业分派的的数量大于能排产的数量");

            ExceptionUtil.checkTrueThrowException(
                    splitQuantityConst.doubleValue() > mainQuantity.intValue(), "拆分的数量大于可拆分数量");


            mainTaskWorkunitVal.setQuantity(mainQuantity.subtract(splitQuantityConst));
            if (Objects.equals(type, TaskConst.ASSIST_TASK)) {
                mainTaskWorkunitVal.setApiFlag(true);
            }
            proTaskWorkunitService.updateProTaskWorkunit(mainTaskWorkunitVal);

        }


        ProTaskWorkunit insertTaskWorkunit = proTaskVo.deepSetObj(taskWorkunitSplitConst);
        String workunitName = taskWorkunitSplitConst.getWorkunitName();
        Long workunitId = taskWorkunitSplitConst.getWorkunitId();
        QueryWrapper<MdWorkunit> mdWorkunitQueryWrapper = new QueryWrapper<>();
        mdWorkunitQueryWrapper.eq(StringUtils.isNotEmpty(workunitName), "workunit_name", workunitName);
        mdWorkunitQueryWrapper.eq(StringUtils.isNotEmpty(workunitId), "workunit_id", workunitId);
        List<MdWorkunit> mdWorkunits = mdWorkunitMapper.selectListByQw(mdWorkunitQueryWrapper);

        MdWorkunit mdWorkunit = mdWorkunits.get(0);
        insertTaskWorkunit.setWorkunitId(mdWorkunit.getWorkunitId());
        insertTaskWorkunit.setWorkunitCode(mdWorkunit.getWorkunitCode());
        insertTaskWorkunit.setWorkunitName(mdWorkunit.getWorkunitName());

        // 封装任务-工作单元
        insertTaskWorkunit.setQuantity(splitQuantityConst);
        insertTaskWorkunit.setQuantityProduced(BigDecimal.ZERO);
        insertTaskWorkunit.setQuantityQualify(BigDecimal.ZERO);
        insertTaskWorkunit.setQuantityUnqualify(BigDecimal.ZERO);
        insertTaskWorkunit.setStatus(TaskStatusEnum.PREPARE.getStatus());
        insertTaskWorkunit.setTaskType(type);

        Date startTime = proTaskVo.getScheduleStartDate() == null ? new Date() : proTaskVo.getScheduleStartDate();
        insertTaskWorkunit.setScheduleStartDate(startTime);
        insertTaskWorkunit.setScheduleEndDate(new Date(startTime.getTime() + proTaskVo.getDuration() * 1000 * 60 * 60));
        if (Objects.equals(type, TaskConst.ASSIST_TASK)) {
            insertTaskWorkunit.setApiFlag(true);

        }

        proTaskWorkunitService.insertProTaskWorkunit(insertTaskWorkunit);
        return insertTaskWorkunit;
    }

    @Override
    @Transactional
    public void taskWorkunitSplit(ProTaskVo proTaskVo) {
        ProTaskWorkunit taskWorkunit = splitTask(proTaskVo, TaskConst.SPLIT_TASK);
        proTaskVo.setQuantity(taskWorkunit.getQuantity());
        proTaskVo.setStartTime(DataUtil.repliceData(proTaskVo.getStartTime(), proTaskVo.getScheduleStartDate()));
        proTaskVo.setEndTime(DataUtil.repliceData(proTaskVo.getEndTime(), proTaskVo.getScheduleEndDate()));
        proTaskVo.setTaskWorkunitId(taskWorkunit.getTaskWorkunitId());

        ProTask proTask = proTaskVo.deepCopyObj(ProTask.class);

        // 自动生产物料领用单
        iProMaterialRequestService.insertProMaterialRequestItemV2(proTask);

        // 自动生成刀模版申请单
        tmToolRequestService.copyTmToolMachines(proTask);
    }

    @Override
    @Transactional
    public void copyTask(ProTask proTask) {
        // 封装保存
        this.updateProTask(proTask);

        // 封装任务-工作单元
        ProTaskWorkunit proTaskWorkunit = new ProTaskWorkunit();
        proTaskWorkunit.setTaskId(proTask.getTaskId());
        proTaskWorkunit.setIdx(1L);
        proTaskWorkunit.setWorkunitId(proTask.getWorkunitId());
        proTaskWorkunit.setUnitOfMeasure(proTask.getUnitOfMeasure());
        proTaskWorkunit.setQuantity(proTask.getQuantity());
        proTaskWorkunit.setQuantityProduced(BigDecimal.ZERO);
        proTaskWorkunit.setQuantityQualify(BigDecimal.ZERO);
        proTaskWorkunit.setQuantityUnqualify(BigDecimal.ZERO);
        proTaskWorkunit.setStatus(TaskStatusEnum.PREPARE.getStatus());

        if (proTask.getStartTime() != null) {
            proTaskWorkunit.setScheduleStartDate(proTask.getStartTime());
        }

        if (proTask.getEndTime() != null && proTask.getStartTime() != null) {
            proTaskWorkunit.setScheduleEndDate(proTask.getEndTime() == null ? new Date(proTask.getStartTime().getTime() + proTask.getDuration() * 1000 * 60 * 60) : proTask.getEndTime());
        }

        proTaskWorkunitService.insertProTaskWorkunit(proTaskWorkunit);

        // 自动生产物料领用单
        iProMaterialRequestService.insertProMaterialRequestItemV2(proTask);

        // 自动生成刀模版申请单
        proTask.setTaskWorkunitId(proTaskWorkunit.getTaskWorkunitId());
        proTask.setTaskId(proTask.getTaskId());
        tmToolRequestService.copyTmToolMachines(proTask);
    }

    @Override
    public List<ProTask> selectEquipmentNewestTask(QueryWrapper<ProTask> taskQuery) {
        return proTaskMapper.selectEquipmentNewestTask(taskQuery);
    }

    @Override
    public List<ProTask> selectProTaskByWorkorderCode(String workorderCode) {
        QueryWrapper<ProTask> proTaskQueryWrapper = new QueryWrapper<>();
        proTaskQueryWrapper.eq("workorder_code", workorderCode);
        return proTaskMapper.selectListJoinByQw(proTaskQueryWrapper);
    }

    @Override
    public void closeObj(List<ProTaskVo> taskVos) {
        if (CollectionUtil.isNotEmpty(taskVos)) {
            for (ProTaskVo taskVo : taskVos) {
                ProTask proTask = taskVo.deepCopyObj(ProTask.class);
                if (proTask.getQuantity().doubleValue() == 0) {
                    proTask.setStatus(TaskStatusEnum.CLOSE.getStatus());
                }
                proTaskMapper.updateProTask(proTask);
            }
        }

    }


    @Override
    public ProTask getNextTaskByTaskId(Long taskId) {
        ProTask thisProTask = this.selectProTaskByTaskId(taskId);
        String arrangeCode = thisProTask.getArrangeCode();
        QueryWrapper<ProTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotEmpty(arrangeCode), "arrange_code", arrangeCode);
        queryWrapper.notIn(StringUtils.isNotEmpty(taskId), "task_id", taskId);
        queryWrapper.ge(StringUtils.isNotEmpty(thisProTask.getOrdinal()), "ordinal", thisProTask.getOrdinal());
        queryWrapper.orderByAsc("ordinal");
        List<ProTask> tasks = proTaskMapper.selectListByQw(queryWrapper);
        return tasks.get(0);
    }

    @Override
    public List<ProTask> selectListByQw(QueryWrapper<ProTask> proTaskQueryWrapper) {
        return proTaskMapper.selectListJoinByQw(proTaskQueryWrapper);
    }

    @Transactional
    @Override
    public void schedule(List<Long> orderIds) {
        BaoshenScheduleAlgorithmAdapter baoshenScheduleAlgorithmAdapter = new BaoshenScheduleAlgorithmAdapter();
        baoshenScheduleAlgorithmAdapter.setAlgorithmDataSource(algorithmDataSource);
        baoshenScheduleAlgorithmAdapter.setAlgorithmResultProcess(algorithmResultProcess);
        EquipmentSelectionStrategyImpl defaultStrategy = new EquipmentSelectionStrategyImpl();
        defaultStrategy.addEvaluateEquipment(evaluateEquipmentChangeOver);
        defaultStrategy.addEvaluateEquipment(new EvaluateEquipmentFunction());
        baoshenScheduleAlgorithmAdapter.setEquipmentSelectionStrategy(defaultStrategy);
        baoshenScheduleAlgorithmAdapter.setAlgorithmExtendDataSources(new ArrayList<AlgorithmExtendDataSource>() {
            private static final long serialVersionUID = -4466020352312471396L;

            {
                add(equipmentNewestTaskAlgorithmData);
                add(scheduleSetupRuleAlgorithmData);
            }
        });
        List<ScheduledResult> scheduledResults = baoshenScheduleAlgorithmAdapter.schedule(LocalDateTime.now(),
                orderIds);

        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        // closeSapWorkorderUpdate(orderIds);
        stopWatch.stop();
        logger.info(String.format("排产结果发送SAP耗时：%s", stopWatch.getTotalTimeSeconds()));

    }

    private void closeSapWorkorderUpdate(List<Long> workorderIds) {
        List<ProWorkorder> proWorkorders = proWorkorderMapper.selectListByQw(new QueryWrapper<ProWorkorder>().in("workorder_id", workorderIds));
        Set<String> workorderCodes = proWorkorders.stream().map(ProWorkorder::getWorkorderCode).filter(Objects::nonNull).collect(Collectors.toSet());
        List<Map<String, String>> objects = new ArrayList<>();
        for (String workorderCode : workorderCodes) {
            Map<String, String> map = new HashMap<>();
            map.put("AUFNR", workorderCode);
            map.put("STATUS", WorkorderStatusEnum.SCHEDULED.getValue());
            objects.add(map);
        }

        logger.info(String.format("排产发送SAP关闭工单请求参数：%s", JSON.toJSONString(objects)));
        String s = sapService.updateWorkorderStatus(JSON.toJSONString(objects));
        logger.info(String.format("排产发送SAP关闭工单返回结果：%s", JSON.toJSONString(s)));

    }

    @Override
    public ProTask selectBaseById(Long taskId) {
        List<ProTask> proTasks = proTaskMapper.selectListByQw(new QueryWrapper<ProTask>().eq("task_id", taskId));

        return proTasks.get(0);
    }


    @Override
    public List<ProTask> getTaskList(ProTaskQuery proTask) {
        ProTaskQuery proTaskQuery = new ProTaskQuery();
        BeanUtils.copyProperties(proTask, proTaskQuery);
        //判断前端传来是编号还是工单
        if (StringUtils.isNotEmpty(proTask.getArrangeCode())) {
            if (proTask.getArrangeCode().length() == 12) {
                proTask.setWorkorderCode(proTask.getArrangeCode());
                proTask.setArrangeCode(null);
            }
        }

        List<ProTask> rst = new ArrayList<>();
        List<ProTask> list = new ArrayList<>();
        QueryWrapper<ProTask> query = new QueryWrapper<>();
        List<String> statusList = Arrays.asList(TaskStatusEnum.BEGINNING.getStatus(), TaskStatusEnum.PREPARE.getStatus(),
                TaskStatusEnum.PAUSE.getStatus(), TaskStatusEnum.ERROR_STOP.getStatus());
        query.in("ptw.status", statusList);
        query.eq(proTask.getWorkunitId() != null, "mw.workunit_id", proTask.getWorkunitId());
        query.eq(StringUtils.isNotEmpty(proTask.getArrangeCode()), "t.arrange_code", proTask.getArrangeCode());
        query.gt(proTask.getAllowProduce() != null && proTask.getAllowProduce() == 1, "t.quantity_wait", 0);
        query.orderByAsc("statusIndex").orderByAsc("ptw.schedule_start_date");
        //搜索条件为工单号查询相应任务ID作为查询条件
        if (StringUtils.isNotEmpty(proTask.getWorkorderCode())) {
            QueryWrapper<ProTask> taskQuery = new QueryWrapper<>();
            taskQuery.eq("t3.workorder_code", proTask.getWorkorderCode());
            taskQuery.eq(proTask.getWorkunitId() != null, "t4.workunit_id", proTask.getWorkunitId());
            List<ProTaskVo> taskVoList = proTaskMapper.selectProTaskJoinWorkorder(taskQuery);
            if (CollectionUtil.isEmpty(taskVoList)) {
                if (CollectionUtil.isNotEmpty(rst)) {
                    for (ProTask task : rst) {
                        Double v = proFeedbackService.selectQuantityQualifySum(new ProFeedback(task.getArrangeCode(), null, null, task.getTaskWorkunitId()));
                        task.setArrangeFeedbackSum(v);
                    }
                }
                return rst;
            } else {
                query.in("t.task_id", taskVoList.stream().map(ProTaskVo::getTaskId).collect(Collectors.toList()));
            }
        }

        //判断是否前端有没传来工单或者是编码
        if (StringUtils.isNotEmpty(proTaskQuery.getArrangeCode())) {
            QueryWrapper<ProTask> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("ptw.status", statusList);
            queryWrapper.eq(proTask.getWorkunitId() != null, "mw.workunit_id", proTask.getWorkunitId());
            queryWrapper.gt(proTask.getAllowProduce() != null && proTask.getAllowProduce() == 1, "t.quantity_wait", 0);
            queryWrapper.orderByAsc("statusIndex").orderByAsc("ptw.schedule_start_date");

            List<ProTask> proTasks = this.selectProTaskJoinTaskWorkUnit(queryWrapper);
            List<ProTask> proTasks1 = this.selectProTaskJoinTaskWorkUnit(query);
            for (ProTask task : proTasks1) {
                for (ProTask task1 : proTasks) {
                    if (task.getTaskId().equals(task1.getTaskId())) {
                        task1.setLocation(1L);
                    }
                }
            }
            list.addAll(proTasks);
        } else {
            list = this.selectProTaskJoinTaskWorkUnit(query);
        }

        rst = list.stream().filter(t -> !TaskStatusEnum.FINISHED.getStatus().equals(t.getStatus())).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(rst)) {
            for (ProTask task : rst) {
                String arrangeCode = task.getArrangeCode();
                if (StringUtils.isNotEmpty(arrangeCode)) {
                    ProWorkorderQuery workorderQuery = new ProWorkorderQuery();
                    workorderQuery.setArrangeCode(arrangeCode);
                    List<ProWorkorder> proWorkorders = proWorkorderService.selectProWorkorderList(workorderQuery);
                    task.setProWorkorderList(proWorkorders);

                    Double v = proFeedbackService.selectQuantityQualifySum(new ProFeedback(arrangeCode, null, null, task.getTaskWorkunitId()));
                    task.setArrangeFeedbackSum(v);
                }
            }
        }

        Set<Long> taskWorkunitIds = rst.stream().map(ProTask::getTaskWorkunitId).collect(Collectors.toSet());
        if (CollectionUtil.isNotEmpty(taskWorkunitIds)) {
            Map<Long, ProTaskAssistProcess> assistProcessMap = proTaskAssistProcessMapper.selectListByQw(new QueryWrapper<ProTaskAssistProcess>().in("task_workunit_id", taskWorkunitIds)).stream().collect(Collectors.toMap(ProTaskAssistProcess::getTaskWorkunitId, x -> x));

            List<ProTask> proTasks = proTaskWorkunitMapper.selectListIsExistToolByTaskWorkunitIds(new QueryWrapper<ProTaskWorkunit>().in("task_workunit_id", taskWorkunitIds));
            Map<Long, ProTask> isExistToolList = proTasks.stream().collect(Collectors.toMap(ProTask::getTaskWorkunitId, x -> x));

            for (ProTask task : rst) {
                ProTaskAssistProcess assistProcess = assistProcessMap.get(task.getTaskWorkunitId());
                ProTask taskVal = isExistToolList.get(task.getTaskWorkunitId());

                if (taskVal != null) {
                    task.setIsExistTool(taskVal.getIsExistTool());
                }

                if (assistProcess != null) {
                    task.setCloseType(assistProcess.getCloseType());
                    task.setWorkorderCode(assistProcess.getWorkorderCode());
                }
            }


        }
        return rst;

    }
}
