DeletionServiceImpl.java 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. package com.simuwang.manage.service.impl;
  2. import cn.hutool.core.date.DateUtil;
  3. import com.simuwang.base.common.enums.DeletionType;
  4. import com.simuwang.base.common.enums.DistributeType;
  5. import com.simuwang.base.common.enums.Frequency;
  6. import com.simuwang.base.common.support.MybatisPage;
  7. import com.simuwang.base.common.util.DateUtils;
  8. import com.simuwang.base.common.util.StringUtil;
  9. import com.simuwang.base.mapper.*;
  10. import com.simuwang.base.pojo.dos.*;
  11. import com.simuwang.base.pojo.dto.DeletionDownParam;
  12. import com.simuwang.base.pojo.dto.ExcelDeletionInfoDTO;
  13. import com.simuwang.base.pojo.dto.query.DeletionPageQuery;
  14. import com.simuwang.base.pojo.dto.query.FundDeletionPageQuery;
  15. import com.simuwang.base.pojo.vo.*;
  16. import com.simuwang.manage.service.DeletionService;
  17. import com.simuwang.shiro.utils.UserUtils;
  18. import org.springframework.beans.factory.annotation.Autowired;
  19. import org.springframework.stereotype.Service;
  20. import java.math.BigDecimal;
  21. import java.util.*;
  22. import java.util.stream.Collectors;
  23. /**
  24. * FileName: DeletionServiceImpl
  25. * Author: chenjianhua
  26. * Date: 2024/9/17 18:54
  27. * Description: ${DESCRIPTION}
  28. */
  29. @Service
  30. public class DeletionServiceImpl implements DeletionService {
  31. @Autowired
  32. private DeletionInfoMapper deletionInfoMapper;
  33. @Autowired
  34. private FundInfoMapper fundInfoMapper;
  35. @Autowired
  36. private AssetMapper assetMapper;
  37. @Autowired
  38. private FundReportFrequencyMapper fundReportFrequencyMapper;
  39. @Autowired
  40. private TradeDateMapper tradeDateMapper;
  41. @Autowired
  42. private DistributionMapper distributionMapper;
  43. @Autowired
  44. private NavMapper navMapper;
  45. @Override
  46. public MybatisPage<DeletionInfoVO> searchDeletionList(DeletionPageQuery deletionPageQuery) {
  47. List<DeletionInfoDO> deletionInfoDOList = deletionInfoMapper.searchDeletionList(deletionPageQuery);
  48. long total = deletionInfoMapper.countDeletion(deletionPageQuery);
  49. List<DeletionInfoVO> dataList = deletionInfoDOList.stream().map(DeletionInfoDO::toVO).collect(Collectors.toList());
  50. for(DeletionInfoVO vo : dataList){
  51. String fundId = vo.getFundId();
  52. String lastDeletionDate = deletionInfoMapper.getLastDeletionDateByFundId(fundId,vo.getDeletionType());
  53. vo.setLastDeletionDate(lastDeletionDate);
  54. }
  55. return MybatisPage.of(total,dataList);
  56. }
  57. @Override
  58. public MybatisPage<FundDeletionInfoVO> searchFundDeletionList(FundDeletionPageQuery fundDeletionPageQuery) {
  59. List<FundDeletionInfoDO> deletionInfoDOList = deletionInfoMapper.searchFundDeletionList(fundDeletionPageQuery);
  60. long total = deletionInfoMapper.countFundDeletionList(fundDeletionPageQuery);
  61. List<FundDeletionInfoVO> dataList = deletionInfoDOList.stream().map(FundDeletionInfoDO::toVO).collect(Collectors.toList());
  62. for(FundDeletionInfoVO infoVO : dataList){
  63. infoVO.setFundName(fundInfoMapper.getFundNameByFundId(infoVO.getFundId()));
  64. }
  65. return MybatisPage.of(total,dataList);
  66. }
  67. @Override
  68. public void saveFundDeletionList(List<FundDeletionInfoVO> fundDeletionInfoVOList) {
  69. List<FundDeletionInfoDO> fundDeletionInfoDOList = new ArrayList<>();
  70. for(FundDeletionInfoVO vo : fundDeletionInfoVOList){
  71. FundDeletionInfoDO fundDeletionInfoDO = new FundDeletionInfoDO();
  72. fundDeletionInfoDO.setId(vo.getId());
  73. fundDeletionInfoDO.setDeletionType(vo.getDeletionType());
  74. fundDeletionInfoDO.setFundId(vo.getFundId());
  75. fundDeletionInfoDO.setDeletionDate(vo.getDeletionDate());
  76. fundDeletionInfoDO.setRemark(vo.getRemark());
  77. fundDeletionInfoDO.setIsvalid(1);
  78. fundDeletionInfoDO.setUpdateTime(DateUtils.getNowDate());
  79. fundDeletionInfoDO.setUpdaterId(UserUtils.getLoginUser().getUserId());
  80. fundDeletionInfoDOList.add(fundDeletionInfoDO);
  81. }
  82. deletionInfoMapper.batchUpdate(fundDeletionInfoDOList);
  83. }
  84. @Override
  85. public void saveBatchDeletionRemark(FundDeletionRemarkVO fundDeletionRemarkVO) {
  86. String remark = fundDeletionRemarkVO.getRemark();
  87. Integer userId = UserUtils.getLoginUser().getUserId();
  88. for(FundDeletionTypeVO remarkVO : fundDeletionRemarkVO.getFundDeletionTypeList()){
  89. deletionInfoMapper.updateRemark(remarkVO.getFundId(),remarkVO.getDeletionType(),remarkVO.getDeletionDate(),remark,userId);
  90. }
  91. }
  92. @Override
  93. public List<ExcelDeletionInfoDTO> selectFundDeletionInfoVOList(FundDeletionListVO fundDeletionListVO) {
  94. List<ExcelDeletionInfoDTO> result = new ArrayList<>();
  95. List<DeletionDownParam> deletionDownParamList = fundDeletionListVO.getDeletionDownParamList();
  96. for(DeletionDownParam deletionDownParam : deletionDownParamList){
  97. List<FundDeletionInfoDO> deletionInfoDOList = deletionInfoMapper.selectFundDeletionInfoVOList(deletionDownParam.getFundId(),deletionDownParam.getDeletionType());
  98. for(FundDeletionInfoDO infoDO : deletionInfoDOList){
  99. ExcelDeletionInfoDTO dto = new ExcelDeletionInfoDTO();
  100. dto.setFundName(fundInfoMapper.getFundNameByFundId(infoDO.getFundId()));
  101. dto.setCompanyName(fundInfoMapper.getCompanyNameByFundId(infoDO.getFundId()));
  102. dto.setDeletionType(DeletionType.getDeletionTypeByCode(infoDO.getDeletionType()).getInfo());
  103. dto.setDeletionDate(infoDO.getDeletionDate());
  104. dto.setRemark(infoDO.getRemark());
  105. dto.setFundId(infoDO.getFundId());
  106. result.add(dto);
  107. }
  108. }
  109. return result;
  110. }
  111. @Override
  112. public void computeDeletion(DeletionDownParam deletionDownParam) {
  113. String fundId = deletionDownParam.getFundId();
  114. String liquidateDate = fundInfoMapper.getLiquidateDateByFundId(fundId);
  115. if(StringUtil.isNotEmpty(liquidateDate)){
  116. return;
  117. }
  118. String inceptionDate = fundInfoMapper.getInceptionDateByFundId(fundId);
  119. if(StringUtil.isEmpty(inceptionDate)){
  120. return;
  121. }
  122. String today = DateUtils.getAroundToday(0);
  123. //获取基金对应的净值报送频率
  124. FundReportFrequencyDO fundReportFrequencyDO = fundReportFrequencyMapper.getFrequencyByFundId(fundId);
  125. if(StringUtil.isNull(fundReportFrequencyDO)){
  126. return;
  127. }
  128. List<NavDO> navDOList = navMapper.selectNavByFundId(fundId);
  129. List<AssetDO> assetDOList = assetMapper.selectAssetByFundId(fundId);
  130. //查询成立日到今天为止的交易日集合
  131. List<TradeDateDO> tradeDateDOList = tradeDateMapper.selectTradeDate(inceptionDate,today);
  132. if(deletionDownParam.getDeletionType() != null && deletionDownParam.getDeletionType().equals(DeletionType.NAV_DELETION.getCode())){
  133. navDeletion(fundId,navDOList,tradeDateDOList,fundReportFrequencyDO);
  134. }else if(deletionDownParam.getDeletionType() != null && deletionDownParam.getDeletionType().equals(DeletionType.ASSET_DELETION.getCode())){
  135. assetDeletion(fundId,assetDOList,tradeDateDOList,fundReportFrequencyDO);
  136. }else if(deletionDownParam.getDeletionType() != null && deletionDownParam.getDeletionType().equals(DeletionType.DISTRIBUTION_DELETION.getCode())){
  137. distributionDeletion(fundId,navDOList);
  138. }else{
  139. navDeletion(fundId,navDOList,tradeDateDOList,fundReportFrequencyDO);
  140. assetDeletion(fundId,assetDOList,tradeDateDOList,fundReportFrequencyDO);
  141. distributionDeletion(fundId,navDOList);
  142. }
  143. }
  144. private void distributionDeletion(String fundId, List<NavDO> navDOList) {
  145. if(navDOList.size() < 1){
  146. return;
  147. }
  148. //查询是否存在拆分
  149. List<DistributionDO> distributionDOS = distributionMapper.getDistributionByFundId(fundId, DistributeType.DIVIDENDS_SPLIT);
  150. if(distributionDOS.size() > 0){
  151. //存在拆分,不做分红缺失计算,同时把以往的数据添加备注
  152. deletionInfoMapper.updateRemark(fundId,DeletionType.ASSET_DELETION.getCode(),null,DeletionType.EXIST_SPLIT.getInfo(),null);
  153. return;
  154. }
  155. BigDecimal threshold = new BigDecimal(0.0035);
  156. BigDecimal preDifference = new BigDecimal(0);
  157. for(int navIdx=0;navIdx < navDOList.size() ;navIdx++){
  158. NavDO navDO = navDOList.get(navIdx);
  159. //获取当前净值日期下的分红总和
  160. BigDecimal sumDistribute = distributionMapper.getSumDistributeByFundId(navDO.getFundId(),DateUtils.format(navDO.getPriceDate(),DateUtils.YYYY_MM_DD));
  161. BigDecimal nav = navDO.getNav();
  162. BigDecimal cumulativeNavWithdrawal = navDO.getCumulativeNavWithdrawal();
  163. if(sumDistribute == null){
  164. sumDistribute = new BigDecimal(0);
  165. }
  166. //不存在分红的时候,判断当前的差值是否符合要求
  167. BigDecimal difference = cumulativeNavWithdrawal.subtract(nav.add(sumDistribute));
  168. if(difference.compareTo(threshold) > 0){
  169. //存在缺失
  170. String tradeDate = null;
  171. if(navIdx == 0 || navDOList.size() ==1){
  172. //有且仅有一条数据
  173. tradeDate = DateUtils.format(navDO.getPriceDate(),DateUtils.YYYY_MM_DD)+"~"+DateUtils.format(navDO.getPriceDate(),DateUtils.YYYY_MM_DD);
  174. }else{
  175. //判断前一条的差值与当前是否一致,一致就不处理
  176. if(difference.compareTo(preDifference) == 0){
  177. continue;
  178. }
  179. tradeDate = DateUtils.format(navDOList.get(navIdx-1).getPriceDate(),DateUtils.YYYY_MM_DD)+"~"+DateUtils.format(navDO.getPriceDate(),DateUtils.YYYY_MM_DD);
  180. }
  181. saveDeletionInfoDO(fundId,tradeDate,DeletionType.DISTRIBUTION_DELETION.getCode());
  182. }
  183. preDifference = difference;
  184. }
  185. }
  186. private void assetDeletion(String fundId, List<AssetDO> assetDOList, List<TradeDateDO> tradeDateDOList, FundReportFrequencyDO fundReportFrequencyDO) {
  187. if(Frequency.DAY == Frequency.getFrequencyByCode(fundReportFrequencyDO.getAssetFrequency())){
  188. Map<String,List<AssetDO>> navListMap = assetDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getPriceDate(),DateUtils.YYYY_MM_DD)));
  189. Map<String,List<TradeDateDO>> tradeListMap = tradeDateDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getTradeDate(),DateUtils.YYYY_MM_DD)));
  190. for(String tradeDate : tradeListMap.keySet()){
  191. if(navListMap.containsKey(tradeDate)){
  192. deletionInfoMapper.updateRemark(fundId,DeletionType.ASSET_DELETION.getCode(),tradeDate,DeletionType.NO_DELETION.getInfo(),null);
  193. continue;
  194. }
  195. if(tradeDateDOList.size() <= 3){
  196. continue;
  197. }
  198. TradeDateDO tradeDateDO = tradeDateDOList.get(tradeDateDOList.size()-3);
  199. if(tradeDateDO.getTradeDate().compareTo(DateUtils.parse(tradeDate,DateUtils.YYYY_MM_DD)) < 0){
  200. continue;
  201. }
  202. //写入缺失信息表
  203. saveDeletionInfoDO(fundId,tradeDate,DeletionType.ASSET_DELETION.getCode());
  204. }
  205. }
  206. if(Frequency.WEEK == Frequency.getFrequencyByCode(fundReportFrequencyDO.getAssetFrequency())){
  207. Map<String,List<AssetDO>> navListMap = assetDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getPriceDate(),DateUtils.YYYY_MM_DD)));
  208. TreeMap<Integer,List<AssetDO>> weekNavListMap = new TreeMap<>();
  209. //按周数整合
  210. for(String priceDate : navListMap.keySet()){
  211. Integer weekOfYear = Integer.parseInt(priceDate.substring(0,4)+DateUtil.weekOfYear(DateUtils.parse(priceDate,DateUtils.YYYY_MM_DD)));
  212. if(weekNavListMap.containsKey(weekOfYear)){
  213. List<AssetDO> assetDOS = weekNavListMap.get(weekOfYear);
  214. assetDOS.addAll(navListMap.get(priceDate));
  215. weekNavListMap.put(weekOfYear,assetDOS);
  216. }else{
  217. List<AssetDO> navDOS = new ArrayList<>();
  218. navDOS.addAll(navListMap.get(priceDate));
  219. weekNavListMap.put(weekOfYear,navDOS);
  220. }
  221. }
  222. Map<Integer,List<TradeDateDO>> tradeListMap = tradeDateDOList.stream().collect(Collectors.groupingBy(e -> e.getYearWeek()));
  223. for(Integer weekOfYear : tradeListMap.keySet()){
  224. List<AssetDO> assetDOS = weekNavListMap.get(weekOfYear);
  225. if(weekNavListMap.containsKey(weekOfYear)){
  226. for(AssetDO assetDO : assetDOS){
  227. String tradeDate = DateUtils.format(assetDO.getPriceDate(),DateUtils.YYYY_MM_DD);
  228. deletionInfoMapper.updateRemark(fundId,DeletionType.ASSET_DELETION.getCode(),tradeDate,DeletionType.NO_DELETION.getInfo(),null);
  229. }
  230. continue;
  231. }else{
  232. if(StringUtil.isNotEmpty(assetDOS)){
  233. for(int idx=0;idx < assetDOS.size()-1 ; idx++){
  234. AssetDO assetDO = assetDOS.get(idx);
  235. String tradeDate = DateUtils.format(assetDO.getPriceDate(),DateUtils.YYYY_MM_DD);
  236. deletionInfoMapper.deleteDeletionRemark(fundId,DeletionType.ASSET_DELETION.getCode(),tradeDate);
  237. }
  238. }
  239. }
  240. //不包含的话,默认取每周的最后一个交易日作为周净值日期
  241. List<TradeDateDO> tradeDateDOS = tradeListMap.get(weekOfYear);
  242. String tradeDate = null;
  243. if(tradeDateDOS.size() > 0){
  244. tradeDate = DateUtils.format(tradeDateDOS.get(tradeDateDOS.size()-1).getTradeDate(),DateUtils.YYYY_MM_DD);
  245. }
  246. //判断当前缺失交易日是否是近三个交易日
  247. if(tradeDateDOList.size() <= 3){
  248. continue;
  249. }
  250. TradeDateDO tradeDateDO = tradeDateDOList.get(tradeDateDOList.size()-3);
  251. if(tradeDateDO.getTradeDate().compareTo(DateUtils.parse(tradeDate,DateUtils.YYYY_MM_DD)) < 0){
  252. continue;
  253. }
  254. //写入缺失信息表
  255. saveDeletionInfoDO(fundId,tradeDate,DeletionType.ASSET_DELETION.getCode());
  256. }
  257. }
  258. if(Frequency.MONTH == Frequency.getFrequencyByCode(fundReportFrequencyDO.getAssetFrequency())){
  259. Map<String,List<AssetDO>> navListMap = assetDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getPriceDate(),DateUtils.YYYY_MM_DD)));
  260. TreeMap<String,List<AssetDO>> monthNavListMap = new TreeMap<>();
  261. //按周数整合
  262. for(String priceDate : navListMap.keySet()){
  263. String yearMonth = priceDate.substring(0,7);
  264. if(monthNavListMap.containsKey(yearMonth)){
  265. List<AssetDO> navDOS = monthNavListMap.get(yearMonth);
  266. navDOS.addAll(navListMap.get(priceDate));
  267. monthNavListMap.put(yearMonth,navDOS);
  268. }else{
  269. List<AssetDO> navDOS = new ArrayList<>();
  270. navDOS.addAll(navListMap.get(priceDate));
  271. monthNavListMap.put(yearMonth,navDOS);
  272. }
  273. }
  274. Map<String,List<TradeDateDO>> tradeListMap = tradeDateDOList.stream().collect(Collectors.groupingBy(e -> e.getYearmonth()));
  275. for(String yearMonth : tradeListMap.keySet()){
  276. //本月的数据不考虑
  277. String thisMonth = DateUtils.format(new Date(),DateUtils.YYYY_MM);
  278. if(yearMonth.equals(thisMonth)){
  279. continue;
  280. }
  281. List<AssetDO> assetDOS = monthNavListMap.get(yearMonth);
  282. if(monthNavListMap.containsKey(yearMonth)){
  283. for(AssetDO assetDO : assetDOS){
  284. String tradeDate = DateUtils.format(assetDO.getPriceDate(),DateUtils.YYYY_MM_DD);
  285. deletionInfoMapper.updateRemark(fundId,DeletionType.ASSET_DELETION.getCode(),tradeDate,DeletionType.NO_DELETION.getInfo(),null);
  286. }
  287. continue;
  288. }else{
  289. if(StringUtil.isNotEmpty(assetDOS)){
  290. for(int idx=0;idx < assetDOS.size()-1 ; idx++){
  291. AssetDO assetDO = assetDOS.get(idx);
  292. String tradeDate = DateUtils.format(assetDO.getPriceDate(),DateUtils.YYYY_MM_DD);
  293. deletionInfoMapper.deleteDeletionRemark(fundId,DeletionType.ASSET_DELETION.getCode(),tradeDate);
  294. }
  295. }
  296. }
  297. //不包含的话,默认取每周的最后一个交易日作为周净值日期
  298. List<TradeDateDO> tradeDateDOS = tradeListMap.get(yearMonth);
  299. String tradeDate = null;
  300. if(tradeDateDOS.size() > 0){
  301. tradeDate = DateUtils.format(tradeDateDOS.get(tradeDateDOS.size()-1).getTradeDate(),DateUtils.YYYY_MM_DD);
  302. }
  303. if(tradeDateDOList.size() <= 3){
  304. continue;
  305. }
  306. TradeDateDO tradeDateDO = tradeDateDOList.get(tradeDateDOList.size()-3);
  307. if(tradeDateDO.getTradeDate().compareTo(DateUtils.parse(tradeDate,DateUtils.YYYY_MM_DD)) < 0){
  308. continue;
  309. }
  310. //写入缺失信息表
  311. saveDeletionInfoDO(fundId,tradeDate,DeletionType.ASSET_DELETION.getCode());
  312. }
  313. }
  314. }
  315. private void navDeletion(String fundId,List<NavDO> navDOList, List<TradeDateDO> tradeDateDOList,FundReportFrequencyDO fundReportFrequencyDO) {
  316. //只处理日月季频率
  317. if(Frequency.DAY == Frequency.getFrequencyByCode(fundReportFrequencyDO.getNavFrequency())){
  318. Map<String,List<NavDO>> navListMap = navDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getPriceDate(),DateUtils.YYYY_MM_DD)));
  319. Map<String,List<TradeDateDO>> tradeListMap = tradeDateDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getTradeDate(),DateUtils.YYYY_MM_DD)));
  320. for(String tradeDate : tradeListMap.keySet()){
  321. if(navListMap.containsKey(tradeDate)){
  322. deletionInfoMapper.updateRemark(fundId,DeletionType.NAV_DELETION.getCode(),tradeDate,DeletionType.NO_DELETION.getInfo(),null);
  323. continue;
  324. }
  325. //写入缺失信息表
  326. saveDeletionInfoDO(fundId,tradeDate,DeletionType.NAV_DELETION.getCode());
  327. }
  328. }
  329. if(Frequency.WEEK == Frequency.getFrequencyByCode(fundReportFrequencyDO.getNavFrequency())){
  330. Map<String,List<NavDO>> navListMap = navDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getPriceDate(),DateUtils.YYYY_MM_DD)));
  331. TreeMap<Integer,List<NavDO>> weekNavListMap = new TreeMap<>();
  332. //按周数整合
  333. for(String priceDate : navListMap.keySet()){
  334. Integer weekOfYear = Integer.parseInt(priceDate.substring(0,4)+DateUtil.weekOfYear(DateUtils.parse(priceDate,DateUtils.YYYY_MM_DD)));;
  335. if(weekNavListMap.containsKey(weekOfYear)){
  336. List<NavDO> navDOS = weekNavListMap.get(weekOfYear);
  337. navDOS.addAll(navListMap.get(priceDate));
  338. weekNavListMap.put(weekOfYear,navDOS);
  339. }else{
  340. List<NavDO> navDOS = new ArrayList<>();
  341. navDOS.addAll(navListMap.get(priceDate));
  342. weekNavListMap.put(weekOfYear,navDOS);
  343. }
  344. }
  345. Map<Integer,List<TradeDateDO>> tradeListMap = tradeDateDOList.stream().collect(Collectors.groupingBy(e -> e.getYearWeek()));
  346. for(Integer weekOfYear : tradeListMap.keySet()){
  347. List<NavDO> navDOS = weekNavListMap.get(weekOfYear);
  348. if(weekNavListMap.containsKey(weekOfYear)){
  349. for(NavDO navDO : navDOS){
  350. String tradeDate = DateUtils.format(navDO.getPriceDate(),DateUtils.YYYY_MM_DD);
  351. deletionInfoMapper.updateRemark(fundId,DeletionType.NAV_DELETION.getCode(),tradeDate,DeletionType.NO_DELETION.getInfo(),null);
  352. }
  353. continue;
  354. }else{
  355. //防止频率变更导致数据异常,需要把当前日期下所在的频率全部无效掉
  356. if(StringUtil.isNotEmpty(navDOS)){
  357. for(int idx=0;idx < navDOS.size()-1 ; idx++){
  358. NavDO navDO = navDOS.get(idx);
  359. String tradeDate = DateUtils.format(navDO.getPriceDate(),DateUtils.YYYY_MM_DD);
  360. deletionInfoMapper.deleteDeletionRemark(fundId,DeletionType.NAV_DELETION.getCode(),tradeDate);
  361. }
  362. }
  363. }
  364. //不包含的话,默认取每周的最后一个交易日作为周净值日期
  365. List<TradeDateDO> tradeDateDOS = tradeListMap.get(weekOfYear);
  366. String tradeDate = null;
  367. if(tradeDateDOS.size() > 0){
  368. tradeDate = DateUtils.format(tradeDateDOS.get(tradeDateDOS.size()-1).getTradeDate(),DateUtils.YYYY_MM_DD);
  369. }
  370. if(tradeDateDOList.size() <= 3){
  371. continue;
  372. }
  373. TradeDateDO tradeDateDO = tradeDateDOList.get(tradeDateDOList.size()-3);
  374. if(tradeDateDO.getTradeDate().compareTo(DateUtils.parse(tradeDate,DateUtils.YYYY_MM_DD)) < 0){
  375. continue;
  376. }
  377. //写入缺失信息表
  378. saveDeletionInfoDO(fundId,tradeDate,DeletionType.NAV_DELETION.getCode());
  379. }
  380. }
  381. if(Frequency.MONTH == Frequency.getFrequencyByCode(fundReportFrequencyDO.getNavFrequency())){
  382. Map<String,List<NavDO>> navListMap = navDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getPriceDate(),DateUtils.YYYY_MM_DD)));
  383. TreeMap<String,List<NavDO>> monthNavListMap = new TreeMap<>();
  384. //按周数整合
  385. for(String priceDate : navListMap.keySet()){
  386. String yearMonth = priceDate.substring(0,7);
  387. if(monthNavListMap.containsKey(yearMonth)){
  388. List<NavDO> navDOS = monthNavListMap.get(yearMonth);
  389. navDOS.addAll(navListMap.get(priceDate));
  390. monthNavListMap.put(yearMonth,navDOS);
  391. }else{
  392. List<NavDO> navDOS = new ArrayList<>();
  393. navDOS.addAll(navListMap.get(priceDate));
  394. monthNavListMap.put(yearMonth,navDOS);
  395. }
  396. }
  397. Map<String,List<TradeDateDO>> tradeListMap = tradeDateDOList.stream().collect(Collectors.groupingBy(e -> e.getYearmonth()));
  398. for(String yearMonth : tradeListMap.keySet()){
  399. //本月的数据不考虑
  400. String thisMonth = DateUtils.format(new Date(),DateUtils.YYYY_MM);
  401. if(yearMonth.equals(thisMonth)){
  402. continue;
  403. }
  404. List<NavDO> navDOS = monthNavListMap.get(yearMonth);
  405. if(monthNavListMap.containsKey(yearMonth)){
  406. for(NavDO navDO : navDOS){
  407. String tradeDate = DateUtils.format(navDO.getPriceDate(),DateUtils.YYYY_MM_DD);
  408. deletionInfoMapper.updateRemark(fundId,DeletionType.NAV_DELETION.getCode(),tradeDate,DeletionType.NO_DELETION.getInfo(),null);
  409. }
  410. continue;
  411. }else{
  412. //防止频率变更导致数据异常,需要把当前日期下所在的频率全部无效掉
  413. if(StringUtil.isNotEmpty(navDOS)){
  414. for(NavDO navDO : navDOS){
  415. String tradeDate = DateUtils.format(navDO.getPriceDate(),DateUtils.YYYY_MM_DD);
  416. deletionInfoMapper.deleteDeletionRemark(fundId,DeletionType.NAV_DELETION.getCode(),tradeDate);
  417. }
  418. }
  419. }
  420. //不包含的话,默认取每周的最后一个交易日作为周净值日期
  421. List<TradeDateDO> tradeDateDOS = tradeListMap.get(yearMonth);
  422. String tradeDate = null;
  423. if(tradeDateDOS.size() > 0){
  424. tradeDate = DateUtils.format(tradeDateDOS.get(tradeDateDOS.size()-1).getTradeDate(),DateUtils.YYYY_MM_DD);
  425. }
  426. if(tradeDateDOList.size() <= 3){
  427. continue;
  428. }
  429. TradeDateDO tradeDateDO = tradeDateDOList.get(tradeDateDOList.size()-3);
  430. if(tradeDateDO.getTradeDate().compareTo(DateUtils.parse(tradeDate,DateUtils.YYYY_MM_DD)) < 0){
  431. continue;
  432. }
  433. //写入缺失信息表
  434. saveDeletionInfoDO(fundId,tradeDate,DeletionType.NAV_DELETION.getCode());
  435. }
  436. }
  437. }
  438. private void saveDeletionInfoDO(String fundId, String tradeDate, Integer code) {
  439. if(tradeDate == null){
  440. return;
  441. }
  442. DeletionInfoDO deletionInfoDO = new DeletionInfoDO();
  443. deletionInfoDO.setFundId(fundId);
  444. deletionInfoDO.setDeletionDate(tradeDate);
  445. deletionInfoDO.setDeletionType(code);
  446. DeletionInfoDO oldDeletionDO = deletionInfoMapper.getDeletionInfoDO(deletionInfoDO);
  447. if(StringUtil.isNull(oldDeletionDO)){
  448. deletionInfoDO.setIsvalid(1);
  449. deletionInfoDO.setIsSend(0);
  450. deletionInfoDO.setUpdateTime(DateUtils.getNowDate());
  451. deletionInfoDO.setCreateTime(DateUtils.getNowDate());
  452. deletionInfoMapper.saveDeletionInfoDO(deletionInfoDO);
  453. }
  454. }
  455. }