package com.cim.idm.service.Impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cim.idm.dao.MesToWmsDao;
import com.cim.idm.data.ErpMessageLog;
import com.cim.idm.exception.GlobalException;
import com.cim.idm.framework.IDMFrameServiceProxy;
import com.cim.idm.framework.data.EventInfo;
import com.cim.idm.framework.orm.SqlTemplate;
import com.cim.idm.framework.util.sys.SystemPropHelper;
import com.cim.idm.framework.util.time.TimeStampUtil;
import com.cim.idm.data.changeOrder.changeOrderDto;
import com.cim.idm.mwmsextend.materialpacking.service.MaterialPackingServiceImpl;
import com.cim.idm.service.MESToWMSService;
import com.cim.idm.service.QMSService;
import com.cim.idm.service.impl.ToSAPServiceImpl;
import com.cim.idm.util.MessageLogUtil;
import com.cim.idm.utils.AjaxResult;
import com.cim.idm.utils.CommonUtils;
import com.cim.idm.utils.EventInfoUtil;
import com.cim.idm.wmspackage.materialpacking.MaterialPackingServiceProxy;
import com.cim.idm.wmspackage.materialpacking.management.data.MaterialPackingKey;
import com.cim.idm.wmspackage.materialpacking.management.info.RemoveInfo;
import com.cim.idm.wmspackage.materialpacking.management.info.SetEventInfo;
import com.cim.idm.wmspackage.name.NameServiceProxy;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.sql.Timestamp;
import java.util.*;

@Service("MESToWMS")
@Slf4j
public class MESToWMSServiceImpl implements MESToWMSService {


    @Autowired
    private ToSAPServiceImpl toSAPService;

    @Autowired
    private SqlTemplate sqlTemplate;

    @Autowired
    private ProductIntoServiceImpl productIntoServiceImpl;
    @Autowired
    private ReturnStockIntoServiceImpl returnStockIntoServiceImpl;
    @Autowired
    private QMSService qmsService;

    @Autowired
    private MesToWmsDao mesToWmsDao;
    @Autowired
    private InvoiceServiceImpl invoiceService;

