package com.sunda.spmswms.service.impl;

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.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.sunda.spmscommon.Constans;
import com.sunda.spmscommon.ConstantWhsOther;
import com.sunda.spmscommon.ResponseResult;
import com.sunda.spmscommon.entity.ZSapOrgClient;
import com.sunda.spmscommon.feign.IFeignServiceCommon;
import com.sunda.spmscommon.mapper.ZSapOrgClientMapper;
import com.sunda.spmswms.entity.WhsOtherUnloadDtl;
import com.sunda.spmswms.entity.WhsOtherDtl;
import com.sunda.spmswms.entity.WhsOtherTask;
import com.sunda.spmswms.entity.WhsOtherUnload;
import com.sunda.spmswms.entity.WhsStorageInventory;
import com.sunda.spmswms.mapper.WhsOtherUnloadMapper;
import com.sunda.spmswms.service.*;
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 static com.sunda.spmscommon.Constans.SUCCESS;
import static com.sunda.spmscommon.constant.CommonConstant.WHS_OTHER_TASK_DONE;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * <p>
 * 卸货入库任务表 服务实现类
 * </p>
 *
 * @author 
 * @since 
 */
@Service
@Slf4j
public class WhsOtherUnloaderviceImpl extends ServiceImpl<WhsOtherUnloadMapper, WhsOtherUnload> implements IWhsOtherUnloadService {

    @Autowired
    WhsOtherUnloadDtlServiceImpl whsOtherDtlService;

    @Autowired
    WhsStorageInventoryServiceImpl whsStorageInventoryService;
    @Autowired
    WhsInventoryInfoServiceImpl whsInventoryInfoService;
    @Autowired
    ISapDeliveryNoteLogService iSapDeliveryNoteLogService;
    @Autowired
    IWhsOperateLogService iWhsOperateLogService;
    @Autowired
    IDataToSap iDataToSap;
    @Autowired
    IFeignServiceCommon iFeignServiceCommon;
    @Autowired
    ZSapOrgClientMapper zSapOrgClientMapper;
    
    @Value("${zxd.sap.client}")
    private String sapClient;


    /*获取任务列表
   *{
         "werks":"CN01",
         "whsLocationCode":"1011",
         "movementType":"311",
         "goodsType":"M",
         "createDate":["2021-06-18","2021-06-21"],
         "taskStatus":"1",
     }
   * */
    @Override
    public ResponseResult getWhsOtherList(JSONObject whsOFilter) {
        String werks = whsOFilter.getString("werks");
        String whsLocationCode = whsOFilter.getString("whsLocationCode");
        String movementType = whsOFilter.getString("movementType");
        String goodsType = whsOFilter.getString("goodsType");
        String taskStatus = whsOFilter.getString("taskStatus");
        int pageNo = StringUtils.isEmpty(whsOFilter.getString("pageNo")) ? 1 : whsOFilter.getInteger("pageNo");
        int pageSize = StringUtils.isEmpty(whsOFilter.getString("pageSize")) ? 20 : whsOFilter.getInteger("pageSize");

        String startDate = null, endDate = null;
        if (whsOFilter.containsKey("createDate")) {
            List<String> datePeriod = (List) whsOFilter.getJSONArray("createDate");
            if (datePeriod.size() == 2) {
                startDate = datePeriod.get(0);
                endDate = datePeriod.get(1);
            }
        }
        QueryWrapper<WhsOtherUnload> queryWrapper = new QueryWrapper<WhsOtherUnload>();
        if (StringUtils.isNotEmpty(werks)) {
            queryWrapper.eq("WERKS", werks);
        }
        if (StringUtils.isNotEmpty(whsLocationCode)) {
            queryWrapper.eq("WHS_LOCATION_CODE", whsLocationCode);
        }
        if (StringUtils.isNotEmpty(movementType)) {
            queryWrapper.eq("MOVEMENT_TYPE", movementType);
        }
        if (StringUtils.isNotEmpty(goodsType)) {
            queryWrapper.eq("GOODS_TYPE", goodsType);
        }
        if (StringUtils.isNotEmpty(taskStatus)) {
            queryWrapper.eq("TASK_STATUS", taskStatus);
        }

        if (StringUtils.isNotEmpty(startDate) && StringUtils.isNotEmpty(endDate)) {
            queryWrapper.between("CREATE_DATE", startDate, endDate);
        }
        IPage<WhsOtherUnload> iPage = new Page<>(pageNo, pageSize);
        return ResponseResult.success().add("whsOtherList", this.baseMapper.selectPage(iPage, queryWrapper.orderByDesc("CREATE_TIME")));
        //return ResponseResult.success().add("whsOtherList", this.baseMapper.selectList(queryWrapper.orderByDesc("CREATE_TIME")));
    }

    @Override
    public ResponseResult getWhsOtherWithDtl(String uuid) {
        QueryWrapper<WhsOtherUnload> queryWrapper = new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid);
        WhsOtherUnload whsOtherTask = this.baseMapper.selectOne(queryWrapper);
        if (null == whsOtherTask) {
            return ResponseResult.error("Could not find Inventory Check for uuid: " + uuid);
        }

        ResponseResult whsOtherDtlRes = whsOtherDtlService.getWhsOtherDtl(uuid);
        if (whsOtherDtlRes.getCode() != 200) {
            return whsOtherDtlRes;
        }
        return whsOtherDtlRes.add("whsOther", whsOtherTask);
    }

    /**
     * 保存WhsOther,根据uuid，有则更新，无则新建
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult onSaveWhsOther(JSONObject WhsOtherUnloadDtl, String userId) throws  Exception{
        JSONObject whsOther = WhsOtherUnloadDtl.containsKey("whsOther") ? WhsOtherUnloadDtl.getJSONObject("whsOther") : null;
        JSONArray whsOtherDtl = WhsOtherUnloadDtl.containsKey("whsOtherDtl") ? WhsOtherUnloadDtl.getJSONArray("whsOtherDtl") : null;
        if (null == whsOther || null == whsOtherDtl) {
            throw new RuntimeException("Error, whsOther and whsOtherDtl are mandatory required");
        }
        String movementType = whsOther.getString("movementType");
        String goodsType = whsOther.getString("goodsType");
        if (StringUtils.isEmpty(movementType) || StringUtils.isEmpty(goodsType)) {
            throw new RuntimeException("movementType and goodsType in whsOther are mandatory required");
        }
        ResponseResult resp = new ResponseResult();
        // 卸货入库
        if (movementType.equals(ConstantWhsOther.InHouseUnload)) {
            resp = handleInHouseUnload(whsOther, whsOtherDtl, goodsType, userId);
        }
        //领用/报废出库
//        if (movementType.equals(ConstantWhsOther.OutHouseScrap) ||
//                movementType.equals(ConstantWhsOther.SampleAcquisition) ||
//                movementType.equals(ConstantWhsOther.ToolsAcquistion) ||
//                movementType.equals(ConstantWhsOther.OtherAcquistion) ||
//                movementType.equals(ConstantWhsOther.OutHouseOEM)) {
//            resp = acquistionAndScrap(whsOther, whsOtherDtl, goodsType, userId);
//        }
        //赠品入库
//        if (movementType.equals(ConstantWhsOther.InHousePresenter)) {
//            resp = handleInHousePresenter(whsOther, whsOtherDtl, goodsType, userId);
//        }
        //串货调整
//        if (movementType.equals(ConstantWhsOther.PartAdjustment)) {
//            resp = handlePartAdjustment(whsOther, whsOtherDtl, goodsType, userId);
//        }
        // 采购入库
//        if (movementType.equals(ConstantWhsOther.PurchasingInWarehouse)) {
//            resp = handlePurchasingInWarehouse(whsOther, whsOtherDtl, goodsType, userId);
//        }

        // 仓库移仓 其它移出，其它移入
//        if (movementType.equals(ConstantWhsOther.MoveIn311)) {
//            resp = moveIn311(whsOther, whsOtherDtl, goodsType, userId);
//        }
//        if (movementType.equals(ConstantWhsOther.MoveOut311)) {
//            resp = moveOut311(whsOther, whsOtherDtl, goodsType, userId);
//        }
        /** 其它出入库 - 海运出库 */
//        if (movementType.equals(ConstantWhsOther.OutHouseByShip)) {
//            resp = OutWHZ641(whsOther, whsOtherDtl, goodsType, userId);
//        }

        /***退货出库 */
