package com.sunda.spmsoversea.service.impl;

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.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.OverseaConsumptionDTO;
import com.sunda.spmsoversea.dto.OverseaReport;
import com.sunda.spmsoversea.dto.WelcomePageSearchDTO;
import com.sunda.spmsoversea.dto.WelcomePageWerksOrderDTO;
import com.sunda.spmsoversea.mapper.OverseaReportMapper;
import com.sunda.spmsoversea.service.IOverseaReportService;
import lombok.extern.slf4j.Slf4j;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: spms
 * @description:
 * @author: Wayne Wu
 * @create: 2022-01-11 09:55
 **/
@Service
@Slf4j
public class OverseaReportServiceImpl implements IOverseaReportService {

    @Autowired
    OverseaReportMapper overseaReportMapper;

    @Autowired
    IFeignServiceCommon iFeignServiceCommon;
    
    @Autowired
    ZSapOrgClientMapper zSapOrgClientMapper;

    /** 库龄分析报表计算逻辑步骤：
     1.按指定条件查询工厂仓库库存，工厂字段必输，查询结果不带储位，按料号数量求和；
     2.遍历物料仓库库存，按工厂、仓库、料号，查询物料库存增加记录日志，按天汇总每天增加数量；
     */
    @Override
    public List<Map<String, Object>> getInventoryAge(String werks, String whsLocationCode, String materialNo, Integer daysSearch) {
        daysSearch = daysSearch == null ? 0 : daysSearch;
        List<Map<String, Object>> inventoryAgeList = new ArrayList<>();
        List<Map<String, Object>> whsInventory = overseaReportMapper.getWhsInventory(werks, whsLocationCode, materialNo);
        int item = 1;
        if (whsInventory != null && whsInventory.size() > 0){
            for (int i = 0; i < whsInventory.size(); i++){
                werks = whsInventory.get(i).get("werks").toString();
                whsLocationCode = whsInventory.get(i).get("whsLocationCode").toString();
                materialNo = whsInventory.get(i).get("materialNo").toString();
                double totalQuantity = Double.parseDouble(whsInventory.get(i).get("quantity").toString());
                String materialZhDesc = whsInventory.get(i).get("materialZhDesc").toString();
                String materialEnDesc = whsInventory.get(i).get("materialEnDesc").toString();
                String basicUnit = whsInventory.get(i).get("basicUnit").toString();

                List<Map<String, Object>> whsOperateLogList = overseaReportMapper.getWhsOperate(werks, whsLocationCode, materialNo);
                if (whsOperateLogList != null && whsOperateLogList.size() > 0){
                    double tempQuantity = totalQuantity;
                    for (int j = 0; j < whsOperateLogList.size(); j ++){
                        Map<String, Object> inventoryAge = new HashMap<>();
                        double quantity = Double.parseDouble(whsOperateLogList.get(j).get("quantity").toString());
                        String createDate = whsOperateLogList.get(j).get("createDate").toString();
                        Integer days = Integer.parseInt(whsOperateLogList.get(j).get("days").toString());
                        tempQuantity = tempQuantity - quantity;
                        inventoryAge.put("rowId", item);
                        item ++;
                        inventoryAge.put("werks", werks);
                        inventoryAge.put("whsLocationCode", whsLocationCode);
                        inventoryAge.put("materialNo", materialNo);
                        inventoryAge.put("createDate", createDate);
                        inventoryAge.put("days", days);
                        inventoryAge.put("materialZhDesc", materialZhDesc);
                        inventoryAge.put("materialEnDesc", materialEnDesc);
                        inventoryAge.put("basicUnit", basicUnit);
                        if (tempQuantity <= 0){
                            inventoryAge.put("quantity", (tempQuantity + quantity));
                            inventoryAgeList.add(inventoryAge);
                            break;
                        }
                        inventoryAge.put("quantity", quantity);
                        inventoryAgeList.add(inventoryAge);
                    }
                }
            }
        }
        if (daysSearch <= 0 || inventoryAgeList.size() == 0){
            return inventoryAgeList;
        }
        List<Map<String, Object>> searchResult = new ArrayList<>();
        for (int k = 0; k < inventoryAgeList.size(); k ++){
            Map<String, Object> inventoryAge = inventoryAgeList.get(k);
            if (Integer.parseInt(inventoryAge.get("days").toString()) >= daysSearch){
                searchResult.add(inventoryAge);
            }
        }
        return searchResult;
    }

    /** 库龄分析(按箱码) */
    @Override
    public List<Map<String, Object>> getBoxInventoryAge(String werks, String whsLocationCode, String boxNote, Integer days) {
        days = days == null ? 0 : days;
        return overseaReportMapper.getBoxInventoryAge(werks, whsLocationCode, boxNote, days);
    }

    /** 获取耗用记录 */
    @Override
    public List<Map<String, Object>> getConsumptionRecord(OverseaConsumptionDTO dto) {
        return overseaReportMapper.getConsumptionRecord(dto);
    }

    /**
     机电主任登录首页信息统计，首页待办项信息展示：
     1.(机电主任)需求提报单审批：获取当前人关联工厂下待审批的车间请购单数量；跨工厂合并，全周期；
     2.(机电主任)工厂请购单：获取本人创建的待提交/待重提SRM/OA审批不通过的工厂请购单数量；跨工厂合并，全周期；
                 各状态单据量；跨工厂合并、近30天；
     3.非目录物料申请单：待提交——获取本人创建的非目录物料申请待提交OA的数量；跨工厂合并，全周期；
                      编码未发放——获取本人创建的非目录物料申请，编码为空的明细行数；跨工厂合并，全周期；
     4.车间领用单：待审批——获取当前人关联工厂待审批的领用单；跨工厂合并，全周期；
                 待领用——获取本人创建的审批通过但未生成出库任务的领用任务；跨工厂合并，全周期；
     5.(车间主任)需求提报单审批：获取本人创建的需求申请单，待提交 和 审批不通过、已提交三个状态下数量，本人关联工厂内数据；跨工厂合并，全周期；
      */
    @Override
    public List<Map<String, Object>> getToDoTasks(String userId) {
        List<Map<String, Object>> toDoTaskList = new ArrayList<>();
        Map<String, Object> orderWorkshopToDoItemsMap = new HashMap<>();
        orderWorkshopToDoItemsMap.put("orderWorkshopToDoItems", overseaReportMapper.orderWorkshopToDoItemsMap(userId));
        toDoTaskList.add(orderWorkshopToDoItemsMap);

        Map<String, Object> orderWerksToDoItemsMap = new HashMap<>();
        orderWerksToDoItemsMap.put("orderWerksToDoItems", overseaReportMapper.orderWerksToDoItemsMap(userId));
        toDoTaskList.add(orderWerksToDoItemsMap);

        Map<String, Object> orderWerksQuantityEachStatus = new HashMap<>();
        orderWerksQuantityEachStatus.put("orderWerksQuantityEachStatus", overseaReportMapper.orderWerksQuantityEachStatus(userId));
        toDoTaskList.add(orderWerksQuantityEachStatus);

        Map<String, Object> materialApplicationToDoItems = new HashMap<>();
        materialApplicationToDoItems.put("materialApplicationToDoItems", overseaReportMapper.materialApplicationToDoItems(userId));
        toDoTaskList.add(materialApplicationToDoItems);

        Map<String, Object> materialApplicationWithoutMaterialNo = new HashMap<>();
        materialApplicationWithoutMaterialNo.put("materialApplicationWithoutMaterialNo", overseaReportMapper.materialApplicationWithoutMaterialNo(userId));
        toDoTaskList.add(materialApplicationWithoutMaterialNo);

        Map<String, Object> overseaRequisitionToDoItems = new HashMap<>();
        overseaRequisitionToDoItems.put("overseaRequisitionToDoItems", overseaReportMapper.overseaRequisitionToDoItems(userId));
        toDoTaskList.add(overseaRequisitionToDoItems);

        Map<String, Object> overseaRequisitionWithoutOut = new HashMap<>();
        overseaRequisitionWithoutOut.put("overseaRequisitionWithoutOut", overseaReportMapper.overseaRequisitionWithoutOut(userId));
        toDoTaskList.add(overseaRequisitionWithoutOut);

        Map<String, Object> orderWorkshopQuantityEachStatus = new HashMap<>();
        orderWorkshopQuantityEachStatus.put("orderWorkshopQuantityEachStatus", overseaReportMapper.orderWorkshopQuantityEachStatus(userId));
        toDoTaskList.add(orderWorkshopQuantityEachStatus);

        return toDoTaskList;
    }

    /** 海外仓首页，车间请购单整单追溯查询 */
    @Override
    public ResponseResult getOrderWorkshopTrace(WelcomePageSearchDTO welcomePageSearchDTO, String userId) {
        if (StringUtils.isNotEmpty(welcomePageSearchDTO.getUserId())){
            userId = welcomePageSearchDTO.getUserId();
        }
        IPage iPage = welcomePageSearchDTO.getPage();
        List<Map<String, Object>> resultList = new ArrayList<>();
        List<Map<String, Object>> mapList = overseaReportMapper.orderWorkshopTrace(iPage, welcomePageSearchDTO, userId);
        if (mapList != null && mapList.size() > 0){
            for (int i = 0; i < mapList.size(); i ++){
                Map<String, Object> map = mapList.get(i);
                String spmsId = map.get("spmsId") == null ? "" : map.get("spmsId").toString();
                if (StringUtils.isNotEmpty(spmsId)){
                    JSONObject dataToSrm = formatDataSend(spmsId);
                    JSONObject message = JSONObject.parseObject(iFeignServiceCommon.sendRestToSapCommon(dataToSrm));
                    JSONObject returnDate = message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA");
                    //按工厂请购单号查询 SRM 状态
                    //"1"——待采购处理
                    //"2"——已下单未交付
                    //"3"——国内全部收货
                    if ("S".equals(returnDate.getString("status"))){
                        String requestType = returnDate.getJSONArray("data").getJSONObject(0).getString("requestType");
                        if ("1".equals(requestType)){
                            map.put("srmStatus", "9");
                        }
                        if ("2".equals(requestType)){
                            map.put("srmStatus", "10");
                        }
                        if ("3".equals(requestType)){
                            map.put("srmStatus", "11");
                        }
                    } else {
                        map.put("srmStatus", "");
                    }
                } else {
                    map.put("srmStatus", "");
                }
                resultList.add(map);
            }
        }
        return ResponseResult.success().add("orderWorkshopTraceList", iPage.setRecords(resultList));
    }