    @Override
    @Transactional
    public AjaxResult materialConsume_Request(JSONArray in) throws Exception {
        AjaxResult result = new AjaxResult();
        ErpMessageLog loginfo = new ErpMessageLog();
        loginfo.setServerName("MESToWms");
        loginfo.setMessageId("");
        loginfo.setEventUser("MES");
        loginfo.setId(TimeStampUtil.getCurrentEventTimeKey());
        loginfo.setInterfaceTime(TimeStampUtil.getCurrentTime(TimeStampUtil.FORMAT_DEFAULT));
        loginfo.setSendMsg(in.toJSONString());
        loginfo.setEventName("materialConsume_Request");
        String siteName = System.getProperty("company", "SDK");
        EventInfo eventInfo = new com.cim.idm.wmsextend.generic.util.EventInfoUtil().makeEventInfo("MES消耗UNDOID", "MES", "MES消耗UNDOID", "", "");
        String aufnr = "";
        List<String> boxIdList = new ArrayList<>();
        List<String> qtyList = new ArrayList<>();
        List<MaterialPackingKey> mpList = new ArrayList<>();
        //key=BOXID  value=消耗数量
        Map<String, String> materialPackingNameMap = new HashMap<String, String>();
        int success = 0;
        String errorCode = "";
        //根据wo，qty，materialSpecName生成物料消耗
        /**
         * 1. 从MATERIALPACKINGMDC该要求先进先出取出满足消耗的charge
         * 2. 写入接口临时表
         * 3. 过账
         * 4. 更新MATERIALPACKINGMDC表库存
         */
        String payMentDate = "";
        for (int i = 0; i < in.size(); i++) {
            JSONObject jb = in.getJSONObject(i);
            String materialSpecName = jb.get("materialSpecName").toString();
            String qty = jb.get("qty").toString(); // 消耗数量
            String  wo = jb.get("requestName") == null ? "" : jb.get("requestName").toString(); // 工单
            String flag = jb.get("flag") == null ? "" : jb.get("flag").toString();
            String charge = jb.get("charge") == null ? "" : jb.get("charge").toString();
            String erpFactory = jb.get("erpFactory") == null ? "" : jb.get("erpFactory").toString();//仓库
            String erpLocation = jb.get("erpLocation") == null ? "" : jb.get("erpLocation").toString();//库位
            payMentDate = jb.get("payMentDate") == null ? "" : jb.get("payMentDate").toString();
            //判空
            if (StringUtils.isBlank(materialSpecName) || StringUtils.isBlank(qty)) {
                result = AjaxResult.me().setSuccess(false).setErrorCode(500).setMessage("料号或数量不能为空");
                loginfo.setResultCode("1");
                loginfo.setReturnMsg(JSONObject.toJSONString(result));
                // 消息保存日志，erp推送wms的数据写入表BS_ERPMESSAGELOG中
                MessageLogUtil.writeMessageLog(loginfo);
                return result;
            }
            if (StringUtils.isBlank(wo)) {
                result = AjaxResult.me().setSuccess(false).setErrorCode(500).setMessage("工单不能为空");
                loginfo.setResultCode("1");
                loginfo.setReturnMsg(JSONObject.toJSONString(result));
                // 消息保存日志，erp推送wms的数据写入表BS_ERPMESSAGELOG中
                MessageLogUtil.writeMessageLog(loginfo);
                return result;
            }
            if (StringUtils.isBlank(payMentDate)) {
                result = AjaxResult.me().setSuccess(false).setErrorCode(500).setMessage("过账日期不能为空");
                loginfo.setResultCode("1");
                loginfo.setReturnMsg(JSONObject.toJSONString(result));
                // 消息保存日志，erp推送wms的数据写入表BS_ERPMESSAGELOG中
                MessageLogUtil.writeMessageLog(loginfo);
                return result;
            }
            //调用存储MES_CONSUME
            String procedureName = "MES_CONSUME";
            aufnr = wo;
            // 调用存储过程返回参数
//            IDMFrameServiceProxy.getSqlTemplate().getJdbcTemplate().execute(procedureName);
            Map<String, Object> bindMap = new HashMap<String, Object>() {
                {
                    put("V_WO", wo);
                    put("V_MATERIALSPECNAME", materialSpecName);
                    put("V_QTY", qty);
                        put("V_FLAG", flag);
                    put("V_RETURN_CODE", "");
                    put("V_RETURN_MESSAGE", "");
                    put("V_CHARGE", charge);
                    put("V_ERPFACTORY", erpFactory);
                    put("V_ERPLOCATION", erpLocation);
                }
            };
            //Map<String, Object> stringObjectMap = IDMFrameServiceProxy.getSqlTemplate().executeProcedure(procedureName, bindMap);
            //判断V_CHARGE是否为空
            if (StringUtils.isNotEmpty(charge)){
                //不等于空，根据CHARGE+V_MATERIALSPECNAME消耗库存数量
                String queryMaterialPackingByChargeSql = " SELECT \n" +
                        "\t\t\tT.MATERIALPACKINGNAME, \n" +
                        "      T.MATERIALSPECNAME, \n" +
                        "      T.MATERIALQUANTITY, \n" +
                        "\t\t\tT.UNIT MATERIALUNIT, \n" +
                        "      T.ERPFACTORY, \n" +
                        "      T.ERPLOCATION ,\n" +
                        "      T.SHIPREQUESTNAME\n" +
                        "    FROM \n" +
                        "\t\t\tMATERIALPACKING T\n" +
                        "    WHERE  \n" +
                        "\t\t\tT.MATERIALSPECNAME =:V_MATERIALSPECNAME \n" +
                        "\t\t\tAND T.CHARGE =:V_CHARGE\n" +
                        "\t\t\tAND T.ERPLOCATION =:V_ERPLOCATION\n" +
                        "      AND T.MATERIALQUANTITY > 0  \n" +
                        "\t\t\tAND T.STOCKSTATE = 'Stocked' ";
                List<Map<String,Object>> queryMaterialPackingByChargeForList = IDMFrameServiceProxy.getSqlTemplate().queryForList(queryMaterialPackingByChargeSql, bindMap);
                if (null != queryMaterialPackingByChargeForList && !queryMaterialPackingByChargeForList.isEmpty()) {
                    String materialQuantity = queryMaterialPackingByChargeForList.get(0).get("MATERIALQUANTITY") == null ? "0" : queryMaterialPackingByChargeForList.get(0).get("MATERIALQUANTITY").toString();
                    String materialPackingName = queryMaterialPackingByChargeForList.get(0).get("MATERIALPACKINGNAME") == null ? "" : queryMaterialPackingByChargeForList.get(0).get("MATERIALPACKINGNAME").toString();
                    String materialUnit = queryMaterialPackingByChargeForList.get(0).get("MATERIALUNIT") == null ? "" : queryMaterialPackingByChargeForList.get(0).get("MATERIALUNIT").toString();
                    String shipRequestName = queryMaterialPackingByChargeForList.get(0).get("SHIPREQUESTNAME") == null ? "" : queryMaterialPackingByChargeForList.get(0).get("SHIPREQUESTNAME").toString();

                    BigDecimal materialQuantityBigDecimal = new BigDecimal(materialQuantity);
                    BigDecimal qtyBigDecimal = new BigDecimal(qty);
                    //计算库存数量
                    if (materialQuantityBigDecimal.compareTo(qtyBigDecimal) >= 0){
                        //消耗后的库存数量
                        BigDecimal updateMaterialQuantity = materialQuantityBigDecimal.subtract(qtyBigDecimal);
                        //保留小数点后3位
                        updateMaterialQuantity = updateMaterialQuantity.setScale(3, RoundingMode.DOWN);
                        //更新MATERIALPACKING
                        String updateMaterialPackingMaterialQuantitySql = " UPDATE MATERIALPACKING T SET T.MATERIALQUANTITY =:MATERIALQUANTITY WHERE T.MATERIALPACKINGNAME =:MATERIALPACKINGNAME AND T.ERPFACTORY =:ERPFACTORY AND T.ERPLOCATION =:ERPLOCATION ";
                        Map<String, Object> updateMaterialPackingMaterialQuantityMap = new HashMap<String, Object>();
                        updateMaterialPackingMaterialQuantityMap.put("MATERIALQUANTITY", updateMaterialQuantity);
                        updateMaterialPackingMaterialQuantityMap.put("MATERIALPACKINGNAME", materialPackingName);
                        updateMaterialPackingMaterialQuantityMap.put("ERPFACTORY", erpFactory);
                        updateMaterialPackingMaterialQuantityMap.put("ERPLOCATION", erpLocation);
                        IDMFrameServiceProxy.getSqlTemplate().update(updateMaterialPackingMaterialQuantitySql, updateMaterialPackingMaterialQuantityMap);
                        //更新MATERIALPACKINGMDC
                        String updateMaterialPackingMdcMaterialQuantitySql = " UPDATE MATERIALPACKINGMDC T SET T.MATERIALQUANTITY = MATERIALQUANTITY - :MATERIALQUANTITY WHERE T.MATERIALPACKINGNAME =:MATERIALPACKINGNAME AND T.ERPFACTORY =:ERPFACTORY AND T.ERPLOCATION =:ERPLOCATION ";
                        Map<String, Object> updateMaterialPackingMdcMaterialQuantityMap = new HashMap<String, Object>();
                        updateMaterialPackingMdcMaterialQuantityMap.put("MATERIALQUANTITY", qtyBigDecimal);
                        updateMaterialPackingMdcMaterialQuantityMap.put("MATERIALPACKINGNAME", materialPackingName);
                        updateMaterialPackingMdcMaterialQuantityMap.put("ERPFACTORY", erpFactory);
                        updateMaterialPackingMdcMaterialQuantityMap.put("ERPLOCATION", erpLocation);
                        IDMFrameServiceProxy.getSqlTemplate().update(updateMaterialPackingMdcMaterialQuantitySql, updateMaterialPackingMdcMaterialQuantityMap);
                        //插入临时表TEMP_MESCONSUME
                        String insertTempMesConsumeSql = " INSERT INTO TEMP_MESCONSUME (MATERIALPACKINGNAME, MATERIALSPECNAME, ERPFACTORY, ERPLOCATION,UNIT, QTY,WO,SHIPREQUESTNAME)\n" +
                                "      VALUES (:MATERIALPACKINGNAME, :MATERIALSPECNAME, :ERPFACTORY, :ERPLOCATION, :UNIT, :QTY,:WO,:SHIPREQUESTNAME) ";
                        Map<String, Object> insertTempMesConsumeMap = new HashMap<String, Object>();
                        insertTempMesConsumeMap.put("MATERIALPACKINGNAME",materialPackingName);
                        insertTempMesConsumeMap.put("MATERIALSPECNAME",materialSpecName);
                        insertTempMesConsumeMap.put("ERPFACTORY",erpFactory);
                        insertTempMesConsumeMap.put("ERPLOCATION",erpLocation);
                        insertTempMesConsumeMap.put("UNIT",materialUnit);
                        insertTempMesConsumeMap.put("QTY",qtyBigDecimal);
                        insertTempMesConsumeMap.put("WO",wo);
                        insertTempMesConsumeMap.put("SHIPREQUESTNAME",shipRequestName);
                        IDMFrameServiceProxy.getSqlTemplate().update(insertTempMesConsumeSql,insertTempMesConsumeMap);
                        materialPackingNameMap.put(materialPackingName,qtyBigDecimal.toString());
                        continue;
                    }else {
                        result = AjaxResult.me().setSuccess(false).setErrorCode(400).setMessage("批次：" + charge + " 料号: " + materialSpecName + " 库位: " + erpLocation + " 当前库存短缺" + qtyBigDecimal.subtract(materialQuantityBigDecimal));
                        return result;
                    }
                }else {
                    result = AjaxResult.me().setSuccess(false).setErrorCode(400).setMessage("批次：" + charge + " 料号: " + materialSpecName + " 库位: " + erpLocation + " 当前库存短缺" + qty);
                    return result;
                }
            }else {
                String queryMaterialPackingByMaterialSpecSql = " SELECT T.MATERIALPACKINGNAME, \n" +
                        "  T.MATERIALSPECNAME, \n" +
                        "  T.MATERIALQUANTITY, \n" +
                        "  T.UNIT MATERIALUNIT, \n" +
                        "  T.ERPFACTORY, \n" +
                        "  T.ERPLOCATION ,\n" +
                        "  T.SHIPREQUESTNAME,\n" +
                        "  T.PRODUCTORDER\n" +
                        "  FROM MATERIALPACKING T\n" +
                        "  WHERE  T.MATERIALSPECNAME = :V_MATERIALSPECNAME \n" +
                        "  AND T.MATERIALQUANTITY > 0  AND T.STOCKSTATE = 'Stocked'\n" +
                        "  AND T.ERPFACTORY = :V_ERPFACTORY\n" +
                        "  AND T.ERPLOCATION = :V_ERPLOCATION\n" +
                        "  ORDER BY \n" +
                        "  T.MAKEDATE ASC ";
                List<Map<String,Object>> queryMaterialPackingByMaterialSpecForList = IDMFrameServiceProxy.getSqlTemplate().queryForList(queryMaterialPackingByMaterialSpecSql, bindMap);
                if (null != queryMaterialPackingByMaterialSpecForList && !queryMaterialPackingByMaterialSpecForList.isEmpty()){
                    //所要消耗的数量
                    BigDecimal qtyBigDecimal = new BigDecimal(qty);
                    for (int j = 0; j < queryMaterialPackingByMaterialSpecForList.size(); j++) {
                        String materialQuantity = queryMaterialPackingByMaterialSpecForList.get(j).get("MATERIALQUANTITY") == null ? "0" : queryMaterialPackingByMaterialSpecForList.get(j).get("MATERIALQUANTITY").toString();
                        String materialPackingName = queryMaterialPackingByMaterialSpecForList.get(j).get("MATERIALPACKINGNAME") == null ? "" : queryMaterialPackingByMaterialSpecForList.get(j).get("MATERIALPACKINGNAME").toString();
                        String materialUnit = queryMaterialPackingByMaterialSpecForList.get(j).get("MATERIALUNIT") == null ? "" : queryMaterialPackingByMaterialSpecForList.get(j).get("MATERIALUNIT").toString();
                        String shipRequestName = queryMaterialPackingByMaterialSpecForList.get(j).get("SHIPREQUESTNAME") == null ? "" : queryMaterialPackingByMaterialSpecForList.get(j).get("SHIPREQUESTNAME").toString();
                        //当前批次的库存数量
                        BigDecimal materialQuantityBigDecimal = new BigDecimal(materialQuantity);
                        if (materialQuantityBigDecimal.compareTo(qtyBigDecimal) >= 0){
                            //消耗后的库存数量
                            BigDecimal updateMaterialQuantity = materialQuantityBigDecimal.subtract(qtyBigDecimal);
                            //保留小数点后3位
                            updateMaterialQuantity = updateMaterialQuantity.setScale(3, RoundingMode.DOWN);
                            //更新MATERIALPACKING
                            String updateMaterialPackingMaterialQuantitySql = " UPDATE MATERIALPACKING T SET T.MATERIALQUANTITY =:MATERIALQUANTITY WHERE T.MATERIALPACKINGNAME =:MATERIALPACKINGNAME AND T.ERPFACTORY =:ERPFACTORY AND T.ERPLOCATION =:ERPLOCATION ";
                            Map<String, Object> updateMaterialPackingMaterialQuantityMap = new HashMap<String, Object>();
                            updateMaterialPackingMaterialQuantityMap.put("MATERIALQUANTITY", updateMaterialQuantity);
                            updateMaterialPackingMaterialQuantityMap.put("MATERIALPACKINGNAME", materialPackingName);
                            updateMaterialPackingMaterialQuantityMap.put("ERPFACTORY", erpFactory);
                            updateMaterialPackingMaterialQuantityMap.put("ERPLOCATION", erpLocation);
                            IDMFrameServiceProxy.getSqlTemplate().update(updateMaterialPackingMaterialQuantitySql, updateMaterialPackingMaterialQuantityMap);
                            //更新MATERIALPACKINGMDC
                            String updateMaterialPackingMdcMaterialQuantitySql = " UPDATE MATERIALPACKINGMDC T SET T.MATERIALQUANTITY = MATERIALQUANTITY - :MATERIALQUANTITY WHERE T.MATERIALPACKINGNAME =:MATERIALPACKINGNAME AND T.ERPFACTORY =:ERPFACTORY AND T.ERPLOCATION =:ERPLOCATION ";
                            Map<String, Object> updateMaterialPackingMdcMaterialQuantityMap = new HashMap<String, Object>();
                            updateMaterialPackingMdcMaterialQuantityMap.put("MATERIALQUANTITY", qtyBigDecimal);
                            updateMaterialPackingMdcMaterialQuantityMap.put("MATERIALPACKINGNAME", materialPackingName);
                            updateMaterialPackingMdcMaterialQuantityMap.put("ERPFACTORY", erpFactory);
                            updateMaterialPackingMdcMaterialQuantityMap.put("ERPLOCATION", erpLocation);
                            IDMFrameServiceProxy.getSqlTemplate().update(updateMaterialPackingMdcMaterialQuantitySql, updateMaterialPackingMdcMaterialQuantityMap);
                            //插入临时表TEMP_MESCONSUME
                            String insertTempMesConsumeSql = " INSERT INTO TEMP_MESCONSUME (MATERIALPACKINGNAME, MATERIALSPECNAME, ERPFACTORY, ERPLOCATION,UNIT, QTY,WO,SHIPREQUESTNAME)\n" +
                                    "      VALUES (:MATERIALPACKINGNAME, :MATERIALSPECNAME, :ERPFACTORY, :ERPLOCATION, :UNIT, :QTY,:WO,:SHIPREQUESTNAME) ";
                            Map<String, Object> insertTempMesConsumeMap = new HashMap<String, Object>();
                            insertTempMesConsumeMap.put("MATERIALPACKINGNAME",materialPackingName);
                            insertTempMesConsumeMap.put("MATERIALSPECNAME",materialSpecName);
                            insertTempMesConsumeMap.put("ERPFACTORY",erpFactory);
                            insertTempMesConsumeMap.put("ERPLOCATION",erpLocation);
                            insertTempMesConsumeMap.put("UNIT",materialUnit);
                            insertTempMesConsumeMap.put("QTY",qtyBigDecimal);
                            insertTempMesConsumeMap.put("WO",wo);
                            insertTempMesConsumeMap.put("SHIPREQUESTNAME",shipRequestName);
                            IDMFrameServiceProxy.getSqlTemplate().update(insertTempMesConsumeSql,insertTempMesConsumeMap);
                            materialPackingNameMap.put(materialPackingName,qtyBigDecimal.toString());
                            break;
                        }else {
                            //消耗数量大于循环中当前条码的库存数量
                            //更新MATERIALPACKING
                            String updateMaterialPackingMaterialQuantitySql = " UPDATE MATERIALPACKING T SET T.MATERIALQUANTITY =:MATERIALQUANTITY WHERE T.MATERIALPACKINGNAME =:MATERIALPACKINGNAME AND T.ERPFACTORY =:ERPFACTORY AND T.ERPLOCATION =:ERPLOCATION ";
                            Map<String, Object> updateMaterialPackingMaterialQuantityMap = new HashMap<String, Object>();
                            updateMaterialPackingMaterialQuantityMap.put("MATERIALQUANTITY", "0");
                            updateMaterialPackingMaterialQuantityMap.put("MATERIALPACKINGNAME", materialPackingName);
                            updateMaterialPackingMaterialQuantityMap.put("ERPFACTORY", erpFactory);
                            updateMaterialPackingMaterialQuantityMap.put("ERPLOCATION", erpLocation);
                            IDMFrameServiceProxy.getSqlTemplate().update(updateMaterialPackingMaterialQuantitySql, updateMaterialPackingMaterialQuantityMap);
                            //更新MATERIALPACKINGMDC
                            String updateMaterialPackingMdcMaterialQuantitySql = " UPDATE MATERIALPACKINGMDC T SET T.MATERIALQUANTITY = MATERIALQUANTITY - :MATERIALQUANTITY WHERE T.MATERIALPACKINGNAME =:MATERIALPACKINGNAME AND T.ERPFACTORY =:ERPFACTORY AND T.ERPLOCATION =:ERPLOCATION ";
                            Map<String, Object> updateMaterialPackingMdcMaterialQuantityMap = new HashMap<String, Object>();
                            updateMaterialPackingMdcMaterialQuantityMap.put("MATERIALQUANTITY", "0");
                            updateMaterialPackingMdcMaterialQuantityMap.put("MATERIALPACKINGNAME", materialPackingName);
                            updateMaterialPackingMdcMaterialQuantityMap.put("ERPFACTORY", erpFactory);
                            updateMaterialPackingMdcMaterialQuantityMap.put("ERPLOCATION", erpLocation);
                            IDMFrameServiceProxy.getSqlTemplate().update(updateMaterialPackingMdcMaterialQuantitySql, updateMaterialPackingMdcMaterialQuantityMap);
                            //插入临时表TEMP_MESCONSUME
                            String insertTempMesConsumeSql = " INSERT INTO TEMP_MESCONSUME (MATERIALPACKINGNAME, MATERIALSPECNAME, ERPFACTORY, ERPLOCATION,UNIT, QTY,WO,SHIPREQUESTNAME)\n" +
                                    "      VALUES (:MATERIALPACKINGNAME, :MATERIALSPECNAME, :ERPFACTORY, :ERPLOCATION, :UNIT, :QTY,:WO,:SHIPREQUESTNAME) ";
                            Map<String, Object> insertTempMesConsumeMap = new HashMap<String, Object>();
                            insertTempMesConsumeMap.put("MATERIALPACKINGNAME",materialPackingName);
                            insertTempMesConsumeMap.put("MATERIALSPECNAME",materialSpecName);
                            insertTempMesConsumeMap.put("ERPFACTORY",erpFactory);
                            insertTempMesConsumeMap.put("ERPLOCATION",erpLocation);
                            insertTempMesConsumeMap.put("UNIT",materialUnit);
                            insertTempMesConsumeMap.put("QTY",materialQuantityBigDecimal);
                            insertTempMesConsumeMap.put("WO",wo);
                            insertTempMesConsumeMap.put("SHIPREQUESTNAME",shipRequestName);
                            IDMFrameServiceProxy.getSqlTemplate().update(insertTempMesConsumeSql,insertTempMesConsumeMap);
                            materialPackingNameMap.put(materialPackingName,materialQuantityBigDecimal.toString());
                            //计算剩余消耗数量
                            qtyBigDecimal = qtyBigDecimal.subtract(materialQuantityBigDecimal);
                        }
                    }
                    if (qtyBigDecimal.compareTo(new BigDecimal(BigInteger.ZERO)) >= 0){
                        result = AjaxResult.me().setSuccess(false).setErrorCode(400).setMessage( " 料号: " + materialSpecName + " 库位: " + erpLocation + " 当前库存短缺" + qtyBigDecimal);
                        return result;
                    }
                }else {
                    result = AjaxResult.me().setSuccess(false).setErrorCode(400).setMessage( " 料号: " + materialSpecName + " 库位: " + erpLocation + " 当前库存短缺" + qty);
                    return result;
                }
            }
            /*
            if (stringObjectMap != null) {
                if (stringObjectMap.get("V_RETURN_CODE") != null && !stringObjectMap.get("V_RETURN_CODE").toString().equals("0")) {
                    errorCode = stringObjectMap.get("V_RETURN_CODE").toString();
                    String vReturnMessage = stringObjectMap.get("V_RETURN_MESSAGE").toString();
                    log.error("MES_CONSUME返回错误码：" + errorCode + "，错误信息：" + vReturnMessage);
                    result = AjaxResult.me().setSuccess(false).setErrorCode(400).setMessage(vReturnMessage);
                    return result;
                }
            }
            */
        }
        // 将工单的物料消耗数据传给SAP
        String undoId = toSAPService.mesMaterialConsume("MES",payMentDate, eventInfo,aufnr,materialPackingNameMap);
        result = AjaxResult.me().setSuccess(true).setErrorCode(200).setMessage("执行成功").setResultObj(undoId);
        loginfo.setResultCode("0");
        loginfo.setReturnMsg(JSONObject.toJSONString(result));
        // 消息保存日志，erp推送wms的数据写入表BS_ERPMESSAGELOG中
        MessageLogUtil.writeMessageLog(loginfo);
        return result;
    }

