package com.xisc.pm.app.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xisc.boot.common.feign.pojo.MtUserInfo;
import com.xisc.boot.common.sys.UserClient;
import com.xisc.pm.api.dto.InspectionCertificateDTO;
import com.xisc.pm.api.dto.PmFinishedProductsServeAsStatisticsDTO;
import com.xisc.pm.api.dto.PmMaterialInfoHangOrderDTO;
import com.xisc.pm.api.dto.PmPdRecDTO;
import com.xisc.pm.api.dto.QdMatchParamDTO;
import com.xisc.pm.api.dto.QdSurplusLowMagnificationDTO;
import com.xisc.pm.api.dto.SpotOutContractSendDTO;
import com.xisc.pm.api.dto.ThickPlatePerformanceDeterminationDTO;
import com.xisc.pm.app.service.PmFinishedProductActAsService;
import com.xisc.pm.app.service.PmPdRecService;
import com.xisc.pm.domain.entity.MmSlab;
import com.xisc.pm.domain.entity.PmCdContLog;
import com.xisc.pm.domain.entity.PmCdRuleSet;
import com.xisc.pm.domain.entity.PmCmdCont;
import com.xisc.pm.domain.entity.PmCmdContTra;
import com.xisc.pm.domain.entity.PmCmdLargePlt;
import com.xisc.pm.domain.entity.PmCmdLargePltTra;
import com.xisc.pm.domain.entity.PmCmdSlab;
import com.xisc.pm.domain.entity.PmCmdSlabTra;
import com.xisc.pm.domain.entity.PmCmdSmallPlt;
import com.xisc.pm.domain.entity.PmCmdSmallPltTra;
import com.xisc.pm.domain.entity.PmProContProdTtr;
import com.xisc.pm.domain.repository.MmPlateRepository;
import com.xisc.pm.domain.repository.MmSlabRepository;
import com.xisc.pm.domain.repository.PmCdContLogRepository;
import com.xisc.pm.domain.repository.PmCdRuleSetRepository;
import com.xisc.pm.domain.repository.PmCmdContRepository;
import com.xisc.pm.domain.repository.PmCmdContTraRepository;
import com.xisc.pm.domain.repository.PmCmdLargePltRepository;
import com.xisc.pm.domain.repository.PmCmdLargePltTraRepository;
import com.xisc.pm.domain.repository.PmCmdSlabRepository;
import com.xisc.pm.domain.repository.PmCmdSlabTraRepository;
import com.xisc.pm.domain.repository.PmCmdSmallPltRepository;
import com.xisc.pm.domain.repository.PmCmdSmallPltTraRepository;
import com.xisc.pm.domain.repository.PmProContProdTtrRepository;
import com.xisc.pm.domain.repository.PmQdToLineupResultHeattreatRepository;
import com.xisc.pm.domain.repository.PmQdToLineupResultSizingRepository;
import com.xisc.pm.domain.repository.PmQdToPoOrderRepository;
import com.xisc.pm.domain.vo.CtDetVO;
import com.xisc.pm.domain.vo.CtMainVO;
import com.xisc.pm.domain.vo.ErpInterfaceVO;
import com.xisc.pm.domain.vo.EventFeignVO;
import com.xisc.pm.domain.vo.MatStatusModifyVO;
import com.xisc.pm.domain.vo.MmPlateSmallProVO;
import com.xisc.pm.domain.vo.MmPlateVO;
import com.xisc.pm.domain.vo.MmUstRsltVO;
import com.xisc.pm.domain.vo.QdToLineupResultHeattreatVO;
import com.xisc.pm.domain.vo.QdToLineupResultUTVO;
import com.xisc.pm.domain.vo.QdToPoOrderVO;
import com.xisc.pm.domain.vo.QdToPoOrderVO1;
import com.xisc.pm.domain.vo.WmMatPileVO1;
import com.xisc.pm.domain.vo.WmStockInfoVO;
import com.xisc.pm.infra.client.MmEventClient;
import com.xisc.pm.infra.client.QdOrderClient;
import com.xisc.pm.infra.client.QeApiClient;
import com.xisc.pm.infra.constant.Constants;
import com.xisc.pm.infra.enums.PdEventType;
import com.xisc.pm.infra.mapper.PmCompositeSlabMapper;
import com.xisc.pm.infra.mapper.PmMmPlateMapper;
import com.xisc.pm.infra.mapper.QdToPoOrderMapper;
import com.xisc.pm.infra.util.BeanUtils;
import com.xisc.pm.infra.util.XbusRequestHeaderUtil;
import io.choerodon.core.exception.CommonException;
import io.choerodon.core.oauth.CustomUserDetails;
import io.choerodon.core.oauth.DetailsHelper;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.hzero.boot.interfaces.sdk.dto.RequestPayloadDTO;
import org.hzero.boot.interfaces.sdk.invoke.InterfaceInvokeSdk;
import org.hzero.boot.platform.lov.adapter.LovAdapter;
import org.hzero.boot.platform.lov.dto.LovValueDTO;
import org.hzero.core.base.BaseConstants;
import org.hzero.core.message.MessageAccessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 钢板主数据表(MmPlate)应用服务
 *
 * @author 蒋雨航 yuhang.jiang02@hand-china.com
 * @since 2024-08-14 15:37:09
 */
@Slf4j
@Service
public class PmFinishedProductActAsServiceImpl implements PmFinishedProductActAsService {
    @Autowired
    private MmPlateRepository mmPlateRepository;

    @Autowired
    private PmQdToPoOrderRepository pmQdToPoOrderRepository;

    @Autowired
    private MmSlabRepository mmSlabRepository;

    @Autowired
    private PmProContProdTtrRepository pmProContProdTtrRepository;

    @Autowired
    private PmMmPlateMapper pmMmPlateMapper;

    @Autowired
    private PmQdToLineupResultHeattreatRepository pmQdToLineupResultHeattreatRepository;

    @Autowired
    private PmQdToLineupResultSizingRepository pmQdToLineupResultSizingRepository;

    @Autowired
    private PmCdRuleSetRepository pmCdRuleSetRepository;

    @Autowired
    private PmCdContLogRepository pmCdContLogRepository;

    @Autowired
    private InterfaceInvokeSdk interfaceInvokeSdk;

    @Autowired
    private UserClient userClient;

    @Autowired
    private PmPdRecService pmPdRecService;

    @Autowired
    private PmCmdLargePltRepository pmCmdLargePltRepository;

    @Autowired
    private PmCmdContRepository pmCmdContRepository;

    @Autowired
    private PmCmdSmallPltRepository pmCmdSmallPltRepository;

    @Autowired
    private MmEventClient mmEventClient;

    @Autowired
    private LovAdapter lovAdapter;

    @Autowired
    private QeApiClient qeApiClient;

    @Autowired
    private QdToPoOrderMapper qdToPoOrderMapper;

    @Autowired
    private PmCompositeSlabMapper pmCompositeSlabMapper;

    @Autowired
    private QdOrderClient qdOrderClient;

    @Autowired
    private PmCmdLargePltTraRepository pmCmdLargePltTraRepository;
    @Autowired
    private PmCmdSlabRepository pmCmdSlabRepository;
    @Autowired
    private PmCmdSlabTraRepository pmCmdSlabTraRepository;
    @Autowired
    private PmCmdSmallPltTraRepository pmCmdSmallPltTraRepository;
    @Autowired
    private PmCmdContTraRepository pmCmdContTraRepository;


    @Override
    public List<MmPlateVO> surplusSteelPlateList(MmPlateVO mmPlatesVO, Long organizationId) {
        mmPlatesVO.setOrderThickMinValue(mmPlatesVO.getOrderThickValue());
        mmPlatesVO.setOrderThickMaxValue(mmPlatesVO.getOrderThickValue());
        if (mmPlatesVO.getThickTolMaxValue() != null) {
            mmPlatesVO.setOrderThickMaxValue((mmPlatesVO.getOrderThickMaxValue() == null ? BigDecimal.ZERO : mmPlatesVO.getOrderThickMaxValue()).add(mmPlatesVO.getThickTolMaxValue()));
        }
        if (mmPlatesVO.getThickTolMinValue() != null) {
            mmPlatesVO.setOrderThickMinValue((mmPlatesVO.getOrderThickMinValue() == null ? BigDecimal.ZERO : mmPlatesVO.getOrderThickMinValue()).add(mmPlatesVO.getThickTolMinValue()));
        }
        if (mmPlatesVO.getWidthTolMaxValue() != null) {
            mmPlatesVO.setWidthMaxValue((mmPlatesVO.getWidthMaxValue() == null ? BigDecimal.ZERO : mmPlatesVO.getWidthMaxValue()).add(mmPlatesVO.getWidthTolMaxValue()));
        }
        if (mmPlatesVO.getWidthTolMinValue() != null) {
            mmPlatesVO.setWidthMinValue((mmPlatesVO.getWidthMinValue() == null ? BigDecimal.ZERO : mmPlatesVO.getWidthMinValue()).add(mmPlatesVO.getWidthTolMinValue()));
        }
        if (mmPlatesVO.getLenTolMaxValue() != null) {
            mmPlatesVO.setOrderLenMaxValue((mmPlatesVO.getOrderLenMaxValue() == null ? BigDecimal.ZERO : mmPlatesVO.getOrderLenMaxValue()).add(mmPlatesVO.getLenTolMaxValue()));
        }
        if (mmPlatesVO.getLenTolMinValue() != null) {
            mmPlatesVO.setOrderLenMinValue((mmPlatesVO.getOrderLenMinValue() == null ? BigDecimal.ZERO : mmPlatesVO.getOrderLenMinValue()).add(mmPlatesVO.getLenTolMinValue()));
        }
        return mmPlateRepository.surplusSteelPlateList(mmPlatesVO);
    }

    @Override
    public List<QdToPoOrderVO1> surplusSteelPlateOrderList(QdToPoOrderVO1 qdToPoOrder, Long organizationId) {
        List<QdToPoOrderVO1> qdToPoOrderList = pmQdToPoOrderRepository.surplusSteelPlateOrderList(qdToPoOrder);
        if (CollectionUtils.isEmpty(qdToPoOrderList)) {
            return qdToPoOrderList;
        }

        // 可组板数>0（可组板数：根据合同号，whole_backlog_code=‘13’获取（包括生产合同管理）CT_DET的STOCK_NUM – PLAN_NUM）
        List<String> orderNoList = qdToPoOrderList.stream().map(QdToPoOrderVO1::getOrderNo).distinct().collect(Collectors.toList());
        List<CtDetVO> ctDetVOList = qdToPoOrderMapper.selectCtDetByOrderList(orderNoList, organizationId);
        Map<String, BigDecimal> ctDetVOMap = new HashMap<>(ctDetVOList.size());
        if (CollectionUtils.isNotEmpty(ctDetVOList)) {
            ctDetVOMap = ctDetVOList.stream().collect(Collectors.toMap(CtDetVO::getOrderNo, CtDetVO::getUserdBoardNum));
        }
        List<QdToPoOrderVO1> finalQdToPoOrderList  = new ArrayList<>(qdToPoOrderList.size());
        for (QdToPoOrderVO1 qdToPoOrderVO1 : qdToPoOrderList) {
            if (!ctDetVOMap.containsKey(qdToPoOrderVO1.getOrderNo())) {
                continue;
            }
            qdToPoOrderVO1.setUserdBoardNum(ctDetVOMap.get(qdToPoOrderVO1.getOrderNo()));
            finalQdToPoOrderList.add(qdToPoOrderVO1);
        }
        if (CollectionUtils.isEmpty(finalQdToPoOrderList)) {
            return finalQdToPoOrderList;
        }
        // 组装返参
        return  buildOrderList(finalQdToPoOrderList, organizationId);
    }

