package com.sunda.spmsoversea.service.impl;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunda.spmscommon.ResponseResult;
import com.sunda.spmscommon.feign.IFeignServiceCommon;
import com.sunda.spmscommon.utils.OAMainUtils;
import com.sunda.spmsoversea.dto.OverseaRequisitionPrintDTO;
import com.sunda.spmsoversea.dto.OverseaWhsDumpDTO;
import com.sunda.spmsoversea.dto.OverseaWhsDumpPrintDTO;
import com.sunda.spmsoversea.dto.OverseaWhsDumpQueryDTO;
import com.sunda.spmsoversea.entity.OverseaDn;
import com.sunda.spmsoversea.entity.OverseaWhsDump;
import com.sunda.spmsoversea.entity.OverseaWhsDumpDtl;
import com.sunda.spmsoversea.entity.WhsStorageInventory;
import com.sunda.spmsoversea.entity.ZOaOrgClient;
import com.sunda.spmsoversea.enums.OverseaWhsDumpEnum;
import com.sunda.spmsoversea.mapper.OverseaWhsDumpMapper;
import com.sunda.spmsoversea.service.*;
import com.sunda.spmsuser.entity.SpmsUser;
import localhost.services.RequestService.RequestServicePortTypeProxy;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import weaver.soa.workflow.request.MainTableInfo;
import weaver.soa.workflow.request.Property;
import weaver.soa.workflow.request.RequestInfo;

import java.rmi.RemoteException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.sunda.spmscommon.constant.OaConstant.BUSINESS_TYPE_OVERSEA_DUMP;
import static com.sunda.spmsoversea.constant.CommonConstant.*;
import static com.sunda.spmsoversea.constant.SapConstant.DATA_STATUS_1;
import static com.sunda.spmsoversea.constant.SapConstant.SAP_SUCCESS;
import static com.sunda.spmsoversea.constant.WhsStorageInventoryConstant.*;
import static com.sunda.spmsoversea.enums.OverseaDnEnum.DN_DELETE;
import static com.sunda.spmsoversea.enums.OverseaWhsDumpEnum.*;

/**
 * <p>
 * 海外仓转储任务表 服务实现类
 * </p>
 *
 * @author Wayne
 * @since 2021-11-02
 */
@Service
@Slf4j
public class OverseaWhsDumpServiceImpl extends ServiceImpl<OverseaWhsDumpMapper, OverseaWhsDump> implements IOverseaWhsDumpService {

    @Autowired
    IOverseaWhsDumpDtlService iOverseaWhsDumpDtlService;
    
    @Autowired
    IOverseaDnService iOverseaDnService;

    @Autowired
    IOverseaOperateLogService iOverseaOperateLogService;

    @Autowired
    IWhsStorageInventoryService iWhsStorageInventoryService;

    @Autowired
    IWhsOperateLogService iWhsOperateLogService;

    @Autowired
    IFeignServiceCommon iFeignServiceCommon;

    @Autowired
    IFormatDataToSapService iFormatDataToSapService;

    @Value("${oa.workflow.id0733}")
    String workflow0733;
    
    @Value("${oa.new.workflow.id0733}")
    String workflow0733_new;

    @Value("${oa.ipo.workflow.id0733}")
    String workflow0733_ipo;
    
    @Value("${oa.new.url}")
    String oaUrl;
    
    @Value("${zxd.sap.client}")
    private String zxdSapClient;

    @Autowired
    private IZOaOrgClientService izOaOrgClientService;

    @Override
    public ResponseResult getWhsDumpPage(OverseaWhsDumpQueryDTO overseaWhsDumpQueryDTO) {
        IPage<Map<String, Object>> iPage = overseaWhsDumpQueryDTO.getPage();
        iPage.setRecords(this.baseMapper.getWhsDumpPage(iPage, overseaWhsDumpQueryDTO));
        return ResponseResult.success().add("overseaWhsDumpList", iPage);
    }

    public OverseaWhsDump getOverseaWhsDump(String whsDumpUuid){
        QueryWrapper<OverseaWhsDump> queryWrapper = new QueryWrapper<OverseaWhsDump>().eq("WHS_DUMP_UUID", whsDumpUuid);
        return this.baseMapper.selectOne(queryWrapper);
    }

    @Override
    public List<Map<String, Object>> getWhsDumpDtls(String whsDumpUuid) {
        return iOverseaWhsDumpDtlService.getWhsDumpDtlList(whsDumpUuid);
    }

    @Override
    public List<Map<String, Object>> getWhsDumpDtlListExcel(String whsDumpUuid) {
        return iOverseaWhsDumpDtlService.getWhsDumpDtlListExcel(whsDumpUuid);
    }