//        if(movementType.equals(ConstantWhsOther.OutHouseReturn)){
//            resp = OutHouseReturn(whsOther, whsOtherDtl, goodsType, userId);
//        }
//        if (resp.getCode() != 200) {
//            throw new RuntimeException(resp.getMsg());
//        }
        return resp;
    }

    /**
     * 移仓 -- 其它移出 MoveOut311
     */
    public ResponseResult moveOut311(JSONObject whsOther, JSONArray whsOtherDtl, String goodsType, String userId) {
        try {
            String uuid = whsOther.getString("uuid");
            String werksMoveOut = whsOther.getString("werksMoveOut");
            String whsLocationCodeMoveOut = whsOther.getString("whsLocationCodeMoveOut");
            String werksMoveIn = whsOther.getString("werksMoveIn");
            String whsLocationCodeMoveIn = whsOther.getString("whsLocationCodeMoveIn");
            String currentStatus = whsOther.getString("currentStatus");
            String targetStatus = whsOther.getString("targetStatus");
            String movementType = whsOther.getString("movementType");
            WhsOtherUnload whsOtherTask = whsOther.toJavaObject(WhsOtherUnload.class);
            // 如果uuid为空，新建
            if (StringUtils.isEmpty(uuid)) {
                uuid = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
                whsOtherTask.setUuid(uuid);
                ResponseResult dtlUpdateRes = whsOtherDtlService.updateWhsOtherDtl(uuid, whsOtherDtl);
                if (dtlUpdateRes.getCode() != 200) {
                    throw new Exception(dtlUpdateRes.getMsg());
                }
                if (StringUtils.isNotEmpty(currentStatus) && StringUtils.isNotEmpty(targetStatus) && currentStatus.equals(whsOtherTask.getTaskStatus())) {
                    whsOtherTask.setTaskStatus(targetStatus);
                }
                this.baseMapper.insert(whsOtherTask);
                iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.createDocument);
                return dtlUpdateRes.add("whsOther", this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid)));
            } else {
                if (StringUtils.isEmpty(currentStatus) || StringUtils.isEmpty(targetStatus)) {
                    throw new Exception("currentStatus and targetStatus in whsOther are mandatory required");
                }
                WhsOtherUnload currWT = this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                if (null == currWT) {
                    throw new Exception("The given WhsOtherUnload ID:" + uuid + " does not exist");
                }
                if (!currWT.getTaskStatus().equals(currentStatus)) {
                    throw new Exception("The given task status: " + currentStatus + " is not match with database");
                }
                // 保存数据
                ResponseResult dtlUpdateRes = whsOtherDtlService.updateWhsOtherDtl(uuid, whsOtherDtl);
                if (dtlUpdateRes.getCode() != 200) {
                    throw new Exception(dtlUpdateRes.getMsg());
                }

                if (targetStatus.equals(ConstantWhsOther.StatusClosed)) {
                    // 如果uuid 不为空，并且targetStatus 为 StatusClosed，首先设定status为pendingSAP
                    whsOtherTask.setTaskStatus(ConstantWhsOther.StatusPendingSAP);
                    this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                    iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.updateDocument);

                    // 检查可出库存
                    for (int i = 0; i < whsOtherDtl.size(); i++) {
                        JSONObject dtl = whsOtherDtl.getJSONObject(i);
                        double operateQty = dtl.getDouble("operateQty");
                        String materialNo = dtl.getString("materialNo");
                        if (operateQty > 0) {
                            JSONArray tempStorage = dtl.containsKey("tempStorage") ? dtl.getJSONArray("tempStorage") : null;
                            if (null == tempStorage || tempStorage.size() <= 0) {
                                throw new Exception("error for " + materialNo + ", storageOutInfo can not be null");
                            }
                            ResponseResult checkInvRes = whsStorageInventoryService.checkStorageInventory(tempStorage, materialNo);
                            if (checkInvRes.getCode() != 200) {
                                throw new Exception(checkInvRes.getMsg());
                            }
                        }
                    }

                    // 调用方法同步SAP
                    ResponseResult syncSAPRes = submitWhsOtherToSap(userId, uuid, this.baseMapper.moveOut311DataToSapHead(uuid),
                            this.baseMapper.moveOut311DataToSapItem(uuid), "Z_SPMS_ANOMALY_POST");
                    if (400 == syncSAPRes.getCode()) {
                        throw new Exception("当前状态禁止提交SAP");
                    }
//                    if (100 == syncSAPRes.getCode()) {
//                        return syncSAPRes;
//                    }


                    // 如果同步成功
                    if (syncSAPRes.getCode() == 200) {
                        // 扣减库存
                        if (goodsType.equals("M")) {
                            for (int i = 0; i < whsOtherDtl.size(); i++) {
                                JSONObject dtl = whsOtherDtl.getJSONObject(i);
                                double operateQty = dtl.getDouble("operateQty");
                                String materialNo = dtl.getString("materialNo");
                                String rowId = dtl.getString("rowId");
                                if (operateQty > 0) {
                                    JSONArray tempStorage = dtl.containsKey("tempStorage") ? dtl.getJSONArray("tempStorage") : null;
                                    if (null == tempStorage || tempStorage.size() <= 0) {
                                        throw new Exception("error for " + materialNo + ", storageInfo can not be null");
                                    }
                                    for (int k = 0; k < tempStorage.size(); k++) {
                                        JSONObject storage = tempStorage.getJSONObject(k);
                                        String storageUuid = storage.getString("storageUuid");
                                        double qty = storage.getDouble("qty");
                                        String storageNo = storage.getString("storageNo");
                                        if (StringUtils.isEmpty(storageUuid) || StringUtils.isEmpty(storageNo) || qty <= 0) {
                                            throw new Exception("error for " + materialNo + " on storage Info, storageUuid: " +
                                                    storageUuid + ",storageNo:" + storageNo +
                                                    ", qty: " + qty);
                                        }
                                        // 扣减储位库存
                                        if (whsStorageInventoryService.updateWhsStorage(storageUuid, materialNo, qty) < 0) {
                                            throw new Exception("Update Storage Inventory failed for " + materialNo + " on storage Info, storageUuid: " +
                                                    storageUuid + ",storageNo:" + storageNo +
                                                    ", qty: " + qty);
                                        }


                                        iWhsOperateLogService.insertWhsOperateLog(
                                                Constans.WhsOperateLog_DocumentType_NanShaStorageLog,
                                                storageUuid,
                                                materialNo,
                                                "",
                                                qty,
                                                Constans.WhsOperateLog_OperationType_ShelfOff,
                                                uuid,
                                                Constans.WHS_OTHER_MoveOut311,
                                                userId,
                                                "targetWarehouse:" + werksMoveIn + ":" + whsLocationCodeMoveIn,
                                                werksMoveOut,
                                                whsLocationCodeMoveOut, rowId);
                                    }
                                }
                            }
                        } else {
                            // 不支持备件货
                        }

                        //更新状态为关闭
                        whsOtherTask.setTaskStatus(ConstantWhsOther.StatusClosed);
                        this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                        iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.completedDocument);
                    } else {
                        throw new Exception(JSON.toJSONString(syncSAPRes.getData()));
                    }
                } else {
                    // 如果uuid 不为空，并且targetStatus 不为 StatusClosed，只保存
                    whsOtherTask.setTaskStatus(targetStatus);
                    this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                    iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.updateDocument);
                }
                return dtlUpdateRes.add("whsOther", this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid)));
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error(e.getMessage());
        }
    }

    /**
     * 其他移入、其他移出、报废、领用、赠品入库、成本中心入库、卸货入库 等调用SAP处理方法
     */
    @SuppressWarnings("unchecked")
	ResponseResult submitWhsOtherToSap(String userId, String whsOtherUuid, Map<String, Object> dataToSapHead, List<Map<String, Object>> dataToSapItem, String operation) {
        QueryWrapper<WhsOtherUnload> queryWrapper = new QueryWrapper<WhsOtherUnload>().eq("UUID", whsOtherUuid);
        WhsOtherUnload otherTask = this.baseMapper.selectOne(queryWrapper);
        if ("4".equals(otherTask.getTaskStatus()) || "5".equals(otherTask.getTaskStatus()) || "6".equals(otherTask.getTaskStatus())) {
            return ResponseResult.error("当前状态禁止提交", 400);
        }
        if("ZZXD_IF_SPMS_04".equals(operation)){
        	// 根据工厂获取MANDT
        	if(dataToSapItem.get(0).get("WERKS")!=null){
                // 根据工厂查询对应的SAP Clinet
                List<ZSapOrgClient> selectList = zSapOrgClientMapper.selectList(new QueryWrapper<ZSapOrgClient>().eq("WERKS", dataToSapItem.get(0).get("WERKS")));
                if (CollectionUtils.isNotEmpty(selectList)) {
                    dataToSapHead.put("MANDT_PO", selectList.get(0).getZmandt());
                } else {
                    throw new RuntimeException("工厂："+dataToSapItem.get(0).get("werks")+"未找到对应的SAP Clinet");
                }
            }
        }
        JSONObject dataToSap = iDataToSap.formatDataToSap(dataToSapHead, dataToSapItem, operation);
        log.info("======dataToSap=====" + dataToSap);
        JSONObject message = iDataToSap.submitDataToSap(dataToSap);
        log.info("======message=====" + message);
        String O_TYPE = "";
        if("ZZXD_IF_SPMS_04".equals(operation)){
            O_TYPE = message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA").getJSONArray("T_R_HEAD").getJSONObject(0).getString("TYPE");
        }else{
        	O_TYPE = message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA").getString("MSTYPE");
        }
        if ("S".equals(O_TYPE)) {
            if("ZZXD_IF_SPMS_04".equals(operation)){
                otherTask.setSapVoucherNumber(message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA").getJSONArray("T_R_HEAD").getJSONObject(0).getString("MBLNR"));
                otherTask.setSapVoucherYear(message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA").getJSONArray("T_R_HEAD").getJSONObject(0).getString("MJAHR"));
            }else{
                otherTask.setSapVoucherNumber(message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA").getString("MBLNR"));
                otherTask.setSapVoucherYear(message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA").getString("MJAHR"));
            }
            otherTask.setTaskStatus(ConstantWhsOther.StatusSapFailed);
            this.baseMapper.update(otherTask, queryWrapper);
            iSapDeliveryNoteLogService.insertSapRequestRecord(whsOtherUuid, userId, ConstantWhsOther.sendToSAP, message.toJSONString(), dataToSap.toJSONString());
            return ResponseResult.success().add("dataToSap", dataToSap).add("sapReturnedData", message);
        } else {
            otherTask.setTaskStatus(ConstantWhsOther.StatusPendingSAP);
            this.baseMapper.update(otherTask, queryWrapper);
            iSapDeliveryNoteLogService.insertSapRequestRecord(whsOtherUuid, userId, ConstantWhsOther.sendToSAPError, message.toJSONString(), dataToSap.toJSONString());
            return ResponseResult.error().add("dataToSap", dataToSap).add("sapReturnedData", message);
        }
    }

    /**
     * 仓库移仓 - 其它移入 MoveIn311
     */
    public ResponseResult moveIn311(JSONObject whsOther, JSONArray whsOtherDtl, String goodsType, String userId) {
        try {
            String uuid = whsOther.getString("uuid");
            String werksMoveOut = whsOther.getString("werksMoveOut");
            String whsLocationCodeMoveOut = whsOther.getString("whsLocationCodeMoveOut");
            String werksMoveIn = whsOther.getString("werksMoveIn");
            String whsLocationCodeMoveIn = whsOther.getString("whsLocationCodeMoveIn");
            String currentStatus = whsOther.getString("currentStatus");
            String targetStatus = whsOther.getString("targetStatus");
            WhsOtherUnload whsOtherTask = whsOther.toJavaObject(WhsOtherUnload.class);
            // 如果uuid为空，新建
            if (StringUtils.isEmpty(uuid)) {
                uuid = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
                whsOtherTask.setUuid(uuid);
                ResponseResult dtlUpdateRes = whsOtherDtlService.updateWhsOtherDtl(uuid, whsOtherDtl);
                if (dtlUpdateRes.getCode() != 200) {
                    throw new Exception(dtlUpdateRes.getMsg());
                }
                if (StringUtils.isNotEmpty(currentStatus) && StringUtils.isNotEmpty(targetStatus) && currentStatus.equals(whsOtherTask.getTaskStatus())) {
                    whsOtherTask.setTaskStatus(targetStatus);
                }
                this.baseMapper.insert(whsOtherTask);
                iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.createDocument);
                return dtlUpdateRes.add("whsOther", this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid)));
            } else {
                if (StringUtils.isEmpty(currentStatus) || StringUtils.isEmpty(targetStatus)) {
                    throw new Exception("currentStatus and targetStatus in whsOther are mandatory required");
                }
                WhsOtherUnload currWT = this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                if (null == currWT) {
                    throw new Exception("The given WhsOtherUnload ID:" + uuid + " does not exist");
                }
                if (!currWT.getTaskStatus().equals(currentStatus)) {
                    throw new Exception("The given task status: " + currentStatus + " is not match with database");
                }
                // 保存数据
                ResponseResult dtlUpdateRes = whsOtherDtlService.updateWhsOtherDtl(uuid, whsOtherDtl);
                if (dtlUpdateRes.getCode() != 200) {
                    throw new Exception(dtlUpdateRes.getMsg());
                }

                if (targetStatus.equals(ConstantWhsOther.StatusClosed)) {
                    // 如果uuid 不为空，并且targetStatus 为 StatusClosed，首先设定status为pendingSAP
                    whsOtherTask.setTaskStatus(ConstantWhsOther.StatusPendingSAP);
                    this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                    iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.updateDocument);
                    // 调用方法同步SAP
                    ResponseResult syncSAPRes = submitWhsOtherToSap(userId, uuid, this.baseMapper.moveOut311DataToSapHead(uuid),
                            this.baseMapper.moveOut311DataToSapItem(uuid), "Z_SPMS_ANOMALY_POST");
                    if (400 == syncSAPRes.getCode()) {
                        throw new Exception("当前状态禁止提交SAP");
                    }
//                    if (100 == syncSAPRes.getCode()) {
//                        return syncSAPRes;
//                    }


                    // 如果同步成功
                    if (syncSAPRes.getCode() == 200) {
                        // 增加库存
                        if (goodsType.equals("M")) {
                            for (int i = 0; i < whsOtherDtl.size(); i++) {
                                JSONObject dtl = whsOtherDtl.getJSONObject(i);
                                double operateQty = dtl.getDouble("operateQty");
                                String materialNo = dtl.getString("materialNo");
                                String rowId = dtl.getString("rowId");
                                String deliveryNoteSap = dtl.getString("deliveryNoteSap");
                                if (operateQty > 0) {
                                    JSONArray tempStorage = dtl.containsKey("tempStorage") ? dtl.getJSONArray("tempStorage") : null;
                                    if (null == tempStorage || tempStorage.size() <= 0) {
                                        throw new Exception("error for " + materialNo + ", storageInfo can not be null");
                                    }
                                    for (int k = 0; k < tempStorage.size(); k++) {
                                        JSONObject storage = tempStorage.getJSONObject(k);
                                        String storageUuid = storage.getString("storageUuid");
                                        double qty = storage.getDouble("qty");
                                        String storageNo = storage.getString("storageNo");
                                        if (StringUtils.isEmpty(storageUuid) || StringUtils.isEmpty(storageNo) || qty <= 0) {
                                            throw new Exception("error for " + materialNo + " on storage Info, storageUuid: " +
                                                    storageUuid + ",storageNo:" + storageNo +
                                                    ", qty: " + qty);
                                        }
                                        if (whsStorageInventoryService.updateWhsStorageInventoryMOld(storageUuid, materialNo, qty) < 0) {
                                            throw new Exception("Update Storage Inventory failed for " + materialNo + " on storage Info, storageUuid: " +
                                                    storageUuid + ",storageNo:" + storageNo +
                                                    ", qty: " + qty);
                                        }
                                        iWhsOperateLogService.insertWhsOperateLog(
                                                Constans.WhsOperateLog_DocumentType_NanShaStorageLog,
                                                storageUuid,
                                                materialNo,
                                                "",
                                                qty,
                                                Constans.WhsOperateLog_OperationType_ShelfOn,
                                                uuid,
                                                Constans.WHS_OTHER_MoveIn311,
                                                userId,
                                                "SourceWH:" + werksMoveOut + ":" + whsLocationCodeMoveOut,
                                                werksMoveIn,
                                                whsLocationCodeMoveIn, rowId);
                                    }
                                }
                            }
                        } else {
                            // 不支持备件货
                        }

                        //更新入库单状态为关闭
                        whsOtherTask.setTaskStatus(ConstantWhsOther.StatusClosed);
                        this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                        iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.completedDocument);
                    } else {
                        throw new Exception(JSON.toJSONString(syncSAPRes.getData()));
                    }
                } else {
                    // 如果uuid 不为空，并且targetStatus 不为 StatusClosed，只保存
                    whsOtherTask.setTaskStatus(targetStatus);
                    this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                    iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.updateDocument);
                }
                return dtlUpdateRes.add("whsOther", this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid)));
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error(e.getMessage());
        }
    }

    /**退货出库 */
    public ResponseResult OutHouseReturn(JSONObject whsOther, JSONArray whsOtherDtl, String goodsType, String userId){
        try {
            String uuid = whsOther.getString("uuid");
            String werks = whsOther.getString("werks");
            String whsLocationCode = whsOther.getString("whsLocationCode");
            String currentStatus = whsOther.getString("currentStatus");
            String targetStatus = whsOther.getString("targetStatus");
            WhsOtherUnload whsOtherTask = whsOther.toJavaObject(WhsOtherUnload.class);
            // 如果uuid为空，新建
            if (StringUtils.isEmpty(uuid)) {
                uuid = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
                whsOtherTask.setUuid(uuid);
                ResponseResult dtlUpdateRes = whsOtherDtlService.updateWhsOtherDtl(uuid, whsOtherDtl);
                if (dtlUpdateRes.getCode() != 200) {
                    throw new RuntimeException(dtlUpdateRes.getMsg());
                }
                if (StringUtils.isNotEmpty(currentStatus) && StringUtils.isNotEmpty(targetStatus) && currentStatus.equals(whsOtherTask.getTaskStatus())) {
                    whsOtherTask.setTaskStatus(targetStatus);
                }
                this.baseMapper.insert(whsOtherTask);
                iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.createDocument);
                return dtlUpdateRes.add("whsOther", this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid)));
            } else {
                if (StringUtils.isEmpty(currentStatus) || StringUtils.isEmpty(targetStatus)) {
                    throw new RuntimeException("currentStatus and targetStatus in whsOther are mandatory required");
                }
                WhsOtherUnload currWT = this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                if (null == currWT) {
                    throw new RuntimeException("The given WhsOtherUnload ID:" + uuid + " does not exist");
                }
                if (!currWT.getTaskStatus().equals(currentStatus)) {
                    throw new RuntimeException("The given task status: " + currentStatus + " is not match with database");
                }
                // 保存数据
                ResponseResult dtlUpdateRes = whsOtherDtlService.updateWhsOtherDtl(uuid, whsOtherDtl);
                if (dtlUpdateRes.getCode() != 200) {
                    throw new RuntimeException(dtlUpdateRes.getMsg());
                }

                if (targetStatus.equals(ConstantWhsOther.StatusClosed)) {
                    // 如果uuid 不为空，并且targetStatus 为 StatusClosed，首先设定status为pendingSAP
                    whsOtherTask.setTaskStatus(ConstantWhsOther.StatusPendingSAP);
                    this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                    iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.updateDocument);

                    // 检查可出库存
                    if (goodsType.equals("M")) {
                        // 贸易货
                        for (int i = 0; i < whsOtherDtl.size(); i++) {
                            JSONObject dtl = whsOtherDtl.getJSONObject(i);
                            double operateQty = dtl.getDouble("operateQty");
                            String materialNo = dtl.getString("materialNo");
                            if (operateQty > 0) {
                                JSONArray tempStorage = dtl.containsKey("tempStorage") ? dtl.getJSONArray("tempStorage") : null;
                                if (null == tempStorage || tempStorage.size() <= 0) {
                                    throw new RuntimeException("error for " + materialNo + ", storageOutInfo can not be null");
                                }
                                ResponseResult checkInvRes = whsStorageInventoryService.checkStorageInventory(tempStorage, materialNo);
                                if (checkInvRes.getCode() != 200) {
                                    throw new RuntimeException(checkInvRes.getMsg());
                                }
                            }
                        }
                    } else {
                        return ResponseResult.error("退货出库不支持备件货");
                        //备件货
                        // for (int i = 0; i < whsOtherDtl.size(); i++) {
                        //     JSONObject dtl = whsOtherDtl.getJSONObject(i);
                        //     double operateQty = dtl.getDouble("operateQty");
                        //     String boxNote = dtl.getString("boxNote");
                        //     if (operateQty > 0) {
                        //         JSONArray tempStorage = dtl.containsKey("tempStorage") ? dtl.getJSONArray("tempStorage") : null;
                        //         if (null == tempStorage || tempStorage.size() <= 0) {
                        //             throw new Exception("error for " + boxNote + ", storageInfo can not be null");
                        //         }
                        //         JSONObject storage = tempStorage.getJSONObject(0);
                        //         String storageUuid = storage.getString("storageUuid");
                        //         double qty = storage.getDouble("qty");
                        //         String storageNo = storage.getString("storageNo");
                        //         if (StringUtils.isEmpty(storageUuid) || StringUtils.isEmpty(storageNo)) {
                        //             throw new Exception("error for " + boxNote + " on storage Info, storageUuid: " +
                        //                     storageUuid + ",storageNo:" + storageNo +
                        //                     ", qty: " + qty);
                        //         }

                        //         // 检查储位库存
                        //         WhsStorageInventory whsStorageInventory = whsStorageInventoryService.getStorageBoxNote(storageUuid, boxNote);
                        //         if (null == whsStorageInventory || whsStorageInventory.getQuantity() <= 0) {
                        //             throw new Exception("error, there is no enough inventory for " + boxNote + " on storageUuid: " +
                        //                     storageUuid + ",storageNo:" + storageNo);
                        //         }
                        //     }
                        // }
                    }

                    // 调用方法同步SAP
                    ResponseResult syncSAPRes = submitWhsOtherToSap(userId, uuid, this.baseMapper.getWhsOtherTaskReturnOutHouseHead(uuid),
                            this.baseMapper.getWhsOtherTaskReturnOutHouseItem(uuid), "ZZXD_IF_SPMS_04");
                    if (400 == syncSAPRes.getCode()) {
                        throw new Exception("当前状态禁止提交SAP");
                    }
                    // 如果同步成功
                    if (syncSAPRes.getCode() == 200) {
                        String operateType = Constans.WHS_OTHER_OutHouseReturn;
                        // 扣减库存
                        if (goodsType.equals("M")) {
                            for (int i = 0; i < whsOtherDtl.size(); i++) {
                                JSONObject dtl = whsOtherDtl.getJSONObject(i);
                                double operateQty = dtl.getDouble("operateQty");
                                String materialNo = dtl.getString("materialNo");
                                String rowId = dtl.getString("rowId");
                                if (operateQty > 0) {
                                    JSONArray tempStorage = dtl.containsKey("tempStorage") ? dtl.getJSONArray("tempStorage") : null;
                                    if (null == tempStorage || tempStorage.size() <= 0) {
                                        throw new RuntimeException("error for " + materialNo + ", storageInfo can not be null");
                                    }
                                    for (int k = 0; k < tempStorage.size(); k++) {
                                        JSONObject storage = tempStorage.getJSONObject(k);
                                        String storageUuid = storage.getString("storageUuid");
                                        double qty = storage.getDouble("qty");
                                        String storageNo = storage.getString("storageNo");
                                        if (StringUtils.isEmpty(storageUuid) || StringUtils.isEmpty(storageNo) || qty <= 0) {
                                            throw new RuntimeException("error for " + materialNo + " on storage Info, storageUuid: " +
                                                    storageUuid + ",storageNo:" + storageNo +
                                                    ", qty: " + qty);
                                        }
                                        // 扣减储位库存
                                        if (whsStorageInventoryService.updateWhsStorage(storageUuid, materialNo, qty) < 0) {
                                            throw new RuntimeException("Update Storage Inventory failed for " + materialNo + " on storage Info, storageUuid: " +
                                                    storageUuid + ",storageNo:" + storageNo +
                                                    ", qty: " + qty);
                                        }


                                        iWhsOperateLogService.insertWhsOperateLog(
                                                Constans.WhsOperateLog_DocumentType_NanShaStorageLog,
                                                storageUuid,
                                                materialNo,
                                                "",
                                                qty,
                                                Constans.WhsOperateLog_OperationType_ShelfOff,
                                                uuid,
                                                operateType,
                                                userId,
                                                operateType,
                                                werks,
                                                whsLocationCode, rowId);
                                    }
                                }
                            }
                        } else {
                            return ResponseResult.error("退货出库不支持备件货");
                            // for (int i = 0; i < whsOtherDtl.size(); i++) {
                            //     JSONObject dtl = whsOtherDtl.getJSONObject(i);
                            //     double operateQty = dtl.getDouble("operateQty");
                            //     String boxNote = dtl.getString("boxNote");

                            //     if (operateQty > 0) {
                            //         JSONArray tempStorage = dtl.containsKey("tempStorage") ? dtl.getJSONArray("tempStorage") : null;
                            //         if (null == tempStorage || tempStorage.size() <= 0) {
                            //             throw new RuntimeException("error for " + boxNote + ", storageInfo can not be null");
                            //         }
                            //         JSONObject storage = tempStorage.getJSONObject(0);
                            //         String storageUuid = storage.getString("storageUuid");
                            //         double qty = storage.getDouble("qty");
                            //         String storageNo = storage.getString("storageNo");
                            //         if (StringUtils.isEmpty(storageUuid) || StringUtils.isEmpty(storageNo)) {
                            //             throw new RuntimeException("error for " + boxNote + " on storage Info, storageUuid: " +
                            //                     storageUuid + ",storageNo:" + storageNo +
                            //                     ", qty: " + qty);
                            //         }
                            //         // 扣减储位库存
                            //         if (whsStorageInventoryService.deleteStorageByBoxNoteStorageId(storageUuid, boxNote) < 0) {
                            //             throw new RuntimeException("error for " + boxNote + " on storage Info, storageUuid: " +
                            //                     storageUuid + ",storageNo:" + storageNo +
                            //                     ", qty: " + qty);
                            //         }
                            //         iWhsOperateLogService.insertWhsOperateLog(
                            //                 Constans.WhsOperateLog_DocumentType_NanShaStorageLog,
                            //                 storageUuid,
                            //                 "",
                            //                 boxNote,
                            //                 1,
                            //                 Constans.WhsOperateLog_OperationType_ShelfOff,
                            //                 uuid,
                            //                 operateType,
                            //                 userId,
                            //                 operateType,
                            //                 werks,
                            //                 whsLocationCode);
                            //     }
                            // }
                        }

                        //更新状态为关闭
                        whsOtherTask.setTaskStatus(ConstantWhsOther.StatusClosed);
                        this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                        iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.completedDocument);
                    } else {
                        throw new Exception(JSON.toJSONString(syncSAPRes.getData()));
                    }
                } else {
                    // 如果uuid 不为空，并且targetStatus 不为 StatusClosed，只保存
                    whsOtherTask.setTaskStatus(targetStatus);
                    this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                    iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.updateDocument);
                }
                return dtlUpdateRes.add("whsOther", this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid)));
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error(e.getMessage());
        }
    }
    /**
     * 海运出库
     */
    public ResponseResult OutWHZ641(JSONObject whsOther, JSONArray whsOtherDtl, String goodsType, String userId) {
        try {
            String uuid = whsOther.getString("uuid");
            String werks = whsOther.getString("werks");
            String whsLocationCode = whsOther.getString("whsLocationCode");
            String currentStatus = whsOther.getString("currentStatus");
            String targetStatus = whsOther.getString("targetStatus");
            WhsOtherUnload whsOtherTask = whsOther.toJavaObject(WhsOtherUnload.class);
            // 如果uuid为空，新建
            if (StringUtils.isEmpty(uuid)) {
                uuid = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
                whsOtherTask.setUuid(uuid);
                ResponseResult dtlUpdateRes = whsOtherDtlService.updateWhsOtherDtl(uuid, whsOtherDtl);
                if (dtlUpdateRes.getCode() != 200) {
                    throw new RuntimeException(dtlUpdateRes.getMsg());
                }
                if (StringUtils.isNotEmpty(currentStatus) && StringUtils.isNotEmpty(targetStatus) && currentStatus.equals(whsOtherTask.getTaskStatus())) {
                    whsOtherTask.setTaskStatus(targetStatus);
                }
                this.baseMapper.insert(whsOtherTask);
                iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.createDocument);
                return dtlUpdateRes.add("whsOther", this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid)));
            } else {
                if (StringUtils.isEmpty(currentStatus) || StringUtils.isEmpty(targetStatus)) {
                    throw new RuntimeException("currentStatus and targetStatus in whsOther are mandatory required");
                }
                WhsOtherUnload currWT = this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                if (null == currWT) {
                    throw new RuntimeException("The given WhsOtherUnload ID:" + uuid + " does not exist");
                }
                if (!currWT.getTaskStatus().equals(currentStatus)) {
                    throw new RuntimeException("The given task status: " + currentStatus + " is not match with database");
                }
                // 保存数据
                ResponseResult dtlUpdateRes = whsOtherDtlService.updateWhsOtherDtl(uuid, whsOtherDtl);
                if (dtlUpdateRes.getCode() != 200) {
                    throw new RuntimeException(dtlUpdateRes.getMsg());
                }

                if (targetStatus.equals(ConstantWhsOther.StatusClosed)) {
                    // 如果uuid 不为空，并且targetStatus 为 StatusClosed，首先设定status为pendingSAP
                    whsOtherTask.setTaskStatus(ConstantWhsOther.StatusPendingSAP);
                    this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                    iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.updateDocument);

                    // 检查可出库存
                    if (goodsType.equals("M")) {
                        // 贸易货
                        for (int i = 0; i < whsOtherDtl.size(); i++) {
                            JSONObject dtl = whsOtherDtl.getJSONObject(i);
                            double operateQty = dtl.getDouble("operateQty");
                            String materialNo = dtl.getString("materialNo");
                            if (operateQty > 0) {
                                JSONArray tempStorage = dtl.containsKey("tempStorage") ? dtl.getJSONArray("tempStorage") : null;
                                if (null == tempStorage || tempStorage.size() <= 0) {
                                    throw new RuntimeException("error for " + materialNo + ", storageOutInfo can not be null");
                                }
                                ResponseResult checkInvRes = whsStorageInventoryService.checkStorageInventory(tempStorage, materialNo);
                                if (checkInvRes.getCode() != 200) {
                                    throw new RuntimeException(checkInvRes.getMsg());
                                }
                            }
                        }
                    } else {
                        //备件货
                        for (int i = 0; i < whsOtherDtl.size(); i++) {
                            JSONObject dtl = whsOtherDtl.getJSONObject(i);
                            double operateQty = dtl.getDouble("operateQty");
                            String boxNote = dtl.getString("boxNote");
                            if (operateQty > 0) {
                                JSONArray tempStorage = dtl.containsKey("tempStorage") ? dtl.getJSONArray("tempStorage") : null;
                                if (null == tempStorage || tempStorage.size() <= 0) {
                                    throw new Exception("error for " + boxNote + ", storageInfo can not be null");
                                }
                                JSONObject storage = tempStorage.getJSONObject(0);
                                String storageUuid = storage.getString("storageUuid");
                                double qty = storage.getDouble("qty");
                                String storageNo = storage.getString("storageNo");
                                if (StringUtils.isEmpty(storageUuid) || StringUtils.isEmpty(storageNo)) {
                                    throw new Exception("error for " + boxNote + " on storage Info, storageUuid: " +
                                            storageUuid + ",storageNo:" + storageNo +
                                            ", qty: " + qty);
                                }

                                // 检查储位库存
                                WhsStorageInventory whsStorageInventory = whsStorageInventoryService.getStorageBoxNote(storageUuid, boxNote);
                                if (null == whsStorageInventory || whsStorageInventory.getQuantity() <= 0) {
                                    throw new Exception("error, there is no enough inventory for " + boxNote + " on storageUuid: " +
                                            storageUuid + ",storageNo:" + storageNo);
                                }
                            }
                        }
                    }

                    // 调用方法同步SAP
                    ResponseResult syncSAPRes = whsOtherPackageListToSap(userId, uuid);

                    // 如果同步成功
                    if (syncSAPRes.getCode() == 200) {
                        String operateType = Constans.WHS_OTHER_OutHouseByShip;
                        // 扣减库存
                        if (goodsType.equals("M")) {
                            for (int i = 0; i < whsOtherDtl.size(); i++) {
                                JSONObject dtl = whsOtherDtl.getJSONObject(i);
                                double operateQty = dtl.getDouble("operateQty");
                                String materialNo = dtl.getString("materialNo");
                                String rowId = dtl.getString("rowId");
                                if (operateQty > 0) {
                                    JSONArray tempStorage = dtl.containsKey("tempStorage") ? dtl.getJSONArray("tempStorage") : null;
                                    if (null == tempStorage || tempStorage.size() <= 0) {
                                        throw new RuntimeException("error for " + materialNo + ", storageInfo can not be null");
                                    }
                                    for (int k = 0; k < tempStorage.size(); k++) {
                                        JSONObject storage = tempStorage.getJSONObject(k);
                                        String storageUuid = storage.getString("storageUuid");
                                        double qty = storage.getDouble("qty");
                                        String storageNo = storage.getString("storageNo");
                                        if (StringUtils.isEmpty(storageUuid) || StringUtils.isEmpty(storageNo) || qty <= 0) {
                                            throw new RuntimeException("error for " + materialNo + " on storage Info, storageUuid: " +
                                                    storageUuid + ",storageNo:" + storageNo +
                                                    ", qty: " + qty);
                                        }
                                        // 扣减储位库存
                                        if (whsStorageInventoryService.updateWhsStorage(storageUuid, materialNo, qty) < 0) {
                                            throw new RuntimeException("Update Storage Inventory failed for " + materialNo + " on storage Info, storageUuid: " +
                                                    storageUuid + ",storageNo:" + storageNo +
                                                    ", qty: " + qty);
                                        }


                                        iWhsOperateLogService.insertWhsOperateLog(
                                                Constans.WhsOperateLog_DocumentType_NanShaStorageLog,
                                                storageUuid,
                                                materialNo,
                                                "",
                                                qty,
                                                Constans.WhsOperateLog_OperationType_ShelfOff,
                                                uuid,
                                                operateType,
                                                userId,
                                                operateType,
                                                werks,
                                                whsLocationCode, rowId);
                                    }
                                }
                            }
                        } else {
                            for (int i = 0; i < whsOtherDtl.size(); i++) {
                                JSONObject dtl = whsOtherDtl.getJSONObject(i);
                                double operateQty = dtl.getDouble("operateQty");
                                String boxNote = dtl.getString("boxNote");
                                String rowId = dtl.getString("rowId");

                                if (operateQty > 0) {
                                    JSONArray tempStorage = dtl.containsKey("tempStorage") ? dtl.getJSONArray("tempStorage") : null;
                                    if (null == tempStorage || tempStorage.size() <= 0) {
                                        throw new RuntimeException("error for " + boxNote + ", storageInfo can not be null");
                                    }
                                    JSONObject storage = tempStorage.getJSONObject(0);
                                    String storageUuid = storage.getString("storageUuid");
                                    double qty = storage.getDouble("qty");
                                    String storageNo = storage.getString("storageNo");
                                    if (StringUtils.isEmpty(storageUuid) || StringUtils.isEmpty(storageNo)) {
                                        throw new RuntimeException("error for " + boxNote + " on storage Info, storageUuid: " +
                                                storageUuid + ",storageNo:" + storageNo +
                                                ", qty: " + qty);
                                    }
                                    // 扣减储位库存
                                    if (whsStorageInventoryService.deleteStorageByBoxNoteStorageId(storageUuid, boxNote) < 0) {
                                        throw new RuntimeException("error for " + boxNote + " on storage Info, storageUuid: " +
                                                storageUuid + ",storageNo:" + storageNo +
                                                ", qty: " + qty);
                                    }
                                    iWhsOperateLogService.insertWhsOperateLog(
                                            Constans.WhsOperateLog_DocumentType_NanShaStorageLog,
                                            storageUuid,
                                            "",
                                            boxNote,
                                            1,
                                            Constans.WhsOperateLog_OperationType_ShelfOff,
                                            uuid,
                                            operateType,
                                            userId,
                                            operateType,
                                            werks,
                                            whsLocationCode, rowId);
                                    whsInventoryInfoService.updateWhsInventoryX(werks,whsLocationCode,boxNote,1,"sub",userId);
                                    iWhsOperateLogService.insertWhsOperateLog(
                                            Constans.WhsOperateLog_DocumentType_NanShaWHSLog,
                                            "",
                                            "",
                                            boxNote,
                                            1,
                                            Constans.WhsOperateLog_OperationType_OutHouse,
                                            uuid,
                                            operateType,
                                            userId,
                                            operateType,
                                            werks,
                                            whsLocationCode, rowId);

                                
                                }
                            }
                        }

                        //更新状态为关闭
                        whsOtherTask.setTaskStatus(ConstantWhsOther.StatusClosed);
                        this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                        iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.completedDocument);
                    } else {
                        throw new Exception(JSON.toJSONString(syncSAPRes.getData()));
                    }
                } else {
                    // 如果uuid 不为空，并且targetStatus 不为 StatusClosed，只保存
                    whsOtherTask.setTaskStatus(targetStatus);
                    this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                    iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.updateDocument);
                }
                return dtlUpdateRes.add("whsOther", this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid)));
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error(e.getMessage());
        }
    }

    /**
     * 领用/报废出库
     * "报废：551（冲销对应552）
     * 样品领用：Z09（冲销对应Z10）
     * 仓库工具领用：Z21（冲销对应Z22）
     * 其他公司领用：Z23 (冲销对应Z24
     * 委外加工发货出库 541
     */
    public ResponseResult acquistionAndScrap(JSONObject whsOther, JSONArray whsOtherDtl, String goodsType, String userId) {
        try {
            String uuid = whsOther.getString("uuid");
            String werks = whsOther.getString("werks");
            String whsLocationCode = whsOther.getString("whsLocationCode");
            String currentStatus = whsOther.getString("currentStatus");
            String targetStatus = whsOther.getString("targetStatus");
            String movementType = whsOther.getString("movementType");
            WhsOtherUnload whsOtherTask = whsOther.toJavaObject(WhsOtherUnload.class);
            // 如果uuid为空，新建
            if (StringUtils.isEmpty(uuid)) {
                uuid = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
                whsOtherTask.setUuid(uuid);
                ResponseResult dtlUpdateRes = whsOtherDtlService.updateWhsOtherDtl(uuid, whsOtherDtl);
                if (dtlUpdateRes.getCode() != 200) {
                    throw new Exception(dtlUpdateRes.getMsg());
                }
                if (StringUtils.isNotEmpty(currentStatus) && StringUtils.isNotEmpty(targetStatus) && currentStatus.equals(whsOtherTask.getTaskStatus())) {
                    whsOtherTask.setTaskStatus(targetStatus);
                }
                this.baseMapper.insert(whsOtherTask);
                iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.createDocument);
                return dtlUpdateRes.add("whsOther", this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid)));
            } else {
                if (StringUtils.isEmpty(currentStatus) || StringUtils.isEmpty(targetStatus)) {
                    throw new Exception("currentStatus and targetStatus in whsOther are mandatory required");
                }
                WhsOtherUnload currWT = this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                if (null == currWT) {
                    throw new Exception("The given WhsOtherUnload ID:" + uuid + " does not exist");
                }
                if (!currWT.getTaskStatus().equals(currentStatus)) {
                    throw new Exception("The given task status: " + currentStatus + " is not match with database");
                }
                // 保存数据
                ResponseResult dtlUpdateRes = whsOtherDtlService.updateWhsOtherDtl(uuid, whsOtherDtl);
                if (dtlUpdateRes.getCode() != 200) {
                    throw new Exception(dtlUpdateRes.getMsg());
                }

                if (targetStatus.equals(ConstantWhsOther.StatusClosed)) {
                    // 如果uuid 不为空，并且targetStatus 为 StatusClosed，首先设定status为pendingSAP
                    whsOtherTask.setTaskStatus(ConstantWhsOther.StatusPendingSAP);
                    this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                    iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.updateDocument);

                    // 检查可出库存
                    for (int i = 0; i < whsOtherDtl.size(); i++) {
                        JSONObject dtl = whsOtherDtl.getJSONObject(i);
                        double operateQty = dtl.getDouble("operateQty");
                        String materialNo = dtl.getString("materialNo");
                        if (operateQty > 0) {
                            JSONArray tempStorage = dtl.containsKey("tempStorage") ? dtl.getJSONArray("tempStorage") : null;
                            if (null == tempStorage || tempStorage.size() <= 0) {
                                throw new Exception("error for " + materialNo + ", storageOutInfo can not be null");
                            }
                            ResponseResult checkInvRes = whsStorageInventoryService.checkStorageInventory(tempStorage, materialNo);
                            if (checkInvRes.getCode() != 200) {
                                throw new Exception(checkInvRes.getMsg());
                            }
                        }
                    }

                    // 调用方法同步SAP
                    ResponseResult syncSAPRes = submitWhsOtherToSap(userId, uuid, this.baseMapper.acquistionAndScrapDataToSapHead(uuid),
                            this.baseMapper.acquistionAndScrapDataToSapItem(uuid), "Z_SPMS_ANOMALY_POST");
                    if (400 == syncSAPRes.getCode()) {
                        throw new Exception("当前状态禁止提交SAP");
                    }
//                    if (100 == syncSAPRes.getCode()) {
//                        return syncSAPRes;
//                    }


                    // 如果同步成功
                    if (syncSAPRes.getCode() == 200) {
                        String operateType = "";
                        if (movementType.equals(ConstantWhsOther.OutHouseScrap)) {
                            operateType = Constans.WHS_OTHER_ScrapOut;
                        } else if (movementType.equals(ConstantWhsOther.SampleAcquisition)) {
                            operateType = Constans.WHS_OTHER_SampleAcquistion;
                        } else if (movementType.equals(ConstantWhsOther.ToolsAcquistion)) {
                            operateType = Constans.WHS_OTHER_ToolAcquistion;
                        } else if (movementType.equals(ConstantWhsOther.OtherAcquistion)) {
                            operateType = Constans.WHS_OTHER_OtherAcquistion;
                        } else if (movementType.equals(ConstantWhsOther.OutHouseOEM)) {
                            operateType = Constans.WHS_OTHER_OutHouseOEM;
                        }
                        // 扣减库存
                        if (goodsType.equals("M")) {
                            for (int i = 0; i < whsOtherDtl.size(); i++) {
                                JSONObject dtl = whsOtherDtl.getJSONObject(i);
                                double operateQty = dtl.getDouble("operateQty");
                                String materialNo = dtl.getString("materialNo");
                                String rowId = dtl.getString("rowId");
                                if (operateQty > 0) {
                                    JSONArray tempStorage = dtl.containsKey("tempStorage") ? dtl.getJSONArray("tempStorage") : null;
                                    if (null == tempStorage || tempStorage.size() <= 0) {
                                        throw new Exception("error for " + materialNo + ", storageInfo can not be null");
                                    }
                                    for (int k = 0; k < tempStorage.size(); k++) {
                                        JSONObject storage = tempStorage.getJSONObject(k);
                                        String storageUuid = storage.getString("storageUuid");
                                        double qty = storage.getDouble("qty");
                                        String storageNo = storage.getString("storageNo");
                                        if (StringUtils.isEmpty(storageUuid) || StringUtils.isEmpty(storageNo) || qty <= 0) {
                                            throw new Exception("error for " + materialNo + " on storage Info, storageUuid: " +
                                                    storageUuid + ",storageNo:" + storageNo +
                                                    ", qty: " + qty);
                                        }
                                        // 扣减储位库存
                                        if (whsStorageInventoryService.updateWhsStorage(storageUuid, materialNo, qty) < 0) {
                                            throw new Exception("Update Storage Inventory failed for " + materialNo + " on storage Info, storageUuid: " +
                                                    storageUuid + ",storageNo:" + storageNo +
                                                    ", qty: " + qty);
                                        }


                                        iWhsOperateLogService.insertWhsOperateLog(
                                                Constans.WhsOperateLog_DocumentType_NanShaStorageLog,
                                                storageUuid,
                                                materialNo,
                                                "",
                                                qty,
                                                Constans.WhsOperateLog_OperationType_ShelfOff,
                                                uuid,
                                                operateType,
                                                userId,
                                                operateType,
                                                werks,
                                                whsLocationCode, rowId);
                                    }
                                }
                            }
                        } else {
                            for (int i = 0; i < whsOtherDtl.size(); i++) {
                                JSONObject dtl = whsOtherDtl.getJSONObject(i);
                                double operateQty = dtl.getDouble("operateQty");
                                String boxNote = dtl.getString("boxNote");
                                String rowId = dtl.getString("rowId");

                                if (operateQty > 0) {
                                    JSONArray tempStorage = dtl.containsKey("tempStorage") ? dtl.getJSONArray("tempStorage") : null;
                                    if (null == tempStorage || tempStorage.size() <= 0) {
                                        throw new Exception("error for " + boxNote + ", storageInfo can not be null");
                                    }
                                    JSONObject storage = tempStorage.getJSONObject(0);
                                    String storageUuid = storage.getString("storageUuid");
                                    double qty = storage.getDouble("qty");
                                    String storageNo = storage.getString("storageNo");
                                    if (StringUtils.isEmpty(storageUuid) || StringUtils.isEmpty(storageNo)) {
                                        throw new Exception("error for " + boxNote + " on storage Info, storageUuid: " +
                                                storageUuid + ",storageNo:" + storageNo +
                                                ", qty: " + qty);
                                    }
                                    // 扣减储位库存
                                    if (whsStorageInventoryService.deleteStorageByBoxNoteStorageId(storageUuid, boxNote) < 0) {
                                        throw new Exception("error for " + boxNote + " on storage Info, storageUuid: " +
                                                storageUuid + ",storageNo:" + storageNo +
                                                ", qty: " + qty);
                                    }
                                    iWhsOperateLogService.insertWhsOperateLog(
                                            Constans.WhsOperateLog_DocumentType_NanShaStorageLog,
                                            storageUuid,
                                            "",
                                            boxNote,
                                            1,
                                            Constans.WhsOperateLog_OperationType_ShelfOff,
                                            uuid,
                                            operateType,
                                            userId,
                                            operateType,
                                            werks,
                                            whsLocationCode, rowId);
                                    whsInventoryInfoService.updateWhsInventoryX(werks,whsLocationCode,boxNote,1,"sub",userId);
                                    iWhsOperateLogService.insertWhsOperateLog(
                                                    Constans.WhsOperateLog_DocumentType_NanShaWHSLog,
                                                    "",
                                                    "",
                                                    boxNote,
                                                    1,
                                                    Constans.WhsOperateLog_OperationType_OutHouse,
                                                    uuid,
                                                    operateType,
                                                    userId,
                                                    operateType,
                                                    werks,
                                                    whsLocationCode, rowId);
                                }
                            }
                        }

                        //更新状态为关闭
                        whsOtherTask.setTaskStatus(ConstantWhsOther.StatusClosed);
                        this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                        iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.completedDocument);
                    } else {
                        throw new Exception(JSON.toJSONString(syncSAPRes.getData()));
                    }
                } else {
                    // 如果uuid 不为空，并且targetStatus 不为 StatusClosed，只保存
                    whsOtherTask.setTaskStatus(targetStatus);
                    this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                    iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.updateDocument);
                }
                return dtlUpdateRes.add("whsOther", this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid)));
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error(e.getMessage());
        }
    }

    /**
     * 卸货入库
     */
    public ResponseResult handleInHouseUnload(JSONObject whsOther, JSONArray whsOtherDtl, String goodsType, String userId) throws Exception {
        String uuid = whsOther.getString("uuid");
        String werks = whsOther.getString("werks");
        String whsLocationCode = whsOther.getString("whsLocationCode");
        String currentStatus = whsOther.getString("currentStatus");
        String targetStatus = whsOther.getString("targetStatus");
        WhsOtherUnload whsOtherTask = whsOther.toJavaObject(WhsOtherUnload.class);
        // 如果uuid为空，新建
        if (StringUtils.isEmpty(uuid)) {
            uuid = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
            whsOtherTask.setUuid(uuid);
            ResponseResult dtlUpdateRes = whsOtherDtlService.updateWhsOtherDtl(uuid, whsOtherDtl);
            if (dtlUpdateRes.getCode() != 200) {
                throw new Exception(dtlUpdateRes.getMsg());
            }
            if (StringUtils.isNotEmpty(currentStatus) && StringUtils.isNotEmpty(targetStatus) && currentStatus.equals(whsOtherTask.getTaskStatus())) {
                whsOtherTask.setTaskStatus(targetStatus);
            }
            this.baseMapper.insert(whsOtherTask);
            iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.createDocument);
            return dtlUpdateRes.add("whsOther", this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid)));
        } else {
            if (StringUtils.isEmpty(currentStatus) || StringUtils.isEmpty(targetStatus)) {
                throw new Exception("currentStatus and targetStatus in whsOther are mandatory required");
            }
            WhsOtherUnload currWT = this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
            if (null == currWT) {
                throw new Exception("The given WhsOtherUnload ID:" + uuid + " does not exist");
            }
            if (!currWT.getTaskStatus().equals(currentStatus)) {
                throw new Exception("The given task status: " + currentStatus + " is not match with database");
            }
            // 保存数据
            ResponseResult dtlUpdateRes = whsOtherDtlService.updateWhsOtherDtl(uuid, whsOtherDtl);
            if (dtlUpdateRes.getCode() != 200) {
                throw new Exception(dtlUpdateRes.getMsg());
            }
            if (targetStatus.equals("5")) {
                // 调用方法同步SAP
            	if ("4".equals(currWT.getTaskStatus()) || "5".equals(currWT.getTaskStatus()) || "6".equals(currWT.getTaskStatus())) {
            		throw new Exception("当前状态禁止提交");
                }
            	List<Map<String, Object>> dataToSapItem = this.baseMapper.handleInHouseUnloadDataToSapItem(uuid);
            	JSONObject dataToSap = this.setToSapData(dataToSapItem);
                log.info("======dataToSap=====" + dataToSap);
                JSONObject message = iDataToSap.submitDataToSap(dataToSap);
                log.info("======message=====" + message);
                String O_TYPE = message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA").getString("MSTYPE");
                if ("S".equals(O_TYPE)) {
                	//更新卸货入库单状态为已完成
                    whsOtherTask.setTaskStatus(ConstantWhsOther.StatusSapFailed);
                    whsOtherTask.setSapVoucherNumber(message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA").getString("MBLNR"));
                    whsOtherTask.setSapVoucherYear(message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA").getString("MJAHR"));
                    this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                    iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.sendToSAP);
                    iSapDeliveryNoteLogService.insertSapRequestRecord(uuid, userId, ConstantWhsOther.sendToSAP, message.toJSONString(), dataToSap.toJSONString());
                    // 增加库存
                    if (goodsType.equals("M")) {
                        for (int i = 0; i < whsOtherDtl.size(); i++) {
                            JSONObject dtl = whsOtherDtl.getJSONObject(i);
                            double operateQty = dtl.getDouble("operateQty");
                            String materialNo = dtl.getString("materialNo");
                            String rowId = dtl.getString("rowId");
                            String packageList = dtl.getString("packageList");
                            if (operateQty > 0) {
                                JSONArray tempStorage = dtl.containsKey("tempStorage") ? dtl.getJSONArray("tempStorage") : null;
                                if (null == tempStorage || tempStorage.size() <= 0) {
                                    throw new Exception("error for " + materialNo + ", storageInfo can not be null");
                                }
                                for (int k = 0; k < tempStorage.size(); k++) {
                                    JSONObject storage = tempStorage.getJSONObject(k);
                                    String storageUuid = storage.getString("storageUuid");
                                    double qty = storage.getDouble("qty");
                                    String storageNo = storage.getString("storageNo");
                                    if (StringUtils.isEmpty(storageUuid) || StringUtils.isEmpty(storageNo) || qty <= 0) {
                                        throw new Exception("error for " + materialNo + " on storage Info, storageUuid: " +
                                                storageUuid + ",storageNo:" + storageNo +
                                                ", qty: " + qty);
                                    }
                                    if (whsStorageInventoryService.updateWhsStorageInventoryMOld(storageUuid, materialNo, qty) < 0) {
                                        throw new Exception("Update Storage Inventory failed for " + materialNo + " on storage Info, storageUuid: " +
                                                storageUuid + ",storageNo:" + storageNo +
                                                ", qty: " + qty);
                                    }
                                    iWhsOperateLogService.insertWhsOperateLog(
                                            Constans.WhsOperateLog_DocumentType_NanShaStorageLog,
                                            storageUuid,
                                            materialNo,
                                            "",
                                            qty,
                                            Constans.WhsOperateLog_OperationType_ShelfOn,
                                            uuid,
                                            Constans.WHS_OTHER_InHouseUnload,
                                            userId,
                                            Constans.TRADE_GOODS_INTO_STORAGE,
                                            werks,
                                            whsLocationCode, rowId);
                                }
                            }
                        }
                    } else {
                        for (int i = 0; i < whsOtherDtl.size(); i++) {
                            JSONObject dtl = whsOtherDtl.getJSONObject(i);
                            double operateQty = dtl.getDouble("operateQty");
                            String boxNote = dtl.getString("boxNote");
                            String rowId = dtl.getString("rowId");
                            String packageList = dtl.getString("packageList");
                            if (operateQty > 0) {
                                JSONArray tempStorage = dtl.containsKey("tempStorage") ? dtl.getJSONArray("tempStorage") : null;
                                if (null == tempStorage || tempStorage.size() <= 0) {
                                    throw new Exception("error for " + boxNote + ", storageInfo can not be null");
                                }
                                JSONObject storage = tempStorage.getJSONObject(0);
                                String storageUuid = storage.getString("storageUuid");
                                double qty = storage.getDouble("qty");
                                String storageNo = storage.getString("storageNo");
                                if (StringUtils.isEmpty(storageUuid) || StringUtils.isEmpty(storageNo)) {
                                    throw new Exception("error for " + boxNote + " on storage Info, storageUuid: " +
                                            storageUuid + ",storageNo:" + storageNo +
                                            ", qty: " + qty);
                                }
                                whsStorageInventoryService.insertStorageInventory(storageUuid, null, boxNote);
                                iWhsOperateLogService.insertWhsOperateLog(
                                        Constans.WhsOperateLog_DocumentType_NanShaStorageLog,
                                        storageUuid,
                                        "",
                                        boxNote,
                                        1,
                                        Constans.WhsOperateLog_OperationType_ShelfOn,
                                        uuid,
                                        Constans.WHS_OTHER_InHouseUnload,
                                        userId,
                                        Constans.SPARE_PARTS_INTO_STORAGE,
                                        werks,
                                        whsLocationCode, rowId);
                                ResponseResult updateWhsInventoryX = whsInventoryInfoService.updateWhsInventoryX(werks,whsLocationCode,boxNote,1,"add",userId);
                                if (!SUCCESS.equals(updateWhsInventoryX.getCode())){
                                	throw new Exception("卸货入库备件增加仓库库存失败："+JSONObject.toJSONString(updateWhsInventoryX));
                                }
                                iWhsOperateLogService.insertWhsOperateLog(
                                                Constans.WhsOperateLog_DocumentType_NanShaWHSLog,
                                                "",
                                                "",
                                                boxNote,
                                                1,
                                                Constans.WhsOperateLog_OperationType_InHouse,
                                                uuid,
                                                Constans.WHS_OTHER_InHouseUnload,
                                                userId,
                                                Constans.SPARE_PARTS_INTO_WHS,
                                                werks,
                                                whsLocationCode, rowId);
                            }
                        }
                    }
                    return ResponseResult.success().add("dataToSap", dataToSap).add("sapReturnedData", message);
                } else {
                	throw new Exception("提交SAP失败："+message.toJSONString());
                }
            } else {
                // 如果uuid 不为空，并且targetStatus 不为 StatusClosed，只保存
                whsOtherTask.setTaskStatus(targetStatus);
                this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.updateDocument);
            }
            return dtlUpdateRes.add("whsOther", this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid)));
        }
    }


    private JSONObject setToSapData(List<Map<String, Object>> dataToSapItem) {
    	JSONObject doc = new JSONObject();
        JSONObject REQUEST = new JSONObject();
        JSONObject ESB_ATTRS = new JSONObject();
        JSONObject REQUEST_DATA = new JSONObject();
        REQUEST_DATA.put("Target_ID", sapClient);
        ESB_ATTRS.put("App_ID", "SPMS");
        ESB_ATTRS.put("Application_ID", "00020000000002");
        ESB_ATTRS.put("Transaction_ID", UUID.randomUUID().toString());
        Map<String, Object> tables = new HashMap<>();
        tables.put("IT_ITEM", dataToSapItem);
        REQUEST_DATA.put("tables", tables);
        REQUEST_DATA.put("Operation", "ZZXD_IF_SPMS_10");
        REQUEST_DATA.put("Type", "ZZXD_IF_SPMS_10");
        ESB_ATTRS.put("Target_ID", sapClient);
        REQUEST.put("ESB_ATTRS", ESB_ATTRS);
        REQUEST.put("REQUEST_DATA", REQUEST_DATA);
        doc.put("REQUEST", REQUEST);
        return doc;
	}

	/**
     * 采购入库
     */
    public ResponseResult handlePurchasingInWarehouse(JSONObject whsOther, JSONArray whsOtherDtl, String goodsType, String userId) {
        try {
            String uuid = whsOther.getString("uuid");
            String werks = whsOther.getString("werks");
            String whsLocationCode = whsOther.getString("whsLocationCode");
            String currentStatus = whsOther.getString("currentStatus");
            String targetStatus = whsOther.getString("targetStatus");
            WhsOtherUnload whsOtherTask = whsOther.toJavaObject(WhsOtherUnload.class);
            // 如果uuid为空，新建
            if (StringUtils.isEmpty(uuid)) {
                uuid = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
                whsOtherTask.setUuid(uuid);
                ResponseResult dtlUpdateRes = whsOtherDtlService.updateWhsOtherDtl(uuid, whsOtherDtl);
                if (dtlUpdateRes.getCode() != 200) {
                    throw new Exception(dtlUpdateRes.getMsg());
                }
                if (StringUtils.isNotEmpty(currentStatus) && StringUtils.isNotEmpty(targetStatus) && currentStatus.equals(whsOtherTask.getTaskStatus())) {
                    whsOtherTask.setTaskStatus(targetStatus);
                }
                this.baseMapper.insert(whsOtherTask);
                iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.createDocument);
                return dtlUpdateRes.add("whsOther", this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid)));
            } else {
                if (StringUtils.isEmpty(currentStatus) || StringUtils.isEmpty(targetStatus)) {
                    throw new Exception("currentStatus and targetStatus in whsOther are mandatory required");
                }
                WhsOtherUnload currWT = this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                if (null == currWT) {
                    throw new Exception("The given WhsOtherUnload ID:" + uuid + " does not exist");
                }
                if (!currWT.getTaskStatus().equals(currentStatus)) {
                    throw new Exception("The given task status: " + currentStatus + " is not match with database");
                }
                // 保存数据
                ResponseResult dtlUpdateRes = whsOtherDtlService.updateWhsOtherDtl(uuid, whsOtherDtl);
                if (dtlUpdateRes.getCode() != 200) {
                    throw new Exception(dtlUpdateRes.getMsg());
                }

                if (targetStatus.equals(ConstantWhsOther.StatusClosed)) {
                    // 如果uuid 不为空，并且targetStatus 为 StatusClosed，首先设定status为pendingSAP
                    whsOtherTask.setTaskStatus(ConstantWhsOther.StatusPendingSAP);
                    this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                    iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.updateDocument);
                    // 调用方法同步SAP
                    ResponseResult syncSAPRes = ResponseResult.success();


                    // 如果同步成功
                    if (syncSAPRes.getCode() == 200) {
                        // 增加库存
                        if (goodsType.equals("M")) {
                            for (int i = 0; i < whsOtherDtl.size(); i++) {
                                JSONObject dtl = whsOtherDtl.getJSONObject(i);
                                double operateQty = dtl.getDouble("operateQty");
                                String materialNo = dtl.getString("materialNo");
                                String rowId = dtl.getString("rowId");
                                String deliveryNoteSap = dtl.getString("deliveryNoteSap");
                                if (operateQty > 0) {
                                    JSONArray tempStorage = dtl.containsKey("tempStorage") ? dtl.getJSONArray("tempStorage") : null;
                                    if (null == tempStorage || tempStorage.size() <= 0) {
                                        throw new Exception("error for " + materialNo + ", storageInfo can not be null");
                                    }
                                    for (int k = 0; k < tempStorage.size(); k++) {
                                        JSONObject storage = tempStorage.getJSONObject(k);
                                        String storageUuid = storage.getString("storageUuid");
                                        double qty = storage.getDouble("qty");
                                        String storageNo = storage.getString("storageNo");
                                        if (StringUtils.isEmpty(storageUuid) || StringUtils.isEmpty(storageNo) || qty <= 0) {
                                            throw new Exception("error for " + materialNo + " on storage Info, storageUuid: " +
                                                    storageUuid + ",storageNo:" + storageNo +
                                                    ", qty: " + qty);
                                        }
                                        if (whsStorageInventoryService.updateWhsStorageInventoryMOld(storageUuid, materialNo, qty) < 0) {
                                            throw new Exception("Update Storage Inventory failed for " + materialNo + " on storage Info, storageUuid: " +
                                                    storageUuid + ",storageNo:" + storageNo +
                                                    ", qty: " + qty);
                                        }
                                        iWhsOperateLogService.insertWhsOperateLog(
                                                Constans.WhsOperateLog_DocumentType_NanShaStorageLog,
                                                storageUuid,
                                                materialNo,
                                                "",
                                                qty,
                                                Constans.WhsOperateLog_OperationType_ShelfOn,
                                                uuid,
                                                Constans.WHS_OTHER_PurchaseInHour,
                                                userId,
                                                "deliveryNoteSap:" + deliveryNoteSap,
                                                werks,
                                                whsLocationCode, rowId);
                                    }
                                }
                            }
                        } else {
                            // 不支持备件货
                        }

                        //更新入库单状态为关闭
                        whsOtherTask.setTaskStatus(ConstantWhsOther.StatusClosed);
                        this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                        iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.completedDocument);
                    } else {
                        throw new Exception(JSON.toJSONString(syncSAPRes.getData()));
                    }
                } else {
                    // 如果uuid 不为空，并且targetStatus 不为 StatusClosed，只保存
                    whsOtherTask.setTaskStatus(targetStatus);
                    this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                    iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.updateDocument);
                }
                return dtlUpdateRes.add("whsOther", this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid)));
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error(e.getMessage());
        }
    }

    /**
     * 赠品入库
     * InHousePresenter:511
     */
    public ResponseResult handleInHousePresenter(JSONObject whsOther, JSONArray whsOtherDtl, String goodsType, String userId) {
        try {
            String uuid = whsOther.getString("uuid");
            String werks = whsOther.getString("werks");
            String whsLocationCode = whsOther.getString("whsLocationCode");
            String currentStatus = whsOther.getString("currentStatus");
            String targetStatus = whsOther.getString("targetStatus");
            WhsOtherUnload whsOtherTask = whsOther.toJavaObject(WhsOtherUnload.class);
            // 如果uuid为空，新建
            if (StringUtils.isEmpty(uuid)) {
                uuid = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
                whsOtherTask.setUuid(uuid);
                ResponseResult dtlUpdateRes = whsOtherDtlService.updateWhsOtherDtl(uuid, whsOtherDtl);
                if (dtlUpdateRes.getCode() != 200) {
                    throw new Exception(dtlUpdateRes.getMsg());
                }
                if (StringUtils.isNotEmpty(currentStatus) && StringUtils.isNotEmpty(targetStatus) && currentStatus.equals(whsOtherTask.getTaskStatus())) {
                    whsOtherTask.setTaskStatus(targetStatus);
                }
                this.baseMapper.insert(whsOtherTask);
                iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.createDocument);
                return dtlUpdateRes.add("whsOther", this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid)));
            } else {
                if (StringUtils.isEmpty(currentStatus) || StringUtils.isEmpty(targetStatus)) {
                    throw new Exception("currentStatus and targetStatus in whsOther are mandatory required");
                }
                WhsOtherUnload currWT = this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                if (null == currWT) {
                    throw new Exception("The given WhsOtherUnload ID:" + uuid + " does not exist");
                }
                if (!currWT.getTaskStatus().equals(currentStatus)) {
                    throw new Exception("The given task status: " + currentStatus + " is not match with database");
                }
                // 保存数据
                ResponseResult dtlUpdateRes = whsOtherDtlService.updateWhsOtherDtl(uuid, whsOtherDtl);
                if (dtlUpdateRes.getCode() != 200) {
                    throw new Exception(dtlUpdateRes.getMsg());
                }

                if (targetStatus.equals(ConstantWhsOther.StatusClosed)) {
                    // 如果uuid 不为空，并且targetStatus 为 StatusClosed，首先设定status为pendingSAP
                    whsOtherTask.setTaskStatus(ConstantWhsOther.StatusPendingSAP);
                    this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                    iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.updateDocument);
                    // 调用方法同步SAP
                    ResponseResult syncSAPRes = submitWhsOtherToSap(userId, uuid, this.baseMapper.acquistionAndScrapDataToSapHead(uuid),
                            this.baseMapper.acquistionAndScrapDataToSapItem(uuid), "Z_SPMS_ANOMALY_POST");
                    if (400 == syncSAPRes.getCode()) {
                        throw new Exception("当前状态禁止提交SAP");
                    }


                    // 如果同步成功
                    if (syncSAPRes.getCode() == 200) {
                        // 增加库存
                        if (goodsType.equals("M")) {
                            for (int i = 0; i < whsOtherDtl.size(); i++) {
                                JSONObject dtl = whsOtherDtl.getJSONObject(i);
                                double operateQty = dtl.getDouble("operateQty");
                                String materialNo = dtl.getString("materialNo");
                                String rowId = dtl.getString("rowId");

                                if (operateQty > 0) {
                                    JSONArray tempStorage = dtl.containsKey("tempStorage") ? dtl.getJSONArray("tempStorage") : null;
                                    if (null == tempStorage || tempStorage.size() <= 0) {
                                        throw new Exception("error for " + materialNo + ", storageInfo can not be null");
                                    }
                                    for (int k = 0; k < tempStorage.size(); k++) {
                                        JSONObject storage = tempStorage.getJSONObject(k);
                                        String storageUuid = storage.getString("storageUuid");
                                        double qty = storage.getDouble("qty");
                                        String storageNo = storage.getString("storageNo");
                                        if (StringUtils.isEmpty(storageUuid) || StringUtils.isEmpty(storageNo) || qty <= 0) {
                                            throw new Exception("error for " + materialNo + " on storage Info, storageUuid: " +
                                                    storageUuid + ",storageNo:" + storageNo +
                                                    ", qty: " + qty);
                                        }
                                        if (whsStorageInventoryService.updateWhsStorageInventoryMOld(storageUuid, materialNo, qty) < 0) {
                                            throw new Exception("Update Storage Inventory failed for " + materialNo + " on storage Info, storageUuid: " +
                                                    storageUuid + ",storageNo:" + storageNo +
                                                    ", qty: " + qty);
                                        }
                                        iWhsOperateLogService.insertWhsOperateLog(
                                                Constans.WhsOperateLog_DocumentType_NanShaStorageLog,
                                                storageUuid,
                                                materialNo,
                                                "",
                                                qty,
                                                Constans.WhsOperateLog_OperationType_ShelfOn,
                                                uuid,
                                                Constans.WHS_OTHER_InHousePresenter,
                                                userId,
                                                Constans.WHS_OTHER_InHousePresenter,
                                                werks,
                                                whsLocationCode, rowId);
                                    }
                                }
                            }
                        } else {
                            for (int i = 0; i < whsOtherDtl.size(); i++) {
                                JSONObject dtl = whsOtherDtl.getJSONObject(i);
                                double operateQty = dtl.getDouble("operateQty");
                                String boxNote = dtl.getString("boxNote");
                                String rowId = dtl.getString("rowId");

                                if (operateQty > 0) {
                                    JSONArray tempStorage = dtl.containsKey("tempStorage") ? dtl.getJSONArray("tempStorage") : null;
                                    if (null == tempStorage || tempStorage.size() <= 0) {
                                        throw new Exception("error for " + boxNote + ", storageInfo can not be null");
                                    }
                                    JSONObject storage = tempStorage.getJSONObject(0);
                                    String storageUuid = storage.getString("storageUuid");
                                    double qty = storage.getDouble("qty");
                                    String storageNo = storage.getString("storageNo");
                                    if (StringUtils.isEmpty(storageUuid) || StringUtils.isEmpty(storageNo)) {
                                        throw new Exception("error for " + boxNote + " on storage Info, storageUuid: " +
                                                storageUuid + ",storageNo:" + storageNo +
                                                ", qty: " + qty);
                                    }
                                    whsStorageInventoryService.insertStorageInventory(storageUuid, null, boxNote);
                                    iWhsOperateLogService.insertWhsOperateLog(
                                            Constans.WhsOperateLog_DocumentType_NanShaStorageLog,
                                            storageUuid,
                                            "",
                                            boxNote,
                                            1,
                                            Constans.WhsOperateLog_OperationType_ShelfOn,
                                            uuid,
                                            Constans.WHS_OTHER_InHousePresenter,
                                            userId,
                                            Constans.WHS_OTHER_InHousePresenter,
                                            werks,
                                            whsLocationCode, rowId);
                                    whsInventoryInfoService.updateWhsInventoryX(werks,whsLocationCode,boxNote,1,"add",userId);
                                    iWhsOperateLogService.insertWhsOperateLog(
                                                            Constans.WhsOperateLog_DocumentType_NanShaWHSLog,
                                                            "",
                                                            "",
                                                            boxNote,
                                                            1,
                                                            Constans.WhsOperateLog_OperationType_OutHouse,
                                                            uuid,
                                                            Constans.WHS_OTHER_InHousePresenter,
                                                            userId,
                                                            Constans.WHS_OTHER_InHousePresenter,
                                                            werks,
                                                            whsLocationCode, rowId);
                                }
                            }
                        }

                        //更新入库单状态为关闭
                        whsOtherTask.setTaskStatus(ConstantWhsOther.StatusClosed);
                        this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                        iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.completedDocument);
                    } else {
                        throw new Exception(JSON.toJSONString(syncSAPRes.getData()));
                    }
                } else {
                    // 如果uuid 不为空，并且targetStatus 不为 StatusClosed，只保存
                    whsOtherTask.setTaskStatus(targetStatus);
                    this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                    iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.updateDocument);
                }
                return dtlUpdateRes.add("whsOther", this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid)));
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error(e.getMessage());
        }
    }

    /**
     * 串货调整 309
     * 1. 从materialNoOut, qtyOut,storageOut出
     * 2. 从materialNoIn,qtyIn,storageIn入
     */
    public ResponseResult handlePartAdjustment(JSONObject whsOther, JSONArray whsOtherDtl, String goodsType, String userId) {
        try {
            String uuid = whsOther.getString("uuid");
            String werks = whsOther.getString("werks");
            String whsLocationCode = whsOther.getString("whsLocationCode");
            String currentStatus = whsOther.getString("currentStatus");
            String targetStatus = whsOther.getString("targetStatus");
            WhsOtherUnload whsOtherTask = whsOther.toJavaObject(WhsOtherUnload.class);
            // 如果uuid为空，新建
            if (StringUtils.isEmpty(uuid)) {
                uuid = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
                whsOtherTask.setUuid(uuid);
                ResponseResult dtlUpdateRes = whsOtherDtlService.updateWhsOtherDtl(uuid, whsOtherDtl);
                if (dtlUpdateRes.getCode() != 200) {
                    throw new Exception(dtlUpdateRes.getMsg());
                }
                if (StringUtils.isNotEmpty(currentStatus) && StringUtils.isNotEmpty(targetStatus) && currentStatus.equals(whsOtherTask.getTaskStatus())) {
                    whsOtherTask.setTaskStatus(targetStatus);
                }
                this.baseMapper.insert(whsOtherTask);
                iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.createDocument);
                return dtlUpdateRes.add("whsOther", this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid)));
            } else {
                if (StringUtils.isEmpty(currentStatus) || StringUtils.isEmpty(targetStatus)) {
                    throw new Exception("currentStatus and targetStatus in whsOther are mandatory required");
                }
                WhsOtherUnload currWT = this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                if (null == currWT) {
                    throw new Exception("The given WhsOtherUnload ID:" + uuid + " does not exist");
                }
                if (!currWT.getTaskStatus().equals(currentStatus)) {
                    throw new Exception("The given task status: " + currentStatus + " is not match with database");
                }
                // 保存数据
                ResponseResult dtlUpdateRes = whsOtherDtlService.updateWhsOtherDtl(uuid, whsOtherDtl);
                if (dtlUpdateRes.getCode() != 200) {
                    throw new Exception(dtlUpdateRes.getMsg());
                }

                if (targetStatus.equals(ConstantWhsOther.StatusClosed)) {
                    // 如果uuid 不为空，并且targetStatus 为 StatusClosed，首先设定status为pendingSAP
                    whsOtherTask.setTaskStatus(ConstantWhsOther.StatusPendingSAP);
                    this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                    iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.updateDocument);
                    // 检查可出库存
                    for (int i = 0; i < whsOtherDtl.size(); i++) {
                        JSONObject dtl = whsOtherDtl.getJSONObject(i);
                        double qtyOut = dtl.getDouble("qtyOut");
                        String materialNoOut = dtl.getString("materialNoOut");
                        if (qtyOut > 0) {
                            JSONArray tempStorage = dtl.containsKey("storageOut") ? dtl.getJSONArray("storageOut") : null;
                            if (null == tempStorage || tempStorage.size() <= 0) {
                                throw new Exception("error for " + materialNoOut + ", storageOutInfo can not be null");
                            }
                            ResponseResult checkInvRes = whsStorageInventoryService.checkStorageInventory(tempStorage, materialNoOut);
                            if (checkInvRes.getCode() != 200) {
                                throw new Exception(checkInvRes.getMsg());
                            }
                        }
                    }
                    // 调用方法同步SAP
                    ResponseResult syncSAPRes = handlePartAdjustmentToSap(userId, uuid);
                    // 如果同步成功
                    if (syncSAPRes.getCode() == 200) {

                        if (goodsType.equals("M")) {
                            for (int i = 0; i < whsOtherDtl.size(); i++) {
                                JSONObject dtl = whsOtherDtl.getJSONObject(i);

                                // 从materialNoOut, qtyOut,storageOut出
                                double qtyOut = dtl.getDouble("qtyOut");
                                String materialNoOut = dtl.getString("materialNoOut");
                                String rowId = dtl.getString("rowId");

                                if (qtyOut > 0) {
                                    JSONArray tempStorage = dtl.containsKey("storageOut") ? dtl.getJSONArray("storageOut") : null;
                                    if (null == tempStorage || tempStorage.size() <= 0) {
                                        throw new Exception("error for " + materialNoOut + ", storageOutInfo can not be null");
                                    }
                                    ResponseResult checkInvRes = whsStorageInventoryService.checkStorageInventory(tempStorage, materialNoOut);
                                    if (checkInvRes.getCode() != 200) {
                                        throw new Exception(checkInvRes.getMsg());
                                    }
                                    ;

                                    for (int k = 0; k < tempStorage.size(); k++) {
                                        JSONObject storage = tempStorage.getJSONObject(k);
                                        String storageUuid = storage.getString("storageUuid");
                                        double qty = storage.getDouble("qty");
                                        String storageNo = storage.getString("storageNo");
                                        if (StringUtils.isEmpty(storageUuid) || StringUtils.isEmpty(storageNo) || qty <= 0) {
                                            throw new Exception("error for " + materialNoOut + " on storage Info, storageUuid: " +
                                                    storageUuid + ",storageNo:" + storageNo +
                                                    ", qty: " + qty);
                                        }
                                        // 扣减储位库存
                                        if (whsStorageInventoryService.updateWhsStorage(storageUuid, materialNoOut, qty) < 0) {
                                            throw new Exception("Update Storage Inventory failed for " + materialNoOut + " on storageOut Info, storageUuid: " +
                                                    storageUuid + ",storageNo:" + storageNo +
                                                    ", qty: " + qty);
                                        }


                                        iWhsOperateLogService.insertWhsOperateLog(
                                                Constans.WhsOperateLog_DocumentType_NanShaStorageLog,
                                                storageUuid,
                                                materialNoOut,
                                                "",
                                                qty,
                                                Constans.WhsOperateLog_OperationType_ShelfOff,
                                                uuid,
                                                Constans.WHS_OTHER_PartAdjustment_Out,
                                                userId,
                                                Constans.WHS_OTHER_PartAdjustment,
                                                werks,
                                                whsLocationCode, rowId);
                                    }
                                }
                                // 从materialNoIn,qtyIn,storageIn入
                                double qtyIn = dtl.getDouble("qtyIn");
                                String materialNoIn = dtl.getString("materialNoIn");
                                if (qtyIn > 0) {
                                    JSONArray tempStorage = dtl.containsKey("storageIn") ? dtl.getJSONArray("storageIn") : null;
                                    if (null == tempStorage || tempStorage.size() <= 0) {
                                        throw new Exception("error for " + materialNoIn + ", storage In Info can not be null");
                                    }
                                    for (int k = 0; k < tempStorage.size(); k++) {
                                        JSONObject storage = tempStorage.getJSONObject(k);
                                        String storageUuid = storage.getString("storageUuid");
                                        double qty = storage.getDouble("qty");
                                        String storageNo = storage.getString("storageNo");
                                        if (StringUtils.isEmpty(storageUuid) || StringUtils.isEmpty(storageNo) || qty <= 0) {
                                            throw new Exception("error for " + materialNoIn + " on storage Info, storageUuid: " +
                                                    storageUuid + ",storageNo:" + storageNo +
                                                    ", qty: " + qty);
                                        }
                                        if (whsStorageInventoryService.updateWhsStorageInventoryMOld(storageUuid, materialNoIn, qty) < 0) {
                                            throw new Exception("Update Storage Inventory failed for " + materialNoIn + " on storage Info, storageUuid: " +
                                                    storageUuid + ",storageNo:" + storageNo +
                                                    ", qty: " + qty);
                                        }
                                        iWhsOperateLogService.insertWhsOperateLog(
                                                Constans.WhsOperateLog_DocumentType_NanShaStorageLog,
                                                storageUuid,
                                                materialNoIn,
                                                "",
                                                qty,
                                                Constans.WhsOperateLog_OperationType_ShelfOn,
                                                uuid,
                                                Constans.WHS_OTHER_PartAdjustment_In,
                                                userId,
                                                Constans.WHS_OTHER_PartAdjustment,
                                                werks,
                                                whsLocationCode, rowId);
                                    }
                                }
                            }
                        } else {
                            // 暂不支持备件串货调整
                        }

                        //更新入库单状态为关闭
                        whsOtherTask.setTaskStatus(ConstantWhsOther.StatusClosed);
                        this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                        iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.completedDocument);
                    } else {
                        throw new Exception(JSON.toJSONString(syncSAPRes.getData()));
                    }
                } else {
                    // 如果uuid 不为空，并且targetStatus 不为 StatusClosed，只保存
                    whsOtherTask.setTaskStatus(targetStatus);
                    this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid));
                    iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(uuid, userId, ConstantWhsOther.updateDocument);
                }
                return dtlUpdateRes.add("whsOther", this.baseMapper.selectOne(new QueryWrapper<WhsOtherUnload>().eq("UUID", uuid)));
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error(e.getMessage());
        }
    }

    /**
     * 退货出库————退货订单获取接口，输入交货单号，采购订单号等信息向SAP REST请求获取退货订单信息
     */
    @Override
    public ResponseResult getSapReturnedOrder(String deliveryNoteSap, String purchaseOrderNo,String werks) {
        try {
            JSONObject dataToSap = 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");
            // 根据工厂查询对应的SAP Clinet
            List<ZSapOrgClient> selectList = zSapOrgClientMapper.selectList(new QueryWrapper<ZSapOrgClient>().eq("WERKS", werks));
            if (CollectionUtils.isNotEmpty(selectList)) {
                ESB_ATTRS.put("Target_ID", "SAP-"+selectList.get(0).getZmandt());
            } else {
                throw new Exception("工厂："+werks+"未找到对应的SAP Clinet");
            }
            ESB_ATTRS.put("Application_ID", "00020000000002");
            ESB_ATTRS.put("Transaction_ID", UUID.randomUUID().toString());

            Head.put("I_VBELN", "");
            Head.put("I_DATES", "");
            Head.put("I_DATEE", "");
            Head.put("I_WERKS", werks);
            Head.put("I_EBELN", purchaseOrderNo);
            Head.put("I_FLAG", "05");

            REQUEST_DATA.put("fileds", Head);
            REQUEST_DATA.put("Operation", "Z_SPMS_GETHWDN");
            REQUEST_DATA.put("Type", "GETHWDN");

            REQUEST.put("ESB_ATTRS", ESB_ATTRS);
            REQUEST.put("REQUEST_DATA", REQUEST_DATA);
            dataToSap.put("REQUEST", REQUEST);
            JSONObject message = JSONObject.parseObject(iFeignServiceCommon.sendRestToSapCommon((dataToSap)));
            if ("E".equals(message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA").getString("O_TYPE"))) {
                return ResponseResult.error("从SAP获取采购订单失败").add("dataToSap", dataToSap).add("sendSapReturnedMessage", message);
            }
            return ResponseResult.success("从SAP获取采购订单成功")
                    .add("sapReturnedOrder", formatSapReturnedData(message))
                    .add("dataToSap", dataToSap)
                    .add("sendSapReturnedMessage", message);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error().add("error", e.getMessage());
        }
    }

    JSONObject formatSapReturnedData(JSONObject message) {
        JSONObject doc = new JSONObject();
        JSONObject purchaseOrder = new JSONObject();
        JSONArray purchaseOrderDtl = new JSONArray();
        JSONArray deliveryNoteDtl = new JSONArray();

        /** 采购订单表，每次只会有一条 */
        JSONArray IT_EKKO = message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA").getJSONArray("IT_EKKO");

        /** 采购订单明细表 */
        JSONArray IT_EKPO = message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA").getJSONArray("IT_EKPO");

        /** 交货单明细表 */
        JSONArray IT_LIPS = message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA").getJSONArray("IT_LIPS");

        if (IT_EKKO.size() > 0) {
            JSONObject tempDoc = IT_EKKO.getJSONObject(0);
            if (tempDoc != null) {
                purchaseOrder.put("purchaseOrderNo", tempDoc.getString("EBELN"));
                purchaseOrder.put("voucherType", tempDoc.getString("BSART"));
                purchaseOrder.put("createDate", tempDoc.getString("AEDAT"));
                purchaseOrder.put("purchaseGroup", tempDoc.getString("EKGRP"));
                purchaseOrder.put("purchaseOrg", tempDoc.getString("EKORG"));
                purchaseOrder.put("createUserId", tempDoc.getString("ERNAM"));
                purchaseOrder.put("supplierNo", tempDoc.getString("LIFNR"));
            }
        }

        if (IT_EKPO.size() > 0) {
            for (int i = 0; i < IT_EKPO.size(); i++) {
                JSONObject tempDoc = IT_EKPO.getJSONObject(i);
                JSONObject docTemp = new JSONObject();
                String materialNo = tempDoc.getString("MATNR").replaceFirst("^0*", "");
                docTemp.put("purchaseOrderNo", tempDoc.getString("EBELN"));
                docTemp.put("purchaseOrderItem", String.valueOf(Integer.parseInt(tempDoc.getString("EBELP").trim())));
                docTemp.put("werks", tempDoc.getString("WERKS"));
                docTemp.put("whsLocationCode", tempDoc.getString("LGORT"));
                docTemp.put("materialNo", materialNo);

                Map<String, Object> materialInfo = this.baseMapper.getNumeratorDenominator(materialNo);
                docTemp.put("numerator", Double.parseDouble(materialInfo.get("numerator").toString()));
                docTemp.put("denominator", Double.parseDouble(materialInfo.get("denominator").toString()));
                docTemp.put("materialZhDesc", materialInfo.get("materialZhDesc").toString());
                docTemp.put("materialEnDesc", materialInfo.get("materialEnDesc").toString());
                docTemp.put("unitSales", materialInfo.get("unitSales").toString());

                docTemp.put("deliveryUnit", tempDoc.getString("MEINS"));
                docTemp.put("deliveryQty", tempDoc.getString("MENGE"));
                docTemp.put("deliveryDate", tempDoc.getString("EINDT"));
                docTemp.put("remark", tempDoc.getString("TXZ01"));
                docTemp.put("RETPO", tempDoc.getString("RETPO"));
                purchaseOrderDtl.add(docTemp);
            }
        }

        if (IT_LIPS.size() > 0) {
            for (int i = 0; i < IT_LIPS.size(); i++) {
                JSONObject tempDoc = IT_LIPS.getJSONObject(i);
                JSONObject docTemp = new JSONObject();
                docTemp.put("deliveryNote", tempDoc.getString("VBELN"));
                docTemp.put("deliveryNoteItem", String.valueOf(Integer.parseInt(tempDoc.getString("POSNR").trim())));
                docTemp.put("werks", tempDoc.getString("WERKS"));
                docTemp.put("whsLocationCode", tempDoc.getString("LGORT"));
                docTemp.put("purchaseOrderNo", tempDoc.getString("VGBEL"));
                docTemp.put("purchaseOrderItem", String.valueOf(Integer.parseInt(tempDoc.getString("VGPOS").trim())));
                docTemp.put("unitSales", tempDoc.getString("VRKME"));
                docTemp.put("qtyUnitSales", tempDoc.getString("LFIMG"));
                docTemp.put("qtyBasicUnit", tempDoc.getString("LGMNG"));
                docTemp.put("basicUnit", tempDoc.getString("MEINS"));
                deliveryNoteDtl.add(docTemp);
            }
        }
        doc.put("purchaseOrder", purchaseOrder);
        doc.put("purchaseOrderDtl", purchaseOrderDtl);
        doc.put("deliveryNoteDtl", deliveryNoteDtl);
        return doc;
    }

    /**
     * 其他出入库，海运出库，结果提交SAP，f1afdf55a6e44b2383d5e98d896dae65，
     * 单据状态 0-作废 1-草稿 2-操作中 3-待提交SAP 4-提交SAP成功 5-提交SAP失败 6-关闭
     */
    ResponseResult whsOtherPackageListToSap(String userId, String whsOtherUuid) {
        if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(whsOtherUuid)) {
            return ResponseResult.error("请求参数错误");
        }
        QueryWrapper<WhsOtherUnload> queryWrapper = new QueryWrapper<WhsOtherUnload>().eq("UUID", whsOtherUuid);
        WhsOtherUnload otherTask = this.baseMapper.selectOne(queryWrapper);
        if (otherTask == null || !("3".equals(otherTask.getTaskStatus()) || "5".equals(otherTask.getTaskStatus()))) {
            return ResponseResult.error("当前状态禁止提交", 400);
        }
        if (otherTask.getPackageList() == null) {
            return ResponseResult.error("其他出入库装箱单号数据错误");
        }
        List<Map<String, Object>> whsOtherPLDataToSap = new ArrayList<>();
        if ("M".equals(otherTask.getGoodsType())){
            whsOtherPLDataToSap = this.baseMapper.whsOtherPackageListToSapM(whsOtherUuid);
        } else {
            whsOtherPLDataToSap = this.baseMapper.whsOtherPackageListToSapX(whsOtherUuid);
        }

        if (whsOtherPLDataToSap == null || whsOtherPLDataToSap.size() == 0) {
            return ResponseResult.error("查询没有可提交SAP的数据");
        }
        /** confirmLastSubmission 默认赋值 0-不是同装箱单下最后一个提交SAP的海运出库任务；当 getWhsOutStatusCount 查询结果为 0 时则当前
         * 其他出入库-海运出库 任务即为 最后一次提交SAP的任务，提交SAP需额外附带一些信息 */
        String confirmLastSubmission = "0";
        if ("0".equals(this.baseMapper.getWhsOutStatusCount(otherTask.getPackageList()))) {
            confirmLastSubmission = "1";
        }
        JSONObject dataFormatPL = whsOtherPackageListToSapFormat(whsOtherPLDataToSap, otherTask.getPackageList(), confirmLastSubmission, otherTask.getGoodsType());
        System.out.println(dataFormatPL);
        JSONObject message = JSONObject.parseObject(iFeignServiceCommon.sendRestToSapCommon((dataFormatPL)));
        System.out.println(message);
        if (message.containsKey("RESPONSE") && message.getJSONObject("RESPONSE").containsKey("RETURN_DATA")
                && "S".equals(message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA").getString("EX_TYPE"))) {
            // 海运出库提交SAP暂时没有整单的返回 凭证 和 凭证年份 字段
            // otherTask.setSapVoucherNumber(message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA").getString("O_MBLNR"));
            // otherTask.setSapVoucherYear(message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA").getString("O_MJAHR"));
            otherTask.setTaskStatus(ConstantWhsOther.StatusSapSuccessed);
            this.baseMapper.update(otherTask, queryWrapper);
            iSapDeliveryNoteLogService.insertSapRequestRecord(whsOtherUuid, userId, ConstantWhsOther.sendToSAP, message.toJSONString(), dataFormatPL.toJSONString());
            return ResponseResult.success().add("dataToSap", dataFormatPL).add("sapReturnedData", message);
        }
        otherTask.setTaskStatus(ConstantWhsOther.StatusSapFailed);
        this.baseMapper.update(otherTask, queryWrapper);
        iSapDeliveryNoteLogService.insertSapRequestRecord(whsOtherUuid, userId, ConstantWhsOther.sendToSAPError, message.toJSONString(), dataFormatPL.toJSONString());
        return ResponseResult.error().add("dataToSap", dataFormatPL).add("sapReturnedData", message);
    }

    /**
     * 其他出入库 - 海运出库 - 数据提交SAP格式化
     */
    JSONObject whsOtherPackageListToSapFormat(List<Map<String, Object>> whsOtherPLDataToSap, String packageList, String confirmLastSubmission, String goodsType) {
        JSONObject obj = new JSONObject();
        JSONObject REQUEST = new JSONObject();
        JSONObject ESB_ATTRS = new JSONObject();
        JSONObject REQUEST_DATA = new JSONObject();
        JSONObject Head = new JSONObject();
        JSONObject MapItems = new JSONObject();
        JSONArray PT_INPUT_LIST = new JSONArray();
        JSONArray PT_STATE = new JSONArray();
        List<Map<String, Object>> PT_CONFIRM = new ArrayList<>();

        ESB_ATTRS.put("App_ID", "SPMS");
        ESB_ATTRS.put("Application_ID", "00020000000002");
        ESB_ATTRS.put("Transaction_ID", UUID.randomUUID().toString());

        Head.put("imImportFlag", "A");

        REQUEST_DATA.put("Head", Head);
        REQUEST_DATA.put("Operation", "Z_ZXD_IMPROT_AND_CONFIRM");
        REQUEST_DATA.put("Type", "IMPROT_AND_CONFIRM");

        for (int i = 0; i < whsOtherPLDataToSap.size(); i++) {
            JSONObject tempDoc = new JSONObject();
            tempDoc.put("zxdidEx", whsOtherPLDataToSap.get(i).get("itemNo").toString());
            tempDoc.put("zspmsTaskid", whsOtherPLDataToSap.get(i).get("uuid").toString());
            tempDoc.put("xdnum", whsOtherPLDataToSap.get(i).get("packageList").toString());
            tempDoc.put("cabno", whsOtherPLDataToSap.get(i).get("cabinetNumber").toString());
            tempDoc.put("azdat", whsOtherPLDataToSap.get(i).get("actualLoadingDate").toString().replaceAll("-", ""));
            tempDoc.put("algort", whsOtherPLDataToSap.get(i).get("whsLocationCode").toString());
            tempDoc.put("algobe", whsOtherPLDataToSap.get(i).get("whsLocationDesc").toString());
            tempDoc.put("sealn", whsOtherPLDataToSap.get(i).get("leadSeal") == null ? "" : whsOtherPLDataToSap.get(i).get("leadSeal"));
            tempDoc.put("matnr", whsOtherPLDataToSap.get(i).get("materialNo").toString());
            tempDoc.put("maktx", whsOtherPLDataToSap.get(i).get("materialZhDesc").toString());
            /** vrkme 销售单位；aemng 实际装箱件数；meins 基本计量单位——留空; ameng 实际装箱数量——留空; cdQty 报关件数; */
            tempDoc.put("vrkme", whsOtherPLDataToSap.get(i).get("unitSales").toString());
            tempDoc.put("meins", whsOtherPLDataToSap.get(i).get("basicUnit").toString());
            tempDoc.put("ameng", whsOtherPLDataToSap.get(i).get("operateQty") == null ? "0" : whsOtherPLDataToSap.get(i).get("operateQty").toString());
            /** bzgg 包装规格; jyjg 货柜检验结果; kgBrgew 空柜重量（KG）; wxBrand 外箱品牌;  */
            tempDoc.put("bzgg", whsOtherPLDataToSap.get(i).get("packingSpec") == null ? "" : whsOtherPLDataToSap.get(i).get("packingSpec"));
            tempDoc.put("jyjg", whsOtherPLDataToSap.get(i).get("cabinetCheckResult") == null ? "" : whsOtherPLDataToSap.get(i).get("cabinetCheckResult"));
            tempDoc.put("kgBrgew", whsOtherPLDataToSap.get(i).get("emptyCabinetWeight") == null ? "" : whsOtherPLDataToSap.get(i).get("emptyCabinetWeight").toString());
            tempDoc.put("wxBrand", whsOtherPLDataToSap.get(i).get("containerBrand") == null ? "" : whsOtherPLDataToSap.get(i).get("containerBrand"));
            if ("M".equals(goodsType)) {
                /** aemng 实际装箱件数；cdQty 报关件数； */
                tempDoc.put("cdQty", null == whsOtherPLDataToSap.get(i).get("customsDeclarationNumber") ? "" : whsOtherPLDataToSap.get(i).get("customsDeclarationNumber").toString());
                tempDoc.put("aemng", null == whsOtherPLDataToSap.get(i).get("packingQty") ? "0" : whsOtherPLDataToSap.get(i).get("packingQty").toString());
                tempDoc.put("colorCode", whsOtherPLDataToSap.get(i).get("colorNumber") == null ? "" : whsOtherPLDataToSap.get(i).get("colorNumber").toString());
                tempDoc.put("zh", whsOtherPLDataToSap.get(i).get("thickness") == null ? "" : whsOtherPLDataToSap.get(i).get("thickness").toString());
                tempDoc.put("cpsjpjBrgew", whsOtherPLDataToSap.get(i).get("actualAvgGrossWeight") == null ? "" : whsOtherPLDataToSap.get(i).get("actualAvgGrossWeight").toString());
            }else {
                /** 备件货实际装箱件数，由国内实际数量字段、销售单位和基本单位换算分子分母关系，计算得出保留三位小数；cdQty 报关件数备件货传空； */
                double actualOperateQty = whsOtherPLDataToSap.get(i).get("operateQty") == null ? 0 : Double.parseDouble(whsOtherPLDataToSap.get(i).get("operateQty").toString());
                double numerator = Double.parseDouble(whsOtherPLDataToSap.get(i).get("numerator").toString());
                double denominator = Double.parseDouble(whsOtherPLDataToSap.get(i).get("denominator").toString());
                String actualPackingNumber = String.format("%.3f", (denominator / numerator) * actualOperateQty);
                tempDoc.put("aemng", actualPackingNumber);
                tempDoc.put("cdQty", "");
                tempDoc.put("colorCode", "");
                tempDoc.put("zh", "");
                tempDoc.put("cpsjpjBrgew", "");
                /** 备件货国内出库结果回传SAP信息结构带上箱码、箱码行号 —— 20211116 */
                tempDoc.put("serial", whsOtherPLDataToSap.get(i).get("boxNoteItem").toString());
                tempDoc.put("boxCode", whsOtherPLDataToSap.get(i).get("boxNote").toString());
            }
            tempDoc.put("jzry", whsOtherPLDataToSap.get(i).get("monitorLoading") == null ? "" : whsOtherPLDataToSap.get(i).get("monitorLoading"));
            tempDoc.put("zgfs", whsOtherPLDataToSap.get(i).get("loadingType") == null ? "" : whsOtherPLDataToSap.get(i).get("loadingType"));
            tempDoc.put("mark", whsOtherPLDataToSap.get(i).get("remarks") == null ? "" : whsOtherPLDataToSap.get(i).get("remarks"));
            tempDoc.put("pkmakYn", "N");
            tempDoc.put("del", "");
            tempDoc.put("importFlag", "A");
            PT_INPUT_LIST.add(tempDoc);
        }
        MapItems.put("PT_INPUT_LIST", PT_INPUT_LIST);
        if ("1".equals(confirmLastSubmission)) {
            JSONObject tempDoc = new JSONObject();
            tempDoc.put("xdnum", packageList);
            tempDoc.put("xzhj", "2");
            tempDoc.put("curtu", "X");
            PT_STATE.add(tempDoc);
            MapItems.put("PT_STATE", PT_STATE);
            PT_CONFIRM = this.baseMapper.getPackageListBoxNote(packageList);
            MapItems.put("PT_CONFIRM", PT_CONFIRM);
        }
        REQUEST_DATA.put("MapItems", MapItems);
        REQUEST.put("ESB_ATTRS", ESB_ATTRS);
        REQUEST.put("REQUEST_DATA", REQUEST_DATA);

        obj.put("REQUEST", REQUEST);
        return obj;
    }

    /**
     * 其他出入库 - 串货调整 - 数据提交SAP
     */
    ResponseResult handlePartAdjustmentToSap(String userId, String whsOtherUuid) {
        QueryWrapper<WhsOtherUnload> queryWrapper = new QueryWrapper<WhsOtherUnload>().eq("UUID", whsOtherUuid);
        WhsOtherUnload otherTask = this.baseMapper.selectOne(queryWrapper);
        if (otherTask == null || !("3".equals(otherTask.getTaskStatus()) || "5".equals(otherTask.getTaskStatus()))) {
            return ResponseResult.error("当前状态禁止提交", 400);
        }
        Map<String, Object> Head = this.baseMapper.getWhsOtherTaskAdjustmentHead(whsOtherUuid);
        List<Map<String, Object>> Items = this.baseMapper.getWhsOtherTaskAdjustmentItems(whsOtherUuid);
        if (Head == null || Items == null || Items.size() == 0) {
            return ResponseResult.error("查询没有可提交SAP的数据");
        }
        return submitWhsOtherToSap(userId, whsOtherUuid, Head, Items, "Z_SPMS_ANOMALY_POST");
    }

	@Override
	public ResponseResult updateLoadingData(JSONObject doc, String userId) {
		if (doc == null){
            return ResponseResult.error();
        }
        String spmsId = doc.getString("spmsId");
        if (StringUtils.isEmpty(spmsId)){
            return ResponseResult.error("SPMS单号为空，请求失败");
        }
        QueryWrapper<WhsOtherUnload> queryWrapper = new QueryWrapper<WhsOtherUnload>().eq("SPMS_ID", spmsId);
        WhsOtherUnload sapDeliveryNote = this.baseMapper.selectOne(queryWrapper);
        if (sapDeliveryNote == null) {
        	return ResponseResult.error("SPMS单号："+spmsId+"不存在");
        }
        WhsOtherUnload updateVO = new WhsOtherUnload();
        updateVO.setUuid(sapDeliveryNote.getUuid());
        updateVO.setSpmsId(spmsId);
        updateVO.setBatchNo(doc.get("batchNo") == null ? "" : doc.getString("batchNo"));
        updateVO.setWarehouseKeeper(doc.get("warehouseKeeper") == null ? "" : doc.getString("warehouseKeeper"));
        updateVO.setToWarehouseTime(doc.get("toWarehouseTime") == null ? null : doc.getDate("toWarehouseTime"));
        updateVO.setStartOperationTime(doc.get("startOperationTime") == null ? null : doc.getDate("startOperationTime"));
        updateVO.setEndOperationTime(doc.get("endOperationTime") == null ? null : doc.getDate("endOperationTime"));
        updateVO.setHandlingGroup(doc.get("handlingGroup") == null ? "" : doc.getString("handlingGroup"));
        this.baseMapper.update(updateVO, queryWrapper);
		// 保存日志
        iSapDeliveryNoteLogService.insertSapRequestRecord(spmsId, userId, ConstantWhsOther.updateLoadData,
                "更新前数据："+JSONObject.toJSONString(sapDeliveryNote), "更新后数据："+JSONObject.toJSONString(updateVO));
		return ResponseResult.success();
	}

	@Override
	public Map<String, Object> getLoadingData(String spmsId) {
		Map<String, Object> map = this.baseMapper.selectLoadingData(spmsId);
		return map;
	}

    @Override
    public ResponseResult updateWhsOtherTask(WhsOtherUnload doc, String userId) throws  Exception {
        String spmsId = doc.getSpmsId();
        if (StringUtils.isEmpty(spmsId)){
            throw new Exception("SPMS单号不能为空！");
        }
        this.baseMapper.update(doc, new QueryWrapper<WhsOtherUnload>().eq("SPMS_ID", spmsId));
        return ResponseResult.success();
    }

	@Override
	@Transactional(rollbackFor = Exception.class)
	public ResponseResult cancelWhsOtherTask(String userId, String whsOtherUuid, String cancelDate,
			String cancelRemark) throws Exception {
		if (StringUtils.isEmpty(whsOtherUuid) || StringUtils.isEmpty(cancelDate)){
            return ResponseResult.error("请求参数错误");
        }
        QueryWrapper<WhsOtherUnload> queryWrapper = new QueryWrapper<WhsOtherUnload>().eq("UUID", whsOtherUuid);
        WhsOtherUnload whsOtherTask = this.baseMapper.selectOne(queryWrapper);
        List<WhsOtherUnloadDtl> whsOtherDtlList = whsOtherDtlService.getWhsOtherDtlList(whsOtherUuid);
        ResponseResult resp = checkCancelWhsOtherTaskValidate(whsOtherTask, whsOtherDtlList);
        if (resp.getCode() != SUCCESS){
            return resp;
        }
		// 调用接口同步SAP
        if (ConstantWhsOther.InHouseUnload.equals(whsOtherTask.getMovementType())) {
        	List<Map<String, Object>> dataToSapItem = this.baseMapper.handleInHouseUnloadDataToSapItem(whsOtherUuid);
        	for (int i = 0; i < dataToSapItem.size(); i++) {
        		Map<String, Object> map = dataToSapItem.get(i);
        		map.put("LOEKZ", "X");
        	}
        	JSONObject dataToSap = this.setToSapData(dataToSapItem);
            log.info("======dataToSap=====" + dataToSap);
            JSONObject message = iDataToSap.submitDataToSap(dataToSap);
            log.info("======message=====" + message);
            String O_TYPE = message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA").getString("MSTYPE");
            if ("S".equals(O_TYPE)) {
            	// 更新状态为待处理
            	whsOtherTask.setTaskStatus(ConstantWhsOther.StatusDraft);
                whsOtherTask.setSapVoucherNumber(message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA").getString("MBLNR"));
                whsOtherTask.setSapVoucherYear(message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA").getString("MJAHR"));
                this.baseMapper.update(whsOtherTask, new QueryWrapper<WhsOtherUnload>().eq("UUID", whsOtherUuid));
                iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(whsOtherUuid, userId, ConstantWhsOther.sendToSAPCancel);
                iSapDeliveryNoteLogService.insertSapRequestRecord(whsOtherUuid, userId, ConstantWhsOther.sendToSAPCancel, message.toJSONString(), dataToSap.toJSONString());
            } else {
            	throw new Exception("撤销提交SAP失败："+message.toJSONString());
            }
            // 扣减库存
            this.unStorageWhsInventory(whsOtherTask, whsOtherDtlList, userId);
            return ResponseResult.success().add("dataToSap", dataToSap).add("sapReturnedData", message);
        }
        return ResponseResult.success("撤销成功");
	}

	private void unStorageWhsInventory(WhsOtherUnload whsOtherTask, List<WhsOtherUnloadDtl> whsOtherDtlList, String userId) throws Exception {
		if ("M".equals(whsOtherTask.getGoodsType())) {
            for (int i = 0; i < whsOtherDtlList.size(); i++) {
            	WhsOtherUnloadDtl dtl = whsOtherDtlList.get(i);
                double operateQty = dtl.getOperateQty();
                String materialNo = dtl.getMaterialNo();
                String rowId = dtl.getRowId()+"";
//                String packageList = dtl.getPackageList();
                if (operateQty > 0) {
                    JSONArray tempStorage = StringUtils.isNotEmpty(dtl.getTempStorage()) ? JSON.parseArray(dtl.getTempStorage()) : null;
                    if (null == tempStorage || tempStorage.size() <= 0) {
                        throw new Exception("error for " + materialNo + ", storageInfo can not be null");
                    }
                    for (int k = 0; k < tempStorage.size(); k++) {
                        JSONObject storage = tempStorage.getJSONObject(k);
                        String storageUuid = storage.getString("storageUuid");
                        double qty = storage.getDouble("qty");
                        String storageNo = storage.getString("storageNo");
                        if (StringUtils.isEmpty(storageUuid) || StringUtils.isEmpty(storageNo) || qty <= 0) {
                            throw new Exception("error for " + materialNo + " on storage Info, storageUuid: " +
                                    storageUuid + ",storageNo:" + storageNo +
                                    ", qty: " + qty);
                        }
                        if (whsStorageInventoryService.updateWhsStorage(storageUuid, materialNo, qty) < 0) {
                            throw new Exception("Update Storage Inventory failed for " + materialNo + " on storage Info, storageUuid: " +
                                    storageUuid + ",storageNo:" + storageNo +
                                    ", qty: " + qty);
                        }
                        iWhsOperateLogService.insertWhsOperateLog(
                                Constans.WhsOperateLog_DocumentType_NanShaStorageLog,
                                storageUuid,
                                materialNo,
                                "",
                                qty,
                                "20",
                                whsOtherTask.getUuid(),
                                Constans.WHS_OTHER_InHouseUnload,
                                userId,
                                Constans.WHS_WhsIn_WithdrawM,
                                whsOtherTask.getWerks(),
                                whsOtherTask.getWhsLocationCode(), rowId);
                    }
                }
            }
        } else {
            for (int i = 0; i < whsOtherDtlList.size(); i++) {
            	WhsOtherUnloadDtl dtl = whsOtherDtlList.get(i);
                double operateQty = dtl.getOperateQty();
                String boxNote = dtl.getBoxNote();
                String rowId = dtl.getRowId()+"";
//                String packageList = dtl.getPackageList();
                if (operateQty > 0) {
                    JSONArray tempStorage = StringUtils.isNotEmpty(dtl.getTempStorage()) ? JSON.parseArray(dtl.getTempStorage()) : null;
                    if (null == tempStorage || tempStorage.size() <= 0) {
                        throw new Exception("error for " + boxNote + ", storageInfo can not be null");
                    }
                    JSONObject storage = tempStorage.getJSONObject(0);
                    String storageUuid = storage.getString("storageUuid");
                    double qty = storage.getDouble("qty");
                    String storageNo = storage.getString("storageNo");
                    if (StringUtils.isEmpty(storageUuid) || StringUtils.isEmpty(storageNo)) {
                        throw new Exception("error for " + boxNote + " on storage Info, storageUuid: " +
                                storageUuid + ",storageNo:" + storageNo +
                                ", qty: " + qty);
                    }
                    ResponseResult updateStorageInvX = whsStorageInventoryService.updateStorageInvX(storageUuid, boxNote, qty, "sub");
                    if (!SUCCESS.equals(updateStorageInvX.getCode())){
                    	throw new Exception("卸货入库撤销备件扣减储位库存失败："+JSONObject.toJSONString(updateStorageInvX));
                    }
                    iWhsOperateLogService.insertWhsOperateLog(
                            Constans.WhsOperateLog_DocumentType_NanShaStorageLog,
                            storageUuid,
                            "",
                            boxNote,
                            1,
                            Constans.WhsOperateLog_OperationType_ShelfOff,
                            whsOtherTask.getUuid(),
                            Constans.WHS_OTHER_InHouseUnload,
                            userId,
                            Constans.WHS_WhsIn_WithdrawX,
                            whsOtherTask.getWerks(),
                            whsOtherTask.getWhsLocationCode(), rowId);
                    ResponseResult updateWhsInventoryX = whsInventoryInfoService.updateWhsInventoryX(whsOtherTask.getWerks(),whsOtherTask.getWhsLocationCode(),boxNote,1,"sub",userId);
                    if (!SUCCESS.equals(updateWhsInventoryX.getCode())){
                    	throw new Exception("卸货入库撤销备件扣减仓库库存失败："+JSONObject.toJSONString(updateWhsInventoryX));
                    }
                    iWhsOperateLogService.insertWhsOperateLog(
                                    Constans.WhsOperateLog_DocumentType_NanShaWHSLog,
                                    "",
                                    "",
                                    boxNote,
                                    1,
                                    Constans.WhsOperateLog_OperationType_OutHouse,
                                    whsOtherTask.getUuid(),
                                    Constans.WHS_OTHER_InHouseUnload,
                                    userId,
                                    Constans.WHS_WhsIn_WithdrawX,
                                    whsOtherTask.getWerks(),
                                    whsOtherTask.getWhsLocationCode(), rowId);
                }
            }
        }
		
	}

	private ResponseResult checkCancelWhsOtherTaskValidate(WhsOtherUnload whsOtherTask, List<WhsOtherUnloadDtl> whsOtherDtlList) {
		if (null == whsOtherTask || null == whsOtherTask.getUuid()){
            return ResponseResult.error("卸货入库数据不存在");
        }
        if (null == whsOtherDtlList || whsOtherDtlList.size() == 0){
            return ResponseResult.error("卸货入库明细行不能为空");
        }
        if (StringUtils.isEmpty(whsOtherTask.getTaskStatus()) || !ConstantWhsOther.StatusSapFailed.equals(whsOtherTask.getTaskStatus())){
            return ResponseResult.error("卸货入库单据当前状态不允许撤销");
        }
        if (whsOtherTask.getMovementType().equals(ConstantWhsOther.InHouseUnload)){
            if (StringUtils.isEmpty(whsOtherTask.getSapVoucherNumber()) || StringUtils.isEmpty(whsOtherTask.getSapVoucherYear())){
                return ResponseResult.error("卸货入库 SAP凭证号 或 SAP凭证年份 不能为空");
            }
            if (StringUtils.isEmpty(whsOtherTask.getPackageList())){
                return ResponseResult.error("卸货入库 装箱单号不能为空");
            }
            if ("M".equals(whsOtherTask.getGoodsType())){
                for (WhsOtherUnloadDtl whsOtherDtl : whsOtherDtlList){
                    if (whsOtherDtl.getOperateQty() > 0){
                        JSONArray tempStorage = JSONArray.parseArray(whsOtherDtl.getTempStorage());
                        String materialNo = whsOtherDtl.getMaterialNo();
                        if (null == tempStorage || tempStorage.size() == 0){
                            return ResponseResult.error("卸货入库明细行物料" + whsOtherDtl.getMaterialNo() + "储位信息错误");
                        }
                        ResponseResult checkInventoryResult = whsStorageInventoryService.checkStorageInventory(tempStorage, materialNo);
                        if (!SUCCESS.equals(checkInventoryResult.getCode())){
                        	return checkInventoryResult;
                        }
                    }
                }
            }
        }
        return ResponseResult.success();
	}


}