    @GlobalTransactional(rollbackFor = Exception.class)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String surplusSteelPlateHangOrder(PmMaterialInfoHangOrderDTO dto, Long organizationId) {
        //材料信息
        List<MmPlateVO> mmPlateVOList = dto.getMmPlateList();
        //合同号
        String orderNo = dto.getOrderNo();

        String information = Strings.EMPTY;

        // 2. 检查目标合同转用条件
        //根据合同号查询合同跟踪主表CT_MAIN的合同状态order_status并校验存在，其值必须大于等于40且小于57，否则中断，提示信息为：PM.CD_PLATE_001。
        String orderStatus = pmMmPlateMapper.selectOrderStatusByOrderNo(orderNo);
        if (StringUtils.isNotEmpty(orderStatus)) {
            long status = Long.parseLong(orderStatus);
            if (status < 40 || status >= 57) {
                throw new CommonException("pm.cd_plate_001", orderNo, orderStatus);
            }
        } else {
            throw new CommonException("pm.cd_plate_030", orderNo, "合同跟踪主表CT_MAIN");
        }
        //根据合同号order_no查询合同的MES合同主档QD_TO_PO_ORDER信息
        List<QdToPoOrderVO1> toPoOrderList = pmMmPlateMapper.selectOrderInfo(Arrays.asList(orderNo), organizationId);
        if (CollectionUtils.isEmpty(toPoOrderList)) {
            throw new CommonException("pm.cd_plate_030", orderNo, "MES合同主档QD_TO_PO_ORDER");
        }
        QdToPoOrderVO1 qdToPoOrder = toPoOrderList.get(0);
        //根据合同号查询MES合同主档QD_TO_PO_ORDER的奉送样标记give_sample_flag并校验存在，如果值等于1则函数中断，提示信息为：PM.CD_PLATE_002。
        if (Objects.nonNull(qdToPoOrder.getGiveSampleFlag()) && "1".equals(qdToPoOrder.getGiveSampleFlag())) {
            throw new CommonException("pm.cd_plate_002", qdToPoOrder.getOrderNo(), qdToPoOrder.getGiveSampleFlag());
        }

        //根据合同号order_no查询生产合同产品属性表PM_PRO_CONT_PROD_ATTR的订货厚度ORDER_THICK、宽度上限WIDTH_MAX、宽宽度下限WIDTH_MIN、
        // 订货长度上限ORDER_MAX_LEN、订货长度下限ORDER_MIN_LEN并校验存在。如果不存在，提示信息为：PM.CD.PLATE.003。
        PmProContProdTtr pmProContProdTtrQuery = new PmProContProdTtr();
        pmProContProdTtrQuery.setOrderNo(orderNo);
        PmProContProdTtr pmProContProdTtr = pmProContProdTtrRepository.selectOne(pmProContProdTtrQuery);
        if (Objects.nonNull(pmProContProdTtr)) {
            if (Objects.isNull(pmProContProdTtr.getOrderThick()) || Objects.isNull(pmProContProdTtr.getWidthMax())
                    || Objects.isNull(pmProContProdTtr.getWidthMin()) || Objects.isNull(pmProContProdTtr.getOrderMaxLen())
                    || Objects.isNull(pmProContProdTtr.getOrderMinLen())) {
                throw new CommonException("pm.cd_plate_003", orderNo, pmProContProdTtr.getOrderThick(), pmProContProdTtr.getWidthMax()
                        , pmProContProdTtr.getWidthMin(), pmProContProdTtr.getOrderMaxLen(), pmProContProdTtr.getOrderMinLen());
            }
        }

        // 3. 材料与合同信息验证与确认
        List<String> matNoList = mmPlateVOList.stream().map(MmPlateVO::getMatNo).collect(Collectors.toList());
      //  String recSts = "2";
        //查询已产出的材料信息
      //  List<MmPlateVO> mmPlates1VO = pmMmPlateMapper.selectMmPateList(matNoList, recSts);
        for (MmPlateVO mmPlateVO : mmPlateVOList) {
            // 板坯号以F或K开头的钢板,挂复合板合同QFH、ZSF、NSF,
            if ((mmPlateVO.getSlabNo().startsWith("F") || mmPlateVO.getSlabNo().startsWith("K")) &&
                    !"QFH".equals(qdToPoOrder.getOrderTypeCode()) && !"ZSF".equals(qdToPoOrder.getOrderTypeCode()) &&
                    !"NSF".equals(qdToPoOrder.getOrderTypeCode())) {
                throw new CommonException("pm.cd_plate_005", mmPlateVO.getMatNo(), orderNo);
            }

            // 板坯号不以F或K开头的钢板,挂非、ZSF、NSF合同，
            if (!(mmPlateVO.getSlabNo().startsWith("F") || mmPlateVO.getSlabNo().startsWith("K")) &&
                    ("ZSF".equals(qdToPoOrder.getOrderTypeCode()) || "NSF".equals(qdToPoOrder.getOrderTypeCode()))) {
                throw new CommonException("pm.cd_plate_010", mmPlateVO.getMatNo(), orderNo);
            }

            //校验材料的材料状态mat_status等于39，否则不通过，提示信息为：PM.CD.PLATE.006
            if (!"39".equals(mmPlateVO.getMatStatus())) {
                throw new CommonException("pm.cd_plate_006", mmPlateVO.getMatNo(), mmPlateVO.getMatStatus());
            }
            //校验材料的综合判定代码complex_decide_code等于1（已综判），否则不通过，提示信息为：PM.CD.PLATE.007。
            if (!"1".equals(mmPlateVO.getComplexDecideCode())) {
                throw new CommonException("pm.cd_plate_007", mmPlateVO.getMatNo(), mmPlateVO.getComplexDecideCode());
            }
            //若MES合同主档QD_TO_PO_ORDER的计重方式代码wt_method_code等于1则校验钢板主数据表(状态代码为已产出)MM_PLATE的钢板毛重MAT_GROSS_WGT不等于0，如果等于0，
            // 则函数中断，提示信息为：PM.CD.PLATE.016。
            if ("1".equals(qdToPoOrder.getWtMethodCode())) {
                if (BigDecimal.ZERO.compareTo(mmPlateVO.getMatGrossWgt()) == 0) {
                    throw new CommonException("pm.cd_plate_016", mmPlateVO.getOrderNo(), mmPlateVO.getMatNo());
                }
            }
        }

        // 获取产线号
        List<String> mscLineNoList = mmPlateVOList.stream().map(MmPlateVO::getMscLineNo).collect(Collectors.toList());
//        mscLineNoList.add(qdToPoOrder.getMscLineNo());
//        recSts = "1";
//        List<MmPlateVO> mmPlates2VO = pmMmPlateMapper.selectMmPateList(matNoList, recSts);
//        for (MmPlateVO mmPlateVO : mmPlates2VO) {
//            //若钢板主数据表(状态为有计划未切)MM_PLATE的合同号order_no不为空，则函数中断，提示信息为：PM.CD.PLATE.013。
//            if (Objects.nonNull(mmPlateVO.getOrderNo())) {
//                throw new CommonException("pm.cd_plate_013", mmPlateVO.getMatNo(), mmPlateVO.getOrderNo());
//            }
//            //若钢板主数据表(状态为有计划未切)MM_PLATE的原合同号ORG_ORDER_NO为空，则函数中断，提示信息为：PM.CD.PLATE.014
//            if (Objects.isNull(mmPlateVO.getOrgOrderNo())) {
//                throw new CommonException("pm.cd_plate_014");
//            }
//        }
        //若MES合同主档QD_TO_PO_ORDER的厚度公差下限GAUGE_TOL_L大于原合同的或者厚度公差上限GAUGE_TOL_U小于原合同的，则函数中断，提示信息为：PM.CD.PLATE.017。
        List<String> orgOrderNoList = mmPlateVOList.stream().map(MmPlateVO::getOrgOrderNo).collect(Collectors.toList());
        List<QdToPoOrderVO1> orgOderList = pmMmPlateMapper.selectOrderInfo(orgOrderNoList, organizationId);
        for (QdToPoOrderVO1 orgOrder : orgOderList) {
            if (qdToPoOrder.getThickTolMin().compareTo(orgOrder.getThickTolMin()) > 0 || qdToPoOrder.getThickTolMax().compareTo(orgOrder.getThickTolMax()) < 0) {
                throw new CommonException("pm.cd_plate_017", qdToPoOrder.getOrderNo(), qdToPoOrder.getThickTolMin(), qdToPoOrder.getThickTolMax(),
                        orgOrder.getOrderNo(), orgOrder.getThickTolMin(), orgOrder.getThickTolMax());
            }
        }
//        List<String> newMatoList = new ArrayList<>();
//        matNoList.forEach(item -> {
//                    //取前7位拼接上"000"
//                    String newItem = item.substring(0, 7) + "000";
//                    newMatoList.add(newItem);
//                }
//        );

        // 根据钢板号等于钢板小工序表MM_PLATE_SMALL_PRO的mat_no、小工序代码sub_backlog_code第二位等于A或Q或N或者T、工序追加区分backlog_add_div等于0，
        // 工序通过时间BACKLOG_PASS_TIME不为空，按小工序顺序号SUB_BACKLOG_SEQ从小到大排序，将查询结果拼成一个字符串。
       List<MmPlateSmallProVO> mmPlateSmallProVOList = pmMmPlateMapper.getSubBacklogCode(matNoList, organizationId);
       // 钢板号和对应材料热处理方式代码
       Map<String,String> plateCodeMap = new HashMap<>(mmPlateSmallProVOList.size());
       if (CollectionUtils.isNotEmpty(mmPlateSmallProVOList)) {
           Map<String, List<MmPlateSmallProVO>> plateSmallMap = mmPlateSmallProVOList.stream().collect(Collectors.groupingBy(MmPlateSmallProVO::getMatNo));
           for(Map.Entry<String, List<MmPlateSmallProVO>> entry : plateSmallMap.entrySet()) {
               String result = entry.getValue().stream().sorted(Comparator.comparing(MmPlateSmallProVO::getSubBacklogSeq))
                       .map(MmPlateSmallProVO::getSubBacklogCode).collect(Collectors.joining());
               plateCodeMap.put(entry.getKey(), result);
           }
       }

       // 根据勾选材料信息（旧合同号：MM_PLATE表ORG_ORDER_NO）、勾选合同信息（新合同号：QD_TO_PO_ORDER表ORDER_NO）分别对应的合同号ORDER_NO
        // 获取合同处理热处理工艺标准QD_TO_LINEUP_RESULT_HEATTREAT表的HEAT_TREATMENT_TYPE作为合同的热处理方式代码，多条记录则取第一条（取时间最早）
        List<String> orderNoAllList = new ArrayList<>(16);
        orderNoAllList.addAll(orgOrderNoList);
        orderNoAllList.add(orderNo);
        List<QdToLineupResultHeattreatVO> resultHeattreatVOList = pmMmPlateMapper.getHeatTreatType(orderNoAllList, mscLineNoList, organizationId);
        Map<String, String> orderTypeMap = new HashMap<>(resultHeattreatVOList.size());
        if (CollectionUtils.isNotEmpty(resultHeattreatVOList)) {
           orderTypeMap = resultHeattreatVOList.stream().collect(Collectors
                    .toMap(item->item.getOrderNo() + item.getMscLineNo(), QdToLineupResultHeattreatVO::getHeatTreatmentType));
        }

        // 2)	合同的轧制方向代码与控轧代码查询与校验
        //根据合同号order_no、钢板主数据表(状态代码为已产出)MM_PLATE的产线号msc_line_no查询合同处理轧钢工艺标准QD_TO_LINEUP_RESULT_HEAT的轧制方向代码ROLL_DIRECT_CODE、控轧代码CTRL_ROLL_CODE并校验存在。
 //       List<QdToLineupResultRollingVO> rollingList = pmMmPlateMapper.selectQdtoLineupResultRolling(qdToPoOrder.getOrderNo(), mscLineNoList, organizationId);
//        Map<String, QdToLineupResultRollingVO> mscLineNoMap = rollingList.stream().collect(Collectors.toMap(QdToLineupResultRollingVO::getMscLineNo, Function.identity(), (v1, v2) -> v1));
//        for (MmPlateVO mmPlateVO : mmPlateVOList) {
//            //材料轧制方向代码
//            mmPlateVO.setRollDirectCode(mscLineNoMap.get(mmPlateVO.getMscLineNo()).getRollDirectCode());
//            //材料控轧代码
//            mmPlateVO.setCtrlRollCode(mscLineNoMap.get(mmPlateVO.getMscLineNo()).getCtrlRollCode());
//        }
        //合同轧制方向代码
//        qdToPoOrder.setRollDirectCode(mscLineNoMap.get(qdToPoOrder.getMscLineNo()).getRollDirectCode());
//        //合同控轧代码
//        qdToPoOrder.setCtrlRollCode(mscLineNoMap.get(qdToPoOrder.getMscLineNo()).getCtrlRollCode());


        // 3)	新旧合同超声探伤代码ULT_CODE查询与校验
        // 根据合同号order_no查询合同处理精整工艺标准QD_TO_LINEUP_RESULT_UT中第一行记录的超声探伤代码UT_CODE并将去重、按UT_CODE顺序排序，并将结果拼成一个“-”间隔的字符串。
        List<QdToLineupResultUTVO> qdToLineupResultUTVOList =  pmMmPlateMapper.selectUtCode(Arrays.asList(orderNo), organizationId);
         Map<String, List<MmUstRsltVO>> mmUstRsltVOMap = new HashMap<>(qdToLineupResultUTVOList.size());
         String ultCodeNew = Strings.EMPTY;
        if (CollectionUtils.isNotEmpty(qdToLineupResultUTVOList)) {
            // 新合同超声探伤代码ULT_COD 升序排序拼接
            ultCodeNew = qdToLineupResultUTVOList.stream().map(QdToLineupResultUTVO::getUtCode).filter(StringUtils::isNotEmpty).sorted()
                    .distinct().collect(Collectors.joining("-"));
            List<String> newUtCodeList = qdToLineupResultUTVOList.stream().map(QdToLineupResultUTVO::getUtCode).collect(Collectors.toList());
            List<MmUstRsltVO> mmUstRsltVOList = pmMmPlateMapper.selectResutCode(matNoList, newUtCodeList, organizationId);
            if (CollectionUtils.isEmpty(mmUstRsltVOList)) {
                mmUstRsltVOMap = mmUstRsltVOList.stream().collect(Collectors.groupingBy(MmUstRsltVO::getPlateNo));
            }
        }


        // 旧合同超声探伤代码ULT_CODE确定：
        //根据原合同号order_no查询合同探伤标准QD_TO_LINEUP_RESULT_UT中第一行记录的超声探伤代码ULT_CODE并校验存在。（不存在是否需要抛出异常）
        List<QdToLineupResultUTVO> orgOrderResultSizingList = pmMmPlateMapper.selectUtCode(orgOrderNoList, organizationId);
        Map<String, String>  oldUtCodeMap = new HashMap<>(orgOrderResultSizingList.size());
        if (CollectionUtils.isNotEmpty(orgOrderResultSizingList)) {
            //旧合同超声探伤代码ULT_COD
           oldUtCodeMap = orgOrderResultSizingList.stream().filter(item->StringUtils.isNotEmpty(item.getUtCode()))
                   .collect(Collectors.groupingBy(QdToLineupResultUTVO::getOrderNo,
                            Collectors.mapping(QdToLineupResultUTVO::getUtCode,  Collectors.collectingAndThen(
                                    Collectors.toList(), list -> list.stream().sorted().collect(Collectors.joining("-"))))));
        }
//        for (MmPlateVO mmPlateVO : mmPlates2VO) {
//            //根据材料号mat_no查询钢板主数据表(状态为有计划未切)MM_PLATE的原合同号ORG_ORDER_NO并校验存在
//            if (Objects.isNull(mmPlateVO.getOrgOrderNo())) {
//                throw new CommonException("pm.cd_plate_025", mmPlateVO.getMatNo());
//            }
//        }

        //检查目标合同是否超欠量
        //根据合同号order_no查询合同处理产线组合QD_TO_PO_LINE_COMB的产线号msc_line_no并校验存在。
        //产线号
//        String mscLineNo = pmMmPlateMapper.selectMscLineNo(orderNo);
//        if (StringUtils.isEmpty(mscLineNo)) {
//            throw new CommonException("pm.cd_plate_026");
//        }

        // 2、	转用规则检查：
        //转用规则检查：根据规则集类型RULE_SET_TYPE等于HP查询充当规则集PM_CD_RULE_SET并按照规则号RULE_NO排序，并根据查询结果进行相应规则检查。
        PmCdRuleSet pmCdRuleSetQuery = new PmCdRuleSet();
        pmCdRuleSetQuery.setRuleSetType("HP");
        pmCdRuleSetQuery.setValidFlag(1L);
        pmCdRuleSetQuery.setTenantId(organizationId);
        List<PmCdRuleSet> pmCdRuleSetList = pmCdRuleSetRepository.selectList(pmCdRuleSetQuery);
        List<Long> ruleNoList = pmCdRuleSetList.stream().map(PmCdRuleSet::getRuleNo).collect(Collectors.toList());
        //根据新合同号查询对应的轧制方向代码
//        String rollDirectCode = pmMmPlateMapper.selectRollDirectCode(orderNo, organizationId);
        // 获取新旧合同的扎制代码
        List<MmPlateVO> voList = pmMmPlateMapper.selectRollDirectCodeList(orderNoAllList, mscLineNoList,organizationId);
        Map<String, MmPlateVO> map = voList.stream().collect(Collectors.toMap(item->item.getOrderNo() + item.getMscLineNo(), Function.identity(), (K,V)->K));
        for (Long ruleNo : ruleNoList) {
            for (MmPlateVO mmPlateVO : mmPlateVOList) {
                checkFieldNotEmpty(qdToPoOrder);
                if (ruleNo == 1) {
                    //规则号rule_no为1：校验合同与材料的牌号一致，否则函数中断，提示信息为：PM.CD.RULE.001。
                    if (!mmPlateVO.getSgSign().equals(qdToPoOrder.getSgSign())) {
                        throw new CommonException("pm.cd_rule_001", qdToPoOrder.getOrderNo(), mmPlateVO.getSgSign());
                    }
                }
                if (ruleNo == 2) {
                    //若订货厚度加上厚度公差下限大于材料实际厚度则函数中断，提示信息为：PM.CD.RULE.002。
                    if (qdToPoOrder.getOrderThick().add(qdToPoOrder.getThickTolMin()).compareTo(mmPlateVO.getMatActThk()) > 0) {
                        throw new CommonException("pm.cd_rule_002", qdToPoOrder.getThickTolMin(), mmPlateVO.getMatActThk());
                    }
                    //若订货厚度加厚度公差上限小于材料实际厚度则函数中断，提示信息为：PM.CD.RULE.002。
                    if (qdToPoOrder.getOrderThick().add(qdToPoOrder.getThickTolMax()).compareTo(mmPlateVO.getMatActThk()) < 0) {
                        throw new CommonException("pm.cd_rule_002", qdToPoOrder.getThickTolMax(), mmPlateVO.getMatActThk());
                    }
                }
                if (ruleNo == 3) {
                    //若宽度上限加宽度公差上限小于材料实际宽度则函数中断，提示信息为：PM.CD.RULE.003。
                    if (qdToPoOrder.getWidthMax().add(qdToPoOrder.getWidthTolMax()).compareTo(mmPlateVO.getMatActWid()) < 0) {
                        throw new CommonException("pm.cd_rule_003", qdToPoOrder.getWidthTolMax().add(qdToPoOrder.getWidthMax()), mmPlateVO.getMatActWid());
                    }
                    //若宽度下限加宽度公差下限大于材料实际宽度则函数中断，提示信息为：PM.CD.RULE.004。
                    if (qdToPoOrder.getWidthMin().add(qdToPoOrder.getWidthTolMin()).compareTo(mmPlateVO.getMatActWid()) > 0) {
                        throw new CommonException("pm.cd_rule_004", qdToPoOrder.getWidthTolMin().add(qdToPoOrder.getWidthMin()), mmPlateVO.getMatActWid());
                    }
                }
                if (ruleNo == 4) {
                    //若订货最小长度加长度公差下限大于材料实际长度，则函数中断，提示信息为：PM.CD.RULE.005。
                    if (qdToPoOrder.getOrderMinLen().add(qdToPoOrder.getLenTolMin()).compareTo(mmPlateVO.getMatActLen()) > 0) {
                        throw new CommonException("pm.cd_rule_005", qdToPoOrder.getLenTolMin().add(qdToPoOrder.getOrderMinLen()), mmPlateVO.getMatActLen());
                    }
                    //若订货最大长度加长度公差上限小于材料实际长度，则函数中断，提示信息为：PM.CD.RULE.006。
                    if (qdToPoOrder.getOrderMaxLen().add(qdToPoOrder.getLenTolMax()).compareTo(mmPlateVO.getMatActLen()) < 0) {
                        throw new CommonException("pm.cd_rule_006", qdToPoOrder.getLenTolMax().add(qdToPoOrder.getOrderMaxLen()), mmPlateVO.getMatActLen());
                    }
                }
                if (ruleNo == 6) {
                    // 合同没有查询到相关信息，但材料有，则提示
                    if (!orderTypeMap.containsKey(orderNo + mmPlateVO.getMscLineNo()) && plateCodeMap.containsKey(mmPlateVO.getMatNo())) {
                        // 提示查不到记录
                        information = MessageAccessor.getMessage("pm.cd_plate_019", new Object[]{null, plateCodeMap.get(mmPlateVO.getMatNo())}).getDesc();
                    }
                    // 若查不到记录则不做此规则集校验；
                    //若新旧合同热处理方式不一致，则报错：“新旧合同热处理方式不一致，不能充当”；
                    if (orderTypeMap.containsKey(orderNo + mmPlateVO.getMscLineNo()) && !orderTypeMap.get(orderNo + mmPlateVO.getMscLineNo())
                            .equals(orderTypeMap.getOrDefault(mmPlateVO.getOrgOrderNo()+ mmPlateVO.getMscLineNo(), ""))) {
                        throw new CommonException("pm.cd_rule_007");
                    }
                    // 若材料与合同热处理方式代码不相等，则函数中断，提示信息为：PM.CD.RULE.008。
                    if (orderTypeMap.containsKey(orderNo+ mmPlateVO.getMscLineNo()) && !orderTypeMap.get(orderNo+ mmPlateVO.getMscLineNo())
                            .equals(plateCodeMap.getOrDefault(mmPlateVO.getMatNo(), ""))) {
                        throw new CommonException("pm.cd_rule_008", orderTypeMap.getOrDefault(orderNo+ mmPlateVO.getMscLineNo(), null),
                                plateCodeMap.getOrDefault(mmPlateVO.getMatNo(),null));
                    }
                }
                if (ruleNo == 7) {
                    String rollDirectCodeOld = map.getOrDefault(mmPlateVO.getOrgOrderNo() + mmPlateVO.getMscLineNo(),new MmPlateVO()).getRollDirectCode();
                    String rollDirectCodeNew = map.getOrDefault(orderNo + mmPlateVO.getMscLineNo(),new MmPlateVO()).getRollDirectCode();
                    if (StringUtils.isNotEmpty(rollDirectCodeOld) && StringUtils.isNotEmpty(rollDirectCodeNew)) {
                        //若合同的轧制方向代码与材料的轧制方向代码不相等，则函数中断，提示信息为：PM.CD.RULE.009。
                        if (!rollDirectCodeOld.equals(rollDirectCodeNew)) {
                            throw new CommonException("pm.cd_rule_009", rollDirectCodeNew, rollDirectCodeOld);
                        }
                    }
                }
                if (ruleNo == 8) {
                    String ctrlDirectCodeOld = map.getOrDefault(mmPlateVO.getOrgOrderNo() + mmPlateVO.getMscLineNo(),new MmPlateVO()).getCtrlRollCode();
                    String ctrlDirectCodeNew = map.getOrDefault(orderNo + mmPlateVO.getMscLineNo(),new MmPlateVO()).getCtrlRollCode();
                    if (StringUtils.isNotEmpty(ctrlDirectCodeOld) && StringUtils.isNotEmpty(ctrlDirectCodeNew)) {
                        //若合同的轧制方向代码与材料的轧制方向代码不相等，则函数中断，提示信息为：PM.CD.RULE.009。
                        if (!ctrlDirectCodeOld.equals(ctrlDirectCodeNew)) {
                            throw new CommonException("pm.cd_rule_010", ctrlDirectCodeNew, ctrlDirectCodeOld);
                        }
                    }

                }
                if (ruleNo == 9) {
                    // 外部接口 厚板余材性能判定，若接口返回参数中结果标记pch_judge_code不等于1则函数中断，提示信息为：PM.CD.RULE.011。
                    ThickPlatePerformanceDeterminationDTO queryDto = new ThickPlatePerformanceDeterminationDTO();
                    queryDto.setOrderNo(dto.getOrderNo());
                    queryDto.setPlateId(mmPlateVO.getPlateId());
                    queryDto.setOldOrderNo(mmPlateVO.getOrgOrderNo());
                    ThickPlatePerformanceDeterminationDTO resultDto = qeApiClient.thickPlatePerformanceDeterminationApi(organizationId, queryDto);
                    if ("2".equals(resultDto.getResult())) {
                        throw new CommonException("pm.cd_rule_011", resultDto.getFailAbn());
                    }
                }
                if (ruleNo == 10) {
                    //若合同的切边标记与材料的最终切断面代码不相等则校验不通过，进行以下逻辑：
                    if (StringUtils.isEmpty(mmPlateVO.getFinalCutSurfaceCode())) {
                        mmPlateVO.setFinalCutSurfaceCode("0");
                    } else if ("1".equals(mmPlateVO.getFinalCutSurfaceCode())) {
                        mmPlateVO.setFinalCutSurfaceCode("2");
                    }
                    if (!mmPlateVO.getFinalCutSurfaceCode().equals(qdToPoOrder.getTrimFlag())) {
                        //若切边标记trim_flag等于2且最终切断面代码final_cut_surface_code等于4，提示信息：PM.CD.RULE.012。否则函数中断，提示信息为：PM.CD.RULE.013。
                        if ("2".equals(qdToPoOrder.getTrimFlag()) && "4".equals(mmPlateVO.getFinalCutSurfaceCode())) {
//                            throw new CommonException("pm.cd_rule_012", qdToPoOrder.getTrimFlag(), mmPlateVO.getFinalCutSurfaceCode()); 提示细腻
                        } else {
                            throw new CommonException("pm.cd_rule_013", qdToPoOrder.getTrimFlag(), mmPlateVO.getFinalCutSurfaceCode());
                        }
                    }
                }
                if (ruleNo == 11) {
                    //判断新旧合同是否一致，则函数中断，提示信息为PM.CD.RULE.014。
                    if (StringUtils.isNotEmpty(ultCodeNew) && !ultCodeNew.equals(oldUtCodeMap.get(mmPlateVO.getOrgOrderNo()))) {
                        throw new CommonException("pm.cd_rule_014", ultCodeNew, oldUtCodeMap.get(mmPlateVO.getOrgOrderNo()));
                    }
                }
                if (ruleNo == 12) {
                    // MM_UST_RSLT探伤实绩表，根据plate_no钢板号、新合同号的超声探伤代码UT_CODE查询DETECT_RESULT_CODE探伤结果代码，按时间取最新的一条记录，
                    // 如果不存在则为空;结果中只要有一个N则最终结果为不合格，则函数中断，”材料探伤不合格，合同对探伤有要求不能充当
                    if (mmUstRsltVOMap.containsKey(mmPlateVO.getMatNo())) {
                        boolean flag = mmUstRsltVOMap.get(mmPlateVO.getMatNo()).stream().anyMatch(mmUstRsltVO -> "N".equals(mmUstRsltVO.getDetectResultCode()));
                        if (flag) {
                            throw new CommonException("pm.cd_plate_012", mmPlateVO.getMatNo());
                        }
                    }
                }
            }
        }

        // 校验可组板数
        List<CtDetVO> ctDetVOList = pmCompositeSlabMapper.selectCtDetByOrderList(Arrays.asList(orderNo), organizationId);
        if (CollectionUtils.isEmpty(ctDetVOList)) {
            throw new CommonException("pm.cd_plate_034", orderNo);
        }
        if (ctDetVOList.get(0).getUserdBoardNum().compareTo(BigDecimal.ONE) < 0) {
            throw new CommonException("pm.cd_plate_033", ctDetVOList.get(0).getUserdBoardNum());
        }


        // 校验如果新旧合同喷刻印信息
        Map<String, String> orgOrderResultMap = new HashMap<>(orgOderList.size());
        for (QdToPoOrderVO1 qdToPoOrderVO1 : orgOderList) {
            if ( StringUtils.isNotEmpty(qdToPoOrder.getPrintType()) && !qdToPoOrder.getPrintType().equals(qdToPoOrderVO1.getPrintType())) {
                orgOrderResultMap.put(qdToPoOrderVO1.getOrderNo(), "Y");
                continue;
            }
            if ( StringUtils.isNotEmpty(qdToPoOrder.getFacePrintDetailA()) && !qdToPoOrder.getFacePrintDetailA().equals(qdToPoOrderVO1.getFacePrintDetailA())) {
                orgOrderResultMap.put(qdToPoOrderVO1.getOrderNo(), "Y");
                continue;
            }
            if ( StringUtils.isNotEmpty(qdToPoOrder.getFacePrintDetailB()) && !qdToPoOrder.getFacePrintDetailB().equals(qdToPoOrderVO1.getFacePrintDetailB())) {
                orgOrderResultMap.put(qdToPoOrderVO1.getOrderNo(), "Y");
                continue;
            }
            if ( StringUtils.isNotEmpty(qdToPoOrder.getFacePrintDetailC()) && !qdToPoOrder.getFacePrintDetailC().equals(qdToPoOrderVO1.getFacePrintDetailC())) {
                orgOrderResultMap.put(qdToPoOrderVO1.getOrderNo(), "Y");
                continue;
            }
            if ( StringUtils.isNotEmpty(qdToPoOrder.getFacePrintDetailD()) && !qdToPoOrder.getFacePrintDetailD().equals(qdToPoOrderVO1.getFacePrintDetailD())) {
                orgOrderResultMap.put(qdToPoOrderVO1.getOrderNo(), "Y");
                continue;
            }
            if ( StringUtils.isNotEmpty(qdToPoOrder.getFacePrintDetailE()) && !qdToPoOrder.getFacePrintDetailE().equals(qdToPoOrderVO1.getFacePrintDetailE())) {
                orgOrderResultMap.put(qdToPoOrderVO1.getOrderNo(), "Y");
                continue;
            }
            if ( StringUtils.isNotEmpty(qdToPoOrder.getFacePrintDetailF()) && !qdToPoOrder.getFacePrintDetailF().equals(qdToPoOrderVO1.getFacePrintDetailF())) {
                orgOrderResultMap.put(qdToPoOrderVO1.getOrderNo(), "Y");
                continue;
            }
            if ( StringUtils.isNotEmpty(qdToPoOrder.getFacePrintDetailG()) && !qdToPoOrder.getFacePrintDetailG().equals(qdToPoOrderVO1.getFacePrintDetailG())) {
                orgOrderResultMap.put(qdToPoOrderVO1.getOrderNo(), "Y");
                continue;
            }
            if ( StringUtils.isNotEmpty(qdToPoOrder.getSidePrintDetailA()) && !qdToPoOrder.getSidePrintDetailA().equals(qdToPoOrderVO1.getSidePrintDetailA())) {
                orgOrderResultMap.put(qdToPoOrderVO1.getOrderNo(), "Y");
                continue;
            }
            if ( StringUtils.isNotEmpty(qdToPoOrder.getSidePrintDetailB()) && !qdToPoOrder.getSidePrintDetailB().equals(qdToPoOrderVO1.getSidePrintDetailB())) {
                orgOrderResultMap.put(qdToPoOrderVO1.getOrderNo(), "Y");
                continue;
            }
            if ( StringUtils.isNotEmpty(qdToPoOrder.getStampPrintDetailA()) && !qdToPoOrder.getStampPrintDetailA().equals(qdToPoOrderVO1.getStampPrintDetailA())) {
                orgOrderResultMap.put(qdToPoOrderVO1.getOrderNo(), "Y");
                continue;
            }
            if ( StringUtils.isNotEmpty(qdToPoOrder.getStampPrintDetailB()) && !qdToPoOrder.getStampPrintDetailB().equals(qdToPoOrderVO1.getStampPrintDetailB())) {
                orgOrderResultMap.put(qdToPoOrderVO1.getOrderNo(), "Y");
                continue;
            }
            if ( StringUtils.isNotEmpty(qdToPoOrder.getStampPrintDetailC()) && !qdToPoOrder.getStampPrintDetailC().equals(qdToPoOrderVO1.getStampPrintDetailC())) {
                orgOrderResultMap.put(qdToPoOrderVO1.getOrderNo(), "Y");
                continue;
            }
            if ( StringUtils.isNotEmpty(qdToPoOrder.getStampPrintDetailD()) && !qdToPoOrder.getStampPrintDetailC().equals(qdToPoOrderVO1.getStampPrintDetailD())) {
                orgOrderResultMap.put(qdToPoOrderVO1.getOrderNo(), "Y");
                continue;
            }
            orgOrderResultMap.put(qdToPoOrderVO1.getOrderNo(), "N");
        }

        // 5、	添加四大命令信息(如果新旧合同喷刻印信息不一致)
        // 钢板主数据表MM_PLATE根据钢板号查询到命令板坯号PONO_SLAB
        List<String> ponoSlabList = mmPlateVOList.stream().map(MmPlateVO::getPonoSlab).distinct().collect(Collectors.toList());
        // 在钢板主数据表 MM PLATE 根据钢板号査询到命令板坯号 PONO SLAB,根据命令板坯号 PONO SLAB 查询以下三张表的原表原字段值;

        // 1)	命令大板表（PM_CMD_LARGE_PLT）
        List<PmCmdLargePlt> pmCmdLargePltList = pmCmdLargePltRepository.selectByPonoSlabList(ponoSlabList, organizationId);
        Map<String, PmCmdLargePlt> pmCmdLargePltMap = new HashMap<>(pmCmdLargePltList.size());
        if (CollectionUtils.isNotEmpty(pmCmdLargePltList)) {
           pmCmdLargePltMap = pmCmdLargePltList.stream()
                    .collect(Collectors.toMap(PmCmdLargePlt::getPonoSlabNo, Function.identity(), (k, v) -> k));
        }
        List<PmCmdLargePltTra> pmCmdLargePltTraList = pmCmdLargePltTraRepository.selectByPonoSlabList(ponoSlabList, organizationId);
        Map<String, PmCmdLargePltTra> pmCmdLargePltTraMap = new HashMap<>(pmCmdLargePltList.size());
        if (CollectionUtils.isNotEmpty(pmCmdLargePltTraList)) {
            pmCmdLargePltTraMap = pmCmdLargePltTraList.stream()
                    .collect(Collectors.toMap(PmCmdLargePltTra::getPonoSlabNo, Function.identity()));
        }

        // 2)	命令参数表（PM_CMD_CONT）
        List<PmCmdCont> pmCmdContList = pmCmdContRepository.selectByPonoSlabList(ponoSlabList, organizationId);
        Map<String, PmCmdCont> pmCmdContMap = new HashMap<>(pmCmdContList.size());
        if (CollectionUtils.isNotEmpty(pmCmdContList)) {
            pmCmdContMap = pmCmdContList.stream()
                    .collect(Collectors.toMap(PmCmdCont::getPonoSlabNo, Function.identity(), (k, v) -> k));
        }
        List<PmCmdContTra> pmCmdContTraList = pmCmdContTraRepository.selectByPonoSlabList(ponoSlabList, organizationId);
        Map<String, PmCmdContTra> pmCmdContTraMap = new HashMap<>(pmCmdLargePltList.size());
        if (CollectionUtils.isNotEmpty(pmCmdContTraList)) {
            pmCmdContTraMap = pmCmdContTraList.stream()
                    .collect(Collectors.toMap(PmCmdContTra::getPonoSlabNo, Function.identity()));
        }
        // 3)	命令小板表（PM_CMD_SMALL_PLT）
        List<PmCmdSmallPlt> pmCmdSmallPltList = pmCmdSmallPltRepository.selectByPonoSlabList(ponoSlabList, organizationId);
        Map<String, PmCmdSmallPlt> pmCmdSmallPltMap = new HashMap<>(pmCmdSmallPltList.size());
        if (CollectionUtils.isNotEmpty(pmCmdSmallPltList)) {
            pmCmdSmallPltMap = pmCmdSmallPltList.stream()
                    .collect(Collectors.toMap(PmCmdSmallPlt::getPonoSlabNo, Function.identity(), (k, v) -> k));
        }
        List<PmCmdSmallPltTra> pmCmdSmallPltTraList = pmCmdSmallPltTraRepository.selectByPonoSlabList(ponoSlabList, organizationId);
        Map<String, PmCmdSmallPltTra> pmCmdSmallPltTraMap = new HashMap<>(pmCmdLargePltList.size());
        if (CollectionUtils.isNotEmpty(pmCmdSmallPltTraList)) {
            pmCmdSmallPltTraMap = pmCmdSmallPltTraList.stream()
                    .collect(Collectors.toMap(PmCmdSmallPltTra::getPonoSlabNo, Function.identity()));
        }

        // 使用钢板号PLATE NO 匹配命令小板表(PM_CMD_SMALL_PLT)钢板号 PLATE NO、命令板坏号 PONO SLAB NO，两个字段都等于钢板号，如果没有返回结果，则下面三张表新增记录;
        List<PmCmdLargePlt> existCmdLargePltList = pmCmdLargePltRepository.selectByPonoAndPlateNo(matNoList, matNoList, organizationId);
        Map<String, List<PmCmdLargePlt>> existCmdLargePltMap = new HashMap<>(existCmdLargePltList.size());
        if (CollectionUtils.isNotEmpty(existCmdLargePltList)) {
            existCmdLargePltMap = pmCmdLargePltList.stream()
                    .collect(Collectors.groupingBy(PmCmdLargePlt::getPonoSlabNo));
        }

        List<PmCmdCont> existCmdContList = pmCmdContRepository.selectByPonoAndPlateNo(matNoList, matNoList, organizationId);
        Map<String,  List<PmCmdCont>> existCmdContMap = new HashMap<>(existCmdContList.size());
        if (CollectionUtils.isNotEmpty(existCmdContList)) {
            existCmdContMap = existCmdContList.stream()
                    .collect(Collectors.groupingBy(PmCmdCont::getPonoSlabNo));
        }

        List<PmCmdSmallPlt> existCmdSmallPltList = pmCmdSmallPltRepository.selectByPonoAndPlateNo(matNoList, matNoList, organizationId);
        Map<String,   List<PmCmdSmallPlt>> existCmdSmallPltMap = new HashMap<>(existCmdSmallPltList.size());
        if (CollectionUtils.isNotEmpty(existCmdSmallPltList)) {
            existCmdSmallPltMap = existCmdSmallPltList.stream().collect(Collectors.groupingBy(PmCmdSmallPlt::getPonoSlabNo));
        }

        List<PmCmdLargePlt> insertLargePltList = new ArrayList<>();
        List<PmCmdCont> insertCmdContList = new ArrayList<>();
        List<PmCmdSmallPlt> insertSmallPltList = new ArrayList<>();
        List<PmCmdLargePlt> updateLargePltList = new ArrayList<>();
        List<PmCmdCont> updateCmdContList = new ArrayList<>();
        List<PmCmdSmallPlt> updateSmallPltList = new ArrayList<>();

        // 查询材料所属库区产线
        List<WmStockInfoVO> wmStockInfoVOList =  pmMmPlateMapper.queryStockLineByMatNo(matNoList, organizationId);
        Map<String, WmStockInfoVO> wmStockInfoVOMap = new HashMap<>(wmStockInfoVOList.size());
        if (CollectionUtils.isNotEmpty(wmStockInfoVOList)) {
           wmStockInfoVOMap = wmStockInfoVOList.stream().collect(Collectors.toMap(WmStockInfoVO::getMatNo, Function.identity(), (k,v)->k));
        }

        List<PmPdRecDTO> pmPdRecs = new ArrayList<>();
        for (MmPlateVO mmPlateVO : mmPlateVOList) {
            PmPdRecDTO res = new PmPdRecDTO();
            res.setOrderNo(dto.getOrderNo());
            res.setMscLineNo(mmPlateVO.getMscLineNo());
            res.setMatNo(mmPlateVO.getMatNo());
            res.setWt(mmPlateVO.getMatActWgt());
            res.setQty(BigDecimal.ONE);
            res.setOrderNo(dto.getOrderNo());
            pmPdRecs.add(res);

            // (如果新旧合同喷刻印信息一致，则不生成
            if ("N".equals(orgOrderResultMap.get(mmPlateVO.getOrgOrderNo()))) {
                continue;
            }
            if (StringUtils.isEmpty(mmPlateVO.getMscLineNo()) || mmPlateVO.getMscLineNo().length() < 4) {
                throw new CommonException("pm.cd_plate_028", mmPlateVO.getMatNo(), mmPlateVO.getMscLineNo());
            }
            // 1)	喷刻印工序
            //如果产线号的第三四位为10，当前预定工序代码取值为“1P0”
            String platePreProc1 = Strings.EMPTY;
            if ("10".equals(mmPlateVO.getMscLineNo().substring(2, 4))) {
                platePreProc1 = "1P0";
            }else if ("20".equals(mmPlateVO.getMscLineNo().substring(2, 4))) {
                platePreProc1 = "2P0";
            } else if ("30".equals(mmPlateVO.getMscLineNo().substring(2, 4))) {
                platePreProc1 = "5P0";
            }

            // 2)	形合工序
            //如果产线号的第三四位为10，当前预定工序代码取值为“1Z1”
            String platePreProc2 = Strings.EMPTY;
            if ("10".equals(mmPlateVO.getMscLineNo().substring(2, 4))) {
                platePreProc2 = "1Z1";
            }else if ("20".equals(mmPlateVO.getMscLineNo().substring(2, 4))) {
                platePreProc2 = "2Z1";
            } else if ("30".equals(mmPlateVO.getMscLineNo().substring(2, 4))) {
                platePreProc2 = "5Z1";
            }


            // 命令大板表
            // 更新
            if (existCmdLargePltMap.containsKey(mmPlateVO.getMatNo())) {
                List<PmCmdLargePlt> largePltList = existCmdLargePltMap.get(mmPlateVO.getMatNo());
                if (largePltList.size() > 1) {
                    throw new CommonException("pm.cd_plate_027", mmPlateVO.getMatNo());
                }
                PmCmdLargePlt pmCmdLargePlt = largePltList.get(0);
                pmCmdLargePlt.setPonoSlabNo(mmPlateVO.getMatNo());
                pmCmdLargePlt.setPlateNo(mmPlateVO.getMatNo());
                pmCmdLargePlt.setOrderNumInPlate(1L);
                pmCmdLargePlt.setTotSmallPlateNum(1L);
                pmCmdLargePlt.setPlatePreProc1(platePreProc1);
                pmCmdLargePlt.setPlatePreProc2(platePreProc2);
                updateLargePltList.add(pmCmdLargePlt);

            } else {
                // 新增
                if (!pmCmdLargePltMap.containsKey(mmPlateVO.getPonoSlab()) && !pmCmdLargePltTraMap.containsKey(mmPlateVO.getPonoSlab())) {
                    throw new CommonException("pm.cd_plate_029","命令大板表", mmPlateVO.getPonoSlab());
                }
                PmCmdLargePlt pmCmdLargePlt = new PmCmdLargePlt();
                if (pmCmdLargePltMap.containsKey(mmPlateVO.getPonoSlab())) {
                    BeanUtils.copy(pmCmdLargePltMap.get(mmPlateVO.getPonoSlab()), pmCmdLargePlt);
                } else {
                    BeanUtils.copy(pmCmdLargePltTraMap.get(mmPlateVO.getPonoSlab()), pmCmdLargePlt);
                }
                pmCmdLargePlt.setPonoSlabNo(mmPlateVO.getMatNo());
                pmCmdLargePlt.setPlateNo(mmPlateVO.getMatNo());
                pmCmdLargePlt.setOrderNumInPlate(1L);
                pmCmdLargePlt.setTotSmallPlateNum(1L);
                pmCmdLargePlt.setPlatePreProc1(platePreProc1);
                pmCmdLargePlt.setPlatePreProc2(platePreProc2);
                pmCmdLargePlt.setPmCmdLargePltId(null);
                insertLargePltList.add(pmCmdLargePlt);

            }

            // 命令参数表
            if (existCmdContMap.containsKey(mmPlateVO.getMatNo())) {
                List<PmCmdCont> cmdContList = existCmdContMap.get(mmPlateVO.getMatNo());
                if (cmdContList.size() > 1) {
                    throw new CommonException("pm.cd_plate_027", mmPlateVO.getMatNo());
                }
                PmCmdCont pmCmdCont = cmdContList.get(0);
                pmCmdCont.setPonoSlabNo(mmPlateVO.getMatNo());
                pmCmdCont.setOrderSeqNo(1L);
                pmCmdCont.setSmallPlateNum(1L);
                pmCmdCont.setOrderNo(qdToPoOrder.getOrderNo());
                pmCmdCont.setProdShotMark(qdToPoOrder.getProdShotMark());
                pmCmdCont.setOrderThick(qdToPoOrder.getOrderThick());
                pmCmdCont.setOrderWidth(qdToPoOrder.getOrderWidth());
                pmCmdCont.setOrderLen(qdToPoOrder.getOrderLen());
                pmCmdCont.setOrderLenMax(qdToPoOrder.getOrderMaxLen());
                pmCmdCont.setOrderLenMin(qdToPoOrder.getOrderMinLen());
                pmCmdCont.setSmallPlateThick(qdToPoOrder.getOrderThick());
                pmCmdCont.setSmallPlateWidth(qdToPoOrder.getOrderWidth());
                pmCmdCont.setSmallPlateLen(qdToPoOrder.getOrderLen());
                pmCmdCont.setPlateNo(mmPlateVO.getMatNo());
                updateCmdContList.add(pmCmdCont);
            } else {
                // 新增
                if (!pmCmdContMap.containsKey(mmPlateVO.getPonoSlab()) && !pmCmdContTraMap.containsKey(mmPlateVO.getPonoSlab())) {
                    throw new CommonException("pm.cd_plate_029","命令参数表", mmPlateVO.getPonoSlab());
                }
                PmCmdCont pmCmdCont = new PmCmdCont();
                if (pmCmdContMap.containsKey(mmPlateVO.getPonoSlab())) {
                    BeanUtils.copy(pmCmdContMap.get(mmPlateVO.getPonoSlab()), pmCmdCont);
                } else {
                    BeanUtils.copy(pmCmdContTraMap.get(mmPlateVO.getPonoSlab()), pmCmdCont);
                }
                pmCmdCont.setPonoSlabNo(mmPlateVO.getMatNo());
                pmCmdCont.setOrderSeqNo(1L);
                pmCmdCont.setSmallPlateNum(1L);
                pmCmdCont.setOrderNo(qdToPoOrder.getOrderNo());
                pmCmdCont.setProdShotMark(qdToPoOrder.getProdShotMark());
                pmCmdCont.setOrderThick(qdToPoOrder.getOrderThick());
                pmCmdCont.setOrderWidth(qdToPoOrder.getOrderWidth());
                pmCmdCont.setOrderLen(qdToPoOrder.getOrderLen());
                pmCmdCont.setOrderLenMax(qdToPoOrder.getOrderMaxLen());
                pmCmdCont.setOrderLenMin(qdToPoOrder.getOrderMinLen());
                pmCmdCont.setSmallPlateThick(qdToPoOrder.getOrderThick());
                pmCmdCont.setSmallPlateWidth(qdToPoOrder.getOrderWidth());
                pmCmdCont.setSmallPlateLen(qdToPoOrder.getOrderLen());
                pmCmdCont.setPmCmdContId(null);
                pmCmdCont.setPlateNo(mmPlateVO.getMatNo());
                insertCmdContList.add(pmCmdCont);

            }

            // 命令小板表
            if (existCmdSmallPltMap.containsKey(mmPlateVO.getMatNo())) {
                List<PmCmdSmallPlt> cmdSmallPltList = existCmdSmallPltMap.get(mmPlateVO.getMatNo());
                if (cmdSmallPltList.size() > 1) {
                    throw new CommonException("pm.cd_plate_027", mmPlateVO.getMatNo());
                }
                PmCmdSmallPlt pmCmdSmallPlt = cmdSmallPltList.get(0);
                pmCmdSmallPlt.setPonoSlabNo(mmPlateVO.getMatNo());
                pmCmdSmallPlt.setSmallPlateDivNo("100");
                pmCmdSmallPlt.setOrderSeqNo(1L);
                pmCmdSmallPlt.setOrderNo(qdToPoOrder.getOrderNo());
                pmCmdSmallPlt.setOrderThick(qdToPoOrder.getOrderThick());
                pmCmdSmallPlt.setOrderWidth(qdToPoOrder.getOrderWidth());
                pmCmdSmallPlt.setOrderLen(qdToPoOrder.getOrderLen());
                pmCmdSmallPlt.setOrderLenMax(qdToPoOrder.getOrderMaxLen());
                pmCmdSmallPlt.setOrderLenMin(qdToPoOrder.getOrderMinLen());
                pmCmdSmallPlt.setSmallPlateThick(qdToPoOrder.getOrderThick());
                pmCmdSmallPlt.setSmallPlateWidth(qdToPoOrder.getOrderWidth());
                pmCmdSmallPlt.setSmallPlateLen(qdToPoOrder.getOrderLen());
                pmCmdSmallPlt.setPlateNo(mmPlateVO.getMatNo());
                updateSmallPltList.add(pmCmdSmallPlt);
            } else {
                // 新增
                if (!pmCmdSmallPltMap.containsKey(mmPlateVO.getPonoSlab()) && !pmCmdSmallPltTraMap.containsKey(mmPlateVO.getPonoSlab())) {
                    throw new CommonException("pm.cd_plate_029","命令小板表", mmPlateVO.getPonoSlab());
                }
                PmCmdSmallPlt pmCmdSmallPlt = new PmCmdSmallPlt();
                if (pmCmdSmallPltMap.containsKey(mmPlateVO.getPonoSlab())) {
                    BeanUtils.copy(pmCmdSmallPltMap.get(mmPlateVO.getPonoSlab()), pmCmdSmallPlt);
                } else {
                    BeanUtils.copy(pmCmdSmallPltTraMap.get(mmPlateVO.getPonoSlab()), pmCmdSmallPlt);
                }
                pmCmdSmallPlt.setPonoSlabNo(mmPlateVO.getMatNo());
                pmCmdSmallPlt.setSmallPlateDivNo("100");
                pmCmdSmallPlt.setOrderSeqNo(1L);
                pmCmdSmallPlt.setOrderNo(qdToPoOrder.getOrderNo());
                pmCmdSmallPlt.setOrderThick(qdToPoOrder.getOrderThick());
                pmCmdSmallPlt.setOrderWidth(qdToPoOrder.getOrderWidth());
                pmCmdSmallPlt.setOrderLen(qdToPoOrder.getOrderLen());
                pmCmdSmallPlt.setOrderLenMax(qdToPoOrder.getOrderMaxLen());
                pmCmdSmallPlt.setOrderLenMin(qdToPoOrder.getOrderMinLen());
                pmCmdSmallPlt.setSmallPlateThick(qdToPoOrder.getOrderThick());
                pmCmdSmallPlt.setSmallPlateWidth(qdToPoOrder.getOrderWidth());
                pmCmdSmallPlt.setSmallPlateLen(qdToPoOrder.getOrderLen());
                pmCmdSmallPlt.setPmCmdSmallPltId(null);
                pmCmdSmallPlt.setPlateNo(mmPlateVO.getMatNo());
                insertSmallPltList.add(pmCmdSmallPlt);
            }
        }


        // 	内部接口：更新钢板主数据表
        //更新钢板主数据表(状态为有2计划未切)MM_PLATE与钢板主数据表(状态代码为已产出)MM_PLATE：依据原始的数据库表数据进行取值
//        for (MmPlateVO mmPlateVO : mmPlateVOList) {
//            mmPlateVO.setOrderNo(orderNo);
//        }
//
//        for (MmPlateVO mmPlateVO : mmPlateVOList) {
//            mmPlateVO.setOrderNo(orderNo);
//        }


        List<PmCdContLog> insertList = new ArrayList<>();
        //新增转用充当履历
        for (MmPlateVO mmPlateVO : mmPlateVOList) {
            PmCdContLog pmCdContLog = new PmCdContLog();
            pmCdContLog.setOrderNo(orderNo);
            pmCdContLog.setMatStatus(mmPlateVO.getMatStatus());
            pmCdContLog.setWholeBacklog(mmPlateVO.getWholeBacklog());
            pmCdContLog.setMscLineNo(mmPlateVO.getMscLineNo());
            pmCdContLog.setMsc(mmPlateVO.getMsc());
            pmCdContLog.setPsc(mmPlateVO.getPsc());
            pmCdContLog.setApn(mmPlateVO.getApn());
            pmCdContLog.setSgStd(mmPlateVO.getSgStd());
            pmCdContLog.setComplexDecideCode(mmPlateVO.getComplexDecideCode());
            pmCdContLog.setWt(mmPlateVO.getMatActWgt());
            pmCdContLog.setNum(1L);
            pmCdContLog.setOldOrderNo(mmPlateVO.getOrgOrderNo());
            pmCdContLog.setSgSign(mmPlateVO.getSgSign());
            pmCdContLog.setEventId("PM_MATERIAL_HANGING_CONTRACT");
            pmCdContLog.setSystemId("PMOA");
            pmCdContLog.setFuncId("pmoahp02_putup");
            pmCdContLog.setMatKind("HP");
            pmCdContLog.setMatNo(mmPlateVO.getMatNo());
            pmCdContLog.setOriginMatNo(null);
            pmCdContLog.setTenantId(organizationId);
            insertList.add(pmCdContLog);
        }

        //否则若材料与合同的热处理方式代码不一致且合同的热处理方式代码为0则提示信息返回：PM.CD_PLATE_019。

        // 新增或者更新
        pmCmdLargePltRepository.batchInsertSelective(insertLargePltList);
        pmCmdLargePltRepository.batchUpdateByPrimaryKey(updateLargePltList);
        pmCmdContRepository.batchInsertSelective(insertCmdContList);
        pmCmdContRepository.batchUpdateByPrimaryKey(updateCmdContList);
        pmCmdSmallPltRepository.batchInsertSelective(insertSmallPltList);
        pmCmdSmallPltRepository.batchUpdateByPrimaryKey(updateSmallPltList);
        pmCdContLogRepository.batchInsert(insertList);

        // 6、 调用组板履历函数，抛组板履历事件
        pmPdRecService.createEvent(organizationId, pmPdRecs, PdEventType.HP46, Constants.SYSTEM_PD_CODE, Constants.PdProgram.STEEL_HANG_PROGRAM);

        // 调用轧钢材料状态变更-抛合同，抛账
        for (MmPlateVO mmPlateVO : mmPlateVOList) {
            MatStatusModifyVO matStatusModifyVO = new MatStatusModifyVO();
            String eventCode = Strings.EMPTY;

            // 抛账
            List<ErpInterfaceVO> erpInterfaceVOList = new ArrayList<>();
            // 负账
            ErpInterfaceVO erpInterfaceVO = new ErpInterfaceVO();
            if (wmStockInfoVOMap.containsKey(mmPlateVO.getMatNo())) {
                if ("1".equals(wmStockInfoVOMap.get(mmPlateVO.getMatNo()).getStockLine()) || "2".equals(wmStockInfoVOMap.get(mmPlateVO.getMatNo()).getStockLine())) {
                    erpInterfaceVO.setStoreFactory("HP1");
                } else if ("5".equals(wmStockInfoVOMap.get(mmPlateVO.getMatNo()).getStockLine()) || "9".equals(wmStockInfoVOMap.get(mmPlateVO.getMatNo()).getStockLine())) {
                    erpInterfaceVO.setStoreFactory("HP2");
                } else {
                    erpInterfaceVO.setStoreFactory("CW1");
                }
                erpInterfaceVO.setStockNo(wmStockInfoVOMap.get(mmPlateVO.getMatNo()).getStockCode());
            } else {
                throw new CommonException("pm.cd_plate_031", mmPlateVO.getMatNo());
            }
            erpInterfaceVO.setEventRelatedId(mmPlateVO.getMatNo());
            erpInterfaceVO.setRecCreator(Constants.ErpCreator.PMCDHP);
            erpInterfaceVO.setEventId("27");
            erpInterfaceVO.setEventName("生产挂合同");
            erpInterfaceVO.setMatNo(mmPlateVO.getMatNo());
            erpInterfaceVO.setAcFlag("1");
            erpInterfaceVO.setMatWt(mmPlateVO.getMatActWgt() != null ? mmPlateVO.getMatActWgt().negate().longValue() : null);
            erpInterfaceVO.setBackCode10("2");
            erpInterfaceVO.setSgSign(mmPlateVO.getSgSign());
            erpInterfaceVO.setMsc(qdToPoOrder.getMsc());
            erpInterfaceVO.setApn(qdToPoOrder.getApn());
            erpInterfaceVO.setOrderTypeCode(qdToPoOrder.getOrderTypeCode());
            erpInterfaceVO.setAccpAuthCode(" ");
            erpInterfaceVO.setBackCode2(" ");
            erpInterfaceVO.setMatId(mmPlateVO.getPlateId());
            erpInterfaceVOList.add(erpInterfaceVO);

            // 正账
            ErpInterfaceVO interfaceVO = new ErpInterfaceVO();
            BeanUtils.copy(erpInterfaceVO, interfaceVO);
            interfaceVO.setMatWt(mmPlateVO.getMatActWgt() != null ? mmPlateVO.getMatActWgt().longValue() : null);
            erpInterfaceVOList.add(interfaceVO);


            // 抛合同信息
            List<EventFeignVO> eventFeignVOS = new ArrayList<>();
            EventFeignVO eventFeignVO = new EventFeignVO();
            eventFeignVO.setEventCode(Constants.EventCode.PM_MATERIAL_HANGING_CONTRACT);
            Map<String, String> eventMap = new HashMap<>(16);
            eventMap.put("contractNum", orderNo.substring(0, 8));
            eventMap.put("orderNo", orderNo);
            eventMap.put("matNo", mmPlateVO.getMatNo());
            eventMap.put("ppFlag", ("BP".equals(mmPlateVO.getProdCd()) || "MP".equals(mmPlateVO.getProdCd())) ? "6" : "7");
            eventMap.put("ordFlag", "1");
            eventMap.put("procCd", "9AA");
            eventMap.put("wholeBacklogCode", "9A");
            Map<String, String> informationMap = new HashMap<>(16);
            // (如果新旧合同喷刻印信息不一致)事件英文：PM_HANG_ORDER_PROCESS_MATERIAL
            if ("Y".equals(orgOrderResultMap.get(mmPlateVO.getOrgOrderNo()))) {
                eventCode = Constants.EventCode.PM_HANG_ORDER_PROCESS_MATERIAL;
                informationMap.put("ponoSlab", mmPlateVO.getPonoSlab());
                eventMap.put("matStatus", "23");
            } else {
                // (如果新旧合同喷刻印信息一致)事件英文：MM_END_PROCESS_MATERIAL_HANG_CONTRACT
                eventCode = Constants.EventCode.MM_END_PROCESS_MATERIAL_HANG_CONTRACT;
                eventMap.put("matStatus", "33");
            }
            eventFeignVO.setEventContext(JSONObject.toJSONString(Collections.singletonList(eventMap)));
            eventFeignVOS.add(eventFeignVO);
            informationMap.put("contractCode", orderNo);
            informationMap.put("procCd", "9AA");
            informationMap.put("wholeBacklogCode", "9A");
            matStatusModifyVO.setMatNo(mmPlateVO.getMatNo());
            matStatusModifyVO.setPpFlag(mmPlateVO.getProdCd());
            matStatusModifyVO.setCtEventList(eventFeignVOS);
            matStatusModifyVO.setErpInterfaceList(erpInterfaceVOList);
            matStatusModifyVO.setMatInformationString(JSONObject.toJSONString(informationMap));

            log.info("<=====钢板挂合同调用轧钢入参: eventCode = {}, matStatusModifyVO = {}", eventCode, JSONObject.toJSON(matStatusModifyVO));
             mmEventClient.matStatusModify(organizationId, eventCode, matStatusModifyVO);
        }

        return information;
    }