    /**
     海外SPMS转储单据状态:0删除；1草稿；2待审批；3SPMS审批通过(提交OA);4OA驳回(操作同1);5OA审批通过(出库中);6出库完成;
     7提交SAP获取PO失败;8提交SAP获取PO;9提交SAP获取DN失败;10提交SAP获取DN成功(扣转出方库存);11转出已撤销(撤到状态5出库中，SAP撤回成功则加回库存);
     新建固定值：采购组240，采购组织1000，凭证类型传值公司内ZU01，公司间ZC01；
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized ResponseResult createWhsDump(OverseaWhsDumpDTO overseaWhsDumpDTO, String userId, SpmsUser spmsUser, boolean newOa)throws Exception  {
        ResponseResult checkResult = checkCreate(overseaWhsDumpDTO);
        if (checkResult.getCode() != SUCCESS){
            return checkResult;
        }
        String whsDumpUuid = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
        String spmsStatus = overseaWhsDumpDTO.getSpmsStatus();
        QueryWrapper<OverseaWhsDump> queryWrapper = new QueryWrapper<OverseaWhsDump>().eq("WHS_DUMP_UUID", whsDumpUuid);
        /** 创建转储任务日志 */
        iOverseaOperateLogService.addOverseaOperateLog(userId, whsDumpUuid, WHS_DUMP_CANCEL_CREATE.getDescZh(), WHS_DUMP_CANCEL_CREATE.getDescEn(), "", WHS_DUMP_CANCEL_CREATE.getDescRu());
        /** 创建转储任务表头 */
        int createDumpResult = createOverseaWhsDump(whsDumpUuid, overseaWhsDumpDTO, userId);
        if (createDumpResult < 1){
            throw new RuntimeException("创建转储任务表头错误");
        }
        /** 创建转储任务明细 */
        int createDumpDtlResult = createOverseaWhsDumpDtl(whsDumpUuid, overseaWhsDumpDTO);
        if (createDumpDtlResult < 1){
            throw new RuntimeException("创建转储任务行项目错误");
        }
        /** spmsStatus = 3 时创建转储任务申请直接提交OA，返回结果 > 0 表示提交成功的OA单据号 */
        // 增加是否需要OA审批ApproveFlag，0-否，1-是，不需要OA审批时直接到OA审批通过状态 2022-07-19 xzp add
        if (WHS_DUMP_SUBMIT_OA.getCode().equals(spmsStatus) && !"0".equals(overseaWhsDumpDTO.getApproveFlag())){
            int oaBianhao = whsDumpSubmitOa(whsDumpUuid, overseaWhsDumpDTO.getSubmitOaDate(), spmsUser,newOa);
            OverseaWhsDump overseaWhsDump = getOverseaWhsDump(whsDumpUuid);
            if (oaBianhao > 0){
                //iOverseaOperateLogService.addOverseaOperateLog(userId, whsDumpUuid, WHS_DUMP_SUBMIT_OA.getDescZh(), WHS_DUMP_SUBMIT_OA.getDescEn(), "");
                overseaWhsDump.setOaWorkflow("0733");
                overseaWhsDump.setSpmsStatus(WHS_DUMP_SUBMIT_OA.getCode());
                overseaWhsDump.setSubmitOaDate(overseaWhsDumpDTO.getSubmitOaDate());
                overseaWhsDump.setOaBianhao(String.valueOf(oaBianhao));
                List<ZOaOrgClient> selectList = izOaOrgClientService.getByWerks(overseaWhsDump.getWerksDumpOut());
                String oaClient = "OA";
                if (CollectionUtils.isNotEmpty(selectList)) {
                    String oaUl =  selectList.get(0).getOa();
                    if(oaUl.contains("fm-oa")  || oaUl.contains("oa-ipo")){
                        oaClient = "FM-OA";
                    }
                } else {
                    throw new RuntimeException("工厂："+overseaWhsDump.getWerksDumpOut()+"未找到对应的OA服务");
                }
                overseaWhsDump.setOaClient(oaClient);
                this.baseMapper.update(overseaWhsDump, queryWrapper);

                return ResponseResult.success("转储任务提交OA成功")
                        .add("overseaWhsDump", getOverseaWhsDump(whsDumpUuid))
                        .add("overseaWhsDumpDtls", getWhsDumpDtls(whsDumpUuid))
                        .add("oaBianhao", oaBianhao);
            } else {
                //iOverseaOperateLogService.addOverseaOperateLog(userId, whsDumpUuid, WHS_DUMP_SUBMIT_OA_ERROR.getDescZh(), WHS_DUMP_SUBMIT_OA_ERROR.getDescEn(), "");
                overseaWhsDump.setOaWorkflow("0733");
                overseaWhsDump.setSpmsStatus(WHS_DUMP_SAVE.getCode());
                overseaWhsDump.setSubmitOaDate(overseaWhsDumpDTO.getSubmitOaDate());
                this.baseMapper.update(overseaWhsDump, queryWrapper);
                return ResponseResult.error("转储任务创建成功，提交OA失败")
                        .add("overseaWhsDump", getOverseaWhsDump(whsDumpUuid))
                        .add("overseaWhsDumpDtls", getWhsDumpDtls(whsDumpUuid))
                        .add("oaBianhao", oaBianhao);
            }
        } else if (WHS_DUMP_SUBMIT_OA.getCode().equals(spmsStatus) && "0".equals(overseaWhsDumpDTO.getApproveFlag())) {
        	OverseaWhsDump overseaWhsDump = getOverseaWhsDump(whsDumpUuid);
            overseaWhsDump.setSpmsStatus(WHS_DUMP_OA_APPROVE.getCode());
            this.baseMapper.update(overseaWhsDump, queryWrapper);
            return ResponseResult.success("转储任务提交OA成功")
                    .add("overseaWhsDump", getOverseaWhsDump(whsDumpUuid))
                    .add("overseaWhsDumpDtls", getWhsDumpDtls(whsDumpUuid));
        } else {
            return ResponseResult.success("转储任务创建成功")
                    .add("overseaWhsDump", getOverseaWhsDump(whsDumpUuid))
                    .add("overseaWhsDumpDtls", getWhsDumpDtls(whsDumpUuid));
        }
    }

    int createOverseaWhsDump(String whsDumpUuid, OverseaWhsDumpDTO overseaWhsDumpDTO, String userId){
        OverseaWhsDump overseaWhsDump = new OverseaWhsDump();
        overseaWhsDump.setWhsDumpUuid(whsDumpUuid);
        overseaWhsDump.setWerksDumpIn(overseaWhsDumpDTO.getWerksDumpIn());
        overseaWhsDump.setWhsLocationCodeDumpIn(overseaWhsDumpDTO.getWhsLocationCodeDumpIn());
        overseaWhsDump.setWerksDumpOut(overseaWhsDumpDTO.getWerksDumpOut());
        overseaWhsDump.setWhsLocationCodeDumpOut(overseaWhsDumpDTO.getWhsLocationCodeDumpOut());
        overseaWhsDump.setCreateDate(overseaWhsDumpDTO.getCreateDate());
        overseaWhsDump.setSpmsStatus(WHS_DUMP_SAVE.getCode());
        overseaWhsDump.setOaRemark(overseaWhsDumpDTO.getOaRemark());
        overseaWhsDump.setDeliveryDate(overseaWhsDumpDTO.getDeliveryDate());
        overseaWhsDump.setVoucherType(overseaWhsDumpDTO.getVoucherType());
        overseaWhsDump.setPurchaseGroup(overseaWhsDumpDTO.getPurchaseGroup());
        overseaWhsDump.setPurchaseOrg(overseaWhsDumpDTO.getPurchaseOrg());
        overseaWhsDump.setCreateUserid(userId);
        overseaWhsDump.setApproveFlag(overseaWhsDumpDTO.getApproveFlag());
        overseaWhsDump.setTransnational(overseaWhsDumpDTO.getTransnational());
        overseaWhsDump.setTransportType(overseaWhsDumpDTO.getTransportType());
        return this.baseMapper.insert(overseaWhsDump);
    }

    int createOverseaWhsDumpDtl(String whsDumpUuid, OverseaWhsDumpDTO overseaWhsDumpDTO){
        List<OverseaWhsDumpDtl> dtlList = overseaWhsDumpDTO.getOverseaWhsDumpDtlList();
        int createResult = 0;
        for (int i = 0; i < dtlList.size(); i ++){
            OverseaWhsDumpDtl dtl = dtlList.get(i);
            OverseaWhsDumpDtl overseaWhsDumpDtl = new OverseaWhsDumpDtl();
            overseaWhsDumpDtl.setWhsDumpUuid(whsDumpUuid);
            overseaWhsDumpDtl.setItem((i + 1) * 10);
            overseaWhsDumpDtl.setMaterialNo(dtl.getMaterialNo());
            overseaWhsDumpDtl.setBasicUnit(dtl.getBasicUnit());
            overseaWhsDumpDtl.setUnitSales(dtl.getUnitSales());
            overseaWhsDumpDtl.setApplyQtyBasicUnit(dtl.getApplyQtyBasicUnit() == null ? 0.0 : dtl.getApplyQtyBasicUnit());
            overseaWhsDumpDtl.setApplyQtyUnitSales(dtl.getApplyQtyUnitSales() == null ? 0.0 : dtl.getApplyQtyUnitSales());
            overseaWhsDumpDtl.setApplyRemark(dtl.getApplyRemark());
            overseaWhsDumpDtl.setActualQtyBasicUnit(0.0);
            overseaWhsDumpDtl.setActualQtyUnitSales(0.0);
            if (iOverseaWhsDumpDtlService.save(overseaWhsDumpDtl)){
                createResult += 1;
            }
        }
        return createResult;
    }

    int whsDumpSubmitOa(String whsDumpUuid, String submitOaDate, SpmsUser spmsUser, boolean newOa){
        QueryWrapper<OverseaWhsDump> queryWrapper = new QueryWrapper<OverseaWhsDump>().eq("WHS_DUMP_UUID", whsDumpUuid);
        OverseaWhsDump overseaWhsDump = this.baseMapper.selectOne(queryWrapper);
        String spmsStatus = overseaWhsDump.getSpmsStatus();

        RequestServicePortTypeProxy wfproxy = new RequestServicePortTypeProxy();
        try {
            RequestInfo reqinfo = new RequestInfo();
            reqinfo.setCreatorid(spmsUser.getWorkId()); // OAID 提交人
            reqinfo.setWorkflowid(workflow0733);// workflowid 为测试系统ID
            reqinfo.setRequestlevel("0");// 紧急程度 默认
            reqinfo.setRemindtype("0"); // 默认
            reqinfo.setIsNextFlow("1"); // 默认
            reqinfo.setDescription("海外仓转储申请单号" + overseaWhsDump.getWhsDumpNo() + "审批"); // 自定义

            Map<String, Object> mapHead = new HashMap<>();
            mapHead.put("sdnumber", "");
            mapHead.put("sdworkcode", spmsUser.getUserId());
            mapHead.put("sddate", submitOaDate);
            mapHead.put("sdapplicant", spmsUser.getWorkId());
            mapHead.put("sddepartment", spmsUser.getDeptId() == null  ? "" : spmsUser.getDeptId());
            mapHead.put("sdjobtitle", spmsUser.getPositionId() == null  ? "" : spmsUser.getPositionId());
            mapHead.put("sdsub", spmsUser.getCompany() == null ? "" : spmsUser.getCompany());
            mapHead.put("sdpoint", spmsUser.getBranchPoint() == null ? "" : spmsUser.getBranchPoint());
            mapHead.put("sdline", spmsUser.getBranchLine() == null ? "" : spmsUser.getBranchLine());
            mapHead.put("sdexplain", "");
            mapHead.put("sddumptasklistno", overseaWhsDump.getWhsDumpNo());
            mapHead.put("sdInfactory", overseaWhsDump.getWerksDumpIn());
            mapHead.put("sdexfactory", overseaWhsDump.getWerksDumpOut());
            mapHead.put("sdinwarehouse", overseaWhsDump.getWhsLocationCodeDumpIn());
            mapHead.put("sdexwarehouse", overseaWhsDump.getWhsLocationCodeDumpOut());
            mapHead.put("sdseason", overseaWhsDump.getOaRemark() == null ? "" : overseaWhsDump.getOaRemark());
            mapHead.put("sdneeddate", overseaWhsDump.getDeliveryDate());
            mapHead.put("sdexremark", overseaWhsDump.getDumpOutRemark() == null ? "" : overseaWhsDump.getDumpOutRemark());
            mapHead.put("spmsordernum", overseaWhsDump.getWhsDumpNo());
            mapHead.put("businessType", BUSINESS_TYPE_OVERSEA_DUMP);

            MainTableInfo wmi = new MainTableInfo();
            Property[] wrti = new Property[mapHead.size()];
            int i = 0;
            for (Map.Entry<String, Object> entry : mapHead.entrySet()){
                wrti[i] = new Property();
                wrti[i].setName(entry.getKey());
                wrti[i].setValue(entry.getValue() == null ? "" : entry.getValue().toString());
                i ++;
            }
            wmi.setProperty(wrti);
            reqinfo.setMainTableInfo(wmi);
            log.info("==========海外转储申请提交OA reqinfo==========\n" + JSON.toJSONString(reqinfo));

            int reqid = 0;
            if(newOa){
                Map<String, Object> rl = new HashMap<String, Object>();
                rl.put("requestName", "海外仓转储申请单号" + overseaWhsDump.getWhsDumpNo() + "审批");
                // 根据工厂查询对应的OA Clinet
                String oaUl = oaUrl;
                List<ZOaOrgClient> selectList = izOaOrgClientService.getByWerks(overseaWhsDump.getWerksDumpOut());
                if (CollectionUtils.isNotEmpty(selectList)) {
                    oaUl =  selectList.get(0).getOa();
                    if(oaUl.contains("fm-oa")  || oaUl.contains("oa-ipo")){
                        rl.put("workflowId", workflow0733_ipo);
                    }else{
                        rl.put("workflowId", workflow0733_new);
                    }
                } else {
                    throw new RuntimeException("工厂："+overseaWhsDump.getWerksDumpOut()+"未找到对应的OA服务");
                }
                rl.put("requestlevel", "0");// 紧急程度 默认
                rl.put("remindtype", "0");
                rl.put("isNextFlow", "1");
                rl.put("description","海外仓转储申请单号" + overseaWhsDump.getWhsDumpNo() + "审批");

                List<Map<String, Object>> aas = new ArrayList<Map<String, Object>>();
                for (Map.Entry<String, Object> entry : mapHead.entrySet()){
                    Map<String, Object> ol = new HashMap<String, Object>();
                    ol.put("fieldName", entry.getKey());
                    ol.put("fieldValue", entry.getValue() == null ? "" : entry.getValue().toString());
                    aas.add(ol);
                }
                rl.put("mainData", JSONUtil.parseArray(aas).toString());
                String jsonParams = JSONUtil.parseObj(rl).toString();
                OAMainUtils oaMainUtils = new OAMainUtils();



                String message =  oaMainUtils.oaRestFul(oaUl, "/api/workflow/paService/doCreateRequest", rl,spmsUser.getUserId());
                JSONObject messageDoc = JSONObject.parseObject(message);
                String reqidStr = "";
                if("SUCCESS".equals(messageDoc.getString("code"))){
                    String data = messageDoc.getString("data");
                    JSONObject dataJson = JSONObject.parseObject(data);
                    reqid = Integer.parseInt(dataJson.getString("requestid"));
                }else{
                    throw new Exception("保存异常：" + messageDoc.getString("errMsg"));
                }
            }else{
                reqid = Integer.parseInt(wfproxy.createRequest(reqinfo));
            }

            log.info("==========海外转储申请提交OA审批，返回 reqid:" + reqid);
            if (reqid > 0){
                iOverseaOperateLogService.addOverseaOperateLog(spmsUser.getUserId(), whsDumpUuid, WHS_DUMP_SUBMIT_OA.getDescZh()  + ":" + String.valueOf(reqid),
                        WHS_DUMP_SUBMIT_OA.getDescEn(), oaLog, JSON.toJSONString(reqinfo), String.valueOf(reqid), "", WHS_DUMP_SUBMIT_OA.getDescRu());
            } else {
                iOverseaOperateLogService.addOverseaOperateLog(spmsUser.getUserId(), whsDumpUuid, WHS_DUMP_SUBMIT_OA_ERROR.getDescZh() + ":" + String.valueOf(reqid),
                        WHS_DUMP_SUBMIT_OA_ERROR.getDescEn(), oaLog, JSON.toJSONString(reqinfo), String.valueOf(reqid), "", WHS_DUMP_SUBMIT_OA_ERROR.getDescRu());
            }
            return reqid;
        }catch (RemoteException remoteException){
            remoteException.printStackTrace();
            log.info("=========海外转储申请提交OA连接错误=========" + remoteException.getMessage());
            return 0;
        } catch (Exception e){
            e.printStackTrace();
            log.error("========海外转储申请提交OA请求参数：" + whsDumpUuid + "\n请求提交OA异常=========\n" + e.getMessage());
            return 0;
        }
    }

    ResponseResult checkCreate(OverseaWhsDumpDTO overseaWhsDumpDTO){
        if (overseaWhsDumpDTO == null){
            return ResponseResult.error("请求参数错误");
        }
        if (StringUtils.isEmpty(overseaWhsDumpDTO.getWerksDumpIn()) || StringUtils.isEmpty(overseaWhsDumpDTO.getWhsLocationCodeDumpIn())
                || StringUtils.isEmpty(overseaWhsDumpDTO.getWerksDumpOut()) || StringUtils.isEmpty(overseaWhsDumpDTO.getWhsLocationCodeDumpOut())
                || StringUtils.isEmpty(overseaWhsDumpDTO.getCreateDate()) || StringUtils.isEmpty(overseaWhsDumpDTO.getSpmsStatus())
                || StringUtils.isEmpty(overseaWhsDumpDTO.getDeliveryDate())){
            return ResponseResult.error("请求参数错误");
        }
        String spmsStatus = overseaWhsDumpDTO.getSpmsStatus();
        if (WHS_DUMP_SUBMIT_OA.getCode().equals(spmsStatus) && StringUtils.isEmpty(overseaWhsDumpDTO.getSubmitOaDate())){
            return ResponseResult.error("请求参数错误");
        }
        List<OverseaWhsDumpDtl> overseaWhsDumpDtlList = overseaWhsDumpDTO.getOverseaWhsDumpDtlList();
        if (overseaWhsDumpDtlList == null || overseaWhsDumpDtlList.size() == 0){
            return ResponseResult.error("请求参数任务明细行数据不能为空");
        }
        return ResponseResult.success();
    }

    /** 转储任务关闭，状态变化为：1-0,4-0,5-0 */
    @Override
    public synchronized ResponseResult closeWhsDump(String whsDumpUuid, Integer dataVersion, String userId) {
        if (StringUtils.isEmpty(whsDumpUuid) || dataVersion == null){
            return ResponseResult.error("请求参数错误");
        }
        QueryWrapper<OverseaWhsDump> queryWrapper = new QueryWrapper<OverseaWhsDump>().eq("WHS_DUMP_UUID", whsDumpUuid);
        OverseaWhsDump overseaWhsDump = this.baseMapper.selectOne(queryWrapper);
        if (overseaWhsDump == null){
            return ResponseResult.error("请求转储任务不存在");
        }
        if (!dataVersion.equals(overseaWhsDump.getDataVersion())){
            return ResponseResult.error("请求转储任务已更新请刷新后重试");
        }
        String spmsStatus = overseaWhsDump.getSpmsStatus();
        if (!WHS_DUMP_SAVE.getCode().equals(spmsStatus)
                && !WHS_DUMP_OA_REJECT.getCode().equals(spmsStatus)
                && !WHS_DUMP_OA_APPROVE.getCode().equals(spmsStatus)){
            return ResponseResult.error("转储任务当前状态禁止此操作");
        }
        overseaWhsDump.setSpmsStatus(WHS_DUMP_DELETE.getCode());
        this.baseMapper.update(overseaWhsDump, queryWrapper);
        iOverseaOperateLogService.addOverseaOperateLog(userId, whsDumpUuid, WHS_DUMP_DELETE.getDescZh(), WHS_DUMP_DELETE.getDescEn(), "", WHS_DUMP_DELETE.getDescRu());
        return ResponseResult.success("转储任务已删除");
    }

    /** 转储任务新增行项目 */
    @Override
    public synchronized ResponseResult addOverseaWhsDumpDtls(List<OverseaWhsDumpDtl> dumpDtls, String userId) {
        if (dumpDtls == null || dumpDtls.size() == 0){
            return ResponseResult.error("请求参数错误");
        }
        String whsDumpUuid = dumpDtls.get(0).getWhsDumpUuid();
        OverseaWhsDump overseaWhsDump = getOverseaWhsDump(whsDumpUuid);
        if (overseaWhsDump == null){
            return ResponseResult.error("请求转储任务不存在");
        }
        Integer maxItemNumber = this.baseMapper.getWhsDumpMaxItemNumber(whsDumpUuid);
        for (int i = 0; i < dumpDtls.size(); i ++){
            OverseaWhsDumpDtl overseaWhsDumpDtl = new OverseaWhsDumpDtl();
            OverseaWhsDumpDtl dumpDtl = dumpDtls.get(i);
            overseaWhsDumpDtl.setWhsDumpUuid(dumpDtl.getWhsDumpUuid());
            overseaWhsDumpDtl.setItem((i + 1) * 10 + maxItemNumber);
            overseaWhsDumpDtl.setMaterialNo(dumpDtl.getMaterialNo());
            overseaWhsDumpDtl.setBasicUnit(dumpDtl.getBasicUnit());
            overseaWhsDumpDtl.setUnitSales(dumpDtl.getUnitSales());
            overseaWhsDumpDtl.setApplyQtyBasicUnit(dumpDtl.getApplyQtyBasicUnit() == null ? 0.0 : dumpDtl.getApplyQtyBasicUnit());
            overseaWhsDumpDtl.setApplyQtyUnitSales(dumpDtl.getApplyQtyUnitSales() == null ? 0.0 : dumpDtl.getApplyQtyUnitSales());
            overseaWhsDumpDtl.setApplyRemark(dumpDtl.getApplyRemark());
            overseaWhsDumpDtl.setActualQtyBasicUnit(0.0);
            overseaWhsDumpDtl.setActualQtyUnitSales(0.0);
            iOverseaWhsDumpDtlService.save(overseaWhsDumpDtl);
        }
        iOverseaOperateLogService.addOverseaOperateLog(userId, whsDumpUuid, WHS_DUMP_UPDATE.getDescZh(), WHS_DUMP_UPDATE.getDescEn(), "", WHS_DUMP_UPDATE.getDescRu());
        return ResponseResult.success().add("overseaWhsDumpDtls", getWhsDumpDtls(whsDumpUuid));
    }

    /** 转储任务删除行项目 */
    @Override
    public ResponseResult deleteOverseaWhsDumpDtls(List<OverseaWhsDumpDtl> dumpDtls, String userId) {
        if (dumpDtls == null || dumpDtls.size() == 0){
            return ResponseResult.error("请求参数错误");
        }
        String whsDumpUuid = "";
        for (int i = 0; i < dumpDtls.size(); i ++){
            OverseaWhsDumpDtl dumpDtl = dumpDtls.get(i);
            whsDumpUuid = dumpDtl.getWhsDumpUuid();
            Integer item = dumpDtl.getItem();
            iOverseaWhsDumpDtlService.deleteWhsDumpDtl(whsDumpUuid, item);
        }
        iOverseaOperateLogService.addOverseaOperateLog(userId, whsDumpUuid, WHS_DUMP_UPDATE.getDescZh(), WHS_DUMP_UPDATE.getDescEn(), "", WHS_DUMP_UPDATE.getDescRu());
        return ResponseResult.success().add("overseaWhsDumpDtls", getWhsDumpDtls(whsDumpUuid));
    }

    /** OA 审批通过接口 1498718, S */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult oaApproveWhsDump(String oaBianhao, String oaStatus, String userId) throws Exception  {
        SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd");
        if (StringUtils.isEmpty(oaBianhao) || StringUtils.isEmpty(oaStatus)){
            ResponseResult.error("请求参数错误");
        }
        QueryWrapper<OverseaWhsDump> queryWrapper = new QueryWrapper<OverseaWhsDump>().eq("OA_BIANHAO", oaBianhao);
        OverseaWhsDump overseaWhsDump = this.baseMapper.selectOne(queryWrapper);
        if (overseaWhsDump == null){
            return ResponseResult.error("请求转储任务不存在");
        }
        String whsDumpUuid = overseaWhsDump.getWhsDumpUuid();
        if (!WHS_DUMP_SUBMIT_OA.getCode().equals(overseaWhsDump.getSpmsStatus())){
            return ResponseResult.error("当前状态禁止此操作");
        }
        if (OA_APPROVE.equals(oaStatus)){
            overseaWhsDump.setSpmsStatus(WHS_DUMP_OA_APPROVE.getCode());
            overseaWhsDump.setOaApprovalDate(sdf.format(new Date()));
            this.baseMapper.update(overseaWhsDump, queryWrapper);
            iOverseaOperateLogService.addOverseaOperateLog(userId, whsDumpUuid, WHS_DUMP_OA_APPROVE.getDescZh(), WHS_DUMP_OA_APPROVE.getDescEn(), "", WHS_DUMP_OA_APPROVE.getDescRu());
            return ResponseResult.success("OA审批通过，SPMS更新状态成功");
        } else {
            overseaWhsDump.setSpmsStatus(WHS_DUMP_OA_REJECT.getCode());
            this.baseMapper.update(overseaWhsDump, queryWrapper);
            iOverseaOperateLogService.addOverseaOperateLog(userId, whsDumpUuid, WHS_DUMP_OA_REJECT.getDescZh(), WHS_DUMP_OA_REJECT.getDescEn(), "", WHS_DUMP_OA_REJECT.getDescRu());
            return ResponseResult.success("OA审批不通过，SPMS更新状态成功");
        }
    }

    /** 转储任务更新状态变化控制：1-1(保存), 1-3(提交OA), 4-4(驳回保存), 4-3(驳回重提), 5-6(出库完成) */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized ResponseResult updateWhsDump(OverseaWhsDumpDTO overseaWhsDumpDTO, String userId, SpmsUser spmsUser, boolean newOa)throws Exception  {
        ResponseResult checkResult = checkUpdate(overseaWhsDumpDTO);
        if (checkResult.getCode() != SUCCESS){
            return checkResult;
        }
        String whsDumpUuid = overseaWhsDumpDTO.getWhsDumpUuid();
        String spmsStatus = overseaWhsDumpDTO.getSpmsStatus();
        QueryWrapper<OverseaWhsDump> queryWrapper = new QueryWrapper<OverseaWhsDump>().eq("WHS_DUMP_UUID", whsDumpUuid);
        OverseaWhsDump overseaWhsDump = this.baseMapper.selectOne(queryWrapper);
        overseaWhsDump.setSpmsStatus(spmsStatus);
        overseaWhsDump.setOaRemark(overseaWhsDumpDTO.getOaRemark());
        overseaWhsDump.setSubmitOaDate(overseaWhsDumpDTO.getSubmitOaDate());
        overseaWhsDump.setDumpOutDate(overseaWhsDumpDTO.getDumpOutDate());
        overseaWhsDump.setDumpOutRemark(overseaWhsDumpDTO.getDumpOutRemark());
        overseaWhsDump.setDeliveryDate(overseaWhsDumpDTO.getDeliveryDate());
        overseaWhsDump.setApproveFlag(overseaWhsDumpDTO.getApproveFlag());
        overseaWhsDump.setTransnational(overseaWhsDumpDTO.getTransnational());
        overseaWhsDump.setTransportType(overseaWhsDumpDTO.getTransportType());
        overseaWhsDump.setPdaSN(StringUtils.isNotEmpty(overseaWhsDumpDTO.getPdaSN()) ? overseaWhsDumpDTO.getPdaSN() : "");
        overseaWhsDump.setPdaTime(StringUtils.isNotEmpty(overseaWhsDumpDTO.getPdaTime()) ? overseaWhsDumpDTO.getPdaTime() : "");
        int updateResult = this.baseMapper.update(overseaWhsDump, queryWrapper);
        if (updateResult < 1){
            throw new RuntimeException("转储任务表头更新错误");
        }
        List<OverseaWhsDumpDtl> dtlList = overseaWhsDumpDTO.getOverseaWhsDumpDtlList();
        for (int i = 0; i < dtlList.size(); i ++){
            OverseaWhsDumpDtl dtl = dtlList.get(i);
            OverseaWhsDumpDtl overseaWhsDumpDtl = new OverseaWhsDumpDtl();
            overseaWhsDumpDtl.setWhsDumpUuid(whsDumpUuid);
            overseaWhsDumpDtl.setItem(dtl.getItem());
            overseaWhsDumpDtl.setApplyQtyBasicUnit(dtl.getApplyQtyBasicUnit() == null ? 0.0 : dtl.getApplyQtyBasicUnit());
            overseaWhsDumpDtl.setApplyQtyUnitSales(dtl.getApplyQtyUnitSales() == null ? 0.0 : dtl.getApplyQtyUnitSales());
            overseaWhsDumpDtl.setApplyRemark(dtl.getApplyRemark());
            overseaWhsDumpDtl.setActualQtyBasicUnit(dtl.getActualQtyBasicUnit());
            overseaWhsDumpDtl.setActualQtyUnitSales(dtl.getActualQtyUnitSales());
            overseaWhsDumpDtl.setActualStorageInfo(dtl.getActualStorageInfo());
            overseaWhsDumpDtl.setActualRemark(dtl.getActualRemark() == null ? "" : dtl.getActualRemark());
            QueryWrapper<OverseaWhsDumpDtl> dtlQueryWrapper = new QueryWrapper<OverseaWhsDumpDtl>()
                    .eq("WHS_DUMP_UUID", whsDumpUuid).eq("ITEM", dtl.getItem());
            iOverseaWhsDumpDtlService.update(overseaWhsDumpDtl, dtlQueryWrapper);
        }

        if (WHS_DUMP_SAVE.getCode().equals(spmsStatus) || WHS_DUMP_OA_REJECT.getCode().equals(spmsStatus)){
            iOverseaOperateLogService.addOverseaOperateLog(userId, whsDumpUuid, WHS_DUMP_SAVE.getDescZh(), WHS_DUMP_SAVE.getDescEn(), "", WHS_DUMP_SAVE.getDescRu());
        } else if (WHS_DUMP_DELIVERY.getCode().equals(spmsStatus)){
            iOverseaOperateLogService.addOverseaOperateLog(userId, whsDumpUuid, WHS_DUMP_DELIVERY.getDescZh(), WHS_DUMP_DELIVERY.getDescEn(), "", WHS_DUMP_DELIVERY.getDescRu());
        }

        /** spmsStatus = 3 时更新转储任务提交OA，返回结果 > 0 表示提交成功的OA单据号 */
        // 增加是否需要OA审批ApproveFlag，0-否，1-是，不需要OA审批时直接到OA审批通过状态 2022-07-19 xzp add
        if (WHS_DUMP_SUBMIT_OA.getCode().equals(spmsStatus) && !"0".equals(overseaWhsDumpDTO.getApproveFlag())){
            int oaBianhao = whsDumpSubmitOa(whsDumpUuid, overseaWhsDumpDTO.getSubmitOaDate(), spmsUser,newOa);
            OverseaWhsDump whsDump = getOverseaWhsDump(whsDumpUuid);
            if (oaBianhao > 0){
                //iOverseaOperateLogService.addOverseaOperateLog(userId, whsDumpUuid, WHS_DUMP_SUBMIT_OA.getDescZh(), WHS_DUMP_SUBMIT_OA.getDescEn(), "");
                whsDump.setOaWorkflow("0733");
                whsDump.setSpmsStatus(WHS_DUMP_SUBMIT_OA.getCode());
                whsDump.setSubmitOaDate(overseaWhsDumpDTO.getSubmitOaDate());
                whsDump.setOaBianhao(String.valueOf(oaBianhao));
                List<ZOaOrgClient> selectList = izOaOrgClientService.getByWerks(whsDump.getWerksDumpOut());
                String oaClient = "OA";
                if (CollectionUtils.isNotEmpty(selectList)) {
                    String oaUl =  selectList.get(0).getOa();
                    if(oaUl.contains("fm-oa")  || oaUl.contains("oa-ipo")){
                        oaClient = "FM-OA";
                    }
                } else {
                    throw new RuntimeException("工厂："+whsDump.getWerksDumpOut()+"未找到对应的OA服务");
                }
                whsDump.setOaClient(oaClient);
                this.baseMapper.update(whsDump, queryWrapper);

                return ResponseResult.success("转储任务提交OA成功")
                        .add("overseaWhsDump", getOverseaWhsDump(whsDumpUuid))
                        .add("overseaWhsDumpDtls", getWhsDumpDtls(whsDumpUuid))
                        .add("oaBianhao", oaBianhao);
            } else {
                //iOverseaOperateLogService.addOverseaOperateLog(userId, whsDumpUuid, WHS_DUMP_SUBMIT_OA_ERROR.getDescZh(), WHS_DUMP_SUBMIT_OA_ERROR.getDescEn(), "");
                whsDump.setOaWorkflow("0733");
                whsDump.setSpmsStatus(WHS_DUMP_SAVE.getCode());
                whsDump.setSubmitOaDate(overseaWhsDumpDTO.getSubmitOaDate());
                this.baseMapper.update(whsDump, queryWrapper);
                return ResponseResult.error("转储任务更新成功，提交OA失败")
                        .add("overseaWhsDump", getOverseaWhsDump(whsDumpUuid))
                        .add("overseaWhsDumpDtls", getWhsDumpDtls(whsDumpUuid))
                        .add("oaBianhao", oaBianhao);
            }
        } else if (WHS_DUMP_SUBMIT_OA.getCode().equals(spmsStatus) && "0".equals(overseaWhsDumpDTO.getApproveFlag())) {
        	OverseaWhsDump whsDump = getOverseaWhsDump(whsDumpUuid);
            whsDump.setSpmsStatus(WHS_DUMP_OA_APPROVE.getCode());
            this.baseMapper.update(whsDump, queryWrapper);
            return ResponseResult.success("转储任务提交成功")
                    .add("overseaWhsDump", getOverseaWhsDump(whsDumpUuid))
                    .add("overseaWhsDumpDtls", getWhsDumpDtls(whsDumpUuid));
        } else {
            return ResponseResult.success("转储任务更新成功")
                    .add("overseaWhsDump", getOverseaWhsDump(whsDumpUuid))
                    .add("overseaWhsDumpDtls", getWhsDumpDtls(whsDumpUuid));
        }
    }

    /** 转储任务更新状态变化控制：1-1(保存), 1-3(提交OA), 4-4(驳回保存), 4-3(驳回重提), 5-6(出库完成) */
    ResponseResult checkUpdate(OverseaWhsDumpDTO overseaWhsDumpDTO){
        if (overseaWhsDumpDTO == null || overseaWhsDumpDTO.getOverseaWhsDumpDtlList() == null){
            return ResponseResult.error("请求参数错误");
        }
        String whsDumpUuid = overseaWhsDumpDTO.getWhsDumpUuid();
        Integer dataVersion = overseaWhsDumpDTO.getDataVersion();
        if (StringUtils.isEmpty(whsDumpUuid)){
            return ResponseResult.error("请求参数错误");
        }
        QueryWrapper<OverseaWhsDump> queryWrapper = new QueryWrapper<OverseaWhsDump>().eq("WHS_DUMP_UUID", whsDumpUuid);
        OverseaWhsDump overseaWhsDump = this.baseMapper.selectOne(queryWrapper);
        if (overseaWhsDump == null || !dataVersion.equals(overseaWhsDump.getDataVersion())){
            return ResponseResult.error("请求转储任务已更新或不存在");
        }
        String currentStatus = overseaWhsDump.getSpmsStatus();
        String targetStatus = overseaWhsDumpDTO.getSpmsStatus();
        if (!WHS_DUMP_SAVE.getCode().equals(currentStatus) && !WHS_DUMP_OA_REJECT.getCode().equals(currentStatus) &&
                !WHS_DUMP_OA_APPROVE.getCode().equals(currentStatus)){
            return ResponseResult.error("当前任务状态禁止此操作");
        }
        if (!WHS_DUMP_SAVE.getCode().equals(targetStatus) && !WHS_DUMP_SUBMIT_OA.getCode().equals(targetStatus) &&
                !WHS_DUMP_OA_REJECT.getCode().equals(targetStatus) && !WHS_DUMP_DELIVERY.getCode().equals(targetStatus) &&
                !WHS_DUMP_OA_APPROVE.getCode().equals(targetStatus)){
            return ResponseResult.error("任务目标状态禁止此操作");
        }
        return ResponseResult.success();
    }

    /** 提交SAP状态变化控制：6/7-8/7(获取PO), 8/9-10/9(获取DN), 获取到DN扣库存 */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult whsDumpToSap(String whsDumpUuid, String postingDate, Integer dataVersion, String userId) throws Exception {
        ResponseResult checkResult = checkToSap(whsDumpUuid, postingDate, dataVersion);
        if (checkResult.getCode() != SUCCESS){
            return checkResult;
        }
        QueryWrapper<OverseaWhsDump> queryWrapper = new QueryWrapper<OverseaWhsDump>().eq("WHS_DUMP_UUID", whsDumpUuid);
        OverseaWhsDump overseaWhsDump = this.baseMapper.selectOne(queryWrapper);

        String spmsStatus = overseaWhsDump.getSpmsStatus();
        overseaWhsDump.setPurchasePostingDate(postingDate);
        this.baseMapper.update(overseaWhsDump, queryWrapper);
        if (WHS_DUMP_DELIVERY.getCode().equals(spmsStatus) || WHS_DUMP_PO_ERROR.getCode().equals(spmsStatus)){
        	// 扣减库存
            String werks = overseaWhsDump.getWerksDumpOut();
            String whsLocationCode = overseaWhsDump.getWhsLocationCodeDumpOut();
            ResponseResult updateInventoryResult = updateOverseaWhsDumpInventory(whsDumpUuid, SUB, userId, "16", werks, whsLocationCode, overseaWhsDump.getMovementType(), "转储出库");
            if (updateInventoryResult.getCode() != SUCCESS){
                throw new RuntimeException("储位库存更新错误\n" + updateInventoryResult.getMsg());
            }
            iOverseaOperateLogService.addOverseaOperateLog(userId, whsDumpUuid, WHS_DUMP_INV_UPDATE.getDescZh(), WHS_DUMP_INV_UPDATE.getDescEn(), "", WHS_DUMP_INV_UPDATE.getDescRu());
        	// 调用接口ZZXD_IF_SPMS_01同步SAP
        	Map<String, Object> head = this.baseMapper.getSapPoHead(whsDumpUuid);
        	head.put("DATE_CR", postingDate.replaceAll("-", ""));
        	List<Map<String, Object>> items = this.baseMapper.getSapPoItem(whsDumpUuid);
        	JSONObject dataToSap = this.setDataToSapCreatePo(head, items);
            JSONObject message = JSONObject.parseObject(iFeignServiceCommon.sendRestToSapCommon(dataToSap));
            JSONObject RETURN_DATA = message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA");
            JSONArray T_RETURN = RETURN_DATA.getJSONArray("T_RETURN");
            if (!SAP_SUCCESS.equals(T_RETURN.getJSONObject(0).getString("TYPE"))){
//                overseaWhsDump.setSpmsStatus(WHS_DUMP_PO_ERROR.getCode());
//                this.baseMapper.update(overseaWhsDump, queryWrapper);
//                iOverseaOperateLogService.addOverseaOperateLog(userId, whsDumpUuid, WHS_DUMP_PO_ERROR.getDescZh(),
//                WHS_DUMP_PO_ERROR.getDescEn(), sapLog, dataToSap.toJSONString(), message.toJSONString(), "转储任务提交SAP获取PO");
                throw new Exception("转储任务提交SAP获取PO失败："+message);
            }
            // 调用ZZXD_IF_SPMS_01接口，SAP同步返回PO、DN单号
            overseaWhsDump.setSpmsStatus(WHS_DUMP_DN.getCode());
            overseaWhsDump.setPurchasePostingDate(postingDate);
            overseaWhsDump.setSapPurchaseNo(T_RETURN.getJSONObject(0).getString("EBELN"));
            overseaWhsDump.setOrderSapClient(T_RETURN.getJSONObject(0).getString("MANDT_PO"));
            overseaWhsDump.setSapDeliveryNote(StringUtils.isNotEmpty(T_RETURN.getJSONObject(0).getString("VBELN_VL")) ? T_RETURN.getJSONObject(0).getString("VBELN_VL") : T_RETURN.getJSONObject(0).getString("IN_VBELN_VL"));
            overseaWhsDump.setDnSapClient(StringUtils.isNotEmpty(T_RETURN.getJSONObject(0).getString("MANDT_DN")) ? T_RETURN.getJSONObject(0).getString("MANDT_DN") : T_RETURN.getJSONObject(0).getString("IN_CLIENT"));
            overseaWhsDump.setSalesOrderNumber(T_RETURN.getJSONObject(0).getString("VBELN"));
            overseaWhsDump.setSalesSapClient(T_RETURN.getJSONObject(0).getString("SO_CLIENT"));
            this.baseMapper.update(overseaWhsDump, queryWrapper);
            iOverseaOperateLogService.addOverseaOperateLog(userId, whsDumpUuid, WHS_DUMP_DN.getDescZh(),
            		WHS_DUMP_DN.getDescEn(), sapLog, dataToSap.toJSONString(), message.toJSONString(), "转储任务提交SAP获取DN成功", WHS_DUMP_DN.getDescRu());
            return ResponseResult.success("转储任务提交SAP成功")
                    .add("overseaWhsDump", getOverseaWhsDump(whsDumpUuid))
                    .add("sapReturnedMessage", message)
                    .add("dataToSap", dataToSap);
        }
        return ResponseResult.success();
    }

    private JSONObject setDataToSapCreatePo(Map<String, Object> head, List<Map<String, Object>> items) {
    	JSONObject doc = new JSONObject();
        JSONObject request = new JSONObject();
        JSONObject esbAttrs = new JSONObject();
        JSONObject requestData = new JSONObject();
        esbAttrs.put("App_ID", "SPMS");
        esbAttrs.put("Target_ID", zxdSapClient);
        esbAttrs.put("Application_ID", "00020000000002");
        esbAttrs.put("Transaction_ID", UUID.randomUUID().toString());

//        SimpleDateFormat simp = new SimpleDateFormat("yyyy:MM:ddHH:mm:ss:SS");//月日时分秒 毫秒
//        String serialNumber=simp.format(new Date()).replace(":","" );
//        headMap.put("ZID", "SPMS"+serialNumber);
        Map<String, Object> structures = new HashMap<>();
        structures.put("IS_HEAD", head);
        requestData.put("structures", structures);
        if (CollectionUtils.isNotEmpty(items)) {
        	Map<String, Object> tables = new HashMap<>();
        	tables.put("IT_ITEM", items);
        	requestData.put("tables", tables);
        }
        
        requestData.put("Operation", "ZZXD_IF_SPMS_01");
        requestData.put("Type", "ZZXD_IF_SPMS_01");
        request.put("ESB_ATTRS", esbAttrs);
        request.put("REQUEST_DATA", requestData);
        doc.put("REQUEST", request);
        return doc;
	}

	ResponseResult updateOverseaWhsDumpInventory(String whsDumpUuid, String operateType, String userId, String logType, String werks, String whsLocationCode, String movementType, String remark){
        QueryWrapper<OverseaWhsDumpDtl> dtlQueryWrapper =
                new QueryWrapper<OverseaWhsDumpDtl>().eq("WHS_DUMP_UUID", whsDumpUuid).gt("ACTUAL_QTY_BASIC_UNIT", 0);
        List<OverseaWhsDumpDtl> dumpDtlList = iOverseaWhsDumpDtlService.list(dtlQueryWrapper);
        if (dumpDtlList == null || dumpDtlList.size() == 0){
            return ResponseResult.error("出库任务明细数据查询不存在");
        }
        for (OverseaWhsDumpDtl whsDumpDtl : dumpDtlList){
            String materialNo = whsDumpDtl.getMaterialNo();
            Integer item = whsDumpDtl.getItem();
            double actualQtyBasicUnit = whsDumpDtl.getActualQtyBasicUnit();
            if (actualQtyBasicUnit > 0){
                //storageInfoArray 结构参考：[{"storageUuid":"f17e13b4d9ad4d39ba55548eff544391","qty":100,"storageNo":"C010101"}]
                JSONArray storageInfoArray = JSONArray.parseArray(whsDumpDtl.getActualStorageInfo());
                for (int i = 0; i < storageInfoArray.size(); i ++){
                    JSONObject storageInfoObj = storageInfoArray.getJSONObject(i);
                    String storageUuid = storageInfoObj.getString("storageUuid");
                    double qty = storageInfoObj.getDoubleValue("qty");
                    if (qty > 0){
                        ResponseResult updateInventory = iWhsStorageInventoryService.updateWhsStorageInventory(storageUuid, materialNo, qty, operateType);
                        if (updateInventory.getCode() != SUCCESS){
                            return updateInventory;
                        }
                        String comments = operateType.equals(ADD) ? WHS_DUMP_ADD : WHS_DUMP_SUB;
                        iWhsOperateLogService.insertWhsOperateLog(storageUuid, materialNo, qty, logType, whsDumpUuid, comments, userId, remark, werks, whsLocationCode, movementType, String.valueOf(item));
                    }
                }
            }
        }
        return ResponseResult.success();
    }

    /** 提交SAP状态变化控制：6/7-8/7(获取PO), 8/9-10/9(获取DN), 获取到DN扣库存 */
    ResponseResult checkToSap(String whsDumpUuid, String postingDate, Integer dataVersion){
        if (StringUtils.isEmpty(whsDumpUuid) || StringUtils.isEmpty(postingDate) || INVALID_DATE.equals(postingDate) || dataVersion == null){
            return ResponseResult.error("请求参数错误");
        }
        QueryWrapper<OverseaWhsDump> queryWrapper = new QueryWrapper<OverseaWhsDump>().eq("WHS_DUMP_UUID", whsDumpUuid);
        OverseaWhsDump overseaWhsDump = this.baseMapper.selectOne(queryWrapper);

        QueryWrapper<OverseaWhsDumpDtl> dtlQueryWrapper =
                new QueryWrapper<OverseaWhsDumpDtl>().eq("WHS_DUMP_UUID", whsDumpUuid).gt("ACTUAL_QTY_BASIC_UNIT", 0);
        List<OverseaWhsDumpDtl> dumpDtlList = iOverseaWhsDumpDtlService.list(dtlQueryWrapper);

        if (overseaWhsDump == null || !dataVersion.equals(overseaWhsDump.getDataVersion())){
            return ResponseResult.error("请求转储任务已更新或不存在");
        }
        if (dumpDtlList == null || dumpDtlList.size() == 0){
            return ResponseResult.error("请求转储任务明细有效行数据为空");
        }
        String spmsStatus = overseaWhsDump.getSpmsStatus();
        if (WHS_DUMP_DELIVERY.getCode().equals(spmsStatus) || WHS_DUMP_PO_ERROR.getCode().equals(spmsStatus)){
        	// 检查行物料是否足够库存进行扣减
        	ResponseResult checkInventoryResult = checkMaterialInventory(dumpDtlList);
            if (checkInventoryResult.getCode() != SUCCESS){
                return checkInventoryResult;
            }
        } else {
            return ResponseResult.error("请求任务当前状态禁止此操作");
        }
        return ResponseResult.success();
    }

    /** 扣减库存时，检查任务明细行数据每一行物料库存是否足够扣减 */
    ResponseResult checkMaterialInventory(List<OverseaWhsDumpDtl> dumpDtlList){
        for (OverseaWhsDumpDtl dtl : dumpDtlList){
            Integer item = dtl.getItem();
            String materialNo = dtl.getMaterialNo();
            String storageInfo = dtl.getActualStorageInfo();
            if (StringUtils.isEmpty(storageInfo)){
                return ResponseResult.error("实收数量大于0的行:" + item + "，料号:" + materialNo + "储位信息无效");
            }
            JSONArray storageInfoArray = JSONArray.parseArray(storageInfo);
            for (int i = 0; i < storageInfoArray.size(); i ++){
                JSONObject storageInfoObj = storageInfoArray.getJSONObject(i);
                String storageUuid = storageInfoObj.getString("storageUuid");
                double qty = storageInfoObj.getDoubleValue("qty");
                String storageNo = storageInfoObj.getString("storageNo");
                if (qty > 0){
                    WhsStorageInventory whsStorageInventory = iWhsStorageInventoryService.getWhsStorageInventory(storageUuid, materialNo);
                    if (whsStorageInventory == null){
                        return ResponseResult.error("物料号" + materialNo + "在储位" + storageNo + "无可用库存");
                    }
                    if (qty > whsStorageInventory.getAvailableQty()){
                        return ResponseResult.error("物料号" + materialNo + "在储位" + storageNo + "可用库存不足");
                    }
                }
            }
        }
        return ResponseResult.success();
    }

    /** 获取DN请求SAP结构拼接 */
    JSONObject whsDumpToSapGetDn(OverseaWhsDump overseaWhsDump, String postingDate){
        JSONObject doc = new JSONObject();
        JSONObject REQUEST = new JSONObject();
        JSONObject ESB_ATTRS = new JSONObject();
        JSONObject REQUEST_DATA = new JSONObject();
        JSONObject Head = new JSONObject();
        ESB_ATTRS.put("App_ID", "SPMS");
        ESB_ATTRS.put("Application_ID", "00020000000002");
        ESB_ATTRS.put("Transaction_ID", UUID.randomUUID().toString());

        Head.put("iFlag", "01");
        Head.put("iBudat", postingDate.replaceAll("-", ""));
        Head.put("iEbeln", StringUtils.isEmpty(overseaWhsDump.getSapPurchaseNo()) ? "" : overseaWhsDump.getSapPurchaseNo());
        Head.put("iVbeln", StringUtils.isEmpty(overseaWhsDump.getSapDeliveryNote()) ? "" : overseaWhsDump.getSapDeliveryNote());
        Head.put("iLgort", StringUtils.isEmpty(overseaWhsDump.getWhsLocationCodeDumpOut()) ? "" : overseaWhsDump.getWhsLocationCodeDumpOut());

        REQUEST_DATA.put("Head", Head);
        REQUEST_DATA.put("Operation", "Z_SPMS_DN_POST");
        REQUEST_DATA.put("Type", "DN_POST");
        REQUEST.put("ESB_ATTRS", ESB_ATTRS);
        REQUEST.put("REQUEST_DATA", REQUEST_DATA);
        doc.put("REQUEST", REQUEST);
        return doc;
    }


    JSONObject whsDumpToMDMFormat(OverseaWhsDump overseaWhsDump,List<OverseaWhsDumpDtl> dumpDtlList){
        JSONObject doc = new JSONObject();
        JSONObject REQUEST = new JSONObject();
        JSONObject ESB_ATTRS = new JSONObject();
        JSONObject REQUEST_DATA = new JSONObject();
        Map<String, Object> sendData = new HashMap<String, Object>();

//        Map<String, Object> head = new HashMap<String, Object>();
//        head.put("CREATE_DATE", overseaWhsDump.getCreateDate().replaceAll("-", ""));//转储单创建时间
//        head.put("WHS_DUMP_NO", overseaWhsDump.getWhsDumpNo());//转储申请单号
//        head.put("WERKS_DUMP_OUT", overseaWhsDump.getWerksDumpOut());//转出工厂
//        head.put("WERKS_DUMP_IN", overseaWhsDump.getWerksDumpIn());//转入工厂
//        sendData.put("HEAD", head);
//
//        Map<String, Object> data = new HashMap<String, Object>();
//        String materialNumber = dumpDtlList.stream().map(OverseaWhsDumpDtl::getMaterialNo).filter(o -> StringUtils.isNotEmpty(o))
//                .distinct().collect(Collectors.joining(","));
//        data.put("MATERIAL_NO", materialNumber);//转入工厂

        List<String> materialList = dumpDtlList.stream().map(OverseaWhsDumpDtl::getMaterialNo).filter(o -> StringUtils.isNotEmpty(o))
                .distinct().collect(Collectors.toList());
        List<Map<String, String>> mapItems = new ArrayList<Map<String, String>>();
        for (int i = 0; i < materialList.size(); i ++){
            Map<String, String> itemIn = new HashMap<String, String>();
            itemIn.put("MATNR", materialList.get(i));
            itemIn.put("WERKS", overseaWhsDump.getWerksDumpIn());

            Map<String, String> itemOut = new HashMap<String, String>();
            itemOut.put("MATNR", materialList.get(i));
            itemOut.put("WERKS", overseaWhsDump.getWerksDumpOut());

            mapItems.add(itemIn);
            mapItems.add(itemOut);
        }

        String transaction_ID = UUID.randomUUID().toString();
        sendData.put("App_ID", "SPMS");
        sendData.put("Transaction_ID", transaction_ID);
        sendData.put("MapItems", mapItems);

        REQUEST_DATA.put("SendData", sendData);
        REQUEST_DATA.put("Operation", "Z_WL_WERKS");
        REQUEST_DATA.put("Type", "Z_WL_WERKS");
        ESB_ATTRS.put("App_ID", "SPMS");
        ESB_ATTRS.put("Target_ID", "MDM");
        ESB_ATTRS.put("Application_ID", "00020000000002");
        ESB_ATTRS.put("Transaction_ID", transaction_ID);
        REQUEST.put("ESB_ATTRS", ESB_ATTRS);
        REQUEST.put("REQUEST_DATA", REQUEST_DATA);
        doc.put("REQUEST", REQUEST);
        return doc;
    }

    /**
     海外SPMS转储单据状态:
         0删除；1草稿；2待审批；3SPMS审批通过(提交OA);4OA驳回(操作同1);5OA审批通过(出库中);6出库完成;7提交SAP获取PO失败;
         8提交SAP获取PO;9提交SAP获取DN失败;10提交SAP获取DN成功(扣转出方库存);11转出已撤销(撤到状态5出库中，SAP撤回成功则加回库存);
     转储任务撤回状态变化及处理：
         2-1 更新状态; 5-1 更新状态;
         6-5 更新状态; 7-5 更新状态;
         8-5 从SAP撤回PO; 9-5 从SAP撤回PO;
         10-8,8-5 从SAP撤回DN、加回库存、从SAP撤回PO;
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult cancelWhsDump(String whsDumpUuid, String cancelPostingDate, Integer dataVersion, String userId) throws Exception {
        ResponseResult checkCancelResult = checkCancel(whsDumpUuid, cancelPostingDate, dataVersion);
        if (checkCancelResult.getCode() != SUCCESS){
            return checkCancelResult;
        }
        QueryWrapper<OverseaWhsDump> queryWrapper = new QueryWrapper<OverseaWhsDump>().eq("WHS_DUMP_UUID", whsDumpUuid);
        OverseaWhsDump overseaWhsDump = this.baseMapper.selectOne(queryWrapper);
        String spmsStatus = overseaWhsDump.getSpmsStatus();
//            String whsLocationCodeDumpOut = overseaWhsDump.getWhsLocationCodeDumpOut();
        if (WHS_DUMP_PENDING.getCode().equals(spmsStatus) || WHS_DUMP_OA_APPROVE.getCode().equals(spmsStatus)){
            overseaWhsDump.setSpmsStatus(WHS_DUMP_SAVE.getCode());
            this.baseMapper.update(overseaWhsDump, queryWrapper);
            iOverseaOperateLogService.addOverseaOperateLog(userId, whsDumpUuid, WHS_DUMP_CANCEL_TO1.getDescZh(), WHS_DUMP_CANCEL_TO1.getDescEn(), "", WHS_DUMP_CANCEL_TO1.getDescRu());
            return ResponseResult.success("撤回成功").add("overseaWhsDump", getOverseaWhsDump(whsDumpUuid));
        }
        if (WHS_DUMP_DELIVERY.getCode().equals(spmsStatus) || WHS_DUMP_PO_ERROR.getCode().equals(spmsStatus)){
            overseaWhsDump.setSpmsStatus(WHS_DUMP_OA_APPROVE.getCode());
            this.baseMapper.update(overseaWhsDump, queryWrapper);
            iOverseaOperateLogService.addOverseaOperateLog(userId, whsDumpUuid, WHS_DUMP_CANCEL_TO5.getDescZh(), WHS_DUMP_CANCEL_TO5.getDescEn(), "", WHS_DUMP_CANCEL_TO5.getDescRu());
            return ResponseResult.success("撤回成功").add("overseaWhsDump", getOverseaWhsDump(whsDumpUuid));
        }
        if (WHS_DUMP_DN.getCode().equals(spmsStatus)){
        	// 增加库存
        	String werks = overseaWhsDump.getWerksDumpOut();
            String whsLocationCode = overseaWhsDump.getWhsLocationCodeDumpOut();
            ResponseResult cancelAddWhs = updateOverseaWhsDumpInventory(whsDumpUuid, ADD, userId, "19",
                    werks, whsLocationCode, overseaWhsDump.getMovementType(), "转储撤销入库");
            if (cancelAddWhs.getCode() != SUCCESS){
                throw new RuntimeException("储位库存更新错误\n" + cancelAddWhs.getMsg());
            }
            iOverseaOperateLogService.addOverseaOperateLog(userId, whsDumpUuid, WHS_DUMP_INV_UPDATE.getDescZh(), WHS_DUMP_INV_UPDATE.getDescEn(), "", WHS_DUMP_INV_UPDATE.getDescRu());
            // 调用接口ZZXD_IF_SPMS_12撤销同步SAP
//        	Map<String, Object> head = this.baseMapper.getSapPoHead(whsDumpUuid);
//        	head.put("LOEKZ", "X");
//        	List<Map<String, Object>> items = this.baseMapper.getSapPoItem(whsDumpUuid);
            Map<String, Object> head = new HashMap<>();
            // 单据号
            head.put("LYDJH", overseaWhsDump.getWhsDumpNo());
            // 凭证中的过账日期
            head.put("BUDAT", cancelPostingDate.replaceAll("-", ""));
            // 交货单
            head.put("VBELN", overseaWhsDump.getSapDeliveryNote());
            // 客户端
            head.put("DN_MANDT", overseaWhsDump.getDnSapClient());
        	JSONObject dataToSap = this.setCancelDataToSapCreatePo(head);
            JSONObject message = JSONObject.parseObject(iFeignServiceCommon.sendRestToSapCommon(dataToSap));
            JSONObject RETURN_DATA = message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA");
            JSONObject T_RETURN = RETURN_DATA.getJSONObject("E_DATA");
            if (!SAP_SUCCESS.equals(T_RETURN.getString("TYPE"))){
                throw new Exception("转储任务撤销DN提交SAP失败："+message);
            }
            overseaWhsDump.setSpmsStatus(WHS_DUMP_OA_APPROVE.getCode());
            overseaWhsDump.setCancelVoucherNumber(T_RETURN.getString("MBLNR"));
            overseaWhsDump.setCancelPostingDate(cancelPostingDate);
            overseaWhsDump.setCancelVoucherYear(T_RETURN.getString("MJAHR"));
            this.baseMapper.update(overseaWhsDump, queryWrapper);
            iOverseaOperateLogService.addOverseaOperateLog(userId, whsDumpUuid, WHS_DUMP_CANCEL_TO5.getDescZh(),
                    WHS_DUMP_CANCEL_TO5.getDescEn(), sapLog, dataToSap.toJSONString(), message.toJSONString(), "转储任务撤销DN提交SAP", WHS_DUMP_CANCEL_TO5.getDescRu());
            return ResponseResult.success("转储任务撤销DN提交SAP")
                    .add("overseaWhsDump", getOverseaWhsDump(whsDumpUuid))
                    .add("sapReturnedData", message)
                    .add("dataToSap", dataToSap);
            
        }
        return ResponseResult.error("请求错误");
    }

    private JSONObject setCancelDataToSapCreatePo(Map<String, Object> head) {
    	JSONObject doc = new JSONObject();
        JSONObject request = new JSONObject();
        JSONObject esbAttrs = new JSONObject();
        JSONObject requestData = new JSONObject();
        esbAttrs.put("App_ID", "SPMS");
        esbAttrs.put("Target_ID", zxdSapClient);
        esbAttrs.put("Application_ID", "00020000000002");
        esbAttrs.put("Transaction_ID", UUID.randomUUID().toString());
        Map<String, Object> structures = new HashMap<>();
        structures.put("I_DATA", head);
        requestData.put("structures", structures);
        requestData.put("Operation", "ZZXD_IF_SPMS_12");
        requestData.put("Type", "ZZXD_IF_SPMS_12");
        request.put("ESB_ATTRS", esbAttrs);
        request.put("REQUEST_DATA", requestData);
        doc.put("REQUEST", request);
        return doc;
	}

//    private JSONObject setDataToSapDelPo(Map<String, Object> headMap, List<Map<String, Object>> itemMap) {
//    	JSONObject doc = new JSONObject();
//        JSONObject request = new JSONObject();
//        JSONObject esbAttrs = new JSONObject();
//        JSONObject requestData = new JSONObject();
//        esbAttrs.put("App_ID", "SPMS");
//        esbAttrs.put("Application_ID", "00020000000002");
//        esbAttrs.put("Transaction_ID", UUID.randomUUID().toString());
//
//        SimpleDateFormat simp = new SimpleDateFormat("yyyy:MM:ddHH:mm:ss:SS");//月日时分秒 毫秒
//        String serialNumber=simp.format(new Date()).replace(":","" );
//        headMap.put("ZID", "SPMS"+serialNumber);
//
//        requestData.put("Head", headMap);
//        if (CollectionUtils.isNotEmpty(itemMap)) {
//        	requestData.put("Items", itemMap);
//        }
//        requestData.put("Operation", "Z_POS_PO_CREATE");
//        requestData.put("Type", "ZZD");
//
//        request.put("ESB_ATTRS", esbAttrs);
//        request.put("REQUEST_DATA", requestData);
//
//        doc.put("REQUEST", request);
//        return doc;
//	}

	/**
     海外SPMS转储单据状态:
     0删除；1草稿；2待审批；3SPMS审批通过(提交OA);4OA驳回(操作同1);5OA审批通过(出库中);6出库完成;7提交SAP获取PO失败;
     8提交SAP获取PO;9提交SAP获取DN失败;10提交SAP获取DN成功(扣转出方库存);11转出已撤销(撤到状态5出库中，SAP撤回成功则加回库存);
     转储任务撤回状态变化及处理：
     2-1 更新状态; 5-1 更新状态;
     6-5 更新状态; 7-5 更新状态;
     8-5 从SAP撤回PO; 9-5 从SAP撤回PO;
     10-8,8-5 从SAP撤回DN、加回库存、从SAP撤回PO;
     */
    ResponseResult checkCancel(String whsDumpUuid, String cancelPostingDate, Integer dataVersion){
        if (StringUtils.isEmpty(whsDumpUuid) || dataVersion == null){
            return ResponseResult.error("请求参数错误");
        }
        QueryWrapper<OverseaWhsDump> queryWrapper = new QueryWrapper<OverseaWhsDump>().eq("WHS_DUMP_UUID", whsDumpUuid);
        OverseaWhsDump overseaWhsDump = this.baseMapper.selectOne(queryWrapper);
        if (overseaWhsDump == null || !dataVersion.equals(overseaWhsDump.getDataVersion())){
            return ResponseResult.error("请求转储任务已更新或不存在");
        }
        String spmsStatus = overseaWhsDump.getSpmsStatus();
        if (WHS_DUMP_PENDING.getCode().equals(spmsStatus) || WHS_DUMP_OA_APPROVE.getCode().equals(spmsStatus)){

        } else if (WHS_DUMP_DELIVERY.getCode().equals(spmsStatus) || WHS_DUMP_PO_ERROR.getCode().equals(spmsStatus)){

        } else if (WHS_DUMP_DN.getCode().equals(spmsStatus) || WHS_DUMP_DN_ERROR.getCode().equals(spmsStatus)){
            if (StringUtils.isEmpty(cancelPostingDate) || INVALID_DATE.equals(cancelPostingDate)){
                return ResponseResult.error("撤销过账日期不能为空");
            }
            String po = overseaWhsDump.getSapPurchaseNo();
            if (StringUtils.isEmpty(po)){
                return ResponseResult.error("单据采购订单号PO为空，禁止撤销操作");
            }
            String dn = overseaWhsDump.getSapDeliveryNote();
            if (StringUtils.isEmpty(dn)){
                return ResponseResult.error("单据交货单号DN为空，禁止撤销操作");
            }
        } else {
            return ResponseResult.error("当前转储任务状态不可撤销");
        }
        return ResponseResult.success();
    }

    JSONObject dataToSapCancel(String cancelPostingDate, String sapPurchaseOrder, String sapDeliveryNote, String whsLocationCodeDumpOut){
        JSONObject obj = new JSONObject();

        JSONObject REQUEST = new JSONObject();
        JSONObject ESB_ATTRS = new JSONObject();
        JSONObject REQUEST_DATA = new JSONObject();
        JSONObject Head = new JSONObject();

        ESB_ATTRS.put("App_ID", "SPMS");
        ESB_ATTRS.put("Application_ID", "00020000000002");
        ESB_ATTRS.put("Transaction_ID", UUID.randomUUID().toString());

        Head.put("iFlag", "02");
        Head.put("iBudat", cancelPostingDate.replaceAll("-", ""));
        //Head.put("iEbeln", StringUtils.isEmpty(sapPurchaseOrder) ? "" : sapPurchaseOrder);
        Head.put("iEbeln", "");
        Head.put("iVbeln", StringUtils.isEmpty(sapDeliveryNote) ? "" : sapDeliveryNote);
        Head.put("iLgort", StringUtils.isEmpty(whsLocationCodeDumpOut) ? "" : whsLocationCodeDumpOut);

        REQUEST_DATA.put("Head", Head);
        REQUEST_DATA.put("Operation", "Z_SPMS_DN_POST");
        REQUEST_DATA.put("Type", "DN_POST");

        REQUEST.put("ESB_ATTRS", ESB_ATTRS);
        REQUEST.put("REQUEST_DATA", REQUEST_DATA);
        obj.put("REQUEST", REQUEST);
        return obj;
    }
    
    @Transactional
	@Override
	public ResponseResult batchCreateDumpDtl(List<OverseaWhsDumpDtl> dumpDtls, String userId, String whsDumpUuid) {
    	if (dumpDtls == null || dumpDtls.size() == 0){
            return ResponseResult.error("请求参数错误");
        }
        OverseaWhsDump overseaWhsDump = getOverseaWhsDump(whsDumpUuid);
        if (overseaWhsDump == null){
            return ResponseResult.error("请求转储任务不存在");
        }
        Integer maxItemNumber = this.baseMapper.getWhsDumpMaxItemNumber(whsDumpUuid);
        for (int i = 0; i < dumpDtls.size(); i ++){
            OverseaWhsDumpDtl overseaWhsDumpDtl = new OverseaWhsDumpDtl();
            OverseaWhsDumpDtl dumpDtl = dumpDtls.get(i);
            overseaWhsDumpDtl.setWhsDumpUuid(whsDumpUuid);
            overseaWhsDumpDtl.setItem((i + 1) * 10 + maxItemNumber);
            overseaWhsDumpDtl.setMaterialNo(dumpDtl.getMaterialNo());
            overseaWhsDumpDtl.setBasicUnit(dumpDtl.getBasicUnit());
            overseaWhsDumpDtl.setUnitSales(dumpDtl.getUnitSales());
            overseaWhsDumpDtl.setApplyQtyBasicUnit(dumpDtl.getApplyQtyBasicUnit() == null ? 0.0 : dumpDtl.getApplyQtyBasicUnit());
            overseaWhsDumpDtl.setApplyQtyUnitSales(dumpDtl.getApplyQtyUnitSales() == null ? 0.0 : dumpDtl.getApplyQtyUnitSales());
            overseaWhsDumpDtl.setApplyRemark(dumpDtl.getApplyRemark());
            overseaWhsDumpDtl.setActualQtyBasicUnit(0.0);
            overseaWhsDumpDtl.setActualQtyUnitSales(0.0);
            iOverseaWhsDumpDtlService.save(overseaWhsDumpDtl);
        }
        iOverseaOperateLogService.addOverseaOperateLog(userId, whsDumpUuid, WHS_DUMP_UPDATE.getDescZh(), WHS_DUMP_UPDATE.getDescEn(), "", WHS_DUMP_UPDATE.getDescRu());
        return ResponseResult.success();
	}

	@Override
	public ResponseResult getOverseaWhsDumpHead(String spmsId) {
		if (StringUtils.isEmpty(spmsId)) {
			ResponseResult.error("SPMS单号为空，请求失败");
		}
		// 查询转储单头信息
		QueryWrapper<OverseaWhsDump> queryWrapper = new QueryWrapper<OverseaWhsDump>().eq("WHS_DUMP_NO", spmsId);
        OverseaWhsDump headVO = this.baseMapper.selectOne(queryWrapper);
        // 查询行项目信息
        List<Map<String, Object>> dtlList = iOverseaWhsDumpDtlService.getWhsDumpDtlList(headVO != null ? headVO.getWhsDumpUuid() : "");
		return ResponseResult.success().add("headVO", headVO).add("itemList", dtlList);
	}

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult whsDumpToMdM(String whsDumpUuid,String userId) throws Exception {
        QueryWrapper<OverseaWhsDump> queryWrapper = new QueryWrapper<OverseaWhsDump>().eq("WHS_DUMP_UUID", whsDumpUuid);
        OverseaWhsDump overseaWhsDump = this.baseMapper.selectOne(queryWrapper);

        QueryWrapper<OverseaWhsDumpDtl> dtlQueryWrapper =
                new QueryWrapper<OverseaWhsDumpDtl>().eq("WHS_DUMP_UUID", whsDumpUuid).gt("ACTUAL_QTY_BASIC_UNIT", 0);

        List<OverseaWhsDumpDtl> dumpDtlList = iOverseaWhsDumpDtlService.list(dtlQueryWrapper);
        // 根据物料编码分组去重
        ArrayList<OverseaWhsDumpDtl> dumpDtlListGroup = dumpDtlList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getMaterialNo()))), ArrayList::new));

        JSONObject dataToSap = new JSONObject();
        dataToSap = whsDumpToMDMFormat(overseaWhsDump,dumpDtlListGroup);
        log.info("=======dataToSap get whsDumpToMDMFormat=========\n" + dataToSap);
        JSONObject message = JSONObject.parseObject(iFeignServiceCommon.sendRestToSapCommon(dataToSap));
        log.info("=======message get whsDumpToMDMFormat=========\n" + message);