    @Override
    @Transactional
    public AjaxResult materialOutByMES(JSONArray in) throws Exception {
        AjaxResult result = new AjaxResult();
        ErpMessageLog loginfo = new ErpMessageLog();
        loginfo.setServerName("MESToWms");
        loginfo.setMessageId("");
        loginfo.setEventUser("MES");
        loginfo.setInterfaceTime(TimeStampUtil.getCurrentTime(TimeStampUtil.FORMAT_DEFAULT));
        loginfo.setSendMsg(in.toJSONString());
        loginfo.setEventName("MaterialOut_Request");

        List<String> boxIdList = new ArrayList<>();
        String shipRequestName = "";
        String payMentDate = "";
        for (int i = 0; i < in.size(); i++) {
            JSONObject jb = in.getJSONObject(i);
//            String charge = jb.get("charge").toString(); // 批号
            String materialPackingName = jb.get("lotName") == null ? "" : jb.get("lotName").toString();
            shipRequestName = jb.get("shipRequestName") == null ? "" : jb.get("shipRequestName").toString(); // 领料单号
            payMentDate = jb.get("payMentDate") == null ? "" : jb.get("payMentDate").toString(); // 过账时间
            //判空
            if (StringUtils.isEmpty(payMentDate) || StringUtils.isEmpty(shipRequestName) || StringUtils.isEmpty(materialPackingName)) {
                result = AjaxResult.me().setSuccess(false).setErrorCode(500).setMessage("过账日期、单号、条码不能为空");
                loginfo.setResultCode("1");
                loginfo.setReturnMsg(JSONObject.toJSONString(result));
                // 消息保存日志，erp推送wms的数据写入表BS_ERPMESSAGELOG中
                MessageLogUtil.writeMessageLog(loginfo);
                return result;
            }
            boxIdList.add(materialPackingName);
        }

        String billCode = new ToSAPServiceImpl().ProductionStockOut_NEW(shipRequestName, "SDK", "MES", boxIdList, payMentDate);
        if (billCode == null) {
            throw new RuntimeException("SAP接口过账失败");
        }
        EventInfo makeEventInfo = new EventInfoUtil().makeEventInfo("CompleteShipRequest", "MES", "CompleteShipRequest:MES Receive");
        new CommonUtils().SaveUnDoInfoByStockPending(boxIdList, billCode, makeEventInfo);

        result = AjaxResult.me().setSuccess(true).setErrorCode(200).setMessage("执行成功");
        loginfo.setResultCode("S");
        loginfo.setReturnMsg(JSONObject.toJSONString(result));
        // 消息保存日志，erp推送wms的数据写入表BS_ERPMESSAGELOG中
        MessageLogUtil.writeMessageLog(loginfo);
        return result;
    }

