Blame view

fw-morax-service/src/main/java/cn/fw/morax/service/biz/eval/EvalCalculateService.java 30.7 KB
f946d0a5   姜超   feature(*): 考评定时任务
1
2
  package cn.fw.morax.service.biz.eval;
  
36a2a360   姜超   feature(*): 禁用考评
3
  import cn.fw.morax.common.utils.PublicUtil;
8b61df4a   姜超   feature(*): 计算考评排名
4
  import cn.fw.morax.common.utils.StringUtils;
5ad9dc20   姜超   feature(*): 缓存考评组
5
  import cn.fw.morax.common.utils.ThreadPoolUtil;
f946d0a5   姜超   feature(*): 考评定时任务
6
  import cn.fw.morax.domain.bo.eval.EvalGroupCalculableBO;
e2386ce2   姜超   feature(*): 考评计算得分修改
7
  import cn.fw.morax.domain.bo.eval.EvalGroupUserShop;
8b61df4a   姜超   feature(*): 计算考评排名
8
  import cn.fw.morax.domain.bo.kpi.EvalGroupCalculableRankBO;
e2386ce2   姜超   feature(*): 考评计算得分修改
9
  import cn.fw.morax.domain.db.eval.*;
8b61df4a   姜超   feature(*): 计算考评排名
10
  import cn.fw.morax.domain.enums.*;
e2386ce2   姜超   feature(*): 考评计算得分修改
11
12
13
  import cn.fw.morax.service.biz.calculator.eval.kpi.EvalKpiBaseCalculator;
  import cn.fw.morax.service.biz.calculator.eval.reward.EvalRewardBaseCalculator;
  import cn.fw.morax.service.data.eval.*;
f946d0a5   姜超   feature(*): 考评定时任务
14
15
16
  import com.alibaba.fastjson.JSON;
  import com.alibaba.fastjson.JSONObject;
  import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
5ad9dc20   姜超   feature(*): 缓存考评组
17
  import com.baomidou.mybatisplus.core.toolkit.Wrappers;
f946d0a5   姜超   feature(*): 考评定时任务
18
  import lombok.Getter;
f946d0a5   姜超   feature(*): 考评定时任务
19
20
  import lombok.extern.slf4j.Slf4j;
  import org.springframework.beans.factory.annotation.Value;
5ad9dc20   姜超   feature(*): 缓存考评组
21
  import org.springframework.data.redis.core.BoundSetOperations;
8b61df4a   姜超   feature(*): 计算考评排名
22
  import org.springframework.data.redis.core.ListOperations;
f946d0a5   姜超   feature(*): 考评定时任务
23
24
  import org.springframework.data.redis.core.StringRedisTemplate;
  import org.springframework.stereotype.Service;
8b61df4a   姜超   feature(*): 计算考评排名
25
26
27
  import org.springframework.transaction.PlatformTransactionManager;
  import org.springframework.transaction.TransactionDefinition;
  import org.springframework.transaction.TransactionStatus;
15a68981   姜超   feature(*): 处理百分数
28
  import org.springframework.transaction.annotation.Transactional;
f946d0a5   姜超   feature(*): 考评定时任务
29
  
e2386ce2   姜超   feature(*): 考评计算得分修改
30
  import java.math.BigDecimal;
c1b3c16f   姜超   feature(*): 门店考评池查询
31
  import java.math.RoundingMode;
f946d0a5   姜超   feature(*): 考评定时任务
32
  import java.time.LocalDate;
eccb0d64   姜超   feature(*): 考评详情查询
33
  import java.time.YearMonth;
e2386ce2   姜超   feature(*): 考评计算得分修改
34
  import java.util.*;
5ad9dc20   姜超   feature(*): 缓存考评组
35
36
  import java.util.concurrent.RejectedExecutionException;
  import java.util.concurrent.ThreadPoolExecutor;
e2386ce2   姜超   feature(*): 考评计算得分修改
37
  import java.util.stream.Collectors;
f946d0a5   姜超   feature(*): 考评定时任务
38
39
40
41
42
43
44
45
  
  /**
   * @author jiangchao
   * @des: 考评计算
   * @date 2023/1/12 17:39
   */
  @Slf4j
  @Service