//        if (!SAP_SUCCESS.equals(message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA").getString("O_TYPE"))){
//            iOverseaOperateLogService.addOverseaOperateLog(userId, whsDumpUuid, WHS_DUMP_MDM_ERROR.getDescZh(),
//                    WHS_DUMP_MDM_ERROR.getDescEn(), sapLog, dataToSap.toJSONString(), message.toJSONString(), "转储任务详情推送工厂与物料到MDM");
//            return ResponseResult.error("转储任务推送工厂与物料到MDM失败")
//                    .add("sapReturnedData", message)
//                    .add("dataToSap", dataToSap);
//        }
        iOverseaOperateLogService.addOverseaOperateLog(userId, whsDumpUuid, WHS_DUMP_MDM.getDescZh(),
                WHS_DUMP_MDM.getDescEn(), sapLog, dataToSap.toJSONString(), message.toJSONString(), "转储任务详情推送工厂与物料到MDM", WHS_DUMP_MDM.getDescRu());

        return ResponseResult.success("转储任务详情推送工厂与物料到MDM成功")
                .add("sapReturnedMessage", message);

    }

	@Override
	@Transactional(rollbackFor = Exception.class)
	public ResponseResult deleteWhsDumpToSap(String whsDumpNo, String userId) throws Exception {
		if (StringUtils.isEmpty(whsDumpNo)) {
			return ResponseResult.error("转储单号为空，请求失败");
		}
		// 查询转储单信息
		QueryWrapper<OverseaWhsDump> queryWrapper = new QueryWrapper<OverseaWhsDump>().eq("WHS_DUMP_NO", whsDumpNo);
        OverseaWhsDump overseaWhsDump = this.baseMapper.selectOne(queryWrapper);
        if (overseaWhsDump == null) {
        	return ResponseResult.error("输入的转储单号不存在，请求失败");
        }
        if (StringUtils.isEmpty(overseaWhsDump.getSapPurchaseNo()) || "10".equals(overseaWhsDump.getSpmsStatus()) || "0".equals(overseaWhsDump.getSpmsStatus())) {
        	return ResponseResult.error("转储单的状态是已完成或已作废或采购订单是空的，请求失败");
        }
        // 调用接口ZZXD_IF_SPMS_14同步SAP
        JSONObject doc = new JSONObject();
        JSONObject request = new JSONObject();
        JSONObject esbAttrs = new JSONObject();
        JSONObject requestData = new JSONObject();
        esbAttrs.put("App_ID", "SPMS");
        esbAttrs.put("Target_ID", zxdSapClient);
        esbAttrs.put("Application_ID", "00020000000002");
        esbAttrs.put("Transaction_ID", UUID.randomUUID().toString());
        Map<String, Object> fileds = new HashMap<>();
        fileds.put("I_ZZID", whsDumpNo);
        fileds.put("I_SYSID", "SPMS");
        requestData.put("fileds", fileds);
        requestData.put("Operation", "ZZXD_IF_SPMS_14");
        requestData.put("Type", "ZZXD_IF_SPMS_14");
        request.put("ESB_ATTRS", esbAttrs);
        request.put("REQUEST_DATA", requestData);
        doc.put("REQUEST", request);
        JSONObject message = JSONObject.parseObject(iFeignServiceCommon.sendRestToSapCommon(doc));
        JSONObject RETURN_DATA = message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA");
        JSONObject E_RETURN = RETURN_DATA.getJSONObject("E_RETURN");
        if (!SAP_SUCCESS.equals(E_RETURN.getString("TYPE"))){
            throw new Exception("转储单同步SAP删除STO&DN失败："+message);
        }
        // 根据交货单号删除其他收货待到货的单据
        QueryWrapper<OverseaDn> dnQw = new QueryWrapper<OverseaDn>().eq("SAP_DELIVERY_NOTE", overseaWhsDump.getSapDeliveryNote()).eq("SPMS_STATUS", "0");
        OverseaDn dn = new OverseaDn();
        dn.setSpmsStatus(DN_DELETE.getCode());
        dn.setDataStatus(DATA_STATUS_1);
        iOverseaDnService.update(dn, dnQw);
        QueryWrapper<OverseaDn> dnQw2 = new QueryWrapper<OverseaDn>().eq("SAP_DELIVERY_NOTE_RELA", overseaWhsDump.getSapDeliveryNote()).eq("SPMS_STATUS", "0");
        iOverseaDnService.update(dn, dnQw2);
        iOverseaOperateLogService.addOverseaOperateLog(userId, overseaWhsDump.getSapDeliveryNote(), DN_DELETE.getDescZh(), DN_DELETE.getDescEn(), "", DN_DELETE.getDescRu());
		return ResponseResult.success("转储单同步SAP删除STO&DN成功");
	}
	
	/**
	 * 转储单打印
	 * @param dsName
	 * @param datasetName
	 * @param parameters
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<OverseaWhsDumpPrintDTO> overseaDumpPrint(String dsName,String datasetName,Map<String,Object> parameters) {
		String whsDumpUuid = (String) parameters.get("whsDumpUuid");
		String language = (String) parameters.get("language");
		List<OverseaWhsDumpPrintDTO> list = new ArrayList<>();
		if (StringUtils.isEmpty(whsDumpUuid)) {
			return list;
		}
		// 查询转储单头信息
		Map<String, Object> overseaWhsDump = this.baseMapper.getOverseaWhsDump(whsDumpUuid);
        if (overseaWhsDump == null) {
        	return list;
        }
        // 查询转储申请行信息
        List<Map<String, Object>> dumpDtlList = iOverseaWhsDumpDtlService.getWhsDumpDtlList(whsDumpUuid);
        if (CollectionUtils.isNotEmpty(dumpDtlList)) {
        	for (Map<String, Object> dtl : dumpDtlList) {
        		OverseaWhsDumpPrintDTO dto = new OverseaWhsDumpPrintDTO();
        		// 转储单号
        		dto.setWhsDumpNo(overseaWhsDump.get("whsDumpNo").toString());
        		// 创建日期
        		dto.setCreateDate(overseaWhsDump.get("createDate").toString());
        		// 申请人
        		dto.setCreateUser(overseaWhsDump.get("createUsername").toString());
        		// 转出工厂
        		dto.setWerksDumpOut(overseaWhsDump.get("werksDumpOut")+"_"+overseaWhsDump.get("whsLocationCodeDumpOut"));
        		// 转入工厂
        		dto.setWerksDumpIn(overseaWhsDump.get("werksDumpIn")+"_"+overseaWhsDump.get("whsLocationCodeDumpIn"));
        		// 转储订单
        		dto.setSapPurchaseNo(overseaWhsDump.get("sapPurchaseNo").toString());
        		// 交货单
        		dto.setSapDeliveryNote(overseaWhsDump.get("sapDeliveryNote").toString());
        		// 状态
        		dto.setSpmsStatus(OverseaWhsDumpEnum.getDescByValue(overseaWhsDump.get("spmsStatus").toString(), language));
        		// 部门
        		dto.setDepatName(overseaWhsDump.get("deptName").toString());
        		// 备注
                if(overseaWhsDump.get("dumpOutRemark")!=null){
                    dto.setDumpOutRemark(overseaWhsDump.get("dumpOutRemark").toString());
                }else{
                    dto.setDumpOutRemark("");
                }
        		// 行项目
        		dto.setItem(dtl.get("item").toString());
        		// 物料编码
        		dto.setMaterialNo(dtl.get("materialNo").toString());
        		// 物料描述
        		if ("zh-CN".equals(language)) {
    				dto.setMaterialName(dtl.get("materialZhDesc") != null ? dtl.get("materialZhDesc").toString() : "");
    			} else {
    				dto.setMaterialName(dtl.get("materialEnDesc") != null ? dtl.get("materialEnDesc").toString() : "");
    			}
        		// 申请数量基本单位
        		dto.setBasicUnit(dtl.get("basicUnit").toString());
        		// 申请数量销售单位
        		dto.setUnitSales(dtl.get("unitSales").toString());
        		// 申请转出基本单位数量
        		dto.setApplyQtyBasicUnit(dtl.get("applyQtyBasicUnit") != null ? Double.valueOf(dtl.get("applyQtyBasicUnit").toString()) : 0);
        		// 申请转出销售单位数量
        		dto.setApplyQtyUnitSales(dtl.get("applyQtyUnitSales") != null ? Double.valueOf(dtl.get("applyQtyUnitSales").toString()) : 0);
        		// 实际转出基本单位数量
        		dto.setActualQtyBasicUnit(dtl.get("actualQtyBasicUnit") != null ? Double.valueOf(dtl.get("actualQtyBasicUnit").toString()) : 0);
        		// 实际转出销售单位数量
        		dto.setActualQtyUnitSales(dtl.get("actualQtyUnitSales") != null ? Double.valueOf(dtl.get("actualQtyUnitSales").toString()) : 0);
        		// 储位
        		if (dtl.get("actualStorageInfo") != null) {
        			JSONArray parseArray = JSONArray.parseArray(dtl.get("actualStorageInfo").toString());
        			if (parseArray.size() > 0) {
        				Map<String, Object> map = (Map<String, Object>) parseArray.get(0);
        				dto.setActualStorageInfo(map.get("storageNo") != null ? map.get("storageNo").toString() : "");
        			} else {
        				dto.setActualStorageInfo("");
        			}
        		} else {
        			dto.setActualStorageInfo("");
        		}
        		// 备注
        		dto.setApplyRemark(dtl.get("applyRemark") != null ? dtl.get("applyRemark").toString() : "");
        		list.add(dto);
        	}
        }
		return list;
	}

}
