package cn.gov.customs.data.timer;


import cn.gov.customs.data.entity.wxjy.bus.*;
import cn.gov.customs.data.entity.wxjy.common.PubCustomsMapping;
import cn.gov.customs.data.repository.h2018.H2018Repository;
import cn.gov.customs.data.repository.iedg.IedgRepository;
import cn.gov.customs.data.repository.inspect.InspectRepository;
import cn.gov.customs.data.repository.rh2k.Rh2kRepository;
import cn.gov.customs.data.repository.wxjy.WxjyRepository;
import cn.gov.customs.data.repository.wxjy.bus.CustomMonthlyStatFinalRepository;
import cn.gov.customs.data.repository.wxjy.bus.CustomMonthlyStatRepository;
import cn.gov.customs.data.repository.wxjy.bus.EntryHeadRepository;
import cn.gov.customs.data.repository.wxjy.bus.EntryListRepository;
import cn.gov.customs.data.repository.wxjy.common.PubCustomsMappingRepository;
import cn.gov.customs.data.repository.zmqd.ZmqdRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: H2018危险品
 * @Author wq
 * @Date 2025-09-30 14:31:11
 * @Version 1.0
 */
@Component
@Configuration
@PropertySource("classpath:data-acquisition.properties")
public class H2018ZhDangerGoodsUtil {

	Logger logger = LoggerFactory.getLogger(H2018ZhDangerGoodsUtil.class);
	private static SimpleDateFormat yearSdf = new SimpleDateFormat("yyyy");

	private static SimpleDateFormat monthSdf = new SimpleDateFormat("yyyyMM");
	private static SimpleDateFormat daySdf = new SimpleDateFormat("yyyyMMdd");
	private static SimpleDateFormat fullSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private static final String IE_DATE_ADAPT = "12:00:00";//下发的报关单I_E_DATE丢失时分精度
	private static boolean reGenerateAllData = false;
	private static final String noRelStatMonth = "201812"; // 该月及之前月份月度统计中间数据不用维护所有字段内容，比如相对差值字段,去年/前年xx平均值

	private static final BigDecimal zero = new BigDecimal(0);
	private static HashMap<String, String> rootCustomsMap = new HashMap<String, String>();// 根据关区代码获得所隶属的一级关区代码

	private static List<String> hasMultipleCustomList = new ArrayList<String>(); // 拥有下级关区的关区代码

	private static Set<String> firstClassCustoms = new HashSet<String>(); // 一级关区代码集合

	@Autowired
	private H2018Repository h2018Dao;

	@Autowired
	private WxjyRepository dao;

	@Autowired
	private IedgRepository iedgRepository;

	@Autowired
	private InspectRepository inspDao;

	@Autowired
	private ZmqdRepository zmqdRepository;

	@Autowired
	private Rh2kRepository rh2kRepository;

	@Autowired
	private PubCustomsMappingRepository mappingRepository;

	@Autowired
	private EntryHeadRepository entryHeadRepository;

	@Autowired
	private EntryListRepository entryListRepository;

	@Autowired
	private CustomMonthlyStatFinalRepository customMonthlyStatFinalRepository;

	@Autowired
	private CustomMonthlyStatRepository customMonthlyStatRepository;
    @Autowired
    private PubCustomsMappingRepository pubCustomsMappingRepository;

	/**
	 * @description: H2018危险品报关单信息
	 * @param: hsCodes
	 * endTime
	 * @return: void
	 * @author zoumin
	 * @date: 2021-11-09 16:06:48
	 * @version 1.0
	 */
	public void h2018Business(List<String> ciqCodeList, Calendar c, String type) {
		/**H2018已结关报关单危险品信息*/
		logger.info("=================同步H2018已结关(80)报关单危险品信息======start==========");
		SimpleDateFormat daySdf = new SimpleDateFormat("yyyy-MM-dd");
		Date today = c.getTime();
		c.add(Calendar.DATE, -1);
		Date yesterday = c.getTime();
		String yesterdayStr = "";
		Date statBegin = null;
		Date statEnd = null;
		try {
			yesterdayStr = daySdf.format(yesterday);
			statBegin = daySdf.parse(yesterdayStr);
			statEnd = daySdf.parse(daySdf.format(today));
		} catch (ParseException e) {
			e.printStackTrace();
			return;
		}
		dao.executeUpdate("delete from WXJY_ENTRY_HEAD where RELEASE_DATE >= ? and RELEASE_DATE < ?", statBegin, statEnd);
		dao.executeUpdate("delete from WXJY_ENTRY_LIST where RELEASE_DATE >= ? and RELEASE_DATE < ?", statBegin, statEnd);//根据结关时间同步删除通过报关单号关联的商品编码表  zoumin 2020-11-11
		dao.executeUpdate("delete from WXJY_MID_D_M_STATUS where DATA_TYPE = 'EntryHead' and BUSINESS_TYPE = ? and STAT_PERIOD = ?", type, yesterdayStr);
		//获取危险品的ciq编码
		List<String> allCiqCodeList = (List<String>) iedgRepository.getQueryBySql("select distinct c.ciq_code from iedg_sync_chemicals_ciq c");
		try {
			// 一体化通关
			ythDeclMain(statBegin, statEnd, ciqCodeList, allCiqCodeList);

			// 口岸清关(直接进出口)
			kaqgDeclMain(statBegin, statEnd, ciqCodeList, allCiqCodeList);

			// 转关(因为需求不要求出境的，只考虑维护入境转关类型报关的转关数据发送时间、转关数据核销时间)
			zgDeclMain(statBegin, statEnd, ciqCodeList, allCiqCodeList);
//
			// 运维时可以查询MiddleDataMainStatus对应记录来分析哪些时间的定时任务没有正确执行，届时进行维护
			MiddleDataMainStatus mStatus = new MiddleDataMainStatus();
			mStatus.setCreateTime(new Date());
			mStatus.setDataType(EntryHead.class.getSimpleName());
			mStatus.setStatPeriod(yesterdayStr);
			mStatus.setBusinessType(type);
			dao.executeUpdate("insert into WXJY_MID_D_M_STATUS (ID,DATA_TYPE, STAT_PERIOD,BUSINESS_TYPE, CREATE_TIME) " +
					"values(sys_guid(),?,?,?,?) ", mStatus.getDataType(), mStatus.getStatPeriod(), mStatus.getBusinessType(), new Date());
		} catch (Exception e) {
			logger.error("危险品报关单通关时长统计每日中间表数据维护异常", e);
		}
		try {
			//删除中间表中涉案和删单的
			delSpecialAndDelHeadLogData(statEnd);
			logger.info("每日中间表涉案和删单的数据删除成功！");
		} catch (Exception e1) {
			logger.error("删除危险品报关单通关时长统计每日中间表涉案和删单数据异常", e1);
		}
		// 2019-11-19 增加每天维护当月的月度统计数据
		// reGenerateAllData 生产环境正式代码设置为false；清空所有中间数据重新生成时设置为true以提升效率，这时会全新生成所有月度统计；
		if (!reGenerateAllData) {
			// 月度统计维护关区合并的FINAL表用到，需要先初始化，否则首次执行时无法维护几个FINAL后缀的表数据
			if (firstClassCustoms.size() == 0) {// 还没有初始化过
				rootCustomsMap.clear();
				hasMultipleCustomList.clear();
				List<PubCustomsMapping> custMapping = mappingRepository.findAll();
				for (PubCustomsMapping m : custMapping) {
					String pCustomCode = m.getMappingCode();
					if (rootCustomsMap.containsValue(pCustomCode)) {
						hasMultipleCustomList.add(pCustomCode);
					}
					rootCustomsMap.put(m.getCustomsCode(), pCustomCode);
					firstClassCustoms.add(pCustomCode);
				}
			}

			String dataPeriod = monthSdf.format(yesterday);// 当天凌晨维护的是昨天的数据，故月度统计是昨天所在月度
			// 维护月度之前尝试删除可能未删除的月度维护日志，便于月度维护开展
			// 月度统计定时维护触发时间晚于每日中间数据维护，需要维护好月度统计日志
			dao.executeUpdate("delete from WXJY_MID_D_M_STATUS where STAT_PERIOD = ?", dataPeriod);

			Date monthStatBegin = statBegin;// 随意初始化为昨日0点
			try {
				monthStatBegin = monthSdf.parse(dataPeriod);// 昨日所在月份1日0点
			} catch (ParseException e) {
				e.printStackTrace();
			}
			monthlyDataMaintance(dataPeriod, monthStatBegin, statEnd);
			// 维护完当月月度统计临时数值后删除维护日志，便于月度统计定时维护持续工作，每月初月度定时任务重新执行一次不碍事
			dao.executeUpdate("delete from WXJY_MID_D_M_STATUS where STAT_PERIOD = ?", dataPeriod);

		}
	}

