package com.sunda.spmsoversea.service.impl;

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.sunda.spmscommon.ResponseResult;
import com.sunda.spmscommon.entity.ZSapOrgClient;
import com.sunda.spmscommon.feign.IFeignServiceCommon;
import com.sunda.spmscommon.mapper.ZSapOrgClientMapper;
import com.sunda.spmsoversea.dto.*;
import com.sunda.spmsoversea.entity.OverseaRequisition;
import com.sunda.spmsoversea.entity.OverseaRequisitionDtl;
import com.sunda.spmsoversea.entity.OverseaWhsOut;
import com.sunda.spmsoversea.entity.OverseaWhsOutDtl;
import com.sunda.spmsoversea.enums.OverseaRequisitionPrintEnum;
import com.sunda.spmsoversea.enums.OverseaWhsOutEnum;
import com.sunda.spmsoversea.mapper.OverseaRequisitionMapper;
import com.sunda.spmsoversea.mapper.WhsStorageInventoryMapper;
import com.sunda.spmsoversea.service.IOverseaOperateLogService;
import com.sunda.spmsoversea.service.IOverseaRequisitionDtlService;
import com.sunda.spmsoversea.service.IOverseaRequisitionService;
import com.sunda.spmsoversea.service.IOverseaWhsOutService;
import com.sunda.spmsoversea.service.IWhsStorageInventoryService;
import com.sunda.spmsuser.service.ISpmsRoleService;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.*;
import java.util.stream.Collectors;

import static com.sunda.spmsoversea.constant.CommonConstant.SUCCESS;
import static com.sunda.spmsoversea.constant.SapConstant.SAP_FAIL;
import static com.sunda.spmsoversea.constant.SapConstant.SAP_SUCCESS;
import static com.sunda.spmsoversea.constant.WhsStorageInventoryConstant.ADD;
import static com.sunda.spmsoversea.enums.OverseaRequisitionEnum.*;

/**
 * <p>
 * 领用申请表 服务实现类
 * </p>
 *
 * @author Wayne
 * @since 2021-09-22
 */
@Service
@Slf4j
public class OverseaRequisitionServiceImpl extends ServiceImpl<OverseaRequisitionMapper, OverseaRequisition> implements IOverseaRequisitionService {

    @Autowired
    IOverseaRequisitionDtlService iOverseaRequisitionDtlService;

    @Autowired
    IOverseaOperateLogService iOverseaOperateLogService;
    
    @Autowired
    @Lazy
    IOverseaWhsOutService iOverseaWhsOutService;
    
    @Autowired
    ISpmsRoleService iSpmsRoleService;

    @Autowired
    WhsStorageInventoryMapper whsStorageInventoryMapper;
    
    @Autowired
    IWhsStorageInventoryService iWhsStorageInventoryService;
    
    @Autowired
    IFeignServiceCommon iFeignServiceCommon;

    @Autowired
    ZSapOrgClientMapper zSapOrgClientMapper;

    @Override
    public IPage getOverseaRequisitionPage(OverseaRequisitionQueryDTO overseaRequisitionQueryDTO) {
        IPage iPage = overseaRequisitionQueryDTO.getPage();
        List<Map<String, Object>> mapList = this.baseMapper.getOverseaRequisitionIPage(iPage, overseaRequisitionQueryDTO);
        iPage.setRecords(mapList);
        return iPage;
    }