    @Override
    public List<MmSlab> surplusSlabList(MmSlab mmSlab, Long organizationId) {
        mmSlab.setOrderThickMinValue(mmSlab.getOrderThickValue());
        mmSlab.setOrderThickMaxValue(mmSlab.getOrderThickValue());
        if (mmSlab.getThickTolMaxValue() != null) {
            mmSlab.setOrderThickMaxValue((mmSlab.getOrderThickMaxValue() == null ? BigDecimal.ZERO : mmSlab.getOrderThickMaxValue()).add(mmSlab.getThickTolMaxValue()));
        }
        if (mmSlab.getThickTolMinValue() != null) {
            mmSlab.setOrderThickMinValue((mmSlab.getOrderThickMinValue() == null ? BigDecimal.ZERO : mmSlab.getOrderThickMinValue()).add(mmSlab.getThickTolMinValue()));
        }
        if (mmSlab.getWidthTolMaxValue() != null) {
            mmSlab.setWidthMaxValue((mmSlab.getWidthMaxValue() == null ? BigDecimal.ZERO : mmSlab.getWidthMaxValue()).add(mmSlab.getWidthTolMaxValue()));
        }
        if (mmSlab.getWidthTolMinValue() != null) {
            mmSlab.setWidthMinValue((mmSlab.getWidthMinValue() == null ? BigDecimal.ZERO : mmSlab.getWidthMinValue()).add(mmSlab.getWidthTolMinValue()));
        }
        if (mmSlab.getLenTolMaxValue() != null) {
            mmSlab.setOrderLenMaxValue((mmSlab.getOrderLenMaxValue() == null ? BigDecimal.ZERO : mmSlab.getOrderLenMaxValue()).add(mmSlab.getLenTolMaxValue()));
        }
        if (mmSlab.getLenTolMinValue() != null) {
            mmSlab.setOrderLenMinValue((mmSlab.getOrderLenMinValue() == null ? BigDecimal.ZERO : mmSlab.getOrderLenMinValue()).add(mmSlab.getLenTolMinValue()));
        }
        return mmSlabRepository.surplusSlabList(mmSlab);
    }