    /** 海外仓首页，工厂请购单整单追溯查询 */
    @Override
    public ResponseResult getOrderWerksTrace(WelcomePageWerksOrderDTO welcomePageWerksOrderDTO, String userId) {
        IPage iPage = welcomePageWerksOrderDTO.getPage();
        List<Map<String, Object>> resultList = new ArrayList<>();
        List<Map<String, Object>> mapList = overseaReportMapper.orderWerksTrace(iPage, welcomePageWerksOrderDTO);
        if (mapList != null && mapList.size() > 0){
            for (int i = 0; i < mapList.size(); i ++){
                Map<String, Object> map = mapList.get(i);
                String spmsId = map.get("spmsId") == null ? "" : map.get("spmsId").toString();
                if (StringUtils.isNotEmpty(spmsId)){
                    JSONObject dataToSrm = formatDataSend(spmsId);
                    JSONObject message = JSONObject.parseObject(iFeignServiceCommon.sendRestToSapCommon(dataToSrm));
                    JSONObject returnDate = message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA");
                    //按工厂请购单号查询 SRM 状态
                    //"1"——待采购处理
                    //"2"——已下单未交付
                    //"3"——国内全部收货
                    if ("S".equals(returnDate.getString("status"))){
                        String requestType = returnDate.getJSONArray("data").getJSONObject(0).getString("requestType");
                        if ("1".equals(requestType)){
                            map.put("srmStatus", "9");
                        }
                        if ("2".equals(requestType)){
                            map.put("srmStatus", "10");
                        }
                        if ("3".equals(requestType)){
                            map.put("srmStatus", "11");
                        }
                    } else {
                        map.put("srmStatus", "");
                    }
                }
                resultList.add(map);
            }
        }
        return ResponseResult.success().add("orderWerksTraceList", iPage.setRecords(resultList));
    }