    @Override
    @Transactional
    public AjaxResult cancelShipByMES(JSONArray in) {
        AjaxResult result = new AjaxResult();
        ErpMessageLog loginfo = new ErpMessageLog();
        loginfo.setServerName("MESToWms");
        loginfo.setMessageId("");
        loginfo.setEventUser("MES");
        loginfo.setInterfaceTime(TimeStampUtil.getCurrentTime(TimeStampUtil.FORMAT_DEFAULT));
        loginfo.setSendMsg(in.toJSONString());
        loginfo.setEventName("CancelShip_Request");

        List<String> boxIdList = new ArrayList<>();
        for (int i = 0; i < in.size(); i++) {
            JSONObject jb = in.getJSONObject(i);
            String charge = jb.get("charge").toString(); // 批号
            boxIdList.add(charge);

        }

        String sqld = "DELETE FROM BS_MES_SHIPPED  b WHERE b.CHARGE in(:BOXIDLIST) AND NVL(b.receive_flag,'N')<>'Y' ";
        Map<String, Object> hashMap = new HashMap<>();
        hashMap.put("BOXIDLIST", boxIdList);
        IDMFrameServiceProxy.getSqlTemplate().update(sqld, hashMap);

        result = AjaxResult.me().setSuccess(true).setErrorCode(200).setMessage("执行成功");
        loginfo.setResultCode("S");
        loginfo.setReturnMsg(JSONObject.toJSONString(result));
        // 消息保存日志，erp推送wms的数据写入表BS_ERPMESSAGELOG中
        MessageLogUtil.writeMessageLog(loginfo);
        return result;
    }

    /**
     * 成品入库SAP冲销
     * @param undoId
     * @param user
     */
    @Override
    @Transactional
    public AjaxResult sapcprkUndo(String undoId, String user, String payMentDate) throws Exception {

        String billCode = toSAPService.cancelShipInter(undoId, user, payMentDate);
        if (billCode == null) {
            throw new GlobalException("报送SAP失败,请联系IT处理！");
        }


        AjaxResult result = new AjaxResult();

        EventInfo makeEventInfo = new EventInfoUtil ().makeEventInfo("MakeUndo", user, "MakeUndo");
        String  condition="SELECT MATERIALPACKINGNAME FROM MATERIALPACKING WHERE UNDOID = :UNDOID ";
//		String[] bindSet={undoId};
        Map<String, Object> hashMap = new HashMap<String, Object> ();
        hashMap.put("UNDOID", undoId);
        //根据物料凭证找到所有的待冲销数据，更新库存状态为创建
        List<Map<String, Object>> MPlIST = IDMFrameServiceProxy.getSqlTemplate().queryForList(condition, hashMap);
        SetEventInfo setEventInfo = new SetEventInfo();
        setEventInfo.setUserColumns(hashMap);
        RemoveInfo removeInfo = new RemoveInfo();
        for (Map<String, Object> MP : MPlIST) {

            String MATERIALPACKINGNAME = MP.get("MATERIALPACKINGNAME").toString();
            hashMap.put("MATERIALPACKINGNAME", MATERIALPACKINGNAME);
            /*
            //根据当前的数据跟新完工报告且删除入库表的数据
            String sql = "SELECT M.RECEIVEREQUESTNAME,M.RECEIVEREQUESTDETAILNAME,M.QTY FROM MATERIALPACKINGSUB M WHERE M.MATERIALPACKINGNAME = :MATERIALPACKINGNAME\r\n" +
                    "UNION \r\n" +
                    "SELECT M.RECEIVEREQUESTNAME,M.RECEIVEREQUESTDETAILNAME,M.QTY FROM MATERIALPACKINGSUBHISTORY M WHERE M.MATERIALPACKINGNAME = :MATERIALPACKINGNAME";

            List<Map<String, Object>> queryForList = IDMFrameServiceProxy.getSqlTemplate().queryForList(sql, hashMap);
            for (int i = 0; i < queryForList.size(); i++) {
                String dh = queryForList.get(i).get("RECEIVEREQUESTNAME").toString();
                hashMap.put("RECEIVEREQUESTNAME", dh);
                String hh = queryForList.get(i).get("RECEIVEREQUESTDETAILNAME").toString();
                hashMap.put("RECEIVEREQUESTDETAILNAME", hh);
//				String sl = queryForList.get(i).get("QTY").toString();
                String updateSql = "UPDATE MATERIALRECEIVEREQUESTDETAIL T  \r\n" +
                        "SET T.RECEIVEDQUANTITY = T.RECEIVEDQUANTITY - (  \r\n" +
                        "    SELECT NVL(SUM(M.QTY),0)  \r\n" +
                        "    FROM MATERIALPACKINGSUB M  \r\n" +
                        "    WHERE M.MATERIALPACKINGNAME = :MATERIALPACKINGNAME  \r\n" +
                        "      AND M.RECEIVEREQUESTNAME = T.RECEIVEREQUESTNAME  \r\n" +
                        "      AND M.RECEIVEREQUESTDETAILNAME = T.RECEIVEREQUESTDETAILNAME  \r\n" +
                        ")  \r\n" +
                        "WHERE T.RECEIVEREQUESTNAME = :RECEIVEREQUESTNAME  \r\n" +
                        "  AND T.RECEIVEREQUESTDETAILNAME = :RECEIVEREQUESTDETAILNAME";
                IDMFrameServiceProxy.getSqlTemplate().update(updateSql, hashMap);


                String updateSql2 = "UPDATE MATERIALRECEIVEREQUESTDETAIL T  \r\n" +
                        "SET T.RECEIVEDQUANTITY = T.RECEIVEDQUANTITY - (  \r\n" +
                        "    SELECT NVL(SUM(M.QTY),0)  \r\n" +
                        "    FROM MATERIALPACKINGSUBHISTORY M  \r\n" +
                        "    WHERE M.MATERIALPACKINGNAME = :MATERIALPACKINGNAME  \r\n" +
                        "      AND M.RECEIVEREQUESTNAME = T.RECEIVEREQUESTNAME  \r\n" +
                        "      AND M.RECEIVEREQUESTDETAILNAME = T.RECEIVEREQUESTDETAILNAME  \r\n" +
                        ")  \r\n" +
                        "WHERE T.RECEIVEREQUESTNAME = :RECEIVEREQUESTNAME  \r\n" +
                        "  AND T.RECEIVEREQUESTDETAILNAME = :RECEIVEREQUESTDETAILNAME";
                IDMFrameServiceProxy.getSqlTemplate().update(updateSql2, hashMap);

                String deleteSql = " DELETE FROM MATERIALPACKINGSUB T WHERE T.RECEIVEREQUESTNAME = :RECEIVEREQUESTNAME AND "
                        + "T.RECEIVEREQUESTDETAILNAME = :RECEIVEREQUESTDETAILNAME AND T.MATERIALPACKINGNAME = :MATERIALPACKINGNAME";
                IDMFrameServiceProxy.getSqlTemplate().update(deleteSql, hashMap);

                String MESsQL = " UPDATE BS_MES_SHIPPED T SET T.RECEIVE_FLAG = 'N' WHERE T.LOTNAME = :MATERIALPACKINGNAME ";
                IDMFrameServiceProxy.getSqlTemplate().update(MESsQL, hashMap);
            }
            */
            String MESsQL = " DELETE FROM BS_MES_SHIPPED T WHERE T.LOTNAME = :MATERIALPACKINGNAME ";
            IDMFrameServiceProxy.getSqlTemplate().update(MESsQL, hashMap);
            MaterialPackingServiceProxy.getMaterialPackingService().remove(new MaterialPackingKey("SDK", MATERIALPACKINGNAME), makeEventInfo, removeInfo);
        }

        String sql = "UPDATE IF_ERPUNDO T SET T.FLAG = 'Y' WHERE  T.UNDOID = :UNDOID ";
        Map<String, Object> hashMap2 = new HashMap<String, Object> ();
        hashMap2.put("UNDOID", undoId);
        IDMFrameServiceProxy.getSqlTemplate().update(sql, hashMap2);

        result = AjaxResult.me().setSuccess(true).setErrorCode(200).setMessage("执行成功");
        return result;
    }
    // 改造成mybase实现
//    @Override
//    @Transactional
//    public AjaxResult sapcprkUndo(String undoId, String user) throws Exception {
//
//        String billCode = toSAPService.cancelShipInter(undoId, user);
//        if (billCode == null) {
//            throw new GlobalException("报送ERP失败,请联系IT处理！");
//        }
//
//
//        AjaxResult result = new AjaxResult();
//
//        EventInfo makeEventInfo = new EventInfoUtil ().makeEventInfo("MakeUndo", user, "MakeUndo");
//        String  condition="SELECT MATERIALPACKINGNAME FROM MATERIALPACKING WHERE UNDOID = :UNDOID ";
////		String[] bindSet={undoId};
//        Map<String, Object> hashMap = new HashMap<String, Object> ();
//        hashMap.put("UNDOID", undoId);
//        //根据物料凭证找到所有的待冲销数据，更新库存状态为创建
//        List<Map<String, Object>> MPlIST = IDMFrameServiceProxy.getSqlTemplate().queryForList(condition, hashMap);
//        SetEventInfo setEventInfo = new SetEventInfo();
//        setEventInfo.setUserColumns(hashMap);
//        RemoveInfo removeInfo = new RemoveInfo();
//        for (Map<String, Object> MP : MPlIST) {
//            //根据当前的数据跟新完工报告且删除入库表的数据
//            String MATERIALPACKINGNAME = MP.get("MATERIALPACKINGNAME").toString();
//            hashMap.put("MATERIALPACKINGNAME", MATERIALPACKINGNAME);
//            List<MaterialPackingSubDto> queryForList = mesToWmsDao.getEndReportList(MATERIALPACKINGNAME);
//
//            for (int i = 0; i < queryForList.size(); i++) {
//                String dh = queryForList.get(i).getReceiveRequestName().toString();
//                hashMap.put("RECEIVEREQUESTNAME", dh);
//                String hh = queryForList.get(i).getReceiveRequestDetailName().toString();
//                hashMap.put("RECEIVEREQUESTDETAILNAME", hh);
//
//                mesToWmsDao.updateEndReport(dh, hh, MATERIALPACKINGNAME);
//
//                mesToWmsDao.updateEndReport2(dh, hh, MATERIALPACKINGNAME);
//
//                mesToWmsDao.deleteSub(dh, hh, MATERIALPACKINGNAME);
//
//                mesToWmsDao.updateBsMesShipped(MATERIALPACKINGNAME);
//
//            }
//            MaterialPackingServiceProxy.getMaterialPackingService().remove(new MaterialPackingKey("SDK", MATERIALPACKINGNAME), makeEventInfo, removeInfo);
//        }
//
//        Map<String, Object> hashMap2 = new HashMap<String, Object> ();
//        hashMap2.put("UNDOID", undoId);
//        mesToWmsDao.updateUnDoId(undoId);
//
//        result = AjaxResult.me().setSuccess(true).setErrorCode(200).setMessage("执行成功");
//        return result;
//    }