    @Override
    public List<QdToPoOrderVO1> surplusSlabOrderList(QdToPoOrderVO1 qdToPoOrder, Long organizationId) {
        List<QdToPoOrderVO1> resultList = pmQdToPoOrderRepository.surplusSlabOrderList(qdToPoOrder);

        if (CollectionUtils.isEmpty(resultList)) {
            return resultList;
        }

        // 可组板数>0（可组板数：根据合同号，whole_backlog_code=‘13’获取（包括生产合同管理）CT_DET的STOCK_NUM – PLAN_NUM）
        List<String> orderNoList = resultList.stream().map(QdToPoOrderVO1::getOrderNo).distinct().collect(Collectors.toList());
        List<CtDetVO> ctDetVOList = qdToPoOrderMapper.selectCtDetByOrderList(orderNoList, organizationId);
        Map<String, BigDecimal> ctDetVOMap = new HashMap<>(ctDetVOList.size());
        if (CollectionUtils.isNotEmpty(ctDetVOList)) {
            ctDetVOMap = ctDetVOList.stream().collect(Collectors.toMap(CtDetVO::getOrderNo, CtDetVO::getUserdBoardNum));
        }
        List<QdToPoOrderVO1> finalQdToPoOrderList  = new ArrayList<>(resultList.size());
        for (QdToPoOrderVO1 qdToPoOrderVO1 : resultList) {
            if (!ctDetVOMap.containsKey(qdToPoOrderVO1.getOrderNo())) {
                continue;
            }
            qdToPoOrderVO1.setUserdBoardNum(ctDetVOMap.get(qdToPoOrderVO1.getOrderNo()));
            finalQdToPoOrderList.add(qdToPoOrderVO1);
        }
        if (CollectionUtils.isEmpty(finalQdToPoOrderList)) {
            return finalQdToPoOrderList;
        }

        return buildOrderList(finalQdToPoOrderList, organizationId);
    }

