package com.simuwang.manage.service.impl; import cn.hutool.core.date.DateUtil; import com.simuwang.base.common.enums.DeletionType; import com.simuwang.base.common.enums.DistributeType; import com.simuwang.base.common.enums.Frequency; import com.simuwang.base.common.support.MybatisPage; import com.simuwang.base.common.util.DateUtils; import com.simuwang.base.common.util.StringUtil; import com.simuwang.base.mapper.daq.*; import com.simuwang.base.pojo.dos.*; import com.simuwang.base.pojo.dto.DeletionDownParam; import com.simuwang.base.pojo.dto.EmailInfoDTO; import com.simuwang.base.pojo.dto.ExcelDeletionInfoDTO; import com.simuwang.base.pojo.dto.query.DeletionPageQuery; import com.simuwang.base.pojo.dto.query.FundDeletionPageQuery; import com.simuwang.base.pojo.vo.*; import com.simuwang.manage.service.DeletionService; import com.simuwang.shiro.utils.UserUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; /** * FileName: DeletionServiceImpl * Author: chenjianhua * Date: 2024/9/17 18:54 * Description: ${DESCRIPTION} */ @Service public class DeletionServiceImpl implements DeletionService { private static final Logger log = LoggerFactory.getLogger(DeletionServiceImpl.class); @Autowired private DeletionInfoMapper deletionInfoMapper; @Autowired private FundInfoMapper fundInfoMapper; @Autowired private FundPositionDetailMapper fundPositionDetailMapper; @Autowired private AssetMapper assetMapper; @Autowired private FundReportFrequencyMapper fundReportFrequencyMapper; @Autowired private TradeDateMapper tradeDateMapper; @Autowired private DistributionMapper distributionMapper; @Autowired private ChannelEmailMapper channelEmailMapper; @Autowired private NavMapper navMapper; @Override public MybatisPage searchDeletionList(DeletionPageQuery deletionPageQuery) { List deletionInfoDOList = deletionInfoMapper.searchDeletionList(deletionPageQuery); long total = deletionInfoMapper.countDeletion(deletionPageQuery); List dataList = deletionInfoDOList.stream().map(DeletionInfoDO::toVO).collect(Collectors.toList()); return MybatisPage.of(total,dataList); } @Override public MybatisPage searchFundDeletionList(FundDeletionPageQuery fundDeletionPageQuery) { List deletionInfoDOList = deletionInfoMapper.searchFundDeletionList(fundDeletionPageQuery); long total = deletionInfoMapper.countFundDeletionList(fundDeletionPageQuery); List dataList = deletionInfoDOList.stream().map(FundDeletionInfoDO::toVO).collect(Collectors.toList()); return MybatisPage.of(total,dataList); } @Override public void saveFundDeletionList(List fundDeletionInfoVOList) { List fundDeletionInfoDOList = new ArrayList<>(); for(FundDeletionInfoVO vo : fundDeletionInfoVOList){ FundDeletionInfoDO fundDeletionInfoDO = new FundDeletionInfoDO(); fundDeletionInfoDO.setId(vo.getId()); fundDeletionInfoDO.setChannelId(vo.getChannelId()); fundDeletionInfoDO.setDeletionType(vo.getDeletionType()); fundDeletionInfoDO.setFundId(vo.getFundId()); fundDeletionInfoDO.setDeletionDate(vo.getDeletionDate()); fundDeletionInfoDO.setRemark(vo.getRemark()); fundDeletionInfoDO.setIsvalid(1); fundDeletionInfoDO.setUpdateTime(DateUtils.getNowDate()); fundDeletionInfoDO.setUpdaterId(UserUtils.getLoginUser().getUserId()); fundDeletionInfoDOList.add(fundDeletionInfoDO); } deletionInfoMapper.batchUpdate(fundDeletionInfoDOList); } @Override public void saveBatchDeletionRemark(FundDeletionRemarkVO fundDeletionRemarkVO) { String remark = fundDeletionRemarkVO.getRemark(); Integer userId = UserUtils.getLoginUser().getUserId(); for(FundDeletionTypeVO remarkVO : fundDeletionRemarkVO.getFundDeletionTypeList()){ deletionInfoMapper.updateRemark(remarkVO.getChannelId(),remarkVO.getFundId(),remarkVO.getDeletionType(),remarkVO.getDeletionDate(),remark,userId); } } @Override public List selectFundDeletionInfoVOList(FundDeletionListVO fundDeletionListVO) { List result = new ArrayList<>(); List deletionDownParamList = fundDeletionListVO.getDeletionDownParamList(); for(DeletionDownParam deletionDownParam : deletionDownParamList){ List deletionInfoDOList = deletionInfoMapper.selectFundDeletionInfoVOList(deletionDownParam.getFundId(),deletionDownParam.getDeletionType()); for(FundDeletionInfoDO infoDO : deletionInfoDOList){ ExcelDeletionInfoDTO dto = new ExcelDeletionInfoDTO(); dto.setFundName(fundInfoMapper.getFundNameByFundId(infoDO.getFundId())); dto.setCompanyName(fundInfoMapper.getCompanyNameByFundId(infoDO.getFundId())); dto.setDeletionType(DeletionType.getDeletionTypeByCode(infoDO.getDeletionType()).getInfo()); dto.setDeletionDate(infoDO.getDeletionDate()); dto.setRemark(infoDO.getRemark()); dto.setFundId(infoDO.getFundId()); result.add(dto); } } return result; } @Override public void computeDeletion(List mailboxInfoDOList) { Map> channelEmailMap = new HashMap<>(); //按渠道分组 for (MailboxInfoDO mailboxInfoDO : mailboxInfoDOList) { try{ String email = mailboxInfoDO.getEmail(); Integer channelId = channelEmailMapper.selectChannelIdByEmail(email); if(channelId == null){ continue; } if(!channelEmailMap.containsKey(channelId)){ List channelEmailList = new ArrayList<>(); channelEmailList.add(email); channelEmailMap.put(channelId,channelEmailList); }else{ List channelEmailList = channelEmailMap.get(channelId); channelEmailList.add(email); channelEmailMap.put(channelId,channelEmailList); } }catch (Exception e){ log.error(e.getMessage(),e); } } for (Integer channelId : channelEmailMap.keySet()) { List navDOList = navMapper.selectNavByChannelId(channelId); Map> fundIdNavMap = navDOList.stream().collect(Collectors.groupingBy(NavDO::getFundId)); for (String fundId : fundIdNavMap.keySet()) { String liquidateDate = fundInfoMapper.getLiquidateDateByFundId(fundId); if(StringUtil.isNotEmpty(liquidateDate)){ return; } String inceptionDate = fundInfoMapper.getInceptionDateByFundId(fundId); if(StringUtil.isEmpty(inceptionDate)){ return; } String today = DateUtils.getAroundToday(0); //获取基金对应的净值报送频率 FundReportFrequencyDO fundReportFrequencyDO = fundReportFrequencyMapper.getFrequencyByFundId(fundId); if(StringUtil.isNull(fundReportFrequencyDO)){ return; } List fundNavDOList = fundIdNavMap.get(fundId); //查询成立日到今天为止的交易日集合 List tradeDateDOList = tradeDateMapper.selectTradeDate(inceptionDate,today); navDeletion(channelId,fundId,fundNavDOList,tradeDateDOList,fundReportFrequencyDO); List assetDOList = assetMapper.selectAssetByFundId(fundId,channelId); List fundPositionDetailDOList = fundPositionDetailMapper.fundPositionDetailByFundId(fundId,channelId); assetDeletion(channelId,fundId,assetDOList,tradeDateDOList,fundReportFrequencyDO); distributionDeletion(channelId,fundId,navDOList); valuationDeletion(channelId,fundId,fundPositionDetailDOList,tradeDateDOList,fundReportFrequencyDO); } } } @Override public int countFundDeletion(String fundId) { return deletionInfoMapper.countFundDeletion(fundId); } @Override public List selectDeletionInfoByFundId(String fundId,String updateTime) { //只查询每日新增的缺失数据 return deletionInfoMapper.selectDeletionDetailByFundId(fundId,updateTime); } private void distributionDeletion(Integer channelId,String fundId, List navDOList) { if(navDOList.size() < 1){ return; } //将现有数据无效掉 deletionInfoMapper.deleteDeletion(channelId,fundId,DeletionType.DISTRIBUTION_DELETION.getCode()); //查询是否存在拆分 List distributionDOS = distributionMapper.getDistributionByFundId(channelId,fundId, DistributeType.DIVIDENDS_SPLIT.getCode()); if(distributionDOS.size() > 0){ //存在拆分,不做分红缺失计算,同时把以往的数据添加备注 deletionInfoMapper.updateRemark(channelId,fundId,DeletionType.DISTRIBUTION_DELETION.getCode(),null,DeletionType.EXIST_SPLIT.getInfo(),null); return; } BigDecimal threshold = new BigDecimal(0.0035); BigDecimal preDifference = new BigDecimal(0); List tradeDateList = new ArrayList<>(); for(int navIdx=0;navIdx < navDOList.size() ;navIdx++){ NavDO navDO = navDOList.get(navIdx); //获取当前净值日期下的分红总和 BigDecimal sumDistribute = distributionMapper.getSumDistributeByFundId(navDO.getFundId(),DateUtils.format(navDO.getPriceDate(),DateUtils.YYYY_MM_DD)); BigDecimal nav = navDO.getNav(); BigDecimal cumulativeNavWithdrawal = navDO.getCumulativeNavWithdrawal(); if(sumDistribute == null){ sumDistribute = new BigDecimal(0); } //判断当前的差值是否符合要求 BigDecimal difference = cumulativeNavWithdrawal.subtract(nav.add(sumDistribute)); if(difference.compareTo(threshold) > 0){ //存在缺失 String tradeDate = null; if(navIdx == 0 || navDOList.size() ==1){ //有且仅有一条数据 tradeDate = DateUtils.format(navDO.getPriceDate(),DateUtils.YYYY_MM_DD)+"~"+DateUtils.format(navDO.getPriceDate(),DateUtils.YYYY_MM_DD); }else{ //判断前一条的差值与当前是否一致,一致就不处理 if(difference.compareTo(preDifference) == 0){ continue; } tradeDate = DateUtils.format(navDOList.get(navIdx-1).getPriceDate(),DateUtils.YYYY_MM_DD)+"~"+DateUtils.format(navDO.getPriceDate(),DateUtils.YYYY_MM_DD); } tradeDateList.add(tradeDate); } preDifference = difference; } saveDeletionInfoDO(channelId,fundId,tradeDateList,DeletionType.DISTRIBUTION_DELETION.getCode()); } private void assetDeletion(Integer channelId,String fundId, List assetDOList, List tradeDateDOList, FundReportFrequencyDO fundReportFrequencyDO) { //将现有数据无效掉 deletionInfoMapper.deleteDeletion(channelId,fundId,DeletionType.ASSET_DELETION.getCode()); List tradeDateList = new ArrayList<>(); if(Frequency.DAY == Frequency.getFrequencyByCode(fundReportFrequencyDO.getAssetFrequency())){ Map> navListMap = assetDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getPriceDate(),DateUtils.YYYY_MM_DD))); Map> tradeListMap = tradeDateDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getTradeDate(),DateUtils.YYYY_MM_DD))); List updateTradeDateList = new ArrayList<>(); for(String tradeDate : tradeListMap.keySet()){ if(navListMap.containsKey(tradeDate)){ updateTradeDateList.add(tradeDate); continue; } if(tradeDateDOList.size() <= 3){ continue; } TradeDateDO tradeDateDO = tradeDateDOList.get(tradeDateDOList.size()-3); if(tradeDateDO.getTradeDate().compareTo(DateUtils.parse(tradeDate,DateUtils.YYYY_MM_DD)) < 0){ continue; } tradeDateList.add(tradeDate); } if(updateTradeDateList.size() > 0){ List batchUpdateDeletionInfoDO = new ArrayList<>(); for(String tradeDate : updateTradeDateList){ DeletionInfoDO deletionInfoDO = new DeletionInfoDO(); deletionInfoDO.setFundId(fundId); deletionInfoDO.setChannelId(channelId); deletionInfoDO.setDeletionType(DeletionType.ASSET_DELETION.getCode()); deletionInfoDO.setDeletionDate(tradeDate); deletionInfoDO.setRemark(DeletionType.NO_DELETION.getInfo()); batchUpdateDeletionInfoDO.add(deletionInfoDO); } deletionInfoMapper.batchUpdateRemark(batchUpdateDeletionInfoDO); } //写入缺失信息表 saveDeletionInfoDO(channelId,fundId,tradeDateList,DeletionType.ASSET_DELETION.getCode()); } if(Frequency.WEEK == Frequency.getFrequencyByCode(fundReportFrequencyDO.getAssetFrequency())){ Map> navListMap = assetDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getPriceDate(),DateUtils.YYYY_MM_DD))); TreeMap> weekNavListMap = new TreeMap<>(); //按周数整合 for(String priceDate : navListMap.keySet()){ Integer weekOfYear = Integer.parseInt(priceDate.substring(0,4)+DateUtil.weekOfYear(DateUtils.parse(priceDate,DateUtils.YYYY_MM_DD))); if(weekNavListMap.containsKey(weekOfYear)){ List assetDOS = weekNavListMap.get(weekOfYear); assetDOS.addAll(navListMap.get(priceDate)); weekNavListMap.put(weekOfYear,assetDOS); }else{ List navDOS = new ArrayList<>(); navDOS.addAll(navListMap.get(priceDate)); weekNavListMap.put(weekOfYear,navDOS); } } Map> tradeListMap = tradeDateDOList.stream().collect(Collectors.groupingBy(e -> e.getYearWeek())); for(Integer weekOfYear : tradeListMap.keySet()){ List assetDOS = weekNavListMap.get(weekOfYear); if(weekNavListMap.containsKey(weekOfYear)){ List updateTradeDateList = new ArrayList<>(); for(TradeDateDO tradeDateDO : tradeListMap.get(weekOfYear)){ String tradeDate = DateUtils.format(tradeDateDO.getTradeDate(),DateUtils.YYYY_MM_DD); updateTradeDateList.add(tradeDate); } if(updateTradeDateList.size() > 0){ List batchUpdateDeletionInfoDO = new ArrayList<>(); for(String tradeDate : updateTradeDateList){ DeletionInfoDO deletionInfoDO = new DeletionInfoDO(); deletionInfoDO.setFundId(fundId); deletionInfoDO.setDeletionType(DeletionType.ASSET_DELETION.getCode()); deletionInfoDO.setDeletionDate(tradeDate); deletionInfoDO.setRemark(DeletionType.NO_DELETION.getInfo()); batchUpdateDeletionInfoDO.add(deletionInfoDO); } deletionInfoMapper.batchUpdateRemark(batchUpdateDeletionInfoDO); } continue; }else{ if(StringUtil.isNotEmpty(assetDOS)){ List deleteTradeDateList = new ArrayList<>(); for(int idx=0;idx < assetDOS.size()-1 ; idx++){ AssetDO assetDO = assetDOS.get(idx); String tradeDate = DateUtils.format(assetDO.getPriceDate(),DateUtils.YYYY_MM_DD); deleteTradeDateList.add(tradeDate); } deletionInfoMapper.deleteDeletionRemark(fundId,DeletionType.ASSET_DELETION.getCode(),deleteTradeDateList); } } //不包含的话,默认取每周的最后一个交易日作为周净值日期 List tradeDateDOS = tradeListMap.get(weekOfYear); String tradeDate = null; if(tradeDateDOS.size() > 0){ tradeDate = DateUtils.format(tradeDateDOS.get(tradeDateDOS.size()-1).getTradeDate(),DateUtils.YYYY_MM_DD); } //判断当前缺失交易日是否是近三个交易日 if(tradeDateDOList.size() <= 3){ continue; } TradeDateDO tradeDateDO = tradeDateDOList.get(tradeDateDOList.size()-3); if(tradeDateDO.getTradeDate().compareTo(DateUtils.parse(tradeDate,DateUtils.YYYY_MM_DD)) < 0){ continue; } tradeDateList.add(tradeDate); } //写入缺失信息表 saveDeletionInfoDO(channelId,fundId,tradeDateList,DeletionType.ASSET_DELETION.getCode()); } if(Frequency.MONTH == Frequency.getFrequencyByCode(fundReportFrequencyDO.getAssetFrequency())){ Map> navListMap = assetDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getPriceDate(),DateUtils.YYYY_MM_DD))); TreeMap> monthNavListMap = new TreeMap<>(); //按周数整合 for(String priceDate : navListMap.keySet()){ String yearMonth = priceDate.substring(0,7); if(monthNavListMap.containsKey(yearMonth)){ List navDOS = monthNavListMap.get(yearMonth); navDOS.addAll(navListMap.get(priceDate)); monthNavListMap.put(yearMonth,navDOS); }else{ List navDOS = new ArrayList<>(); navDOS.addAll(navListMap.get(priceDate)); monthNavListMap.put(yearMonth,navDOS); } } Map> tradeListMap = tradeDateDOList.stream().collect(Collectors.groupingBy(e -> e.getYearmonth())); for(String yearMonth : tradeListMap.keySet()){ //本月的数据不考虑 String thisMonth = DateUtils.format(new Date(),DateUtils.YYYY_MM); if(yearMonth.equals(thisMonth)){ continue; } List assetDOS = monthNavListMap.get(yearMonth); if(monthNavListMap.containsKey(yearMonth)){ List updateTradeDateList = new ArrayList<>(); for(TradeDateDO tradeDateDO : tradeListMap.get(yearMonth)){ String tradeDate = DateUtils.format(tradeDateDO.getTradeDate(),DateUtils.YYYY_MM_DD); updateTradeDateList.add(tradeDate); } if(updateTradeDateList.size() > 0){ List batchUpdateDeletionInfoDO = new ArrayList<>(); for(String tradeDate : updateTradeDateList){ DeletionInfoDO deletionInfoDO = new DeletionInfoDO(); deletionInfoDO.setFundId(fundId); deletionInfoDO.setDeletionType(DeletionType.ASSET_DELETION.getCode()); deletionInfoDO.setDeletionDate(tradeDate); deletionInfoDO.setRemark(DeletionType.NO_DELETION.getInfo()); batchUpdateDeletionInfoDO.add(deletionInfoDO); } deletionInfoMapper.batchUpdateRemark(batchUpdateDeletionInfoDO); } continue; }else{ if(StringUtil.isNotEmpty(assetDOS)){ List deleteTradeDateList = new ArrayList<>(); for(int idx=0;idx < assetDOS.size()-1 ; idx++){ AssetDO assetDO = assetDOS.get(idx); String tradeDate = DateUtils.format(assetDO.getPriceDate(),DateUtils.YYYY_MM_DD); deleteTradeDateList.add(tradeDate); } deletionInfoMapper.deleteDeletionRemark(fundId,DeletionType.ASSET_DELETION.getCode(),deleteTradeDateList); } } //不包含的话,默认取每月的最后一个交易日作为周净值日期 List tradeDateDOS = tradeListMap.get(yearMonth); String tradeDate = null; if(tradeDateDOS.size() > 0){ tradeDate = DateUtils.format(tradeDateDOS.get(tradeDateDOS.size()-1).getTradeDate(),DateUtils.YYYY_MM_DD); } if(tradeDateDOList.size() <= 3){ continue; } TradeDateDO tradeDateDO = tradeDateDOList.get(tradeDateDOList.size()-3); if(tradeDateDO.getTradeDate().compareTo(DateUtils.parse(tradeDate,DateUtils.YYYY_MM_DD)) < 0){ continue; } tradeDateList.add(tradeDate); } //写入缺失信息表 saveDeletionInfoDO(channelId,fundId,tradeDateList,DeletionType.ASSET_DELETION.getCode()); } } private void navDeletion(Integer channelId,String fundId,List navDOList, List tradeDateDOList,FundReportFrequencyDO fundReportFrequencyDO) { //将现有数据无效掉 deletionInfoMapper.deleteDeletion(channelId,fundId,DeletionType.NAV_DELETION.getCode()); List tradeDateList = new ArrayList<>(); //只处理日月季频率 if(Frequency.DAY == Frequency.getFrequencyByCode(fundReportFrequencyDO.getNavFrequency())){ Map> navListMap = navDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getPriceDate(),DateUtils.YYYY_MM_DD))); Map> tradeListMap = tradeDateDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getTradeDate(),DateUtils.YYYY_MM_DD))); List updateTradeDateList = new ArrayList<>(); for(String tradeDate : tradeListMap.keySet()){ if(navListMap.containsKey(tradeDate)){ updateTradeDateList.add(tradeDate); continue; } if(tradeDateDOList.size() <= 3){ continue; } TradeDateDO tradeDateDO = tradeDateDOList.get(tradeDateDOList.size()-3); if(tradeDateDO.getTradeDate().compareTo(DateUtils.parse(tradeDate,DateUtils.YYYY_MM_DD)) < 0){ continue; } tradeDateList.add(tradeDate); } if(updateTradeDateList.size() > 0){ List batchUpdateDeletionInfoDO = new ArrayList<>(); for(String tradeDate : updateTradeDateList){ DeletionInfoDO deletionInfoDO = new DeletionInfoDO(); deletionInfoDO.setFundId(fundId); deletionInfoDO.setChannelId(channelId); deletionInfoDO.setDeletionType(DeletionType.NAV_DELETION.getCode()); deletionInfoDO.setDeletionDate(tradeDate); deletionInfoDO.setRemark(DeletionType.NO_DELETION.getInfo()); batchUpdateDeletionInfoDO.add(deletionInfoDO); } deletionInfoMapper.batchUpdateRemark(batchUpdateDeletionInfoDO); } //写入缺失信息表 saveDeletionInfoDO(channelId,fundId,tradeDateList,DeletionType.NAV_DELETION.getCode()); } if(Frequency.WEEK == Frequency.getFrequencyByCode(fundReportFrequencyDO.getNavFrequency())){ Map> navListMap = navDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getPriceDate(),DateUtils.YYYY_MM_DD))); TreeMap> weekNavListMap = new TreeMap<>(); //按周数整合 for(String priceDate : navListMap.keySet()){ Integer weekOfYear = Integer.parseInt(priceDate.substring(0,4)+DateUtil.weekOfYear(DateUtils.parse(priceDate,DateUtils.YYYY_MM_DD)));; if(weekNavListMap.containsKey(weekOfYear)){ List navDOS = weekNavListMap.get(weekOfYear); navDOS.addAll(navListMap.get(priceDate)); weekNavListMap.put(weekOfYear,navDOS); }else{ List navDOS = new ArrayList<>(); navDOS.addAll(navListMap.get(priceDate)); weekNavListMap.put(weekOfYear,navDOS); } } Map> tradeListMap = tradeDateDOList.stream().collect(Collectors.groupingBy(e -> e.getYearWeek())); for(Integer weekOfYear : tradeListMap.keySet()){ List navDOS = weekNavListMap.get(weekOfYear); if(weekNavListMap.containsKey(weekOfYear)){ List deleteTradeDateList = new ArrayList<>(); for(TradeDateDO tradeDateDO : tradeListMap.get(weekOfYear)){ String tradeDate = DateUtils.format(tradeDateDO.getTradeDate(),DateUtils.YYYY_MM_DD); deleteTradeDateList.add(tradeDate); } if(deleteTradeDateList.size() > 0){ List batchUpdateDeletionInfoDO = new ArrayList<>(); for(String tradeDate : deleteTradeDateList){ DeletionInfoDO deletionInfoDO = new DeletionInfoDO(); deletionInfoDO.setFundId(fundId); deletionInfoDO.setDeletionType(DeletionType.NAV_DELETION.getCode()); deletionInfoDO.setDeletionDate(tradeDate); deletionInfoDO.setRemark(DeletionType.NO_DELETION.getInfo()); batchUpdateDeletionInfoDO.add(deletionInfoDO); } deletionInfoMapper.batchUpdateRemark(batchUpdateDeletionInfoDO); } continue; }else{ //防止频率变更导致数据异常,需要把当前日期下所在的频率全部无效掉 if(StringUtil.isNotEmpty(navDOS)){ List deleteTradeDateList = new ArrayList<>(); for(int idx=0;idx < navDOS.size()-1 ; idx++){ NavDO navDO = navDOS.get(idx); String tradeDate = DateUtils.format(navDO.getPriceDate(),DateUtils.YYYY_MM_DD); deleteTradeDateList.add(tradeDate); } deletionInfoMapper.deleteDeletionRemark(fundId,DeletionType.NAV_DELETION.getCode(),deleteTradeDateList); } } //不包含的话,默认取每周的最后一个交易日作为周净值日期 List tradeDateDOS = tradeListMap.get(weekOfYear); String tradeDate = null; if(tradeDateDOS.size() > 0){ tradeDate = DateUtils.format(tradeDateDOS.get(tradeDateDOS.size()-1).getTradeDate(),DateUtils.YYYY_MM_DD); } if(tradeDateDOList.size() <= 3){ continue; } TradeDateDO tradeDateDO = tradeDateDOList.get(tradeDateDOList.size()-3); if(tradeDateDO.getTradeDate().compareTo(DateUtils.parse(tradeDate,DateUtils.YYYY_MM_DD)) < 0){ continue; } tradeDateList.add(tradeDate); } //写入缺失信息表 saveDeletionInfoDO(channelId,fundId,tradeDateList,DeletionType.NAV_DELETION.getCode()); } if(Frequency.MONTH == Frequency.getFrequencyByCode(fundReportFrequencyDO.getNavFrequency())){ Map> navListMap = navDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getPriceDate(),DateUtils.YYYY_MM_DD))); TreeMap> monthNavListMap = new TreeMap<>(); //按周数整合 for(String priceDate : navListMap.keySet()){ String yearMonth = priceDate.substring(0,7); if(monthNavListMap.containsKey(yearMonth)){ List navDOS = monthNavListMap.get(yearMonth); navDOS.addAll(navListMap.get(priceDate)); monthNavListMap.put(yearMonth,navDOS); }else{ List navDOS = new ArrayList<>(); navDOS.addAll(navListMap.get(priceDate)); monthNavListMap.put(yearMonth,navDOS); } } Map> tradeListMap = tradeDateDOList.stream().collect(Collectors.groupingBy(e -> e.getYearmonth())); for(String yearMonth : tradeListMap.keySet()){ //本月的数据不考虑 String thisMonth = DateUtils.format(new Date(),DateUtils.YYYY_MM); if(yearMonth.equals(thisMonth)){ continue; } List navDOS = monthNavListMap.get(yearMonth); if(monthNavListMap.containsKey(yearMonth)){ List batchUpdateTradeList = new ArrayList<>(); for(TradeDateDO tradeDateDO : tradeListMap.get(yearMonth)){ String tradeDate = DateUtils.format(tradeDateDO.getTradeDate(),DateUtils.YYYY_MM_DD); batchUpdateTradeList.add(tradeDate); } if(batchUpdateTradeList.size() > 0){ List batchUpdateDeletionInfoDO = new ArrayList<>(); for(String tradeDate : batchUpdateTradeList){ DeletionInfoDO deletionInfoDO = new DeletionInfoDO(); deletionInfoDO.setFundId(fundId); deletionInfoDO.setDeletionType(DeletionType.NAV_DELETION.getCode()); deletionInfoDO.setDeletionDate(tradeDate); deletionInfoDO.setRemark(DeletionType.NO_DELETION.getInfo()); batchUpdateDeletionInfoDO.add(deletionInfoDO); } deletionInfoMapper.batchUpdateRemark(batchUpdateDeletionInfoDO); } continue; }else{ //防止频率变更导致数据异常,需要把当前日期下所在的频率全部无效掉 if(StringUtil.isNotEmpty(navDOS)){ List deleteTradeDateList = new ArrayList<>(); for(NavDO navDO : navDOS){ String tradeDate = DateUtils.format(navDO.getPriceDate(),DateUtils.YYYY_MM_DD); deleteTradeDateList.add(tradeDate); } deletionInfoMapper.deleteDeletionRemark(fundId,DeletionType.NAV_DELETION.getCode(),deleteTradeDateList); } } //不包含的话,默认取每月的最后一个交易日作为周净值日期 List tradeDateDOS = tradeListMap.get(yearMonth); String tradeDate = null; if(tradeDateDOS.size() > 0){ tradeDate = DateUtils.format(tradeDateDOS.get(tradeDateDOS.size()-1).getTradeDate(),DateUtils.YYYY_MM_DD); } if(tradeDateDOList.size() <= 3){ continue; } TradeDateDO tradeDateDO = tradeDateDOList.get(tradeDateDOList.size()-3); if(tradeDateDO.getTradeDate().compareTo(DateUtils.parse(tradeDate,DateUtils.YYYY_MM_DD)) < 0){ continue; } tradeDateList.add(tradeDate); } //写入缺失信息表 saveDeletionInfoDO(channelId,fundId,tradeDateList,DeletionType.NAV_DELETION.getCode()); } } private void valuationDeletion(Integer channelId,String fundId,List fundPositionDetailDOList, List tradeDateDOList,FundReportFrequencyDO fundReportFrequencyDO) { //将现有数据无效掉 deletionInfoMapper.deleteDeletion(channelId,fundId,DeletionType.VALUATION_DELETION.getCode()); List tradeDateList = new ArrayList<>(); //只处理日月季频率 if(Frequency.DAY == Frequency.getFrequencyByCode(fundReportFrequencyDO.getValuationFrequency())){ Map> valuationListMap = fundPositionDetailDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getValuationDate(),DateUtils.YYYY_MM_DD))); Map> tradeListMap = tradeDateDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getTradeDate(),DateUtils.YYYY_MM_DD))); List batchUpdateTrade = new ArrayList<>(); for(String tradeDate : tradeListMap.keySet()){ if(valuationListMap.containsKey(tradeDate)){ batchUpdateTrade.add(tradeDate); continue; } if(tradeDateDOList.size() <= 3){ continue; } TradeDateDO tradeDateDO = tradeDateDOList.get(tradeDateDOList.size()-3); if(tradeDateDO.getTradeDate().compareTo(DateUtils.parse(tradeDate,DateUtils.YYYY_MM_DD)) < 0){ continue; } tradeDateList.add(tradeDate); } if(batchUpdateTrade.size() > 0){ List batchUpdateDeletionInfoDO = new ArrayList<>(); for(String tradeDate : batchUpdateTrade){ DeletionInfoDO deletionInfoDO = new DeletionInfoDO(); deletionInfoDO.setFundId(fundId); deletionInfoDO.setDeletionType(DeletionType.VALUATION_DELETION.getCode()); deletionInfoDO.setDeletionDate(tradeDate); deletionInfoDO.setRemark(DeletionType.NO_DELETION.getInfo()); batchUpdateDeletionInfoDO.add(deletionInfoDO); } deletionInfoMapper.batchUpdateRemark(batchUpdateDeletionInfoDO); } //写入缺失信息表 saveDeletionInfoDO(channelId,fundId,tradeDateList,DeletionType.VALUATION_DELETION.getCode()); } if(Frequency.WEEK == Frequency.getFrequencyByCode(fundReportFrequencyDO.getValuationFrequency())){ Map> valuationListMap = fundPositionDetailDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getValuationDate(),DateUtils.YYYY_MM_DD))); TreeMap> weekNavListMap = new TreeMap<>(); //按周数整合 for(String priceDate : valuationListMap.keySet()){ Integer weekOfYear = Integer.parseInt(priceDate.substring(0,4)+DateUtil.weekOfYear(DateUtils.parse(priceDate,DateUtils.YYYY_MM_DD)));; if(weekNavListMap.containsKey(weekOfYear)){ List valuationDOS = weekNavListMap.get(weekOfYear); valuationDOS.addAll(valuationListMap.get(priceDate)); weekNavListMap.put(weekOfYear,valuationDOS); }else{ List valuationDOS = new ArrayList<>(); valuationDOS.addAll(valuationListMap.get(priceDate)); weekNavListMap.put(weekOfYear,valuationDOS); } } Map> tradeListMap = tradeDateDOList.stream().collect(Collectors.groupingBy(e -> e.getYearWeek())); for(Integer weekOfYear : tradeListMap.keySet()){ List valuationDOS = weekNavListMap.get(weekOfYear); if(weekNavListMap.containsKey(weekOfYear)){ List batchUpdateTradeList = new ArrayList<>(); for(TradeDateDO tradeDateDO : tradeListMap.get(weekOfYear)){ String tradeDate = DateUtils.format(tradeDateDO.getTradeDate(),DateUtils.YYYY_MM_DD); batchUpdateTradeList.add(tradeDate); } if(batchUpdateTradeList.size() > 0){ List batchUpdateDeletionInfoDO = new ArrayList<>(); for(String tradeDate : batchUpdateTradeList){ DeletionInfoDO deletionInfoDO = new DeletionInfoDO(); deletionInfoDO.setFundId(fundId); deletionInfoDO.setDeletionType(DeletionType.VALUATION_DELETION.getCode()); deletionInfoDO.setDeletionDate(tradeDate); deletionInfoDO.setRemark(DeletionType.NO_DELETION.getInfo()); batchUpdateDeletionInfoDO.add(deletionInfoDO); } deletionInfoMapper.batchUpdateRemark(batchUpdateDeletionInfoDO); } continue; }else{ //防止频率变更导致数据异常,需要把当前日期下所在的频率全部无效掉 if(StringUtil.isNotEmpty(valuationDOS)){ List deleteTradeDateList = new ArrayList<>(); for(int idx=0;idx < valuationDOS.size()-1 ; idx++){ FundPositionDetailDO valautionDO = valuationDOS.get(idx); String tradeDate = DateUtils.format(valautionDO.getValuationDate(),DateUtils.YYYY_MM_DD); deleteTradeDateList.add(tradeDate); } deletionInfoMapper.deleteDeletionRemark(fundId,DeletionType.VALUATION_DELETION.getCode(),deleteTradeDateList); } } //不包含的话,默认取每周的最后一个交易日作为周净值日期 List tradeDateDOS = tradeListMap.get(weekOfYear); String tradeDate = null; if(tradeDateDOS.size() > 0){ tradeDate = DateUtils.format(tradeDateDOS.get(tradeDateDOS.size()-1).getTradeDate(),DateUtils.YYYY_MM_DD); } if(tradeDateDOList.size() <= 3){ continue; } TradeDateDO tradeDateDO = tradeDateDOList.get(tradeDateDOList.size()-3); if(tradeDateDO.getTradeDate().compareTo(DateUtils.parse(tradeDate,DateUtils.YYYY_MM_DD)) < 0){ continue; } tradeDateList.add(tradeDate); } //写入缺失信息表 saveDeletionInfoDO(channelId,fundId,tradeDateList,DeletionType.VALUATION_DELETION.getCode()); } if(Frequency.MONTH == Frequency.getFrequencyByCode(fundReportFrequencyDO.getValuationFrequency())){ Map> valuationListMap = fundPositionDetailDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getValuationDate(),DateUtils.YYYY_MM_DD))); TreeMap> monthNavListMap = new TreeMap<>(); //按周数整合 for(String priceDate : valuationListMap.keySet()){ String yearMonth = priceDate.substring(0,7); if(monthNavListMap.containsKey(yearMonth)){ List fundPositionDetailDOS = monthNavListMap.get(yearMonth); fundPositionDetailDOS.addAll(valuationListMap.get(priceDate)); monthNavListMap.put(yearMonth,fundPositionDetailDOS); }else{ List fundPositionDetailDOS = new ArrayList<>(); fundPositionDetailDOS.addAll(valuationListMap.get(priceDate)); monthNavListMap.put(yearMonth,fundPositionDetailDOS); } } Map> tradeListMap = tradeDateDOList.stream().collect(Collectors.groupingBy(e -> e.getYearmonth())); for(String yearMonth : tradeListMap.keySet()){ //本月的数据不考虑 String thisMonth = DateUtils.format(new Date(),DateUtils.YYYY_MM); if(yearMonth.equals(thisMonth)){ continue; } List fundPositionDetailDOS = monthNavListMap.get(yearMonth); if(monthNavListMap.containsKey(yearMonth)){ List batchUpdateTradeList = new ArrayList<>(); for(TradeDateDO tradeDateDO : tradeListMap.get(yearMonth)){ String tradeDate = DateUtils.format(tradeDateDO.getTradeDate(),DateUtils.YYYY_MM_DD); batchUpdateTradeList.add(tradeDate); } if(batchUpdateTradeList.size() > 0){ List batchUpdateDeletionInfoDO = new ArrayList<>(); for(String tradeDate : batchUpdateTradeList){ DeletionInfoDO deletionInfoDO = new DeletionInfoDO(); deletionInfoDO.setFundId(fundId); deletionInfoDO.setDeletionType(DeletionType.VALUATION_DELETION.getCode()); deletionInfoDO.setDeletionDate(tradeDate); deletionInfoDO.setRemark(DeletionType.NO_DELETION.getInfo()); batchUpdateDeletionInfoDO.add(deletionInfoDO); } deletionInfoMapper.batchUpdateRemark(batchUpdateDeletionInfoDO); } continue; }else{ //防止频率变更导致数据异常,需要把当前日期下所在的频率全部无效掉 if(StringUtil.isNotEmpty(fundPositionDetailDOS)){ List deleteTradeDateList = new ArrayList<>(); for(FundPositionDetailDO fundPositionDetailDO : fundPositionDetailDOS){ String tradeDate = DateUtils.format(fundPositionDetailDO.getValuationDate(),DateUtils.YYYY_MM_DD); deleteTradeDateList.add(tradeDate); } deletionInfoMapper.deleteDeletionRemark(fundId,DeletionType.VALUATION_DELETION.getCode(),deleteTradeDateList); } } //不包含的话,默认取每月的最后一个交易日作为周净值日期 List tradeDateDOS = tradeListMap.get(yearMonth); String tradeDate = null; if(tradeDateDOS.size() > 0){ tradeDate = DateUtils.format(tradeDateDOS.get(tradeDateDOS.size()-1).getTradeDate(),DateUtils.YYYY_MM_DD); } if(tradeDateDOList.size() <= 3){ continue; } TradeDateDO tradeDateDO = tradeDateDOList.get(tradeDateDOList.size()-3); if(tradeDateDO.getTradeDate().compareTo(DateUtils.parse(tradeDate,DateUtils.YYYY_MM_DD)) < 0){ continue; } tradeDateList.add(tradeDate); } //写入缺失信息表 saveDeletionInfoDO(channelId,fundId,tradeDateList,DeletionType.VALUATION_DELETION.getCode()); } } private void saveDeletionInfoDO(Integer channelId,String fundId, List tradeDateList, Integer code) { if(tradeDateList.size() < 1){ return; } List oldDeletionDOList = deletionInfoMapper.getDeletionInfoDO(channelId,fundId,code,tradeDateList); if(oldDeletionDOList != null && oldDeletionDOList.size() > 0){ for(DeletionInfoDO oldDeletionDO : oldDeletionDOList){ oldDeletionDO.setIsvalid(1); oldDeletionDO.setUpdateTime(DateUtils.getNowDate()); } deletionInfoMapper.batchUpdateDeletionInfoDO(oldDeletionDOList); } List oldTradeDateList = oldDeletionDOList.stream().map(e -> e.getDeletionDate()).collect(Collectors.toList()); List insertTradeDateList = new ArrayList<>(); for(String tradeDate : tradeDateList){ if(oldTradeDateList.contains(tradeDate)){ continue; } insertTradeDateList.add(tradeDate); } if(insertTradeDateList.size() > 0){ List insertDeletionInfoDO = new ArrayList<>(); for(String tradeDate : insertTradeDateList){ DeletionInfoDO deletionInfoDO = new DeletionInfoDO(); deletionInfoDO.setFundId(fundId); deletionInfoDO.setChannelId(channelId); deletionInfoDO.setDeletionType(code); deletionInfoDO.setDeletionDate(tradeDate); deletionInfoDO.setIsvalid(1); deletionInfoDO.setIsSend(0); deletionInfoDO.setUpdateTime(DateUtils.getNowDate()); deletionInfoDO.setCreateTime(DateUtils.getNowDate()); insertDeletionInfoDO.add(deletionInfoDO); } deletionInfoMapper.batchSaveDeletionInfoDO(insertDeletionInfoDO); } } }