    @Override
    @Transactional
    public AjaxResult shipByMES(JSONArray in) throws Exception {
        AjaxResult result = new AjaxResult();
        ErpMessageLog loginfo = new ErpMessageLog();
        loginfo.setServerName("MESToWms");
        loginfo.setMessageId("");
        loginfo.setEventUser("MES");
        loginfo.setInterfaceTime(TimeStampUtil.getCurrentTime(TimeStampUtil.FORMAT_DEFAULT));
        loginfo.setSendMsg(in.toJSONString());
        loginfo.setEventName("Ship_Request");

        List<String> boxIdList = new ArrayList<>();
        List<String> barCodeList = new ArrayList<>();
        String stockInType = ""; // 用于记录是产成品入库，还是生产退料入库  入库类型，成品FG，退料MAT
        String operationType = ""; // 用于记录是否是自动入库  手动入库0，自动入库1
        String fgStockIn = "";
        if (in != null && in.size() > 0) {
            String payMentDate = in.getJSONObject(0).get("payMentDate") == null ? "" : in.getJSONObject(0).get("payMentDate").toString(); //日期
            if (StringUtils.isBlank(payMentDate)) {
                result = AjaxResult.me().setSuccess(false).setErrorCode(500).setMessage("payMentDate过账日期不能为空");
                loginfo.setResultCode("1");
                loginfo.setReturnMsg(JSONObject.toJSONString(result));
                // 消息保存日志，erp推送wms的数据写入表BS_ERPMESSAGELOG中
                MessageLogUtil.writeMessageLog(loginfo);
                return result;
            }
            for (int i = 0; i < in.size(); i++) {
                JSONObject jb = in.getJSONObject(i);
                String charge = jb.get("charge").toString(); // 批号
                boxIdList.add(charge);
                barCodeList.add(jb.get("lotName").toString());

                String stype = jb.get("stockInType") == null ? "" : jb.get("stockInType").toString();

                if("MAT".equals(stype)) {
                    String sqld = "SELECT b.LOTNAME FROM BS_MES_SHIPPED  b WHERE b.CHARGE = :CHARGE ";
                    Map<String, Object> hashMapdel = new HashMap<>();
                    hashMapdel.put("CHARGE", charge);
                    List<Map<String, Object>> delqueryForList = sqlTemplate.queryForList(sqld, hashMapdel);
                    if(delqueryForList != null && delqueryForList.size() > 0) {
                        String deleteSql="DELETE FROM BS_MES_SHIPPED WHERE  CHARGE=?";
                        Object[] obj=new Object[] {charge};
                        IDMFrameServiceProxy.getSqlTemplate().update(deleteSql, obj);
                    }
                }
            }
            String sqld = "SELECT b.charge,b.RECEIVE_FLAG,b.LOTNAME FROM BS_MES_SHIPPED  b WHERE b.CHARGE in(:BOXIDLIST) ";
            Map<String, Object> hashMap = new HashMap<>();
            hashMap.put("BOXIDLIST", boxIdList);
            List<Map<String, Object>> existShips = sqlTemplate.queryForList(sqld, hashMap);
            if (existShips != null && existShips.size() > 0) {
                List<String> lots = new ArrayList<>();
                for (Map<String, Object> existShip : existShips) {
                    String receiveFlag = (String) existShip.get("RECEIVE_FLAG");
                    String lot = (String) existShip.get("charge");
                    String lotName = (String) existShip.get("LOTNAME");
                    if(!"N".equals(receiveFlag)) {
                        lots.add(lot);
                    }
                    else {
                        String querypacksql = "SELECT * FROM MATERIALPACKING m WHERE MATERIALPACKINGNAME =:MATERIALPACKINGNAME";
                        Map<String, Object> hashMap2 = new HashMap<>();
                        hashMap2.put("MATERIALPACKINGNAME", lotName);
                        List<Map<String, Object>> queryPackForList = IDMFrameServiceProxy.getSqlTemplate().queryForList(querypacksql, hashMap2);
                        if(queryPackForList.size() > 0) {
                            String deletePackSql="DELETE FROM MATERIALPACKING WHERE  MATERIALPACKINGNAME=?";
                            Object[] obj=new Object[] {lotName};
                            IDMFrameServiceProxy.getSqlTemplate().update(deletePackSql, obj);
                        }
                        String deleteSql="DELETE FROM BS_MES_SHIPPED WHERE  CHARGE=?";
                        Object[] obj=new Object[] {lot};
                        IDMFrameServiceProxy.getSqlTemplate().update(deleteSql, obj);
                    }
                }
                if(lots.size() > 0) {
                    result = AjaxResult.me().setSuccess(false).setErrorCode(500).setMessage("执行失败:" + lots + " 已经SHIP并且使用,请不要重复SHIP");
                    return result;
                }
            }
            String needIqcSql = SystemPropHelper.CR + "SELECT IQCFLAG "
                    + "  FROM BS_MATERIALFACTORY bm "
                    + " WHERE bm.MATERIALSPECNAME = :MATERIALSPECNAME "
                    + "   AND bm.ERPFACTORY = :ERPFACTORY";
            String insertSql = SystemPropHelper.CR + "INSERT INTO BS_MES_SHIPPED(LOTNAME,QTY, UNIT, REQUESTNAME, AREA, "
                    + "PRODUCTSPECNAME, PRODUCTNAME, SDK_ID, PHASE, RECEIVE_FLAG,  REMARK, SHIPTIME, "
                    + "SHIPUSER, SITENAME, MATERIALSPECTYPE,SALESHIPREQUESTNAME,SALESHIPREQUESTDETAILNAME,"
                    + "INVENTORYTYPE, SALENO, SALEDETAILNO, ERPLOCATION, CHARGE, LOCATIONNAME, "
                    + "OPERATIONTYPE, MAKEDATE,ERPFACTORY,PACKINGGRADE,GXID)" + SystemPropHelper.CR
                    + "                     VALUES(:LOTNAME,:QTY,:UNIT,:REQUESTNAME, :AREA, "
                    + ":PRODUCTSPECNAME, :PRODUCTNAME, :SDK_ID, :PHASE, 'N',  :REMARK, :SHIPTIME, "
                    + "'MES', 'SDK', :MATERIALSPECTYPE, :SALESHIPREQUESTNAME,:SALESHIPREQUESTDETAILNAME,"
                    + ":INVENTORYTYPE, :SALENO, :SALEDETAILNO, :ERPLOCATION, :CHARGE, :LOCATIONNAME, "
                    + ":OPERATIONTYPE,TO_DATE(:MAKEDATE, 'YYYY-MM-DD'),:ERPFACTORY,:PACKINGGRADE,:GXID)";
            String receiveActNo = "";
            String productSpecName = "";
            String erpFactory = "";
            for (int i = 0; i < in.size(); i++) {
                JSONObject jo = in.getJSONObject(i);
                String charge = jo.get("charge").toString(); // 批号
                String lotname = jo.getString("lotName");
                double qty = StringUtils.isEmpty(jo.getString("qty")) ? 0 : Double.parseDouble(jo.getString("qty"));
                String unit = jo.getString("unit");
                String requestName = jo.getString("requestName");
                String area = jo.getString("area");
                //recycledParticlesSpec表示回收粒子
                productSpecName = jo.getString("productSpecName");
                String productName = jo.getString("productName");
                String sdkId = jo.getString("sdkId");
                String phase = jo.getString("phase");
                String remark = jo.getString("remark");
                String shipTimeStr = jo.getString("shipTime");
                Timestamp shipTime = StringUtils.isEmpty(shipTimeStr) ? TimeStampUtil.getCurrentTimestamp() : TimeStampUtil.getTimestamp(shipTimeStr);
                String shipUser = jo.getString("shipUser");
                String inventoryType = jo.getString("inventoryType");
                String saleNo = jo.getString("saleNo");
                String saleDetailNo = jo.getString("saleDetailNo");
                String erpLocation = jo.getString("erpLocation");
                String locationName = jo.getString("locationName");
                String gxId = jo.getString("gxId"); // 增加管芯字段
                String makeDate = jo.getString("makeDate");
                erpFactory = jo.getString("erpFactory");
                String materialPackingName = jo.getString("materialPackingName"); // 退料原条码二维码
                String saleShipRequestName = jo.getString("saleShipRequestName") == null ? "" : jo.getString("saleShipRequestName"); // 销售订单号   e库存
                String saleShipRequestDetailName = jo.getString("saleShipRequestDetailName") == null ? "" : jo.getString("saleShipRequestDetailName"); // 销售订单号行项 e库存
                String packingGrade = jo.getString("packingGrade");

                if (i == 0) {
                    stockInType = jo.getString("stockInType");
                    operationType = jo.getString("operationType");
                    List<String> args = Arrays.asList(new String[]{"SH", "F", TimeStampUtil.getCurrentTime("yyyyMMdd")});
                    receiveActNo = NameServiceProxy.getNameRuleDefService().generateName("ReceiveActNo", args, 1).get(0);
                }
                String recycledParticlesSpec = jo.get("recycledParticlesSpec") == null ? "" : jo.get("recycledParticlesSpec").toString();
                //如果是回收例子，料号修改为recycledParticlesSpec
                if ("BFG".equals(stockInType)) {
                    productSpecName = recycledParticlesSpec;
                    //回收粒子需要生成新的Box ID
                    List<String> boxIDs =  MaterialPackingServiceImpl.generateBoxID("LabelId", "SDK",
                            1 + ""
                            , shipTimeStr, "SH", erpFactory);
                    lotname = boxIDs.get(0);
                }
                Map<String, Object> bindMap = new HashMap<>();
                bindMap.put("LOTNAME", lotname);
                bindMap.put("QTY", qty);
                bindMap.put("UNIT", unit);
                bindMap.put("REQUESTNAME", requestName);
                bindMap.put("AREA", area);
                bindMap.put("PRODUCTSPECNAME", productSpecName);
                bindMap.put("PRODUCTNAME", productName);
                bindMap.put("SDK_ID", sdkId);
                bindMap.put("TRUEGG", sdkId); // sap用于实际规格
                bindMap.put("PHASE", phase);
                bindMap.put("REMARK", remark);
                bindMap.put("SHIPTIME", shipTime);
                bindMap.put("SHIPUSER", shipUser);
                bindMap.put("INVENTORYTYPE", inventoryType);
                bindMap.put("SALENO", saleNo);
                bindMap.put("SALEDETAILNO", saleDetailNo);
                bindMap.put("ERPLOCATION", erpLocation);
                bindMap.put("LOCATIONNAME", locationName);
                bindMap.put("OPERATIONTYPE", operationType);
                bindMap.put("ERPFACTORY", erpFactory);
                bindMap.put("MATERIALSPECTYPE", stockInType);
                bindMap.put("CHARGE", charge);
                bindMap.put("GXID", gxId);
                bindMap.put("MATERIALPACKINGNAME", materialPackingName);
                bindMap.put("MAKEDATE", makeDate);
                bindMap.put("SALESHIPREQUESTNAME", saleShipRequestName);  // e库存 销售订单号
                bindMap.put("SALESHIPREQUESTDETAILNAME", saleShipRequestDetailName); // e库存 销售订单行项
                bindMap.put("PACKINGGRADE", packingGrade);

                if ("1".equals(operationType)) { // 自动入库
                    if ("FG".equals(stockInType) || "BFG".equals(stockInType)) { // 产成品入库  增加回收例子入库
                        sqlTemplate.update(insertSql, bindMap);
                        MaterialPackingServiceImpl.checkMaterialPackingExist(lotname);

                        EventInfo makeEventInfo = EventInfoUtil.makeEventInfo("createfgBoxInfo", "MES", "createfgBoxInfo", "", "");
                        productIntoServiceImpl.receiveMesShippInfo2(makeEventInfo, "SDK", lotname, "", "MES",
                                lotname, receiveActNo, erpLocation, erpFactory, locationName, requestName, "", "");
                    } else if ("MAT".equals(stockInType)) { // 生产退料入库
                        Map<String, Object> iqcBind = new HashMap<>();
                        iqcBind.put("MATERIALSPECNAME", productSpecName);
                        iqcBind.put("ERPFACTORY", erpFactory);
                        List<Map<String, Object>> iqcFlags = sqlTemplate.queryForList(needIqcSql, iqcBind);
                        if (iqcFlags != null && iqcFlags.size() > 0) {
                            if ("Y".equals(iqcFlags.get(0).get("IQCFLAG"))) {
                                throw new GlobalException("物料[" + productSpecName + "]需要质检，不允许自动入库，请手动入库");
                            }
                        }
                        sqlTemplate.update(insertSql, bindMap);
                        MaterialPackingServiceImpl.checkMaterialPackingExist(lotname);

                        EventInfo makeEventInfo = EventInfoUtil.makeEventInfo("createBoxInfoReturn", "MES", "createBoxInfoReturn", "", "");
//                        returnStockIntoServiceImpl.CreateMaterialReceiveRequestAct
//                                (makeEventInfo, "SDK", requestName, productSpecName, shipTimeStr,
//                                        receiveActNo, "ProduceReturn", Double.toString(qty), productSpecName);
                        returnStockIntoServiceImpl.SHIPMesShippInfo(makeEventInfo, "SDK", lotname, "", "MES",
                                lotname, receiveActNo, erpLocation, erpFactory, locationName, requestName,
                                productSpecName);
                    }
                }else if ("0".equals(operationType)){
                    String insertBS_MES_SHIP_PEDSql = SystemPropHelper.CR + "INSERT INTO BS_MES_SHIPPED(LOTNAME,QTY, UNIT, REQUESTNAME, AREA, "
                            + "PRODUCTSPECNAME, PRODUCTNAME, SDK_ID, PHASE, RECEIVE_FLAG,  REMARK, SHIPTIME, MATERIALPACKINGNAME,"
                            + "SHIPUSER, SITENAME, MATERIALSPECTYPE,"
                            + "INVENTORYTYPE, SALENO, SALEDETAILNO, ERPLOCATION, CHARGE, PACKINGGRADE, LOCATIONNAME, "
                            + "OPERATIONTYPE, MAKEDATE,ERPFACTORY,GXID,SHIPREQUESTNAME, SHIPREQUESTDETAILNAME)" + SystemPropHelper.CR
                            + "                     VALUES(:LOTNAME,:QTY,:UNIT,:REQUESTNAME, :AREA, "
                            + ":PRODUCTSPECNAME, :PRODUCTNAME, :SDK_ID, :PHASE, 'N',  :REMARK, :SHIPTIME, :MATERIALPACKINGNAME,"
                            + "'MES', 'SDK', :MATERIALSPECTYPE, "
                            + ":INVENTORYTYPE, :SALENO, :SALEDETAILNO, :ERPLOCATION, :CHARGE, :PACKINGGRADE, :LOCATIONNAME, "
                            + ":OPERATIONTYPE,TO_DATE(:MAKEDATE, 'YYYY-MM-DD'),:ERPFACTORY,:GXID,:SHIPREQUESTNAME, :SHIPREQUESTDETAILNAME)";
                    Map<String, Object> insertBS_MES_SHIP_PEDMap = new HashMap<>();
                    insertBS_MES_SHIP_PEDMap.put("LOTNAME", lotname);
                    insertBS_MES_SHIP_PEDMap.put("QTY", qty);
                    insertBS_MES_SHIP_PEDMap.put("UNIT", unit);
                    insertBS_MES_SHIP_PEDMap.put("REQUESTNAME", requestName);
                    insertBS_MES_SHIP_PEDMap.put("AREA", area);
                    insertBS_MES_SHIP_PEDMap.put("PRODUCTSPECNAME", productSpecName);
                    insertBS_MES_SHIP_PEDMap.put("PRODUCTNAME", productName);
                    insertBS_MES_SHIP_PEDMap.put("SDK_ID", sdkId);
                    insertBS_MES_SHIP_PEDMap.put("TRUEGG", sdkId); // sap用于实际规格
                    insertBS_MES_SHIP_PEDMap.put("PHASE", phase);
                    insertBS_MES_SHIP_PEDMap.put("REMARK", remark);
                    insertBS_MES_SHIP_PEDMap.put("SHIPTIME", shipTime);
                    insertBS_MES_SHIP_PEDMap.put("SHIPUSER", shipUser);
                    insertBS_MES_SHIP_PEDMap.put("INVENTORYTYPE", inventoryType);
                    insertBS_MES_SHIP_PEDMap.put("SALENO", saleNo);
                    insertBS_MES_SHIP_PEDMap.put("SALEDETAILNO", saleDetailNo);
                    insertBS_MES_SHIP_PEDMap.put("ERPLOCATION", erpLocation);
                    insertBS_MES_SHIP_PEDMap.put("LOCATIONNAME", locationName);
                    insertBS_MES_SHIP_PEDMap.put("OPERATIONTYPE", operationType);
                    insertBS_MES_SHIP_PEDMap.put("ERPFACTORY", erpFactory);
                    insertBS_MES_SHIP_PEDMap.put("MATERIALSPECTYPE", stockInType);
                    insertBS_MES_SHIP_PEDMap.put("CHARGE", charge);
                    insertBS_MES_SHIP_PEDMap.put("GXID", gxId);
                    insertBS_MES_SHIP_PEDMap.put("MATERIALPACKINGNAME", materialPackingName);
                    insertBS_MES_SHIP_PEDMap.put("MAKEDATE", makeDate);
                    String shipRequestName = jo.getString("shipRequestName"); // 增加管芯字段
                    insertBS_MES_SHIP_PEDMap.put("SHIPREQUESTNAME", shipRequestName);
                    String shipRequestDetailName = jo.getString("shipRequestDetailName");
                    insertBS_MES_SHIP_PEDMap.put("SHIPREQUESTDETAILNAME", shipRequestDetailName);
                    insertBS_MES_SHIP_PEDMap.put("PACKINGGRADE", packingGrade);
                    sqlTemplate.update(insertBS_MES_SHIP_PEDSql, insertBS_MES_SHIP_PEDMap);
                }else {
                    sqlTemplate.update(insertSql, bindMap);
                }

            }
            if ("1".equals(operationType)) { // 自动入库
                if ("FG".equals(stockInType) || "BFG".equals(stockInType)) { // 产成品入库 增加回收粒子入库
                    fgStockIn = productIntoServiceImpl.outoFgStockIn(receiveActNo, "MES",stockInType,payMentDate);
                    if (fgStockIn.isEmpty()) {
                        throw new GlobalException("报送ERP失败,请联系IT处理！");
                    }
                    String checkIqcSql = "SELECT DISTINCT MATERIALSPECNAME, ERPFACTORY FROM MATERIALPACKING m WHERE M.RECEIVEACTNO = :RECEIVEACTNO";
                    Map<String, Object> bindMap = new HashMap<>();
                    bindMap.put("RECEIVEACTNO", receiveActNo);
                    bindMap.put("MATERIALSPECNAME", productSpecName);
                    bindMap.put("ERPFACTORY", erpFactory);
                    List<Map<String, Object>> materialSpecs = sqlTemplate.queryForList(needIqcSql, bindMap);
                    if (materialSpecs != null && materialSpecs.size() > 0) {
                        for (Map<String, Object> materialSpec : materialSpecs) {
                            Map<String, Object> iqcBind = new HashMap<>();
                            iqcBind.put("MATERIALSPECNAME", materialSpec.get("MATERIALSPECNAME"));
                            iqcBind.put("ERPFACTORY", materialSpec.get("ERPFACTORY"));
                            List<Map<String, Object>> iqcFlags = sqlTemplate.queryForList(needIqcSql, iqcBind);
                            if (iqcFlags != null && iqcFlags.size() > 0) {
                                if ("Y".equals(iqcFlags.get(0).get("IQCFLAG"))) {
                                    qmsService.PreIQCInfoSend(receiveActNo, "SDK", "", "");
                                }
                            }
                        }
                    }

                } else if ("MAT".equals(stockInType)) { // 生产退料入库
                    //fgStockIn = returnStockIntoServiceImpl.ReturnStockIn(receiveActNo, "MES", "", "");
                    fgStockIn = returnStockIntoServiceImpl.ReturnStockInPayMentDate(receiveActNo, "MES", "", "",payMentDate);
                    if (fgStockIn.isEmpty()) {
                        throw new GlobalException("报送ERP失败,请联系IT处理！");
                    }
                    return AjaxResult.me().setResultObj(null);
                }
            }
        }
        result = AjaxResult.me().setResultObj(fgStockIn).setSuccess(true).setErrorCode(200).setMessage("执行成功");
        loginfo.setResultCode("S");
        loginfo.setReturnMsg(JSONObject.toJSONString(result));
        // 消息保存日志，erp推送wms的数据写入表BS_ERPMESSAGELOG中
        MessageLogUtil.writeMessageLog(loginfo);
        return result;
    }