    private List<QdToPoOrderVO1> buildOrderList(List<QdToPoOrderVO1> qdToPoOrderList, Long tenantId) {

        // 获取合同号
        List<String> orderNoList = qdToPoOrderList.stream().map(QdToPoOrderVO1::getOrderNo).distinct().collect(Collectors.toList());

        // 查询探伤级别和探伤代码
        List<QdToLineupResultUTVO> qdToLineupResultUTVOList =  pmMmPlateMapper.selectUtCode(orderNoList, tenantId);
        Map<String, List<QdToLineupResultUTVO>> qdToLineupResultUTVOMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(qdToLineupResultUTVOList)) {
            qdToLineupResultUTVOMap = qdToLineupResultUTVOList.stream().collect(Collectors.groupingBy(QdToLineupResultUTVO::getOrderNo));
        }

        // 合同状态
        List<LovValueDTO> orderStatusList = lovAdapter.queryLovValue(Constants.LovCode.ORDER_STATUS, tenantId);
        Map<String, String> orderStatusMap = new HashMap<>(orderStatusList.size());
        if (CollectionUtils.isNotEmpty(orderStatusList)) {
            orderStatusMap = orderStatusList.stream().collect(Collectors.toMap(LovValueDTO::getValue, LovValueDTO::getMeaning));
        }

        // 是否分段管理
        List<LovValueDTO> whetherFlagList = lovAdapter.queryLovValue(Constants.LovCode.XISC_WHETHER_FLAG_01, tenantId);
        Map<String, String> whetherFlagListMap = new HashMap<>(orderStatusList.size());
        if (CollectionUtils.isNotEmpty(whetherFlagList)) {
            whetherFlagListMap = whetherFlagList.stream().collect(Collectors.toMap(LovValueDTO::getValue, LovValueDTO::getMeaning));
        }

        // 赋值
        for (QdToPoOrderVO1 qdToPoOrderVO1 : qdToPoOrderList) {
            qdToPoOrderVO1.setOrderStatus(qdToPoOrderVO1.getOrderStatus() + "-" + orderStatusMap.getOrDefault(qdToPoOrderVO1.getOrderStatus(), qdToPoOrderVO1.getOrderStatus()));
            qdToPoOrderVO1.setSectionManage(whetherFlagListMap.getOrDefault(qdToPoOrderVO1.getSectionManage(), qdToPoOrderVO1.getSectionManage()));
            if (qdToLineupResultUTVOMap.containsKey(qdToPoOrderVO1.getOrderNo())) {
                // 按照“-"拼接
                qdToPoOrderVO1.setUstStand(qdToLineupResultUTVOMap.get(qdToPoOrderVO1.getOrderNo()).stream()
                        .filter(item->StringUtils.isNotEmpty(item.getUtCode()) && StringUtils.isNotEmpty(item.getUtStdname()))
                        .sorted(Comparator.comparing(QdToLineupResultUTVO::getUtCode))
                        .map(QdToLineupResultUTVO::getUtStdname).collect(Collectors.joining("-")));
                qdToPoOrderVO1.setRsltLevel(qdToLineupResultUTVOMap.get(qdToPoOrderVO1.getOrderNo()).stream()
                        .filter(item->StringUtils.isNotEmpty(item.getUtCode()) && StringUtils.isNotEmpty(item.getUtGrade()))
                        .sorted(Comparator.comparing(QdToLineupResultUTVO::getUtCode))
                        .map(QdToLineupResultUTVO::getUtGrade).collect(Collectors.joining("-")));

            }
        }

        return qdToPoOrderList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @GlobalTransactional(rollbackFor = Exception.class)
    public void surplusSlabHangOrder(PmMaterialInfoHangOrderDTO dto, Long organizationId) {
        //材料信息
        List<MmSlab> mmSlabList = dto.getMmSlabList();
        //检查目标合同转用条件：根据合同号order_no查询合同跟踪主表CT_MAIN合同状态并校验存在，其值必须大于等于40且小于57，否则中断，提示信息为：PM.CD.SLAB.001。
        String orderStatus = pmMmPlateMapper.selectOrderStatusByOrderNo(dto.getOrderNo());
        if (Objects.nonNull(orderStatus)) {
            long status = Long.parseLong(orderStatus);
            if (status < 40 || status >= 57) {
                throw new CommonException("pm.cd_slab_001", dto.getOrderNo(), status);
            }
        }
        //根据合同号order_no查询合同的MES合同主档QD_TO_PO_ORDER信息
        QdToPoOrderVO1 query = new QdToPoOrderVO1();
        query.setOrderNo(dto.getOrderNo());
        query.setTenantId(organizationId);
        //合同信息
        QdToPoOrderVO1 qdToPoOrder = pmQdToPoOrderRepository.selectList(query).get(0);
        if (Objects.isNull(qdToPoOrder)) {
            throw new CommonException("pm.cd_slab_013",dto.getOrderNo());
        }
        //根据板坯号SLAB_NO查询材料的板坯主数据主表MM_SLAB信息并校验存在。
        List<String> slabNoList = mmSlabList.stream().map(MmSlab::getSlabNo).collect(Collectors.toList());
        List<MmSlab> slabList = pmMmPlateMapper.selectMmSlabList(slabNoList);
        //通过“材料号”mat_no关联“材料垛位信息表”WM_MAT_PILE
        List<WmMatPileVO1> wmMatPileList = pmMmPlateMapper.selectWmMatPileList(slabNoList);
        for (WmMatPileVO1 item : wmMatPileList) {
            //材料垛位信息表WM_MAT_PILE的库区代码stock_code为空提示信息为：PM.CD.SLAB.006。
            if (Objects.isNull(item.getStockCode())) {
                throw new CommonException("pm.cd_slab_006");
            }
        }
        PmCdRuleSet pmCdRuleSetQuery = new PmCdRuleSet();
        pmCdRuleSetQuery.setRuleSetType("SM");
        pmCdRuleSetQuery.setValidFlag(1L);
        pmCdRuleSetQuery.setTenantId(organizationId);
        List<PmCdRuleSet> pmCdRuleSetList = pmCdRuleSetRepository.selectList(pmCdRuleSetQuery);
        List<PmPdRecDTO> pmPdRecs = new ArrayList<>();
        for (MmSlab mmSlab : slabList) {
            long status = Long.parseLong(mmSlab.getSlabStatus());
            //校验材料的材料状态SLAB_STATUS等于39，否则报错，提示信息为：PM.CD.SLAB.002。
            if (status != 39) {
                throw new CommonException("pm.cd_slab_002", mmSlab.getSlabNo(), status);
            }
            //校验材料的综合判定代码complex_decide_code等于1，否则报错，提示信息为：PM.CD.SLAB.003。
//            if (!"1".equals(mmSlab.getComplexDecideCode())) {
//                throw new CommonException("pm.cd_slab_003", mmSlab.getSlabNo());
//            }
            //校验材料的合同号order_no等于空，否则报错，提示信息为：PM.CD.SLAB.004
            if (StringUtils.isNotEmpty(mmSlab.getOrderNo()) && StringUtils.isNotBlank(mmSlab.getOrderNo())) {
                throw new CommonException("pm.cd_slab_004", mmSlab.getSlabNo(), mmSlab.getOrderNo());
            }
            //转用规则检查
            //转用规则检查：根据规则集类型RULE_SET_TYPE等于HP查询充当规则集PM_CD_RULE_SET并按照规则号RULE_NO排序，并根据查询结果进行相应规则检查。
            List<Long> ruleNoList = pmCdRuleSetList.stream().map(PmCdRuleSet::getRuleNo).collect(Collectors.toList());
            for (Long ruleNo : ruleNoList) {
                for (MmSlab slab : mmSlabList) {
                    checkFieldNotEmpty(qdToPoOrder);
                    //需要校验rule_no为2，3，4，13，14，15 对应的规则
                    if (ruleNo == 2) {
                        //若订货厚度加上厚度公差下限大于材料实际厚度则函数中断，提示信息为：PM.CD.RULE.002。
                        if (qdToPoOrder.getOrderThick().add(qdToPoOrder.getThickTolMin()).compareTo(slab.getSlabActThk()) > 0) {
                            throw new CommonException("pm.cd_rule_002", qdToPoOrder.getOrderThick().add(qdToPoOrder.getThickTolMin()), slab.getSlabActThk());
                        }
                        //若订货厚度加厚度公差上限小于材料实际厚度则函数中断，提示信息为：PM.CD.RULE.002。
                        if (qdToPoOrder.getOrderThick().add(qdToPoOrder.getThickTolMax()).compareTo(slab.getSlabActThk()) < 0) {
                            throw new CommonException("pm.cd_rule_002", qdToPoOrder.getOrderThick().add(qdToPoOrder.getThickTolMax()), slab.getSlabActThk());
                        }
                    }
                    if (ruleNo == 3) {
                        //若宽度上限加宽度公差上限小于材料实际宽度则函数中断，提示信息为：PM.CD.RULE.003。
                        if (qdToPoOrder.getWidthMax().add(qdToPoOrder.getWidthTolMax()).compareTo(slab.getSlabActWid()) < 0) {
                            throw new CommonException("pm.cd_rule_003", qdToPoOrder.getThickTolMax().add(qdToPoOrder.getWidthMin()), slab.getSlabActWid());
                        }
                        //若宽度下限加宽度公差下限大于材料实际宽度则函数中断，提示信息为：PM.CD.RULE.004。
                        if (qdToPoOrder.getWidthMin().add(qdToPoOrder.getWidthTolMin()).compareTo(slab.getSlabActWid()) > 0) {
                            throw new CommonException("pm.cd_rule_004", qdToPoOrder.getWidthTolMin().add(qdToPoOrder.getWidthMin()), slab.getSlabActWid());
                        }
                    }
                    if (ruleNo == 4) {
                        //若订货最小长度加长度公差下限大于材料实际长度，则函数中断，提示信息为：PM.CD.RULE.005。
                        if (qdToPoOrder.getOrderMinLen().add(qdToPoOrder.getLenTolMin()).compareTo(slab.getSlabActLen()) > 0) {
                            throw new CommonException("pm.cd_rule_005", qdToPoOrder.getOrderMinLen().add(qdToPoOrder.getLenTolMin()), slab.getSlabActLen());
                        }
                        //若订货最大长度加长度公差上限小于材料实际长度，则函数中断，提示信息为：PM.CD.RULE.006。
                        if (qdToPoOrder.getOrderMaxLen().add(qdToPoOrder.getLenTolMax()).compareTo(slab.getSlabActLen()) < 0) {
                            throw new CommonException("pm.cd_rule_006", qdToPoOrder.getOrderMaxLen().add(qdToPoOrder.getLenTolMax()), slab.getSlabActLen());
                        }
                    }

                    if (ruleNo == 13) {
                        //规则号rule_no为13：校验材料与合同的冶金规范码MSC一致，否则函数中断，提示信息为：PM.CD.RULE.016。
                        if (!Objects.equals(slab.getMsc(), qdToPoOrder.getMsc())) {
                            throw new CommonException("pm.cd_rule_016", slab.getMsc(), qdToPoOrder.getMsc());
                        }
                    }
                    if (ruleNo == 14) {
                        //规则号rule_no为14：校验材料与合同的产品规范码PSC一致，否则函数中断，提示信息为：PM.CD.RULE.017。
                        if (!Objects.equals(slab.getPsc(), qdToPoOrder.getPsc())) {
                            throw new CommonException("pm.cd_rule_017", slab.getPsc(), qdToPoOrder.getPsc());
                        }
                    }
                    if (ruleNo == 15) {
                        //规则号rule_no为15：校验材料与合同的产品最终用途码APN一致，否则函数中断，提示信息为：PM.CD.RULE.018。
                        if (!Objects.equals(slab.getApn(), qdToPoOrder.getApn())) {
                            throw new CommonException("pm.cd_rule_018", slab.getApn(), qdToPoOrder.getApn());
                        }
                    }
                }
            }

            PmPdRecDTO res = new PmPdRecDTO();
            res.setOrderNo(dto.getOrderNo());
            res.setMscLineNo(mmSlab.getMscLineNo());
            res.setMatNo(mmSlab.getSlabNo());
            res.setWt(mmSlab.getSlabActWgt());
            res.setQty(BigDecimal.ONE);
            res.setOrderNo(dto.getOrderNo());
            pmPdRecs.add(res);
        }
        //2、差欠重量判断
        //根据合同号（ORDER_NO）去合同跟踪主表CT_MAIN获取到得差欠重量，进行如下比对：
        //1)校验板坯主数据主表MM_SLAB的炼钢板坯重量SLAB_ACT_WGT不能大于差欠重量ORD_REM_WGT，否则报错，提示信息为：PM.CD_SLAB_005。
//        BigDecimal ordRemWgt = pmMmPlateMapper.selectOrdRemWgt(dto.getOrderNo());
//        for (MmSlab mmSlab : mmSlabList) {
//            if (mmSlab.getSlabActWgt().compareTo(ordRemWgt) > 0) {
//                throw new CommonException("pm.cd_slab_005", ordRemWgt, mmSlab.getSlabActWgt());
//            }
//        }
        // 校验可组板数
        // 校验可组板数
        List<CtDetVO> ctDetVOList = pmCompositeSlabMapper.selectCtDetByOrderList(Arrays.asList(dto.getOrderNo()), organizationId);
        if (CollectionUtils.isEmpty(ctDetVOList)) {
            throw new CommonException("pm.cd_plate_034", dto.getOrderNo());
        }
        if (ctDetVOList.get(0).getUserdBoardNum().compareTo(BigDecimal.ONE) < 0) {
            throw new CommonException("pm.cd_plate_033", ctDetVOList.get(0).getUserdBoardNum());
        }

        // 查询材料所属库区产线
        List<WmStockInfoVO> wmStockInfoVOList =  pmMmPlateMapper.queryStockLineByMatNo(slabNoList, organizationId);
        Map<String, WmStockInfoVO> wmStockInfoVOMap = new HashMap<>(wmStockInfoVOList.size());
        if (CollectionUtils.isNotEmpty(wmStockInfoVOList)) {
            wmStockInfoVOMap = wmStockInfoVOList.stream().collect(Collectors.toMap(WmStockInfoVO::getMatNo, Function.identity(), (k,v)->k));
        }
        // 更新板坯主数据主表MM_SLAB：依据原始的数据库表数据进行取值
        /*for (MmSlab slab : mmSlabList) {
            slab.setOrderNo(qdToPoOrder.getOrderNo());
        }
        mmSlabRepository.batchUpdateByPrimaryKey(mmSlabList);*/

        // 调用接口
        Map<String, String>  slabNoMap = new HashMap<>(mmSlabList.size());
        List<QdMatchParamDTO> qdMatchParamDTOList = new ArrayList<>();
        List<QdSurplusLowMagnificationDTO> chemicalMatchDTOList = new ArrayList<>();
        for (MmSlab mmSlab : mmSlabList) {
            slabNoMap.put(mmSlab.getPono(), mmSlab.getSlabNo());

            QdMatchParamDTO qdMatchParamDTO = new QdMatchParamDTO();
            qdMatchParamDTO.setOrderNo(dto.getOrderNo());
            qdMatchParamDTO.setPono(mmSlab.getPono());
            qdMatchParamDTOList.add(qdMatchParamDTO);

            QdSurplusLowMagnificationDTO phyFurnaceChemicalMatchDTO = new QdSurplusLowMagnificationDTO();
            phyFurnaceChemicalMatchDTO.setOrderNo(dto.getOrderNo());
            phyFurnaceChemicalMatchDTO.setPono(mmSlab.getPono());
            chemicalMatchDTOList.add(phyFurnaceChemicalMatchDTO);
        }
        List<QdMatchParamDTO> qdMatchParamResultList = qdOrderClient.phyFurnaceChemicalMatchApi(organizationId, qdMatchParamDTOList);
        if (CollectionUtils.isNotEmpty(qdMatchParamResultList)) {
            for (QdMatchParamDTO qdMatchParamDTO : qdMatchParamResultList) {
                if (!"合格".equals(qdMatchParamDTO.getResult())) {
                    throw new CommonException("pm.cd_plate_036", slabNoMap.get(qdMatchParamDTO.getPono()));
                }
            }
        }
        List<QdSurplusLowMagnificationDTO> chemicalMatchResultList = qdOrderClient.surplusLowMagnificationMatchApi(organizationId,
                chemicalMatchDTOList);
        if (CollectionUtils.isNotEmpty(chemicalMatchResultList)) {
            for (QdSurplusLowMagnificationDTO lowMagnificationDTO : chemicalMatchResultList) {
                if (!"合格".equals(lowMagnificationDTO.getResult())) {
                    throw new CommonException("pm.cd_plate_038", slabNoMap.get(lowMagnificationDTO.getPono()));
                }
            }
        }

        // 4、 调用组板履历函数，抛组板履历事件
//        pmPdRecService.createEvent(organizationId, pmPdRecs, PdEventType.HP46, Constants.SYSTEM_PD_CODE, Constants.PdProgram.ORDER_HANG_PROGRAM);

        //新增转用充当履历PM_CD_CONT_LOG：依据更新后的板坯主数据主表MM_SLAB数据进行取值
        //新增转用充当履历
        List<PmCdContLog> insertList = new ArrayList<>();
        for (MmSlab mmSlab : mmSlabList) {
            PmCdContLog pmCdContLog = new PmCdContLog();
            pmCdContLog.setOrderNo(qdToPoOrder.getOrderNo());
            pmCdContLog.setMatStatus(mmSlab.getSlabStatus());
            pmCdContLog.setWholeBacklog(mmSlab.getWholeBacklog());
            pmCdContLog.setMscLineNo(mmSlab.getMscLineNo());
            pmCdContLog.setMsc(mmSlab.getMsc());
            pmCdContLog.setPsc(mmSlab.getPsc());
            pmCdContLog.setApn(mmSlab.getApn());
            pmCdContLog.setSgStd(mmSlab.getSgStd());
            pmCdContLog.setComplexDecideCode(mmSlab.getComplexDecideCode());
            pmCdContLog.setWt(mmSlab.getSlabActWgt());
            pmCdContLog.setNum(1L);
            pmCdContLog.setOldOrderNo(mmSlab.getOldOrderNo());
            pmCdContLog.setSgSign(mmSlab.getSgSign());
            pmCdContLog.setEventId("PM_MATERIAL_HANGING_CONTRACT");
            pmCdContLog.setSystemId("PMOA");
            pmCdContLog.setFuncId("pmoasm01_putup");
            pmCdContLog.setMatKind("SM");
            pmCdContLog.setMatNo(mmSlab.getSlabNo());
            pmCdContLog.setOriginMatNo(mmSlab.getOriginSlabNo());
            pmCdContLog.setTenantId(organizationId);
            insertList.add(pmCdContLog);
        }
        pmCdContLogRepository.batchInsert(insertList);

        // 调用轧钢材料状态变更-抛合同，抛账
        Long userId = DetailsHelper.getUserDetails().getUserId();
        Date now = new Date();
        for (MmSlab mmSlab : mmSlabList) {
            MatStatusModifyVO matStatusModifyVO = new MatStatusModifyVO();
            // 内部接口调用：合同跟踪
            List<EventFeignVO> eventFeignVOS = new ArrayList<>();
            EventFeignVO eventFeignVO = new EventFeignVO();
            eventFeignVO.setEventCode(Constants.EventCode.PM_MATERIAL_HANGING_CONTRACT);
            Map<String, String> eventMap = new HashMap<>(16);
            eventMap.put("contractNum", dto.getOrderNo().substring(0, 8));
            eventMap.put("orderNo", dto.getOrderNo());
            eventMap.put("matNo", mmSlab.getSlabNo());
            eventMap.put("ppFlag", "5");
            eventMap.put("matStatus", "33");
            eventMap.put("ordFlag", "1");
            eventMap.put("procCd", "9AA");
            eventMap.put("wholeBacklogCode", "9A");
            eventFeignVO.setEventContext(JSONObject.toJSONString(Collections.singletonList(eventMap)));
            eventFeignVOS.add(eventFeignVO);

            //  厚板成本抛帐
            List<ErpInterfaceVO> erpInterfaceVOList = new ArrayList<>();
            // 负账
            ErpInterfaceVO erpInterfaceVO = new ErpInterfaceVO();
            if (wmStockInfoVOMap.containsKey(mmSlab.getSlabNo())) {
                if ("1".equals(wmStockInfoVOMap.get(mmSlab.getSlabNo()).getStockLine()) || "2".equals(wmStockInfoVOMap.get(mmSlab.getSlabNo()).getStockLine())) {
                    erpInterfaceVO.setStoreFactory("HP1");
                } else if ("5".equals(wmStockInfoVOMap.get(mmSlab.getSlabNo()).getStockLine()) || "9".equals(wmStockInfoVOMap.get(mmSlab.getSlabNo()).getStockLine())) {
                    erpInterfaceVO.setStoreFactory("HP2");
                } else {
                    erpInterfaceVO.setStoreFactory("CW1");
                }
                erpInterfaceVO.setStockNo(wmStockInfoVOMap.get(mmSlab.getSlabNo()).getStockCode());
            } else {
                throw new CommonException("pm.cd_plate_031", mmSlab.getSlabNo());
            }
            erpInterfaceVO.setEventRelatedId(mmSlab.getHeatNo());
            erpInterfaceVO.setRecCreator(Constants.ErpCreator.PMCDSM);
            erpInterfaceVO.setEventId("27");
            erpInterfaceVO.setEventName("生产挂合同");
            erpInterfaceVO.setMatNo(mmSlab.getSlabNo());
            erpInterfaceVO.setAcFlag("1");
            erpInterfaceVO.setMatWt(mmSlab.getSlabActWgt() != null ? mmSlab.getSlabActWgt().negate().longValue() : null);
            erpInterfaceVO.setBackCode10("1");
            erpInterfaceVO.setSgSign(mmSlab.getSgSign());
            erpInterfaceVO.setMsc(qdToPoOrder.getMsc());
            erpInterfaceVO.setApn(qdToPoOrder.getApn());
            erpInterfaceVO.setOrderTypeCode(qdToPoOrder.getOrderTypeCode());
            erpInterfaceVO.setAccpAuthCode(".");
            erpInterfaceVO.setBackCode2(".");
            erpInterfaceVO.setMatId(mmSlab.getSlabId());
            erpInterfaceVOList.add(erpInterfaceVO);

            // 正账
            ErpInterfaceVO interfaceVO = new ErpInterfaceVO();
            BeanUtils.copy(erpInterfaceVO, interfaceVO);
            interfaceVO.setMatWt(mmSlab.getSlabActWgt() != null ? mmSlab.getSlabActWgt().longValue() : null);
            erpInterfaceVOList.add(interfaceVO);

            matStatusModifyVO.setMatNo(mmSlab.getSlabNo());
            matStatusModifyVO.setPpFlag(Constants.PpFlag.SM);
            Map<String, Object> informationMap = new HashMap<>(16);
            informationMap.put("contractCode", dto.getOrderNo());
            informationMap.put("procCd", "9AA");
            informationMap.put("wholeBacklogCode", "9A");
            informationMap.put("complexDecideCode", "1");
            informationMap.put("complexDecideMaker", userId.toString());
            informationMap.put("complexDecideTime", now);
            matStatusModifyVO.setMatInformationString(JSONObject.toJSONString(informationMap));
            matStatusModifyVO.setCtEventList(eventFeignVOS);
            matStatusModifyVO.setErpInterfaceList(erpInterfaceVOList);

            log.info("<=====板坯挂合同调用轧钢入参: matStatusModifyVO = {}", JSONObject.toJSON(matStatusModifyVO));
            mmEventClient.matStatusModify(organizationId, Constants.EventCode.MM_END_PROCESS_MATERIAL_HANG_CONTRACT, matStatusModifyVO);
        }
    }