f946d0a5   姜超   feature(*): 考评定时任务
46
47
  public class EvalCalculateService {
  
e2386ce2   姜超   feature(*): 考评计算得分修改
48
49
50
51
      private final EvalPoolRewardDetailService evalPoolRewardDetailService;
      private final EvalPoolCommonService evalPoolCommonService;
      private final EvalUserPoolService evalUserPoolService;
      private final EvalShopPoolService evalShopPoolService;
f946d0a5   姜超   feature(*): 考评定时任务
52
      private final EvalGroupService evalGroupService;
8945afe5   姜超   feature(*): 考评保存修改
53
      private final EvalGroupRankStageService evalGroupRankStageService;
725e9bc8   姜超   feature(*): 计算考评修改
54
      private final EvalGroupIndicatorService evalGroupIndicatorService;
e2386ce2   姜超   feature(*): 考评计算得分修改
55
56
      private final EvalPoolIndicatorDetailService evalPoolIndicatorDetailService;
      private final EvalGroupRewardService evalGroupRewardService;
7e7c92a1   姜超   feature(*): 考评排名组...
57
      private final EvalGroupRewardDimService evalGroupRewardDimService;
5ad9dc20   姜超   feature(*): 缓存考评组
58
      private final EvalGroupUserService evalGroupUserService;
f946d0a5   姜超   feature(*): 考评定时任务
59
      private final StringRedisTemplate stringRedisTemplate;
8b61df4a   姜超   feature(*): 计算考评排名
60
61
62
      private final EvalGroupRankService evalGroupRankService;
      private final PlatformTransactionManager platformTransactionManager;
      private final TransactionDefinition transactionDefinition;
e2386ce2   姜超   feature(*): 考评计算得分修改
63
      private final Map<EvalRewardCalMethodEnum, EvalRewardBaseCalculator> calculatorRewardMap;
e0944b69   姜超   feature(*): 修改计算考评
64
65
66
67
68
69
70
71
72
73
74
75
      private final Map<ScoreWayEnum, EvalKpiBaseCalculator> calculatorEvalMap;
  
      public EvalCalculateService(final EvalPoolRewardDetailService evalPoolRewardDetailService,
                                  final EvalPoolCommonService evalPoolCommonService,
                                  final EvalUserPoolService evalUserPoolService,
                                  final EvalShopPoolService evalShopPoolService,
                                  final EvalGroupService evalGroupService,
                                  final EvalGroupIndicatorService evalGroupIndicatorService,
                                  final EvalPoolIndicatorDetailService evalPoolIndicatorDetailService,
                                  final EvalGroupRewardService evalGroupRewardService,
                                  final EvalGroupUserService evalGroupUserService,
                                  final StringRedisTemplate stringRedisTemplate,
8b61df4a   姜超   feature(*): 计算考评排名
76
77
78
                                  final EvalGroupRankService evalGroupRankService,
                                  final PlatformTransactionManager platformTransactionManager,
                                  final TransactionDefinition transactionDefinition,
8945afe5   姜超   feature(*): 考评保存修改
79
                                  final EvalGroupRankStageService evalGroupRankStageService,
7e7c92a1   姜超   feature(*): 考评排名组...
80
                                  final EvalGroupRewardDimService evalGroupRewardDimService,
e0944b69   姜超   feature(*): 修改计算考评
81
82
83
84
85
86
87
88
89
90
91
92
                                  final List<EvalRewardBaseCalculator> rewardBaseCalculators,
                                  final List<EvalKpiBaseCalculator> kpiBaseCalculators) {
          this.evalPoolRewardDetailService = evalPoolRewardDetailService;
          this.evalPoolCommonService = evalPoolCommonService;
          this.evalUserPoolService = evalUserPoolService;
          this.evalShopPoolService = evalShopPoolService;
          this.evalGroupService = evalGroupService;
          this.evalGroupIndicatorService = evalGroupIndicatorService;
          this.evalPoolIndicatorDetailService = evalPoolIndicatorDetailService;
          this.evalGroupRewardService = evalGroupRewardService;
          this.evalGroupUserService = evalGroupUserService;
          this.stringRedisTemplate = stringRedisTemplate;
8b61df4a   姜超   feature(*): 计算考评排名
93
94
95
          this.evalGroupRankService = evalGroupRankService;
          this.platformTransactionManager = platformTransactionManager;
          this.transactionDefinition = transactionDefinition;
8945afe5   姜超   feature(*): 考评保存修改
96
          this.evalGroupRankStageService = evalGroupRankStageService;
7e7c92a1   姜超   feature(*): 考评排名组...
97
          this.evalGroupRewardDimService = evalGroupRewardDimService;
e0944b69   姜超   feature(*): 修改计算考评
98
99
100
          this.calculatorRewardMap = rewardBaseCalculators.stream().collect(Collectors.toMap(EvalRewardBaseCalculator::getCalMethod, v -> v));
          this.calculatorEvalMap = kpiBaseCalculators.stream().collect(Collectors.toMap(EvalKpiBaseCalculator::getCalMethod, v -> v));
      }
f946d0a5   姜超   feature(*): 考评定时任务
101
102
103
  
      @Value("${spring.cache.custom.global-prefix}:calculable:eval-group")
      @Getter
80e64f6f   姜超   feature(*): 考评排名组...
104
      private String calcEvalGroup;
f946d0a5   姜超   feature(*): 考评定时任务
105
  
8b61df4a   姜超   feature(*): 计算考评排名
106
107
108
109
      @Value("${spring.cache.custom.global-prefix}:eval:calculate-rank")
      @Getter
      private String calcEvalRankKey;
  
f946d0a5   姜超   feature(*): 考评定时任务
110
111
112
113
114
115
      /**
       * 缓存需要计算绩效的绩效组信息
       *
       * @param localDate 日期
       */
      public void cacheCalculableEvalGroupIds(final LocalDate localDate) {
ffcadcaf   姜超   feature(*): 定时任务时间修改
116
          log.info("定时任务【缓存需要计算的考评组】开始执行");
80e64f6f   姜超   feature(*): 考评排名组...
117
118
119
          List<EvalGroup> evalGroups = evalGroupService.getAllEffectGroups(localDate);
          Set<Long> evalGroupIds = evalGroups.stream().map(EvalGroup::getId).collect(Collectors.toSet());
  //        Set<Long> evalGroupIds = evalGroupService.queryCalculableEvalGroupIds(localDate);
f946d0a5   姜超   feature(*): 考评定时任务
120
121
122
          if (CollectionUtils.isEmpty(evalGroupIds)) {
              return;
          }
ffcadcaf   姜超   feature(*): 定时任务时间修改
123
          log.info("缓存需要计算的考评组信息,evalGroupIds:{},日期:{}", JSON.toJSONString(evalGroupIds), localDate);
f946d0a5   姜超   feature(*): 考评定时任务
124
125
126
127
128
129
130
131
132
          cacheGroupIds(evalGroupIds, localDate);
      }
  
  
      private void cacheGroupIds(final Set<Long> evalGroupIds, final LocalDate localDate) {
          String[] array = evalGroupIds.stream()
                  .map(evalGroupId -> new EvalGroupCalculableBO(evalGroupId, localDate))
                  .map(JSONObject::toJSONString)
                  .toArray(String[]::new);
80e64f6f   姜超   feature(*): 考评排名组...
133
          stringRedisTemplate.opsForSet().add(getCalcEvalGroup(), array);
f946d0a5   姜超   feature(*): 考评定时任务
134
135
      }
  
5ad9dc20   姜超   feature(*): 缓存考评组
136
137
  
      public void calculateCacheEvalGroup() {
80e64f6f   姜超   feature(*): 考评排名组...
138
          BoundSetOperations<String, String> setOps = stringRedisTemplate.boundSetOps(getCalcEvalGroup());
5ad9dc20   姜超   feature(*): 缓存考评组
139
140
141
142
143
144
145
146
147
148
149
          ThreadPoolExecutor threadPool = ThreadPoolUtil.getInstance().getThreadPool();
          List<String> overflowsList = new ArrayList<>();
          String str;
          while ((str = setOps.pop()) != null) {
              final EvalGroupCalculableBO bo = JSONObject.parseObject(str, EvalGroupCalculableBO.class);
              if (Objects.isNull(bo)) {
                  continue;
              }
              try {
                  String finalStr = str;
                  threadPool.execute(() -> {
8b61df4a   姜超   feature(*): 计算考评排名
150
                      TransactionStatus transactionStatus = platformTransactionManager.getTransaction(transactionDefinition);
5ad9dc20   姜超   feature(*): 缓存考评组
151
                      try {
4964363d   姜超   feature(*): 考评阶段指标上报
152
153
                          calculateEvalGroup(bo, EvalScopeEnum.STAFF);
                          calculateEvalGroup(bo, EvalScopeEnum.SHOP);
8b61df4a   姜超   feature(*): 计算考评排名
154
                          platformTransactionManager.commit(transactionStatus);
5ad9dc20   姜超   feature(*): 缓存考评组
155
                      } catch (Exception ex) {
8b61df4a   姜超   feature(*): 计算考评排名
156
                          platformTransactionManager.rollback(transactionStatus);
c1b3c16f   姜超   feature(*): 门店考评池查询
157
                          log.error("计算考评数据失败:{}", bo, ex);
5ad9dc20   姜超   feature(*): 缓存考评组
158
159
160
161
162
163
164
165
166
167
168
169
170
171
                          setOps.add(finalStr);
                      }
                  });
              } catch (RejectedExecutionException re) {
                  overflowsList.add(str);
              }
          }
          if (!CollectionUtils.isEmpty(overflowsList)) {
              for (String s : overflowsList) {
                  setOps.add(s);
              }
          }
      }
  
4964363d   姜超   feature(*): 考评阶段指标上报
172
      public void calculateEvalGroup(EvalGroupCalculableBO bo, EvalScopeEnum scopeType) {
b5babc65   姜超   feature(*): 参数修改
173
          log.info("考评组计算:{}", JSON.toJSONString(bo));
5ad9dc20   姜超   feature(*): 缓存考评组
174
          final Long evalGroupId = bo.getEvalGroupId();
ea6b2fd6   姜超   feature(*): 门店奖惩分配
175
176
          final LocalDate localDate = bo.getLocalDate();
  
5ad9dc20   姜超   feature(*): 缓存考评组
177
178
179
180
181
          EvalGroup evalGroup = evalGroupService.getById(evalGroupId);
          if (Objects.isNull(evalGroup)) {
              log.error("考评组[{}]不存在,终止计算!", evalGroupId);
              return;
          }
80e64f6f   姜超   feature(*): 考评排名组...
182
183
184
185
186
187
          EvalGroupRankStage evalGroupRankStage = evalGroupRankStageService.getById(evalGroup.getEvalGroupRankStageId());
          if (Objects.isNull(evalGroupRankStage)) {
              log.error("考评排名组阶段[{}]不存在,终止计算!", JSON.toJSONString(evalGroup));
              return;
          }
          List<EvalGroupUserShop> userShops = this.buildEvalGroupObj(evalGroup, evalGroupRankStage.getBeginTime(), localDate, scopeType);
e2386ce2   姜超   feature(*): 考评计算得分修改
188
189
190
191
192
          if (CollectionUtils.isEmpty(userShops)) {
              log.error("考评组[{}]人员为空,终止计算!", evalGroupId);
              return;
          }
  
7e7c92a1   姜超   feature(*): 考评排名组...
193
194
195
196
197
          List<EvalGroupRewardDim> rewardDims = evalGroupRewardDimService.list(Wrappers.<EvalGroupRewardDim>lambdaQuery()
                  .eq(EvalGroupRewardDim::getEvalGroupId, evalGroupId)
                  .eq(EvalGroupRewardDim::getType, scopeType)
                  .eq(EvalGroupRewardDim::getYn, Boolean.TRUE)
          );
e2386ce2   姜超   feature(*): 考评计算得分修改
198
199
200
201
          List<EvalGroupReward> rewards = evalGroupRewardService.list(Wrappers.<EvalGroupReward>lambdaQuery()
                  .eq(EvalGroupReward::getEvalGroupId, evalGroupId)
                  .eq(EvalGroupReward::getYn, Boolean.TRUE)
          );
7e7c92a1   姜超   feature(*): 考评排名组...
202
          Map<Long, List<EvalGroupReward>> dimRewardMap = rewards.stream().collect(Collectors.groupingBy(EvalGroupReward::getEvalGroupDimId));
e2386ce2   姜超   feature(*): 考评计算得分修改
203
204
205
206
207
          List<EvalGroupIndicator> indicators = evalGroupIndicatorService.list(Wrappers.<EvalGroupIndicator>lambdaQuery()
                  .eq(EvalGroupIndicator::getEvalGroupId, evalGroupId)
                  .eq(EvalGroupIndicator::getYn, Boolean.TRUE)
          );
  
e2386ce2   姜超   feature(*): 考评计算得分修改
208
          List<EvalPoolRewardDetail> rewardDetails = new ArrayList<>();
e2386ce2   姜超   feature(*): 考评计算得分修改
209
210
211
          BigDecimal totalScore = indicators.stream()
                  .map(indicator -> BigDecimal.valueOf(indicator.getBaseScore()))
                  .reduce(BigDecimal.ZERO, BigDecimal::add);
ea6b2fd6   姜超   feature(*): 门店奖惩分配
212
213
  
          //计算
7e7c92a1   姜超   feature(*): 考评排名组...
214
215
          calcRewardRnkCond(userShops, rewardDims, dimRewardMap, scopeType);
          calcTotalPushMoney(userShops, rewardDims, dimRewardMap, scopeType, rewardDetails);
e2386ce2   姜超   feature(*): 考评计算得分修改
216
217
          for (EvalGroupUserShop userShop : userShops) {
              userShop.setIndicatorTotalScore(totalScore);
e0944b69   姜超   feature(*): 修改计算考评
218
              calcRewardMoney(rewards, userShop, rewardDetails);
da42a3d8   姜超   feature(*): 计算考评代码优化
219
              calcEvalKpi(userShop, indicators);
e2386ce2   姜超   feature(*): 考评计算得分修改
220
          }
4964363d   姜超   feature(*): 考评阶段指标上报
221
          updatePool(evalGroup, localDate, scopeType, rewardDetails, userShops);
15a68981   姜超   feature(*): 处理百分数
222
223
      }
  
4964363d   姜超   feature(*): 考评阶段指标上报
224
225
      public void updatePool(EvalGroup evalGroup, LocalDate localDate, EvalScopeEnum scopeType,
                             List<EvalPoolRewardDetail> rewardDetails, List<EvalGroupUserShop> userShops) {
15a68981   姜超   feature(*): 处理百分数
226
          final Long evalGroupId = evalGroup.getId();
15a68981   姜超   feature(*): 处理百分数
227
228
229
230
231
232
233
234
235
          List<Long> poolIds = userShops.stream().map(EvalGroupUserShop::getPoolId).collect(Collectors.toList());
          if (PublicUtil.isNotEmpty(rewardDetails)) {
              evalPoolRewardDetailService.remove(Wrappers.<EvalPoolRewardDetail>lambdaQuery()
                      .in(EvalPoolRewardDetail::getPoolId, poolIds)
                      .eq(EvalPoolRewardDetail::getEvalGroupId, evalGroupId)
                      .eq(EvalPoolRewardDetail::getDataDate, localDate)
              );
              evalPoolRewardDetailService.saveBatch(rewardDetails);
          }
4964363d   姜超   feature(*): 考评阶段指标上报
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
          if (EvalScopeEnum.STAFF.equals(scopeType)) {
              for (EvalGroupUserShop userShop : userShops) {
                  BigDecimal scoreRatio = BigDecimal.ZERO;
                  if (userShop.getIndicatorTotalScore().compareTo(BigDecimal.ZERO) > 0) {
                      scoreRatio = userShop.getScore().divide(userShop.getIndicatorTotalScore(), 2, RoundingMode.DOWN);
                  }
                  evalUserPoolService.update(Wrappers.<EvalUserPool>lambdaUpdate()
                          .eq(EvalUserPool::getId, userShop.getPoolId())
                          .eq(EvalUserPool::getYn, Boolean.TRUE)
                          .set(EvalUserPool::getReward, userShop.getReward())
                          .set(EvalUserPool::getScore, userShop.getScore())
                          .set(EvalUserPool::getScoreRatio, scoreRatio)
                          .set(EvalUserPool::getMonthly, YearMonth.from(localDate))
                          .set(EvalUserPool::getDataDate, localDate)
                  );
              }
              return;
          }
1365b620   姜超   feature(*): 计算得分率修复
254
255
256
257
          for (EvalGroupUserShop userShop : userShops) {
              BigDecimal scoreRatio = BigDecimal.ZERO;
              if (userShop.getIndicatorTotalScore().compareTo(BigDecimal.ZERO) > 0) {
                  scoreRatio = userShop.getScore().divide(userShop.getIndicatorTotalScore(), 2, RoundingMode.DOWN);
e2386ce2   姜超   feature(*): 考评计算得分修改
258
              }
4964363d   姜超   feature(*): 考评阶段指标上报
259
260
261
262
263
264
265
266
              evalShopPoolService.update(Wrappers.<EvalShopPool>lambdaUpdate()
                      .eq(EvalShopPool::getId, userShop.getPoolId())
                      .eq(EvalShopPool::getYn, Boolean.TRUE)
                      .set(EvalShopPool::getReward, userShop.getReward())
                      .set(EvalShopPool::getScore, userShop.getScore())
                      .set(EvalShopPool::getScoreRatio, scoreRatio)
                      .set(EvalShopPool::getMonthly, YearMonth.from(localDate))
                      .set(EvalShopPool::getDataDate, localDate)
1365b620   姜超   feature(*): 计算得分率修复
267
              );
e2386ce2   姜超   feature(*): 考评计算得分修改
268
          }
e2386ce2   姜超   feature(*): 考评计算得分修改
269
270
      }
  
da42a3d8   姜超   feature(*): 计算考评代码优化
271
  
80e64f6f   姜超   feature(*): 考评排名组...
272
      public List<EvalGroupUserShop> buildEvalGroupObj(EvalGroup evalGroup, LocalDate beginDate, LocalDate localDate, EvalScopeEnum scopeType) {
da42a3d8   姜超   feature(*): 计算考评代码优化
273
          List<EvalGroupUserShop> userShops = new ArrayList<>();
4964363d   姜超   feature(*): 考评阶段指标上报
274
275
276
277
278
279
          if (EvalScopeEnum.STAFF.equals(scopeType)) {
              List<EvalGroupUser> users = evalGroupUserService.list(Wrappers.<EvalGroupUser>lambdaQuery()
                      .eq(EvalGroupUser::getEvalGroupId, evalGroup.getId())
                      .eq(EvalGroupUser::getDataDate, localDate)
                      .eq(EvalGroupUser::getYn, Boolean.TRUE)
              );
36a2a360   姜超   feature(*): 禁用考评
280
  
4964363d   姜超   feature(*): 考评阶段指标上报
281
282
283
284
285
286
287
              Map<Long, EvalUserPool> userPoolMap = evalPoolCommonService.inspectionUserPoolMap(evalGroup, users, localDate);
              for (EvalGroupUser user : users) {
                  if (Boolean.TRUE.equals(user.getIgnored())) {
                      continue;
                  }
                  EvalUserPool userPool = userPoolMap.get(user.getUserId());
                  userShops.add(convertBO(user, userPool));
da42a3d8   姜超   feature(*): 计算考评代码优化
288
              }
4964363d   姜超   feature(*): 考评阶段指标上报
289
              return userShops;
ea6b2fd6   姜超   feature(*): 门店奖惩分配
290
          }
8945afe5   姜超   feature(*): 考评保存修改
291
  
bc484bc4   姜超   feature(*): 定时任务发送修改
292
293
294
295
296
297
          List<Long> distShopIds = this.getEvalDistShopIds(evalGroup);
          if (PublicUtil.isEmpty(distShopIds)) {
              return new ArrayList<>();
          }
          Map<Long, EvalShopPool> shopPoolBOMap = evalPoolCommonService.inspectionShopPools(evalGroup, localDate, distShopIds);
          for (Long shopId : distShopIds) {
4964363d   姜超   feature(*): 考评阶段指标上报
298
              EvalShopPool shopPool = shopPoolBOMap.get(shopId);
80e64f6f   姜超   feature(*): 考评排名组...
299
              userShops.add(convertBO(shopPool, evalGroup, beginDate, localDate));
4964363d   姜超   feature(*): 考评阶段指标上报
300
301
          }
          return userShops;
ea6b2fd6   姜超   feature(*): 门店奖惩分配
302
      }
e2386ce2   姜超   feature(*): 考评计算得分修改
303
  
da42a3d8   姜超   feature(*): 计算考评代码优化
304
  
bc484bc4   姜超   feature(*): 定时任务发送修改
305
306
307
308
309
310
311
312
313
314
315
      public List<Long> getEvalDistShopIds(EvalGroup evalGroup) {
          List<EvalGroupRewardDim> rewardDims = evalGroupRewardDimService.list(Wrappers.<EvalGroupRewardDim>lambdaQuery()
                  .eq(EvalGroupRewardDim::getEvalGroupId, evalGroup.getId())
                  .eq(EvalGroupRewardDim::getType, EvalScopeEnum.SHOP)
                  .eq(EvalGroupRewardDim::getYn, Boolean.TRUE)
          );
          if (PublicUtil.isEmpty(rewardDims)) {
              return new ArrayList<>();
          }
          return rewardDims.stream().flatMap(dim -> dim.getShopIds().stream()).distinct().collect(Collectors.toList());
      }
e2386ce2   姜超   feature(*): 考评计算得分修改
316
317
318
319
320
321
322
323
  
  
  
      /**
       * 计算绩效组人员的绩效数据
       * 计算单个人员绩效数据
       *
       */
da42a3d8   姜超   feature(*): 计算考评代码优化
324
      private void calcEvalKpi(EvalGroupUserShop userShop, List<EvalGroupIndicator> indicators) {
e2386ce2   姜超   feature(*): 考评计算得分修改
325
326
327
328
  //        KpiPool kpiPool = kpiPoolCommonService.inspectionPool(user);
  //        if (Boolean.TRUE.equals(user.getIgnored())) {
  //            return;
  //        }
da42a3d8   姜超   feature(*): 计算考评代码优化
329
          final Long poolId = userShop.getPoolId();
15a68981   姜超   feature(*): 处理百分数
330
          final Long evalGroupId = userShop.getEvalGroupId();
e2386ce2   姜超   feature(*): 考评计算得分修改
331
332
          List<EvalPoolIndicatorDetail> indicatorDetails = new ArrayList<>();
          for (EvalGroupIndicator indicator : indicators) {
e0944b69   姜超   feature(*): 修改计算考评
333
              EvalKpiBaseCalculator calculator = calculatorEvalMap.get(indicator.getScoreWay());
e2386ce2   姜超   feature(*): 考评计算得分修改
334
335
336
337
              if (calculator == null) {
                  continue;
              }
              BigDecimal score = calculator.calculate(userShop, indicator);
da42a3d8   姜超   feature(*): 计算考评代码优化
338
              EvalPoolIndicatorDetail indicatorDetail = createPoolIndicatorValue(score, indicator, userShop.getGroupId());
e2386ce2   姜超   feature(*): 考评计算得分修改
339
              indicatorDetail.setDataDate(userShop.getDataDate());
e0944b69   姜超   feature(*): 修改计算考评
340
              indicatorDetail.setPoolId(poolId);
e2386ce2   姜超   feature(*): 考评计算得分修改
341
342
343
344
345
346
              indicatorDetail.setScopeType(userShop.getScopeType());
              indicatorDetails.add(indicatorDetail);
          }
  
          if (CollectionUtils.isNotEmpty(indicatorDetails)) {
              evalPoolIndicatorDetailService.remove(Wrappers.<EvalPoolIndicatorDetail>lambdaQuery()
e0944b69   姜超   feature(*): 修改计算考评
347
                      .eq(EvalPoolIndicatorDetail::getPoolId, poolId)
15a68981   姜超   feature(*): 处理百分数
348
                      .eq(EvalPoolIndicatorDetail::getEvalGroupId, evalGroupId)
e2386ce2   姜超   feature(*): 考评计算得分修改
349
350
                      .eq(EvalPoolIndicatorDetail::getScopeType, userShop.getScopeType())
                      .eq(EvalPoolIndicatorDetail::getDataDate, userShop.getDataDate())
e2386ce2   姜超   feature(*): 考评计算得分修改
351
                      .eq(EvalPoolIndicatorDetail::getYn, Boolean.TRUE));
5ad9dc20   姜超   feature(*): 缓存考评组
352
  
e2386ce2   姜超   feature(*): 考评计算得分修改
353
              evalPoolIndicatorDetailService.saveBatch(indicatorDetails);
5ad9dc20   姜超   feature(*): 缓存考评组
354
          }
e2386ce2   姜超   feature(*): 考评计算得分修改
355
356
357
358
          BigDecimal totalScore = BigDecimal.ZERO;
          for (EvalPoolIndicatorDetail indicatorValue : indicatorDetails) {
              totalScore = totalScore.add(indicatorValue.getScore());
          }
da42a3d8   姜超   feature(*): 计算考评代码优化
359
          userShop.setScore(totalScore);
e2386ce2   姜超   feature(*): 考评计算得分修改
360
      }
5ad9dc20   姜超   feature(*): 缓存考评组
361
  
05639e47   姜超   feature(*): 查询修改
362
  
97c9de51   姜超   feature(*): 审批修改
363
      /**
05639e47   姜超   feature(*): 查询修改
364
       * 计算考评排名条件
97c9de51   姜超   feature(*): 审批修改
365
       *
05639e47   姜超   feature(*): 查询修改
366
       * @param
97c9de51   姜超   feature(*): 审批修改
367
       */
7e7c92a1   姜超   feature(*): 考评排名组...
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
      private void calcRewardRnkCond(List<EvalGroupUserShop> userShops, List<EvalGroupRewardDim> rewardDims,
                                     Map<Long, List<EvalGroupReward>> dimRewardMap, EvalScopeEnum scopeType) {
          for (EvalGroupRewardDim dim : rewardDims) {
              List<EvalGroupUserShop> filterUserShops = filterUserShops(dim, scopeType, userShops);
              if (PublicUtil.isEmpty(filterUserShops)) {
                  continue;
              }
              for (EvalGroupReward evalGroupReward : dimRewardMap.getOrDefault(dim.getId(), new ArrayList<>())) {
                  final String rewardProjectName = evalGroupReward.getName();
                  EvalRewardBaseCalculator calculator = calculatorRewardMap.get(evalGroupReward.getCalMethod());
                  if (Objects.isNull(calculator)) {
                      log.error("[{}_{}]计算器不存在", evalGroupReward.getId(), rewardProjectName);
                      return;
                  }
  
                  calculator.calculateRankPrecondition(filterUserShops, evalGroupReward);
97c9de51   姜超   feature(*): 审批修改
384
              }
97c9de51   姜超   feature(*): 审批修改
385
386
          }
      }
e2386ce2   姜超   feature(*): 考评计算得分修改
387
  
7e7c92a1   姜超   feature(*): 考评排名组...
388
389
390
391
392
393
394
395
396
397
      public List<EvalGroupUserShop> filterUserShops(EvalGroupRewardDim dim, EvalScopeEnum scopeType, List<EvalGroupUserShop> userShops) {
          List<EvalGroupUserShop> filterUserShops = new ArrayList<>();
          if (EvalScopeEnum.STAFF.equals(scopeType)) {
              filterUserShops = userShops.stream().filter(userShop -> dim.getPostIds().contains(userShop.getPostId())).collect(Collectors.toList());
          } else {
              filterUserShops = userShops.stream().filter(userShop -> dim.getShopIds().contains(userShop.getShopId())).collect(Collectors.toList());
          }
          return filterUserShops;
      }
  
e2386ce2   姜超   feature(*): 考评计算得分修改
398
399
400
401
402
      /**
       * 计算绩效金额
       *
       * @param rewardDetails
       */
7e7c92a1   姜超   feature(*): 考评排名组...
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
      private void calcTotalPushMoney(List<EvalGroupUserShop> userShops, List<EvalGroupRewardDim> rewardDims,
                                      Map<Long, List<EvalGroupReward>> dimRewardMap, EvalScopeEnum scopeType, List<EvalPoolRewardDetail> rewardDetails) {
  
          for (EvalGroupRewardDim dim : rewardDims) {
              List<EvalGroupReward> totalCalcRewards = dimRewardMap.getOrDefault(dim.getId(), new ArrayList<>()).stream()
                      .filter(reward -> EvalRewardCalMethodEnum.RANK.equals(reward.getCalMethod()) ||
                              EvalRewardCalMethodEnum.TOTAL_PROPORTION.equals(reward.getCalMethod()))
                      .collect(Collectors.toList());
  
              for (EvalGroupReward evalGroupReward : totalCalcRewards) {
                  List<EvalGroupUserShop> filterUserShops = filterUserShops(dim, scopeType, userShops);
                  if (PublicUtil.isEmpty(filterUserShops)) {
                      continue;
                  }
                  final String rewardProjectName = evalGroupReward.getName();
                  EvalRewardBaseCalculator calculator = calculatorRewardMap.get(evalGroupReward.getCalMethod());
                  if (Objects.isNull(calculator)) {
                      log.error("[{}_{}]计算器不存在", evalGroupReward.getId(), rewardProjectName);
                      return;
                  }
                  calculator.calculateGroup(userShops, evalGroupReward);
                  for (EvalGroupUserShop userShop : filterUserShops) {
                      EvalPoolRewardDetail detail = createDetail(userShop);
                      detail.setScopeType(userShop.getScopeType());
                      detail.setEvalGroupRewardId(evalGroupReward.getId());
                      detail.setAmount(Optional.ofNullable(userShop.getEvalGroupRewardAmount()).orElse(BigDecimal.ZERO));
                      rewardDetails.add(detail);
                  }
e2386ce2   姜超   feature(*): 考评计算得分修改
431
432
433
434
435
436
              }
          }
      }
      /**
       * 计算绩效金额
       *
e2386ce2   姜超   feature(*): 考评计算得分修改
437
438
       * @param rewardDetails
       */
da42a3d8   姜超   feature(*): 计算考评代码优化
439
440
441
442
443
444
445
446
447
      private void calcRewardMoney(List<EvalGroupReward> rewards, EvalGroupUserShop userShop, List<EvalPoolRewardDetail> rewardDetails) {
  
          List<EvalGroupReward> calcRewards = rewards.stream()
                  .filter(reward ->
                          EvalRewardCalMethodEnum.FIXATION.equals(reward.getCalMethod()) ||
                          EvalRewardCalMethodEnum.LADDER.equals(reward.getCalMethod()) ||
                          EvalRewardCalMethodEnum.LADDER_DOUBLE.equals(reward.getCalMethod()))
                  .collect(Collectors.toList());
          for (EvalGroupReward evalGroupReward : calcRewards) {
e2386ce2   姜超   feature(*): 考评计算得分修改
448
449
450
451
452
453
454
455
              final String rewardProjectName = evalGroupReward.getName();
              EvalRewardBaseCalculator calculator = calculatorRewardMap.get(evalGroupReward.getCalMethod());
              if (Objects.isNull(calculator)) {
                  log.error("[{}_{}]计算器不存在", evalGroupReward.getId(), rewardProjectName);
                  return;
              }
              final BigDecimal salaryMoney = calculator.calculate(userShop, evalGroupReward);
              if (Objects.nonNull(salaryMoney)) {
da42a3d8   姜超   feature(*): 计算考评代码优化
456
                  EvalPoolRewardDetail detail = createDetail(userShop);
e2386ce2   姜超   feature(*): 考评计算得分修改
457
458
                  detail.setScopeType(userShop.getScopeType());
                  detail.setEvalGroupRewardId(evalGroupReward.getId());
ea6b2fd6   姜超   feature(*): 门店奖惩分配
459
                  detail.setAmount(salaryMoney);
e2386ce2   姜超   feature(*): 考评计算得分修改
460
                  rewardDetails.add(detail);
c1b3c16f   姜超   feature(*): 门店考评池查询
461
462
  
                  userShop.setReward(userShop.getReward().add(salaryMoney));
e2386ce2   姜超   feature(*): 考评计算得分修改
463
464
465
466
              }
          }
      }
  
8b61df4a   姜超   feature(*): 计算考评排名
467
468
469
470
471
472
473
      /**
       * 缓存需要计算考评排名
       *
       * @param localDate
       */
      public void cacheCalculableEvalGroupRank(LocalDate localDate) {
          List<EvalGroupRank> evalGroupRanks = evalGroupRankService.list(Wrappers.<EvalGroupRank>lambdaQuery()
a33a5f4c   姜超   feature(*): 考评数据抽取修改
474
                  .ge(EvalGroupRank::getOverTime, localDate)
8b61df4a   姜超   feature(*): 计算考评排名
475
476
                  .eq(EvalGroupRank::getYn, Boolean.TRUE)
          );
8945afe5   姜超   feature(*): 考评保存修改
477
478
479
          if (PublicUtil.isEmpty(evalGroupRanks)) {
              return;
          }
8b61df4a   姜超   feature(*): 计算考评排名
480
481
          List<String> rankBOS = new ArrayList<>();
          for (EvalGroupRank evalGroupRank : evalGroupRanks) {
8945afe5   姜超   feature(*): 考评保存修改
482
483
484
              List<EvalGroup> evalGroups = evalGroupService.getEffectsByRankId(evalGroupRank.getId(), localDate);
              if (PublicUtil.isEmpty(evalGroups)) {
                  continue;
8b61df4a   姜超   feature(*): 计算考评排名
485
              }
8945afe5   姜超   feature(*): 考评保存修改
486
              rankBOS.add(convertRankStr(evalGroupRank, localDate, evalGroups));
8b61df4a   姜超   feature(*): 计算考评排名
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
          }
  
          if (PublicUtil.isNotEmpty(rankBOS)) {
              ListOperations<String, String> listOps = stringRedisTemplate.opsForList();
              listOps.rightPushAll(getCalcEvalRankKey(), rankBOS);
          }
      }
  
  
      /**
       * 计算考评排名组
       */
      public void calcEvalGroupRank() {
          ListOperations<String, String> listOps = stringRedisTemplate.opsForList();
          List<String> errList = new ArrayList<>();
          String jsonStr;
          while ((jsonStr = listOps.leftPop(getCalcEvalRankKey())) != null) {
              if (StringUtils.isValid(jsonStr)) {
                  EvalGroupCalculableRankBO calculableBO = JSONObject.parseObject(jsonStr, EvalGroupCalculableRankBO.class);
                  if (Objects.nonNull(calculableBO)) {
                      try {
8945afe5   姜超   feature(*): 考评保存修改
508
                          calcEvalRank(calculableBO);
8b61df4a   姜超   feature(*): 计算考评排名
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
                      } catch (Exception ex) {
                          log.error("计算考评排名组失败:[{}]", jsonStr, ex);
                          errList.add(jsonStr);
                      }
                  }
              }
          }
          if (!CollectionUtils.isEmpty(errList)) {
              listOps.rightPushAll(getCalcEvalRankKey(), errList);
          }
      }
  
      /**
       * 计算排名
       *
       * @param bo
       */
      @Transactional(rollbackFor = Exception.class)
8945afe5   姜超   feature(*): 考评保存修改
527
528
529
530
531
532
533
534
      public void calcEvalRank(EvalGroupCalculableRankBO bo) {
          final List<Long> evalGroupIds = bo.getEvalGroupIds();
  
          List<EvalUserPool> pools = evalUserPoolService.list(Wrappers.<EvalUserPool>lambdaQuery()
                  .in(EvalUserPool::getEvalGroupId, evalGroupIds)
                  .eq(EvalUserPool::getInclusion, Boolean.TRUE)
                  .eq(EvalUserPool::getYn, Boolean.TRUE)
                  .orderByDesc(EvalUserPool::getScoreRatio)
8b61df4a   姜超   feature(*): 计算考评排名
535
          );
8945afe5   姜超   feature(*): 考评保存修改
536
537
          calcEvalUserRank(pools);
          evalUserPoolService.updateBatchById(pools);
8b61df4a   姜超   feature(*): 计算考评排名
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
      }
  
      /**
       * 计算考评排名
       *
       * @param pools
       */
      public void calcEvalUserRank(List<EvalUserPool> pools) {
          int rank = 1;
          Optional<BigDecimal> lastKpiScoreRatioOp = pools.stream().map(EvalUserPool::getScoreRatio).max(BigDecimal::compareTo);
          if (Boolean.FALSE.equals(lastKpiScoreRatioOp.isPresent())) {
              return;
          }
          BigDecimal lastKpiScoreRatio = lastKpiScoreRatioOp.get();
          for (EvalUserPool pool : pools) {
              if (PublicUtil.isEmpty(pool.getScoreRatio())) {
                  continue;
              }
              if (lastKpiScoreRatio.compareTo(pool.getScoreRatio()) != 0) {
                  rank++;
              }
              pool.setRank(rank);
              lastKpiScoreRatio = pool.getScoreRatio();
          }
      }
  
      /**
       * 计算考评排名
       *
       * @param pools
       */
      public void calcEvalShopRank(List<EvalShopPool> pools) {
          int rank = 1;
          Optional<BigDecimal> lastKpiScoreRatioOp = pools.stream().map(EvalShopPool::getScoreRatio).max(BigDecimal::compareTo);
          if (Boolean.FALSE.equals(lastKpiScoreRatioOp.isPresent())) {
              return;
          }
          BigDecimal lastKpiScoreRatio = lastKpiScoreRatioOp.get();
          for (EvalShopPool pool : pools) {
              if (PublicUtil.isEmpty(pool.getScoreRatio())) {
                  continue;
              }
              if (lastKpiScoreRatio.compareTo(pool.getScoreRatio()) != 0) {
                  rank++;
              }
              pool.setRank(rank);
              lastKpiScoreRatio = pool.getScoreRatio();
          }
      }
  
  
8945afe5   姜超   feature(*): 考评保存修改
589
      public String convertRankStr(EvalGroupRank evalGroupRank, LocalDate localDate, List<EvalGroup> evalGroups) {
8b61df4a   姜超   feature(*): 计算考评排名
590
591
          EvalGroupCalculableRankBO rankBO = EvalGroupCalculableRankBO.builder()
                  .groupId(evalGroupRank.getGroupId())
8945afe5   姜超   feature(*): 考评保存修改
592
593
594
  //                .scopeType(evalGroupRank.getScopeType())
  //                .egcs(evalGroupRank.getEgcs())
                  .evalGroupIds(evalGroups.stream().map(EvalGroup::getId).collect(Collectors.toList()))
8b61df4a   姜超   feature(*): 计算考评排名
595
596
597
598
599
                  .localDate(localDate)
                  .build();
          return JSONObject.toJSONString(rankBO);
      }
  
e2386ce2   姜超   feature(*): 考评计算得分修改
600
601
      private EvalPoolIndicatorDetail createPoolIndicatorValue(BigDecimal score, EvalGroupIndicator indicator, Long groupId) {
          EvalPoolIndicatorDetail indicatorDetail = new EvalPoolIndicatorDetail();
15a68981   姜超   feature(*): 处理百分数
602
          indicatorDetail.setEvalGroupId(indicator.getEvalGroupId());
e2386ce2   姜超   feature(*): 考评计算得分修改
603
604
605
606
607
608
609
610
611
612
          indicatorDetail.setEvalGroupIndicatorId(indicator.getId());
          indicatorDetail.setScore(score);
          indicatorDetail.setYn(Boolean.TRUE);
          indicatorDetail.setGroupId(groupId);
          return indicatorDetail;
      }
  
      /**
       * 创建实体
       *
e2386ce2   姜超   feature(*): 考评计算得分修改
613
614
       * @return
       */
da42a3d8   姜超   feature(*): 计算考评代码优化
615
      private EvalPoolRewardDetail createDetail(EvalGroupUserShop userShop) {
e2386ce2   姜超   feature(*): 考评计算得分修改
616
          EvalPoolRewardDetail poolDetail = new EvalPoolRewardDetail();
e0944b69   姜超   feature(*): 修改计算考评
617
          poolDetail.setPoolId(userShop.getPoolId());
15a68981   姜超   feature(*): 处理百分数
618
          poolDetail.setEvalGroupId(userShop.getEvalGroupId());
da42a3d8   姜超   feature(*): 计算考评代码优化
619
          poolDetail.setScopeType(userShop.getScopeType());
ea6b2fd6   姜超   feature(*): 门店奖惩分配
620
          poolDetail.setAmount(BigDecimal.ZERO);
da42a3d8   姜超   feature(*): 计算考评代码优化
621
622
          poolDetail.setDataDate(userShop.getDataDate());
          poolDetail.setGroupId(userShop.getGroupId());
e2386ce2   姜超   feature(*): 考评计算得分修改
623
624
625
626
          poolDetail.setYn(Boolean.TRUE);
          return poolDetail;
      }
  
da42a3d8   姜超   feature(*): 计算考评代码优化
627
      public EvalGroupUserShop convertBO(EvalGroupUser user, EvalUserPool userPool) {
e2386ce2   姜超   feature(*): 考评计算得分修改
628
          EvalGroupUserShop userShop = new EvalGroupUserShop();
9161579f   姜超   feature(*): 排名返回名称
629
          userShop.setName(user.getUserName());
e2386ce2   姜超   feature(*): 考评计算得分修改
630
          userShop.setScopeType(EvalScopeEnum.STAFF);
e2386ce2   姜超   feature(*): 考评计算得分修改
631
          userShop.setEvalGroupId(user.getEvalGroupId());
da42a3d8   姜超   feature(*): 计算考评代码优化
632
          userShop.setPoolId(userPool.getId());
7e7c92a1   姜超   feature(*): 考评排名组...
633
634
          userShop.setPostId(userPool.getPostId());
          userShop.setShopId(userPool.getShopId());
e2386ce2   姜超   feature(*): 考评计算得分修改
635
636
637
          userShop.setReferId(user.getUserId());
          userShop.setDataDate(user.getDataDate());
          userShop.setGroupId(user.getGroupId());
da42a3d8   姜超   feature(*): 计算考评代码优化
638
639
          userShop.setScore(BigDecimal.ZERO);
          userShop.setReward(BigDecimal.ZERO);
e2386ce2   姜超   feature(*): 考评计算得分修改
640
641
642
          return userShop;
      }
  
80e64f6f   姜超   feature(*): 考评排名组...
643
      public EvalGroupUserShop convertBO(EvalShopPool shopPool, EvalGroup evalGroup, LocalDate beginDate, LocalDate dataDate) {
da42a3d8   姜超   feature(*): 计算考评代码优化
644
          EvalGroupUserShop userShop = new EvalGroupUserShop();
9161579f   姜超   feature(*): 排名返回名称
645
          userShop.setName(shopPool.getShopName());
da42a3d8   姜超   feature(*): 计算考评代码优化
646
647
          userShop.setReferId(shopPool.getShopId());
          userShop.setPoolId(shopPool.getId());
7e7c92a1   姜超   feature(*): 考评排名组...
648
          userShop.setShopId(shopPool.getShopId());
da42a3d8   姜超   feature(*): 计算考评代码优化
649
650
651
          userShop.setScopeType(EvalScopeEnum.SHOP);
          userShop.setEvalId(userShop.getEvalId());
          userShop.setEvalGroupId(evalGroup.getId());
80e64f6f   姜超   feature(*): 考评排名组...
652
          userShop.setBeginDate(beginDate);
da42a3d8   姜超   feature(*): 计算考评代码优化
653
654
655
656
657
          userShop.setDataDate(dataDate);
          userShop.setGroupId(evalGroup.getGroupId());
          userShop.setScore(BigDecimal.ZERO);
          userShop.setReward(BigDecimal.ZERO);
          return userShop;
725e9bc8   姜超   feature(*): 计算考评修改
658
      }
5ad9dc20   姜超   feature(*): 缓存考评组
659
  
f946d0a5   姜超   feature(*): 考评定时任务
660
  }