	public void ythDeclMain(Date statBegin, Date statEnd, List<String> code, List<String> allCode) {
		Map<String, Object[]> tmpMap1 = new HashMap<String, Object[]>();
		Map<String, Date[]> tmpMap2 = new HashMap<String, Date[]>();
		Map<String, Date> tmpMap9 = new HashMap<String, Date>();
		Map<String, Object[]> tmpMap10 = new HashMap<String, Object[]>();
		Map<String, Object[]> tmpMap11 = new HashMap<String, Object[]>();
		Map<String, Date> tmpMap12 = new HashMap<String, Date>();
		if (code != null && code.size() > 0) {
			List<String> entryH2018IdList = new ArrayList<>();//存放所有
			StringBuilder codeSb = new StringBuilder();
			int j = 1;
			for (Iterator itera = code.iterator(); itera.hasNext(); ) {
				String ciqCode = (String) itera.next();

				codeSb.append("'").append(ciqCode).append("',");
				if ((j % 600 == 0 || !itera.hasNext()) && codeSb.length() > 0) {
					codeSb.deleteCharAt(codeSb.length() - 1);
					String codes = codeSb.toString();
					//存在后续查出的报关单前面已经有，所以需要处理去重
					//出口按编码、ungid不为空和货物属性包含31或32
					//进口按ungid不为空或货物属性包含31或32
					String sql = "select distinct(d.ENTRY_ID) from ENTRY_HEAD d, ENTRY_WORKFLOW w,ENTRY_LIST l where " +
							"d.ENTRY_ID like '47%' and (substr(d.EDI_REMARK,7,1)!='C' or substr(d.EDI_REMARK,15,1)!='1') " +
							"and (substr(d.EDI_REMARK,17,1) in ('a','c','d','e','f') " +
							"or substr(d.EDI_REMARK,17,1) = 'C' and substr(d.EDI_REMARK,8,1) = 'G' ) " +
							"and d.ENTRY_ID = w.ENTRY_ID and d.ENTRY_ID = l.ENTRY_ID and w.STEP_ID = '80000000' and w.CREATE_DATE >= ? and w.CREATE_DATE < ? " +
							"and ((d.I_E_FLAG = 'E' and (l.IQ_CODE in (" + codes + ") or l.UNGID is not null or l.PRODUCT_CHAR_CODE like '%31%' " +
							"or l.PRODUCT_CHAR_CODE like '%32%')) or (d.I_E_FLAG = 'I' and (l.UNGID is not null or l.PRODUCT_CHAR_CODE like '%31%' " +
							"or l.PRODUCT_CHAR_CODE like '%32%'))) order by d.ENTRY_ID;";
					List<String> entryIdList = (List<String>) h2018Dao.getQueryBySql(sql, statBegin, statEnd);
					entryH2018IdList.addAll(entryIdList);
					codeSb.delete(0, codeSb.length());
				}
				j++;
			}
			//用JDK1.8 Stream中对List进行去重：list.stream().distinct();
			entryH2018IdList = (List) entryH2018IdList.stream().distinct().collect(Collectors.toList());
			if (entryH2018IdList != null && entryH2018IdList.size() > 0) {
				StringBuilder sb = new StringBuilder();
				int i = 1;
				for (Iterator iterator = entryH2018IdList.iterator(); iterator.hasNext(); ) {
					String id = (String) iterator.next();

					sb.append("'").append(id).append("',");

					if ((i % 300 == 0 || !iterator.hasNext()) && sb.length() > 0) {
						List<String> impIdList2 = new ArrayList<String>();//20191210 进口水运（新舱单部分）、空运可以从新舱单系统MANIFEST_LIST_NEW查到精确I_E_DATE
						List<String> impIdList3 = new ArrayList<String>();//20211210 出口水运（新舱单部分）、空运可以从新舱单系统MANIFEST_MONITOR_NEW查到精确ARRIVAL_DATE
						Map<String, Object> map = new HashMap<String, Object>();
						sb.deleteCharAt(sb.length() - 1);
						String ids = sb.toString();
						String entryIds = sb.toString();
						String sql = "select h.ENTRY_ID, I_E_DATE, I_E_PORT, I_E_FLAG, TRAF_MODE, D_DATE, DECL_PORT, CONSIGN_SCC, CONSIGN_CODE, CONSIGN_NAME, FRN_I_E_COUNTRY,"
								+ " TRADE_MODE, nvl(GROSS_WT,0), nvl(NET_WT,0), substr(EDI_REMARK,11,1), substr(EDI_REMARK,41,1),nvl(count(c.ENTRY_ID),0),substr(EDI_REMARK,53,1) "
								+ "from ENTRY_HEAD h left join `g_whdb_zmqd`.h18c_ENTRY_CONTAINER c on h.ENTRY_ID = c.ENTRY_ID where h.ENTRY_ID in ("
								+ ids + ") group by h.ENTRY_ID, I_E_DATE, I_E_PORT, I_E_FLAG, TRAF_MODE, D_DATE, DECL_PORT, CONSIGN_SCC, CONSIGN_CODE, CONSIGN_NAME, FRN_I_E_COUNTRY," +
								"TRADE_MODE, nvl(GROSS_WT,0), nvl(NET_WT,0), substr(EDI_REMARK,11,1), substr(EDI_REMARK,41,1),substr(EDI_REMARK,53,1);";
						List<Object[]> list = (List<Object[]>) h2018Dao.getQueryBySql(sql);
						for (Object[] d : list) {
							String idH = (String) d[0];
							String iEFlag = (String) d[3];
							String traMode = (String) d[4];
							if ("I".equals(iEFlag)) {
								if ("2".equals(traMode) || "5".equals(traMode)) {
									impIdList2.add(idH);
								}
							} else {
								if ("2".equals(traMode) || "5".equals(traMode)) {
									impIdList3.add(idH);
								}
							}
							tmpMap1.put((String) d[0],
									new Object[]{(Date) d[1], (String) d[2], (String) d[3], (String) d[4], (Date) d[5], (String) d[6], (String) d[7], (String) d[8], (String) d[9], (String) d[10], (String) d[11],
											(BigDecimal) d[12], (BigDecimal) d[13], (String) d[14], (String) d[15], (BigInteger) d[16], (String) d[17]});
						}

						sql = "select h.ENTRY_ID,(select max(CREATE_DATE) from ENTRY_WORKFLOW a where STEP_ID='10000000' AND h.ENTRY_ID = a.ENTRY_ID) as authDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW a where STEP_ID='80000000' AND h.ENTRY_ID = a.ENTRY_ID) as releaseDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW b where STEP_ID='81000000' AND h.ENTRY_ID = b.ENTRY_ID) as preReleaseDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW c where STEP_ID='70000000' AND h.ENTRY_ID = c.ENTRY_ID) as certRlsDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW c where STEP_ID='82000000' AND h.ENTRY_ID = c.ENTRY_ID) as passDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW c where STEP_ID='30000000' AND h.ENTRY_ID = c.ENTRY_ID) as orderDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW b where STEP_ID='30000000' AND h.ENTRY_ID = b.ENTRY_ID AND PROC_RESULT like '%G%' and PROC_ER like '47%') as orderReceiveDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW c where STEP_ID='00200000' AND h.ENTRY_ID = c.ENTRY_ID) as compEleDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW b where STEP_ID='33000000' AND h.ENTRY_ID = b.ENTRY_ID AND PROC_RESULT like '%G%' and PROC_ER like '47%') as profVerifyDate, "
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW b where STEP_ID='00000000' AND h.ENTRY_ID = b.ENTRY_ID) as eleDeclDate, "
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW b where STEP_ID='26000000' AND h.ENTRY_ID = b.ENTRY_ID AND PROC_RESULT like '%M%') as assessStartDate, "
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW b where STEP_ID='26000000' AND h.ENTRY_ID = b.ENTRY_ID AND PROC_RESULT like '%G%') as assessEndDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW b where STEP_ID in ('10000000','10200000','20000000') AND h.ENTRY_ID = b.ENTRY_ID and substr(b.status_code,4,1) = 5 and b.proc_result like '%E%') as refundDate "
								+ "from ENTRY_HEAD h where h.ENTRY_ID in (" + ids
								+ ") group by ENTRY_ID;";
						list = (List<Object[]>) h2018Dao.getQueryBySql(sql);
						for (Object[] d : list) {
							tmpMap2.put((String) d[0], new Date[]{(Date) d[1], (Date) d[2], (Date) d[3], (Date) d[4], (Date) d[5], (Date) d[6], (Date) d[7], (Date) d[8], (Date) d[9],
									(Date) d[10], (Date) d[11], (Date) d[12], (Date) d[13]});
						}

						sql = "select h.ENTRY_ID,substr(h.CHECK_REQUEST_TOTAL,-1,1),h.CREATE_TIME,h.MAN_CHK_TIME_START,h.MAN_CHK_TIME_END,MAN_PROC_RESULT,MAN_PROC_IDEA,CHECK_CUSTOMS_CODE "
								+ "from CI_CHECK_MAN_WORK_HEAD h where h.CHECK_STATE = 'M' and h.MODIFY_TIME = "
								+ "(select max(d.MODIFY_TIME) from CI_CHECK_MAN_WORK_HEAD d where d.ID = h.ID) and h.ENTRY_ID in(" + ids + ") ;";
						list = (List<Object[]>) inspDao.getQueryBySql(sql);
						for (Object[] d : list) {
							tmpMap11.put((String) d[0], new Object[]{(String) d[1], (Date) d[2], (Date) d[3], (Date) d[4], (String) d[5], (String) d[6], (String) d[7]});
						}

						//货运量毛重、净重、货运值人民币、美元、集装箱数量GROUP_CONCAT方法放在此处当传一个报关单id并且没有随附单证时会报错，所以加上nvl()
						sql = "select h.ENTRY_ID,sum(nvl(l.RMB_PRICE,0)),sum(nvl(l.USD_PRICE,0)),h.AGENT_CODE,h.AGENT_NAME,h.NOTE_S,"
								+ "h.OWNER_CODE,h.OWNER_NAME,h.FRN_CONSIGN_CODE,h.FRN_CONSIGN_NAME from ENTRY_HEAD h left join ENTRY_LIST l on h.ENTRY_ID=l.ENTRY_ID "
								+ "where h.ENTRY_ID in("
								+ ids + ") group by h.ENTRY_ID,h.AGENT_CODE,h.AGENT_NAME,h.NOTE_S,h.OWNER_CODE,h.OWNER_NAME,h.FRN_CONSIGN_CODE,h.FRN_CONSIGN_NAME;";
						list = (List<Object[]>) h2018Dao.getQueryBySql(sql);
						for (Object[] d : list) {
							tmpMap10.put((String) d[0], new Object[]{(BigDecimal) d[1], (BigDecimal) d[2], (String) d[3], (String) d[4], (String) d[5], (String) d[6], (String) d[7]
									, (String) d[8], (String) d[9]});
						}
						if (impIdList2.size() > 0) {
							sb.delete(0, sb.length());
							for (String impId : impIdList2) {
								sb.append("'").append(impId).append("',");
							}
							sb.deleteCharAt(sb.length() - 1);
							ids = sb.toString();
							// 进口新舱单水运、空运的I_E_DATE精准值由MANIFEST_LIST_NEW的REAL_ARRIVE_DATE给定
							// 注意：提运单号会被重用，当天的也可能有不同报关单使用了相同的提运单号
							sql = "select a.ENTRY_ID, b.REAL_ARRIVE_DATE from ENTRY_HEAD a, `g_whdb_zmqd`.mft_MANIFEST_LIST_NEW b where a.ENTRY_ID in ("
									+ ids + ") and a.BILL_NO = b.BILL_NO and a.I_E_PORT = b.CUSTOMS_CODE and to_char(a.I_E_DATE,'yyyyMMdd') = to_char(b.REAL_ARRIVE_DATE,'yyyyMMdd')";

							list = (List<Object[]>) h2018Dao.getQueryBySql(sql);
							for (Object[] d : list) {
								String entryId = (String) d[0];
								tmpMap9.put(entryId, (Date) d[1]);
							}
							impIdList2.clear();
						}
						//出口舱单
						if (impIdList3.size() > 0) {
							sb.delete(0, sb.length());
							for (String impId : impIdList3) {
								sb.append("'").append(impId).append("',");
							}
							sb.deleteCharAt(sb.length() - 1);
							ids = sb.toString();
							// 出口新舱单水运、空运可能提前但航班晚到，无法用时间去精准定位哪一条会卸载很多次，精准值由MANIFEST_MONITOR_NEW的ARRIVAL_DATE给定
							// 注意：提运单号会被重用，当天的也可能有不同报关单使用了相同的提运单号,ARRIVAL_DATE为00:00:00的赋值12:00:00
							//20210508舱单只获取和武汉海关有关的数据进行时间赋值，所以a.I_E_PORT = b.CUSTOMS_CODE
							sql = "select a.ENTRY_ID, min(b.ARRIVAL_DATE) from ENTRY_HEAD a, `g_whdb_zmqd`.mft_MANIFEST_MONITOR_NEW b where a.ENTRY_ID in ("
									+ ids + ") and a.BILL_NO = b.BILL_NO and a.I_E_PORT = b.CUSTOMS_CODE group by a.ENTRY_ID";

							list = (List<Object[]>) h2018Dao.getQueryBySql(sql);
							for (Object[] d : list) {
								String entryId = (String) d[0];
								tmpMap12.put(entryId, (Date) d[1]);
							}
							impIdList3.clear();
						}
						for (Map.Entry<String, Object[]> d : tmpMap1.entrySet()) {
							String entryId = d.getKey();
							Object[] v = d.getValue();
							Date ieDate = (Date) v[0];// 货物运抵时间
							String iePort = (String) v[1];
							String ieFlag = (String) v[2];
							String trafMode = (String) v[3];
							Date declDate = (Date) v[4];// 申报时间
							String declPort = (String) v[5];// 申报口岸
							String consignScc = (String) v[6];
							String consignCode = (String) v[7];
							String consignName = (String) v[8];
							String tradeCountry = (String) v[9];
							String tradeMode = (String) v[10];
							BigDecimal grossWt = (BigDecimal) v[11];//毛重
							BigDecimal netWt = (BigDecimal) v[12];//净重
							String advanceDecl = (String) v[13];//判断是否是提前申报
							//两步申报都下发到了h2018所以使用00200000节点判断只属于两步申报其中一种类型，
							//应当使用edi_remark41位判断是否有值（edi_remark41值为1，2，3均为两步申报）
							String twoStep = (String) v[14];//判断是否是两步申报
							//2018存在twoStepValue截取出来值为' '情况，需要单独处理
							String twoStepDecl = (" ").equals(twoStep) ? "" : twoStep;
							BigInteger container = (BigInteger) v[15];// 集装箱数量
							String newTwoStep = (String) v[16];//判断是否是新两步申报

							Date[] all = tmpMap2.get(entryId);
							Date authDate = null;
							Date releaseDate = null;
							Date preReleaseDate = null;
							Date certRlsDate = null;
							Date passDate = null;
							Date orderDate = null;
							Date orderReceiveDate = null;
							Date compEleDate = null;
							Date profVerifyDate = null;
							Date eleDeclDate = null;
							Date assessStartDate = null;
							Date assessEndDate = null;
							Date refundDate = null;
							if (all != null) {
								authDate = all[0];// 10审单受理时间
								releaseDate = all[1];// 80结关时间
								preReleaseDate = all[2];// 81担保放行时间
								certRlsDate = all[3];// 70单证放行时间
								passDate = all[4];// 82000000通道验放
								orderDate = all[5];// 30000000现场接单
								orderReceiveDate = all[6];// 30现场接单时间
								compEleDate = all[7];// 00200000完整申报电子申报时间
								profVerifyDate = all[8];// 33专业审证单核时间
								eleDeclDate = all[9];// 00电子申报时间
								assessStartDate = all[10];// 26排查处置/现场验估时间
								assessEndDate = all[11];// 26验估处置完毕时间
								refundDate = all[12];// 退单时间
							}

							Date realArriveDate = tmpMap9.get(entryId);
							Object[] obj = tmpMap10.get(entryId);
							BigDecimal rmbPrice = zero;
							BigDecimal usdPrice = zero;
							String agentCode = null;
							String agentName = null;
							String noteS = null;
							String ownerCode = null;
							String ownerName = null;
							String frnConsignCode = null;
							String frnConsignName = null;
							if (obj != null) {
								rmbPrice = (BigDecimal) obj[0];//人民币
								usdPrice = (BigDecimal) obj[1];//美元
								agentCode = (String) obj[2];//申报单位代码
								agentName = (String) obj[3];//申报单位名称
								noteS = (String) obj[4];//备注
								ownerCode = (String) obj[5];//生产销售单位代码
								ownerName = (String) obj[6];//生产销售单位名称
								frnConsignCode = (String) obj[7];//生产销售单位代码
								frnConsignName = (String) obj[8];//生产销售单位名称
							}

							Object[] man = tmpMap11.get(entryId);
							String checkFlag = null;
							Date manCreateTime = null;
							Date manChkTimeStart = null;
							Date manChkTimeEnd = null;
							String manProcResult = null;
							String manProcIdea = null;
							String checkCustomsCode = null;
							if (man != null) {
								checkFlag = (String) man[0];//是否查验送检
								manCreateTime = (Date) man[1];//指令下达时间
								manChkTimeStart = (Date) man[2];//查验开始时间
								manChkTimeEnd = (Date) man[3];//查验结束时间
								manProcResult = (String) man[4];//处理结果
								manProcIdea = (String) man[5];//处理意见
								checkCustomsCode = (String) man[6];//查验关区
							}

							if ("I".equals(ieFlag)) {
								if (realArriveDate != null) {
									ieDate = realArriveDate;
								} else {
									if (ieDate != null) {
										// 由于报关单表中I_E_DATE精度不够，需要做(非精准)修正（用户给的建议应该是错的，模糊处理下好了，时分为0的设置为12点）
										if ("I".equals(ieFlag)) {// 入境
											String ieDateStr = fullSdf.format(ieDate);
											if (ieDateStr.endsWith("00:00:00")) {
												ieDateStr = ieDateStr.substring(0, 11) + IE_DATE_ADAPT;
												try {
													ieDate = fullSdf.parse(ieDateStr);
												} catch (ParseException e1) {
													// TODO Auto-generated catch block
													e1.printStackTrace();
												}
											}
										}
									}
								}
							} else {
								realArriveDate = tmpMap12.get(entryId);
								//ARRIVAL_DATE为00:00:00时赋值12:00:00
								if (realArriveDate != null) {
									String ieDateStr = fullSdf.format(realArriveDate);
									if (ieDateStr.endsWith("00:00:00")) {
										ieDateStr = ieDateStr.substring(0, 11) + IE_DATE_ADAPT;
										try {
											realArriveDate = fullSdf.parse(ieDateStr);
										} catch (ParseException e1) {
											// TODO Auto-generated catch block
											e1.printStackTrace();
										}
									}
								}
							}

							EntryHead e = new EntryHead();
							e.setEntryId(entryId);
							e.setAcceptDate(authDate != null ? authDate : orderDate);
							e.setCertRlsDate(certRlsDate);// 70单证放行时间
							e.setReleaseDate(releaseDate);//80
							e.setPreReleaseDate(preReleaseDate);// 81时间
							e.setPassMode("1");// 一体化通关
							e.setDeclPort(declPort);
							e.setCustomsCode(rootCustomsMap.get(declPort));
							e.setIePort(iePort);
							e.setIeDate(ieDate);
							e.setDeclDate(declDate);
							e.setIeFlag(ieFlag);
							e.setTrafMode(trafMode);
							e.setConsignScc(consignScc);
							e.setConsignCode(consignCode);
							e.setConsignName(consignName);
							e.setTradeCountry(tradeCountry);
							e.setTradeMode(tradeMode);
							e.setOrderReceiveDate(orderReceiveDate);//30接单时间
							e.setCompEleDate(compEleDate);// 00200000完整申报电子申报时间
							e.setProfVerifyFlag(profVerifyDate != null ? "1" : "0");
							e.setNewTwoStepFlag((null != newTwoStep && !"".equals(newTwoStep) && newTwoStep.equals("1")) ? "1" : "0");
							e.setEleDeclDate(eleDeclDate);
							e.setAssessStartDate(assessStartDate);
							e.setAssessEndDate(assessEndDate);
							e.setRefundDate(refundDate);
							e.setRefundFlag(refundDate != null ? "1" : "0");
							e.setCheckFlag(manCreateTime != null ? "1" : "0");
							long orderReceiveCost = 0L;//接单耗时：30000000-10000000
							//20210423新增处理10节点无时间时的赋值，避免程序报错
							if (orderReceiveDate != null && (authDate != null || orderDate != null)) {
								Long time = authDate != null ? authDate.getTime() : orderDate.getTime();
								orderReceiveCost = (orderReceiveDate.getTime() - time) / 1000;
								e.setOrderReceiveCost(orderReceiveCost);
							} else {
								e.setOrderReceiveCost(null);
							}

							long hgCost = 0L;
							long totalCost = 0L;
							//edi_remark11位为T表示提前申报
							if ("T".equals(advanceDecl)) {
								e.setDeclAdvanceFlag("1");
							} else {
								e.setDeclAdvanceFlag("0");
							}
							if ("I".equals(ieFlag)) {// 入境
								/**根据综合处杨科提出的修改意见，这里将原来'电脑审单时间早于货物运抵时间'改成'申报时间早于货物运抵时间'的为提前申报*/
							/*if (authDate.before(ieDate)) {
								authDate = ieDate;
								e.setDeclAdvanceFlag("1");
							}*/
								if (ieDate != null) {
									if (declDate.before(ieDate)) {
										authDate = ieDate;
										//								e.setDeclAdvanceFlag("1");
									} else {
										//20210423新增处理10节点无时间时的赋值，避免程序报错
										if (authDate == null) {
											authDate = orderDate;
										}
									}
								}
								if (e.getPreReleaseDate() == null && e.getReleaseDate() != null) {
									if (authDate != null) {
										hgCost = (e.getReleaseDate().getTime() - authDate.getTime()) / 1000;
									}
									if (ieDate != null) {
										totalCost = (e.getReleaseDate().getTime() - ieDate.getTime()) / 1000;
									}
								} else if (e.getPreReleaseDate() != null) {
									if (authDate != null) {
										hgCost = (e.getPreReleaseDate().getTime() - authDate.getTime()) / 1000;
									}
									if (ieDate != null) {
										totalCost = (e.getPreReleaseDate().getTime() - ieDate.getTime()) / 1000;
									}
								}
								if (hgCost < 0) {
									hgCost = 0L;
								}
								if (totalCost < 0) {
									totalCost = hgCost;
								}
								//新组合查询用00-货物运抵，组合查询用10-货物运抵
								e.setBeforeDeclCost((eleDeclDate.getTime() - e.getIeDate().getTime()) / 1000);// 申报前准备时间
								if (e.getBeforeDeclCost() < 0) {
									e.setBeforeDeclCost(0L);
								}
							} else {// 出境 海关通关时间=70/81之间较早的时间-受理时间
								// 20191211 出口口岸清关、一体化：公路取BINDING_ROAD_TRANSPORT表GEN_DATE；铁路、邮路运输的整体通关时长=海关通关时长
								//20210423新增处理10节点无时间时的赋值，避免程序报错
								if (authDate == null) {
									authDate = orderDate;
								}
								if (realArriveDate != null) {
									//20211209出口舱单有时间赋值给出口货物运抵时间否则使用10审单时间，同时进行计算
									e.setExInPortDate(realArriveDate);
								} else {
									// 取不到数据的统一将货物入境时间设置为受理时间
									if ("3".equals(trafMode) || "6".equals(trafMode) || "9".equals(trafMode)) {// 其它运输方式也假设归为一类
										e.setExInPortDate(authDate);
									} else if ("4".equals(trafMode)) {//TODO 公路：暂时取不到数据
										e.setExInPortDate(authDate);
									} else {
										e.setExInPortDate(authDate);// TODO 出口水运、空运通关时长第一个时间点数据来源还未下发，先临时赋值
									}
								}

								if (e.getCertRlsDate() == null) {
									if (e.getPreReleaseDate() != null) {
										if (authDate != null) {
											hgCost = (e.getPreReleaseDate().getTime() - authDate.getTime()) / 1000;
										}
										totalCost = e.getExInPortDate() != null
												? ((e.getPreReleaseDate().getTime() - e.getExInPortDate().getTime()) / 1000)
												: hgCost;
									}

								} else {
									if (e.getPreReleaseDate() != null) {
										if (e.getCertRlsDate().before(e.getPreReleaseDate())) {
											if (authDate != null) {
												hgCost = (e.getCertRlsDate().getTime() - authDate.getTime()) / 1000;
											}
											totalCost = e.getExInPortDate() != null
													? ((e.getCertRlsDate().getTime() - e.getExInPortDate().getTime()) / 1000)
													: hgCost;
										} else {
											if (authDate != null) {
												hgCost = (e.getPreReleaseDate().getTime() - authDate.getTime()) / 1000;
											}
											totalCost = e.getExInPortDate() != null
													? ((e.getPreReleaseDate().getTime() - e.getExInPortDate().getTime()) / 1000)
													: hgCost;
										}

									} else {
										if (authDate != null) {
											hgCost = (e.getCertRlsDate().getTime() - authDate.getTime()) / 1000;
										}
										totalCost = e.getExInPortDate() != null
												? ((e.getCertRlsDate().getTime() - e.getExInPortDate().getTime()) / 1000)
												: hgCost;
									}
								}
								e.setBeforeDeclCost(e.getExInPortDate() != null
										? ((eleDeclDate.getTime() - e.getExInPortDate().getTime()) / 1000)
										: 0L);// 申报前准备时间
								if (e.getBeforeDeclCost() < 0) {
									e.setBeforeDeclCost(0L);
								}
							}

							e.setMainStatus("1");
							e.setCuCost(hgCost);// 海关通关时间(秒)
							e.setTotalCost(totalCost);// 总体通关时间
							e.setGrossWt(grossWt);//净重
							e.setNetWt(netWt);//毛重
							e.setRmbPrice(rmbPrice);//人民币
							e.setUsdPrice(usdPrice);//美元
							e.setContainer(container);//集装箱数量
							e.setAgentCode(agentCode);//申报单位代码
							e.setAgentName(agentName);//申报单位名称
							e.setNoteS(noteS);//备注
							e.setOwnerCode(ownerCode);//生产销售单位代码
							e.setOwnerName(ownerName);//生产销售单位名称
							e.setFrnConsignCode(frnConsignCode);
							e.setFrnConsignName(frnConsignName);
							//报关模式
							String mode = null;
							//部分订单既是提前申报又是两步申报,不是两步和提前申报的单子均为一般申报,twoStepDecl:0或者空格:代表一分模式
							if ("1".equals(e.getDeclAdvanceFlag()) && (null == twoStepDecl || "".equals(twoStepDecl) || "0".equals(twoStepDecl))) {
								mode = "3";
							} else if ("1".equals(e.getDeclAdvanceFlag()) && (null != twoStepDecl && "".equals(twoStepDecl)) && !"0".equals(twoStepDecl)) {
								mode = "2,3";
							} else if ((null != twoStepDecl && "".equals(twoStepDecl)) && !"0".equals(twoStepDecl)) {
								mode = "2";
							} else {
								mode = "1";
							}
							e.setDeclMode(mode);//报关模式
							//70000000、80000000、81000000、82000000均为空则表示未放行
							if (preReleaseDate == null && certRlsDate == null && releaseDate == null && passDate == null) {
								e.setDeclStatus("1");
							} else if (releaseDate != null) {
								//80表示已结关
								e.setDeclStatus("3");
							} else {
								e.setDeclStatus("2");
							}

							e.setManCreateTime(manCreateTime);//指令下达时间
							e.setManChkTimeStart(manChkTimeStart);//查验开始时间
							e.setManChkTimeEnd(manChkTimeEnd);//查验结束时间
							e.setManProcResult(manProcResult);
							e.setManProcIdea(manProcIdea);
							e.setCheckCustomsCode(rootCustomsMap.get(checkCustomsCode));
							dao.executeUpdate("delete from WXJY_ENTRY_HEAD where ENTRY_ID = ?", entryId);
							entryHeadRepository.save(e);
						}
						//ciqCode存在超过600个情况,每个报关单每次查都拼接重复工作太多，所以提出来
						//先删除这些报关单下的所有商品信息
						dao.executeUpdate("delete from WXJY_ENTRY_LIST where ENTRY_ID in (" + entryIds + ")");
						try {
							StringBuilder codeListSb = new StringBuilder();
							int x = 1;
							for (Iterator it = allCode.iterator(); it.hasNext(); ) {
								String iqCode = (String) it.next();

								codeListSb.append("'").append(iqCode).append("',");
								if ((x % 600 == 0 || !it.hasNext()) && codeListSb.length() > 0) {
									codeListSb.deleteCharAt(codeListSb.length() - 1);
									String iqCodes = codeListSb.toString();
									//报关单表体,报关单第九位0=出口1=进口
									sql = "select ENTRY_ID,G_NO,CODE_TS,G_NAME,QTY_1,RMB_PRICE,USD_PRICE,G_MODEL,G_CERT_FLAG," +
											"(select max(a.CREATE_DATE) from ENTRY_WORKFLOW a where a.STEP_ID='80000000' AND l.ENTRY_ID = a.ENTRY_ID) as RELEASE_DATE," +
											"UNGID,UNG_FLAG,UNG_MODEL,UNG_CLASSIFY,UNG_G_NAME,PRODUCT_CHAR_CODE,IQ_CODE " +
											"from ENTRY_LIST l where l.ENTRY_ID in (" + entryIds + ") " +
											"and ((substr(l.ENTRY_ID,9,1) ='0' and (l.IQ_CODE in (" + iqCodes + ") or l.UNGID is not null " +
											"or l.PRODUCT_CHAR_CODE like '%31%' or l.PRODUCT_CHAR_CODE like '%32%')) or " +
											"(substr(l.ENTRY_ID,9,1) = '1' and (l.UNGID is not null or l.PRODUCT_CHAR_CODE like '%31%' or l.PRODUCT_CHAR_CODE like '%32%')));";
									List<Object[]> codeTsList = (List<Object[]>) h2018Dao.getQueryBySql(sql);
									if (null != codeTsList && codeTsList.size() > 0) {
										//由于新组合查询不设定某个固定节点更新数据，会存在相同报关单在后面更新流程节点时间，所以先从中间表查出数据进行更新
										//会存在商品金额为空的情况，如果只有一条商品并商品为空则报关单头要删除
										EntryList entity = null;
										for (Object[] codeTs : codeTsList) {//将根据报关单编号查询到的商品编号及报关单号添加到KPI_ENTRY_HEAD_NEW_COPY表里
											entity = new EntryList();
											entity.setEntryId(codeTs[0] != null ? codeTs[0].toString() : "");
											entity.setGNo(codeTs[1] != null ? (BigDecimal) codeTs[1] : new BigDecimal(0));
											entity.setCodeTs(codeTs[2] != null ? codeTs[2].toString() : "");
											entity.setGName(codeTs[3] != null ? codeTs[3].toString() : "");
											entity.setQty1(codeTs[4] != null ? (BigDecimal) codeTs[4] : new BigDecimal(0));
											entity.setRmbPrice(codeTs[5] != null ? (BigDecimal) codeTs[5] : new BigDecimal(0));
											entity.setUsdPrice(codeTs[6] != null ? (BigDecimal) codeTs[6] : new BigDecimal(0));
											entity.setGModel(codeTs[7] != null ? codeTs[7].toString() : "");
											entity.setGCertFlag(codeTs[8] != null ? codeTs[8].toString() : "");
											entity.setReleaseDate(codeTs[9] != null ? (Date) codeTs[9] : null);
											entity.setCodeTsShort(codeTs[2] != null ? codeTs[2].toString().substring(0, 6) : "");
											entity.setUngid(codeTs[10] != null ? codeTs[10].toString() : "");
											entity.setUngFlag(codeTs[11] != null ? codeTs[11].toString() : "");
											entity.setUngModel(codeTs[12] != null ? codeTs[12].toString() : "");
											entity.setUngClassify(codeTs[13] != null ? codeTs[13].toString() : "");
											entity.setUngGName(codeTs[14] != null ? codeTs[14].toString() : "");
											entity.setIqCode(codeTs[16] != null ? codeTs[16].toString() : "");
											//货物属性，判断货物属性是否是31/散装危险化学品，32/件装危险化学品
											String goods_attr = "";
											if (codeTs[15] != null) {
												goods_attr = (String) codeTs[15];
												if (goods_attr.contains("31")) {
													goods_attr = "31";
												} else if (goods_attr.contains("32")) {
													goods_attr = "32";
												} else {
													goods_attr = "";
												}
											}
											entity.setProductCharCode(goods_attr);
											//查出的数据可能存在ciqCode或者UNGID为空的情况,报关单第九位0=出口1=进口
											//出口按ciq编码、ungid不为空和货物属性包含31或32
											//进口按ungid不为空或货物属性
											String ieFlag = codeTs[0] != null ? codeTs[0].toString().substring(8, 9) : "";
											//货物属性为不空时可以初步判定该商品是危化品，接下来只需判断该商品是否还包含危险货物的属性
											if (entity.getProductCharCode() != null && !"".equals(entity.getProductCharCode())) {
												if (codeTs[10] != null) {
													entity.setGoodsType("1,2,3");
												} else {
													entity.setGoodsType("1");
												}
											} else {
												//货物属性为空时
												//出口
												if (ieFlag.equals("0")) {
													if (codeTs[16] != null) {
														//syncChemicalsCiq只可能是包含了危化品,因为这个表的数据就是查询的系统中危险品模块里用户已经维护的包含了危化品的数据
														Object[] obj = (Object[]) iedgRepository.getObjectBySql("select * from iedg_sync_chemicals_ciq where CIQ_CODE = ?", (String) codeTs[16]);
														if (obj != null) {
															if (codeTs[16] != null) {
																entity.setGoodsType("1,2,3");
															} else {
																entity.setGoodsType("1");
															}
														} else {
															entity.setGoodsType("2");
														}
													} else {
														entity.setGoodsType("2");
													}
												} else {
													//进口
													entity.setGoodsType("2");
												}
											}
											entity.setId(dao.getGuidStringBySql());
											entryListRepository.save(entity);
										}
									}
									codeListSb.delete(0, codeListSb.length());
								}
								x++;
							}
						} catch (Exception ex) {
							// 主键可能因为多次结关跨天，导致新纪录主键重复
							logger.error("保存危险品新维度一体化通关中间记录失败，重新保存");
							dao.executeUpdate("delete from WXJY_ENTRY_LIST where ENTRY_ID in (" + entryIds + ")");
						}
						tmpMap1.clear();
						tmpMap2.clear();
						tmpMap9.clear();
						tmpMap10.clear();
						tmpMap12.clear();
						tmpMap11.clear();
						sb.delete(0, sb.length());
					}
					i++;
				}
			}
		}
	}

	public void zgDeclMain(Date statBegin, Date statEnd, List<String> code, List<String> allCode) {
		Map<String, Object[]> tmpMap1 = new HashMap<String, Object[]>();
		Map<String, Date[]> tmpMap2 = new HashMap<String, Date[]>();
		Map<String, Date[]> tmpMap5 = new HashMap<String, Date[]>();//转关
		Map<String, Date> tmpMap9 = new HashMap<String, Date>();
		Map<String, Object[]> tmpMap10 = new HashMap<String, Object[]>();
		Map<String, Object[]> tmpMap11 = new HashMap<String, Object[]>();
		Map<String, Date> tmpMap12 = new HashMap<String, Date>();
		if (code != null && code.size() > 0) {
			List<String> entryH2018IdList = new ArrayList<>();//存放所有
			StringBuilder codeSb = new StringBuilder();
			int j = 1;
			for (Iterator itera = code.iterator(); itera.hasNext(); ) {
				String ciqCode = (String) itera.next();

				codeSb.append("'").append(ciqCode).append("',");
				if ((j % 600 == 0 || !itera.hasNext()) && codeSb.length() > 0) {
					codeSb.deleteCharAt(codeSb.length() - 1);
					String codes = codeSb.toString();
					//存在后续查出的报关单前面已经有，所以需要处理去重
					//出口按编码、ungid不为空和货物属性包含31或32
					//进口按ungid不为空或货物属性包含31或32
					String sql = "select distinct(d.ENTRY_ID) from ENTRY_HEAD d, ENTRY_WORKFLOW w, ENTRY_LIST l where " +
							"d.ENTRY_ID like '47%' and (substr(d.EDI_REMARK,7,1)!='C' or substr(d.EDI_REMARK,15,1)!='1') " +
							"and (substr(d.EDI_REMARK,17,1) not in ('a','c','C','d','e','f') " +
							"or (substr(d.EDI_REMARK,17,1) = 'C' and substr(d.EDI_REMARK,8,1) != 'G')) and substr(d.I_E_PORT,0,2)!=substr(d.DECL_PORT,0,2) " +
							"and d.ENTRY_ID = w.ENTRY_ID and d.ENTRY_ID = l.ENTRY_ID and w.STEP_ID = '80000000' and w.CREATE_DATE >= ? and w.CREATE_DATE < ? " +
							"and ((d.I_E_FLAG = 'E' and (l.IQ_CODE in (" + codes + ") or l.UNGID is not null or l.PRODUCT_CHAR_CODE like '%31%' " +
							"or l.PRODUCT_CHAR_CODE like '%32%')) or (d.I_E_FLAG = 'I' and (l.UNGID is not null or l.PRODUCT_CHAR_CODE like '%31%' " +
							"or l.PRODUCT_CHAR_CODE like '%32%'))) order by d.ENTRY_ID;";
					List<String> entryIdList = (List<String>) h2018Dao.getQueryBySql(sql, statBegin, statEnd);
					entryH2018IdList.addAll(entryIdList);
					codeSb.delete(0, codeSb.length());
				}
				j++;
			}
			//用JDK1.8 Stream中对List进行去重：list.stream().distinct();
			entryH2018IdList = (List) entryH2018IdList.stream().distinct().collect(Collectors.toList());
			if (entryH2018IdList != null && entryH2018IdList.size() > 0) {
				StringBuilder sb = new StringBuilder();
				int i = 1;
				for (Iterator iterator = entryH2018IdList.iterator(); iterator.hasNext(); ) {
					String id = (String) iterator.next();

					sb.append("'").append(id).append("',");

					if ((i % 300 == 0 || !iterator.hasNext()) && sb.length() > 0) {
						List<String> impIdList = new ArrayList<String>();
						List<String> impIdList2 = new ArrayList<String>();//20191210 进口水运（新舱单部分）、空运可以从新舱单系统MANIFEST_LIST_NEW查到精确I_E_DATE
						List<String> impIdList3 = new ArrayList<String>();//20211210 出口水运（新舱单部分）、空运可以从新舱单系统MANIFEST_MONITOR_NEW查到精确ARRIVAL_DATE
						Map<String, Object> map = new HashMap<String, Object>();
						sb.deleteCharAt(sb.length() - 1);
						String ids = sb.toString();
						String entryIds = sb.toString();
						String sql = "select h.ENTRY_ID, I_E_DATE, I_E_PORT, I_E_FLAG, TRAF_MODE, D_DATE, DECL_PORT,CONSIGN_SCC, CONSIGN_CODE, CONSIGN_NAME, FRN_I_E_COUNTRY,"
								+ " TRADE_MODE, nvl(GROSS_WT,0), nvl(NET_WT,0), substr(EDI_REMARK,11,1), substr(EDI_REMARK,41,1),nvl(count(c.ENTRY_ID),0),substr(EDI_REMARK,53,1) "
								+ "from ENTRY_HEAD h left join `g_whdb_zmqd`.h18c_ENTRY_CONTAINER c on h.ENTRY_ID = c.ENTRY_ID where h.ENTRY_ID in ("
								+ ids + ")  group by h.ENTRY_ID, I_E_DATE, I_E_PORT, I_E_FLAG, TRAF_MODE, D_DATE, DECL_PORT, CONSIGN_SCC, CONSIGN_CODE, CONSIGN_NAME, FRN_I_E_COUNTRY," +
								"TRADE_MODE, nvl(GROSS_WT,0), nvl(NET_WT,0), substr(EDI_REMARK,11,1), substr(EDI_REMARK,41,1),substr(EDI_REMARK,53,1);";
						List<Object[]> list = (List<Object[]>) h2018Dao.getQueryBySql(sql);
						for (Object[] d : list) {
							String idH = (String) d[0];
							String iEFlag = (String) d[3];
							String traMode = (String) d[4];
							if ("I".equals(iEFlag)) {
								impIdList.add(idH);
								if ("2".equals(traMode) || "5".equals(traMode)) {
									impIdList2.add(idH);
								}
							} else {
								if ("2".equals(traMode) || "5".equals(traMode)) {
									impIdList3.add(idH);
								}
							}
							tmpMap1.put((String) d[0],
									new Object[]{(Date) d[1], (String) d[2], (String) d[3], (String) d[4], (Date) d[5], (String) d[6], (String) d[7], (String) d[8], (String) d[9], (String) d[10], (String) d[11],
											(BigDecimal) d[12], (BigDecimal) d[13], (String) d[14], (String) d[15], (BigInteger) d[16], (String) d[17]});
						}

						sql = "select h.ENTRY_ID,(select max(CREATE_DATE) from ENTRY_WORKFLOW a where STEP_ID='10000000' AND h.ENTRY_ID = a.ENTRY_ID) as authDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW a where STEP_ID='80000000' AND h.ENTRY_ID = a.ENTRY_ID) as releaseDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW b where STEP_ID='81000000' AND h.ENTRY_ID = b.ENTRY_ID) as preReleaseDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW c where STEP_ID='70000000' AND h.ENTRY_ID = c.ENTRY_ID) as certRlsDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW c where STEP_ID='82000000' AND h.ENTRY_ID = c.ENTRY_ID) as passDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW c where STEP_ID='30000000' AND h.ENTRY_ID = c.ENTRY_ID) as orderDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW b where STEP_ID='30000000' AND h.ENTRY_ID = b.ENTRY_ID AND PROC_RESULT like '%G%' and PROC_ER like '47%') as orderReceiveDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW c where STEP_ID='00200000' AND h.ENTRY_ID = c.ENTRY_ID) as compEleDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW b where STEP_ID='33000000' AND h.ENTRY_ID = b.ENTRY_ID AND PROC_RESULT like '%G%' and PROC_ER like '47%') as profVerifyDate, "
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW b where STEP_ID='00000000' AND h.ENTRY_ID = b.ENTRY_ID) as eleDeclDate, "
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW b where STEP_ID='26000000' AND h.ENTRY_ID = b.ENTRY_ID AND PROC_RESULT like '%M%') as assessStartDate, "
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW b where STEP_ID='26000000' AND h.ENTRY_ID = b.ENTRY_ID AND PROC_RESULT like '%G%') as assessEndDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW b where STEP_ID in ('10000000','10200000','20000000') AND h.ENTRY_ID = b.ENTRY_ID and substr(b.status_code,4,1) = 5 and b.proc_result like '%E%') as refundDate "
								+ "from ENTRY_HEAD h where h.ENTRY_ID in (" + ids
								+ ") group by ENTRY_ID;";
						list = (List<Object[]>) h2018Dao.getQueryBySql(sql);
						for (Object[] d : list) {
							tmpMap2.put((String) d[0], new Date[]{(Date) d[1], (Date) d[2], (Date) d[3], (Date) d[4], (Date) d[5], (Date) d[6], (Date) d[7], (Date) d[8], (Date) d[9],
									(Date) d[10], (Date) d[11], (Date) d[12], (Date) d[13]});
						}

						sql = "select h.ENTRY_ID,substr(h.CHECK_REQUEST_TOTAL,-1,1),h.CREATE_TIME,h.MAN_CHK_TIME_START,h.MAN_CHK_TIME_END,MAN_PROC_RESULT,MAN_PROC_IDEA,CHECK_CUSTOMS_CODE "
								+ "from CI_CHECK_MAN_WORK_HEAD h where h.CHECK_STATE = 'M' and h.MODIFY_TIME = "
								+ "(select max(d.MODIFY_TIME) from CI_CHECK_MAN_WORK_HEAD d where d.ID = h.ID) and h.ENTRY_ID in(" + ids + ") ;";
						list = (List<Object[]>) inspDao.getQueryBySql(sql);
						for (Object[] d : list) {
							tmpMap11.put((String) d[0], new Object[]{(String) d[1], (Date) d[2], (Date) d[3], (Date) d[4], (String) d[5], (String) d[6], (String) d[7]});
						}

						//货运量毛重、净重、货运值人民币、美元、集装箱数量GROUP_CONCAT方法放在此处当传一个报关单id并且没有随附单证时会报错，所以加上nvl()
						sql = "select h.ENTRY_ID,sum(nvl(l.RMB_PRICE,0)),sum(nvl(l.USD_PRICE,0)),h.AGENT_CODE,h.AGENT_NAME,h.NOTE_S,"
								+ "h.OWNER_CODE,h.OWNER_NAME,FRN_CONSIGN_CODE,FRN_CONSIGN_NAME from ENTRY_HEAD h left join ENTRY_LIST l on h.ENTRY_ID=l.ENTRY_ID "
								+ "where h.ENTRY_ID in("
								+ ids + ") group by h.ENTRY_ID,h.AGENT_CODE,h.AGENT_NAME,h.NOTE_S,h.OWNER_CODE,h.OWNER_NAME,FRN_CONSIGN_CODE,FRN_CONSIGN_NAME;";
						list = (List<Object[]>) h2018Dao.getQueryBySql(sql);
						for (Object[] d : list) {
							tmpMap10.put((String) d[0], new Object[]{(BigDecimal) d[1], (BigDecimal) d[2], (String) d[3], (String) d[4], (String) d[5], (String) d[6], (String) d[7]
									, (String) d[8], (String) d[9]});
						}
						if (impIdList.size() > 0) {
							sb.delete(0, sb.length());
							for (String impId : impIdList) {
								sb.append("'").append(impId).append("',");
							}
							sb.deleteCharAt(sb.length() - 1);
							ids = sb.toString();
							// 部分转关类型的报关单需要通过新舱单系统拿到转关数据发送时间和转关数据核销时间
							sql = "select a.ENTRY_ID, b.EXAM_TIME, b.CHECK_TIME from ENTRY_HEAD a, `g_whdb_rh2k`.rh2k_IM_DECL_CUR_HEAD b, " +
									"`g_whdb_zmqd`.mft_MANIFEST_CHK_NEW c where a.ENTRY_ID in ("
									+ ids + ") and (a.ENTRY_ID = c.FORM_ID and c.MANIFEST_ID = b.PRE_NO)";

							list = (List<Object[]>) h2018Dao.getQueryBySql(sql);
							for (Object[] d : list) {
								String entryId = (String) d[0];
								tmpMap5.put(entryId, new Date[]{(Date) d[1], (Date) d[2]});
								impIdList.remove(entryId);
							}
							// 从新舱单关联之后，剩下的再从提运单/转关单关联表查询两个时间值
							sb.delete(0, sb.length());
							for (String entryId : impIdList) {
								sb.append("'").append(entryId).append("',");
							}
							if (sb.length() > 0) {
								List<String> tmpIdList = new ArrayList<String>(impIdList);
								sb.deleteCharAt(sb.length() - 1);
								ids = sb.toString();
								// 2019-11-07 入境报关单整体通关时间第一个时间点计算规则变更，水运和空运取报关单和提运单表中I_E_DATE时分秒不为0的，若都为0，则设置为12点；新舱单中I_E_DATE时分秒基本都为0，故不考虑。
								// 公路的取 “进出境承运已确报”（物流监控工作流信息表）
								// 经过数据分析，放弃上面方案，改为若I_E_DATE时分为0的改为12点

								// 只考虑入境报关单的转关数据：可能查到多余报关单量的数据
								sql = "select a.ENTRY_ID, b.EXAM_TIME, b.CHECK_TIME from ENTRY_HEAD a,`g_whdb_rh2k`.rh2k_IM_DECL_CUR_HEAD b," +
										"`g_whdb_rh2k`.rh2k_IM_TRANS_LIST_REL c where a.ENTRY_ID in ("
										+ ids + ") and (a.ENTRY_ID = c.ENTRY_NO and c.PRE_NO = b.PRE_NO)";

								list = (List<Object[]>) h2018Dao.getQueryBySql(sql);
								for (Object[] d : list) {
									String entryId = (String) d[0];
									tmpMap5.put(entryId, new Date[]{(Date) d[1], (Date) d[2]});
									tmpIdList.remove(entryId);
								}
								sb.delete(0, sb.length());
								for (String entryId : tmpIdList) {
									sb.append("'").append(entryId).append("',");
								}
								if (sb.length() > 0) {
									sb.deleteCharAt(sb.length() - 1);
									ids = sb.toString();
									sql = "select a.ENTRY_ID, b.EXAM_TIME, b.CHECK_TIME from ENTRY_HEAD a,`g_whdb_rh2k`.rh2k_IM_DECL_CUR_HEAD b," +
											"`g_whdb_rh2k`.rh2k_IM_TRANS_LIST_REL c where a.ENTRY_ID in ("
											+ ids + ") and (a.BILL_NO = c.BILL_NO and c.PRE_NO = b.PRE_NO)";

									list = (List<Object[]>) h2018Dao.getQueryBySql(sql);
									for (Object[] d : list) {
										String entryId = (String) d[0];
										tmpMap5.put(entryId, new Date[]{(Date) d[1], (Date) d[2]});
										tmpIdList.remove(entryId);
									}
								}
								sb.delete(0, sb.length());
								for (String entryId : tmpIdList) {
									sb.append("'").append(entryId).append("',");
								}
								if (sb.length() > 0) {
									sb.deleteCharAt(sb.length() - 1);
									ids = sb.toString();
									sql = "select a.ENTRY_ID, b.EXAM_TIME, b.CHECK_TIME from ENTRY_HEAD a,`g_whdb_rh2k`.rh2k_IM_DECL_CUR_HEAD b " +
											"where a.ENTRY_ID in (" + ids + ") and instr(a.TRAF_NAME,b.PRE_NO) > 0";

									list = (List<Object[]>) h2018Dao.getQueryBySql(sql);
									for (Object[] d : list) {
										String entryId = (String) d[0];
										tmpMap5.put(entryId, new Date[]{(Date) d[1], (Date) d[2]});
										tmpIdList.remove(entryId);
									}
								}
							}
						}
						if (impIdList2.size() > 0) {
							sb.delete(0, sb.length());
							for (String impId : impIdList2) {
								sb.append("'").append(impId).append("',");
							}
							sb.deleteCharAt(sb.length() - 1);
							ids = sb.toString();
							// 进口新舱单水运、空运的I_E_DATE精准值由MANIFEST_LIST_NEW的REAL_ARRIVE_DATE给定
							// 注意：提运单号会被重用，当天的也可能有不同报关单使用了相同的提运单号
							sql = "select a.ENTRY_ID, b.REAL_ARRIVE_DATE from ENTRY_HEAD a,`g_whdb_zmqd`.mft_MANIFEST_LIST_NEW b where a.ENTRY_ID in ("
									+ ids + ") and a.BILL_NO = b.BILL_NO and a.I_E_PORT = b.CUSTOMS_CODE and to_char(a.I_E_DATE,'yyyyMMdd') = to_char(b.REAL_ARRIVE_DATE,'yyyyMMdd')";

							list = (List<Object[]>) h2018Dao.getQueryBySql(sql);
							for (Object[] d : list) {
								String entryId = (String) d[0];
								tmpMap9.put(entryId, (Date) d[1]);
							}
							impIdList2.clear();
						}
						//出口舱单
						if (impIdList3.size() > 0) {
							sb.delete(0, sb.length());
							for (String impId : impIdList3) {
								sb.append("'").append(impId).append("',");
							}
							sb.deleteCharAt(sb.length() - 1);
							ids = sb.toString();
							// 出口新舱单水运、空运可能提前但航班晚到，无法用时间去精准定位哪一条会卸载很多次，精准值由MANIFEST_MONITOR_NEW的ARRIVAL_DATE给定
							// 注意：提运单号会被重用，当天的也可能有不同报关单使用了相同的提运单号,ARRIVAL_DATE为00:00:00的赋值12:00:00
							//20210508舱单只获取和武汉海关有关的数据进行时间赋值，所以a.I_E_PORT = b.CUSTOMS_CODE
							sql = "select a.ENTRY_ID, min(b.ARRIVAL_DATE) from ENTRY_HEAD a, `g_whdb_zmqd`.mft_MANIFEST_MONITOR_NEW b where a.ENTRY_ID in ("
									+ ids + ") and a.BILL_NO = b.BILL_NO and a.I_E_PORT = b.CUSTOMS_CODE group by a.ENTRY_ID";

							list = (List<Object[]>) h2018Dao.getQueryBySql(sql);
							for (Object[] d : list) {
								String entryId = (String) d[0];
								tmpMap12.put(entryId, (Date) d[1]);
							}
							impIdList3.clear();
						}
						for (Map.Entry<String, Object[]> d : tmpMap1.entrySet()) {
							String entryId = d.getKey();
							Object[] v = d.getValue();
							Date ieDate = (Date) v[0];// 货物运抵时间
							String iePort = (String) v[1];
							String ieFlag = (String) v[2];
							String trafMode = (String) v[3];
							Date declDate = (Date) v[4];// 申报时间
							String declPort = (String) v[5];// 申报口岸
							String consignScc = (String) v[6];
							String consignCode = (String) v[7];
							String consignName = (String) v[8];
							String tradeCountry = (String) v[9];
							String tradeMode = (String) v[10];
							BigDecimal grossWt = (BigDecimal) v[11];//毛重
							BigDecimal netWt = (BigDecimal) v[12];//净重
							String advanceDecl = (String) v[13];//判断是否是提前申报
							//两步申报都下发到了h2018所以使用00200000节点判断只属于两步申报其中一种类型，
							//应当使用edi_remark41位判断是否有值（edi_remark41值为1，2，3均为两步申报）
							String twoStep = (String) v[14];//判断是否是两步申报
							//2018存在twoStepValue截取出来值为' '情况，需要单独处理
							String twoStepDecl = (" ").equals(twoStep) ? "" : twoStep;
							BigInteger container = (BigInteger) v[15];// 集装箱数量
							String newTwoStep = (String) v[16];//判断是否是新两步申报

							Date[] all = tmpMap2.get(entryId);
							Date authDate = null;
							Date releaseDate = null;
							Date preReleaseDate = null;
							Date certRlsDate = null;
							Date passDate = null;
							Date orderDate = null;
							Date orderReceiveDate = null;
							Date compEleDate = null;
							Date profVerifyDate = null;
							Date eleDeclDate = null;
							Date assessStartDate = null;
							Date assessEndDate = null;
							Date refundDate = null;
							if (all != null) {
								authDate = all[0];// 10审单受理时间
								releaseDate = all[1];// 80结关时间
								preReleaseDate = all[2];// 81担保放行时间
								certRlsDate = all[3];// 70单证放行时间
								passDate = all[4];// 82000000通道验放
								orderDate = all[5];// 30000000现场接单
								orderReceiveDate = all[6];// 30现场接单时间
								compEleDate = all[7];// 00200000完整申报电子申报时间
								profVerifyDate = all[8];// 33专业审证单核时间
								eleDeclDate = all[9];// 00电子申报时间
								assessStartDate = all[10];// 26排查处置/现场验估时间
								assessEndDate = all[11];// 26验估处置完毕时间
								refundDate = all[12];// 退单时间
							}

							Date examDate = null;// 转关数据发送时间
							Date checkDate = null;// 转关数据核销时间(极少数转关单该字段为空)
							Date[] dt = tmpMap5.get(entryId);
							if (dt != null) {
								examDate = dt[0];// 转关数据发送时间
								checkDate = dt[1];// 转关数据核销时间
							}

							Date realArriveDate = tmpMap9.get(entryId);
							Object[] obj = tmpMap10.get(entryId);
							BigDecimal rmbPrice = zero;
							BigDecimal usdPrice = zero;
							String agentCode = null;
							String agentName = null;
							String noteS = null;
							String ownerCode = null;
							String ownerName = null;
							String frnConsignCode = null;
							String frnConsignName = null;
							if (obj != null) {
								rmbPrice = (BigDecimal) obj[0];//人民币
								usdPrice = (BigDecimal) obj[1];//美元
								agentCode = (String) obj[2];//申报单位代码
								agentName = (String) obj[3];//申报单位名称
								noteS = (String) obj[4];//备注
								ownerCode = (String) obj[5];//生产销售单位代码
								ownerName = (String) obj[6];//生产销售单位名称
								frnConsignCode = (String) obj[7];//生产销售单位代码
								frnConsignName = (String) obj[8];//生产销售单位名称
							}

							Object[] man = tmpMap11.get(entryId);
							String checkFlag = null;
							Date manCreateTime = null;
							Date manChkTimeStart = null;
							Date manChkTimeEnd = null;
							String manProcResult = null;
							String manProcIdea = null;
							String checkCustomsCode = null;
							if (man != null) {
								checkFlag = (String) man[0];//是否查验送检
								manCreateTime = (Date) man[1];//指令下达时间
								manChkTimeStart = (Date) man[2];//查验开始时间
								manChkTimeEnd = (Date) man[3];//查验结束时间
								manProcResult = (String) man[4];//处理结果
								manProcIdea = (String) man[5];//处理意见
								checkCustomsCode = (String) man[6];//查验关区
							}

							if ("I".equals(ieFlag)) {
								if (realArriveDate != null) {
									ieDate = realArriveDate;
								} else {
									if (ieDate != null) {
										// 由于报关单表中I_E_DATE精度不够，需要做(非精准)修正（用户给的建议应该是错的，模糊处理下好了，时分为0的设置为12点）
										if ("I".equals(ieFlag)) {// 入境
											String ieDateStr = fullSdf.format(ieDate);
											if (ieDateStr.endsWith("00:00:00")) {
												ieDateStr = ieDateStr.substring(0, 11) + IE_DATE_ADAPT;
												try {
													ieDate = fullSdf.parse(ieDateStr);
												} catch (ParseException e1) {
													// TODO Auto-generated catch block
													e1.printStackTrace();
												}
											}
										}
									}
								}
							} else {
								realArriveDate = tmpMap12.get(entryId);
								//ARRIVAL_DATE为00:00:00时赋值12:00:00
								if (realArriveDate != null) {
									String ieDateStr = fullSdf.format(realArriveDate);
									if (ieDateStr.endsWith("00:00:00")) {
										ieDateStr = ieDateStr.substring(0, 11) + IE_DATE_ADAPT;
										try {
											realArriveDate = fullSdf.parse(ieDateStr);
										} catch (ParseException e1) {
											// TODO Auto-generated catch block
											e1.printStackTrace();
										}
									}
								}
							}

							EntryHead e = new EntryHead();
							e.setEntryId(entryId);
							e.setAcceptDate(authDate != null ? authDate : orderDate);
							e.setCertRlsDate(certRlsDate);// 70单证放行时间
							e.setReleaseDate(releaseDate);//80
							e.setPreReleaseDate(preReleaseDate);// 81时间
							e.setPassMode("3");// 转关
							if ("I".equals(ieFlag)) {
								if (examDate != null) {
									e.setPassMode("3");// 转关
								} else {
									e.setPassMode("1");// 一体化
								}
							} else {
								e.setPassMode("3");// 转关
							}
							e.setDeclPort(declPort);
							e.setCustomsCode(rootCustomsMap.get(declPort));
							e.setIePort(iePort);
							e.setIeDate(ieDate);
							e.setDeclDate(declDate);
							e.setIeFlag(ieFlag);
							e.setTrafMode(trafMode);
							e.setConsignScc(consignScc);
							e.setConsignCode(consignCode);
							e.setConsignName(consignName);
							e.setTradeCountry(tradeCountry);
							e.setTradeMode(tradeMode);
							e.setOrderReceiveDate(orderReceiveDate);//30接单时间
							e.setCompEleDate(compEleDate);// 00200000完整申报电子申报时间
							e.setExamDate(examDate);// 转关数据发送时间
							e.setCheckDate(checkDate);// 转关数据核销时间
							e.setProfVerifyFlag(profVerifyDate != null ? "1" : "0");
							e.setNewTwoStepFlag((null != newTwoStep && !"".equals(newTwoStep) && newTwoStep.equals("1")) ? "1" : "0");
							e.setEleDeclDate(eleDeclDate);
							e.setAssessStartDate(assessStartDate);
							e.setAssessEndDate(assessEndDate);
							e.setRefundDate(refundDate);
							e.setRefundFlag(refundDate != null ? "1" : "0");
							e.setCheckFlag(manCreateTime != null ? "1" : "0");
							long orderReceiveCost = 0L;//接单耗时：30000000-10000000
							//20210423新增处理10节点无时间时的赋值，避免程序报错
							if (orderReceiveDate != null && (authDate != null || orderDate != null)) {
								Long time = authDate != null ? authDate.getTime() : orderDate.getTime();
								orderReceiveCost = (orderReceiveDate.getTime() - time) / 1000;
								e.setOrderReceiveCost(orderReceiveCost);
							} else {
								e.setOrderReceiveCost(null);
							}

							long hgCost = 0L;
							long totalCost = 0L;
							//edi_remark11位为T表示提前申报
							if ("T".equals(advanceDecl)) {
								e.setDeclAdvanceFlag("1");
							} else {
								e.setDeclAdvanceFlag("0");
							}
							if ("I".equals(ieFlag)) {// 入境
								/**根据综合处杨科提出的修改意见，这里将原来'电脑审单时间早于货物运抵时间'改成'申报时间早于货物运抵时间'的为提前申报*/
							/*if (authDate.before(ieDate)) {
								authDate = ieDate;
								e.setDeclAdvanceFlag("1");
							}*/
								if (ieDate != null) {
									if (declDate.before(ieDate)) {
										authDate = ieDate;
										//								e.setDeclAdvanceFlag("1");
									} else {
										//20210423新增处理10节点无时间时的赋值，避免程序报错
										if (authDate == null) {
											authDate = orderDate;
										}
									}
								}
								if (e.getPreReleaseDate() == null && e.getReleaseDate() != null) {
									if (authDate != null) {
										hgCost = (e.getReleaseDate().getTime() - authDate.getTime()) / 1000;
									}
									if (ieDate != null) {
										totalCost = (e.getReleaseDate().getTime() - ieDate.getTime()) / 1000;
									}
								} else if (e.getPreReleaseDate() != null) {
									if (authDate != null) {
										hgCost = (e.getPreReleaseDate().getTime() - authDate.getTime()) / 1000;
									}
									if (ieDate != null) {
										totalCost = (e.getPreReleaseDate().getTime() - ieDate.getTime()) / 1000;
									}
								}
								if (hgCost < 0) {
									hgCost = 0L;
								}
								if (totalCost < 0) {
									totalCost = hgCost;
								}
							} else {// 出境 海关通关时间=70/81之间较早的时间-受理时间
								// 20191211 出口口岸清关、一体化：公路取BINDING_ROAD_TRANSPORT表GEN_DATE；铁路、邮路运输的整体通关时长=海关通关时长
								//20210423新增处理10节点无时间时的赋值，避免程序报错
								if (authDate == null) {
									authDate = orderDate;
								}
								if (realArriveDate != null) {
									//20211209出口舱单有时间赋值给出口货物运抵时间否则使用10审单时间，同时进行计算
									e.setExInPortDate(realArriveDate);
								} else {
									// 取不到数据的统一将货物入境时间设置为受理时间
									if ("3".equals(trafMode) || "6".equals(trafMode) || "9".equals(trafMode)) {// 其它运输方式也假设归为一类
										e.setExInPortDate(authDate);
									} else if ("4".equals(trafMode)) {//TODO 公路：暂时取不到数据
										e.setExInPortDate(authDate);
									} else {
										e.setExInPortDate(authDate);// TODO 出口水运、空运通关时长第一个时间点数据来源还未下发，先临时赋值
									}
								}

								if (e.getCertRlsDate() == null) {
									if (e.getPreReleaseDate() != null) {
										if (authDate != null) {
											hgCost = (e.getPreReleaseDate().getTime() - authDate.getTime()) / 1000;
										}
										totalCost = e.getExInPortDate() != null
												? ((e.getPreReleaseDate().getTime() - e.getExInPortDate().getTime()) / 1000)
												: hgCost;
									}

								} else {
									if (e.getPreReleaseDate() != null) {
										if (e.getCertRlsDate().before(e.getPreReleaseDate())) {
											if (authDate != null) {
												hgCost = (e.getCertRlsDate().getTime() - authDate.getTime()) / 1000;
											}
											totalCost = e.getExInPortDate() != null
													? ((e.getCertRlsDate().getTime() - e.getExInPortDate().getTime()) / 1000)
													: hgCost;
										} else {
											if (authDate != null) {
												hgCost = (e.getPreReleaseDate().getTime() - authDate.getTime()) / 1000;
											}
											totalCost = e.getExInPortDate() != null
													? ((e.getPreReleaseDate().getTime() - e.getExInPortDate().getTime()) / 1000)
													: hgCost;
										}

									} else {
										if (authDate != null) {
											hgCost = (e.getCertRlsDate().getTime() - authDate.getTime()) / 1000;
										}
										totalCost = e.getExInPortDate() != null
												? ((e.getCertRlsDate().getTime() - e.getExInPortDate().getTime()) / 1000)
												: hgCost;
									}
								}
							}

							e.setMainStatus("1");
							e.setCuCost(hgCost);// 海关通关时间(秒)
							e.setTotalCost(totalCost);// 总体通关时间
							e.setGrossWt(grossWt);//净重
							e.setNetWt(netWt);//毛重
							e.setRmbPrice(rmbPrice);//人民币
							e.setUsdPrice(usdPrice);//美元
							e.setContainer(container);//集装箱数量
							e.setAgentCode(agentCode);//申报单位代码
							e.setAgentName(agentName);//申报单位名称
							e.setNoteS(noteS);//备注
							e.setOwnerCode(ownerCode);//生产销售单位代码
							e.setOwnerName(ownerName);//生产销售单位名称
							e.setFrnConsignCode(frnConsignCode);
							e.setFrnConsignName(frnConsignName);
							if ("I".equals(ieFlag)) {// 仅入境转关单有以下值
								long beforeDeclCost = 0L;
								if (checkDate != null && examDate != null) {
									beforeDeclCost = (eleDeclDate.getTime() - checkDate.getTime()) / 1000;
									if (beforeDeclCost < 0) {
										beforeDeclCost = 0L;
									}
								}
								e.setBeforeDeclCost(beforeDeclCost);// 申报前准备时间
							} else {// TODO 20191025 出境转关单有 货物进港时间 值
								long beforeDeclCost = e.getExInPortDate() != null
										? (authDate.getTime() - e.getExInPortDate().getTime())
										: 0L;
								if (beforeDeclCost < 0) {
									beforeDeclCost = 0L;
								}
								e.setBeforeDeclCost(beforeDeclCost);
							}
							//报关模式
							String mode = null;
							//部分订单既是提前申报又是两步申报,不是两步和提前申报的单子均为一般申报,twoStepDecl:0或者空格:代表一分模式
							if ("1".equals(e.getDeclAdvanceFlag()) && (null == twoStepDecl || "".equals(twoStepDecl) || "0".equals(twoStepDecl))) {
								mode = "3";
							} else if ("1".equals(e.getDeclAdvanceFlag()) && (null != twoStepDecl && "".equals(twoStepDecl)) && !"0".equals(twoStepDecl)) {
								mode = "2,3";
							} else if ((null != twoStepDecl && "".equals(twoStepDecl)) && !"0".equals(twoStepDecl)) {
								mode = "2";
							} else {
								mode = "1";
							}
							e.setDeclMode(mode);//报关模式
							//70000000、80000000、81000000、82000000均为空则表示未放行
							if (preReleaseDate == null && certRlsDate == null && releaseDate == null && passDate == null) {
								e.setDeclStatus("1");
							} else if (releaseDate != null) {
								//80表示已结关
								e.setDeclStatus("3");
							} else {
								e.setDeclStatus("2");
							}

							e.setManCreateTime(manCreateTime);//指令下达时间
							e.setManChkTimeStart(manChkTimeStart);//查验开始时间
							e.setManChkTimeEnd(manChkTimeEnd);//查验结束时间
							e.setManProcResult(manProcResult);
							e.setManProcIdea(manProcIdea);
							e.setCheckCustomsCode(rootCustomsMap.get(checkCustomsCode));
							dao.executeUpdate("delete from WXJY_ENTRY_HEAD where ENTRY_ID = ?", entryId);
							entryHeadRepository.save(e);
						}
						//ciqCode存在超过600个情况,每个报关单每次查都拼接重复工作太多，所以提出来
						//先删除这些报关单下的所有商品信息
						dao.executeUpdate("delete from WXJY_ENTRY_LIST where ENTRY_ID in (" + entryIds + ")");
						try {
							StringBuilder codeListSb = new StringBuilder();
							int x = 1;
							for (Iterator it = allCode.iterator(); it.hasNext(); ) {
								String iqCode = (String) it.next();

								codeListSb.append("'").append(iqCode).append("',");
								if ((x % 600 == 0 || !it.hasNext()) && codeListSb.length() > 0) {
									codeListSb.deleteCharAt(codeListSb.length() - 1);
									String iqCodes = codeListSb.toString();
									//报关单表体,报关单第九位0=出口1=进口
									sql = "select ENTRY_ID,G_NO,CODE_TS,G_NAME,QTY_1,RMB_PRICE,USD_PRICE,G_MODEL,G_CERT_FLAG," +
											"(select max(a.CREATE_DATE) from ENTRY_WORKFLOW a where a.STEP_ID='80000000' AND l.ENTRY_ID = a.ENTRY_ID) as RELEASE_DATE," +
											"UNGID,UNG_FLAG,UNG_MODEL,UNG_CLASSIFY,UNG_G_NAME,PRODUCT_CHAR_CODE,IQ_CODE " +
											"from ENTRY_LIST l where l.ENTRY_ID in (" + entryIds + ") " +
											"and ((substr(l.ENTRY_ID,9,1) ='0' and (l.IQ_CODE in (" + iqCodes + ") or l.UNGID is not null " +
											"or l.PRODUCT_CHAR_CODE like '%31%' or l.PRODUCT_CHAR_CODE like '%32%')) or " +
											"(substr(l.ENTRY_ID,9,1) = '1' and (l.UNGID is not null or l.PRODUCT_CHAR_CODE like '%31%' or l.PRODUCT_CHAR_CODE like '%32%')));";
									List<Object[]> codeTsList = (List<Object[]>) h2018Dao.getQueryBySql(sql);
									if (null != codeTsList && codeTsList.size() > 0) {
										//由于新组合查询不设定某个固定节点更新数据，会存在相同报关单在后面更新流程节点时间，所以先从中间表查出数据进行更新
										//会存在商品金额为空的情况，如果只有一条商品并商品为空则报关单头要删除
										EntryList entity = null;
										for (Object[] codeTs : codeTsList) {//将根据报关单编号查询到的商品编号及报关单号添加到KPI_ENTRY_HEAD_NEW_COPY表里
											entity = new EntryList();
											entity.setEntryId(codeTs[0] != null ? codeTs[0].toString() : "");
											entity.setGNo(codeTs[1] != null ? (BigDecimal) codeTs[1] : new BigDecimal(0));
											entity.setCodeTs(codeTs[2] != null ? codeTs[2].toString() : "");
											entity.setGName(codeTs[3] != null ? codeTs[3].toString() : "");
											entity.setQty1(codeTs[4] != null ? (BigDecimal) codeTs[4] : new BigDecimal(0));
											entity.setRmbPrice(codeTs[5] != null ? (BigDecimal) codeTs[5] : new BigDecimal(0));
											entity.setUsdPrice(codeTs[6] != null ? (BigDecimal) codeTs[6] : new BigDecimal(0));
											entity.setGModel(codeTs[7] != null ? codeTs[7].toString() : "");
											entity.setGCertFlag(codeTs[8] != null ? codeTs[8].toString() : "");
											entity.setReleaseDate(codeTs[9] != null ? (Date) codeTs[9] : null);
											entity.setCodeTsShort(codeTs[2] != null ? codeTs[2].toString().substring(0, 6) : "");
											entity.setUngid(codeTs[10] != null ? codeTs[10].toString() : "");
											entity.setUngFlag(codeTs[11] != null ? codeTs[11].toString() : "");
											entity.setUngModel(codeTs[12] != null ? codeTs[12].toString() : "");
											entity.setUngClassify(codeTs[13] != null ? codeTs[13].toString() : "");
											entity.setUngGName(codeTs[14] != null ? codeTs[14].toString() : "");
											entity.setIqCode(codeTs[16] != null ? codeTs[16].toString() : "");
											//货物属性，判断货物属性是否是31/散装危险化学品，32/件装危险化学品
											String goods_attr = "";
											if (codeTs[15] != null) {
												goods_attr = (String) codeTs[15];
												if (goods_attr.contains("31")) {
													goods_attr = "31";
												} else if (goods_attr.contains("32")) {
													goods_attr = "32";
												} else {
													goods_attr = "";
												}
											}
											entity.setProductCharCode(goods_attr);
											//查出的数据可能存在ciqCode或者UNGID为空的情况,报关单第九位0=出口1=进口
											//出口按ciq编码、ungid不为空和货物属性包含31或32
											//进口按ungid不为空或货物属性
											String ieFlag = codeTs[0] != null ? codeTs[0].toString().substring(8, 9) : "";
											//货物属性为不空时可以初步判定该商品是危化品，接下来只需判断该商品是否还包含危险货物的属性
											if (entity.getProductCharCode() != null && !"".equals(entity.getProductCharCode())) {
												if (codeTs[10] != null) {
													entity.setGoodsType("1,2,3");
												} else {
													entity.setGoodsType("1");
												}
											} else {
												//货物属性为空时
												//出口
												if (ieFlag.equals("0")) {
													if (codeTs[16] != null) {
														//syncChemicalsCiq只可能是包含了危化品,因为这个表的数据就是查询的系统中危险品模块里用户已经维护的包含了危化品的数据
														Object[] obj = (Object[]) iedgRepository.getObjectBySql("select * from iedg_sync_chemicals_ciq where CIQ_CODE = ?", (String) codeTs[16]);
														if (obj != null) {
															if (codeTs[16] != null) {
																entity.setGoodsType("1,2,3");
															} else {
																entity.setGoodsType("1");
															}
														} else {
															entity.setGoodsType("2");
														}
													} else {
														entity.setGoodsType("2");
													}
												} else {
													//进口
													entity.setGoodsType("2");
												}
											}
											entity.setId(dao.getGuidStringBySql());
											entryListRepository.save(entity);
										}
									}
									codeListSb.delete(0, codeListSb.length());
								}
								x++;
							}
						} catch (Exception ex) {
							// 主键可能因为多次结关跨天，导致新纪录主键重复
							logger.error("保存危险品新维度一体化通关中间记录失败，重新保存");
							dao.executeUpdate("delete from WXJY_ENTRY_LIST where ENTRY_ID in (" + entryIds + ")");
						}
						tmpMap1.clear();
						tmpMap2.clear();
						tmpMap5.clear();
						tmpMap9.clear();
						tmpMap10.clear();
						tmpMap12.clear();
						tmpMap11.clear();
						sb.delete(0, sb.length());
					}
					i++;
				}
			}
		}
	}

	public void kaqgDeclMain(Date statBegin, Date statEnd, List<String> code, List<String> allCode) {
		Map<String, Object[]> tmpMap1 = new HashMap<String, Object[]>();
		Map<String, Date[]> tmpMap2 = new HashMap<String, Date[]>();
		Map<String, Date> tmpMap9 = new HashMap<String, Date>();
		Map<String, Object[]> tmpMap10 = new HashMap<String, Object[]>();
		Map<String, Object[]> tmpMap11 = new HashMap<String, Object[]>();
		Map<String, Date> tmpMap12 = new HashMap<String, Date>();
		if (code != null && code.size() > 0) {
			List<String> entryH2018IdList = new ArrayList<>();//存放所有
			StringBuilder codeSb = new StringBuilder();
			int j = 1;
			for (Iterator itera = code.iterator(); itera.hasNext(); ) {
				String ciqCode = (String) itera.next();

				codeSb.append("'").append(ciqCode).append("',");
				if ((j % 600 == 0 || !itera.hasNext()) && codeSb.length() > 0) {
					codeSb.deleteCharAt(codeSb.length() - 1);
					String codes = codeSb.toString();
					//存在后续查出的报关单前面已经有，所以需要处理去重
					//出口按编码、ungid不为空和货物属性包含31或32
					//进口按ungid不为空或货物属性包含31或32
					String sql = "select distinct(d.ENTRY_ID) from ENTRY_HEAD d, ENTRY_WORKFLOW w, ENTRY_LIST l where " +
							"d.ENTRY_ID like '47%' and (substr(d.EDI_REMARK,7,1)!='C' or substr(d.EDI_REMARK,15,1)!='1') " +
							"and (substr(d.EDI_REMARK,17,1) not in ('a','c','C','d','e','f') or " +
							"(substr(d.EDI_REMARK,17,1) = 'C' and substr(d.EDI_REMARK,8,1) != 'G')) and substr(d.I_E_PORT,0,2)=substr(d.DECL_PORT,0,2) " +
							"and d.ENTRY_ID = w.ENTRY_ID and d.ENTRY_ID = l.ENTRY_ID and w.STEP_ID = '80000000' and w.CREATE_DATE >= ? and w.CREATE_DATE < ? " +
							"and ((d.I_E_FLAG = 'E' and (l.IQ_CODE in (" + codes + ") or l.UNGID is not null or l.PRODUCT_CHAR_CODE like '%31%' " +
							"or l.PRODUCT_CHAR_CODE like '%32%')) or (d.I_E_FLAG = 'I' and (l.UNGID is not null or l.PRODUCT_CHAR_CODE like '%31%' " +
							"or l.PRODUCT_CHAR_CODE like '%32%'))) order by d.ENTRY_ID;";
					List<String> entryIdList = (List<String>) h2018Dao.getQueryBySql(sql, statBegin, statEnd);
					entryH2018IdList.addAll(entryIdList);
					codeSb.delete(0, codeSb.length());
				}
				j++;
			}
			//用JDK1.8 Stream中对List进行去重：list.stream().distinct();
			entryH2018IdList = (List) entryH2018IdList.stream().distinct().collect(Collectors.toList());
			if (entryH2018IdList != null && entryH2018IdList.size() > 0) {
				StringBuilder sb = new StringBuilder();
				int i = 1;
				for (Iterator iterator = entryH2018IdList.iterator(); iterator.hasNext(); ) {
					String id = (String) iterator.next();

					sb.append("'").append(id).append("',");

					if ((i % 300 == 0 || !iterator.hasNext()) && sb.length() > 0) {
						List<String> impIdList2 = new ArrayList<String>();//20191210 进口水运（新舱单部分）、空运可以从新舱单系统MANIFEST_LIST_NEW查到精确I_E_DATE
						List<String> impIdList3 = new ArrayList<String>();//20211210 出口水运（新舱单部分）、空运可以从新舱单系统MANIFEST_MONITOR_NEW查到精确ARRIVAL_DATE
						sb.deleteCharAt(sb.length() - 1);
						String ids = sb.toString();
						String entryIds = sb.toString();
						String sql = "select h.ENTRY_ID, I_E_DATE, I_E_PORT, I_E_FLAG, TRAF_MODE, D_DATE, DECL_PORT,CONSIGN_SCC, CONSIGN_CODE, CONSIGN_NAME, FRN_I_E_COUNTRY,"
								+ " TRADE_MODE, nvl(GROSS_WT,0), nvl(NET_WT,0), substr(EDI_REMARK,11,1), substr(EDI_REMARK,41,1),nvl(count(c.ENTRY_ID),0),substr(EDI_REMARK,53,1) "
								+ "from ENTRY_HEAD h left join `g_whdb_zmqd`.h18c_ENTRY_CONTAINER c on h.ENTRY_ID = c.ENTRY_ID where h.ENTRY_ID in ("
								+ ids + ")  group by h.ENTRY_ID, I_E_DATE, I_E_PORT, I_E_FLAG, TRAF_MODE, D_DATE, DECL_PORT, CONSIGN_SCC, CONSIGN_CODE, CONSIGN_NAME, FRN_I_E_COUNTRY," +
								"TRADE_MODE, nvl(GROSS_WT,0), nvl(NET_WT,0), substr(EDI_REMARK,11,1), substr(EDI_REMARK,41,1),substr(EDI_REMARK,53,1);";
						List<Object[]> list = (List<Object[]>) h2018Dao.getQueryBySql(sql);
						for (Object[] d : list) {
							String idH = (String) d[0];
							String iEFlag = (String) d[3];
							String traMode = (String) d[4];
							if ("I".equals(iEFlag)) {
								if ("2".equals(traMode) || "5".equals(traMode)) {
									impIdList2.add(idH);
								}
							} else {
								if ("2".equals(traMode) || "5".equals(traMode)) {
									impIdList3.add(idH);
								}
							}
							tmpMap1.put((String) d[0],
									new Object[]{(Date) d[1], (String) d[2], (String) d[3], (String) d[4], (Date) d[5], (String) d[6], (String) d[7], (String) d[8], (String) d[9], (String) d[10],
											(String) d[11], (BigDecimal) d[12], (BigDecimal) d[13], (String) d[14], (String) d[15], (BigInteger) d[16], (String) d[17]});
						}

						sql = "select h.ENTRY_ID,(select max(CREATE_DATE) from ENTRY_WORKFLOW a where STEP_ID='10000000' AND h.ENTRY_ID = a.ENTRY_ID) as authDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW a where STEP_ID='80000000' AND h.ENTRY_ID = a.ENTRY_ID) as releaseDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW b where STEP_ID='81000000' AND h.ENTRY_ID = b.ENTRY_ID) as preReleaseDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW c where STEP_ID='70000000' AND h.ENTRY_ID = c.ENTRY_ID) as certRlsDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW c where STEP_ID='82000000' AND h.ENTRY_ID = c.ENTRY_ID) as passDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW c where STEP_ID='30000000' AND h.ENTRY_ID = c.ENTRY_ID) as orderDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW b where STEP_ID='30000000' AND h.ENTRY_ID = b.ENTRY_ID AND PROC_RESULT like '%G%' and PROC_ER like '47%') as orderReceiveDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW c where STEP_ID='00200000' AND h.ENTRY_ID = c.ENTRY_ID) as compEleDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW b where STEP_ID='33000000' AND h.ENTRY_ID = b.ENTRY_ID AND PROC_RESULT like '%G%' and PROC_ER like '47%') as profVerifyDate, "
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW b where STEP_ID='00000000' AND h.ENTRY_ID = b.ENTRY_ID) as eleDeclDate, "
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW b where STEP_ID='26000000' AND h.ENTRY_ID = b.ENTRY_ID AND PROC_RESULT like '%M%') as assessStartDate, "
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW b where STEP_ID='26000000' AND h.ENTRY_ID = b.ENTRY_ID AND PROC_RESULT like '%G%') as assessEndDate,"
								+ "(select max(CREATE_DATE) from ENTRY_WORKFLOW b where STEP_ID in ('10000000','10200000','20000000') AND h.ENTRY_ID = b.ENTRY_ID and substr(b.status_code,4,1) = 5 and b.proc_result like '%E%') as refundDate "
								+ "from ENTRY_HEAD h where h.ENTRY_ID in (" + ids
								+ ") group by ENTRY_ID;";
						list = (List<Object[]>) h2018Dao.getQueryBySql(sql);
						for (Object[] d : list) {
							tmpMap2.put((String) d[0], new Date[]{(Date) d[1], (Date) d[2], (Date) d[3], (Date) d[4], (Date) d[5], (Date) d[6], (Date) d[7], (Date) d[8], (Date) d[9],
									(Date) d[10], (Date) d[11], (Date) d[12], (Date) d[13]});
						}

						sql = "select h.ENTRY_ID,substr(h.CHECK_REQUEST_TOTAL,-1,1),h.CREATE_TIME,h.MAN_CHK_TIME_START,h.MAN_CHK_TIME_END,MAN_PROC_RESULT,MAN_PROC_IDEA,CHECK_CUSTOMS_CODE "
								+ "from CI_CHECK_MAN_WORK_HEAD h where h.CHECK_STATE = 'M' and h.MODIFY_TIME = "
								+ "(select max(d.MODIFY_TIME) from CI_CHECK_MAN_WORK_HEAD d where d.ID = h.ID) and h.ENTRY_ID in(" + ids + ") ;";
						list = (List<Object[]>) inspDao.getQueryBySql(sql);
						for (Object[] d : list) {
							tmpMap11.put((String) d[0], new Object[]{(String) d[1], (Date) d[2], (Date) d[3], (Date) d[4], (String) d[5], (String) d[6], (String) d[7]});
						}

						//货运量毛重、净重、货运值人民币、美元、集装箱数量GROUP_CONCAT方法放在此处当传一个报关单id并且没有随附单证时会报错，所以加上nvl()
						sql = "select h.ENTRY_ID,sum(nvl(l.RMB_PRICE,0)),sum(nvl(l.USD_PRICE,0)),h.AGENT_CODE,h.AGENT_NAME,h.NOTE_S,"
								+ "h.OWNER_CODE,h.OWNER_NAME,FRN_CONSIGN_CODE,FRN_CONSIGN_NAME from ENTRY_HEAD h left join ENTRY_LIST l on h.ENTRY_ID=l.ENTRY_ID "
								+ "where h.ENTRY_ID in("
								+ ids + ") group by h.ENTRY_ID,h.AGENT_CODE,h.AGENT_NAME,h.NOTE_S,h.OWNER_CODE,h.OWNER_NAME,FRN_CONSIGN_CODE,FRN_CONSIGN_NAME;";
						list = (List<Object[]>) h2018Dao.getQueryBySql(sql);
						for (Object[] d : list) {
							tmpMap10.put((String) d[0], new Object[]{(BigDecimal) d[1], (BigDecimal) d[2], (String) d[3], (String) d[4], (String) d[5], (String) d[6], (String) d[7],
									(String) d[8], (String) d[9]});
						}
						if (impIdList2.size() > 0) {
							sb.delete(0, sb.length());
							for (String impId : impIdList2) {
								sb.append("'").append(impId).append("',");
							}
							sb.deleteCharAt(sb.length() - 1);
							ids = sb.toString();
							// 进口新舱单水运、空运的I_E_DATE精准值由MANIFEST_LIST_NEW的REAL_ARRIVE_DATE给定
							// 注意：提运单号会被重用，当天的也可能有不同报关单使用了相同的提运单号
							sql = "select a.ENTRY_ID, b.REAL_ARRIVE_DATE from ENTRY_HEAD a, `g_whdb_zmqd`.mft_MANIFEST_LIST_NEW b where a.ENTRY_ID in ("
									+ ids + ") and a.BILL_NO = b.BILL_NO and a.I_E_PORT = b.CUSTOMS_CODE and to_char(a.I_E_DATE,'yyyyMMdd') = to_char(b.REAL_ARRIVE_DATE,'yyyyMMdd')";

							list = (List<Object[]>) h2018Dao.getQueryBySql(sql);
							for (Object[] d : list) {
								String entryId = (String) d[0];
								tmpMap9.put(entryId, (Date) d[1]);
							}
							impIdList2.clear();
						}
						//出口舱单
						if (impIdList3.size() > 0) {
							sb.delete(0, sb.length());
							for (String impId : impIdList3) {
								sb.append("'").append(impId).append("',");
							}
							sb.deleteCharAt(sb.length() - 1);
							ids = sb.toString();
							// 出口新舱单水运、空运可能提前但航班晚到，无法用时间去精准定位哪一条会卸载很多次，精准值由MANIFEST_MONITOR_NEW的ARRIVAL_DATE给定
							// 注意：提运单号会被重用，当天的也可能有不同报关单使用了相同的提运单号,ARRIVAL_DATE为00:00:00的赋值12:00:00
							//20210508舱单只获取和武汉海关有关的数据进行时间赋值，所以a.I_E_PORT = b.CUSTOMS_CODE
							sql = "select a.ENTRY_ID, min(b.ARRIVAL_DATE) from ENTRY_HEAD a, `g_whdb_zmqd`.mft_MANIFEST_MONITOR_NEW b where a.ENTRY_ID in ("
									+ ids + ") and a.BILL_NO = b.BILL_NO and a.I_E_PORT = b.CUSTOMS_CODE group by a.ENTRY_ID";

							list = (List<Object[]>) h2018Dao.getQueryBySql(sql);
							for (Object[] d : list) {
								String entryId = (String) d[0];
								tmpMap12.put(entryId, (Date) d[1]);
							}
							impIdList3.clear();
						}
						for (Map.Entry<String, Object[]> d : tmpMap1.entrySet()) {
							String entryId = d.getKey();
							Object[] v = d.getValue();
							Date ieDate = (Date) v[0];// 货物运抵时间
							String iePort = (String) v[1];
							String ieFlag = (String) v[2];
							String trafMode = (String) v[3];
							Date declDate = (Date) v[4];// 申报时间
							String declPort = (String) v[5];// 申报口岸
							String consignScc = (String) v[6];
							String consignCode = (String) v[7];
							String consignName = (String) v[8];
							String tradeCountry = (String) v[9];
							String tradeMode = (String) v[10];
							BigDecimal grossWt = (BigDecimal) v[11];//毛重
							BigDecimal netWt = (BigDecimal) v[12];//净重
							String advanceDecl = (String) v[13];//判断是否是提前申报
							//两步申报都下发到了h2018所以使用00200000节点判断只属于两步申报其中一种类型，
							//应当使用edi_remark41位判断是否有值（edi_remark41值为1，2，3均为两步申报）
							String twoStep = (String) v[14];//判断是否是两步申报
							//2018存在twoStepValue截取出来值为' '情况，需要单独处理
							String twoStepDecl = (" ").equals(twoStep) ? "" : twoStep;
							BigInteger container = (BigInteger) v[15];// 集装箱数量
							String newTwoStep = (String) v[16];//判断是否是新两步申报

							Date[] all = tmpMap2.get(entryId);
							Date authDate = null;
							Date releaseDate = null;
							Date preReleaseDate = null;
							Date certRlsDate = null;
							Date passDate = null;
							Date orderDate = null;
							Date orderReceiveDate = null;
							Date compEleDate = null;
							Date profVerifyDate = null;
							Date eleDeclDate = null;
							Date assessStartDate = null;
							Date assessEndDate = null;
							Date refundDate = null;
							if (all != null) {
								authDate = all[0];// 10审单受理时间
								releaseDate = all[1];// 80结关时间
								preReleaseDate = all[2];// 81担保放行时间
								certRlsDate = all[3];// 70单证放行时间
								passDate = all[4];// 82000000通道验放
								orderDate = all[5];// 30000000现场接单
								orderReceiveDate = all[6];// 30现场接单时间
								compEleDate = all[7];// 00200000完整申报电子申报时间
								profVerifyDate = all[8];// 33专业审证单核时间
								eleDeclDate = all[9];// 00电子申报时间
								assessStartDate = all[10];// 26排查处置/现场验估时间
								assessEndDate = all[11];// 26验估处置完毕时间
								refundDate = all[12];// 退单时间
							}

							Date realArriveDate = tmpMap9.get(entryId);
							Object[] obj = tmpMap10.get(entryId);
							BigDecimal rmbPrice = zero;
							BigDecimal usdPrice = zero;
							String agentCode = null;
							String agentName = null;
							String noteS = null;
							String ownerCode = null;
							String ownerName = null;
							String frnConsignCode = null;
							String frnConsignName = null;
							if (obj != null) {
								rmbPrice = (BigDecimal) obj[0];//人民币
								usdPrice = (BigDecimal) obj[1];//美元
								agentCode = (String) obj[2];//申报单位代码
								agentName = (String) obj[3];//申报单位名称
								noteS = (String) obj[4];//备注
								ownerCode = (String) obj[7];//生产销售单位代码
								ownerName = (String) obj[8];//生产销售单位名称
								frnConsignCode = (String) obj[7];//生产销售单位代码
								frnConsignName = (String) obj[8];//生产销售单位名称
							}

							Object[] man = tmpMap11.get(entryId);
							String checkFlag = null;
							Date manCreateTime = null;
							Date manChkTimeStart = null;
							Date manChkTimeEnd = null;
							String manProcResult = null;
							String manProcIdea = null;
							String checkCustomsCode = null;
							if (man != null) {
								checkFlag = (String) man[0];//是否查验送检
								manCreateTime = (Date) man[1];//指令下达时间
								manChkTimeStart = (Date) man[2];//查验开始时间
								manChkTimeEnd = (Date) man[3];//查验结束时间
								manProcResult = (String) man[4];//处理结果
								manProcIdea = (String) man[5];//处理意见
								checkCustomsCode = (String) man[6];//查验关区
							}

							if ("I".equals(ieFlag)) {
								if (realArriveDate != null) {
									ieDate = realArriveDate;
								} else {
									if (ieDate != null) {
										// 由于报关单表中I_E_DATE精度不够，需要做(非精准)修正（用户给的建议应该是错的，模糊处理下好了，时分为0的设置为12点）
										if ("I".equals(ieFlag)) {// 入境
											String ieDateStr = fullSdf.format(ieDate);
											if (ieDateStr.endsWith("00:00:00")) {
												ieDateStr = ieDateStr.substring(0, 11) + IE_DATE_ADAPT;
												try {
													ieDate = fullSdf.parse(ieDateStr);
												} catch (ParseException e1) {
													// TODO Auto-generated catch block
													e1.printStackTrace();
												}
											}
										}
									}
								}
							} else {
								realArriveDate = tmpMap12.get(entryId);
								//ARRIVAL_DATE为00:00:00时赋值12:00:00
								if (realArriveDate != null) {
									String ieDateStr = fullSdf.format(realArriveDate);
									if (ieDateStr.endsWith("00:00:00")) {
										ieDateStr = ieDateStr.substring(0, 11) + IE_DATE_ADAPT;
										try {
											realArriveDate = fullSdf.parse(ieDateStr);
										} catch (ParseException e1) {
											// TODO Auto-generated catch block
											e1.printStackTrace();
										}
									}
								}
							}

							EntryHead e = new EntryHead();
							e.setEntryId(entryId);
							e.setAcceptDate(authDate != null ? authDate : orderDate);
							e.setCertRlsDate(certRlsDate);// 70单证放行时间
							e.setReleaseDate(releaseDate);//80
							e.setPreReleaseDate(preReleaseDate);// 81时间
							e.setPassMode("2");// 一体化通关
							e.setDeclPort(declPort);
							e.setCustomsCode(rootCustomsMap.get(declPort));
							e.setIePort(iePort);
							e.setIeDate(ieDate);
							e.setDeclDate(declDate);
							e.setIeFlag(ieFlag);
							e.setTrafMode(trafMode);

							e.setConsignScc(consignScc);
							e.setConsignCode(consignCode);
							e.setConsignName(consignName);
							e.setTradeCountry(tradeCountry);
							e.setTradeMode(tradeMode);
							e.setOrderReceiveDate(orderReceiveDate);//30接单时间
							e.setCompEleDate(compEleDate);// 00200000完整申报电子申报时间
							e.setProfVerifyFlag(profVerifyDate != null ? "1" : "0");
							e.setNewTwoStepFlag((null != newTwoStep && !"".equals(newTwoStep) && newTwoStep.equals("1")) ? "1" : "0");
							e.setEleDeclDate(eleDeclDate);
							e.setAssessStartDate(assessStartDate);
							e.setAssessEndDate(assessEndDate);
							e.setRefundDate(refundDate);
							e.setRefundFlag(refundDate != null ? "1" : "0");
							e.setCheckFlag(manCreateTime != null ? "1" : "0");
							long orderReceiveCost = 0L;//接单耗时：30000000-10000000
							//20210423新增处理10节点无时间时的赋值，避免程序报错
							if (orderReceiveDate != null && (authDate != null || orderDate != null)) {
								Long time = authDate != null ? authDate.getTime() : orderDate.getTime();
								orderReceiveCost = (orderReceiveDate.getTime() - time) / 1000;
								e.setOrderReceiveCost(orderReceiveCost);
							} else {
								e.setOrderReceiveCost(null);
							}

							long hgCost = 0L;
							long totalCost = 0L;
							//edi_remark11位为T表示提前申报
							if ("T".equals(advanceDecl)) {
								e.setDeclAdvanceFlag("1");
							} else {
								e.setDeclAdvanceFlag("0");
							}
							if ("I".equals(ieFlag)) {// 入境
								/**根据综合处杨科提出的修改意见，这里将原来'电脑审单时间早于货物运抵时间'改成'申报时间早于货物运抵时间'的为提前申报*/
								if (ieDate != null) {
									if (declDate.before(ieDate)) {
										authDate = ieDate;
										//								e.setDeclAdvanceFlag("1");
									} else {
										//20210423新增处理10节点无时间时的赋值，避免程序报错
										if (authDate == null) {
											authDate = orderDate;
										}
									}
								}
								if (e.getPreReleaseDate() == null && e.getReleaseDate() != null) {
									if (authDate != null) {
										hgCost = (e.getReleaseDate().getTime() - authDate.getTime()) / 1000;
									}
									if (ieDate != null) {
										totalCost = (e.getReleaseDate().getTime() - ieDate.getTime()) / 1000;
									}
								} else if (e.getPreReleaseDate() != null) {
									if (authDate != null) {
										hgCost = (e.getPreReleaseDate().getTime() - authDate.getTime()) / 1000;
									}
									if (ieDate != null) {
										totalCost = (e.getPreReleaseDate().getTime() - ieDate.getTime()) / 1000;
									}
								}
								if (hgCost < 0) {
									hgCost = 0L;
								}
								if (totalCost < 0) {
									totalCost = hgCost;
								}
								//新组合查询用00-货物运抵，组合查询用10-货物运抵
								e.setBeforeDeclCost((eleDeclDate.getTime() - e.getIeDate().getTime()) / 1000);// 申报前准备时间
								if (e.getBeforeDeclCost() < 0) {
									e.setBeforeDeclCost(0L);
								}
							} else {// 出境 海关通关时间=70/81之间较早的时间-受理时间
								// 20191211 出口口岸清关、一体化：公路取BINDING_ROAD_TRANSPORT表GEN_DATE；铁路、邮路运输的整体通关时长=海关通关时长
								//20210423新增处理10节点无时间时的赋值，避免程序报错
								if (authDate == null) {
									authDate = orderDate;
								}
								if (realArriveDate != null) {
									//20211209出口舱单有时间赋值给出口货物运抵时间否则使用10审单时间，同时进行计算
									e.setExInPortDate(realArriveDate);
								} else {
									// 取不到数据的统一将货物入境时间设置为受理时间
									if ("3".equals(trafMode) || "6".equals(trafMode) || "9".equals(trafMode)) {// 其它运输方式也假设归为一类
										e.setExInPortDate(authDate);
									} else if ("4".equals(trafMode)) {//TODO 公路：暂时取不到数据
										e.setExInPortDate(authDate);
									} else {
										e.setExInPortDate(authDate);// TODO 出口水运、空运通关时长第一个时间点数据来源还未下发，先临时赋值
									}
								}

								if (e.getCertRlsDate() == null) {
									if (e.getPreReleaseDate() != null) {
										if (authDate != null) {
											hgCost = (e.getPreReleaseDate().getTime() - authDate.getTime()) / 1000;
										}
										totalCost = e.getExInPortDate() != null
												? ((e.getPreReleaseDate().getTime() - e.getExInPortDate().getTime()) / 1000)
												: hgCost;
									}

								} else {
									if (e.getPreReleaseDate() != null) {
										if (e.getCertRlsDate().before(e.getPreReleaseDate())) {
											if (authDate != null) {
												hgCost = (e.getCertRlsDate().getTime() - authDate.getTime()) / 1000;
											}
											totalCost = e.getExInPortDate() != null
													? ((e.getCertRlsDate().getTime() - e.getExInPortDate().getTime()) / 1000)
													: hgCost;
										} else {
											if (authDate != null) {
												hgCost = (e.getPreReleaseDate().getTime() - authDate.getTime()) / 1000;
											}
											totalCost = e.getExInPortDate() != null
													? ((e.getPreReleaseDate().getTime() - e.getExInPortDate().getTime()) / 1000)
													: hgCost;
										}

									} else {
										if (authDate != null) {
											hgCost = (e.getCertRlsDate().getTime() - authDate.getTime()) / 1000;
										}
										totalCost = e.getExInPortDate() != null
												? ((e.getCertRlsDate().getTime() - e.getExInPortDate().getTime()) / 1000)
												: hgCost;
									}
								}
								e.setBeforeDeclCost(e.getExInPortDate() != null
										? ((eleDeclDate.getTime() - e.getExInPortDate().getTime()) / 1000)
										: 0L);// 申报前准备时间
								if (e.getBeforeDeclCost() < 0) {
									e.setBeforeDeclCost(0L);
								}
							}

							e.setMainStatus("1");
							e.setCuCost(hgCost);// 海关通关时间(秒)
							e.setTotalCost(totalCost);// 总体通关时间
							e.setGrossWt(grossWt);//净重
							e.setNetWt(netWt);//毛重
							e.setRmbPrice(rmbPrice);//人民币
							e.setUsdPrice(usdPrice);//美元
							e.setContainer(container);//集装箱数量
							e.setAgentCode(agentCode);//申报单位代码
							e.setAgentName(agentName);//申报单位名称
							e.setNoteS(noteS);//备注
							e.setOwnerCode(ownerCode);//生产销售单位代码
							e.setOwnerName(ownerName);//生产销售单位名称
							e.setFrnConsignCode(frnConsignCode);
							e.setFrnConsignName(frnConsignName);
							//报关模式
							String mode = null;
							//部分订单既是提前申报又是两步申报,不是两步和提前申报的单子均为一般申报,twoStepDecl:0或者空格:代表一分模式
							if ("1".equals(e.getDeclAdvanceFlag()) && (null == twoStepDecl || "".equals(twoStepDecl) || "0".equals(twoStepDecl))) {
								mode = "3";
							} else if ("1".equals(e.getDeclAdvanceFlag()) && (null != twoStepDecl && "".equals(twoStepDecl)) && !"0".equals(twoStepDecl)) {
								mode = "2,3";
							} else if ((null != twoStepDecl && "".equals(twoStepDecl)) && !"0".equals(twoStepDecl)) {
								mode = "2";
							} else {
								mode = "1";
							}
							e.setDeclMode(mode);//报关模式
							//70000000、80000000、81000000、82000000均为空则表示未放行
							if (preReleaseDate == null && certRlsDate == null && releaseDate == null && passDate == null) {
								e.setDeclStatus("1");
							} else if (releaseDate != null) {
								//80表示已结关
								e.setDeclStatus("3");
							} else {
								e.setDeclStatus("2");
							}

							e.setManCreateTime(manCreateTime);//指令下达时间
							e.setManChkTimeStart(manChkTimeStart);//查验开始时间
							e.setManChkTimeEnd(manChkTimeEnd);//查验结束时间
							e.setManProcResult(manProcResult);
							e.setManProcIdea(manProcIdea);
							e.setCheckCustomsCode(rootCustomsMap.get(checkCustomsCode));
							dao.executeUpdate("delete from WXJY_ENTRY_HEAD where ENTRY_ID = ?", entryId);
							entryHeadRepository.save(e);

						}
						//ciqCode存在超过600个情况,每个报关单每次查都拼接重复工作太多，所以提出来
						//先删除这些报关单下的所有商品信息
						dao.executeUpdate("delete from WXJY_ENTRY_LIST where ENTRY_ID in (" + entryIds + ")");
						try {
							StringBuilder codeListSb = new StringBuilder();
							int x = 1;
							for (Iterator it = allCode.iterator(); it.hasNext(); ) {
								String iqCode = (String) it.next();

								codeListSb.append("'").append(iqCode).append("',");
								if ((x % 600 == 0 || !it.hasNext()) && codeListSb.length() > 0) {
									codeListSb.deleteCharAt(codeListSb.length() - 1);
									String iqCodes = codeListSb.toString();
									//报关单表体,报关单第九位0=出口1=进口
									sql = "select ENTRY_ID,G_NO,CODE_TS,G_NAME,QTY_1,RMB_PRICE,USD_PRICE,G_MODEL,G_CERT_FLAG," +
											"(select max(a.CREATE_DATE) from ENTRY_WORKFLOW a where a.STEP_ID='80000000' AND l.ENTRY_ID = a.ENTRY_ID) as RELEASE_DATE," +
											"UNGID,UNG_FLAG,UNG_MODEL,UNG_CLASSIFY,UNG_G_NAME,PRODUCT_CHAR_CODE,IQ_CODE " +
											"from ENTRY_LIST l where l.ENTRY_ID in (" + entryIds + ") " +
											"and ((substr(l.ENTRY_ID,9,1) ='0' and (l.IQ_CODE in (" + iqCodes + ") or l.UNGID is not null " +
											"or l.PRODUCT_CHAR_CODE like '%31%' or l.PRODUCT_CHAR_CODE like '%32%')) or " +
											"(substr(l.ENTRY_ID,9,1) = '1' and (l.UNGID is not null or l.PRODUCT_CHAR_CODE like '%31%' or l.PRODUCT_CHAR_CODE like '%32%')));";
									List<Object[]> codeTsList = (List<Object[]>) h2018Dao.getQueryBySql(sql);
									if (null != codeTsList && codeTsList.size() > 0) {
										//由于新组合查询不设定某个固定节点更新数据，会存在相同报关单在后面更新流程节点时间，所以先从中间表查出数据进行更新
										//会存在商品金额为空的情况，如果只有一条商品并商品为空则报关单头要删除
										EntryList entity = null;
										for (Object[] codeTs : codeTsList) {//将根据报关单编号查询到的商品编号及报关单号添加到KPI_ENTRY_HEAD_NEW_COPY表里
											entity = new EntryList();
											entity.setEntryId(codeTs[0] != null ? codeTs[0].toString() : "");
											entity.setGNo(codeTs[1] != null ? (BigDecimal) codeTs[1] : new BigDecimal(0));
											entity.setCodeTs(codeTs[2] != null ? codeTs[2].toString() : "");
											entity.setGName(codeTs[3] != null ? codeTs[3].toString() : "");
											entity.setQty1(codeTs[4] != null ? (BigDecimal) codeTs[4] : new BigDecimal(0));
											entity.setRmbPrice(codeTs[5] != null ? (BigDecimal) codeTs[5] : new BigDecimal(0));
											entity.setUsdPrice(codeTs[6] != null ? (BigDecimal) codeTs[6] : new BigDecimal(0));
											entity.setGModel(codeTs[7] != null ? codeTs[7].toString() : "");
											entity.setGCertFlag(codeTs[8] != null ? codeTs[8].toString() : "");
											entity.setReleaseDate(codeTs[9] != null ? (Date) codeTs[9] : null);
											entity.setCodeTsShort(codeTs[2] != null ? codeTs[2].toString().substring(0, 6) : "");
											entity.setUngid(codeTs[10] != null ? codeTs[10].toString() : "");
											entity.setUngFlag(codeTs[11] != null ? codeTs[11].toString() : "");
											entity.setUngModel(codeTs[12] != null ? codeTs[12].toString() : "");
											entity.setUngClassify(codeTs[13] != null ? codeTs[13].toString() : "");
											entity.setUngGName(codeTs[14] != null ? codeTs[14].toString() : "");
											entity.setIqCode(codeTs[16] != null ? codeTs[16].toString() : "");
											//货物属性，判断货物属性是否是31/散装危险化学品，32/件装危险化学品
											String goods_attr = "";
											if (codeTs[15] != null) {
												goods_attr = (String) codeTs[15];
												if (goods_attr.contains("31")) {
													goods_attr = "31";
												} else if (goods_attr.contains("32")) {
													goods_attr = "32";
												} else {
													goods_attr = "";
												}
											}
											entity.setProductCharCode(goods_attr);
											//查出的数据可能存在ciqCode或者UNGID为空的情况,报关单第九位0=出口1=进口
											//出口按ciq编码、ungid不为空和货物属性包含31或32
											//进口按ungid不为空或货物属性
											String ieFlag = codeTs[0] != null ? codeTs[0].toString().substring(8, 9) : "";
											//货物属性为不空时可以初步判定该商品是危化品，接下来只需判断该商品是否还包含危险货物的属性
											if (entity.getProductCharCode() != null && !"".equals(entity.getProductCharCode())) {
												if (codeTs[10] != null) {
													entity.setGoodsType("1,2,3");
												} else {
													entity.setGoodsType("1");
												}
											} else {
												//货物属性为空时
												//出口
												if (ieFlag.equals("0")) {
													if (codeTs[16] != null) {
														//syncChemicalsCiq只可能是包含了危化品,因为这个表的数据就是查询的系统中危险品模块里用户已经维护的包含了危化品的数据
														Object[] obj = (Object[]) iedgRepository.getObjectBySql("select * from iedg_sync_chemicals_ciq where CIQ_CODE = ?", (String) codeTs[16]);
														if (obj != null) {
															if (codeTs[16] != null) {
																entity.setGoodsType("1,2,3");
															} else {
																entity.setGoodsType("1");
															}
														} else {
															entity.setGoodsType("2");
														}
													} else {
														entity.setGoodsType("2");
													}
												} else {
													//进口
													entity.setGoodsType("2");
												}
											}
											entity.setId(dao.getGuidStringBySql());
											entryListRepository.save(entity);
										}
									}
									codeListSb.delete(0, codeListSb.length());
								}
								x++;
							}
						} catch (Exception ex) {
							// 主键可能因为多次结关跨天，导致新纪录主键重复
							logger.error("保存危险品新维度一体化通关中间记录失败，重新保存");
							dao.executeUpdate("delete from WXJY_ENTRY_LIST where ENTRY_ID in (" + entryIds + ")");
						}
						tmpMap1.clear();
						tmpMap2.clear();
						tmpMap9.clear();
						tmpMap10.clear();
						tmpMap12.clear();
						tmpMap11.clear();
						sb.delete(0, sb.length());
					}
					i++;
				}
			}
		}
	}

	public void monthlyDataMaintance(String dataPeriod, Date statBegin, Date statEnd) {
		try {
			// 查询当月转关单两个时间不为空的入境转关单信息
			List<Object[]> entryList = (List<Object[]>) dao.getQueryBySql("select DECL_PORT,i_e_flag,CHECK_FLAG,ORDER_RECEIVE_DATE,TOTAL_COST,CU_COST from WXJY_ENTRY_HEAD where RELEASE_DATE >= ? and RELEASE_DATE < ?",
					statBegin, statEnd);
			// 维护CustomMonthlyStat 表1
			mainCustomMonthlyStat(dataPeriod, statBegin, statEnd, entryList);
		} catch (Exception e) {
			logger.error(dataPeriod + " 月通关时长月度统计中间数据维护错误：", e);
		}
	}

	private void mainCustomMonthlyStat(String dataPeriod, Date statBegin, Date statEnd,
									   List<Object[]> entryList) {
		Object[] mainRcd = (Object[]) dao.getObjectBySql(
				"select * from WXJY_MID_D_M_STATUS where DATA_TYPE = ? and STAT_PERIOD = ?", CustomMonthlyStat.class.getSimpleName(), dataPeriod);
		if (mainRcd == null) {
			dao.executeUpdate("delete from WXJY_CUSTOM_M_STAT where month = ?", dataPeriod);// 以往维护过程中可能出错生成了部分数据
			dao.executeUpdate("delete from WXJY_CUSTOM_M_STAT_F where month = ?", dataPeriod);

			Set<String> customCodeSet = new HashSet<String>();

			Map<String, Integer> impDeclCountMap = new HashMap<String, Integer>();
			Map<String, Integer> impManDeclCountMap = new HashMap<String, Integer>();
			Map<String, Integer> impAuditDeclCountMap = new HashMap<String, Integer>();
			Map<String, Long> impTotalCostMap = new HashMap<String, Long>();
			Map<String, Long> impHgCostMap = new HashMap<String, Long>();
			Map<String, Integer> expDeclCountMap = new HashMap<String, Integer>();
			Map<String, Integer> expManDeclCountMap = new HashMap<String, Integer>();
			Map<String, Integer> expAuditDeclCountMap = new HashMap<String, Integer>();
			Map<String, Long> expTotalCostMap = new HashMap<String, Long>();
			Map<String, Long> expHgCostMap = new HashMap<String, Long>();

			for (Object[] e : entryList) {
				String customCode = (String) e[0];
				customCodeSet.add(customCode);
				String ieFlag = (String) e[1];
				String checkFlag = (String) e[2];
				Date orderReceiveDate = (Date) e[3];
				Long totalCost = ((BigDecimal) e[4]).longValue();
				Long hgCost = ((BigDecimal) e[5]).longValue();

				if ("I".equals(ieFlag)) {// 入境
					Integer impCount = impDeclCountMap.get(customCode);
					if (impCount == null) {
						impCount = 1;
					} else {
						impCount++;
					}
					impDeclCountMap.put(customCode, impCount);

					Integer impManCount = impManDeclCountMap.get(customCode);
					if (impManCount == null && checkFlag.equals("0")) {
						impManCount = 1;
					} else {
						if (checkFlag.equals("0")) {
							impManCount++;
						}
					}
					impManDeclCountMap.put(customCode, impManCount);

					Integer impAuditCount = impAuditDeclCountMap.get(customCode);
					if (impAuditCount == null && orderReceiveDate != null) {
						impAuditCount = 1;
					} else {
						if (orderReceiveDate != null) {
							impAuditCount++;
						}
					}
					impAuditDeclCountMap.put(customCode, impAuditCount);

					Long sumTotalCost = impTotalCostMap.get(customCode);
					if (sumTotalCost == null) {
						sumTotalCost = totalCost;
					} else {
						sumTotalCost += totalCost;
					}
					impTotalCostMap.put(customCode, sumTotalCost);

					Long sumHgCost = impHgCostMap.get(customCode);
					if (sumHgCost == null) {
						sumHgCost = hgCost;
					} else {
						sumHgCost += hgCost;
					}
					impHgCostMap.put(customCode, sumHgCost);

				} else {// 出境
					Integer expCount = expDeclCountMap.get(customCode);
					if (expCount == null) {
						expCount = 1;
					} else {
						expCount++;
					}
					expDeclCountMap.put(customCode, expCount);

					Integer expManCount = expManDeclCountMap.get(customCode);
					if (expManCount == null && checkFlag.equals("0")) {
						expManCount = 1;
					} else {
						if (checkFlag.equals("0")) {
							expManCount++;
						}
					}
					expManDeclCountMap.put(customCode, expManCount);

					Integer expAuditCount = expAuditDeclCountMap.get(customCode);
					if (expAuditCount == null && orderReceiveDate != null) {
						expAuditCount = 1;
					} else {
						if (orderReceiveDate != null) {
							expAuditCount++;
						}
					}
					expAuditDeclCountMap.put(customCode, expAuditCount);

					Long sumTotalCost = expTotalCostMap.get(customCode);
					if (sumTotalCost == null) {
						sumTotalCost = totalCost;
					} else {
						sumTotalCost += totalCost;
					}
					expTotalCostMap.put(customCode, sumTotalCost);

					Long sumHgCost = expHgCostMap.get(customCode);
					if (sumHgCost == null) {
						sumHgCost = hgCost;
					} else {
						sumHgCost += hgCost;
					}
					expHgCostMap.put(customCode, sumHgCost);
				}

			}

			BigDecimal impTotalCost = new BigDecimal(0);
			BigDecimal impHgCost = new BigDecimal(0);
			BigDecimal expTotalCost = new BigDecimal(0);
			BigDecimal expHgCost = new BigDecimal(0);

			// 当年各平均值为每个月单量x每个月对应时间累加后，除以总单量
			Map<String, BigDecimal> impCurYearTotalCostMap = new HashMap<String, BigDecimal>();
			Map<String, BigDecimal> impCurYearHgCostMap = new HashMap<String, BigDecimal>();
			Map<String, BigDecimal> impLastMonthTotalCostMap = new HashMap<String, BigDecimal>();
			Map<String, BigDecimal> impLastMonthHgCostMap = new HashMap<String, BigDecimal>();
			Map<String, BigDecimal> impLastYearDecemberTotalCostMap = new HashMap<String, BigDecimal>();
			Map<String, BigDecimal> impLastYearDecemberHgCostMap = new HashMap<String, BigDecimal>();
			Map<String, BigDecimal> impYearBeforeLastTotalCostMap = new HashMap<String, BigDecimal>();
			Map<String, BigDecimal> impYearBeforeLastHgCostMap = new HashMap<String, BigDecimal>();

			Map<String, BigDecimal> expCurYearTotalCostMap = new HashMap<String, BigDecimal>();
			Map<String, BigDecimal> expCurYearHgCostMap = new HashMap<String, BigDecimal>();
			Map<String, BigDecimal> expLastMonthTotalCostMap = new HashMap<String, BigDecimal>();
			Map<String, BigDecimal> expLastMonthHgCostMap = new HashMap<String, BigDecimal>();
			Map<String, BigDecimal> expLastYearDecemberTotalCostMap = new HashMap<String, BigDecimal>();
			Map<String, BigDecimal> expLastYearDecemberHgCostMap = new HashMap<String, BigDecimal>();
			Map<String, BigDecimal> expYearBeforeLastTotalCostMap = new HashMap<String, BigDecimal>();
			Map<String, BigDecimal> expYearBeforeLastHgCostMap = new HashMap<String, BigDecimal>();

			Map<String, Integer> impCurYearDeclCountMap = new HashMap<String, Integer>();
			Map<String, Integer> impLastMonthDeclCountMap = new HashMap<String, Integer>();
			Map<String, Integer> impLastYearDecemberDeclCountMap = new HashMap<String, Integer>();
			Map<String, Integer> impYearBeforeLastDeclCountMap = new HashMap<String, Integer>();

			Map<String, Integer> expCurYearDeclCountMap = new HashMap<String, Integer>();
			Map<String, Integer> expLastMonthDeclCountMap = new HashMap<String, Integer>();
			Map<String, Integer> expLastYearDecemberDeclCountMap = new HashMap<String, Integer>();
			Map<String, Integer> expYearBeforeLastDeclCountMap = new HashMap<String, Integer>();

			if (dataPeriod.compareTo(noRelStatMonth) > 0) {
				if (!dataPeriod.endsWith("01")) {
					int sumImpDeclCount = 0;
					int sumExpDeclCount = 0;
					BigDecimal sumImpCurYearTotalCost = new BigDecimal(0);
					BigDecimal sumImpCurYearHgCost = new BigDecimal(0);
					BigDecimal sumExpCurYearTotalCost = new BigDecimal(0);
					BigDecimal sumExpCurYearHgCost = new BigDecimal(0);

					String indexCustCode = null;
					String year = dataPeriod.substring(0, 4);
					List<Object[]> curYearlist = (List<Object[]>) dao.getQueryBySql(
							"select MONTH,CUSTOM_CODE,IMP_DECL_COUNT,IMP_MAN_DECL_COUNT,IMP_MANUAL_AUDIT_DECL_COUNT,IMP_DECL_COUNT_LM,IMP_DECL_COUNT_LY_DEC," +
									"IMP_DECL_COUNT_CURYEAR,IMP_DECL_COUNT_YBL,IMP_TOTAL_COST,IMP_TOTAL_COST_LM,IMP_TOTAL_COST_LY_DEC,IMP_TOTAL_COST_CY,IMP_TOTAL_COST_YBL," +
									"IMP_CU_COST,IMP_CU_COST_LM,IMP_CU_COST_LY_DEC,IMP_CU_COST_CY,IMP_CU_COST_YBL,EXP_DECL_COUNT,EXP_MAN_DECL_COUNT,EXP_MANUAL_AUDIT_DECL_COUNT," +
									"EXP_DECL_COUNT_LM,EXP_DECL_COUNT_LY_DEC,EXP_DECL_COUNT_CURYEAR,EXP_DECL_COUNT_YBL,EXP_TOTAL_COST,EXP_TOTAL_COST_LM,EXP_TOTAL_COST_LY_DEC," +
									"EXP_TOTAL_COST_CY,EXP_TOTAL_COST_YBL,EXP_CU_COST,EXP_CU_COST_LM,EXP_CU_COST_LY_DEC,EXP_CU_COST_CY,EXP_CU_COST_YBL " +
									"from WXJY_CUSTOM_M_STAT where month >= ? and month < ? order by CUSTOM_CODE", year + "01", dataPeriod);
					for (int i = 0; i < curYearlist.size(); i++) {
						Object[] s = curYearlist.get(i);
						String custCode = (String) s[0];
						int impCount = s[2] != null ? ((BigDecimal) s[2]).intValue() : 0;
						int expCount = s[19] != null ? ((BigDecimal) s[19]).intValue() : 0;

						BigDecimal impMultily = new BigDecimal(impCount);
						BigDecimal expMultily = new BigDecimal(expCount);
						BigDecimal impTotalCostT = (BigDecimal) s[10];
						BigDecimal impCuCostT = (BigDecimal) s[15];
						BigDecimal expTotalCostT = (BigDecimal) s[27];
						BigDecimal expCuCostT = (BigDecimal) s[32];
						if (indexCustCode == null || indexCustCode.equals(custCode)) {// 同一关区，累计数据
							indexCustCode = custCode;
							sumImpDeclCount += impCount;
							sumExpDeclCount += expCount;
							sumImpCurYearTotalCost = sumImpCurYearTotalCost.add(impTotalCostT.multiply(impMultily));
							sumImpCurYearHgCost = sumImpCurYearHgCost.add(impCuCostT.multiply(impMultily));
							sumExpCurYearTotalCost = sumExpCurYearTotalCost.add(expTotalCostT.multiply(expMultily));
							sumExpCurYearHgCost = sumExpCurYearHgCost.add(expCuCostT.multiply(expMultily));
						} else {// 切换关区
							if (sumImpDeclCount != 0) {
								BigDecimal impDivide = new BigDecimal(sumImpDeclCount);
								impCurYearTotalCostMap.put(indexCustCode,
										sumImpCurYearTotalCost.divide(impDivide, 4, BigDecimal.ROUND_HALF_UP));
								impCurYearHgCostMap.put(indexCustCode, sumImpCurYearHgCost.divide(impDivide, 4, BigDecimal.ROUND_HALF_UP));
							} else {
								impCurYearTotalCostMap.put(indexCustCode, zero);
								impCurYearHgCostMap.put(indexCustCode, zero);
							}
							if (sumExpDeclCount != 0) {
								BigDecimal expDivide = new BigDecimal(sumExpDeclCount);
								expCurYearTotalCostMap.put(indexCustCode,
										sumExpCurYearTotalCost.divide(expDivide, 4, BigDecimal.ROUND_HALF_UP));
								expCurYearHgCostMap.put(indexCustCode, sumExpCurYearHgCost.divide(expDivide, 4, BigDecimal.ROUND_HALF_UP));
							} else {
								expCurYearTotalCostMap.put(indexCustCode, zero);
								expCurYearHgCostMap.put(indexCustCode, zero);
							}
							impCurYearDeclCountMap.put(indexCustCode, sumImpDeclCount);
							expCurYearDeclCountMap.put(indexCustCode, sumExpDeclCount);

							sumImpDeclCount = impCount;
							sumExpDeclCount = expCount;
							sumImpCurYearTotalCost = new BigDecimal(0);
							sumImpCurYearHgCost = new BigDecimal(0);
							sumExpCurYearTotalCost = new BigDecimal(0);
							sumExpCurYearHgCost = new BigDecimal(0);
							indexCustCode = custCode;
							sumImpCurYearTotalCost = sumImpCurYearTotalCost.add(impTotalCostT.multiply(impMultily));
							sumImpCurYearHgCost = sumImpCurYearHgCost.add(impCuCostT.multiply(impMultily));
							sumExpCurYearTotalCost = sumExpCurYearTotalCost.add(expTotalCostT.multiply(expMultily));
							sumExpCurYearHgCost = sumExpCurYearHgCost.add(expCuCostT.multiply(expMultily));
						}
						if (i == curYearlist.size() - 1) {// 最后一条记录
							BigDecimal impDivide = new BigDecimal(sumImpDeclCount);
							BigDecimal expDivide = new BigDecimal(sumExpDeclCount);
							if (sumImpDeclCount != 0) {
								impCurYearTotalCostMap.put(indexCustCode,
										sumImpCurYearTotalCost.divide(impDivide, 4, BigDecimal.ROUND_HALF_UP));
								impCurYearHgCostMap.put(indexCustCode, sumImpCurYearHgCost.divide(impDivide, 4, BigDecimal.ROUND_HALF_UP));
							} else {
								impCurYearTotalCostMap.put(indexCustCode, zero);
								impCurYearHgCostMap.put(indexCustCode, zero);
							}
							if (sumExpDeclCount != 0) {
								expCurYearTotalCostMap.put(indexCustCode,
										sumExpCurYearTotalCost.divide(expDivide, 4, BigDecimal.ROUND_HALF_UP));
								expCurYearHgCostMap.put(indexCustCode, sumExpCurYearHgCost.divide(expDivide, 4, BigDecimal.ROUND_HALF_UP));
							} else {
								expCurYearTotalCostMap.put(indexCustCode, zero);
								expCurYearHgCostMap.put(indexCustCode, zero);
							}
						}
					}
				}

				// 先查询到上个月的数据备用
				Date curMonth = null;
				try {
					curMonth = monthSdf.parse(dataPeriod);
				} catch (ParseException e1) {
				}
				Calendar cal = Calendar.getInstance();
				cal.setTime(curMonth);
				cal.add(Calendar.MONTH, -1);
				Date lastMonthDate = cal.getTime();
				String lastMonthStr = monthSdf.format(lastMonthDate);
				List<Object[]> lastMonthData = (List<Object[]>) dao.getQueryBySql(
						"select CUSTOM_CODE,IMP_DECL_COUNT,IMP_TOTAL_COST,IMP_CU_COST,EXP_DECL_COUNT,EXP_TOTAL_COST,EXP_CU_COST " +
								"from WXJY_CUSTOM_M_STAT where month = ? ", lastMonthStr);
				for (Object[] s : lastMonthData) {
					String customCode = (String) s[0];
					Integer impDeclCount = Integer.valueOf(((BigDecimal) s[1]).toString());
					BigDecimal impTotalCostT = (BigDecimal) s[2];
					BigDecimal impCuCostT = (BigDecimal) s[3];
					Integer expDeclCount = Integer.valueOf(((BigDecimal) s[4]).toString());
					BigDecimal expTotalCostT = (BigDecimal) s[5];
					BigDecimal expCuCostT = (BigDecimal) s[6];
					impLastMonthTotalCostMap.put(customCode, impTotalCostT);
					impLastMonthHgCostMap.put(customCode, impCuCostT);
					expLastMonthTotalCostMap.put(customCode, expTotalCostT);
					expLastMonthHgCostMap.put(customCode, expCuCostT);

					impLastMonthDeclCountMap.put(customCode, impDeclCount);
					expLastMonthDeclCountMap.put(customCode, expDeclCount);
				}

				// 去年12月数据
				cal.setTime(curMonth);
				cal.add(Calendar.YEAR, -1);
				String lastDecember = yearSdf.format(cal.getTime()) + "12";
				List<Object[]> lastDecData = (List<Object[]>) dao.getQueryBySql(
						"select CUSTOM_CODE,IMP_DECL_COUNT,IMP_TOTAL_COST,IMP_CU_COST,EXP_DECL_COUNT,EXP_TOTAL_COST,EXP_CU_COST " +
								"from WXJY_CUSTOM_M_STAT where month = ? ", lastDecember);
				for (Object[] s : lastDecData) {
					String customCode = (String) s[0];
					Integer impDeclCount = Integer.valueOf(((BigDecimal) s[1]).toString());
					BigDecimal impTotalCostT = (BigDecimal) s[2];
					BigDecimal impCuCostT = (BigDecimal) s[3];
					Integer expDeclCount = Integer.valueOf(((BigDecimal) s[4]).toString());
					BigDecimal expTotalCostT = (BigDecimal) s[5];
					BigDecimal expCuCostT = (BigDecimal) s[6];
					impLastYearDecemberTotalCostMap.put(customCode, impTotalCostT);
					impLastYearDecemberHgCostMap.put(customCode, impCuCostT);
					expLastYearDecemberTotalCostMap.put(customCode, expTotalCostT);
					expLastYearDecemberHgCostMap.put(customCode, expCuCostT);

					impLastYearDecemberDeclCountMap.put(customCode, impDeclCount);
					expLastYearDecemberDeclCountMap.put(customCode, expDeclCount);
				}

				boolean existData = false;
				if (!existData) {
					cal.setTime(curMonth);
					cal.add(Calendar.YEAR, -2);
					String yearBeforeLast = yearSdf.format(cal.getTime());
					String firstMonthOfYearBeforeLast = yearBeforeLast + "01";
					String lastMonthOfYearBeforeLast = yearBeforeLast + "12";
					List<Object[]> list = (List<Object[]>) dao.getQueryBySql(
							"select CUSTOM_CODE,IMP_DECL_COUNT,IMP_TOTAL_COST,IMP_CU_COST,EXP_DECL_COUNT,EXP_TOTAL_COST,EXP_CU_COST " +
									"from WXJY_CUSTOM_M_STAT where month >= ? and month <= ? order by CUSTOM_CODE", firstMonthOfYearBeforeLast,
							lastMonthOfYearBeforeLast);
					if (list.size() > 0) {
						int sumImpDeclCount = 0;
						int sumExpDeclCount = 0;
						BigDecimal sumImpYearBeforeLastTotalCost = new BigDecimal(0);
						BigDecimal sumImpYearBeforeLastHgCost = new BigDecimal(0);
						BigDecimal sumExpYearBeforeLastTotalCost = new BigDecimal(0);
						BigDecimal sumExpYearBeforeLastHgCost = new BigDecimal(0);
						String indexCustCode = null;
						for (int j = 0; j < list.size(); j++) {
							Object[] s = list.get(j);
							String custCode = (String) s[0];
							Integer impCount = Integer.valueOf(((BigDecimal) s[1]).toString());
							BigDecimal impTotalCostT = (BigDecimal) s[2];
							BigDecimal impCuCostT = (BigDecimal) s[3];
							Integer expCount = Integer.valueOf(((BigDecimal) s[4]).toString());
							BigDecimal expTotalCostT = (BigDecimal) s[5];
							BigDecimal expCuCostT = (BigDecimal) s[6];

							BigDecimal impMultily = new BigDecimal(impCount);
							BigDecimal expMultily = new BigDecimal(expCount);
							if (indexCustCode == null || indexCustCode.equals(custCode)) {// 同一关区，累计数据
								indexCustCode = custCode;
								sumImpDeclCount += impCount;
								sumExpDeclCount += expCount;

								sumImpYearBeforeLastTotalCost = sumImpYearBeforeLastTotalCost.add(impTotalCostT.multiply(impMultily));
								sumImpYearBeforeLastHgCost = sumImpYearBeforeLastHgCost.add(impCuCostT.multiply(impMultily));
								sumExpYearBeforeLastTotalCost = sumExpYearBeforeLastTotalCost.add(expTotalCostT.multiply(expMultily));
								sumExpYearBeforeLastHgCost = sumExpYearBeforeLastHgCost.add(expCuCostT.multiply(expMultily));
							} else {// 切换关区
								BigDecimal impDivide = new BigDecimal(sumImpDeclCount);
								BigDecimal expDivide = new BigDecimal(sumExpDeclCount);
								if (sumImpDeclCount != 0) {
									impYearBeforeLastTotalCostMap.put(indexCustCode,
											sumImpYearBeforeLastTotalCost.divide(impDivide, 4, BigDecimal.ROUND_HALF_UP));
									impYearBeforeLastHgCostMap.put(indexCustCode,
											sumImpYearBeforeLastHgCost.divide(impDivide, 4, BigDecimal.ROUND_HALF_UP));
								} else {
									impYearBeforeLastTotalCostMap.put(indexCustCode, zero);
									impYearBeforeLastHgCostMap.put(indexCustCode, zero);
								}
								if (sumExpDeclCount != 0) {
									expYearBeforeLastTotalCostMap.put(indexCustCode,
											sumExpYearBeforeLastTotalCost.divide(expDivide, 4, BigDecimal.ROUND_HALF_UP));
									expYearBeforeLastHgCostMap.put(indexCustCode,
											sumExpYearBeforeLastHgCost.divide(expDivide, 4, BigDecimal.ROUND_HALF_UP));
								} else {
									expYearBeforeLastTotalCostMap.put(indexCustCode, zero);
									expYearBeforeLastHgCostMap.put(indexCustCode, zero);
								}
								impYearBeforeLastDeclCountMap.put(indexCustCode, sumImpDeclCount);
								expYearBeforeLastDeclCountMap.put(indexCustCode, sumExpDeclCount);

								sumImpDeclCount = impCount;
								sumExpDeclCount = expCount;
								sumImpYearBeforeLastTotalCost = new BigDecimal(0);
								sumImpYearBeforeLastHgCost = new BigDecimal(0);
								sumExpYearBeforeLastTotalCost = new BigDecimal(0);
								sumExpYearBeforeLastHgCost = new BigDecimal(0);
								indexCustCode = custCode;
								sumImpYearBeforeLastTotalCost = sumImpYearBeforeLastTotalCost.add(impTotalCostT.multiply(impMultily));
								sumImpYearBeforeLastHgCost = sumImpYearBeforeLastHgCost.add(impCuCostT.multiply(impMultily));
								sumExpYearBeforeLastTotalCost = sumExpYearBeforeLastTotalCost.add(expTotalCostT.multiply(expMultily));
								sumExpYearBeforeLastHgCost = sumExpYearBeforeLastHgCost.add(expCuCostT.multiply(expMultily));
							}
							if (j == list.size() - 1) {// 最后一条记录
								BigDecimal impDivide = new BigDecimal(sumImpDeclCount);
								BigDecimal expDivide = new BigDecimal(sumExpDeclCount);
								if (sumImpDeclCount != 0) {
									impYearBeforeLastTotalCostMap.put(indexCustCode,
											sumImpYearBeforeLastTotalCost.divide(impDivide, 4, BigDecimal.ROUND_HALF_UP));
									impYearBeforeLastHgCostMap.put(indexCustCode,
											sumImpYearBeforeLastHgCost.divide(impDivide, 4, BigDecimal.ROUND_HALF_UP));
								} else {
									impYearBeforeLastTotalCostMap.put(indexCustCode, zero);
									impYearBeforeLastHgCostMap.put(indexCustCode, zero);
								}
								if (sumExpDeclCount != 0) {
									expYearBeforeLastTotalCostMap.put(indexCustCode,
											sumExpYearBeforeLastTotalCost.divide(expDivide, 4, BigDecimal.ROUND_HALF_UP));
									expYearBeforeLastHgCostMap.put(indexCustCode,
											sumExpYearBeforeLastHgCost.divide(expDivide, 4, BigDecimal.ROUND_HALF_UP));
								} else {
									expYearBeforeLastTotalCostMap.put(indexCustCode, zero);
									expYearBeforeLastHgCostMap.put(indexCustCode, zero);
								}
								impYearBeforeLastDeclCountMap.put(indexCustCode, sumImpDeclCount);
								expYearBeforeLastDeclCountMap.put(indexCustCode, sumExpDeclCount);
							}
						}
					}
				}
			}

			for (String customCode : customCodeSet) {
				CustomMonthlyStat stat = new CustomMonthlyStat();
				stat.setCustomCode(customCode);
				stat.setMonth(dataPeriod);

				Integer impCount = impDeclCountMap.get(customCode);
				if (impCount != null) {
					stat.setImpDeclCount(impCount);
					BigDecimal impDeclDiv = new BigDecimal(impCount * 3600);// 每单耗时x小时

					BigDecimal sumImpTotalCost = new BigDecimal(impTotalCostMap.get(customCode));
					impTotalCost = sumImpTotalCost.divide(impDeclDiv, 4, BigDecimal.ROUND_HALF_UP);
					stat.setImpTotalCost(impTotalCost);

					BigDecimal sumImpHgCost = new BigDecimal(impHgCostMap.get(customCode));
					impHgCost = sumImpHgCost.divide(impDeclDiv, 4, BigDecimal.ROUND_HALF_UP);
					stat.setImpCuCost(impHgCost);
				} else {
					stat.setImpDeclCount(0);
					stat.setImpTotalCost(zero);
					stat.setImpCuCost(zero);
				}
				Integer impManCount = impManDeclCountMap.get(customCode);
				if (impManCount != null) {
					stat.setImpManDeclCount(impManCount);
				} else {
					stat.setImpManDeclCount(0);
				}
				Integer impAuditCount = impAuditDeclCountMap.get(customCode);
				if (impAuditCount != null) {
					stat.setImpManualAuditDeclCount(impAuditCount);
				} else {
					stat.setImpManualAuditDeclCount(0);
				}
				Integer expCount = expDeclCountMap.get(customCode);
				if (expCount != null) {
					stat.setExpDeclCount(expCount);
					BigDecimal expDeclDiv = new BigDecimal(expCount * 3600);// 每单耗时x小时

					BigDecimal sumExpTotalCost = new BigDecimal(expTotalCostMap.get(customCode));
					expTotalCost = sumExpTotalCost.divide(expDeclDiv, 4, BigDecimal.ROUND_HALF_UP);
					stat.setExpTotalCost(expTotalCost);

					BigDecimal sumExpHgCost = new BigDecimal(expHgCostMap.get(customCode));
					expHgCost = sumExpHgCost.divide(expDeclDiv, 4, BigDecimal.ROUND_HALF_UP);
					stat.setExpCuCost(expHgCost);
				} else {
					stat.setExpDeclCount(0);
					stat.setExpTotalCost(zero);
					stat.setExpCuCost(zero);
				}
				Integer expManCount = expManDeclCountMap.get(customCode);
				if (expManCount != null) {
					stat.setExpManDeclCount(expManCount);
				} else {
					stat.setExpManDeclCount(0);
				}
				Integer expAuditCount = expAuditDeclCountMap.get(customCode);
				if (expAuditCount != null) {
					stat.setExpManualAuditDeclCount(expAuditCount);
				} else {
					stat.setExpManualAuditDeclCount(0);
				}
				if (dataPeriod.compareTo(noRelStatMonth) > 0) {
					if (dataPeriod.endsWith("01")) {
						stat.setImpTotalCostCurentYear(impTotalCost);
						stat.setImpCuCostCurentYear(impHgCost);
						stat.setExpTotalCostCurentYear(expTotalCost);
						stat.setExpCuCostCurentYear(expHgCost);

						stat.setImpDeclCountCurentYear(stat.getImpDeclCount());
						stat.setExpDeclCountCurentYear(stat.getExpDeclCount());
					} else {// 另外查询当年前面月份数据来计算
						if (impCount == null) { // 当月进口报单量为0
							stat.setImpTotalCostCurentYear(
									impCurYearTotalCostMap.get(customCode) != null ? impCurYearTotalCostMap.get(customCode) : zero);
							stat.setImpCuCostCurentYear(
									impCurYearHgCostMap.get(customCode) != null ? impCurYearHgCostMap.get(customCode) : zero);
							stat.setImpDeclCountCurentYear(
									impCurYearDeclCountMap.get(customCode) != null ? impCurYearDeclCountMap.get(customCode) : 0);
						} else { // 累计前面月份和当月
							Integer impCurYearDeclCount = impCurYearDeclCountMap.get(customCode);
							if (impCurYearDeclCount == null) { // 对应关区当年前面月份入境报单量为0
								stat.setImpTotalCostCurentYear(impTotalCost);
								stat.setImpCuCostCurentYear(impHgCost);
								stat.setImpDeclCountCurentYear(stat.getImpDeclCount());
							} else {
								BigDecimal impCurYearTotalCost = impCurYearTotalCostMap.get(customCode);
								if (impCurYearTotalCost != null) {
									impCurYearTotalCost = impCurYearTotalCost.multiply(new BigDecimal(impCurYearDeclCount))
											.add(impTotalCost)
											.divide(new BigDecimal(impCurYearDeclCount + impCount), 4, BigDecimal.ROUND_HALF_UP);
									stat.setImpTotalCostCurentYear(impCurYearTotalCost);
								} else {
									stat.setImpTotalCostCurentYear(impTotalCost);
								}
								BigDecimal impCurYearCuCost = impCurYearHgCostMap.get(customCode);
								if (impCurYearCuCost != null) {
									impCurYearCuCost = impCurYearCuCost.multiply(new BigDecimal(impCurYearDeclCount)).add(impHgCost)
											.divide(new BigDecimal(impCurYearDeclCount + impCount), 4, BigDecimal.ROUND_HALF_UP);
									stat.setImpCuCostCurentYear(impCurYearCuCost);
								} else {
									stat.setImpCuCostCurentYear(impHgCost);
								}
								stat.setImpDeclCountCurentYear(impCurYearDeclCount + impCount);
							}
						}

						if (expCount == null) {
							stat.setExpTotalCostCurentYear(
									expCurYearTotalCostMap.get(customCode) != null ? expCurYearTotalCostMap.get(customCode) : zero);
							stat.setExpCuCostCurentYear(
									expCurYearHgCostMap.get(customCode) != null ? expCurYearHgCostMap.get(customCode) : zero);
							stat.setExpDeclCountCurentYear(
									expCurYearDeclCountMap.get(customCode) != null ? expCurYearDeclCountMap.get(customCode) : 0);
						} else {
							Integer expCurYearDeclCount = expCurYearDeclCountMap.get(customCode);
							if (expCurYearDeclCount == null) {
								stat.setExpTotalCostCurentYear(expTotalCost);
								stat.setExpCuCostCurentYear(expHgCost);
								stat.setExpDeclCountCurentYear(stat.getExpDeclCount());
							} else {
								BigDecimal expCurYearTotalCost = expCurYearTotalCostMap.get(customCode);
								if (expCurYearTotalCost != null) {
									expCurYearTotalCost = expCurYearTotalCost.multiply(new BigDecimal(expCurYearDeclCount))
											.add(expTotalCost)
											.divide(new BigDecimal(expCurYearDeclCount + expCount), 4, BigDecimal.ROUND_HALF_UP);
									stat.setExpTotalCostCurentYear(expCurYearTotalCost);
								} else {
									stat.setExpTotalCostCurentYear(expTotalCost);
								}
								BigDecimal expCurYearCuCost = expCurYearHgCostMap.get(customCode);
								if (expCurYearCuCost != null) {
									expCurYearCuCost = expCurYearCuCost.multiply(new BigDecimal(expCurYearDeclCount)).add(expHgCost)
											.divide(new BigDecimal(expCurYearDeclCount + expCount), 4, BigDecimal.ROUND_HALF_UP);
									stat.setExpCuCostCurentYear(expCurYearCuCost);
								} else {
									stat.setExpCuCostCurentYear(expHgCost);
								}
								stat.setExpDeclCountCurentYear(expCurYearDeclCount + expCount);
							}
						}
					}

					stat.setImpTotalCostLastMonth(
							impLastMonthTotalCostMap.get(customCode) != null ? impLastMonthTotalCostMap.get(customCode) : zero);
					stat.setImpTotalCostLastYearDecember(
							impLastYearDecemberTotalCostMap.get(customCode) != null ? impLastYearDecemberTotalCostMap.get(customCode)
									: zero);
					stat.setImpTotalCostYearBeforeLast(
							impYearBeforeLastTotalCostMap.get(customCode) != null ? impYearBeforeLastTotalCostMap.get(customCode) : zero);
					stat.setImpCuCostLastMonth(
							impLastMonthHgCostMap.get(customCode) != null ? impLastMonthHgCostMap.get(customCode) : zero);
					stat.setImpCuCostLastYearDecember(
							impLastYearDecemberHgCostMap.get(customCode) != null ? impLastYearDecemberHgCostMap.get(customCode) : zero);
					stat.setImpCuCostYearBeforeLast(
							impYearBeforeLastHgCostMap.get(customCode) != null ? impYearBeforeLastHgCostMap.get(customCode) : zero);

					stat.setExpTotalCostLastMonth(
							expLastMonthTotalCostMap.get(customCode) != null ? expLastMonthTotalCostMap.get(customCode) : zero);
					stat.setExpTotalCostLastYearDecember(
							expLastYearDecemberTotalCostMap.get(customCode) != null ? expLastYearDecemberTotalCostMap.get(customCode)
									: zero);
					stat.setExpTotalCostYearBeforeLast(
							expYearBeforeLastTotalCostMap.get(customCode) != null ? expYearBeforeLastTotalCostMap.get(customCode) : zero);
					stat.setExpCuCostLastMonth(
							expLastMonthHgCostMap.get(customCode) != null ? expLastMonthHgCostMap.get(customCode) : zero);
					stat.setExpCuCostLastYearDecember(
							expLastYearDecemberHgCostMap.get(customCode) != null ? expLastYearDecemberHgCostMap.get(customCode) : zero);
					stat.setExpCuCostYearBeforeLast(
							expYearBeforeLastHgCostMap.get(customCode) != null ? expYearBeforeLastHgCostMap.get(customCode) : zero);

					stat.setImpDeclCountLastMonth(
							impLastMonthDeclCountMap.get(customCode) != null ? impLastMonthDeclCountMap.get(customCode) : 0);
					stat.setImpDeclCountLastYearDecember(
							impLastYearDecemberDeclCountMap.get(customCode) != null ? impLastYearDecemberDeclCountMap.get(customCode) : 0);
					stat.setImpDeclCountYearBeforeLast(
							impYearBeforeLastDeclCountMap.get(customCode) != null ? impYearBeforeLastDeclCountMap.get(customCode) : 0);

					stat.setExpDeclCountLastMonth(
							expLastMonthDeclCountMap.get(customCode) != null ? expLastMonthDeclCountMap.get(customCode) : 0);
					stat.setExpDeclCountLastYearDecember(
							expLastYearDecemberDeclCountMap.get(customCode) != null ? expLastYearDecemberDeclCountMap.get(customCode) : 0);
					stat.setExpDeclCountYearBeforeLast(
							expYearBeforeLastDeclCountMap.get(customCode) != null ? expYearBeforeLastDeclCountMap.get(customCode) : 0);
				}
				stat.setId(dao.getGuidStringBySql());
				customMonthlyStatRepository.save(stat);
			}

			// 20191014 再次维护合并了关区的统计中间数据
			mainCustomMonthlyStatFinal(dataPeriod);

			MiddleDataMainStatus mStatus = new MiddleDataMainStatus();
			mStatus.setCreateTime(new Date());
			mStatus.setDataType(CustomMonthlyStat.class.getSimpleName());
			mStatus.setStatPeriod(dataPeriod);
			dao.executeUpdate("insert into WXJY_MID_D_M_STATUS (ID,DATA_TYPE, STAT_PERIOD, CREATE_TIME) " +
					"values(sys_guid(),?,?,?) ", mStatus.getDataType(), mStatus.getStatPeriod(), mStatus.getCreateTime());
		}
	}


	private void mainCustomMonthlyStatFinal(String dataPeriod) {
		List<Object[]> copyList = new ArrayList<Object[]>();
		List<Object[]> curMonthStat = (List<Object[]>) dao.getQueryBySql("select ID,MONTH,CUSTOM_CODE,IMP_DECL_COUNT,IMP_MAN_DECL_COUNT,IMP_MANUAL_AUDIT_DECL_COUNT,IMP_DECL_COUNT_LM,IMP_DECL_COUNT_LY_DEC," +
						"IMP_DECL_COUNT_CURYEAR,IMP_DECL_COUNT_YBL,IMP_TOTAL_COST,IMP_TOTAL_COST_LM,IMP_TOTAL_COST_LY_DEC,IMP_TOTAL_COST_CY,IMP_TOTAL_COST_YBL," +
						"IMP_CU_COST,IMP_CU_COST_LM,IMP_CU_COST_LY_DEC,IMP_CU_COST_CY,IMP_CU_COST_YBL,EXP_DECL_COUNT,EXP_MAN_DECL_COUNT,EXP_MANUAL_AUDIT_DECL_COUNT," +
						"EXP_DECL_COUNT_LM,EXP_DECL_COUNT_LY_DEC,EXP_DECL_COUNT_CURYEAR,EXP_DECL_COUNT_YBL,EXP_TOTAL_COST,EXP_TOTAL_COST_LM,EXP_TOTAL_COST_LY_DEC," +
						"EXP_TOTAL_COST_CY,EXP_TOTAL_COST_YBL,EXP_CU_COST,EXP_CU_COST_LM,EXP_CU_COST_LY_DEC,EXP_CU_COST_CY,EXP_CU_COST_YBL " +
						"from WXJY_CUSTOM_M_STAT where month = ?",
				dataPeriod);
		for (Object[] s : curMonthStat) {
			String customCode = (String) s[2];
			s[2] = rootCustomsMap.get(customCode);
			copyList.add(s);
		}

		Integer sumImpDeclCount = 0;// 进口单数
		Integer sumImpManDeclCount = 0;// 进口查验单数
		Integer sumImpAuditDeclCount = 0;// 进口人工审单单数
		Integer sumImpDeclCountLastMonth = 0;// 上个月进口单数
		Integer sumImpDeclCountLastYearDecember = 0;// 去年12月进口单数
		Integer sumImpDeclCountCurentYear = 0;// 今年截止当月总进口单数
		Integer sumImpDeclCountYearBeforeLast = 0;// 前年总进口单数
		Integer sumExpDeclCount = 0;// 出口单数
		Integer sumExpManDeclCount = 0;// 出口查验单数
		Integer sumExpAuditDeclCount = 0;// 出口人工审单单数
		Integer sumExpDeclCountLastMonth = 0;// 上个月出口单数
		Integer sumExpDeclCountLastYearDecember = 0;// 去年12月进口单数
		Integer sumExpDeclCountCurentYear = 0;// 今年截止当月总出口单数
		Integer sumExpDeclCountYearBeforeLast = 0;// 前年总出口单数

		// 20个消耗时间字段
		BigDecimal sumImpTotalCost = zero;// 进口平均整体通关时间（小时）
		BigDecimal sumImpTotalCostLastMonth = zero;// 进口平均整体通关时间-上月
		BigDecimal sumImpTotalCostLastYearDecember = zero;// 进口平均整体通关时间-去年12月
		BigDecimal sumImpTotalCostCurentYear = zero;// 进口平均整体通关时间-1至当月
		BigDecimal sumImpTotalCostYearBeforeLast = zero;// 进口平均整体通关时间-前年
		BigDecimal sumImpCuCost = zero;// 进口平均海关通关时间（小时）
		BigDecimal sumImpCuCostLastMonth = zero;// 进口平均海关通关时间（小时）-上月
		BigDecimal sumImpCuCostLastYearDecember = zero;// 进口平均海关通关时间-去年12月
		BigDecimal sumImpCuCostCurentYear = zero;// 进口平均海关通关时间-1至当月
		BigDecimal sumImpCuCostYearBeforeLast = zero;// 进口平均海关通关时间-前年
		BigDecimal sumExpTotalCost = zero;// 出口平均整体通关时间（小时）
		BigDecimal sumExpTotalCostLastMonth = zero;// 出口平均整体通关时间（小时）-上月
		BigDecimal sumExpTotalCostLastYearDecember = zero; // 出口平均整体通关时间-去年12月
		BigDecimal sumExpTotalCostCurentYear = zero;// 出口平均整体通关时间-1至当月
		BigDecimal sumExpTotalCostYearBeforeLast = zero;// 出口平均整体通关时间-前年
		BigDecimal sumExpCuCost = zero;// 出口平均海关通关时间（小时）
		BigDecimal sumExpCuCostLastMonth = zero;// 出口平均海关通关时间（小时）-上月
		BigDecimal sumExpCuCostLastYearDecember = zero;// 出口平均海关通关时间-去年12月
		BigDecimal sumExpCuCostCurentYear = zero;// 出口平均海关通关时间-1至当月
		BigDecimal sumExpCuCostYearBeforeLast = zero;// 出口平均海关通关时间-前年

		for (String customCode : firstClassCustoms) {
			if (!hasMultipleCustomList.contains(customCode)) {// 无下级关区的关区
				boolean existData = false;
				for (Object[] s : copyList) {
					String customCodeT = (String) s[2];
					if (customCode.equals(customCodeT)) {// 找到了既是唯一一条
						CustomMonthlyStatFinal stat = new CustomMonthlyStatFinal();
						stat.setCustomCode(customCodeT);
						stat.setMonth((String) s[1]);
						stat.setImpDeclCount(Integer.valueOf(((BigDecimal) s[3]).intValue()));
						stat.setImpManDeclCount(Integer.valueOf(((BigDecimal) s[4]).intValue()));
						stat.setImpManualAuditDeclCount(Integer.valueOf(((BigDecimal) s[5]).intValue()));
						stat.setImpDeclCountLastMonth(Integer.valueOf(((BigDecimal) s[6]).intValue()));
						stat.setImpDeclCountLastYearDecember(Integer.valueOf(((BigDecimal) s[7]).intValue()));
						stat.setImpDeclCountCurentYear(Integer.valueOf(((BigDecimal) s[8]).intValue()));
						stat.setImpDeclCountYearBeforeLast(Integer.valueOf(((BigDecimal) s[9]).intValue()));
						stat.setImpTotalCost((BigDecimal) s[10]);
						stat.setImpTotalCostLastMonth((BigDecimal) s[11]);
						stat.setImpTotalCostLastYearDecember((BigDecimal) s[12]);
						stat.setImpTotalCostCurentYear((BigDecimal) s[13]);
						stat.setImpTotalCostYearBeforeLast((BigDecimal) s[14]);
						stat.setImpCuCost((BigDecimal) s[15]);
						stat.setImpCuCostLastMonth((BigDecimal) s[16]);
						stat.setImpCuCostLastYearDecember((BigDecimal) s[17]);
						stat.setImpCuCostCurentYear((BigDecimal) s[18]);
						stat.setImpCuCostYearBeforeLast((BigDecimal) s[19]);
						stat.setExpDeclCount(Integer.valueOf(((BigDecimal) s[20]).intValue()));
						stat.setExpManDeclCount(Integer.valueOf(((BigDecimal) s[21]).intValue()));
						stat.setExpManualAuditDeclCount(Integer.valueOf(((BigDecimal) s[22]).intValue()));
						stat.setExpDeclCountLastMonth(Integer.valueOf(((BigDecimal) s[23]).intValue()));
						stat.setExpDeclCountLastYearDecember(Integer.valueOf(((BigDecimal) s[24]).intValue()));
						stat.setExpDeclCountCurentYear(Integer.valueOf(((BigDecimal) s[25]).intValue()));
						stat.setExpDeclCountYearBeforeLast(Integer.valueOf(((BigDecimal) s[26]).intValue()));
						stat.setExpTotalCost((BigDecimal) s[27]);
						stat.setExpTotalCostLastMonth((BigDecimal) s[28]);
						stat.setExpTotalCostLastYearDecember((BigDecimal) s[29]);
						stat.setExpTotalCostCurentYear((BigDecimal) s[30]);
						stat.setExpTotalCostYearBeforeLast((BigDecimal) s[31]);
						stat.setExpCuCost((BigDecimal) s[32]);
						stat.setExpCuCostLastMonth((BigDecimal) s[33]);
						stat.setExpCuCostLastYearDecember((BigDecimal) s[34]);
						stat.setExpCuCostCurentYear((BigDecimal) s[35]);
						stat.setExpCuCostYearBeforeLast((BigDecimal) s[36]);
						stat.setId(dao.getGuidStringBySql());
						customMonthlyStatFinalRepository.save(stat);
						existData = true;
						break;
					}
				}
				if (!existData) {// 若不存在关区合并前的统计数据，需要补上合并后的统计记录

					CustomMonthlyStatFinal stat = new CustomMonthlyStatFinal();
					stat.setMonth(dataPeriod);
					stat.setCustomCode(customCode);
					stat.setImpDeclCount(0);
					stat.setImpManDeclCount(0);
					stat.setImpManualAuditDeclCount(0);
					stat.setImpCuCost(zero);
					stat.setImpTotalCost(zero);
					stat.setExpDeclCount(0);
					stat.setExpManDeclCount(0);
					stat.setExpManualAuditDeclCount(0);
					stat.setExpCuCost(zero);
					stat.setExpTotalCost(zero);

					Calendar cal = Calendar.getInstance();
					Date curMonth = new Date();
					try {
						curMonth = monthSdf.parse(dataPeriod);
					} catch (ParseException e) {
						e.printStackTrace();
					}
					cal.setTime(curMonth);
					cal.add(Calendar.MONTH, -1);
					Date lastMonthDate = cal.getTime();
					List<Object[]> lastMonthData = (List<Object[]>) dao.getQueryBySql("select ID,MONTH,CUSTOM_CODE,IMP_DECL_COUNT,IMP_MAN_DECL_COUNT,IMP_MANUAL_AUDIT_DECL_COUNT,IMP_DECL_COUNT_LM,IMP_DECL_COUNT_LY_DEC," +
									"IMP_DECL_COUNT_CURYEAR,IMP_DECL_COUNT_YBL,IMP_TOTAL_COST,IMP_TOTAL_COST_LM,IMP_TOTAL_COST_LY_DEC,IMP_TOTAL_COST_CY,IMP_TOTAL_COST_YBL," +
									"IMP_CU_COST,IMP_CU_COST_LM,IMP_CU_COST_LY_DEC,IMP_CU_COST_CY,IMP_CU_COST_YBL,EXP_DECL_COUNT,EXP_MAN_DECL_COUNT,EXP_MANUAL_AUDIT_DECL_COUNT," +
									"EXP_DECL_COUNT_LM,EXP_DECL_COUNT_LY_DEC,EXP_DECL_COUNT_CURYEAR,EXP_DECL_COUNT_YBL,EXP_TOTAL_COST,EXP_TOTAL_COST_LM,EXP_TOTAL_COST_LY_DEC," +
									"EXP_TOTAL_COST_CY,EXP_TOTAL_COST_YBL,EXP_CU_COST,EXP_CU_COST_LM,EXP_CU_COST_LY_DEC,EXP_CU_COST_CY,EXP_CU_COST_YBL " +
									"from WXJY_CUSTOM_M_STAT_F where month = ? and CUSTOM_CODE = ?",
							monthSdf.format(lastMonthDate), customCode);
					if (lastMonthData != null && lastMonthData.size() > 0) {
						for (Object[] s : lastMonthData) {
							stat.setImpDeclCountLastMonth(Integer.valueOf(((BigDecimal)  s[6]).intValue()));
							stat.setImpCuCostLastMonth((BigDecimal) s[15]);
							stat.setImpTotalCostLastMonth((BigDecimal) s[10]);
							stat.setExpDeclCountLastMonth(Integer.valueOf(((BigDecimal)  s[22]).intValue()));
							stat.setExpCuCostLastMonth((BigDecimal) s[31]);
							stat.setExpTotalCostLastMonth((BigDecimal) s[26]);

							if (dataPeriod.endsWith("01")) {
								stat.setImpDeclCountCurentYear(0);
								stat.setImpCuCostCurentYear(zero);
								stat.setImpTotalCostCurentYear(zero);
								stat.setExpDeclCountCurentYear(0);
								stat.setExpCuCostCurentYear(zero);
								stat.setExpTotalCostCurentYear(zero);
								// 去年12月也就是上个月
								stat.setImpDeclCountLastYearDecember(Integer.valueOf(((BigDecimal) s[3]).intValue()));
								stat.setImpCuCostLastYearDecember((BigDecimal) s[14]);
								stat.setImpTotalCostLastYearDecember((BigDecimal) s[9]);
								stat.setExpDeclCountLastYearDecember(Integer.valueOf(((BigDecimal) s[21]).intValue()));
								stat.setExpCuCostLastYearDecember((BigDecimal) s[30]);
								stat.setExpTotalCostLastYearDecember((BigDecimal) s[25]);
								// 前年平均值需要重新查询&计算
								if (dataPeriod.compareTo(noRelStatMonth) > 0) {
									cal.setTime(curMonth);
									cal.add(Calendar.YEAR, -1);
									String lastYearJanuary = monthSdf.format(cal.getTime());
									cal.add(Calendar.YEAR, -1);
									String yearBeforeLastJanuary = monthSdf.format(cal.getTime());
									List<Object[]> yearBeforeLastData = (List<Object[]>) dao.getQueryBySql("select ID,MONTH,CUSTOM_CODE,IMP_DECL_COUNT,IMP_MAN_DECL_COUNT,IMP_MANUAL_AUDIT_DECL_COUNT,IMP_DECL_COUNT_LM,IMP_DECL_COUNT_LY_DEC," +
													"IMP_DECL_COUNT_CURYEAR,IMP_DECL_COUNT_YBL,IMP_TOTAL_COST,IMP_TOTAL_COST_LM,IMP_TOTAL_COST_LY_DEC,IMP_TOTAL_COST_CY,IMP_TOTAL_COST_YBL," +
													"IMP_CU_COST,IMP_CU_COST_LM,IMP_CU_COST_LY_DEC,IMP_CU_COST_CY,IMP_CU_COST_YBL,EXP_DECL_COUNT,EXP_MAN_DECL_COUNT,EXP_MANUAL_AUDIT_DECL_COUNT," +
													"EXP_DECL_COUNT_LM,EXP_DECL_COUNT_LY_DEC,EXP_DECL_COUNT_CURYEAR,EXP_DECL_COUNT_YBL,EXP_TOTAL_COST,EXP_TOTAL_COST_LM,EXP_TOTAL_COST_LY_DEC," +
													"EXP_TOTAL_COST_CY,EXP_TOTAL_COST_YBL,EXP_CU_COST,EXP_CU_COST_LM,EXP_CU_COST_LY_DEC,EXP_CU_COST_CY,EXP_CU_COST_YBL " +
													"from WXJY_CUSTOM_M_STAT_F where month >= ? and month < ? and CUSTOM_CODE = ?",
											yearBeforeLastJanuary, lastYearJanuary, customCode);
									if (yearBeforeLastData != null && yearBeforeLastData.size() > 0) {
										int sumImpDeclCountYBL = 0;
										BigDecimal sumImpCuCostYBL = new BigDecimal(0);
										BigDecimal sumImpTotalCostYBL = new BigDecimal(0);

										int sumExpDeclCountYBL = 0;
										BigDecimal sumExCuCostYBL = new BigDecimal(0);
										BigDecimal sumExpTotalCostYBL = new BigDecimal(0);

										for (Object[] t : yearBeforeLastData) {
											Integer impCount = Integer.valueOf(((BigDecimal) t[3]).intValue());
											if (impCount != null && impCount != 0) {
												sumImpDeclCountYBL += impCount;
												BigDecimal mul = new BigDecimal(impCount);

												BigDecimal impCuCost = (BigDecimal) t[14];
												if (impCuCost != null) {
													sumImpCuCostYBL = sumImpCuCostYBL.add(impCuCost.multiply(mul));
												}
												BigDecimal impTotalCost = (BigDecimal) t[9];
												if (impTotalCost != null) {
													sumImpTotalCostYBL = sumImpTotalCostYBL.add(impTotalCost.multiply(mul));
												}
											}

											Integer expCount = Integer.valueOf(((BigDecimal) t[21]).intValue());
											if (expCount != null && expCount != 0) {
												sumExpDeclCountYBL += expCount;
												BigDecimal mul = new BigDecimal(expCount);

												BigDecimal expCuCost = (BigDecimal) t[30];
												if (expCuCost != null) {
													sumExCuCostYBL = sumExCuCostYBL.add(expCuCost.multiply(mul));
												}
												BigDecimal expTotalCost = (BigDecimal) t[25];
												if (expTotalCost != null) {
													sumExpTotalCostYBL = sumExpTotalCostYBL.add(expTotalCost.multiply(mul));
												}
											}

										}

										if (sumImpDeclCountYBL != 0) {
											BigDecimal div = new BigDecimal(sumImpDeclCountYBL);
											stat.setImpDeclCountYearBeforeLast(sumImpDeclCountYBL);
											stat.setImpCuCostYearBeforeLast(sumImpCuCostYBL.divide(div, 4, BigDecimal.ROUND_HALF_UP));
											stat.setImpTotalCostYearBeforeLast(sumImpTotalCostYBL.divide(div, 4, BigDecimal.ROUND_HALF_UP));
										} else {
											stat.setImpDeclCountYearBeforeLast(0);
											stat.setImpCuCostYearBeforeLast(zero);
											stat.setImpTotalCostYearBeforeLast(zero);
										}

										if (sumExpDeclCountYBL != 0) {
											BigDecimal div = new BigDecimal(sumExpDeclCountYBL);
											stat.setExpDeclCountYearBeforeLast(sumExpDeclCountYBL);
											stat.setExpCuCostYearBeforeLast(sumExCuCostYBL.divide(div, 4, BigDecimal.ROUND_HALF_UP));
											stat.setExpTotalCostYearBeforeLast(sumExpTotalCostYBL.divide(div, 4, BigDecimal.ROUND_HALF_UP));
										} else {
											stat.setExpDeclCountYearBeforeLast(0);
											stat.setExpCuCostYearBeforeLast(zero);
											stat.setExpTotalCostYearBeforeLast(zero);
										}

									} else {
										stat.setImpDeclCountYearBeforeLast(0);
										stat.setImpCuCostYearBeforeLast(zero);
										stat.setImpTotalCostYearBeforeLast(zero);
										stat.setExpDeclCountYearBeforeLast(0);
										stat.setExpCuCostYearBeforeLast(zero);
										stat.setExpTotalCostYearBeforeLast(zero);
									}
								} else {
									stat.setImpDeclCountYearBeforeLast(0);
									stat.setImpCuCostYearBeforeLast(zero);
									stat.setImpTotalCostYearBeforeLast(zero);
									stat.setExpDeclCountYearBeforeLast(0);
									stat.setExpCuCostYearBeforeLast(zero);
									stat.setExpTotalCostYearBeforeLast(zero);
								}
							} else {
								stat.setImpDeclCountCurentYear(Integer.valueOf(((BigDecimal) s[8]).intValue()));
								stat.setImpCuCostCurentYear((BigDecimal) s[17]);
								stat.setImpTotalCostCurentYear((BigDecimal) s[12]);
								stat.setExpDeclCountCurentYear(Integer.valueOf(((BigDecimal) s[24]).intValue()));
								stat.setExpCuCostCurentYear((BigDecimal) s[33]);
								stat.setExpTotalCostCurentYear((BigDecimal) s[28]);
								// 去年12月数据是上个月对应字段的值
								stat.setImpDeclCountLastYearDecember(Integer.valueOf(((BigDecimal) s[7]).intValue()));
								stat.setImpCuCostLastYearDecember((BigDecimal) s[16]);
								stat.setImpTotalCostLastYearDecember((BigDecimal) s[11]);
								stat.setExpDeclCountLastYearDecember(Integer.valueOf(((BigDecimal) s[23]).intValue()));
								stat.setExpCuCostLastYearDecember((BigDecimal) s[32]);
								stat.setExpTotalCostLastYearDecember((BigDecimal) s[27]);

								stat.setImpDeclCountYearBeforeLast(Integer.valueOf(((BigDecimal) s[9]).intValue()));
								stat.setImpCuCostYearBeforeLast((BigDecimal) s[18]);
								stat.setImpTotalCostYearBeforeLast((BigDecimal) s[13]);
								stat.setExpDeclCountYearBeforeLast(Integer.valueOf(((BigDecimal) s[25]).intValue()));
								stat.setExpCuCostYearBeforeLast((BigDecimal) s[34]);
								stat.setExpTotalCostYearBeforeLast((BigDecimal) s[29]);
							}
							break;
						}
					} else {//要求从最早月度开始维护，则若前面数据不存在，当前月度直接设置为0
						stat.setImpDeclCountCurentYear(0);
						stat.setImpCuCostCurentYear(zero);
						stat.setImpTotalCostCurentYear(zero);
						stat.setExpDeclCountCurentYear(0);
						stat.setExpCuCostCurentYear(zero);
						stat.setExpTotalCostCurentYear(zero);

						stat.setImpDeclCountLastMonth(0);
						stat.setImpCuCostLastMonth(zero);
						stat.setImpTotalCostLastMonth(zero);
						stat.setExpDeclCountLastMonth(0);
						stat.setExpCuCostLastMonth(zero);
						stat.setExpTotalCostLastMonth(zero);

						stat.setImpDeclCountLastYearDecember(0);
						stat.setImpCuCostLastYearDecember(zero);
						stat.setImpTotalCostLastYearDecember(zero);
						stat.setExpDeclCountLastYearDecember(0);
						stat.setExpCuCostLastYearDecember(zero);
						stat.setExpTotalCostLastYearDecember(zero);

						stat.setImpDeclCountYearBeforeLast(0);
						stat.setImpCuCostYearBeforeLast(zero);
						stat.setImpTotalCostYearBeforeLast(zero);
						stat.setExpDeclCountYearBeforeLast(0);
						stat.setExpCuCostYearBeforeLast(zero);
						stat.setExpTotalCostYearBeforeLast(zero);
					}
					stat.setId(dao.getGuidStringBySql());
					customMonthlyStatFinalRepository.save(stat);
				}
			} else {// 需要将一级关区及其下级关区的数据合并
				sumImpDeclCount = 0;// 进口单数
				sumImpManDeclCount = 0;//进口查验单数
				sumImpAuditDeclCount = 0;//进口人工审单单数
				sumImpDeclCountLastMonth = 0;// 上个月进口单数
				sumImpDeclCountLastYearDecember = 0;// 去年12月进口单数
				sumImpDeclCountCurentYear = 0;// 今年截止当月总进口单数
				sumImpDeclCountYearBeforeLast = 0;// 前年总进口单数
				sumExpDeclCount = 0;// 出口单数
				sumExpManDeclCount = 0;//进口查验单数
				sumExpAuditDeclCount = 0;//进口人工审单单数
				sumExpDeclCountLastMonth = 0;// 上个月出口单数
				sumExpDeclCountLastYearDecember = 0;// 去年12月进口单数
				sumExpDeclCountCurentYear = 0;// 今年截止当月总出口单数
				sumExpDeclCountYearBeforeLast = 0;// 前年总出口单数

				// 20个消耗时间字段
				sumImpTotalCost = zero;// 进口平均整体通关时间（小时）
				sumImpTotalCostLastMonth = zero;// 进口平均整体通关时间-上月
				sumImpTotalCostLastYearDecember = zero;// 进口平均整体通关时间-去年12月
				sumImpTotalCostCurentYear = zero;// 进口平均整体通关时间-1至当月
				sumImpTotalCostYearBeforeLast = zero;// 进口平均整体通关时间-前年
				sumImpCuCost = zero;// 进口平均海关通关时间（小时）
				sumImpCuCostLastMonth = zero;// 进口平均海关通关时间（小时）-上月
				sumImpCuCostLastYearDecember = zero;// 进口平均海关通关时间-去年12月
				sumImpCuCostCurentYear = zero;// 进口平均海关通关时间-1至当月
				sumImpCuCostYearBeforeLast = zero;// 进口平均海关通关时间-前年
				sumExpTotalCost = zero;// 出口平均整体通关时间（小时）
				sumExpTotalCostLastMonth = zero;// 出口平均整体通关时间（小时）-上月
				sumExpTotalCostLastYearDecember = zero; // 出口平均整体通关时间-去年12月
				sumExpTotalCostCurentYear = zero;// 出口平均整体通关时间-1至当月
				sumExpTotalCostYearBeforeLast = zero;// 出口平均整体通关时间-前年
				sumExpCuCost = zero;// 出口平均海关通关时间（小时）
				sumExpCuCostLastMonth = zero;// 出口平均海关通关时间（小时）-上月
				sumExpCuCostLastYearDecember = zero;// 出口平均海关通关时间-去年12月
				sumExpCuCostCurentYear = zero;// 出口平均海关通关时间-1至当月
				sumExpCuCostYearBeforeLast = zero;// 出口平均海关通关时间-前年

				for (Object[] s : copyList) {
					if (customCode.equals((String) s[2])) {
						sumImpDeclCount += Integer.valueOf(((BigDecimal) s[3]).intValue());
						sumImpManDeclCount += Integer.valueOf(((BigDecimal) s[4]).intValue());
						sumImpAuditDeclCount += Integer.valueOf(((BigDecimal) s[5]).intValue());
						sumImpDeclCountLastMonth += s[6] != null ? Integer.valueOf(((BigDecimal) s[6]).intValue()) : 0;
						sumImpDeclCountLastYearDecember += s[7] != null ? Integer.valueOf(((BigDecimal) s[7]).intValue())
								: 0;
						sumImpDeclCountCurentYear += s[8] != null ? Integer.valueOf(((BigDecimal) s[8]).intValue()) : 0;
						sumImpDeclCountYearBeforeLast += s[9] != null ? Integer.valueOf(((BigDecimal) s[9]).intValue()) : 0;

						sumExpDeclCount += Integer.valueOf(((BigDecimal) s[20]).intValue());
						sumExpManDeclCount += Integer.valueOf(((BigDecimal) s[21]).intValue());
						sumExpAuditDeclCount += Integer.valueOf(((BigDecimal) s[22]).intValue());
						sumExpDeclCountLastMonth += s[23] != null ? Integer.valueOf(((BigDecimal) s[23]).intValue()) : 0;
						sumExpDeclCountLastYearDecember += s[24] != null ? Integer.valueOf(((BigDecimal) s[24]).intValue())
								: 0;
						sumExpDeclCountCurentYear += s[25] != null ? Integer.valueOf(((BigDecimal) s[25]).intValue()) : 0;
						sumExpDeclCountYearBeforeLast += s[26] != null ? Integer.valueOf(((BigDecimal) s[26]).intValue()) : 0;

						BigDecimal impCurMonthMultiply = (BigDecimal) s[3];
						BigDecimal impLastMonthMultiply = s[6] != null ? (BigDecimal) s[6] : new BigDecimal(0);
						BigDecimal impLastYearDecemberMultiply = s[7] != null ? (BigDecimal) s[7] : new BigDecimal(0);
						BigDecimal impCurYearMultiply = s[8] != null ? (BigDecimal) s[8] : new BigDecimal(0);
						BigDecimal impYearBeforeLastMultiply = s[9] != null ? (BigDecimal) s[9] : new BigDecimal(0);

						BigDecimal expCurMonthMultiply = (BigDecimal) s[20];
						BigDecimal expLastMonthMultiply = s[23] != null ? (BigDecimal) s[23] : new BigDecimal(0);
						BigDecimal expLastYearDecemberMultiply = s[24] != null ? (BigDecimal) s[24] : new BigDecimal(0);
						BigDecimal expCurYearMultiply = s[25] != null ? (BigDecimal) s[25] : new BigDecimal(0);
						BigDecimal expYearBeforeLastMultiply = s[26] != null ? (BigDecimal) s[26] : new BigDecimal(0);

						sumImpTotalCost = s[10] != null
								? sumImpTotalCost.add(((BigDecimal) s[10]).multiply(impCurMonthMultiply))
								: sumImpTotalCost;
						sumImpTotalCostLastMonth = s[11] != null
								? sumImpTotalCostLastMonth.add(((BigDecimal) s[11]).multiply(impLastMonthMultiply))
								: sumImpTotalCostLastMonth;
						sumImpTotalCostLastYearDecember = s[12] != null
								? sumImpTotalCostLastYearDecember
								.add(((BigDecimal) s[12]).multiply(impLastYearDecemberMultiply))
								: sumImpTotalCostLastYearDecember;
						sumImpTotalCostCurentYear = s[13] != null
								? sumImpTotalCostCurentYear.add(((BigDecimal) s[13]).multiply(impCurYearMultiply))
								: sumImpTotalCostCurentYear;
						sumImpTotalCostYearBeforeLast = s[14] != null
								? sumImpTotalCostYearBeforeLast.add(((BigDecimal) s[14]).multiply(impYearBeforeLastMultiply))
								: sumImpTotalCostYearBeforeLast;

						sumImpCuCost = s[15] != null ? sumImpCuCost.add(((BigDecimal) s[15]).multiply(impCurMonthMultiply))
								: sumImpCuCost;
						sumImpCuCostLastMonth = s[16] != null
								? sumImpCuCostLastMonth.add(((BigDecimal) s[16]).multiply(impLastMonthMultiply))
								: sumImpCuCostLastMonth;
						sumImpCuCostLastYearDecember = s[17] != null
								? sumImpCuCostLastYearDecember.add(((BigDecimal) s[17]).multiply(impLastYearDecemberMultiply))
								: sumImpCuCostLastYearDecember;
						sumImpCuCostCurentYear = s[18] != null
								? sumImpCuCostCurentYear.add(((BigDecimal) s[18]).multiply(impCurYearMultiply))
								: sumImpCuCostCurentYear;
						sumImpCuCostYearBeforeLast = s[19] != null
								? sumImpCuCostYearBeforeLast.add(((BigDecimal) s[19]).multiply(impYearBeforeLastMultiply))
								: sumImpCuCostYearBeforeLast;

						sumExpTotalCost = s[27] != null
								? sumExpTotalCost.add(((BigDecimal) s[27]).multiply(expCurMonthMultiply))
								: sumExpTotalCost;
						sumExpTotalCostLastMonth = s[28] != null
								? sumExpTotalCostLastMonth.add(((BigDecimal) s[28]).multiply(expLastMonthMultiply))
								: sumExpTotalCostLastMonth;
						sumExpTotalCostLastYearDecember = s[29] != null
								? sumExpTotalCostLastYearDecember
								.add(((BigDecimal) s[29]).multiply(expLastYearDecemberMultiply))
								: sumExpTotalCostLastYearDecember;
						sumExpTotalCostCurentYear = s[30] != null
								? sumExpTotalCostCurentYear.add(((BigDecimal) s[30]).multiply(expCurYearMultiply))
								: sumExpTotalCostCurentYear;
						sumExpTotalCostYearBeforeLast = s[31] != null
								? sumExpTotalCostYearBeforeLast.add(((BigDecimal) s[31]).multiply(expYearBeforeLastMultiply))
								: sumExpTotalCostYearBeforeLast;

						sumExpCuCost = s[32] != null ? sumExpCuCost.add(((BigDecimal) s[32]).multiply(expCurMonthMultiply))
								: sumExpCuCost;
						sumExpCuCostLastMonth = s[33] != null
								? sumExpCuCostLastMonth.add(((BigDecimal) s[33]).multiply(expLastMonthMultiply))
								: sumExpCuCostLastMonth;
						sumExpCuCostLastYearDecember = s[34] != null
								? sumExpCuCostLastYearDecember.add(((BigDecimal) s[34]).multiply(expLastYearDecemberMultiply))
								: sumExpCuCostLastYearDecember;
						sumExpCuCostCurentYear = s[35] != null
								? sumExpCuCostCurentYear.add(((BigDecimal) s[35]).multiply(expCurYearMultiply))
								: sumExpCuCostCurentYear;
						sumExpCuCostYearBeforeLast = s[36] != null
								? sumExpCuCostYearBeforeLast.add(((BigDecimal) s[36]).multiply(expYearBeforeLastMultiply))
								: sumExpCuCostYearBeforeLast;
					}
				}

				CustomMonthlyStatFinal stat = new CustomMonthlyStatFinal();
				stat.setMonth(dataPeriod);
				stat.setCustomCode(customCode);

				stat.setImpCuCost(
						sumImpDeclCount == 0 ? zero : sumImpCuCost.divide(new BigDecimal(sumImpDeclCount), 4, BigDecimal.ROUND_HALF_UP));
				stat.setImpCuCostCurentYear(sumImpDeclCountCurentYear == 0 ? zero
						: sumImpCuCostCurentYear.divide(new BigDecimal(sumImpDeclCountCurentYear), 4, BigDecimal.ROUND_HALF_UP));
				stat.setImpCuCostLastMonth(sumImpDeclCountLastMonth == 0 ? zero
						: sumImpCuCostLastMonth.divide(new BigDecimal(sumImpDeclCountLastMonth), 4, BigDecimal.ROUND_HALF_UP));
				stat.setImpCuCostLastYearDecember(sumImpDeclCountLastYearDecember == 0 ? zero
						: sumImpCuCostLastYearDecember.divide(new BigDecimal(sumImpDeclCountLastYearDecember), 4,
						BigDecimal.ROUND_HALF_UP));
				stat.setImpCuCostYearBeforeLast(sumImpDeclCountYearBeforeLast == 0 ? zero
						: sumImpCuCostYearBeforeLast.divide(new BigDecimal(sumImpDeclCountYearBeforeLast), 4, BigDecimal.ROUND_HALF_UP));
				stat.setImpDeclCount(sumImpDeclCount);
				stat.setImpManDeclCount(sumImpManDeclCount);
				stat.setImpManualAuditDeclCount(sumImpAuditDeclCount);
				stat.setImpDeclCountCurentYear(sumImpDeclCountCurentYear);
				stat.setImpDeclCountLastMonth(sumImpDeclCountLastMonth);
				stat.setImpDeclCountLastYearDecember(sumImpDeclCountLastYearDecember);
				stat.setImpDeclCountYearBeforeLast(sumImpDeclCountYearBeforeLast);
				stat.setImpTotalCost(
						sumImpDeclCount == 0 ? zero : sumImpTotalCost.divide(new BigDecimal(sumImpDeclCount), 4, BigDecimal.ROUND_HALF_UP));
				stat.setImpTotalCostCurentYear(sumImpDeclCountCurentYear == 0 ? zero
						: sumImpTotalCostCurentYear.divide(new BigDecimal(sumImpDeclCountCurentYear), 4, BigDecimal.ROUND_HALF_UP));
				stat.setImpTotalCostLastMonth(sumImpDeclCountLastMonth == 0 ? zero
						: sumImpTotalCostLastMonth.divide(new BigDecimal(sumImpDeclCountLastMonth), 4, BigDecimal.ROUND_HALF_UP));
				stat.setImpTotalCostLastYearDecember(sumImpDeclCountLastYearDecember == 0 ? zero
						: sumImpTotalCostLastYearDecember.divide(new BigDecimal(sumImpDeclCountLastYearDecember), 4,
						BigDecimal.ROUND_HALF_UP));
				stat.setImpTotalCostYearBeforeLast(sumImpDeclCountYearBeforeLast == 0 ? zero
						: sumImpTotalCostYearBeforeLast.divide(new BigDecimal(sumImpDeclCountYearBeforeLast), 4, BigDecimal.ROUND_HALF_UP));

				stat.setExpCuCost(
						sumExpDeclCount == 0 ? zero : sumExpCuCost.divide(new BigDecimal(sumExpDeclCount), 4, BigDecimal.ROUND_HALF_UP));
				stat.setExpCuCostCurentYear(sumExpDeclCountCurentYear == 0 ? zero
						: sumExpCuCostCurentYear.divide(new BigDecimal(sumExpDeclCountCurentYear), 4, BigDecimal.ROUND_HALF_UP));
				stat.setExpCuCostLastMonth(sumExpDeclCountLastMonth == 0 ? zero
						: sumExpCuCostLastMonth.divide(new BigDecimal(sumExpDeclCountLastMonth), 4, BigDecimal.ROUND_HALF_UP));
				stat.setExpCuCostLastYearDecember(sumExpDeclCountLastYearDecember == 0 ? zero
						: sumExpCuCostLastYearDecember.divide(new BigDecimal(sumExpDeclCountLastYearDecember), 4,
						BigDecimal.ROUND_HALF_UP));
				stat.setExpCuCostYearBeforeLast(sumExpDeclCountYearBeforeLast == 0 ? zero
						: sumExpCuCostYearBeforeLast.divide(new BigDecimal(sumExpDeclCountYearBeforeLast), 4, BigDecimal.ROUND_HALF_UP));
				stat.setExpDeclCount(sumExpDeclCount);
				stat.setExpManDeclCount(sumExpManDeclCount);
				stat.setExpManualAuditDeclCount(sumExpAuditDeclCount);
				stat.setExpDeclCountCurentYear(sumExpDeclCountCurentYear);
				stat.setExpDeclCountLastMonth(sumExpDeclCountLastMonth);
				stat.setExpDeclCountLastYearDecember(sumExpDeclCountLastYearDecember);
				stat.setExpDeclCountYearBeforeLast(sumExpDeclCountYearBeforeLast);
				stat.setExpTotalCost(
						sumExpDeclCount == 0 ? zero : sumExpTotalCost.divide(new BigDecimal(sumExpDeclCount), 4, BigDecimal.ROUND_HALF_UP));
				stat.setExpTotalCostCurentYear(sumExpDeclCountCurentYear == 0 ? zero
						: sumExpTotalCostCurentYear.divide(new BigDecimal(sumExpDeclCountCurentYear), 4, BigDecimal.ROUND_HALF_UP));
				stat.setExpTotalCostLastMonth(sumExpDeclCountLastMonth == 0 ? zero
						: sumExpTotalCostLastMonth.divide(new BigDecimal(sumExpDeclCountLastMonth), 4, BigDecimal.ROUND_HALF_UP));
				stat.setExpTotalCostLastYearDecember(sumExpDeclCountLastYearDecember == 0 ? zero
						: sumExpTotalCostLastYearDecember.divide(new BigDecimal(sumExpDeclCountLastYearDecember), 4,
						BigDecimal.ROUND_HALF_UP));
				stat.setExpTotalCostYearBeforeLast(sumExpDeclCountYearBeforeLast == 0 ? zero
						: sumExpTotalCostYearBeforeLast.divide(new BigDecimal(sumExpDeclCountYearBeforeLast), 4, BigDecimal.ROUND_HALF_UP));
				stat.setId(dao.getGuidStringBySql());
				customMonthlyStatFinalRepository.save(stat);
			}
		}
	}

	/**
	 * 删单涉案数据
	 * 删单涉案每天跑近一个月数据量大导致日志打不开，现在改为只查和危险品有关的报关单数据
	 */
	private void delSpecialAndDelHeadLogData(Date end) {
		//原来写的删单只删当前时间前一天数据，这会导致重刷时间范围数据时剔除不了以前删单的单子，而涉案的总是剔除近一年的，如果刷的是一年以前的也剔除不了
		//所以这里按照传递进来的时间做近一年范围剔除
		//新剔除范围
		Date today = null;
		Calendar c = Calendar.getInstance();
		try {
			today = daySdf.parse(daySdf.format(end));
			c.setTime(today);
		} catch (ParseException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		String sa_sql = "";//涉案
		List<String> specialEntryIds = new ArrayList<String>();
		List<String> specialH2018EntryIds = new ArrayList<String>();
		List<String> delEntryIds = new ArrayList<String>();
		//flag 生产环境正式代码设置为true；删除5年内的涉案数据设置为false以提升效率
		//刷数据后会存在很多涉案数据没有剔除干净，因此需要flag改为false跑一次,很多当天查出的报关单在前两年涉案
		boolean flag = true;
		if (flag) {//生产环境
			// 每日维护取最近一年涉案的报关单号来过滤需要汇总的报关单
			c.add(Calendar.YEAR, -1);
			sa_sql = "select distinct(ENTRY_ID) from rh2k_SPECIAL_ENTRY where OP_TIME >= ? and OP_TIME < ?";
			specialEntryIds = (List<String>) rh2kRepository.getQueryBySql(sa_sql, c.getTime(), today);
			specialH2018EntryIds = (List<String>) h2018Dao.getQueryBySql(
					"select distinct(ENTRY_ID) from ENTRY_HEAD where D_DATE >= ? and D_DATE < ? " +
							"and NOTE_S like '%处罚决定书%'", c.getTime(), today);
			//20231013发现退单和删单都会进ENTRY_DEL_HEAD_LOG，只有ENTRY_OP_LOG OP_TYPE第一位为0可以区分删单
			delEntryIds = (List<String>) zmqdRepository.getQueryBySql(
					"select distinct(ENTRY_ID) from h18c_ENTRY_OP_LOG where substr(OP_TYPE,1,1) = '0' "
							+ "and OP_TIME >= ? and OP_TIME < ?", c.getTime(), today);
		} else {//测试环境
			// 全新生成所有中间数据时，取最近5年的涉案单号，每一年涉案的单号大约几千单，2018以前的很少
			c.add(Calendar.YEAR, -5);
			sa_sql = "select distinct(ENTRY_ID) from rh2k_SPECIAL_ENTRY where OP_TIME >= ?";
			specialEntryIds = (List<String>) rh2kRepository.getQueryBySql(sa_sql, c.getTime());
			specialH2018EntryIds = (List<String>) h2018Dao.getQueryBySql(
					"select distinct(ENTRY_ID) from ENTRY_HEAD where D_DATE >= ? " +
							"and NOTE_S like '%处罚决定书%'", c.getTime());
			try {
				// 把维护记录日期当天及之后所有的的删单记录添加进过滤集合（切记：删单记录大多数在结关之后才执行，全新生成是不考虑）
				delEntryIds = (List<String>) zmqdRepository.getQueryBySql("select distinct(ENTRY_ID) from h18c_ENTRY_OP_LOG "
						+ "where substr(OP_TYPE,1,1) = '0' and OP_TIME >= ?", daySdf.parse("20160101"));
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		//删单和涉案的单号
		if (specialEntryIds != null && specialEntryIds.size() > 0) {
			delEntryIds.addAll(specialEntryIds);
		}
		if (specialH2018EntryIds != null && specialH2018EntryIds.size() > 0) {
			delEntryIds.addAll(specialH2018EntryIds);
		}
		if (null != delEntryIds && delEntryIds.size() > 0) {
			int currentPage = 1;
			int pageSize = 100;
			int count = 0;
			int page = (delEntryIds.size() % pageSize == 0 ? delEntryIds.size() / pageSize : delEntryIds.size() / pageSize + 1);
			for (int j = 0; j < page; j++) {
				StringBuilder entryIds = new StringBuilder();
				int total = currentPage * pageSize;
				for (int i = count; i < (delEntryIds.size() - count > 100 ? total : delEntryIds.size()); i++) {
					entryIds.append("'").append(delEntryIds.get(i)).append("',");
				}
				entryIds.deleteCharAt(entryIds.length() - 1);
				String ids = entryIds.toString();

				//同步删除通过报关单号关联的商品编码信息
				String sql2 = "delete from WXJY_ENTRY_LIST where ENTRY_ID in (" + ids + ")";
				dao.executeUpdate(sql2);

				String sql = "delete from WXJY_ENTRY_HEAD where ENTRY_ID in (" + ids + ")";
				dao.executeUpdate(sql);

				currentPage++;
				count += pageSize;
			}
		}
		//如果有涉案数据则需要把月度数据重刷
		if (null != delEntryIds && delEntryIds.size() > 0) {
			//由于删掉涉案是在当月重新刷月度数据前执行，所以需要将一级海关存放，否则合并表不生成数据
			rootCustomsMap.clear();
			hasMultipleCustomList.clear();
			firstClassCustoms.clear();
			List<PubCustomsMapping> custMapping = pubCustomsMappingRepository.findAll();
			for (PubCustomsMapping m : custMapping) {
				String pCustomCode = m.getMappingCode();
				if (rootCustomsMap.containsValue(pCustomCode)) {
					hasMultipleCustomList.add(pCustomCode);
				}
				rootCustomsMap.put(m.getCustomsCode(), pCustomCode);
				firstClassCustoms.add(pCustomCode);
			}
			Calendar cl = Calendar.getInstance();
			Date clNow = new Date();
			Date deadline = clNow;
			cl.setTime(today);
			if (flag) {//生产环境
				// 每日维护取最近一年涉案的报关单号来过滤需要汇总的报关单
				cl.add(Calendar.YEAR, -1);
			} else {//测试环境
				// 全新生成所有中间数据时，取最近5年的涉案单号，每一年涉案的单号大约几千单，2018以前的很少
				cl.add(Calendar.YEAR, -5);
			}
			while (!cl.getTime().after(deadline)) {
				String dataPeriod = monthSdf.format(cl.getTime());
				Date statBegin = null;
				try {
					statBegin = monthSdf.parse(dataPeriod);
				} catch (ParseException e) {
				}
				cl.setTime(statBegin);
				cl.add(Calendar.MONTH, 1);
				Date statEnd = cl.getTime();
				//每日数据不重刷
				dao.executeUpdate("delete from WXJY_MID_D_M_STATUS where DATA_TYPE != ? and STAT_PERIOD = ?", EntryHead.class.getSimpleName(), dataPeriod);
				monthlyDataMaintance(dataPeriod, statBegin, statEnd);
			}
			rootCustomsMap.clear();
			hasMultipleCustomList.clear();
			firstClassCustoms.clear();
			logger.info("涉案删除后月份数据重刷成功");
		} else {
			logger.info("最近无涉案数据不需要重新生成月度数据");
		}
	}
}
