DailyReimMsgWarnTask.java 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. package kd.cosmic.jkjt.tmc.bei.task;
  2. import kd.bos.algo.DataSet;
  3. import kd.bos.context.RequestContext;
  4. import kd.bos.dataentity.entity.DynamicObject;
  5. import kd.bos.dataentity.entity.DynamicObjectCollection;
  6. import kd.bos.db.DB;
  7. import kd.bos.db.DBRoute;
  8. import kd.bos.entity.EntityMetadataCache;
  9. import kd.bos.entity.MainEntityType;
  10. import kd.bos.exception.KDException;
  11. import kd.bos.logging.BizLog;
  12. import kd.bos.orm.ORM;
  13. import kd.bos.orm.query.QCP;
  14. import kd.bos.orm.query.QFilter;
  15. import kd.bos.schedule.api.StopTask;
  16. import kd.bos.schedule.executor.AbstractTask;
  17. import kd.bos.servicehelper.BusinessDataServiceHelper;
  18. import kd.bos.servicehelper.QueryServiceHelper;
  19. import kd.bos.workflow.engine.msg.info.MessageInfo;
  20. import kd.cosmic.jkjt.tmc.bei.common.CommonUtils;
  21. import kd.cosmic.jkjt.tmc.bei.common.DateUtils;
  22. import kd.cosmic.jkjt.tmc.bei.common.FeishuSendMessageUtils;
  23. import kd.cosmic.jkjt.tmc.bei.common.constant.BeiBeTransDetailConstant;
  24. import kd.cosmic.jkjt.tmc.bei.common.constant.MsgWarnConfigConstant;
  25. import kd.cosmic.jkjt.tmc.bei.common.constant.MsgWarnTemplateConstant;
  26. import kd.cosmic.jkjt.tmc.bei.common.entity.MsgWarnMessageInfo;
  27. import kd.cosmic.jkjt.tmc.bei.common.enums.MsgWarnTypeEnum;
  28. import java.math.BigDecimal;
  29. import java.time.LocalDate;
  30. import java.util.*;
  31. import java.util.stream.Collectors;
  32. /**
  33. * 日常报销账户月度提醒
  34. */
  35. public class DailyReimMsgWarnTask extends AbstractTask implements StopTask {
  36. private MsgWarnTypeEnum WARTYPE = MsgWarnTypeEnum.DAILYREIM;
  37. @Override
  38. public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
  39. // 查询生效的账户大额交易通知配置
  40. Set<Long> largeTransIdConfig = getMsgWarnConfig();
  41. largeTransIdConfig.forEach(configId -> transConfigSendMessage(configId));
  42. }
  43. protected Set<Long> getMsgWarnConfig() {
  44. DynamicObjectCollection configCol = QueryServiceHelper.query(MsgWarnConfigConstant.ENTITYID, "id,nckd_company.id", new QFilter[]{
  45. new QFilter(MsgWarnConfigConstant.KEY_NCKD_TYPE, QFilter.equals, WARTYPE.getValue()),
  46. new QFilter(MsgWarnConfigConstant.KEY_STATUS, QFilter.equals, "C"),
  47. new QFilter(MsgWarnConfigConstant.KEY_ENABLE, QFilter.equals, "1")
  48. });
  49. Map<Long, Long> companyIdMap = configCol.stream()
  50. .collect(Collectors.toMap(r -> r.getLong("nckd_company.id"), r -> r.getLong("id"), (a, b) -> a));
  51. return companyIdMap.values().stream().collect(Collectors.toSet());
  52. }
  53. protected void transConfigSendMessage(Long configId) {
  54. DynamicObject msgWarnConfig = BusinessDataServiceHelper.loadSingle(configId, MsgWarnConfigConstant.ENTITYID);
  55. DynamicObject company = msgWarnConfig.getDynamicObject(MsgWarnConfigConstant.KEY_NCKD_COMPANY);
  56. DynamicObject financeDirectors = msgWarnConfig.getDynamicObject(MsgWarnConfigConstant.KEY_NCKD_FINANCE_DIRECTOR);
  57. DynamicObject financeLeader = msgWarnConfig.getDynamicObject(MsgWarnConfigConstant.KEY_NCKD_FINANCE_LEADER);
  58. // 没有设置接收人时跳过
  59. if(financeDirectors == null || financeLeader == null){
  60. BizLog.log("消息接收人为空,不进行消息发送。");
  61. return;
  62. }
  63. List<Long> receiverIdList = new ArrayList<>();
  64. receiverIdList.add(financeDirectors.getLong("id"));
  65. receiverIdList.add(financeLeader.getLong("id"));
  66. //每月首个工作日上午9点发送上月预警信息
  67. LocalDate today = LocalDate.now();
  68. // 上个月第一天
  69. LocalDate firstDayOfLastMonth = today.minusMonths(13).withDayOfMonth(1);
  70. // 本月第一天
  71. LocalDate firstDayOfThisMonth = today.withDayOfMonth(1);
  72. Date beginDate = Date.from(firstDayOfLastMonth.atStartOfDay().atZone(java.time.ZoneId.systemDefault()).toInstant());
  73. Date endDate = Date.from(firstDayOfThisMonth.atStartOfDay().atZone(java.time.ZoneId.systemDefault()).toInstant());
  74. // 获取公司下,发生笔数超过20笔的账户
  75. // 最大交易次数默认20
  76. int maxTimes = 20;
  77. BigDecimal maxAmount = new BigDecimal("100000000");
  78. DynamicObjectCollection transDetailData = getTransDetailData(company, beginDate, endDate,maxAmount,maxTimes);
  79. if(transDetailData == null || transDetailData.isEmpty()){
  80. BizLog.log("没有符合条件的数据,不进行消息发送。");
  81. return;
  82. }
  83. // 获取流水的月份,同一个月只能发送一次
  84. String timeFlag = DateUtils.formatDateMonth(beginDate);
  85. for(DynamicObject transDetail : transDetailData){
  86. String uniqueKey = String.join("-", WARTYPE.getValue(),timeFlag,transDetail.getString("foppunit"));
  87. if(ORM.create().exists("nckd_msgwarnlog",new QFilter("nckd_unique_key", QCP.equals,uniqueKey).toArray())){
  88. // 消息如果已发送,就不在执行
  89. continue;
  90. }
  91. String messageContent = getMcCenterMessage(company.getString("name"),transDetail);
  92. MessageInfo messageInfo = new MessageInfo();
  93. messageInfo.setTitle(String.join("-",WARTYPE.getName()));
  94. messageInfo.setUserIds(receiverIdList);
  95. messageInfo.setContent(messageContent);
  96. messageInfo.setTag(WARTYPE.getName());
  97. messageInfo.setSenderId(RequestContext.get().getCurrUserId());
  98. messageInfo.setEntityNumber("nckd_msgwarnconfig");
  99. messageInfo.setBizDataId(configId);
  100. String feishuMessage = MsgWarnTemplateConstant.getFeishuTemplate(WARTYPE.getName(),messageContent);
  101. MsgWarnMessageInfo warnMessageInfo = new MsgWarnMessageInfo(WARTYPE.getValue(),
  102. company.getString("name"),
  103. uniqueKey,
  104. feishuMessage,
  105. messageInfo);
  106. FeishuSendMessageUtils.sendFeishuMessage(warnMessageInfo);
  107. }
  108. }
  109. protected String getMcCenterMessage(String payerAccount , DynamicObject transDetail) {
  110. Long accountBankId = transDetail.getLong("faccountbankid");
  111. DynamicObject accountBank = QueryServiceHelper.queryOne("bd_accountbanks", "bankaccountnumber,bank.name",
  112. new QFilter("id", QCP.equals,accountBankId).toArray());
  113. return MsgWarnTemplateConstant.formatDailyMessage(
  114. payerAccount,
  115. accountBank.getString("bankaccountnumber"),
  116. accountBank.getString("bank.name"),
  117. transDetail.getString("foppunit"),
  118. transDetail.getString("totaltimes"),
  119. transDetail.getBigDecimal("totalamount").setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString());
  120. }
  121. protected DynamicObjectCollection getTransDetailData(DynamicObject company , Date beginDate , Date endDate,BigDecimal maxAmount,int maxTimes){
  122. DataSet transDetailDataSet = getTransDetailDataSet(company, beginDate, endDate,maxAmount,maxTimes);
  123. // 看报表与消息的兼容程度,再看怎么处理,暂时转成动态对象集合
  124. return ORM.create().toPlainDynamicObjectCollection(transDetailDataSet.copy());
  125. }
  126. protected DataSet getTransDetailDataSet(DynamicObject company , Date beginDate , Date endDate,BigDecimal maxAmount,int maxTimes){
  127. MainEntityType dt = EntityMetadataCache.getDataEntityType(BeiBeTransDetailConstant.ENTITYID);
  128. Long defualtAccountBankId = getDefualtAccountBankId(company);
  129. String dbRouteKey = dt.getDBRouteKey();
  130. String sumTimesSql = "SELECT faccountbankid, foppunit, COUNT(1) totaltimes, SUM(fdebitAmount) totalamount , 'times' source FROM t_bei_transdetail "
  131. + "WHERE fcompanyid = ? and faccountbankid = ? AND fbiztime > ? AND fbiztime < ? AND (HOUR(fbiztime) >= 9 AND HOUR(fbiztime) < 21) "
  132. + "AND TRIM(foppunit) <> '' AND LENGTH(foppunit) <= 4 AND fdebitAmount != 0 "
  133. + "GROUP BY faccountbankid, foppunit HAVING COUNT(1) > ?";
  134. DataSet sumTimesDataSet = DB.queryDataSet(this.getClass().getName(), DBRoute.of(dbRouteKey), sumTimesSql,
  135. new Object[]{company.getPkValue(),defualtAccountBankId, beginDate, endDate, maxTimes});
  136. Set oppUnitSet = CommonUtils.getFieldValue(sumTimesDataSet, "foppunit");
  137. String sumAmountSql = "SELECT faccountbankid, foppunit, COUNT(1) totaltimes, SUM(fdebitAmount) totalamount , 'amount' source FROM t_bei_transdetail "
  138. + "WHERE fcompanyid = ? and faccountbankid = ? AND fbiztime > ? AND fbiztime < ? AND (HOUR(fbiztime) >= 9 AND HOUR(fbiztime) < 21) "
  139. + "AND TRIM(foppunit) <> '' AND LENGTH(foppunit) <= 4 AND fdebitAmount != 0 "
  140. + "GROUP BY faccountbankid, foppunit HAVING SUM(fdebitAmount) > ?";
  141. DataSet sumAmountDataSet = DB.queryDataSet(this.getClass().getName(), DBRoute.of(dbRouteKey), sumAmountSql,
  142. new Object[]{company.getPkValue(), defualtAccountBankId,beginDate, endDate, maxAmount});
  143. HashMap<String, Object> params = new HashMap<>();
  144. params.put("var", oppUnitSet);
  145. DataSet filterSumAmountDataSet = sumAmountDataSet.filter("foppunit not in var", params);
  146. return sumTimesDataSet.union(filterSumAmountDataSet);
  147. }
  148. protected Long getDefualtAccountBankId(DynamicObject company){
  149. DynamicObject accountBankBill = QueryServiceHelper.queryOne("bd_accountbanks", "id", new QFilter[]{
  150. new QFilter("company", QCP.equals, company.getPkValue()),
  151. new QFilter("isdefaultpay", QCP.equals, true)
  152. });
  153. return accountBankBill == null ? null : accountBankBill.getLong("id");
  154. }
  155. }