    @Override
    @Transactional
    public AjaxResult workOrder_Request_new(JSONArray in) throws Exception {
        log.info("Received work order request: {}", in.toJSONString());
        List<Map<String, Object>> mapList = new ArrayList<>();
        for (int i = 0; i < in.size(); i++) {
            String line = "第" + (i + 1) + "行，";
            JSONObject jsonObject = in.getJSONObject(i);
            Map<String, Object> map = new HashMap<>();
            // 料号
            String materialSpecname = jsonObject.getString("materialSpecname");
            if (StringUtils.isEmpty(materialSpecname)) {
                return AjaxResult.me().setSuccess(false).setErrorCode(500).
                        setMessage(line + "料号-materialSpecname-不能为空");
            }
            // 组织
            String WERKS = jsonObject.getString("WERKS");
            if (StringUtils.isEmpty(WERKS)) {
                return AjaxResult.me().setSuccess(false).setErrorCode(500).
                        setMessage(line + "组织-WERKS-不能为空");
            }
            // 仓库
            String LGORT = jsonObject.getString("erpLocation");
            if (StringUtils.isEmpty(LGORT)) {
                return AjaxResult.me().setSuccess(false).setErrorCode(500).
                        setMessage(line + "仓库-erpLocation-不能为空");
            }
            if (StringUtils.isEmpty(jsonObject.getString("MENGE"))) {
                return AjaxResult.me().setSuccess(false).setErrorCode(500).
                        setMessage(line + "数量-MENGE-不能为空");
            }
            // 数量
            BigDecimal MENGE = new BigDecimal(jsonObject.getString("MENGE"));
            // 单位
            String MEINS = jsonObject.getString("MEINS");
            if (StringUtils.isEmpty(MEINS)) {
                return AjaxResult.me().setSuccess(false).setErrorCode(500).
                        setMessage(line + "单位-MEINS-不能为空");
            }
            // 自定义领料单号
            String ZLLORDER = jsonObject.getString("ZLLORDER");
            // 自定义领料单行号
            String ZLLITEM = jsonObject.getString("ZLLITEM");
            // 工单
            String AUFNR = jsonObject.getString("toOrder");
            if (StringUtils.isEmpty(AUFNR)) {
                return AjaxResult.me().setSuccess(false).setErrorCode(500).
                        setMessage(line + "工单-toOrder-不能为空");
            }

            map.put("MATNR", materialSpecname);
            map.put("WERKS", WERKS);
            map.put("LGORT", LGORT);
            map.put("MENGE", MENGE);
            map.put("MEINS", MEINS);
            map.put("ZLLORDER", ZLLORDER);
            map.put("ZLLITEM", ZLLITEM);
            map.put("AUFNR", AUFNR);
            mapList.add(map);
        }
        // 出库
        String undoidOut = toSAPService.StockOutByOrder_new(mapList, "MES", "262");
        // 入库
        String undoidIn = toSAPService.StockOutByOrder_new(mapList, "MES", "261");
        if (StringUtils.isEmpty(undoidIn)) {
            // 冲销
            String undo = invoiceService.cancelShipInter(undoidOut, "MES");
            if (undo == null || undo.isEmpty()) {
                throw new GlobalException("下发mes失败后冲销失败！");
            } else {
                throw new GlobalException("发送到mes失败！");
            }
        }
        return AjaxResult.me().setResultObj(null).setSuccess(true).setErrorCode(200).setMessage("执行成功,物料凭证 " + undoidIn);
    }
    /**
     * 接收MES请求工单请求
     *
     * @param in
     * @return
     */
    @Override
    @Transactional
    public AjaxResult workOrder_Request(JSONArray in) throws Exception {
        //转工单，按照批次先传MDC消耗请求SAP出库，再生成入库信息传SAP入库
        log.info("Received work order request: {}", in.toJSONString());
        //转换前工单formOrder，转换后工单toOrder，料号 materialSpecname，批次 charge
        //先判断Array里面的批次和料号库存是否都存在，如果不存在不执行作业
        //将料号和批次分别放到集合里面从mybatis里面取数据和SAP过账，出库成功后更新changeOrderFlag状态为T，入库成功后更新状态为S
        List<String> materialSpecnameList = new ArrayList<>();
        List<String> chargeList = new ArrayList<>();
        String wo = "";
        for (int i = 0; i < in.size(); i++) {
            JSONObject jsonObject = in.getJSONObject(i);
            String materialSpecname = jsonObject.getString("materialSpecname");
            String charge = jsonObject.getString("charge");
            wo = jsonObject.getString("toOrder");
            materialSpecnameList.add(materialSpecname);
            chargeList.add(charge);
            if (StringUtils.isNotBlank(materialSpecname) && StringUtils.isNotBlank(charge)) {
                //判断批次和料号MDC表是否存在
                if (!checkMaterialPackingExist(materialSpecname, charge)) {
                    log.error("工单转换失败，批次和料号不存在 {} {} ", materialSpecname, charge);
                    //String占位符
                    String message = "工单转换失败，批次和料号不存在 {} {} ";

                    return AjaxResult.me().setResultObj(null).setSuccess(false).setErrorCode(500).setMessage(message);
                }
            } else {
                return AjaxResult.me().setResultObj(null).setSuccess(false).setErrorCode(500).setMessage("工单转换失败,库存不存在");
            }
        }
        //调用出库方法
        String s = materialOutByMES(materialSpecnameList, chargeList);
        //调用入库方法
        String s1 = materialIntoByMES(materialSpecnameList, chargeList,wo);
        if (StringUtils.isEmpty(s1)) {
            // 冲销
            String undo = invoiceService.cancelShipInter(s, "MES");
            if (undo == null || undo.isEmpty()) {
                throw new GlobalException("下发mes失败后冲销失败！");
            } else {
                throw new GlobalException("发送到mes失败！");
            }
        }
        String message = "工单转换成功 物料凭证 {}";
        return AjaxResult.me().setResultObj(null).setSuccess(true).setErrorCode(200).setMessage("执行成功,物料凭证 " + s1);
    }