    /** 按工厂请购单uuid查询所有关联箱码所在位置 */
    @Override
    public ResponseResult getOrderWerksBoxTrace(String uuid) {
        try {
            if (StringUtils.isEmpty(uuid)){
                return ResponseResult.error("请求参数错误请重试");
            }
            List<Map<String, Object>> orderWerksDtlTraceList = overseaReportMapper.orderWerksBoxTraceListByUuid(uuid);
            // 以下注释部分为追溯方式：先按工厂请购单 uuid 获取工厂请购单明细行；再根据每一行明细行的 uuid + 行号，查询关联箱码及所有箱码当前位置；
            //List<Map<String, Object>> orderWerksDtlTraceList = new ArrayList<>();
            //List<Map<String, Object>> orderWerksDtlList = overseaReportMapper.orderWerksDtlList(uuid);
            //if (orderWerksDtlList != null && orderWerksDtlList.size() > 0){
            //    for (int i = 0; i < orderWerksDtlList.size(); i ++){
            //        Map<String, Object> orderWerksDtl = orderWerksDtlList.get(i);
            //        String orderWerksUuid = orderWerksDtl.get("orderWerksUuid") == null ? "" : orderWerksDtl.get("orderWerksUuid").toString();
            //        String rowIdWerks = orderWerksDtl.get("rowIdWerks") == null ? "" : orderWerksDtl.get("rowIdWerks").toString();
            //        if (StringUtils.isNotEmpty(orderWerksUuid) && StringUtils.isNotEmpty(rowIdWerks)){
            //            List<Map<String, Object>> boxLog = overseaReportMapper.orderWerksBoxTraceList(orderWerksUuid, rowIdWerks);
            //            orderWerksDtl.put("boxTraceList", boxLog);
            //        } else {
            //            orderWerksDtl.put("boxTraceList", new ArrayList<>());
            //        }
            //        orderWerksDtlTraceList.add(orderWerksDtl);
            //    }
            //}
            return ResponseResult.success().add("orderWerksDtlTraceList", orderWerksDtlTraceList);
        } catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error("请求数据失败").add("error", e.getMessage());
        }
    }


    /** 根据工厂请购单单号，向SRM请求SRM系统整单状态 */
    @Override
    public ResponseResult getOrderStatusFromSrm(String spmsId) {
        JSONObject dataToSap = formatDataSend(spmsId);
        JSONObject message = JSONObject.parseObject(iFeignServiceCommon.sendRestToSapCommon(dataToSap));
        return ResponseResult.success().add("dataToSap", dataToSap).add("sapReturnedMessage", message);
    }

    public JSONObject formatDataSend(String spmsId){
        JSONObject doc = new JSONObject();
        JSONObject REQUEST = new JSONObject();
        JSONObject ESB_ATTRS = new JSONObject();
        JSONObject REQUEST_DATA = new JSONObject();

        ESB_ATTRS.put("App_ID", "SPMS");
        ESB_ATTRS.put("Target_ID", "SRM-SAP");
        ESB_ATTRS.put("Application_ID", "00020000000002");
        ESB_ATTRS.put("Transaction_ID", UUID.randomUUID().toString());

        JSONObject item = new JSONObject();
        item.put("purchaseRequestNumber", spmsId);

        JSONArray Items = new JSONArray();
        Items.add(item);

        JSONObject SendData = new JSONObject();
        SendData.put("Items", Items);
        REQUEST_DATA.put("SendData", SendData);
        REQUEST_DATA.put("Operation", "SPMS_SRM_PURCHASE_REQUEST_HEAD_TYPE_NEW");
        REQUEST_DATA.put("Type", "purchase_request_head_type");

        REQUEST.put("ESB_ATTRS", ESB_ATTRS);
        REQUEST.put("REQUEST_DATA", REQUEST_DATA);

        doc.put("REQUEST", REQUEST);
        return doc;
    }


    /**
     根据工厂、工厂请购单号、日期区间，查询符合条件下所有请购单全生命周期关键节点日期数据
     werks 必输；
     */
    @Override
    public ResponseResult getOrderKeyDates(OverseaReport overseaReport, String userId) {
//        if (overseaReport == null || StringUtils.isEmpty(overseaReport.getWerks())){
//            return ResponseResult.error("请求工厂不能为空");
//        }
        List<Map<String, Object>> orderKeyDatesList = overseaReportMapper.getOrderKeyDates(overseaReport);
        for (int i = 0; i < orderKeyDatesList.size(); i++){
            Map<String, Object> dataMap = orderKeyDatesList.get(i);
            if(dataMap.get("prStatus")!=null){
                String status = dataMap.get("prStatus").toString();
                dataMap.put("prStatus", "0".equals(status) ? "审批通过" : "1".equals(status) ? "新建" : "2".equals(status) ? "审批中" : "3".equals(status)
                        ? "审批拒绝" : "4".equals(status) ? "已建询价" : "5".equals(status) ? "已建竞价" : "6".equals(status) ? "已建招标" : "7".equals(status)
                        ? "询价完成" : "8".equals(status) ? "竞价完成" : "9".equals(status) ? "招标完成" : "10".equals(status) ? "已建订单" : "11".equals(status)
                        ? "发货在途" : "12".equals(status) ? "部分收货" : "13".equals(status) ? "全部收货" : "14".equals(status) ? "单次合同" : "15".equals(status)
                        ? "长期协议" : "16".equals(status) ? "已发货" : "17".equals(status) ? "已收货" : "18".equals(status) ? "冻结" : "21".equals(status)
                        ? "关闭" : "未知状态");
            }
        }


        return ResponseResult.success().add("orderKeyDatesList", orderKeyDatesList);
    }

    @Override
    public List<Map<String, Object>> getOrderKeyDatesList(OverseaReport overseaReport, String userId) {
        List<Map<String, Object>> orderKeyDatesList = overseaReportMapper.getOrderKeyDates(overseaReport);
        for (int i = 0; i < orderKeyDatesList.size(); i++){
            Map<String, Object> dataMap = orderKeyDatesList.get(i);
            if(dataMap.get("prStatus")!=null){
                String status = dataMap.get("prStatus").toString();
                dataMap.put("prStatus", "0".equals(status) ? "审批通过" : "1".equals(status) ? "新建" : "2".equals(status) ? "审批中" : "3".equals(status)
                        ? "审批拒绝" : "4".equals(status) ? "已建询价" : "5".equals(status) ? "已建竞价" : "6".equals(status) ? "已建招标" : "7".equals(status)
                        ? "询价完成" : "8".equals(status) ? "竞价完成" : "9".equals(status) ? "招标完成" : "10".equals(status) ? "已建订单" : "11".equals(status)
                        ? "发货在途" : "12".equals(status) ? "部分收货" : "13".equals(status) ? "全部收货" : "14".equals(status) ? "单次合同" : "15".equals(status)
                        ? "长期协议" : "16".equals(status) ? "已发货" : "17".equals(status) ? "已收货" : "18".equals(status) ? "冻结" : "21".equals(status)
                        ? "关闭" : "未知状态");
            }
        }
        return orderKeyDatesList;
    }


    @SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public IPage getSendSapFailedListByRecord(OverseaReport overseaReport) {
		IPage iPage = overseaReport.getPage();
		iPage.setRecords(overseaReportMapper.getSendSapFailedPage(iPage, overseaReport));
        return iPage;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public ResponseResult getMaterialPhotosList(OverseaConsumptionDTO dto) {
		IPage iPage = dto.getPage();
		List<Map<String, Object>> list = overseaReportMapper.getMaterialAttachFilePage(iPage, dto);
		if (CollectionUtils.isNotEmpty(list)) {
			for (Map<String, Object> mp : list) {
				if (mp.get("photos") != null) {
					String[] split = mp.get("photos").toString().split(",");
					mp.put("phNum", split.length);
				} else {
					mp.put("phNum", "0");
				}
			}
		}
        Map<String, Object> materialNums = overseaReportMapper.getAllPhotosCount(dto);
        Map<String, Object> materialNumMap = overseaReportMapper.getAllMaterialPhotos(dto);
		// 计算图片覆盖率
//		BigDecimal coverage = BigDecimal.ZERO;
//		if (CollectionUtils.isNotEmpty(list) && list.get(0).get("photosNum") != null && materialNumMap != null && !"0".equals(materialNumMap.get("materNum"))) {
//			coverage = new BigDecimal(list.get(0).get("photosNum").toString()).divide(new BigDecimal(materialNumMap.get("materNum").toString()), 2, BigDecimal.ROUND_HALF_UP);
//		}
        BigDecimal coverage = BigDecimal.ZERO;
        if (materialNums != null && !"0".equals(materialNums.get("materNum")) && materialNumMap != null && !"0".equals(materialNumMap.get("materNum"))) {
            coverage = new BigDecimal(materialNums.get("materNum").toString()).divide(new BigDecimal(materialNumMap.get("materNum").toString()), 2, BigDecimal.ROUND_HALF_UP);
        }
		String cover = coverage.multiply(new BigDecimal("100")).stripTrailingZeros().toPlainString()+"%";
		
		iPage.setRecords(list);
		return ResponseResult.success().add("materialPhotosList", iPage).add("coverage", cover);
	}

	@SuppressWarnings("rawtypes")
	@Override
	public ResponseResult getMaterialStockQtyDifferList(OverseaConsumptionDTO dto) {
		String werks = dto.getWerks();
		String lgort = dto.getWhsLocationCode();
//		String differNum = dto.getDifferNum();
		String displayDiff = dto.getDisplayDiff();
		if (StringUtils.isEmpty(werks)) {
			ResponseResult.error("请求工厂不能为空");
		}
		if (StringUtils.isEmpty(lgort)) {
			ResponseResult.error("仓库编号不能为空");
		}
		String nowDate = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
		// 查询SPMS端的数据
		List<Map<String, Object>> spmsList = overseaReportMapper.selectMaterialStockQtyDifferList(dto);
		List<Map<String, Object>> returnList = new ArrayList<Map<String, Object>>();
		if (CollectionUtils.isNotEmpty(spmsList)) {
			Map<String, List<Map>> collect = new HashMap<>();
			// 调用接口查询SAP数据
			// 如果前端没有使用模糊查询，就先查询SAP同工厂的数据；如果使用了模糊查询，先查询SPMS的数据再循环查询SAP的数据
			if (StringUtils.isEmpty(dto.getMaterialNo())) {
				JSONObject dataToSap = this.materialStockSendSap(dto);
				// 根据工厂查询对应的SAP Clinet
                List<ZSapOrgClient> clinetList = zSapOrgClientMapper.selectList(new QueryWrapper<ZSapOrgClient>().eq("WERKS", werks));
                if (!CollectionUtils.isEmpty(clinetList)) {
                	JSONObject esbObj = dataToSap.getJSONObject("REQUEST").getJSONObject("ESB_ATTRS");
                	esbObj.put("Target_ID", "SAP-"+clinetList.get(0).getZmandt());
                } else {
                	return ResponseResult.error("工厂："+werks+"未找到对应的SAP Clinet");
                }
				JSONObject message = JSONObject.parseObject(iFeignServiceCommon.sendRestToSapCommon(dataToSap));
				JSONObject returnDate = message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA");
				if ("S".equals(returnDate.getString("O_TYPE"))){
					JSONArray jsonArray = returnDate.getJSONArray("IT_STOCK");
					if (jsonArray.size() > 0) {
						List<Map> javaList = jsonArray.toJavaList(Map.class);
						collect = javaList.stream().collect(Collectors.groupingBy(e -> e.get("WERKS")+"_"+e.get("LGORT")+"_"+e.get("MATNR")));
					}
				}
			}
			for (int i = 0; i < spmsList.size(); i++) {
				Map<String, Object> map = spmsList.get(i);
				// 汇总数量
				BigDecimal allNumber = BigDecimal.ZERO;
				String key = map.get("werks")+"_"+map.get("whsLocationCode")+"_"+map.get("materialNo");
				if (StringUtils.isEmpty(dto.getMaterialNo())) {
					List<Map> diffList = collect.get(key);
					if (CollectionUtils.isNotEmpty(diffList)) {
						for (Map mm : diffList) {
							if (StringUtils.isNotEmpty(mm.get("LABST").toString())) {
								allNumber = allNumber.add(new BigDecimal(mm.get("LABST").toString()));
							}
						}
					}
				} else {
					// 模糊查询根据物料编码查询SAP库存数量
					dto.setMaterialNo(map.get("materialNo").toString());
					JSONObject dataToSap = this.materialStockSendSap(dto);
					// 根据工厂查询对应的SAP Clinet
	                List<ZSapOrgClient> clinetList = zSapOrgClientMapper.selectList(new QueryWrapper<ZSapOrgClient>().eq("WERKS", werks));
	                if (!CollectionUtils.isEmpty(clinetList)) {
	                	JSONObject esbObj = dataToSap.getJSONObject("REQUEST").getJSONObject("ESB_ATTRS");
	                	esbObj.put("Target_ID", "SAP-"+clinetList.get(0).getZmandt());
	                } else {
	                	return ResponseResult.error("工厂："+werks+"未找到对应的SAP Clinet");
	                }
					JSONObject message = JSONObject.parseObject(iFeignServiceCommon.sendRestToSapCommon(dataToSap));
					JSONObject returnDate = message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA");
					if ("S".equals(returnDate.getString("O_TYPE"))){
						JSONArray jsonArray = returnDate.getJSONArray("IT_STOCK");
						if (jsonArray.size() > 0) {
							List<Map> javaList = jsonArray.toJavaList(Map.class);
							collect = javaList.stream().collect(Collectors.groupingBy(e -> e.get("WERKS")+"_"+e.get("LGORT")+"_"+e.get("MATNR")));
							List<Map> diffList = collect.get(key);
							if (CollectionUtils.isNotEmpty(diffList)) {
								for (Map mm : diffList) {
									if (StringUtils.isNotEmpty(mm.get("LABST").toString())) {
										allNumber = allNumber.add(new BigDecimal(mm.get("LABST").toString()));
									}
								}
							}
						}
					}
				}
				// sap库存量
				map.put("labst", allNumber.setScale(3));
				// SPMS&SAP库存差异：SPMS库存量-SAP库存量
				if (StringUtils.isEmpty(map.get("availableQty").toString())) {
					map.put("availableQty", "0");
				}
				BigDecimal availableQty = new BigDecimal(map.get("availableQty").toString()).setScale(3);
				BigDecimal diffQty = availableQty.subtract(new BigDecimal(map.get("labst").toString()));
				map.put("availableQty", availableQty);
				map.put("diffQty", diffQty);
				// 未提交SAP库存量：总数量-SPMS库存量
				if (StringUtils.isEmpty(map.get("quantity").toString())) {
					map.put("quantity", "0.000");
				}
				BigDecimal noPushQty = new BigDecimal(map.get("quantity").toString()).subtract(new BigDecimal(map.get("availableQty").toString())).setScale(3, BigDecimal.ROUND_HALF_UP);
				map.put("noPushQty", noPushQty);
				// 待复查库存差异：SPMS库存量-SAP库存量-未提交SAP库存量
				BigDecimal diffReviewQty = new BigDecimal(map.get("availableQty").toString()).subtract(new BigDecimal(map.get("labst").toString())).subtract(new BigDecimal(map.get("noPushQty").toString()));
				map.put("diffReviewQty", diffReviewQty.setScale(3));
				// 查询日期
				map.put("nowDate", nowDate);
				// 是否显示差异
				if ("1".equals(displayDiff)) {
					if (BigDecimal.ZERO.compareTo(new BigDecimal(map.get("diffQty").toString())) != 0) {
						returnList.add(map);
					}
				} else {
					returnList.add(map);
				}
			}
		}
		return ResponseResult.success().add("returnList", returnList);
	}
	
	public JSONObject materialStockSendSap(OverseaConsumptionDTO dto){
        JSONObject doc = new JSONObject();
        JSONObject REQUEST = new JSONObject();
        JSONObject ESB_ATTRS = new JSONObject();
        JSONObject REQUEST_DATA = new JSONObject();

        ESB_ATTRS.put("App_ID", "SPMS");
        ESB_ATTRS.put("Application_ID", "00020000000002");
        ESB_ATTRS.put("Transaction_ID", UUID.randomUUID().toString());
        
        String werks = dto.getWerks();
		String lgort = dto.getWhsLocationCode();
		String materialNo = dto.getMaterialNo();
        JSONObject head = new JSONObject();
        head.put("I_WERKS", werks);
        head.put("I_LGORT", lgort);
        head.put("I_MATNR", materialNo);
        
        REQUEST_DATA.put("fileds", head);
        REQUEST_DATA.put("Operation", "Z_SPMS_READ_STOCK");
        REQUEST_DATA.put("Type", "SPMS_READ_STOCK");

        REQUEST.put("ESB_ATTRS", ESB_ATTRS);
        REQUEST.put("REQUEST_DATA", REQUEST_DATA);

        doc.put("REQUEST", REQUEST);
        return doc;
    }


    @SuppressWarnings("rawtypes")
    @Override
    public ResponseResult getIntransitData(OverseaConsumptionDTO dto) {
        String werks = dto.getWerks();
        String receiveWerks = dto.getReceiveWerks();
        if (StringUtils.isEmpty(receiveWerks)) {
            ResponseResult.error("收货工厂不能为空");
        }
        String sapClient = "";
        List<ZSapOrgClient> selectList = zSapOrgClientMapper.selectList(new QueryWrapper<ZSapOrgClient>().eq("WERKS", receiveWerks));
        if (CollectionUtils.isNotEmpty(selectList)) {
            sapClient = "SAP-"+selectList.get(0).getZmandt();
        } else {
            throw new RuntimeException("工厂："+receiveWerks+"未找到对应的SAP Clinet");
        }

        String nowDate = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
        JSONObject dataToSap = this.intransitDataSendSap(dto,sapClient);
        JSONObject message = JSONObject.parseObject(iFeignServiceCommon.sendRestToSapCommon(dataToSap));
        JSONObject returnData = message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA");
        log.error(returnData.toJSONString());
        List<Map<String,Object>> returnList = new ArrayList<Map<String,Object>>();
        JSONArray jsonArray = returnData.getJSONArray("IT_LIST");

//            {"TBZHUANGCHU":[
//                {"VBELN":"700559734","LOEKZ":"","IMONTH":0.67,"MENGE":0.000,"ZWEMNG_XS":0.000,"LIFEX":"","FHWERKS":"GF03","ZHYF":0.00,"WEMNG":0.000,"WAMNG":2.000,
//                        "WAERS":"","ZZKWERT":0.00,"BEDAT":1667232000000,"ERDAT":1667232000000,"VTWEG":"","SHWERKS":"CM01","ZKWERT":0.00,"REMARK":"","ZWAERS":"",
//                        "MATNR":"160012657","MAKTX":"YM33064G 300喷墨陶瓷仿古釉面砖 17PCS G2","VTEXT":"","EBELN":"4481030912","ZVRKME_XS":"CTN","BOLNR":"",
//                        "ZWAMNG_XS":2.000,"EBELP":"00010","ZCABNO":"","MEINS":"CTN","MAGRV":"","BORGR_GRP":"","SHKZG":"","SPART":"10",
//                        "VKORG":"","POSNR":"000000","VERUR":"","ZNLYF":0.00,"ZBXF":0.00}]}

        SimpleDateFormat simp = new SimpleDateFormat("yyyyMMdd");
        SimpleDateFormat simp1 = new SimpleDateFormat("yyyy-MM-dd");


        if (jsonArray!=null && jsonArray.size() > 0) {
            try {
                List<Map> list = jsonArray.toJavaList(Map.class);
                for (Map<String,Object> item : list) {
                    Map<String,Object> dataMap = new HashMap<>();
                    dataMap.put("werks", item.get("FHWERKS") == null ? "" : item.get("FHWERKS").toString()) ;//发货工厂
                    dataMap.put("receiveWerks",item.get("SHWERKS") == null ? "" : item.get("SHWERKS").toString());//收货工厂

                    if(item.get("BEDAT")!=null && item.get("BEDAT").toString().length()>0){
                        Date time1 = new Date(Long.parseLong(item.get("BEDAT").toString()));
                        dataMap.put("poDate",simp1.format(time1));//采购订单日期
                    }else{
                        dataMap.put("poDate","");//采购订单日期
                    }

                    //dataMap.put("poDate",item.get("BEDAT") == null ? "" : item.get("BEDAT").toString());//采购订单日期
                    dataMap.put("purchaseNo",item.get("EBELN") == null ? "" : item.get("EBELN").toString());//采购订单
                    dataMap.put("poItemNo",item.get("EBELP") == null ? "" : item.get("EBELP").toString());//采购订单行号
                    //dataMap.put("arrivalDate",item.get("ZDEDGDAT") == null ? "" : item.get("ZDEDGDAT").toString());//预计到港日期-
                    if(item.get("ZDEDGDAT")!=null && item.get("ZDEDGDAT").toString().length()>0){
                        Date time1 = new Date(Long.parseLong(item.get("ZDEDGDAT").toString()));
                        dataMap.put("arrivalDate",simp1.format(time1));//预计到港日期
                    }else{
                        dataMap.put("arrivalDate","");//预计到港日期
                    }

                    dataMap.put("packageNo",item.get("BOLNR") == null ? "" : item.get("BOLNR").toString());//装箱单号-
                    dataMap.put("cabNo",item.get("ZCABNO") == null ? "" : item.get("ZCABNO").toString());//柜号
                    dataMap.put("sysCode",item.get("ZSPMS") == null ? "" : item.get("ZSPMS").toString());//收货系统
                    dataMap.put("sapDeliveryNote",item.get("VBELN") == null ? "" : item.get("VBELN").toString());//交货单
                    dataMap.put("sapDevItem",item.get("POSNR") == null ? "" : item.get("POSNR").toString());//交货单行号
                    dataMap.put("boxNote",item.get("PACKAGE_CODE") == null ? "" : item.get("PACKAGE_CODE").toString());//箱码
                    dataMap.put("productLine",item.get("SPART") == null ? "" : item.get("SPART").toString());//产品线
                    dataMap.put("materialNo",item.get("MATNR") == null ? "" : item.get("MATNR").toString());//物料编码
                    dataMap.put("materialName",item.get("MAKTX") == null ? "" : item.get("MAKTX").toString());//物料描述
                    dataMap.put("shippedQty",item.get("WAMNG") == null ? "" : item.get("WAMNG").toString());//发货数量
                    dataMap.put("receivedQty",item.get("WEMNG") == null ? "" : item.get("WEMNG").toString());//收货数量
                    dataMap.put("baseUnit",item.get("MEINS") == null ? "" : item.get("MEINS").toString());//基本单位
                    dataMap.put("shippedNumber",item.get("ZWAMNG_XS") == null ? "" : item.get("ZWAMNG_XS").toString());//发货件数
                    dataMap.put("receivedNumber",item.get("ZWEMNG_XS") == null ? "" : item.get("ZWEMNG_XS").toString());//收货件数
                    dataMap.put("saleUnit",item.get("ZVRKME_XS") == null ? "" : item.get("ZVRKME_XS").toString());//销售单位
                    dataMap.put("nowDate",nowDate);//查询日期
                    returnList.add(dataMap);
                }
            }catch (Exception e){
                log.error("SAP在途数据查询异常："+e.getMessage());
            }

        }else{
            ResponseResult.error("SAP在途数据查询失败："+dataToSap.toJSONString());
        }

        return ResponseResult.success().add("returnList", returnList);
    }


    public JSONObject intransitDataSendSap(OverseaConsumptionDTO dto,String sapClient){
        JSONObject doc = new JSONObject();
        JSONObject REQUEST = new JSONObject();
        JSONObject ESB_ATTRS = new JSONObject();
        JSONObject REQUEST_DATA = new JSONObject();


        ESB_ATTRS.put("App_ID", "SPMS");
        ESB_ATTRS.put("Target_ID", sapClient);
        ESB_ATTRS.put("Application_ID", "00020000000002");
        ESB_ATTRS.put("Transaction_ID", UUID.randomUUID().toString());

        JSONObject head = new JSONObject();

        if(StringUtils.isNotEmpty(dto.getBeginDate())){
            head.put("S_BEDATF", dto.getBeginDate());//凭证日期从
        }
        if(StringUtils.isNotEmpty(dto.getEndDate())){
            head.put("S_BEDATE", dto.getEndDate());//凭证日期到
        }
        if(StringUtils.isNotEmpty(dto.getWerks())){
            head.put("S_FHWERKS", dto.getWerks());//发货工厂
        }
        if(StringUtils.isNotEmpty(dto.getReceiveWerks())){
            head.put("S_SHWERKS", dto.getReceiveWerks());//收货工厂
        }
        if(StringUtils.isNotEmpty(dto.getPurchaseNo())){
            head.put("S_EBELN", dto.getPurchaseNo());//采购订单
        }
        if(StringUtils.isNotEmpty(dto.getSapDeliveryNote())){
            head.put("S_VBELN", dto.getSapDeliveryNote());//交货单
        }
        if(StringUtils.isNotEmpty(dto.getMaterialNo())){
            head.put("S_MATNR", dto.getMaterialNo());//物料编码
        }
        if(StringUtils.isNotEmpty(dto.getBoxNote())){
            head.put("S_PACKAGE_CODE", dto.getBoxNote());//箱码
        }

        REQUEST_DATA.put("Head", head);
        REQUEST_DATA.put("HeadType", "0");// 0:字段Filed 1:结构Structure 2:表Table
        REQUEST_DATA.put("Operation", "Z_SPMS_ZAITURECEIVE_NEW");//Z_SPMS_ZAITU接口换成Z_SPMS_ZAITURECEIVE_NEW新接口，所取到的数据更多
        REQUEST_DATA.put("Type", "Z_SPMS_ZAITURECEIVE_NEW");
//        REQUEST_DATA.put("Operation", "Z_SPMS_INTRANSIT_RECEIPT");
//        REQUEST_DATA.put("Type", "Z_SPMS_INTRANSIT_RECEIPT");

        REQUEST.put("ESB_ATTRS", ESB_ATTRS);
        REQUEST.put("REQUEST_DATA", REQUEST_DATA);

        doc.put("REQUEST", REQUEST);
        return doc;
    }

	@Override
	public ResponseResult getDeliveryReportList(JSONObject doc) throws Exception {
		String werks = StringUtils.isEmpty(doc.getString("werks")) ? null : doc.getString("werks");
		String whsLocationCode = StringUtils.isEmpty(doc.getString("whsLocationCode")) ? null : doc.getString("whsLocationCode");
		String documentType = StringUtils.isEmpty(doc.getString("documentType")) ? null : doc.getString("documentType");
		String beginDate = StringUtils.isEmpty(doc.getString("beginDate")) ? null : doc.getString("beginDate");
		String endDate = StringUtils.isEmpty(doc.getString("endDate")) ? null : doc.getString("endDate");
		int pageNo = StringUtils.isNotEmpty(doc.getString("current")) ? doc.getIntValue("current") : 1;
        int pageSize = StringUtils.isNotEmpty(doc.getString("size")) ? doc.getIntValue("size") : Integer.MAX_VALUE;
		Page<Map<String, Object>> pages = new Page<>(pageNo, pageSize);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String nowDate = sdf.format(new Date());
		List<Map<String, Object>> allList = new ArrayList<>();
		List<Map<String, Object>> targetList = new ArrayList<>();
		Map<String, Object> outlineMap = new HashMap<>();
		if ("1".equals(doc.getString("statisticalType"))) {// 发货效率报表查询
			pages = new Page<>(pageNo, Integer.MAX_VALUE);
			if ("1".equals(doc.getString("documentType")) || "0".equals(doc.getString("documentType"))) {// 查询领用出库数据
				// 发货效率详情列表数据
		        List<Map<String, Object>> pageMaData = this.overseaReportMapper.queryOverseaWhsOutByPage(pages, werks, whsLocationCode, beginDate, endDate);
		        if (CollectionUtils.isNotEmpty(pageMaData)) {
		        	for (Map<String, Object> map : pageMaData) {
		        		map.put("approvalDate", map.get("APPROVALDATE"));
		        		// 计算出库耗时：过账时间-审批通过时间
		        		if (map.get("approvalDate") != null && map.get("postingDate") != null) {
		        			String postingDate = map.get("postingDate").toString();
		        			String approvalDate = map.get("approvalDate").toString();
		        			long postingDateTime = sdf.parse(postingDate).getTime();
		        			long approvalDateTime = sdf.parse(approvalDate).getTime();
		        			// 以分钟计算时间差
		        			long diffTime = (postingDateTime-approvalDateTime)/60000;
		        			map.put("timeConsuming", new BigDecimal(diffTime).setScale(2, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString());
		        		}
		        		map.put("nowDate", nowDate);
		        	}
		        	allList.addAll(pageMaData);
		        }
			} else {
				
			}
			// 统计指标列表数据
			if (CollectionUtils.isNotEmpty(allList)) {
				// 按照工厂、仓库、单据类型分组
				Map<String, List<Map<String, Object>>> collect = allList.stream().collect(Collectors.groupingBy(o -> o.get("werks").toString()+"_"+o.get("whsLocationCode").toString()+"_"+o.get("orderType")));
				for (Map.Entry<String, List<Map<String, Object>>> entry : collect.entrySet()) {
					Map<String, Object> map = new HashMap<>();
					String key = entry.getKey();
					List<Map<String,Object>> values = entry.getValue();
					String[] keySplit = key.split("_");
					map.put("werks", keySplit[0]);
					map.put("whsLocationCode", keySplit[1]);
					map.put("orderType", keySplit[2]);
					// 统计出库总耗时：每个出库单的耗时只统计一次
					Map<String, DoubleSummaryStatistics> outOrderMaps = values.stream().filter(e -> e.get("outSpmsId") != null && e.get("timeConsuming") != null).collect(Collectors.groupingBy(o -> o.get("outSpmsId").toString(), Collectors.summarizingDouble(s -> Double.valueOf(s.get("timeConsuming").toString()))));
					BigDecimal allTime = BigDecimal.ZERO;
					if (outOrderMaps != null) {
						for (Map.Entry<String, DoubleSummaryStatistics> ent : outOrderMaps.entrySet()) {
							allTime = allTime.add(new BigDecimal(ent.getValue().getAverage()));
						}
					}
					map.put("allTimeConsuming", allTime.stripTrailingZeros().toPlainString());
					// 统计单据总量
					Map<String, List<Map<String, Object>>> spmsIdMaps = values.stream().collect(Collectors.groupingBy(o -> o.get("spmsId").toString()));
					map.put("allOrderNum", spmsIdMaps != null ? spmsIdMaps.size() : 0);
					// 统计出库单总量
					Map<String, List<Map<String, Object>>> outSpmsIdMaps = values.stream().filter(e -> e.get("outSpmsId") != null).collect(Collectors.groupingBy(o -> o.get("outSpmsId").toString()));
					map.put("allOutOrderNum", outSpmsIdMaps != null ? outSpmsIdMaps.size() : 0);
					// 统计已关闭的出库单总量
					Map<String, List<Map<String, Object>>> outCloseMaps = values.stream().filter(e -> e.get("outSpmsId") != null && "已关闭".equals(e.get("outSpmsStatus").toString())).collect(Collectors.groupingBy(o -> o.get("outSpmsId").toString()));
					map.put("allOutOrderCloseNum", outCloseMaps != null ? outCloseMaps.size() : 0);
					// 领用申请单行项目数量
					map.put("allItemNum", values.size());
					// 出库单提交SAP成功的行项目数量
					List<Map<String, Object>> allOutItemNumList = values.stream().filter(e -> e.get("outSpmsId") != null && "提交SAP成功".equals(e.get("outSpmsStatus").toString())).collect(Collectors.toList());
					map.put("allOutItemNum", allOutItemNumList != null ? allOutItemNumList.size() : 0);
					// 发货及时率：出库单提交SAP成功的行项目数量/领用申请单行项目数量*100
					BigDecimal divide = new BigDecimal(map.get("allOutItemNum").toString()).multiply(new BigDecimal("100")).divide(new BigDecimal(values.size()), 2, BigDecimal.ROUND_HALF_UP);
					map.put("timelinessRate", divide.stripTrailingZeros().toPlainString());
					if (outSpmsIdMaps != null && outSpmsIdMaps.size() != 0) {
						// 出库时效率：统计出库总耗时/出库单总量*100
						BigDecimal divide2 = new BigDecimal(map.get("allTimeConsuming").toString()).divide(new BigDecimal(map.get("allOutOrderNum").toString()), 2, BigDecimal.ROUND_HALF_UP);
						map.put("timeEfficiencyRate", divide2.stripTrailingZeros().toPlainString());
						// 发货准确率：（出库单总量-已关闭出库单总量）/出库单总量*100
						BigDecimal divide3 = (new BigDecimal(map.get("allOutOrderNum").toString()).subtract(new BigDecimal(map.get("allOutOrderCloseNum").toString()))).multiply(new BigDecimal("100")).divide(new BigDecimal(map.get("allOutOrderNum").toString()), 2, BigDecimal.ROUND_HALF_UP);
						map.put("accuracyRate", divide3.stripTrailingZeros().toPlainString());
					} else {
						map.put("timeEfficiencyRate", 0);
						map.put("accuracyRate", 0);
					}
					// 查询日期
					map.put("nowDate", nowDate);
					targetList.add(map);
				}
			}
			// 统计概要
			if (CollectionUtils.isNotEmpty(allList)) {
				// 出库总耗时
				Map<String, DoubleSummaryStatistics> outOrderMaps = allList.stream().filter(e -> e.get("outSpmsId") != null && e.get("timeConsuming") != null).collect(Collectors.groupingBy(o -> o.get("outSpmsId").toString(), Collectors.summarizingDouble(s -> Double.valueOf(s.get("timeConsuming").toString()))));
				BigDecimal allTime = BigDecimal.ZERO;
				if (outOrderMaps != null) {
					for (Map.Entry<String, DoubleSummaryStatistics> ent : outOrderMaps.entrySet()) {
						allTime = allTime.add(new BigDecimal(ent.getValue().getAverage()));
					}
				}
				// 出库单总量
				Map<String, List<Map<String, Object>>> outNumMaps = allList.stream().filter(e -> e.get("outSpmsId") != null).collect(Collectors.groupingBy(o -> o.get("outSpmsId").toString()));
				outlineMap.put("allOutOrderNum", outNumMaps != null ? outNumMaps.size() : 0);
				// 已关闭的出库单总量
				Map<String, List<Map<String, Object>>> outCloseMaps = allList.stream().filter(e -> e.get("outSpmsId") != null && "已关闭".equals(e.get("outSpmsStatus").toString())).collect(Collectors.groupingBy(o -> o.get("outSpmsId").toString()));
				// 出库单总行数
				List<Map<String, Object>> outItemNumMaps = allList.stream().filter(e -> e.get("outSpmsId") != null && "提交SAP成功".equals(e.get("outSpmsStatus").toString())).collect(Collectors.toList());
				outlineMap.put("allOutItemNum", outItemNumMaps != null ? outItemNumMaps.size() : 0);
				// 发货及时率：出库单总行数/领用单总行数*100
				BigDecimal divide = new BigDecimal(outlineMap.get("allOutItemNum").toString()).multiply(new BigDecimal("100")).divide(new BigDecimal(allList.size()), 2, BigDecimal.ROUND_HALF_UP);
				outlineMap.put("timelinessRate", divide.stripTrailingZeros().toPlainString()+"%");
				if (outNumMaps != null && outNumMaps.size() != 0) {
					// 出库时效率：
					BigDecimal divide2 = allTime.divide(new BigDecimal(outlineMap.get("allOutOrderNum").toString()), 2, BigDecimal.ROUND_HALF_UP);
					outlineMap.put("timeEfficiencyRate", divide2.stripTrailingZeros().toPlainString());
					// 发货准确率
					int closeCount = outCloseMaps != null ? outCloseMaps.size() : 0;
					outlineMap.put("accuracyNum", outNumMaps.size()-closeCount);
					BigDecimal divide3 = new BigDecimal(outNumMaps.size()-closeCount).multiply(new BigDecimal("100")).divide(new BigDecimal(outNumMaps.size()), 2, BigDecimal.ROUND_HALF_UP);
					outlineMap.put("accuracyRate", divide3.stripTrailingZeros().toPlainString()+"%");
				} else {
					outlineMap.put("timeEfficiencyRate", 0);
					outlineMap.put("accuracyNum", 0);
					outlineMap.put("accuracyRate", 0);
				}
			}
		} else if ("2".equals(doc.getString("statisticalType"))) {// 收货效率报表查询
			pages = new Page<>(pageNo, Integer.MAX_VALUE);
			List<Map<String, Object>> pageMaData = this.overseaReportMapper.queryOverseaDeliveryNoteByPage(pages, werks, whsLocationCode, beginDate, endDate, documentType);
	        if (CollectionUtils.isNotEmpty(pageMaData)) {
	        	for (Map<String, Object> map : pageMaData) {
	        		// 计算入库耗时：入库完成时间-入库创建时间
	        		if (map.get("inWhsCreateTime") != null && map.get("inWhsEndTime") != null) {
	        			String whsCreateDate = map.get("inWhsCreateTime").toString();
	        			String whsEndDate = map.get("inWhsEndTime").toString();
	        			long whsCreateDateTime = sdf.parse(whsCreateDate).getTime();
	        			long whsEndDateTime = sdf.parse(whsEndDate).getTime();
	        			// 以分钟计算时间差
	        			long diffTime = (whsEndDateTime-whsCreateDateTime)/60000;
	        			map.put("timeWarehousing", new BigDecimal(diffTime).setScale(2, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString());
	        		}
	        		// 计算交货耗时：交货完成时间-入库创建时间
	        		if (map.get("inWhsCreateTime") != null && map.get("receivingDate") != null) {
	        			String whsCreateDate = map.get("inWhsCreateTime").toString();
	        			String receivingDate = map.get("receivingDate").toString();
	        			long whsCreateDateTime = sdf.parse(whsCreateDate).getTime();
	        			long receivingDateTime = sdf.parse(receivingDate).getTime();
	        			// 以分钟计算时间差
	        			long diffTime = (receivingDateTime-whsCreateDateTime)/60000;
	        			map.put("timeDelivery", new BigDecimal(diffTime).setScale(2, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString());
	        		}
	        		map.put("nowDate", nowDate);
	        	}
	        	allList.addAll(pageMaData);
	        }
	        // 统计指标列表数据
 			if (CollectionUtils.isNotEmpty(allList)) {
 				// 按照工厂、仓库、单据类型分组
 				Map<String, List<Map<String, Object>>> collect = allList.stream().collect(Collectors.groupingBy(o -> o.get("werks").toString()+"_"+o.get("whsLocationCode").toString()+"_"+o.get("orderType")));
 				for (Map.Entry<String, List<Map<String, Object>>> entry : collect.entrySet()) {
 					Map<String, Object> map = new HashMap<>();
 					String key = entry.getKey();
 					List<Map<String,Object>> values = entry.getValue();
 					String[] keySplit = key.split("_");
 					map.put("werks", keySplit[0]);
 					map.put("whsLocationCode", keySplit[1]);
 					map.put("orderType", keySplit[2]);
 					// 统计入库总耗时：每个入库单的耗时只统计一次
 					Map<String, DoubleSummaryStatistics> outOrderMaps = values.stream().filter(e -> e.get("spmsId") != null && e.get("timeWarehousing") != null).collect(Collectors.groupingBy(o -> o.get("spmsId").toString()+"_"+o.get("timeWarehousing").toString(), Collectors.summarizingDouble(s -> Double.valueOf(s.get("timeWarehousing").toString()))));
 					BigDecimal allTime = BigDecimal.ZERO;
 					if (outOrderMaps != null) {
 						for (Map.Entry<String, DoubleSummaryStatistics> ent : outOrderMaps.entrySet()) {
 							allTime = allTime.add(new BigDecimal(ent.getValue().getAverage()));
 						}
 					}
 					map.put("allTimeWarehousing", allTime.stripTrailingZeros().toPlainString());
 					// 统计入库单总量
 					Map<String, List<Map<String, Object>>> spmsIdMaps = values.stream().filter(e -> e.get("spmsId") != null).collect(Collectors.groupingBy(o -> o.get("spmsId").toString()));
 					map.put("allInWhsNum", spmsIdMaps != null ? spmsIdMaps.size() : 0);
 					// 统计入库完成总SKU量
 					Map<String, List<Map<String, Object>>> inItemMaps = values.stream().filter(e -> e.get("spmsId") != null).collect(Collectors.groupingBy(o -> o.get("spmsId").toString()+"_"+o.get("sapDeliveyNoteItem").toString()));
 					map.put("allInWhsSkuNum", inItemMaps != null ? inItemMaps.size() : 0);
 					// 统计存货损失总SKU量
 					Map<String, List<Map<String, Object>>> unInItemMaps = values.stream().filter(e -> e.get("underVoucherNumber") != null ).collect(Collectors.groupingBy(o -> o.get("underVoucherNumber").toString()+"_"+o.get("sapDeliveyNoteItem").toString()));
 					int unItemNum = unInItemMaps != null ? unInItemMaps.size() : 0;
 					Map<String, List<Map<String, Object>>> overInItemMaps = values.stream().filter(e -> e.get("overVoucherNumber") != null ).collect(Collectors.groupingBy(o -> o.get("overVoucherNumber").toString()+"_"+o.get("sapDeliveyNoteItem").toString()));
 					int overItemNum = overInItemMaps != null ? overInItemMaps.size() : 0;
 					map.put("allUnOverSkuNum", unItemNum+overItemNum);
 					// 统计交货总SKU量
 					Map<String, List<Map<String, Object>>> noteMaps = values.stream().collect(Collectors.groupingBy(o -> o.get("sapDeliveyNote").toString()+"_"+o.get("sapDeliveyNoteItem").toString()));
 					map.put("allDeliveryNoteNum", noteMaps != null ? noteMaps.size() : 0);
 					// 计算收货及时率：收货及时率=入库完成总SKU量/交货总SKU量*100
 					if (noteMaps != null && noteMaps.size() > 0) {
 						BigDecimal divide = new BigDecimal(map.get("allInWhsSkuNum").toString()).multiply(new BigDecimal("100")).divide(new BigDecimal(noteMaps.size()), 2, BigDecimal.ROUND_HALF_UP);
 						map.put("timelinessRate", divide.stripTrailingZeros().toPlainString());
 					} else {
 						map.put("timelinessRate", "0");
 					}
 					// 计算入库时效率（天）：入库时效率=入库总时间/入库总单量
 					if (spmsIdMaps != null && spmsIdMaps.size() > 0) {
 						BigDecimal divide = new BigDecimal(map.get("allTimeWarehousing").toString()).divide(new BigDecimal(spmsIdMaps.size()), 3, BigDecimal.ROUND_HALF_UP);
 						// 计算以天为单位
 						BigDecimal divide2 = divide.divide(new BigDecimal("1440"), 1, BigDecimal.ROUND_HALF_UP);
 						map.put("timeEfficiencyRate", divide2.stripTrailingZeros().toPlainString());
 					} else {
 						map.put("timeEfficiencyRate", "0");
 					}
 					// 计算收货准确率：收货准确率=(入库完成总SKU量-存货损失总SKU量)/入库完成总SKU量*100
 					if (inItemMaps != null && inItemMaps.size() > 0) {
 						BigDecimal subtract = new BigDecimal(map.get("allInWhsSkuNum").toString()).subtract(new BigDecimal(map.get("allUnOverSkuNum").toString()));
 						BigDecimal divide = subtract.multiply(new BigDecimal("100")).divide(new BigDecimal(inItemMaps.size()), 2, BigDecimal.ROUND_HALF_UP);
 						map.put("accuracyRate", divide.stripTrailingZeros().toPlainString());
 					} else {
 						map.put("accuracyRate", "0");
 					}
 					// 查询日期
 					map.put("nowDate", nowDate);
 					targetList.add(map);
 				}
 			}
 			// 统计概要
 			if (CollectionUtils.isNotEmpty(allList)) {
 				// 统计入库完成总SKU量
				Map<String, List<Map<String, Object>>> inItemMaps = allList.stream().filter(e -> e.get("spmsId") != null).collect(Collectors.groupingBy(o -> o.get("spmsId").toString()+"_"+o.get("sapDeliveyNoteItem").toString()));
				// 统计交货总SKU量
				Map<String, List<Map<String, Object>>> noteMaps = allList.stream().collect(Collectors.groupingBy(o -> o.get("sapDeliveyNote").toString()+"_"+o.get("sapDeliveyNoteItem").toString()));
				// 入库完成总SKU量
				outlineMap.put("allInWhsSkuNum", inItemMaps != null ? inItemMaps.size() : 0);	
 				// 收货及时率=入库完成总SKU量/交货总SKU量*100
				if (noteMaps != null && noteMaps.size() > 0) {
					BigDecimal divide = new BigDecimal(outlineMap.get("allInWhsSkuNum").toString()).multiply(new BigDecimal("100")).divide(new BigDecimal(noteMaps.size()), 2, BigDecimal.ROUND_HALF_UP);
					outlineMap.put("timelinessRate", divide.stripTrailingZeros().toPlainString()+"%");
				} else {
					outlineMap.put("timelinessRate", "0%");
				}
				// 统计入库总时间
				Map<String, DoubleSummaryStatistics> outOrderMaps = allList.stream().filter(e -> e.get("spmsId") != null && e.get("timeWarehousing") != null).collect(Collectors.groupingBy(o -> o.get("spmsId").toString()+"_"+o.get("timeWarehousing").toString(), Collectors.summarizingDouble(s -> Double.valueOf(s.get("timeWarehousing").toString()))));
				BigDecimal allTime = BigDecimal.ZERO;
				if (outOrderMaps != null) {
					for (Map.Entry<String, DoubleSummaryStatistics> ent : outOrderMaps.entrySet()) {
						allTime = allTime.add(new BigDecimal(ent.getValue().getAverage()));
					}
				}
 				// 入库总单量
				Map<String, List<Map<String, Object>>> spmsIdMaps = allList.stream().filter(e -> e.get("spmsId") != null).collect(Collectors.groupingBy(o -> o.get("spmsId").toString()));
				outlineMap.put("allInWhsOrderNum", spmsIdMaps != null ? spmsIdMaps.size() : 0);
				// 入库时效率（天）=入库总时间/入库总单量
				if (spmsIdMaps != null && spmsIdMaps.size() > 0) {
					BigDecimal divide = allTime.divide(new BigDecimal(spmsIdMaps.size()), 3, BigDecimal.ROUND_HALF_UP);
					// 计算以天为单位
					BigDecimal divide2 = divide.divide(new BigDecimal("1440"), 1, BigDecimal.ROUND_HALF_UP);
					outlineMap.put("timeEfficiencyRate", divide2.stripTrailingZeros().toPlainString()+"天");
				} else {
					outlineMap.put("timeEfficiencyRate", "0天");
				}
				// 统计存货损失总SKU量
				Map<String, List<Map<String, Object>>> unInItemMaps = allList.stream().filter(e -> e.get("underVoucherNumber") != null ).collect(Collectors.groupingBy(o -> o.get("underVoucherNumber").toString()+"_"+o.get("sapDeliveyNoteItem").toString()));
				int unItemNum = unInItemMaps != null ? unInItemMaps.size() : 0;
				Map<String, List<Map<String, Object>>> overInItemMaps = allList.stream().filter(e -> e.get("overVoucherNumber") != null ).collect(Collectors.groupingBy(o -> o.get("overVoucherNumber").toString()+"_"+o.get("sapDeliveyNoteItem").toString()));
				int overItemNum = overInItemMaps != null ? overInItemMaps.size() : 0;
				BigDecimal subtract = new BigDecimal(outlineMap.get("allInWhsSkuNum").toString()).subtract(new BigDecimal(String.valueOf(unItemNum+overItemNum)));
				outlineMap.put("accuracyNum", subtract.stripTrailingZeros().toPlainString());
				if (inItemMaps != null && inItemMaps.size() > 0) {
					BigDecimal divide = subtract.multiply(new BigDecimal("100")).divide(new BigDecimal(inItemMaps.size()), 2, BigDecimal.ROUND_HALF_UP);
					outlineMap.put("accuracyRate", divide.stripTrailingZeros().toPlainString()+"%");
				} else {
					outlineMap.put("accuracyRate", "0%");
				}
 			}
		} else if ("3".equals(doc.getString("statisticalType"))) {// PDA覆盖率报表查询
			if ("0".equals(doc.getString("documentType"))) {// 查询全部类型单据的数据
				List<Map<String, Object>> pageMaData = this.overseaReportMapper.queryPdaCoverageRateByPage(pages, werks, whsLocationCode, beginDate, endDate);
				allList.addAll(pageMaData);
				// 查询全部数据量
				List<Map<String, Object>> allCountMap = this.overseaReportMapper.queryPdaCoverageRateAllCount(werks, whsLocationCode, beginDate, endDate);
				// 查询PDA操作的数据量
				List<Map<String, Object>> pdaCountMap = this.overseaReportMapper.queryPdaCoverageRatePdaCount(werks, whsLocationCode, beginDate, endDate);
				// 全部单据量
				BigDecimal allOrderCount = BigDecimal.ONE;
				// PDA操作单据量
				BigDecimal pdaOrderCount = BigDecimal.ZERO;
				if (CollectionUtils.isNotEmpty(allCountMap)) {
					Map<String, List<Map<String, Object>>> werksMaps = new HashMap<>();
					if (CollectionUtils.isNotEmpty(pdaCountMap)) {
						werksMaps = pdaCountMap.stream().collect(Collectors.groupingBy(o -> o.get("werks").toString()+"_"+o.get("whsLocationCode").toString()));
					}
					for (Map<String, Object> map : allCountMap) {
						map.put("orderType", "所有单据");
						String key = map.get("werks").toString()+"_"+map.get("whsLocationCode").toString();
						List<Map<String, Object>> valueList = werksMaps.get(key);
						map.put("pdaCount", CollectionUtils.isNotEmpty(valueList) ? valueList.get(0).get("pdaCount").toString() : "0");
						// pda覆盖率
						BigDecimal divide = new BigDecimal(map.get("pdaCount").toString()).divide(new BigDecimal(map.get("allCount").toString()), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
						map.put("coverageRate", divide.stripTrailingZeros().toPlainString()+"%");
						allOrderCount = allOrderCount.add(new BigDecimal(map.get("allCount").toString()));
					}
				}
				targetList.addAll(allCountMap);
				if (CollectionUtils.isNotEmpty(pdaCountMap)) {
					for (Map<String, Object> map : pdaCountMap) {
						pdaOrderCount = pdaOrderCount.add(new BigDecimal(map.get("pdaCount").toString()));
					}
				}
				outlineMap.put("pdaCount", pdaOrderCount);
				BigDecimal multiply = pdaOrderCount.divide(allOrderCount, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
				outlineMap.put("coverageRate", multiply.stripTrailingZeros().toPlainString()+"%");
			}
		} else if ("4".equals(doc.getString("statisticalType"))) { // 过账异常率报表查询
			List<Map<String, Object>> pageMaData = this.overseaReportMapper.queryAnomaliesRateByPage(pages, werks, whsLocationCode, beginDate, endDate, documentType);
			allList.addAll(pageMaData);
			// 查询剔除删除、关闭的单据总量
			List<Map<String, Object>> allOrderMaps = this.overseaReportMapper.queryAnomaliesRateAllOrderCount(werks, whsLocationCode, beginDate, endDate, documentType);
			// 不分页查询提交SAP失败单据数量
			int failOrderCount = this.overseaReportMapper.queryAnomaliesRateFailOrderCount(werks, whsLocationCode, beginDate, endDate, documentType);
			BigDecimal multiply = BigDecimal.ZERO;
			List<Map<String, Object>> tagerMap = new ArrayList<>();
			Map<String, Object> map = new HashMap<>();
			if (CollectionUtils.isNotEmpty(allOrderMaps)) {
				BigDecimal orderCount = allOrderMaps.get(0).get("orderCount") != null ? (BigDecimal) allOrderMaps.get(0).get("orderCount") : BigDecimal.ZERO;
				multiply = new BigDecimal(String.valueOf(failOrderCount)).divide(orderCount, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
				map.put("werks", allOrderMaps.get(0).get("werks").toString());
				map.put("whsLocationCode", allOrderMaps.get(0).get("whsLocationCode").toString());
				map.put("orderType", allOrderMaps.get(0).get("orderType").toString());
				map.put("allCount", allOrderMaps.get(0).get("orderCount").toString());
				map.put("failCount", failOrderCount);
			}
			map.put("failRate", multiply.stripTrailingZeros().toPlainString());
			tagerMap.add(map);
			targetList.addAll(tagerMap);
			outlineMap.put("failCount", failOrderCount);
			outlineMap.put("failRate", multiply.stripTrailingZeros().toPlainString()+"%");
		} else if ("5".equals(doc.getString("statisticalType"))) { // 在途超期未收货率报表
			List<Map<String, Object>> pageMaData = this.overseaReportMapper.queryOnwayRateByPage(pages, werks, whsLocationCode, beginDate, endDate, documentType);
			allList.addAll(pageMaData);
			// 不分页根据条件查询全部在途数据
			List<Map<String, Object>> onwayAllList = this.overseaReportMapper.queryOnwayRateByList(werks, whsLocationCode, beginDate, endDate, documentType);
			List<Map<String, Object>> tagerMap = new ArrayList<>();
			Map<String, Object> map = new HashMap<>();
			if (CollectionUtils.isNotEmpty(onwayAllList)) {
				SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
				// 收货工厂
				map.put("werks", onwayAllList.get(0).get("shWerks").toString());
				// 超期未收总单量
				map.put("allCount", onwayAllList.size());
				// 超期3天未收：当前日期-3天 >= 到库日期
				Calendar cal3 = Calendar.getInstance();
				cal3.add(Calendar.DAY_OF_MONTH, -3);
				cal3.getTime();
				String nowDateStr3 = sdf2.format(cal3.getTime());
				Long nowLong3 = sdf2.parse(nowDateStr3).getTime();
				List<Map<String, Object>> onwayDays3 = onwayAllList.stream().filter(o -> {
					try {
						return o.get("dkDate") != null && nowLong3 >= sdf2.parse(o.get("dkDate").toString()).getTime();
					} catch (ParseException e) {
						return false;
					}
				}).collect(Collectors.toList());
				map.put("threeDaysCount", CollectionUtils.isNotEmpty(onwayDays3) ? onwayDays3.size() : 0);
				// 超期7天未收：当前日期-7天 >= 到库日期
				Calendar cal7 = Calendar.getInstance();
				cal7.add(Calendar.DAY_OF_MONTH, -7);
				cal7.getTime();
				String nowDateStr7 = sdf2.format(cal7.getTime());
				Long nowLong7 = sdf2.parse(nowDateStr7).getTime();
				List<Map<String, Object>> onwayDays7 = onwayAllList.stream().filter(o -> {
					try {
						return o.get("dkDate") != null && nowLong7 >= sdf2.parse(o.get("dkDate").toString()).getTime();
					} catch (ParseException e) {
						return false;
					}
				}).collect(Collectors.toList());
				map.put("sevenDaysCount", CollectionUtils.isNotEmpty(onwayDays7) ? onwayDays7.size() : 0);
				// 超期14天未收：当前日期-14天 >= 到库日期
				Calendar cal14 = Calendar.getInstance();
				cal14.add(Calendar.DAY_OF_MONTH, -14);
				cal14.getTime();
				String nowDateStr14 = sdf2.format(cal14.getTime());
				Long nowLong14 = sdf2.parse(nowDateStr14).getTime();
				List<Map<String, Object>> onwayDays14 = onwayAllList.stream().filter(o -> {
					try {
						return o.get("dkDate") != null && nowLong14 >= sdf2.parse(o.get("dkDate").toString()).getTime();
					} catch (ParseException e) {
						return false;
					}
				}).collect(Collectors.toList());
				map.put("fourteenDaysCount", CollectionUtils.isNotEmpty(onwayDays14) ? onwayDays14.size() : 0);
				// 超期21天未收：当前日期-21天 >= 到库日期
				Calendar cal121 = Calendar.getInstance();
				cal121.add(Calendar.DAY_OF_MONTH, -21);
				cal121.getTime();
				String nowDateStr21 = sdf2.format(cal121.getTime());
				Long nowLong21 = sdf2.parse(nowDateStr21).getTime();
				List<Map<String, Object>> onwayDays21 = onwayAllList.stream().filter(o -> {
					try {
						return o.get("dkDate") != null && nowLong21 >= sdf2.parse(o.get("dkDate").toString()).getTime();
					} catch (ParseException e) {
						return false;
					}
				}).collect(Collectors.toList());
				map.put("twentyoneDaysCount", CollectionUtils.isNotEmpty(onwayDays21) ? onwayDays21.size() : 0);
				// 超期28天未收：当前日期-28天 >= 到库日期
				Calendar cal128 = Calendar.getInstance();
				cal128.add(Calendar.DAY_OF_MONTH, -28);
				cal128.getTime();
				String nowDateStr28 = sdf2.format(cal128.getTime());
				Long nowLong28 = sdf2.parse(nowDateStr28).getTime();
				List<Map<String, Object>> onwayDays28 = onwayAllList.stream().filter(o -> {
					try {
						return o.get("dkDate") != null && nowLong28 >= sdf2.parse(o.get("dkDate").toString()).getTime();
					} catch (ParseException e) {
						return false;
					}
				}).collect(Collectors.toList());
				map.put("twentyeightDaysCount", CollectionUtils.isNotEmpty(onwayDays28) ? onwayDays28.size() : 0);
				// 超期28天以上未收：当前日期-28天 >= 到库日期
				Calendar cal129 = Calendar.getInstance();
				cal129.add(Calendar.DAY_OF_MONTH, -29);
				cal129.getTime();
				String nowDateStr29 = sdf2.format(cal129.getTime());
				Long nowLong29 = sdf2.parse(nowDateStr29).getTime();
				List<Map<String, Object>> onwayDays29 = onwayAllList.stream().filter(o -> {
					try {
						return o.get("dkDate") != null && nowLong29 >= sdf2.parse(o.get("dkDate").toString()).getTime();
					} catch (ParseException e) {
						return false;
					}
				}).collect(Collectors.toList());
				map.put("twentynineDaysCount", CollectionUtils.isNotEmpty(onwayDays29) ? onwayDays29.size() : 0);
				// 超期率：超期14天未收/超期未收总单量*100
				BigDecimal multiply = new BigDecimal(map.get("fourteenDaysCount").toString()).divide(new BigDecimal(map.get("allCount").toString()), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
				map.put("overdueRate", multiply.stripTrailingZeros().toPlainString());
				outlineMap.put("overdueCount", map.get("fourteenDaysCount").toString());
				outlineMap.put("overdueRate", multiply.stripTrailingZeros().toPlainString()+"%");
			} else {
				outlineMap.put("overdueCount", "0");
				outlineMap.put("overdueRate", "0%");
			}
			tagerMap.add(map);
			targetList.addAll(tagerMap);
		}
		return ResponseResult.success().add("list", pages.setRecords(allList)).add("targetList", targetList).add("outline", outlineMap);
	}

	@Override
	public List<Map<String, Object>> getOnwayReportList(JSONObject doc) {
		String werks = StringUtils.isEmpty(doc.getString("werks")) ? null : doc.getString("werks");
		String whsLocationCode = StringUtils.isEmpty(doc.getString("whsLocationCode")) ? null : doc.getString("whsLocationCode");
		String documentType = StringUtils.isEmpty(doc.getString("documentType")) ? null : doc.getString("documentType");
		String beginDate = StringUtils.isEmpty(doc.getString("beginDate")) ? null : doc.getString("beginDate");
		String endDate = StringUtils.isEmpty(doc.getString("endDate")) ? null : doc.getString("endDate");
		List<Map<String, Object>> onwayAllList = this.overseaReportMapper.queryOnwayRateByList(werks, whsLocationCode, beginDate, endDate, documentType);
		return onwayAllList;
	}

	@Override
	public List<Map<String, Object>> getOnwayTargetReportList(JSONObject doc) throws Exception {
		String werks = StringUtils.isEmpty(doc.getString("werks")) ? null : doc.getString("werks");
		String whsLocationCode = StringUtils.isEmpty(doc.getString("whsLocationCode")) ? null : doc.getString("whsLocationCode");
		String documentType = StringUtils.isEmpty(doc.getString("documentType")) ? null : doc.getString("documentType");
		String beginDate = StringUtils.isEmpty(doc.getString("beginDate")) ? null : doc.getString("beginDate");
		String endDate = StringUtils.isEmpty(doc.getString("endDate")) ? null : doc.getString("endDate");
		List<Map<String, Object>> onwayAllList = this.overseaReportMapper.queryOnwayRateByList(werks, whsLocationCode, beginDate, endDate, documentType);
		List<Map<String, Object>> tagerMap = new ArrayList<>();
		Map<String, Object> map = new HashMap<>();
		if (CollectionUtils.isNotEmpty(onwayAllList)) {
			SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
			// 收货工厂
			map.put("werks", onwayAllList.get(0).get("shWerks").toString());
			// 超期未收总单量
			map.put("allCount", onwayAllList.size());
			// 超期3天未收：当前日期-3天 >= 到库日期
			Calendar cal3 = Calendar.getInstance();
			cal3.add(Calendar.DAY_OF_MONTH, -3);
			cal3.getTime();
			String nowDateStr3 = sdf2.format(cal3.getTime());
			Long nowLong3 = sdf2.parse(nowDateStr3).getTime();
			List<Map<String, Object>> onwayDays3 = onwayAllList.stream().filter(o -> {
				try {
					return o.get("dkDate") != null && nowLong3 >= sdf2.parse(o.get("dkDate").toString()).getTime();
				} catch (ParseException e) {
					return false;
				}
			}).collect(Collectors.toList());
			map.put("threeDaysCount", CollectionUtils.isNotEmpty(onwayDays3) ? onwayDays3.size() : 0);
			// 超期7天未收：当前日期-7天 >= 到库日期
			Calendar cal7 = Calendar.getInstance();
			cal7.add(Calendar.DAY_OF_MONTH, -7);
			cal7.getTime();
			String nowDateStr7 = sdf2.format(cal7.getTime());
			Long nowLong7 = sdf2.parse(nowDateStr7).getTime();
			List<Map<String, Object>> onwayDays7 = onwayAllList.stream().filter(o -> {
				try {
					return o.get("dkDate") != null && nowLong7 >= sdf2.parse(o.get("dkDate").toString()).getTime();
				} catch (ParseException e) {
					return false;
				}
			}).collect(Collectors.toList());
			map.put("sevenDaysCount", CollectionUtils.isNotEmpty(onwayDays7) ? onwayDays7.size() : 0);
			// 超期14天未收：当前日期-14天 >= 到库日期
			Calendar cal14 = Calendar.getInstance();
			cal14.add(Calendar.DAY_OF_MONTH, -14);
			cal14.getTime();
			String nowDateStr14 = sdf2.format(cal14.getTime());
			Long nowLong14 = sdf2.parse(nowDateStr14).getTime();
			List<Map<String, Object>> onwayDays14 = onwayAllList.stream().filter(o -> {
				try {
					return o.get("dkDate") != null && nowLong14 >= sdf2.parse(o.get("dkDate").toString()).getTime();
				} catch (ParseException e) {
					return false;
				}
			}).collect(Collectors.toList());
			map.put("fourteenDaysCount", CollectionUtils.isNotEmpty(onwayDays14) ? onwayDays14.size() : 0);
			// 超期21天未收：当前日期-21天 >= 到库日期
			Calendar cal121 = Calendar.getInstance();
			cal121.add(Calendar.DAY_OF_MONTH, -21);
			cal121.getTime();
			String nowDateStr21 = sdf2.format(cal121.getTime());
			Long nowLong21 = sdf2.parse(nowDateStr21).getTime();
			List<Map<String, Object>> onwayDays21 = onwayAllList.stream().filter(o -> {
				try {
					return o.get("dkDate") != null && nowLong21 >= sdf2.parse(o.get("dkDate").toString()).getTime();
				} catch (ParseException e) {
					return false;
				}
			}).collect(Collectors.toList());
			map.put("twentyoneDaysCount", CollectionUtils.isNotEmpty(onwayDays21) ? onwayDays21.size() : 0);
			// 超期28天未收：当前日期-28天 >= 到库日期
			Calendar cal128 = Calendar.getInstance();
			cal128.add(Calendar.DAY_OF_MONTH, -28);
			cal128.getTime();
			String nowDateStr28 = sdf2.format(cal128.getTime());
			Long nowLong28 = sdf2.parse(nowDateStr28).getTime();
			List<Map<String, Object>> onwayDays28 = onwayAllList.stream().filter(o -> {
				try {
					return o.get("dkDate") != null && nowLong28 >= sdf2.parse(o.get("dkDate").toString()).getTime();
				} catch (ParseException e) {
					return false;
				}
			}).collect(Collectors.toList());
			map.put("twentyeightDaysCount", CollectionUtils.isNotEmpty(onwayDays28) ? onwayDays28.size() : 0);
			// 超期28天以上未收：当前日期-28天 >= 到库日期
			Calendar cal129 = Calendar.getInstance();
			cal129.add(Calendar.DAY_OF_MONTH, -29);
			cal129.getTime();
			String nowDateStr29 = sdf2.format(cal129.getTime());
			Long nowLong29 = sdf2.parse(nowDateStr29).getTime();
			List<Map<String, Object>> onwayDays29 = onwayAllList.stream().filter(o -> {
				try {
					return o.get("dkDate") != null && nowLong29 >= sdf2.parse(o.get("dkDate").toString()).getTime();
				} catch (ParseException e) {
					return false;
				}
			}).collect(Collectors.toList());
			map.put("twentynineDaysCount", CollectionUtils.isNotEmpty(onwayDays29) ? onwayDays29.size() : 0);
			// 超期率：超期14天未收/超期未收总单量*100
			BigDecimal multiply = new BigDecimal(map.get("fourteenDaysCount").toString()).divide(new BigDecimal(map.get("allCount").toString()), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
			map.put("overdueRate", multiply.stripTrailingZeros().toPlainString());
		}
		tagerMap.add(map);
		return tagerMap;
	}

	@Override
	public List<Map<String, Object>> getAnomaliesReportList(JSONObject doc) {
		String werks = StringUtils.isEmpty(doc.getString("werks")) ? null : doc.getString("werks");
		String whsLocationCode = StringUtils.isEmpty(doc.getString("whsLocationCode")) ? null : doc.getString("whsLocationCode");
		String documentType = StringUtils.isEmpty(doc.getString("documentType")) ? null : doc.getString("documentType");
		String beginDate = StringUtils.isEmpty(doc.getString("beginDate")) ? null : doc.getString("beginDate");
		String endDate = StringUtils.isEmpty(doc.getString("endDate")) ? null : doc.getString("endDate");
		int pageNo = 1;
        int pageSize = Integer.MAX_VALUE;
		Page<Map<String, Object>> pages = new Page<>(pageNo, pageSize);
		List<Map<String, Object>> pageMaData = this.overseaReportMapper.queryAnomaliesRateByPage(pages, werks, whsLocationCode, beginDate, endDate, documentType);
		return pageMaData;
	}

	@Override
	public List<Map<String, Object>> getAnomaliesTargetReportList(JSONObject doc) {
		String werks = StringUtils.isEmpty(doc.getString("werks")) ? null : doc.getString("werks");
		String whsLocationCode = StringUtils.isEmpty(doc.getString("whsLocationCode")) ? null : doc.getString("whsLocationCode");
		String documentType = StringUtils.isEmpty(doc.getString("documentType")) ? null : doc.getString("documentType");
		String beginDate = StringUtils.isEmpty(doc.getString("beginDate")) ? null : doc.getString("beginDate");
		String endDate = StringUtils.isEmpty(doc.getString("endDate")) ? null : doc.getString("endDate");
		List<Map<String, Object>> allOrderMaps = this.overseaReportMapper.queryAnomaliesRateAllOrderCount(werks, whsLocationCode, beginDate, endDate, documentType);
		// 不分页查询提交SAP失败单据数量
		int failOrderCount = this.overseaReportMapper.queryAnomaliesRateFailOrderCount(werks, whsLocationCode, beginDate, endDate, documentType);
		BigDecimal multiply = BigDecimal.ZERO;
		List<Map<String, Object>> tagerMap = new ArrayList<>();
		Map<String, Object> map = new HashMap<>();
		if (CollectionUtils.isNotEmpty(allOrderMaps)) {
			BigDecimal orderCount = allOrderMaps.get(0).get("orderCount") != null ? (BigDecimal) allOrderMaps.get(0).get("orderCount") : BigDecimal.ZERO;
			multiply = new BigDecimal(String.valueOf(failOrderCount)).divide(orderCount, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
			map.put("werks", allOrderMaps.get(0).get("werks").toString());
			map.put("whsLocationCode", allOrderMaps.get(0).get("whsLocationCode").toString());
			map.put("orderType", allOrderMaps.get(0).get("orderType").toString());
			map.put("allCount", allOrderMaps.get(0).get("orderCount").toString());
			map.put("failCount", failOrderCount);
		}
		map.put("failRate", multiply.stripTrailingZeros().toPlainString());
		tagerMap.add(map);
		return tagerMap;
	}

}