    private void checkFieldNotEmpty(QdToPoOrderVO1 qdToPoOrder) {
        if (qdToPoOrder.getOrderThick() == null) {
            throw new CommonException("pm.cd_rule_021", "订货厚度");
        }
        if (qdToPoOrder.getThickTolMin() == null) {
            throw new CommonException("pm.cd_rule_021", "厚度公差下限");
        }
        if (qdToPoOrder.getThickTolMax() == null) {
            throw new CommonException("pm.cd_rule_021", "厚度公差上限");
        }
        if (qdToPoOrder.getWidthMax() == null) {
            throw new CommonException("pm.cd_rule_021", "宽度上限");
        }
        if (qdToPoOrder.getWidthTolMax() == null) {
            throw new CommonException("pm.cd_rule_021", "宽度公差上限");
        }
        if (qdToPoOrder.getWidthMin() == null) {
            throw new CommonException("pm.cd_rule_021", "宽度下限");
        }
        if (qdToPoOrder.getWidthTolMin() == null) {
            throw new CommonException("pm.cd_rule_021", "宽度公差下限");
        }
        if (qdToPoOrder.getOrderMinLen() == null) {
            throw new CommonException("pm.cd_rule_021", "订货最小长度");
        }
        if (qdToPoOrder.getLenTolMin() == null) {
            throw new CommonException("pm.cd_rule_021", "长度公差下限");
        }
        if (qdToPoOrder.getOrderMaxLen() == null) {
            throw new CommonException("pm.cd_rule_021", "订货最大长度");
        }
        if (qdToPoOrder.getLenTolMax() == null) {
            throw new CommonException("pm.cd_rule_021", "长度公差上限");
        }
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @Transactional(rollbackFor = Exception.class)
    public void surplusSteelPlateBreakOrder(PmMaterialInfoHangOrderDTO dto, Long organizationId) {
        List<MmPlateVO> mmPlateVOList = dto.getMmPlateList();

        List<String> matNoList = new ArrayList<>(mmPlateVOList.size());
        List<Long> plateIdList = new ArrayList<>(mmPlateVOList.size());
        List<String> ponoSlabNoList = new ArrayList<>(mmPlateVOList.size());
        List<String> orderNoList = new ArrayList<>(mmPlateVOList.size());
        List<PmPdRecDTO> pmPdRecs = new ArrayList<>();
        for (MmPlateVO mmPlateVO : mmPlateVOList) {
            //根据材料号mat_no查询钢板主数据表(状态代码为已产出)MM_PLATE并校验存在,校验材料的材料状态mat_status等于33，否则不通过，提示信息为：PM.CD.PLATE.020。
            if (!"33".equals(mmPlateVO.getMatStatus())) {
                throw new CommonException("pm.cd_plate_020", mmPlateVO.getMatNo(), mmPlateVO.getMatStatus());
            }
            //如果合同号order_no为空，则函数中断，提示信息为：PM.CD.PLATE.021。
            if (Objects.isNull(mmPlateVO.getOrderNo())) {
                throw new CommonException("pm.cd_plate_021", mmPlateVO.getMatNo());
            }
            PmPdRecDTO res = new PmPdRecDTO();
            res.setOrderNo(mmPlateVO.getOrderNo());
            res.setMscLineNo(mmPlateVO.getMscLineNo());
            res.setMatNo(mmPlateVO.getSlabNo());
            res.setWt(mmPlateVO.getMatActWgt() != null ? mmPlateVO.getMatActWgt().negate() : null);
            res.setQty(BigDecimal.ONE.negate());
            res.setOrderNo(mmPlateVO.getOrderNo());
            pmPdRecs.add(res);

            matNoList.add(mmPlateVO.getMatNo());
            plateIdList.add(mmPlateVO.getPlateId());
            ponoSlabNoList.add(mmPlateVO.getPonoSlab());
            orderNoList.add(mmPlateVO.getOrderNo());
        }

        List<CtMainVO> orderStatusList = pmMmPlateMapper.selectOrderStatus(orderNoList, organizationId);
        Map<String, String> orderStatusMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(orderStatusList)) {
            orderStatusMap = orderStatusList.stream().collect(Collectors.toMap(CtMainVO::getOrderNo, CtMainVO::getOrderStatus, (k,v)->k));
        }
        List<QdToPoOrderVO> giveSampleFlagList = pmMmPlateMapper.selectGiveSampleFlag(orderNoList, organizationId);
        Map<String, String> giveSampleFlagMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(giveSampleFlagList)) {
            giveSampleFlagMap = giveSampleFlagList.stream().collect(Collectors.toMap(QdToPoOrderVO::getOrderNo, item-> Optional.ofNullable(item.getGiveSampleFlag()).orElse(Strings.EMPTY), (k, v)->k));
        }

        for (String orderNo : orderNoList) {
            if (!orderStatusMap.containsKey(orderNo)) {
                throw new CommonException("pm.cd_plate_030", orderNo, "合同跟踪主表CT_MAIN");
            }
            if (!giveSampleFlagMap.containsKey(orderNo)) {
                throw new CommonException("pm.cd_plate_030", orderNo, "MES合同主档QD_TO_PO_ORDER");
            }
            // 根据合同号order_no查询合同跟踪主表CT_MAIN的合同状态order_status并校验存在。若合同状态小于40或者大于等于67则函数中断，提示信息为：PM.CD.PLATE.022
            if (orderStatusMap.get(orderNo).compareTo("40") < 0 ||orderStatusMap.get(orderNo).compareTo("67") >= 0) {
                throw new CommonException("pm.cd_plate_022", orderNo, orderStatusMap.get(orderNo));
            }
            // 根据合同号order_no查询MES合同主档QD_TO_PO_ORDER的奉送样标记give_sample_flag，校验其值为空或者0，否则函数中断，提示信息为：PM.CD.PLATE.023
            if (StringUtils.isNotEmpty(giveSampleFlagMap.get(orderNo)) && !"0".equals(giveSampleFlagMap.get(orderNo))) {
                throw new CommonException("pm.cd_plate_023",orderNo, giveSampleFlagMap.get(orderNo));
            }


        }
        // 内部接口：更新钢板主数据表(状态为有计划未切)MM_PLATE与钢板主数据表(状态代码为已产出)MM_PLATE：依据原始的数据库表数据进行取值
        /*for (MmPlate mmPlate : mmPlateList) {
            mmPlate.setOrderNo(null);
        }
        mmPlateRepository.batchUpdateByPrimaryKey(mmPlateList);*/

        //根据合同号order_no查询合同的MES合同主档QD_TO_PO_ORDER信息
        List<QdToPoOrderVO1> qdOrderList = qdToPoOrderMapper.selectQdOrderList(orderNoList, organizationId);
        if (CollectionUtils.isEmpty(qdOrderList)) {
            throw new CommonException("pm.cd_plate_009",Strings.join(orderNoList, ',' ));
        }
        Map<String, QdToPoOrderVO1> qdOrderMap = qdOrderList.stream().collect(Collectors.toMap(QdToPoOrderVO1::getOrderNo, Function.identity(), (k, v) -> k));


        // 4、 调用组板履历函数，抛组板履历事件
        pmPdRecService.createEvent(organizationId, pmPdRecs, PdEventType.HP46, Constants.SYSTEM_PD_CODE, Constants.PdProgram.STEEL_BREAK_PROGRAM);

        CustomUserDetails userDetails = DetailsHelper.getUserDetails();
        Long userId = userDetails.getUserId();
        MtUserInfo mtUserInfo = userClient.userInfoGet(organizationId, userId);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //新增转用充当履历PM_CD_CONT_LOG：依据更新后的数据进行取值
        //查询合同号对应的合同性质代码
        List<QdToPoOrderVO1> orderTypeCodeList = pmMmPlateMapper.selectOrderTypeCodeList(orderNoList);
        Map<String, String> map = orderTypeCodeList.stream().collect(Collectors.toMap(QdToPoOrderVO1::getOrderNo, QdToPoOrderVO1::getOrderTypeCode));
        List<PmCdContLog> insertList = new ArrayList<>();

        // 查询材料所属库区产线
        List<WmStockInfoVO> wmStockInfoVOList =  pmMmPlateMapper.queryStockLineByMatNo(matNoList, organizationId);
        Map<String, WmStockInfoVO> wmStockInfoVOMap = new HashMap<>(wmStockInfoVOList.size());
        if (CollectionUtils.isNotEmpty(wmStockInfoVOList)) {
            wmStockInfoVOMap = wmStockInfoVOList.stream().collect(Collectors.toMap(WmStockInfoVO::getMatNo, Function.identity(), (k,v)->k));
        }