    /**
     * 出库方法
     */
    @Transactional
    public String materialOutByMES(List<String> materialSpecnameList, List<String> chargeList) throws Exception {
        String result = "";
        //调用Mybatis方法查询当前可出库存
        List<changeOrderDto> materialPackingList = mesToWmsDao.getMaterialPackingList(materialSpecnameList, chargeList);
        //出库过账
        String undoid = toSAPService.StockOutByOrder(
                materialPackingList,
                "MES",
                "262"
        );
        //更新MDC表状态
        mesToWmsDao.updateMDCFlag(materialSpecnameList, chargeList,  "T");
        return undoid;
    }

    /**
     * 入库方法
     */
    @Transactional
    public String materialIntoByMES(List<String> materialSpecnameList, List<String> chargeList, String wo) {
        //更新工单号
        mesToWmsDao.updateWO(materialSpecnameList, chargeList,  wo);
        List<changeOrderDto> materialPackingListByRK = mesToWmsDao.getMaterialPackingListByRK(materialSpecnameList, chargeList);
        //入库过账
        String undoid = toSAPService.StockOutByOrder(
                materialPackingListByRK,
                "MES",
                "261"
        );
        mesToWmsDao.updateMDCFlag(materialSpecnameList, chargeList,  "S");
        return undoid;
    }