    @Override
    public IPage getOverseaRequisitionReport(OverseaRequisitionReportDTO overseaRequisitionReportDTO) {
        IPage iPage = overseaRequisitionReportDTO.getPage();
        List<Map<String, Object>> mapList = this.baseMapper.getOverseaRequisitionReport(iPage, overseaRequisitionReportDTO);
        iPage.setRecords(mapList);
        return iPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized ResponseResult createOverseaRequisition(OverseaRequisitionDTO overseaRequisitionDTO, String userId) throws Exception {
        ResponseResult checkResult = checkDataValidateCreate(overseaRequisitionDTO);
        if (checkResult.getCode() != SUCCESS){
            return checkResult;
        }
        String uuidRequisition = UUID.randomUUID().toString().replaceAll("-","").toLowerCase();
//        try {
            int addRequisitionResult = addOverseaRequisition(uuidRequisition, overseaRequisitionDTO, userId);
            if (addRequisitionResult < 1){
                throw new RuntimeException("创建领用申请表头错误");
            }

            int addRequisitionDtlResult = addOverseaRequisitionDtl(uuidRequisition, overseaRequisitionDTO);
            if (addRequisitionDtlResult < 1){
                throw new RuntimeException("创建领用申请明细错误");
            }

            iOverseaOperateLogService.addOverseaOperateLog(userId, uuidRequisition, REQUISITION_CREATE.getDescZh(), REQUISITION_CREATE.getDescEn(), "", REQUISITION_CREATE.getDescRu());
            if (REQUISITION_PENDING_APPROVAL.getCode().equals(overseaRequisitionDTO.getSpmsStatus())){
                iOverseaOperateLogService.addOverseaOperateLog(userId, uuidRequisition, REQUISITION_PENDING_APPROVAL.getDescZh(), REQUISITION_PENDING_APPROVAL.getDescEn(), "", REQUISITION_PENDING_APPROVAL.getDescRu());
            }
            return getRequisitionAndDtl(uuidRequisition);
//        }catch (Exception e){
//            e.printStackTrace();
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//            return ResponseResult.error("请求执行过程出错请重试").add("error", e.getMessage());
//        }
    }

    @Override
    public ResponseResult getRequisitionAndDtl(String uuidRequisition) {
        if (StringUtils.isEmpty(uuidRequisition)){
            return ResponseResult.error("请求参数不能为空");
        }
        List<Map<String, Object>> overseaRequisitionDtlList = iOverseaRequisitionDtlService.getRequisitionDtlList(uuidRequisition);
        List<Map<String, Object>> marmList = new ArrayList<Map<String, Object>>();
        if(overseaRequisitionDtlList!=null && overseaRequisitionDtlList.size()>0){
            List<String> materialNo = new ArrayList<String>();
            for (int i = 0; i < overseaRequisitionDtlList.size(); i++){
                materialNo.add(overseaRequisitionDtlList.get(i).get("materialNo").toString());
            }
            marmList = whsStorageInventoryMapper.getMaterialMarmByNo(materialNo);
        }

        Map<String, Object> ovr = this.baseMapper.getOverseaRequisition(uuidRequisition);
        ovr.put("werksClient", "SD");//森大端的领用单
        List<ZSapOrgClient> selectList = zSapOrgClientMapper.selectList(new QueryWrapper<ZSapOrgClient>().eq("WERKS", ovr.get("werks").toString()));
        if (CollectionUtils.isNotEmpty(selectList)) {
            String zmandt = selectList.get(0).getZmandt();
            if ("510".equals(zmandt) || "810".equals(zmandt)) {//IPO的工厂
                ovr.put("werksClient", "FM");
            }else if ("520".equals(zmandt) || "820".equals(zmandt)) {//黑犀牛的工厂
                ovr.put("werksClient", "KD");
            }  else {
                ovr.put("werksClient", "SD");//森大端的领用单
            }
        }
        return ResponseResult.success()
                .add("overseaRequisition", ovr)
                .add("overseaRequisitionDtlList",overseaRequisitionDtlList )
                .add("marmList",marmList );
    }

    ResponseResult checkDataValidateCreate(OverseaRequisitionDTO overseaRequisitionDTO){
        if (overseaRequisitionDTO == null || StringUtils.isEmpty(overseaRequisitionDTO.getCreateDate()) ||
                StringUtils.isEmpty(overseaRequisitionDTO.getSpmsStatus()) || StringUtils.isEmpty(overseaRequisitionDTO.getWerks()) ||
                        StringUtils.isEmpty(overseaRequisitionDTO.getWhsLocationCode()) || StringUtils.isEmpty(overseaRequisitionDTO.getWorkshopCode())){
            return ResponseResult.error("请求参数错误");
        }
        String spmsStatus = overseaRequisitionDTO.getSpmsStatus();
        if (!spmsStatus.equals(REQUISITION_TO_SUBMIT.getCode()) && !spmsStatus.equals(REQUISITION_PENDING_APPROVAL.getCode())){
            return ResponseResult.error("请求单据状态不正确");
        }
        List<OverseaRequisitionDtlDTO> overseaRequisitionDtlDTOList = overseaRequisitionDTO.getRequisitionDtlDTOList();
        if (overseaRequisitionDtlDTOList == null || overseaRequisitionDtlDTOList.size() == 0){
            return ResponseResult.error("请求数据明细不能为空");
        }
        for (OverseaRequisitionDtlDTO overseaRequisitionDtlDTO : overseaRequisitionDtlDTOList){
            if (StringUtils.isEmpty(overseaRequisitionDtlDTO.getMaterialNo())){
                return ResponseResult.error("领用申请明细数据错误");
            }
        }
        return ResponseResult.success();
    }

    int addOverseaRequisition(String uuidRequisition, OverseaRequisitionDTO overseaRequisitionDTO, String userId){
        try {
            OverseaRequisition overseaRequisition = new OverseaRequisition();
            overseaRequisition.setUuidRequisition(uuidRequisition);
            overseaRequisition.setCreateDate(overseaRequisitionDTO.getCreateDate());
            overseaRequisition.setBusinessType(overseaRequisitionDTO.getBusinessType());
            overseaRequisition.setSpmsStatus(overseaRequisitionDTO.getSpmsStatus());
            overseaRequisition.setCreateUserid(userId);
            overseaRequisition.setWerks(overseaRequisitionDTO.getWerks());
            overseaRequisition.setWorkshopCode(overseaRequisitionDTO.getWorkshopCode());
            overseaRequisition.setWhsLocationCode(overseaRequisitionDTO.getWhsLocationCode());
            overseaRequisition.setRelateDocument(overseaRequisitionDTO.getRelateDocument());
            overseaRequisition.setCostCenter(overseaRequisitionDTO.getCostCenter());
            overseaRequisition.setCostCenterName(overseaRequisitionDTO.getCostCenterName());
            overseaRequisition.setRemarks(overseaRequisitionDTO.getRemarks());
            overseaRequisition.setComments(overseaRequisitionDTO.getComments());
            overseaRequisition.setOaNumber(overseaRequisitionDTO.getOaNumber());
            return this.baseMapper.insert(overseaRequisition);
        }catch (Exception e){
            e.printStackTrace();
            return -1;
        }
    }

    int addOverseaRequisitionDtl(String uuidRequisition, OverseaRequisitionDTO overseaRequisitionDTO){
        int result = 0;
        try{
            List<OverseaRequisitionDtlDTO> overseaRequisitionDtlDTOList = overseaRequisitionDTO.getRequisitionDtlDTOList();
            for (int i = 0; i < overseaRequisitionDtlDTOList.size(); i ++){
                OverseaRequisitionDtlDTO dtlDTO = overseaRequisitionDtlDTOList.get(i);
                OverseaRequisitionDtl overseaRequisitionDtl = new OverseaRequisitionDtl();
                overseaRequisitionDtl.setUuidRequisition(uuidRequisition);
                overseaRequisitionDtl.setItem((i + 1) * 10);
                overseaRequisitionDtl.setWerks(overseaRequisitionDTO.getWerks());
                overseaRequisitionDtl.setWorkshopCode(overseaRequisitionDTO.getWorkshopCode());
                overseaRequisitionDtl.setWhsLocationCode(overseaRequisitionDTO.getWhsLocationCode());
                overseaRequisitionDtl.setMaterialNo(dtlDTO.getMaterialNo());
                overseaRequisitionDtl.setApplyQtyBasicUnit(dtlDTO.getApplyQtyBasicUnit());
                overseaRequisitionDtl.setActualQtyBasicUnit(dtlDTO.getActualQtyBasicUnit());
                overseaRequisitionDtl.setBasicUnit(dtlDTO.getBasicUnit());
                overseaRequisitionDtl.setApplyQtyUnitSales(dtlDTO.getApplyQtyUnitSales());
                overseaRequisitionDtl.setActualQtyUnitSales(dtlDTO.getActualQtyUnitSales());
                overseaRequisitionDtl.setUnitSales(dtlDTO.getUnitSales());
                overseaRequisitionDtl.setRemarks(dtlDTO.getRemarks());
                overseaRequisitionDtl.setMovementType(dtlDTO.getMovementType());
                overseaRequisitionDtl.setActualMovementType(dtlDTO.getActualMovementType());
                overseaRequisitionDtl.setStorageCode(dtlDTO.getStorageCode());
                overseaRequisitionDtl.setProjectOaNumber(dtlDTO.getProjectOaNumber());
                overseaRequisitionDtl.setCountry(dtlDTO.getCountry());
                overseaRequisitionDtl.setLicenseNo(dtlDTO.getLicenseNo());
                result += iOverseaRequisitionDtlService.addRequisitionDtl(overseaRequisitionDtl);
            }
            return result;
        } catch (Exception e){
            e.printStackTrace();
            return -1;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized ResponseResult updateOverseaRequisition(OverseaRequisitionDTO dto, String userId) throws Exception {
        ResponseResult checkResult = checkUpdateOverseaRequisition(dto);
        if (checkResult.getCode() != SUCCESS){
            return checkResult;
        }
//        try {
            String uuidRequisition = dto.getUuidRequisition();
            String spmsStatus = dto.getSpmsStatus();
            QueryWrapper<OverseaRequisition> queryWrapper = new QueryWrapper<OverseaRequisition>().eq("UUID_REQUISITION", uuidRequisition);

            for (int i = 0; i < dto.getRequisitionDtlDTOList().size(); i ++){
                int resp = iOverseaRequisitionDtlService.updateRequisitionDtl(dto.getRequisitionDtlDTOList().get(i));
                if (resp < 1){
                    throw new RuntimeException("领用申请明细数据更新出错，请刷新重试");
                }
            }

            OverseaRequisition requisition = this.baseMapper.selectOne(queryWrapper);
            requisition.setSpmsStatus(spmsStatus);
            requisition.setApprovalDate(dto.getApprovalDate());
            requisition.setCostCenter(dto.getCostCenter());
            requisition.setCostCenterName(dto.getCostCenterName());
            requisition.setRemarks(dto.getRemarks() == null ? "" : dto.getRemarks());
            requisition.setComments(dto.getComments() == null ? "" : dto.getComments());
            requisition.setOaNumber(dto.getOaNumber() == null ? "" : dto.getOaNumber());
            this.baseMapper.update(requisition, queryWrapper);

            if (spmsStatus.equals(REQUISITION_APPROVED.getCode())){
                iOverseaOperateLogService.addOverseaOperateLog(userId, uuidRequisition, REQUISITION_APPROVED.getDescZh(), REQUISITION_APPROVED.getDescEn(), "", REQUISITION_APPROVED.getDescRu());
            }
            if(spmsStatus.equals(REQUISITION_PENDING_APPROVAL.getCode())) {
                iOverseaOperateLogService.addOverseaOperateLog(userId, uuidRequisition, REQUISITION_PENDING_APPROVAL.getDescZh(), REQUISITION_PENDING_APPROVAL.getDescEn(), "", REQUISITION_PENDING_APPROVAL.getDescRu());
            }
            if(spmsStatus.equals(REQUISITION_TO_SUBMIT.getCode())) {
                iOverseaOperateLogService.addOverseaOperateLog(userId, uuidRequisition, REQUISITION_TO_SUBMIT.getDescZh(), REQUISITION_TO_SUBMIT.getDescEn(), "", REQUISITION_TO_SUBMIT.getDescRu());
            }
            if(spmsStatus.equals(REQUISITION_REJECT.getCode())){
                iOverseaOperateLogService.addOverseaOperateLog(userId, uuidRequisition, REQUISITION_UPDATE.getDescZh(), REQUISITION_UPDATE.getDescEn(), "", REQUISITION_UPDATE.getDescRu());
            }

            return getRequisitionAndDtl(uuidRequisition);
//        }catch (Exception e){
//            e.printStackTrace();
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//            return ResponseResult.error("请求执行过程出错请重试").add("error", e.getMessage());
//        }
    }

    ResponseResult checkUpdateOverseaRequisition(OverseaRequisitionDTO dto){
        if (dto == null || dto.getRequisitionDtlDTOList() == null || dto.getRequisitionDtlDTOList().size() == 0){
            return ResponseResult.error("请求参数错误");
        }
        if (StringUtils.isEmpty(dto.getUuidRequisition()) || dto.getDataVersion() == null || StringUtils.isEmpty(dto.getSpmsStatus())){
            return ResponseResult.error("请求参数错误");
        }
        if (!dto.getSpmsStatus().equals(REQUISITION_APPROVED.getCode()) &&
                !dto.getSpmsStatus().equals(REQUISITION_PENDING_APPROVAL.getCode()) &&
                !dto.getSpmsStatus().equals(REQUISITION_TO_SUBMIT.getCode()) &&
                !dto.getSpmsStatus().equals(REQUISITION_REJECT.getCode())){
            return ResponseResult.error("单据目标状态禁止此操作");
        }
        if (dto.getSpmsStatus().equals(REQUISITION_APPROVED.getCode())){
            if (StringUtils.isEmpty(dto.getApprovalDate())){
                return ResponseResult.error("审批通过日期不允许为空");
            }
        }
        String uuidRequisition = dto.getUuidRequisition();
        OverseaRequisition requisition = this.baseMapper.selectOne(new QueryWrapper<OverseaRequisition>().eq("UUID_REQUISITION", uuidRequisition));
        if (requisition == null || dto.getDataVersion().intValue() != requisition.getDataVersion()){
            return ResponseResult.error("请求数据已更新请刷新重试");
        }
        if (!REQUISITION_PENDING_APPROVAL.getCode().equals(requisition.getSpmsStatus())
                && !REQUISITION_TO_SUBMIT.getCode().equals(requisition.getSpmsStatus())
                && !REQUISITION_REJECT.getCode().equals(requisition.getSpmsStatus())){
            return ResponseResult.error("单据当前状态禁止此操作");
        }
        List<OverseaRequisitionDtlDTO> overseaRequisitionDtlDTOList = dto.getRequisitionDtlDTOList();
        if (overseaRequisitionDtlDTOList == null || overseaRequisitionDtlDTOList.size() == 0){
            return ResponseResult.error("领用申请明细不能为空");
        }
        return ResponseResult.success();
    }

    /**
     *  状态说明：单据状态(0已删除;1待提交;2待审批;3审批通过;4审批拒绝;5已生成出库任务;)。
     *  状态变化：2——4 审批拒绝；1——0，4——0 删除申请；
     * @param uuidRequisition
     * @param dataVersion
     * @param spmsStatus
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult cancelOverseaRequisition(String uuidRequisition, Integer dataVersion, String spmsStatus, String userId) throws Exception{
        if (StringUtils.isEmpty(uuidRequisition) || dataVersion == null || StringUtils.isEmpty(spmsStatus)){
            return ResponseResult.error("请求参数错误");
        }
        QueryWrapper<OverseaRequisition> queryWrapper = new QueryWrapper<OverseaRequisition>().eq("UUID_REQUISITION", uuidRequisition);
        OverseaRequisition overseaRequisition = this.baseMapper.selectOne(queryWrapper);
        if (overseaRequisition == null){
            return ResponseResult.error("请求领用申请不存在");
        }
        if (overseaRequisition.getDataVersion() != dataVersion.intValue()){
            return ResponseResult.error("请求数据已更新，请刷新后重试");
        }
        String currentStatus = overseaRequisition.getSpmsStatus();
//        try {
            if (REQUISITION_PENDING_APPROVAL.getCode().equals(currentStatus)){
                if (!REQUISITION_REJECT.getCode().equals(spmsStatus)){
                    return ResponseResult.error("请求目标状态错误");
                }
                overseaRequisition.setSpmsStatus(spmsStatus);
                this.baseMapper.update(overseaRequisition, queryWrapper);
                iOverseaOperateLogService.addOverseaOperateLog(userId, uuidRequisition, REQUISITION_REJECT.getDescZh(), REQUISITION_REJECT.getDescEn(), "", REQUISITION_REJECT.getDescRu());
            } else if (REQUISITION_TO_SUBMIT.getCode().equals(currentStatus) || REQUISITION_REJECT.getCode().equals(currentStatus)) {
                if (!REQUISITION_DELETE.getCode().equals(spmsStatus)){
                    return ResponseResult.error("请求目标状态错误");
                }
                overseaRequisition.setSpmsStatus(spmsStatus);
                this.baseMapper.update(overseaRequisition, queryWrapper);
                iOverseaOperateLogService.addOverseaOperateLog(userId, uuidRequisition, REQUISITION_DELETE.getDescZh(), REQUISITION_DELETE.getDescEn(), "", REQUISITION_DELETE.getDescRu());
                Map<String, Object> ovr = this.baseMapper.getAllOverseaRequisition(uuidRequisition);
                List<Map<String, Object>> overseaRequisitionDtlList = iOverseaRequisitionDtlService.getRequisitionDtlList(uuidRequisition);
                return ResponseResult.success()
                        .add("overseaRequisition", ovr)
                        .add("overseaRequisitionDtlList",overseaRequisitionDtlList );
            } else {
                return ResponseResult.error("当前状态禁止此操作");
            }
            return getRequisitionAndDtl(uuidRequisition);
//        }catch (Exception e){
//            e.printStackTrace();
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//            return ResponseResult.error("请求执行过程出错请重试").add("error", e.getMessage());
//        }
    }

    @Override
    public OverseaRequisition getOverseaRequisition(String uuidRequisition) {
        if (StringUtils.isEmpty(uuidRequisition)){
            return null;
        }
        return this.baseMapper.selectOne(new QueryWrapper<OverseaRequisition>().eq("UUID_REQUISITION", uuidRequisition));
    }

    @Override
    public int updateRequisition(OverseaRequisition overseaRequisition) {
        String uuidRequisition = overseaRequisition.getUuidRequisition();
        return this.baseMapper.update(overseaRequisition, new QueryWrapper<OverseaRequisition>().eq("UUID_REQUISITION", uuidRequisition));
    }

    /***
     待发货领用申请异常报表/审批通过未出库超过3天
     -- 领用申请单状态为 3(审批通过) 审批通过日期已超过 3 天；且没有出库任务；
     -- 领用申请单状态为 5(已生成出库任务) 审批通过日期已超过 3 天；无有效出库任务 或 有状态为 1 进行中的出库任务；
     */
    @Override
    public List<Map<String, Object>> getRequisitionOverdueReports(String werks, String currentDate) {
        return this.baseMapper.getRequisitionOverdue3(werks, currentDate);
    }

    /**
     * 在途收货报表
     */
    @Override
    public ResponseResult getReceiptAndDeliveryReports(OverseaReceiptAndDeliverySearchDTO overseaReceiptAndDeliverySearchDTO) {
        return ResponseResult.success().add("receiptAndDeliveryReports", this.baseMapper.getReceiptAndDeliveryReports(overseaReceiptAndDeliverySearchDTO));
    }
    /**
     * 领用单在审批通过、已完成状态进行撤回操作，撤回状态为待审批
     */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public ResponseResult rollBackOverseaRequisition(String uuidRequisition, Integer dataVersion, String userId,String cancelReason)throws Exception {
		if (StringUtils.isEmpty(uuidRequisition) || dataVersion == null){
            return ResponseResult.error("请求参数错误");
        }
        boolean updateInventory = true;
        QueryWrapper<OverseaRequisition> queryWrapper = new QueryWrapper<OverseaRequisition>().eq("UUID_REQUISITION", uuidRequisition);
        OverseaRequisition overseaRequisition = this.baseMapper.selectOne(queryWrapper);
        if (overseaRequisition == null){
            return ResponseResult.error("请求领用申请不存在");
        }
        if (overseaRequisition.getDataVersion() != dataVersion.intValue()){
            return ResponseResult.error("请求数据已更新，请刷新后重试");
        }
        if(overseaRequisition!=null && StringUtils.isNotEmpty(overseaRequisition.getRequestNum())){//领用单是EAM创建的
            updateInventory = false;
        }
        // 只有领用审批人才能撤回
//        List<Map<String, Object>> roleList = iSpmsRoleService.getRoleById(userId);
//        if (CollectionUtils.isEmpty(roleList)) {
//            return ResponseResult.error("只有领用审批人的权限才能撤回");
//        }
//        boolean flag = true;
//        for (Map<String, Object> map : roleList) {
//            if ("5002".equals(map.get("roleId")) || "领用审批人".equals(map.get("roleCnName"))) {
//                flag = false;
//            }
//        }
//        if (flag) {
//            return ResponseResult.error("只有领用审批人的权限才能撤回");
//        }

		// 判断是否生成出库单，如果是不能撤回
		List<OverseaWhsOut> outList = iOverseaWhsOutService.findListByRecord(overseaRequisition.getSpmsId());
		if (CollectionUtils.isNotEmpty(outList)) {
			boolean outFlag = false;
			for (OverseaWhsOut out : outList) {
				if (!OverseaWhsOutEnum.OVERSEA_WHS_OUT_DELETE.getCode().equals(out.getSpmsStatus())) {
					// 存在未删除的仓库出库单
					outFlag = true;
				}
			}
			if (outFlag) {
				return ResponseResult.error("已存在未删除的仓库出库单，不能执行撤回操作");
			}
		}
		// 只有在审批通过、完成状态撤回后为待审批状态
		String currentStatus = overseaRequisition.getSpmsStatus();
		if (!REQUISITION_APPROVED.getCode().equals(currentStatus) && !REQUISITION_DONE.getCode().equals(currentStatus)) {
			return ResponseResult.error("只有审批通过、已完成状态才能撤回");
		}
        if(updateInventory) {//SPMS创建的领用单，改状态，撤回
            overseaRequisition.setSpmsStatus(REQUISITION_PENDING_APPROVAL.getCode());
            overseaRequisition.setCancelReason(cancelReason);
            this.baseMapper.update(overseaRequisition, queryWrapper);
            iOverseaOperateLogService.addOverseaOperateLog(userId, uuidRequisition, REQUISITION_PENDING_APPROVAL.getDescZh(), REQUISITION_PENDING_APPROVAL.getDescEn(), "", REQUISITION_PENDING_APPROVAL.getDescRu());
			return getRequisitionAndDtl(uuidRequisition);
        }else{//EAM创建的领用单，直接删除领用数据
            this.baseMapper.delete(queryWrapper);
            QueryWrapper<OverseaRequisitionDtl> dtlWrapper = new QueryWrapper<OverseaRequisitionDtl>().eq("UUID_REQUISITION", uuidRequisition);
            List<OverseaRequisitionDtl> dtlList = iOverseaRequisitionDtlService.list(dtlWrapper);
            iOverseaRequisitionDtlService.remove(dtlWrapper);
            // EAM领用单推送过来时就进行扣减库存，这里撤回时需要将库存加上——库存扣减注释 2023-10-24 xzp 已改到出库单提交SAP时扣减库存
//            for (OverseaRequisitionDtl dtl : dtlList) {
//            	double qty = dtl.getActualQtyBasicUnit();
//            	String materialNo = dtl.getMaterialNo();//物料编码
//                String whsLocationCode = overseaRequisition.getWhsLocationCode();//仓库
//                String storageNo = dtl.getStorageCode();//储位
//                String werks = dtl.getWerks();//工厂
//            	if (qty > 0) {
//            		String storageUuid = "";
//            		List<Map<String, String>> storageUUidList = this.baseMapper.selectWhsStorageUUid(werks, storageNo, whsLocationCode);
//            		if(storageUUidList!=null && storageUUidList.size()>0){
//                        storageUuid = storageUUidList.get(0).get("UUID");
//                    }else{
//                        throw new Exception(werks+"_"+whsLocationCode+"工厂、仓库不存在储位" + storageNo );
//                    }
//            		ResponseResult updateInventorys = iWhsStorageInventoryService.updateWhsStorageInventory(storageUuid, materialNo, qty, ADD);
//                    if (updateInventorys.getCode() != SUCCESS){
//                    	throw new Exception("物料："+materialNo+"增加储位"+storageNo+"库存失败");
//                    }
//            	}
//            }
            JSONObject dataToSap = formatDataToSap(overseaRequisition,"1");
            log.info("=======Z_SPMS_OV_OUT_TO_EAM =========\n" + dataToSap);
            JSONObject message = JSONObject.parseObject(iFeignServiceCommon.sendRestToSapCommon(dataToSap));
            log.info("==========message" + message);
            JSONObject RETURN_DATA = message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA");
            if (!"10000".equals(RETURN_DATA.getString("code"))) {
                throw new Exception("撤回领用EAM接口异常："+RETURN_DATA.getString("errmsg"));
            }
            iOverseaOperateLogService.addOverseaOperateLog(userId, uuidRequisition, REQUISITION_DELETE.getDescZh(), REQUISITION_DELETE.getDescEn(), "", REQUISITION_DELETE.getDescRu());
            overseaRequisition.setSpmsStatus(REQUISITION_DELETE.getCode());
            return ResponseResult.success().add("overseaRequisition", overseaRequisition)
            		.add("overseaRequisitionDtlList",dtlList );
        }
	}
	
	public List<OverseaRequisitionPrintDTO> requistionPrint(String dsName,String datasetName,Map<String,Object> parameters) {
		String uuidRequisition = (String) parameters.get("uuidRequisition");
		String language = (String) parameters.get("language");
		// 查询头信息
		Map<String, Object> headMap = this.baseMapper.getOverseaRequisition(uuidRequisition);
		// 查询行项目
		List<Map<String, Object>> itemMap = iOverseaRequisitionDtlService.getRequisitionDtlList(uuidRequisition);
		// 根据领用单号查询关联全部的出库单行项目
		List<Map<String, Object>> outItemMap = this.baseMapper.selectOversaeWhsOutDtl(headMap.get("spmsId").toString());
		Map<String, List<Map<String, Object>>> outMaps = new HashMap<>();
		if (CollectionUtils.isNotEmpty(outItemMap)) {
			// 根据领用单行号分组
			outMaps = outItemMap.stream().collect(Collectors.groupingBy(m -> m.get("relateDocumentItem").toString()));
		}
		// 查询移动类型基础数据
		List<Map<String, Object>> configList = this.baseMapper.selectOrderKeyValueConfigList("mobileType");
		Map<String, List<Map<String, Object>>> keyCodeMaps = null;
		if (CollectionUtils.isNotEmpty(configList)) {
			keyCodeMaps = configList.stream().collect(Collectors.groupingBy(e -> e.get("keyCode").toString()));
		}
		List<OverseaRequisitionPrintDTO> list = new ArrayList<OverseaRequisitionPrintDTO>();
		// 成本中心
		String costCenter = headMap.get("costCenter") != null ? headMap.get("costCenter").toString() : "";
		String costCenterName = headMap.get("costCenterName") != null ? headMap.get("costCenterName").toString() : "";
		String costCenterEnName = headMap.get("costCenterEnName") != null ? headMap.get("costCenterEnName").toString() : "";
		for (int i = 0; i < itemMap.size(); i++) {
			Map<String, Object> item = itemMap.get(i);
			OverseaRequisitionPrintDTO dto = new OverseaRequisitionPrintDTO();
			dto.setSpmsId(headMap.get("spmsId") != null ? headMap.get("spmsId").toString() : "");
			dto.setComments(headMap.get("comments") != null ? headMap.get("comments").toString() : "");
			dto.setCreateDate(headMap.get("createDate") != null ? headMap.get("createDate").toString() : "");
			dto.setCreateUser(headMap.get("createUsername") != null ? headMap.get("createUsername").toString() : "");
			dto.setDepatName(headMap.get("deptName") != null ? headMap.get("deptName").toString() : "");
			if ("zh-CN".equals(language)) {
				dto.setCostCenter(costCenter+"-"+costCenterName);
			} else {
				if (!StringUtils.isEmpty(costCenterEnName)) {
					dto.setCostCenter(costCenter+"-"+costCenterEnName);
				} else {
					dto.setCostCenter(costCenter+"-"+costCenterName);
				}
			}
			dto.setHeadRemarks(headMap.get("remarks") != null ? headMap.get("remarks").toString() : "");
			dto.setSpmsStatus(headMap.get("spmsStatus") != null ? OverseaRequisitionPrintEnum.getDescByValue(headMap.get("spmsStatus").toString()) : "");
			dto.setItem(item.get("item") != null ? item.get("item").toString() : "");
			dto.setMaterialNo(item.get("materialNo") != null ? item.get("materialNo").toString() : "");
			if ("en-US".equals(language)) {
				dto.setMaterialName(item.get("materialEnDesc") != null ? item.get("materialEnDesc").toString() : "");
			} else if ("zh-CN".equals(language)) {
				dto.setMaterialName(item.get("materialZhDesc") != null ? item.get("materialZhDesc").toString() : "");
			}
//			dto.setMaterialEngName(item.get("materialEnDesc") != null ? item.get("materialEnDesc").toString() : "");
			dto.setApplyQtyBasicUnit(item.get("applyQtyBasicUnit") != null ? item.get("applyQtyBasicUnit").toString() : "");
			dto.setBasicUnit(item.get("basicUnit") != null ? item.get("basicUnit").toString() : "");
			dto.setUnitSales(item.get("unitSales") != null ? item.get("unitSales").toString() : "");
			dto.setApplyQtyUnitSales(item.get("applyQtyUnitSales") != null ? item.get("applyQtyUnitSales").toString() : "");
			dto.setActualQtyBasicUnit(item.get("actualQtyBasicUnit") != null ? item.get("actualQtyBasicUnit").toString() : "");
			dto.setActualQtyUnitSales(item.get("actualQtyUnitSales") != null ? item.get("actualQtyUnitSales").toString() : "");
			dto.setStorageCode(item.get("storageCode") != null ? item.get("storageCode").toString() : "");
			dto.setItemRemarks(item.get("remarks") != null ? item.get("remarks").toString() : "");
			// 用途 
			item.get("actualMovementType");
			if ("en-US".equals(language)) {
				if (item.get("actualMovementType") == null) {
					dto.setUsed("");
				} else if (keyCodeMaps == null) {
					dto.setUsed(item.get("actualMovementType").toString());
				} else {
					List<Map<String, Object>> keyMapList = keyCodeMaps.get(item.get("actualMovementType").toString());
					if (CollectionUtils.isEmpty(keyMapList)) {
						dto.setUsed(item.get("actualMovementType").toString());
					} else {
						dto.setUsed(item.get("actualMovementType").toString()+"-"+keyMapList.get(0).get("keyCodeEnDesc"));
					}
				}
			} else if ("zh-CN".equals(language)) {
				if (item.get("actualMovementType") == null) {
					dto.setUsed("");
				} else if (keyCodeMaps == null) {
					dto.setUsed(item.get("actualMovementType").toString());
				} else {
					List<Map<String, Object>> keyMapList = keyCodeMaps.get(item.get("actualMovementType").toString());
					if (CollectionUtils.isEmpty(keyMapList)) {
						dto.setUsed(item.get("actualMovementType").toString());
					} else {
						dto.setUsed(item.get("actualMovementType").toString()+"-"+keyMapList.get(0).get("keyCodeDesc"));
					}
				}
			}
			if (outMaps != null && CollectionUtils.isNotEmpty(outMaps.get(item.get("item").toString()))) {
				List<Map<String, Object>> list2 = outMaps.get(item.get("item").toString());
				dto.setOverseaWhsOutNo(list2.get(0).get("spmsId").toString());
			} else {
				dto.setOverseaWhsOutNo("");
			}
			list.add(dto);
		}
		return list;
	}



    private JSONObject formatDataToSap(OverseaRequisition overseaRequisition,String state) {
        JSONObject dataToSap = new JSONObject();
        JSONObject REQUEST = new JSONObject();
        JSONObject ESB_ATTRS = new JSONObject();
        JSONObject REQUEST_DATA = new JSONObject();
        Map<String, Object> head = new HashMap<String, Object>();
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("WONUM", overseaRequisition.getRelateDocument());//EAM领用单号
        if(StringUtils.isNotEmpty(overseaRequisition.getCancelReason())){
            data.put("REASON", overseaRequisition.getCancelReason());//撤回原因
        }
        data.put("STATE", state);//状态（0=已完成，1=已撤回）
        head.put("OVDATA", data);
        REQUEST_DATA.put("SendData", head);
        REQUEST_DATA.put("Operation", "Z_SPMS_OV_OUT_TO_EAM");
        REQUEST_DATA.put("Type", "OV_OUT_TO_EAM");
        ESB_ATTRS.put("App_ID", "SPMS");
        ESB_ATTRS.put("Target_ID", "EAM");
        ESB_ATTRS.put("Application_ID", "00020000000002");
        ESB_ATTRS.put("Transaction_ID", UUID.randomUUID().toString());
        REQUEST.put("ESB_ATTRS", ESB_ATTRS);
        REQUEST.put("REQUEST_DATA", REQUEST_DATA);
        dataToSap.put("REQUEST", REQUEST);
        return dataToSap;
    }

}