        // 内部接口调用：会检证书删除
        List<InspectionCertificateDTO> inspectionCertificateDTOList = qeApiClient.inspectionCertificateApi(organizationId, plateIdList);
        if (CollectionUtils.isNotEmpty(inspectionCertificateDTOList)) {
            List<InspectionCertificateDTO> failList = inspectionCertificateDTOList.stream().filter(item -> "失败".equals(item.getResult())).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(failList)) {
                throw new CommonException("pm.cd_plate_032", failList.get(0).getMatNo(), failList.get(0).getErrorMsg());
            }
        }

        // 删除四大命令表
        Date now = new Date();
        String username = DetailsHelper.getUserDetails().getUsername();
        List<PmCmdLargePlt> pmCmdLargePltList = pmCmdLargePltRepository.selectByPonoSlabList(ponoSlabNoList, organizationId);
        List<PmCmdLargePltTra> pmCmdLargePltTraList = pmCmdLargePltTraRepository.buildPmCmdLargePltTraList(pmCmdLargePltList, "D", now, username);
        List<PmCmdSmallPlt> cmdSmallPltList = pmCmdSmallPltRepository.selectByPonoSlabList(ponoSlabNoList, organizationId);
        List<PmCmdSmallPltTra> cmdSmallPltTraList = pmCmdSmallPltTraRepository.buildPmCmdSmallPltTraList(cmdSmallPltList, "D", now, username);
        List<PmCmdCont> pmCmdContList = pmCmdContRepository.selectByPonoSlabList(ponoSlabNoList, organizationId);
        List<PmCmdContTra> pmCmdContTraList = pmCmdContTraRepository.buildPmCmdContTraList(pmCmdContList, "D", now, username);
        List<PmCmdSlab> pmCmdSlabList = pmCmdSlabRepository.selectByPonoSlabList(ponoSlabNoList, organizationId);
        List<PmCmdSlabTra> pmCmdSlabTraList = pmCmdSlabTraRepository.buildPmCmdSlabTraList(pmCmdSlabList, "D", now, username);
        pmCmdLargePltRepository.batchDeleteByPrimaryKey(pmCmdLargePltList);
        pmCmdSmallPltRepository.batchDeleteByPrimaryKey(cmdSmallPltList);
        pmCmdContRepository.batchDeleteByPrimaryKey(pmCmdContList);
        pmCmdSlabRepository.batchDeleteByPrimaryKey(pmCmdSlabList);
        pmCmdLargePltTraRepository.batchInsertSelective(pmCmdLargePltTraList);
        pmCmdSmallPltTraRepository.batchInsertSelective(cmdSmallPltTraList);
        pmCmdContTraRepository.batchInsertSelective(pmCmdContTraList);
        pmCmdSlabTraRepository.batchInsertSelective(pmCmdSlabTraList);


        for (MmPlateVO mmPlateVO : mmPlateVOList) {
            PmCdContLog pmCdContLog = new PmCdContLog();
            pmCdContLog.setOrderNo(mmPlateVO.getOrderNo());
            pmCdContLog.setMatStatus(mmPlateVO.getMatStatus());
            pmCdContLog.setWholeBacklog(mmPlateVO.getWholeBacklog());
            pmCdContLog.setMsc(mmPlateVO.getMsc());
            pmCdContLog.setMscLineNo(mmPlateVO.getMscLineNo());
            pmCdContLog.setPsc(mmPlateVO.getPsc());
            pmCdContLog.setApn(mmPlateVO.getApn());
            pmCdContLog.setSgStd(mmPlateVO.getSgStd());
            pmCdContLog.setComplexDecideCode(mmPlateVO.getComplexDecideCode());
            pmCdContLog.setWt(mmPlateVO.getMatActWgt());
            pmCdContLog.setNum(1L);
            pmCdContLog.setOldOrderNo(mmPlateVO.getOrgOrderNo());
            pmCdContLog.setSgSign(mmPlateVO.getSgSign());
            pmCdContLog.setEventId("QE_MATERIAL_BREACH_OF_CONTRACT");
            pmCdContLog.setSystemId("PMOA");
            pmCdContLog.setFuncId("pmoahp00_putdn");
            pmCdContLog.setMatKind("HP");
            pmCdContLog.setMatNo(mmPlateVO.getMatNo());
            pmCdContLog.setTenantId(organizationId);
            insertList.add(pmCdContLog);
            if ("1".equals(mmPlateVO.getRecSts()) && "X".equals(map.get(mmPlateVO.getOrderNo()).substring(0, 1))) {
                //外部接口：现货脱合同发送电文给ERP
                SpotOutContractSendDTO sendDTO = new SpotOutContractSendDTO();
                sendDTO.setMatNo(mmPlateVO.getMatNo());
                sendDTO.setAffirmNotion(dto.getRemainCauseCode());
                sendDTO.setAffirmld(mtUserInfo.getLoginName());
                sendDTO.setAffirmName(mtUserInfo.getRealName());
                sendDTO.setAffirmTime(sdf.format(new Date()));
                RequestPayloadDTO payloadDTO = new RequestPayloadDTO();
                payloadDTO.setPayload(JSON.toJSONString(sendDTO));
                payloadDTO.setHeaderParamMap(XbusRequestHeaderUtil.getHeaders("BCOMA4"));
                interfaceInvokeSdk.invoke("XISC", "ERP_INTERFACE", "XBUS_INTERFACE", payloadDTO);
            }
        }
        pmCdContLogRepository.batchInsert(insertList);

        // 调用轧钢材料状态变更-抛合同，抛账
        for (MmPlateVO mmPlateVO : mmPlateVOList) {
            MatStatusModifyVO matStatusModifyVO = new MatStatusModifyVO();
            // 内部接口调用：合同跟踪
            List<EventFeignVO> eventFeignVOS = new ArrayList<>();
            EventFeignVO eventFeignVO = new EventFeignVO();
            eventFeignVO.setEventCode(Constants.EventCode.QE_MATERIAL_BREACH_OF_CONTRACT);
            Map<String, String> eventMap = new HashMap<>(16);
            eventMap.put("matNo", mmPlateVO.getMatNo());
            eventMap.put("ppFlag",  ("BP".equals(mmPlateVO.getProdCd()) || "MP".equals(mmPlateVO.getProdCd())) ? "6" : "7");
            eventMap.put("matStatus", "39");
            eventMap.put("stNo", mmPlateVO.getStNo());
            eventMap.put("sgSign", mmPlateVO.getSgSign());
            eventMap.put("remainCauseCode", dto.getRemainCauseCode());
            eventMap.put("ordFlag", "2");
            eventFeignVO.setEventContext(JSONObject.toJSONString(Collections.singletonList(eventMap)));
            eventFeignVOS.add(eventFeignVO);

            // 外部接口调用：厚板成本抛帐
            List<ErpInterfaceVO> erpInterfaceVOList = new ArrayList<>();
            // 负账
            ErpInterfaceVO erpInterfaceVO = new ErpInterfaceVO();
            if (wmStockInfoVOMap.containsKey(mmPlateVO.getMatNo())) {
                if ("1".equals(wmStockInfoVOMap.get(mmPlateVO.getMatNo()).getStockLine()) || "2".equals(wmStockInfoVOMap.get(mmPlateVO.getMatNo()).getStockLine())) {
                    erpInterfaceVO.setStoreFactory("HP1");
                } else if ("5".equals(wmStockInfoVOMap.get(mmPlateVO.getMatNo()).getStockLine()) || "9".equals(wmStockInfoVOMap.get(mmPlateVO.getMatNo()).getStockLine())) {
                    erpInterfaceVO.setStoreFactory("HP2");
                } else {
                    erpInterfaceVO.setStoreFactory("CW1");
                }
                erpInterfaceVO.setStockNo(wmStockInfoVOMap.get(mmPlateVO.getMatNo()).getStockCode());
            } else {
                throw new CommonException("pm.cd_plate_031", mmPlateVO.getMatNo());
            }
            erpInterfaceVO.setEventRelatedId(mmPlateVO.getMatNo());
            erpInterfaceVO.setRecCreator(Constants.ErpCreator.PMCDHP);
            erpInterfaceVO.setEventId("27");
            erpInterfaceVO.setEventName("生产脱合同");
            erpInterfaceVO.setMatNo(mmPlateVO.getMatNo());
            erpInterfaceVO.setAcFlag("1");
            erpInterfaceVO.setMatWt(mmPlateVO.getMatActWgt() != null ? mmPlateVO.getMatActWgt().negate().longValue() : null);
            erpInterfaceVO.setBackCode10("2");
            erpInterfaceVO.setSgSign(mmPlateVO.getSgSign());
            if (!qdOrderMap.containsKey(mmPlateVO.getOrderNo())) {
                throw new CommonException("pm.cd_plate_009",mmPlateVO.getOrderNo());
            }
            erpInterfaceVO.setMsc(qdOrderMap.get(mmPlateVO.getOrderNo()).getMsc());
            erpInterfaceVO.setApn(qdOrderMap.get(mmPlateVO.getOrderNo()).getApn());
            erpInterfaceVO.setOrderTypeCode(qdOrderMap.get(mmPlateVO.getOrderNo()).getOrderTypeCode());
            erpInterfaceVO.setAccpAuthCode(".");
            erpInterfaceVO.setBackCode2(".");
            erpInterfaceVO.setMatId(mmPlateVO.getPlateId());
            erpInterfaceVOList.add(erpInterfaceVO);

            // 正账
            ErpInterfaceVO interfaceVO = new ErpInterfaceVO();
            BeanUtils.copy(erpInterfaceVO, interfaceVO);
            interfaceVO.setMatWt(mmPlateVO.getMatActWgt() != null ? mmPlateVO.getMatActWgt().longValue() : null);
            erpInterfaceVOList.add(interfaceVO);

            matStatusModifyVO.setMatNo(mmPlateVO.getMatNo());
            matStatusModifyVO.setPpFlag(mmPlateVO.getProdCd());
            Map<String, String> informationMap = new HashMap<>(16);
            informationMap.put("remainCauseCode", dto.getRemainCauseCode());
            informationMap.put("remainDecideMaker", DetailsHelper.getUserDetails().getUserId().toString());
            informationMap.put("remainDecideTime", DateFormatUtils.format(new Date(), BaseConstants.Pattern.DATETIME));
            matStatusModifyVO.setMatInformationString(JSONObject.toJSONString(informationMap));
            matStatusModifyVO.setCtEventList(eventFeignVOS);
            matStatusModifyVO.setErpInterfaceList(erpInterfaceVOList);

           mmEventClient.matStatusModify(organizationId, Constants.EventCode.MM_END_PROCESS_MATERIAL_DISENGAGE_CONTRACT, matStatusModifyVO);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @GlobalTransactional(rollbackFor = Exception.class)
    public void surplusSlabBreakOrder(PmMaterialInfoHangOrderDTO dto, Long organizationId) {
        List<MmSlab> mmSlabList = dto.getMmSlabList();
        List<String> orderNoList = mmSlabList.stream().map(MmSlab::getOrderNo).collect(Collectors.toList());
        for (MmSlab mmSlab : mmSlabList) {
            //校验材料的材料状态SLAB_STATUS等于33，否则不通过，提示信息为：PM.CD.SLAB.007。
            if (!"33".equals(mmSlab.getSlabStatus())) {
                throw new CommonException("pm.cd_slab_007", mmSlab.getSlabNo(), mmSlab.getSlabStatus());
            }
            //校验材料的合同号不等于空，否则不通过，提示信息为：PM.CD.SLAB.008。
            if (StringUtils.isEmpty(mmSlab.getOrderNo())) {
                throw new CommonException("pm.cd_slab_008", mmSlab.getSlabNo());
            }
        }
        List<String> slabNoList = mmSlabList.stream().map(MmSlab::getSlabNo).collect(Collectors.toList());
        List<WmMatPileVO1> pileList = pmMmPlateMapper.selectWmMatPileList(slabNoList);
        for (WmMatPileVO1 wmMatPile : pileList) {
            //库区代码stock_code为空,提示信息为：PM.CD.SLAB.009。
            if (StringUtils.isEmpty(wmMatPile.getStockCode())) {
                throw new CommonException("pm.cd_slab_009");
            }
        }
        //根据合同号order_no查询合同跟踪主表CT_MAIN的合同状态order_status并校验存在。
        List<CtMainVO> orderCtMainList = pmMmPlateMapper.selectListOrderStatusByOrderNo(orderNoList, organizationId);
        Map<String, String> orderCtMainMap = new HashMap<>(orderCtMainList.size());
        if (CollectionUtils.isNotEmpty(orderCtMainList)) {
            orderCtMainMap = orderCtMainList.stream().collect(Collectors.toMap(CtMainVO::getOrderNo, CtMainVO::getOrderStatus));
        }
        //根据合同号order_no查询MES合同主档QD_TO_PO_ORDER的奉送样标记give_sample_flag，校验其值为空或者0，否则函数中断，提示信息为：PM.CD.SLAB.011
        List<QdToPoOrderVO> giveSampleFlagList = pmMmPlateMapper.selectGiveSampleFlagListByOrderNo(orderNoList, organizationId);
        Map<String, String> giveSampleFlagMap = new HashMap<>(orderCtMainList.size());
        if (CollectionUtils.isNotEmpty(giveSampleFlagList)) {
            giveSampleFlagMap = giveSampleFlagList.stream().collect(Collectors.toMap(QdToPoOrderVO::getOrderNo, QdToPoOrderVO::getGiveSampleFlag));
        }

        List<PmPdRecDTO> pmPdRecs = new ArrayList<>();
        for (MmSlab mmSlab : mmSlabList) {
             // 若合同状态小于40或者大于等于67则函数中断，提示信息为：PPM.CD.SLAB.010
            if (orderCtMainMap.containsKey(mmSlab.getOrderNo())) {
                if (StringUtils.isNotEmpty(orderCtMainMap.get(mmSlab.getOrderNo())) && StringUtils.isNotBlank(orderCtMainMap.get(mmSlab.getOrderNo()))) {
                    if (Long.parseLong(orderCtMainMap.get(mmSlab.getOrderNo())) < 40 || Long.parseLong(orderCtMainMap.get(mmSlab.getOrderNo())) >= 67) {
                        throw new CommonException("pm.cd_slab_010", mmSlab.getOrderNo(), orderCtMainMap.get(mmSlab.getOrderNo()));
                    }
                }
            } else {
                throw new CommonException("pm.cd_slab_015", mmSlab.getOrderNo());
            }

            // ，校验其值为空或者0，否则函数中断，提示信息为：PM.CD.SLAB.011
            if (giveSampleFlagMap.containsKey(mmSlab.getOrderNo())) {
                if (StringUtils.isNotEmpty(giveSampleFlagMap.get(mmSlab.getOrderNo())) && !"0".equals(giveSampleFlagMap.get(mmSlab.getOrderNo()))) {
                    throw new CommonException("pm.cd_slab_011", mmSlab.getOrderNo(), giveSampleFlagMap.get(mmSlab.getOrderNo()));
                }
            } else {
                throw new CommonException("pm.cd_slab_014", mmSlab.getOrderNo());
            }

            PmPdRecDTO res = new PmPdRecDTO();
            res.setOrderNo(dto.getOrderNo());
            res.setMscLineNo(mmSlab.getMscLineNo());
            res.setMatNo(mmSlab.getSlabNo());
            res.setWt(mmSlab.getSlabActWgt() != null ? mmSlab.getSlabActWgt().negate() : null);
            res.setQty(mmSlab.getFixSlabNum() != null ? new BigDecimal(mmSlab.getFixSlabNum()).negate() : null);
            res.setOrderNo(mmSlab.getOrderNo());
            pmPdRecs.add(res);
        }

        // 查询材料所属库区产线
        List<WmStockInfoVO> wmStockInfoVOList =  pmMmPlateMapper.queryStockLineByMatNo(slabNoList, organizationId);
        Map<String, WmStockInfoVO> wmStockInfoVOMap = new HashMap<>(wmStockInfoVOList.size());
        if (CollectionUtils.isNotEmpty(wmStockInfoVOList)) {
            wmStockInfoVOMap = wmStockInfoVOList.stream().collect(Collectors.toMap(WmStockInfoVO::getMatNo, Function.identity(), (k,v)->k));
        }

        //根据合同号order_no查询合同的MES合同主档QD_TO_PO_ORDER信息
        List<QdToPoOrderVO1> qdOrderList = qdToPoOrderMapper.selectQdOrderList(orderNoList, organizationId);
        if (CollectionUtils.isEmpty(qdOrderList)) {
            throw new CommonException("pm.cd_plate_009",Strings.join(orderNoList, ',' ));
        }
        Map<String, QdToPoOrderVO1> qdOrderMap = qdOrderList.stream().collect(Collectors.toMap(QdToPoOrderVO1::getOrderNo, Function.identity(), (k, v) -> k));

        // 4、 调用组板履历函数，抛组板履历事件
//        pmPdRecService.createEvent(organizationId, pmPdRecs, PdEventType.HP46, Constants.SYSTEM_PD_CODE, Constants.PdProgram.ORDER_BREAK_PROGRAM);

        List<QdToPoOrderVO1> orderTypeCodeList = pmMmPlateMapper.selectOrderTypeCodeList(orderNoList);
        Map<String, String> map = orderTypeCodeList.stream().collect(Collectors.toMap(QdToPoOrderVO1::getOrderNo, QdToPoOrderVO1::getOrderTypeCode));
        CustomUserDetails userDetails = DetailsHelper.getUserDetails();
        Long userId = userDetails.getUserId();
        MtUserInfo mtUserInfo = userClient.userInfoGet(organizationId, userId);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");


        List<PmCdContLog> insertList = new ArrayList<>();
        for (MmSlab mmSlab : mmSlabList) {
            PmCdContLog pmCdContLog = new PmCdContLog();
            pmCdContLog.setEventId("QE_MATERIAL_BREACH_OF_CONTRACT");
            pmCdContLog.setSystemId("PMOA");
            pmCdContLog.setFuncId("pmoasm01_putdn");
            pmCdContLog.setMatKind("SM");
            pmCdContLog.setMatNo(mmSlab.getSlabNo());
            pmCdContLog.setOriginMatNo(mmSlab.getOriginSlabNo());
            pmCdContLog.setOrderNo(mmSlab.getOrderNo());
            pmCdContLog.setMatStatus(mmSlab.getSlabStatus());
            pmCdContLog.setWholeBacklog(mmSlab.getWholeBacklog());
            pmCdContLog.setMsc(mmSlab.getMsc());
            pmCdContLog.setMscLineNo(mmSlab.getMscLineNo());
            pmCdContLog.setPsc(mmSlab.getPsc());
            pmCdContLog.setApn(mmSlab.getApn());
            pmCdContLog.setSgStd(mmSlab.getSgStd());
            pmCdContLog.setComplexDecideCode(mmSlab.getComplexDecideCode());
            pmCdContLog.setWt(mmSlab.getSlabActWgt());
            pmCdContLog.setNum(1L);
            pmCdContLog.setOldOrderNo(mmSlab.getOldOrderNo());
            pmCdContLog.setSgSign(mmSlab.getSgSign());
            pmCdContLog.setTenantId(organizationId);
            insertList.add(pmCdContLog);
            if ("X".equals(map.get(mmSlab.getOrderNo()).substring(0, 1))) {
                //外部接口：现货脱合同发送电文给ERP
                SpotOutContractSendDTO sendDTO = new SpotOutContractSendDTO();
                sendDTO.setMatNo(mmSlab.getSlabNo());
                sendDTO.setAffirmNotion(dto.getRemainCauseCode());
                sendDTO.setAffirmld(mtUserInfo.getLoginName());
                sendDTO.setAffirmName(mtUserInfo.getRealName());
                sendDTO.setAffirmTime(sdf.format(new Date()));
                RequestPayloadDTO payloadDTO = new RequestPayloadDTO();
                payloadDTO.setPayload(JSON.toJSONString(sendDTO));
                payloadDTO.setRequestMethod("POST");
                payloadDTO.setHeaderParamMap(XbusRequestHeaderUtil.getHeaders("BCOMA4"));
                log.info("<=====调用外部接口：现货脱合同发送电文给ERP，入参为{}=====>", JSON.toJSONString(sendDTO));
                interfaceInvokeSdk.invoke("XISC", "ERP_INTERFACE", "XBUS_INTERFACE", payloadDTO);
            }
        }
        pmCdContLogRepository.batchInsert(insertList);

        for (MmSlab mmSlab : mmSlabList) {
            MatStatusModifyVO matStatusModifyVO = new MatStatusModifyVO();
            // 内部接口调用：合同跟踪
            List<EventFeignVO> eventFeignVOS = new ArrayList<>();
            EventFeignVO eventFeignVO = new EventFeignVO();
            eventFeignVO.setEventCode(Constants.EventCode.QE_MATERIAL_BREACH_OF_CONTRACT);
            Map<String, String> eventMap = new HashMap<>(16);
            eventMap.put("matNo", mmSlab.getSlabNo());
            eventMap.put("ppFlag", "5");
            eventMap.put("matStatus", "39");
            eventMap.put("stNo", mmSlab.getStNo());
            eventMap.put("sgSign", mmSlab.getSgSign());
            eventMap.put("remainCauseCode", dto.getRemainCauseCode());
            eventMap.put("ordFlag", "2");
            eventFeignVO.setEventContext(JSONObject.toJSONString(Collections.singletonList(eventMap)));
            eventFeignVOS.add(eventFeignVO);

            // 外部接口调用：厚板成本抛帐
            List<ErpInterfaceVO> erpInterfaceVOList = new ArrayList<>();
            // 负账
            ErpInterfaceVO erpInterfaceVO = new ErpInterfaceVO();
            if (wmStockInfoVOMap.containsKey(mmSlab.getSlabNo())) {
                if ("1".equals(wmStockInfoVOMap.get(mmSlab.getSlabNo()).getStockLine()) || "2".equals(wmStockInfoVOMap.get(mmSlab.getSlabNo()).getStockLine())) {
                    erpInterfaceVO.setStoreFactory("HP1");
                } else if ("5".equals(wmStockInfoVOMap.get(mmSlab.getSlabNo()).getStockLine()) || "9".equals(wmStockInfoVOMap.get(mmSlab.getSlabNo()).getStockLine())) {
                    erpInterfaceVO.setStoreFactory("HP2");
                } else {
                    erpInterfaceVO.setStoreFactory("CW1");
                }
                erpInterfaceVO.setStockNo(wmStockInfoVOMap.get(mmSlab.getSlabNo()).getStockCode());
            } else {
                throw new CommonException("pm.cd_plate_031", mmSlab.getSlabNo());
            }
            erpInterfaceVO.setEventRelatedId(mmSlab.getHeatNo());
            erpInterfaceVO.setRecCreator(Constants.ErpCreator.PMCDSM);
            erpInterfaceVO.setEventId("27");
            erpInterfaceVO.setEventName("生产脱合同");
            erpInterfaceVO.setMatNo(mmSlab.getSlabNo());
            erpInterfaceVO.setAcFlag("1");
            erpInterfaceVO.setMatWt(mmSlab.getSlabActWgt() != null ? mmSlab.getSlabActWgt().negate().longValue() : null);
            erpInterfaceVO.setBackCode10("1");
            erpInterfaceVO.setSgSign(mmSlab.getSgSign());
            if (!qdOrderMap.containsKey(mmSlab.getOrderNo())) {
                throw new CommonException("pm.cd_plate_009",mmSlab.getOrderNo());
            }
            erpInterfaceVO.setMsc(qdOrderMap.get(mmSlab.getOrderNo()).getMsc());
            erpInterfaceVO.setApn(qdOrderMap.get(mmSlab.getOrderNo()).getApn());
            erpInterfaceVO.setOrderTypeCode(qdOrderMap.get(mmSlab.getOrderNo()).getOrderTypeCode());
            erpInterfaceVO.setAccpAuthCode(".");
            erpInterfaceVO.setBackCode2(".");
            erpInterfaceVO.setMatId(mmSlab.getSlabId());
            erpInterfaceVOList.add(erpInterfaceVO);

            // 正账
            ErpInterfaceVO interfaceVO = new ErpInterfaceVO();
            BeanUtils.copy(erpInterfaceVO, interfaceVO);
            interfaceVO.setMatWt(mmSlab.getSlabActWgt() != null ? mmSlab.getSlabActWgt().longValue() : null);
            erpInterfaceVOList.add(interfaceVO);

            matStatusModifyVO.setMatNo(mmSlab.getSlabNo());
            matStatusModifyVO.setPpFlag(Constants.PpFlag.SM);
            Map<String, String> informationMap = new HashMap<>(16);
            informationMap.put("remainCauseCode", dto.getRemainCauseCode());
            informationMap.put("remainDecideMaker", DetailsHelper.getUserDetails().getUserId().toString());
            informationMap.put("remainDecideTime",  DateFormatUtils.format(new Date(), BaseConstants.Pattern.DATETIME));
            matStatusModifyVO.setMatInformationString(JSONObject.toJSONString(informationMap));
            matStatusModifyVO.setCtEventList(eventFeignVOS);
            matStatusModifyVO.setErpInterfaceList(erpInterfaceVOList);

            mmEventClient.matStatusModify(organizationId, Constants.EventCode.MM_END_PROCESS_MATERIAL_DISENGAGE_CONTRACT, matStatusModifyVO);
        }

        // 更新板坯主数据主表MM_SLAB：依据原始的数据库表数据进行取值
      //  mmSlabList.forEach(mmSlab -> mmSlab.setOrderNo(null));
        //mmSlabRepository.batchUpdateByPrimaryKeySelective(mmSlabList);
    }

    @Override
    public Map<String, Object> statisticsQuery(Date timeTo, Date timeFrom, Integer orderTypeCode, Long organizationId, int page, int size, Long createdBy) {
        //去重查询以下所有子查询的牌号（钢级）sg_sign列表并根据牌号正序排序
        List<String> sgSignList = pmMmPlateMapper.selectSgsing(timeTo, timeFrom, orderTypeCode, createdBy);
        List<PmFinishedProductsServeAsStatisticsDTO> dtoList = new ArrayList<>();
        Map<String, Object> pageData = new HashMap<>();
        if (CollectionUtils.isNotEmpty(sgSignList)) {
            //生产合同产品属性表(QD_TO_PO_ORDER)的合同性质代码order_type_code不等于YZA,关联查询组板合同总量表（PM_PD_CONT_SUM）的板坯号PLATE_NO（通过合同号order_no关联）
            List<String> slabNoList = pmMmPlateMapper.selectSlabNoList();
            //产合同产品属性表(QD_TO_PO_ORDER)的合同性质代码order_type_code不等于YZA且不以N开头的合同号order_no
            List<String> orderNoList = pmMmPlateMapper.selectOrderNoList();
            //根据记录创建时间CREATE_DATE在统计时间[起]之前、功能标识func_id等于'pmoahp02_putup'查询转用充当履历PM_CD_CONT_LOG的材料号
            List<String> matNoList = pmMmPlateMapper.selectMatNoList(timeTo);
            //生产合同产品属性表(QD_TO_PO_ORDER)的合同性质代码order_type_code不等于YZA,关联查询组板合同总量表（PM_PD_CONT_SUM）的板坯号SLAB_NO（通过合同号order_no关联）
            List<String> slabNos = pmMmPlateMapper.selectSlabNo();

            //余材钢板组板数量、材料实际重量mat_act_wt总和记为余材钢板组板重量。
            List<PmFinishedProductsServeAsStatisticsDTO> dtoList1 = pmMmPlateMapper.batchSelectHpouupAndHpouupnInfo(timeTo,
                    timeFrom, orderTypeCode, sgSignList, slabNoList);
            //查询5米余材钢板组板重量和数量
            List<PmFinishedProductsServeAsStatisticsDTO> dtoList2 = pmMmPlateMapper.batchSelectHpouup5mAndpouupn5mInfo(timeTo,
                    timeFrom, orderTypeCode, sgSignList, slabNoList);
            Map<String, PmFinishedProductsServeAsStatisticsDTO> dtoMap2 = new HashMap<>(dtoList1.size());
            if (CollectionUtils.isNotEmpty(dtoList2)) {
                dtoMap2 = dtoList2.stream().collect(Collectors.toMap(PmFinishedProductsServeAsStatisticsDTO::getSgSign, Function.identity()));
            }
            //查询3.8米余材钢板组板重量和数量
            List<PmFinishedProductsServeAsStatisticsDTO> dtoList3 = pmMmPlateMapper.batchSelectHpouup3mAndpouupn3mInfo(timeTo,
                    timeFrom, orderTypeCode, sgSignList, slabNoList);
            Map<String, PmFinishedProductsServeAsStatisticsDTO> dtoMap3 = new HashMap<>(dtoList1.size());
            if (CollectionUtils.isNotEmpty(dtoList3)) {
                dtoMap3 = dtoList3.stream().collect(Collectors.toMap(PmFinishedProductsServeAsStatisticsDTO::getSgSign, Function.identity()));
            }
            //5米余材钢板直接充当数量,5米余材钢板直接充当重量
            List<PmFinishedProductsServeAsStatisticsDTO> dtoList5 = pmMmPlateMapper.batchSelectHpoaup5mAndHpoaupn5mInfo(timeTo,
                    timeFrom, orderTypeCode, sgSignList, matNoList, orderNoList);
            Map<String, PmFinishedProductsServeAsStatisticsDTO> dtoMap5 = new HashMap<>(dtoList1.size());
            if (CollectionUtils.isNotEmpty(dtoList5)) {
                dtoMap5 = dtoList5.stream().collect(Collectors.toMap(PmFinishedProductsServeAsStatisticsDTO::getSgSign, Function.identity()));
            }
            //3.8米余材钢板直接充当数量,3.8米余材钢板直接充当重量
            List<PmFinishedProductsServeAsStatisticsDTO> dtoList6 = pmMmPlateMapper.batchSelectHpoaup3mAndHpoaupn3mInfo(timeTo,
                    timeFrom, orderTypeCode, sgSignList, matNoList, orderNoList);
            Map<String, PmFinishedProductsServeAsStatisticsDTO> dtoMap6 = new HashMap<>(dtoList1.size());
            if (CollectionUtils.isNotEmpty(dtoList6)) {
                dtoMap6 = dtoList6.stream().collect(Collectors.toMap(PmFinishedProductsServeAsStatisticsDTO::getSgSign, Function.identity()));
            }
            //余材板坯组板数量,余材板坯组板重量
            List<PmFinishedProductsServeAsStatisticsDTO> dtoList7 = pmMmPlateMapper.batchSelectSmouupAndSmouupnInfo(timeTo,
                    timeFrom, orderTypeCode, sgSignList, slabNos);
            Map<String, PmFinishedProductsServeAsStatisticsDTO> dtoMap7 = new HashMap<>(dtoList1.size());
            if (CollectionUtils.isNotEmpty(dtoList7)) {
                dtoMap7 = dtoList7.stream().collect(Collectors.toMap(PmFinishedProductsServeAsStatisticsDTO::getSgSign, Function.identity()));
            }
            //余材板坯直接充当数量,余材板坯直接充当重量
            List<PmFinishedProductsServeAsStatisticsDTO> dtoList8 = pmMmPlateMapper.batchSelectSmoaupAndSmoaupnInfo(timeTo,
                    timeFrom, orderTypeCode, sgSignList, slabNos);
            Map<String, PmFinishedProductsServeAsStatisticsDTO> dtoMap8 = new HashMap<>(dtoList1.size());
            if (CollectionUtils.isNotEmpty(dtoList8)) {
                dtoMap8 = dtoList8.stream().collect(Collectors.toMap(PmFinishedProductsServeAsStatisticsDTO::getSgSign, Function.identity()));
            }
            for (String sgSign : sgSignList) {
                PmFinishedProductsServeAsStatisticsDTO dto = new PmFinishedProductsServeAsStatisticsDTO();
                //查询5米余材钢板组板重量和数量
                if (dtoMap2.containsKey(sgSign)) {
                    PmFinishedProductsServeAsStatisticsDTO dto2 = dtoMap2.get(sgSign);
                    dto.setHpouup5m(dto2.getHpouup5m());
                    dto.setHpouupn5m(dto2.getHpouupn5m());
                } else {
                    dto.setHpouup5m(BigDecimal.ZERO);
                    dto.setHpouupn5m(0L);
                }
                //查询3.8米余材钢板组板重量和数量
                if (dtoMap3.containsKey(sgSign)) {
                    PmFinishedProductsServeAsStatisticsDTO dto3 = dtoMap3.get(sgSign);
                    dto.setHpouup3m(dto3.getHpouup3m());
                    dto.setHpouupn3m(dto3.getHpouupn3m());
                } else {
                    dto.setHpouup3m(BigDecimal.ZERO);
                    dto.setHpouupn3m(0L);
                }
                //余材钢板组板数量、材料实际重量mat_act_wt总和记为余材钢板组板重量。
                dto.setHpouup(dto.getHpouup3m().add(dto.getHpouup5m()));
                dto.setHpouupn(dto.getHpouupn3m() + dto.getHpouupn5m());

                //5米余材钢板直接充当数量,5米余材钢板直接充当重量
                if (dtoMap5.containsKey(sgSign)) {
                    PmFinishedProductsServeAsStatisticsDTO dto5 = dtoMap5.get(sgSign);
                    dto.setHpoaup5m(dto5.getHpoaup5m());
                    dto.setHpoaupn5m(dto5.getHpoaupn5m());
                } else {
                    dto.setHpoaup5m(BigDecimal.ZERO);
                    dto.setHpoaupn5m(0L);
                }
                //3.8米余材钢板直接充当数量,3.8米余材钢板直接充当重量
                if (dtoMap6.containsKey(sgSign)) {
                    PmFinishedProductsServeAsStatisticsDTO dto6 = dtoMap6.get(sgSign);
                    dto.setHpoaup3m(dto6.getHpoaup3m());
                    dto.setHpoaupn3m(dto6.getHpoaupn3m());
                } else {
                    dto.setHpoaup3m(BigDecimal.ZERO);
                    dto.setHpoaupn3m(0L);
                }
                //余材钢板直接充当数量,余材钢板直接充当重量
                dto.setHpoaup(dto.getHpoaup5m().add(dto.getHpoaup3m()));
                dto.setSghpoaupnSign(dto.getHpoaupn5m() + dto.getHpoaupn3m());
                //余材板坯组板数量,余材板坯组板重量
                if (dtoMap7.containsKey(sgSign)) {
                    PmFinishedProductsServeAsStatisticsDTO dto7 = dtoMap7.get(sgSign);
                    dto.setSmouup(dto7.getSmouup());
                    dto.setSmouupn(dto7.getSmouupn());
                } else {
                    dto.setSmouup(BigDecimal.ZERO);
                    dto.setSmouupn(0L);
                }
                //余材板坯直接充当数量,余材板坯直接充当重量
                if (dtoMap8.containsKey(sgSign)) {
                    PmFinishedProductsServeAsStatisticsDTO dto8 = dtoMap8.get(sgSign);
                    dto.setSmoaup(dto8.getSmoaup());
                    dto.setSmoaupn(dto8.getSmoaupn());
                } else {
                    dto.setSmoaup(new BigDecimal("0"));
                    dto.setSmoaupn(0L);
                }
                dto.setSgSign(sgSign);
                dtoList.add(dto);
            }
        }
        int totalPages = (int) Math.ceil((double) dtoList.size() / size);
        int startIndex = (page) * size;
        int endIndex = Math.min(startIndex + size, dtoList.size());
        List<PmFinishedProductsServeAsStatisticsDTO> currentPageData = dtoList.subList(startIndex, endIndex);
        pageData.put("totalRecords", dtoList.size());
        pageData.put("totalPages", totalPages);
        pageData.put("pageSize", size);
        pageData.put("currentPage", page);
        pageData.put("data", currentPageData);
        for (PmFinishedProductsServeAsStatisticsDTO dto : dtoList) {
            //合计重量等于余材钢板组板重量、余材钢板直接充当重量、余材板坯组板重量、余材板坯直接充当重量之和；
            dto.setHj(dto.getHpouup().add(dto.getHpoaup()).add(dto.getSmouup()).add(dto.getSmoaup()));
            //合计数量等于余材钢板组板数量、余材钢板直接充当数量、余材板坯组板数量、余材板坯直接充当数量之和；
            dto.setHjn(dto.getHpouupn() + dto.getSghpoaupnSign() + dto.getSmouupn() + dto.getSmoaupn());
            //钢板充当总重等于余材钢板组板重量、余材钢板直接充当重量之和；
            dto.setHjp(dto.getHpouup().add(dto.getHpoaup()));
            //板坯充当总重等于余材板坯组板重量、余材板坯直接充当重量之和；
            dto.setHjs(dto.getSmouup().add(dto.getSmoaup()));
        }
        BigDecimal hpouupTotal = new BigDecimal("0");
        long hpouupnTotal = 0L;
        BigDecimal hpouup3mTotal = new BigDecimal("0");
        long hpouupn3mTotal = 0L;
        BigDecimal hpouup5mTotal = new BigDecimal("0");
        long hpouupn5mTotal = 0L;
        BigDecimal hpoaupTotal = new BigDecimal("0");
        long sghpoaupnSignTotal = 0L;
        BigDecimal hpoaup3mTotal = new BigDecimal("0");
        long hpoaupn3mTotal = 0L;
        BigDecimal hpoaup5mTotal = new BigDecimal("0");
        long hpoaupn5mTotal = 0L;
        BigDecimal hjpTotal = new BigDecimal("0");
        BigDecimal smouupTotal = new BigDecimal("0");
        long smouupnTotal = 0L;
        BigDecimal smoaupTotal = new BigDecimal("0");
        long smoaupnTotal = 0L;
        BigDecimal hjsTotal = new BigDecimal("0");
        BigDecimal hjTotal = new BigDecimal("0");
        long hjnTotal = 0L;
        for (PmFinishedProductsServeAsStatisticsDTO pmFinishedProductsServeAsStatisticsDTO : dtoList) {
            hpouupTotal = hpouupTotal.add(pmFinishedProductsServeAsStatisticsDTO.getHpouup());
            hpouupnTotal = hpouupnTotal + pmFinishedProductsServeAsStatisticsDTO.getHpouupn();
            hpouup3mTotal = hpouup3mTotal.add(pmFinishedProductsServeAsStatisticsDTO.getHpouup3m());
            hpouupn3mTotal = hpouupn3mTotal + pmFinishedProductsServeAsStatisticsDTO.getHpouupn3m();
            hpouup5mTotal = hpouup5mTotal.add(pmFinishedProductsServeAsStatisticsDTO.getHpouup5m());
            hpouupn5mTotal = hpouupn5mTotal + pmFinishedProductsServeAsStatisticsDTO.getHpouupn5m();
            hpoaupTotal = hpoaupTotal.add(pmFinishedProductsServeAsStatisticsDTO.getHpoaup());
            sghpoaupnSignTotal = sghpoaupnSignTotal + pmFinishedProductsServeAsStatisticsDTO.getSghpoaupnSign();
            hpoaup3mTotal = hpoaup3mTotal.add(pmFinishedProductsServeAsStatisticsDTO.getHpoaup3m());
            hpoaupn3mTotal = hpoaupn3mTotal + pmFinishedProductsServeAsStatisticsDTO.getHpoaupn3m();
            hpoaup5mTotal = hpoaup5mTotal.add(pmFinishedProductsServeAsStatisticsDTO.getHpoaup5m());
            hpoaupn5mTotal = hpoaupn5mTotal + pmFinishedProductsServeAsStatisticsDTO.getHpoaupn5m();
            hjpTotal = hjpTotal.add(pmFinishedProductsServeAsStatisticsDTO.getHjp());
            smouupTotal = smouupTotal.add(pmFinishedProductsServeAsStatisticsDTO.getSmouup());
            smouupnTotal = smouupnTotal + pmFinishedProductsServeAsStatisticsDTO.getSmouupn();
            smoaupTotal = smoaupTotal.add(pmFinishedProductsServeAsStatisticsDTO.getSmoaup());
            smoaupnTotal = smoaupnTotal + pmFinishedProductsServeAsStatisticsDTO.getSmoaupn();
            hjsTotal = hjsTotal.add(pmFinishedProductsServeAsStatisticsDTO.getHjs());
            hjTotal = hjTotal.add(pmFinishedProductsServeAsStatisticsDTO.getHj());
            hjnTotal = hjnTotal + pmFinishedProductsServeAsStatisticsDTO.getHjn();
        }
        pageData.put("hpouupTotal", hpouupTotal);
        pageData.put("hpouupnTotal", hpouupnTotal);
        pageData.put("hpouup3mTotal", hpouup3mTotal);
        pageData.put("hpouupn3mTotal", hpouupn3mTotal);
        pageData.put("hpouup5mTotal", hpouup5mTotal);
        pageData.put("hpouupn5mTotal", hpouupn5mTotal);
        pageData.put("hpoaupTotal", hpoaupTotal);
        pageData.put("sghpoaupnSignTotal", sghpoaupnSignTotal);
        pageData.put("hpoaup3mTotal", hpoaup3mTotal);
        pageData.put("hpoaupn3mTotal", hpoaupn3mTotal);
        pageData.put("hpoaup5mTotal", hpoaup5mTotal);
        pageData.put("hpoaupn5mTotal", hpoaupn5mTotal);
        pageData.put("hjpTotal", hjpTotal);
        pageData.put("smouupTotal", smouupTotal);
        pageData.put("smouupnTotal", smouupnTotal);
        pageData.put("smoaupTotal", smoaupTotal);
        pageData.put("smoaupnTotal", smoaupnTotal);
        pageData.put("hjsTotal", hjsTotal);
        pageData.put("hjTotal", hjTotal);
        pageData.put("hjnTotal", hjnTotal);
        return pageData;
    }

}