    /**
     * 判断MDC表是否有库存
     */
    public static boolean checkMaterialPackingExist(String materialSpecName,String charge) {
        String sql = "SELECT COUNT(1) FROM MATERIALPACKINGMDC WHERE MATERIALSPECNAME = :MATERIALSPECNAME AND CHARGE = :CHARGE";
        Map<String, Object> bindMap = new HashMap<>();
        bindMap.put("MATERIALSPECNAME", materialSpecName);
        bindMap.put("CHARGE", charge);
        List<Map<String, Object>> maps = IDMFrameServiceProxy.getSqlTemplate().queryForList(sql, bindMap);
        if (maps != null && maps.size() > 0) {
            if (maps.get(0).get("COUNT(1)") != null && Integer.parseInt(maps.get(0).get("COUNT(1)").toString()) > 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * 物料消耗接口-冲销
     * @param undoId
     * @param user
     @param payMentDate
     */
    @Override
    @Transactional
    public AjaxResult materialConsumeRequestSapcprkUndo(String undoId, String user, String payMentDate) throws Exception {

        AjaxResult result = new AjaxResult();
        List<MaterialPackingKey> materialPackingKeyList = new ArrayList<>();
        EventInfo makeEventInfo = new EventInfoUtil ().makeEventInfo("MakeUndo", user, "MakeUndo");
        String  condition="SELECT MATERIALPACKINGNAME FROM MATERIALPACKING WHERE UNDOID = :UNDOID ";
//		String[] bindSet={undoId};
        Map<String, Object> hashMap = new HashMap<String, Object> ();
        hashMap.put("UNDOID", undoId);
        //根据物料凭证找到所有的待冲销数据，更新库存状态为创建
        List<Map<String, Object>> MPlIST = IDMFrameServiceProxy.getSqlTemplate().queryForList(condition, hashMap);
        SetEventInfo setEventInfo = new SetEventInfo();
        setEventInfo.setUserColumns(hashMap);
        RemoveInfo removeInfo = new RemoveInfo();
        for (Map<String, Object> MP : MPlIST) {
            String MATERIALPACKINGNAME = MP.get("MATERIALPACKINGNAME").toString();
            hashMap.put("MATERIALPACKINGNAME", MATERIALPACKINGNAME);
            String  queryBS_MATERIALPACKINGUNDOINFO = "SELECT MATERIALPACKINGNAME, MATERIALQUANTITY FROM BS_MATERIALPACKINGUNDOINFO WHERE UNDOID =:UNDOID AND MATERIALPACKINGNAME =:MATERIALPACKINGNAME AND  LASTEVENTNAME =:LASTEVENTNAME ";
            hashMap.put("LASTEVENTNAME", "MES消耗");
            List<Map<String, Object>> bsMaterialPackingUndoInfo = IDMFrameServiceProxy.getSqlTemplate().queryForList(queryBS_MATERIALPACKINGUNDOINFO, hashMap);
            if (bsMaterialPackingUndoInfo.size() > 0){
                if (null != bsMaterialPackingUndoInfo.get(0).get("MATERIALQUANTITY")){
                    String materialQuantity = bsMaterialPackingUndoInfo.get(0).get("MATERIALQUANTITY").toString();
                    String updateMaterialPackingQtySql = " UPDATE MATERIALPACKING SET MATERIALQUANTITY = MATERIALQUANTITY + :QTY WHERE MATERIALPACKINGNAME =:MATERIALPACKINGNAME ";
                    Map<String, Object> updateMaterialPackingQtyMap = new HashMap<String, Object> ();
                    updateMaterialPackingQtyMap.put("MATERIALPACKINGNAME",MATERIALPACKINGNAME);
                    updateMaterialPackingQtyMap.put("QTY",materialQuantity);
                    IDMFrameServiceProxy.getSqlTemplate().update(updateMaterialPackingQtySql,updateMaterialPackingQtyMap);

                    //记录后续要更新凭证的条件和更新的信息
                    MaterialPackingKey materialPackingKey = new MaterialPackingKey("SDK", MATERIALPACKINGNAME);
                    materialPackingKeyList.add(materialPackingKey);
                }else {
                    throw new Exception("冲销失败，匹配到物料凭证：" + undoId + "的消耗记录中数量异常无法冲销");
                }
            }else {
                throw new Exception("冲销失败，没有匹配该物料凭证：" + undoId + "的消耗记录无法冲销");
            }

            /*
            //根据当前的数据跟新完工报告且删除入库表的数据
            String sql = "SELECT M.RECEIVEREQUESTNAME,M.RECEIVEREQUESTDETAILNAME,M.QTY FROM MATERIALPACKINGSUB M WHERE M.MATERIALPACKINGNAME = :MATERIALPACKINGNAME\r\n" +
                    "UNION \r\n" +
                    "SELECT M.RECEIVEREQUESTNAME,M.RECEIVEREQUESTDETAILNAME,M.QTY FROM MATERIALPACKINGSUBHISTORY M WHERE M.MATERIALPACKINGNAME = :MATERIALPACKINGNAME";

            List<Map<String, Object>> queryForList = IDMFrameServiceProxy.getSqlTemplate().queryForList(sql, hashMap);
            for (int i = 0; i < queryForList.size(); i++) {
                String dh = queryForList.get(i).get("RECEIVEREQUESTNAME").toString();
                hashMap.put("RECEIVEREQUESTNAME", dh);
                String hh = queryForList.get(i).get("RECEIVEREQUESTDETAILNAME").toString();
                hashMap.put("RECEIVEREQUESTDETAILNAME", hh);
//				String sl = queryForList.get(i).get("QTY").toString();
                String updateSql = "UPDATE MATERIALRECEIVEREQUESTDETAIL T  \r\n" +
                        "SET T.RECEIVEDQUANTITY = T.RECEIVEDQUANTITY - (  \r\n" +
                        "    SELECT NVL(SUM(M.QTY),0)  \r\n" +
                        "    FROM MATERIALPACKINGSUB M  \r\n" +
                        "    WHERE M.MATERIALPACKINGNAME = :MATERIALPACKINGNAME  \r\n" +
                        "      AND M.RECEIVEREQUESTNAME = T.RECEIVEREQUESTNAME  \r\n" +
                        "      AND M.RECEIVEREQUESTDETAILNAME = T.RECEIVEREQUESTDETAILNAME  \r\n" +
                        ")  \r\n" +
                        "WHERE T.RECEIVEREQUESTNAME = :RECEIVEREQUESTNAME  \r\n" +
                        "  AND T.RECEIVEREQUESTDETAILNAME = :RECEIVEREQUESTDETAILNAME";
                IDMFrameServiceProxy.getSqlTemplate().update(updateSql, hashMap);


                String updateSql2 = "UPDATE MATERIALRECEIVEREQUESTDETAIL T  \r\n" +
                        "SET T.RECEIVEDQUANTITY = T.RECEIVEDQUANTITY - (  \r\n" +
                        "    SELECT NVL(SUM(M.QTY),0)  \r\n" +
                        "    FROM MATERIALPACKINGSUBHISTORY M  \r\n" +
                        "    WHERE M.MATERIALPACKINGNAME = :MATERIALPACKINGNAME  \r\n" +
                        "      AND M.RECEIVEREQUESTNAME = T.RECEIVEREQUESTNAME  \r\n" +
                        "      AND M.RECEIVEREQUESTDETAILNAME = T.RECEIVEREQUESTDETAILNAME  \r\n" +
                        ")  \r\n" +
                        "WHERE T.RECEIVEREQUESTNAME = :RECEIVEREQUESTNAME  \r\n" +
                        "  AND T.RECEIVEREQUESTDETAILNAME = :RECEIVEREQUESTDETAILNAME";
                IDMFrameServiceProxy.getSqlTemplate().update(updateSql2, hashMap);

                String deleteSql = " DELETE FROM MATERIALPACKINGSUB T WHERE T.RECEIVEREQUESTNAME = :RECEIVEREQUESTNAME AND "
                        + "T.RECEIVEREQUESTDETAILNAME = :RECEIVEREQUESTDETAILNAME AND T.MATERIALPACKINGNAME = :MATERIALPACKINGNAME";
                IDMFrameServiceProxy.getSqlTemplate().update(deleteSql, hashMap);

                String MESsQL = " UPDATE BS_MES_SHIPPED T SET T.RECEIVE_FLAG = 'N' WHERE T.LOTNAME = :MATERIALPACKINGNAME ";
                IDMFrameServiceProxy.getSqlTemplate().update(MESsQL, hashMap);
            }
            */


            String MESsQL = " DELETE FROM BS_MES_SHIPPED T WHERE T.LOTNAME = :MATERIALPACKINGNAME ";
            IDMFrameServiceProxy.getSqlTemplate().update(MESsQL, hashMap);

            //MaterialPackingServiceProxy.getMaterialPackingService().remove(new MaterialPackingKey("SDK", MATERIALPACKINGNAME), makeEventInfo, removeInfo);
        }

        String sql = "UPDATE IF_ERPUNDO T SET T.FLAG = 'Y' WHERE  T.UNDOID = :UNDOID ";
        Map<String, Object> hashMap2 = new HashMap<String, Object> ();
        hashMap2.put("UNDOID", undoId);
        IDMFrameServiceProxy.getSqlTemplate().update(sql, hashMap2);
        String billCode = toSAPService.cancelShipInter(undoId, user, payMentDate);
        if (billCode == null) {
            throw new GlobalException("报送SAP失败,请联系IT处理！");
        }

        //将SAP返回的凭证更新到BOX信息中
        if (!materialPackingKeyList.isEmpty()){
            EventInfo eventInfo = new EventInfoUtil ().makeEventInfo("MES冲销", user, "MES冲销");
            Map<String, Object> updateUndoIdMap = new HashMap<String, Object> ();
            SetEventInfo updateUndoIdSetEventInfo = new SetEventInfo();
            updateUndoIdMap.put("unDoID", billCode);
            updateUndoIdSetEventInfo.setUserColumns(updateUndoIdMap);
            MaterialPackingServiceProxy.getMaterialPackingService().setEvent(materialPackingKeyList, eventInfo, updateUndoIdSetEventInfo);
        }
        result = AjaxResult.me().setSuccess(true).setErrorCode(200).setMessage("冲销成功").setResultObj(billCode);
        return result;
    }
}