Blame view

fw-morax-server/src/main/java/cn/fw/morax/server/task/KpiReportRatioTask.java 26.2 KB
60d0b5db   姜超   feature(*): 绩效报表抽取
1
2
3
4
5
6
7
8
9
  package cn.fw.morax.server.task;
  
  import cn.fw.common.cache.locker.DistributedLocker;
  import cn.fw.morax.common.constant.TimeTaskConstant;
  import cn.fw.morax.common.utils.PublicUtil;
  import cn.fw.morax.domain.db.kpi.KpiGroup;
  import cn.fw.morax.domain.db.kpi.KpiGroupRank;
  import cn.fw.morax.domain.db.kpi.KpiPool;
  import cn.fw.morax.domain.db.kpi.KpiRatio;
60d0b5db   姜超   feature(*): 绩效报表抽取
10
  import cn.fw.morax.domain.dto.GroupCalKpiRatioDTO;
91b69450   姜超   feature(mq): 门店名称...
11
  import cn.fw.morax.domain.enums.ReportDimensionEnum;
60d0b5db   姜超   feature(*): 绩效报表抽取
12
13
  import cn.fw.morax.rpc.ehr.EhrRpcService;
  import cn.fw.morax.rpc.ehr.dto.*;
60d0b5db   姜超   feature(*): 绩效报表抽取
14
15
  import cn.fw.morax.rpc.oop.OopRpcService;
  import cn.fw.morax.rpc.oop.dto.ShopDTO;
60d0b5db   姜超   feature(*): 绩效报表抽取
16
17
18
19
20
21
  import cn.fw.morax.service.data.kpi.KpiGroupRankService;
  import cn.fw.morax.service.data.kpi.KpiGroupService;
  import cn.fw.morax.service.data.kpi.KpiPoolService;
  import cn.fw.morax.service.data.kpi.KpiRatioService;
  import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  import com.google.common.collect.Lists;
7d59a85e   姜超   feature(*): redis...
22
  import lombok.Getter;
60d0b5db   姜超   feature(*): 绩效报表抽取
23
24
  import lombok.RequiredArgsConstructor;
  import lombok.extern.slf4j.Slf4j;
324b51af   姜超   feature(*): 报表字段修改
25
  import org.apache.commons.collections4.map.MultiKeyMap;
60d0b5db   姜超   feature(*): 绩效报表抽取
26
  import org.redisson.api.RLock;
7d59a85e   姜超   feature(*): redis...
27
  import org.springframework.beans.factory.annotation.Value;
60d0b5db   姜超   feature(*): 绩效报表抽取
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
  import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  import org.springframework.scheduling.annotation.Scheduled;
  import org.springframework.stereotype.Component;
  import org.springframework.transaction.annotation.Transactional;
  import org.springframework.util.CollectionUtils;
  
  import java.math.BigDecimal;
  import java.math.RoundingMode;
  import java.time.LocalDate;
  import java.time.YearMonth;
  import java.util.*;
  import java.util.concurrent.locks.Lock;
  import java.util.function.Predicate;
  import java.util.stream.Collectors;
  
  /**
   * @author : jiangchao
1a596c74   姜超   feature(*): 绩效报表
45
46
   * @className : KpiReportRatioTask
   * @description : 绩效报表定时器
60d0b5db   姜超   feature(*): 绩效报表抽取
47
48
49
50
51
52
53
54
   * @date : 2022-04-07 15:29
   */
  @Component
  @Slf4j
  @RequiredArgsConstructor
  @ConditionalOnProperty(prefix = "task", name = "switch", havingValue = "on")
  public class KpiReportRatioTask {
  
584c7bfd   姜超   feature(*): 保存薪酬、...
55
56
      private final KpiGroupRankService kpiGroupRankService;
      private final DistributedLocker distributedLocker;
60d0b5db   姜超   feature(*): 绩效报表抽取
57
58
59
60
      private final KpiGroupService kpiGroupService;
      private final KpiPoolService kpiPoolService;
      private final KpiRatioService kpiRatioService;
      private final EhrRpcService ehrRpcService;
60d0b5db   姜超   feature(*): 绩效报表抽取
61
      private final OopRpcService oopRpcService;
60d0b5db   姜超   feature(*): 绩效报表抽取
62
  
7d59a85e   姜超   feature(*): redis...
63
64
65
      @Value("${spring.cache.custom.global-prefix}:kpi:group:report")
      @Getter
      private String kpiGroupReportDistKey;
60d0b5db   姜超   feature(*): 绩效报表抽取
66
67
68
69
70
71
72
73
  
      /**
       * 绩效报表定时任务
       *
       */
      @Scheduled(cron = TimeTaskConstant.KPI_REPORT)
      @Transactional(rollbackFor = Exception.class)
      public void kpiReportTask() {
9ddefeb7   姜超   feature(*): 报表相关实体类
74
  //        this.kpiReport(LocalDate.now().minusDays(1));
60d0b5db   姜超   feature(*): 绩效报表抽取
75
76
77
78
79
80
81
82
83
      }
  
      /**
       * 绩效报表定时任务
       *
       * @param date
       */
      @Transactional(rollbackFor = Exception.class)
      public void kpiReport(LocalDate date) {
7d59a85e   姜超   feature(*): redis...
84
          Lock lock = distributedLocker.lock(getKpiGroupReportDistKey());
60d0b5db   姜超   feature(*): 绩效报表抽取
85
86
87
88
          if (! ((RLock) lock).isLocked()) {
              return;
          }
          try {
1a596c74   姜超   feature(*): 绩效报表
89
              log.info("定时任务【绩效报表数据抽取】开始执行");
60d0b5db   姜超   feature(*): 绩效报表抽取
90
91
92
93
94
95
  
              kpiRatioService.update(Wrappers.<KpiRatio>lambdaUpdate()
                      .set(KpiRatio::getYn, Boolean.FALSE)
                      .eq(KpiRatio::getDate, date)
              );
  
111a930a   xianpengcheng   阅读过去代码加的一些注释
96
97
98
              /**
               * 获取所有生效中的绩效组
               */
60d0b5db   姜超   feature(*): 绩效报表抽取
99
100
101
102
103
104
              List<KpiGroup> allKpiGroups = kpiGroupService.queryKgiGroupsByDay(date);
              Map<Long, List<KpiGroup>> groupKpiGroupMap = allKpiGroups.stream().collect(Collectors.groupingBy(KpiGroup::getGroupId));
              List<KpiRatio> kpiRatios = Lists.newArrayListWithCapacity(500);
              YearMonth curMonth = YearMonth.from(date);
              YearMonth preMonth = YearMonth.from(date.minusMonths(1));
              YearMonth preTwoMonth = YearMonth.from(date.minusMonths(2));
60d0b5db   姜超   feature(*): 绩效报表抽取
105
  
f1e68b31   姜超   feature(*): 报表修改
106
              //遍历集团
60d0b5db   姜超   feature(*): 绩效报表抽取
107
              oopRpcService.allGroups().stream().forEach(group -> {
f1e68b31   姜超   feature(*): 报表修改
108
                  //构建查询参数
60d0b5db   姜超   feature(*): 绩效报表抽取
109
                  Long groupId = group.getId();
111a930a   xianpengcheng   阅读过去代码加的一些注释
110
111
112
                  /**
                   * calDTO 得到计算的基础数据,包含当月N,上月N-1,上上月N-2的绩效人的绩效数据,还有绩效排名组信息,绩效组信息
                   */
f1e68b31   姜超   feature(*): 报表修改
113
                  GroupCalKpiRatioDTO calDTO = buildParam(curMonth, preMonth, preTwoMonth, groupId);
60d0b5db   姜超   feature(*): 绩效报表抽取
114
                  calDTO.setKpiGroups(groupKpiGroupMap.getOrDefault(groupId, new ArrayList<>()));
60d0b5db   姜超   feature(*): 绩效报表抽取
115
  
111a930a   xianpengcheng   阅读过去代码加的一些注释
116
                  //查询所有绩效组包含的所有门店
f1e68b31   姜超   feature(*): 报表修改
117
118
119
120
121
122
                  Set<Long> shopIds = calDTO.getKpiGroups().stream().map(salaryGroup -> {
                      return salaryGroup.getShopIds().stream().map(Long::new).collect(Collectors.toList());
                  }).collect(HashSet::new, Set::addAll, Set::addAll);
                  if (PublicUtil.isEmpty(shopIds)) {
                      return;
                  }
60d0b5db   姜超   feature(*): 绩效报表抽取
123
124
125
                  List<ShopDTO> shopDTOs = oopRpcService.queryShops(new ArrayList<>(shopIds));
  
                  //计算管理者数据
f1e68b31   姜超   feature(*): 报表修改
126
                  calManagerData(calDTO, kpiRatios, shopDTOs, shopIds);
584c7bfd   姜超   feature(*): 保存薪酬、...
127
                  //计算绩效排名组 门店
f1e68b31   姜超   feature(*): 报表修改
128
                  calKpiRankData(calDTO, kpiRatios, shopDTOs);
60d0b5db   姜超   feature(*): 绩效报表抽取
129
130
                  //计算员工
                  calStaffData(calDTO, kpiRatios);
584c7bfd   姜超   feature(*): 保存薪酬、...
131
                  //计算绩效组门店
f1e68b31   姜超   feature(*): 报表修改
132
                  calShopData(calDTO, kpiRatios, shopDTOs);
60d0b5db   姜超   feature(*): 绩效报表抽取
133
134
135
136
              });
              if (PublicUtil.isNotEmpty(kpiRatios)) {
                  kpiRatios.stream().forEach(kpiRatio -> {
                      kpiRatio.setDate(date);
584c7bfd   姜超   feature(*): 保存薪酬、...
137
                      kpiRatio.setYn(Boolean.TRUE);
60d0b5db   姜超   feature(*): 绩效报表抽取
138
139
140
141
                  });
                  kpiRatioService.saveBatch(kpiRatios);
              }
  
60d0b5db   姜超   feature(*): 绩效报表抽取
142
143
144
145
146
147
148
          } catch (Exception e){
              log.error(e.getMessage(), e);
          } finally {
              lock.unlock();
          }
      }
  
f1e68b31   姜超   feature(*): 报表修改
149
150
151
152
153
154
155
156
157
158
159
160
161
      /**
       *
       * 构建查询参数
       * @param curMonth
       * @param preMonth
       * @param preTwoMonth
       * @param groupId
       * @return
       */
      public GroupCalKpiRatioDTO buildParam(YearMonth curMonth, YearMonth preMonth, YearMonth preTwoMonth, Long groupId) {
  
          List<YearMonth> yearMonths = new ArrayList<YearMonth>(){{add(curMonth);add(preMonth);add(preTwoMonth);}};
  
111a930a   xianpengcheng   阅读过去代码加的一些注释
162
163
164
165
          /**
           * 获取某集团下指定月度下(当月N,上月N-1,上上月N-2)所有人的绩效数据
           * kpi_pool  UNIQUE KEY `pool_kpi_id_user_id_monthly_uindex` (`kpi_group_id`,`user_id`,`monthly`),
           */
f1e68b31   姜超   feature(*): 报表修改
166
167
168
169
170
          List<KpiPool> kpiPools = kpiPoolService.list(Wrappers.<KpiPool>lambdaQuery()
                  .in(KpiPool::getMonthly, yearMonths)
                  .eq(KpiPool::getYn, Boolean.TRUE)
                  .eq(KpiPool::getGroupId, groupId)
          );
111a930a   xianpengcheng   阅读过去代码加的一些注释
171
172
173
          /**
           * 得到(当月N,上月N-1,上上月N-2)对应的各自月度的绩效人数据
           */
f1e68b31   姜超   feature(*): 报表修改
174
175
176
177
178
          Map<YearMonth, List<KpiPool>> poolMap = kpiPools.stream().collect(Collectors.groupingBy(KpiPool::getMonthly));
          List<KpiPool> curMonthPools = poolMap.getOrDefault(curMonth, new ArrayList<>());
          List<KpiPool> preMonthPools = poolMap.getOrDefault(preMonth, new ArrayList<>());
          List<KpiPool> preTwoMonthPools = poolMap.getOrDefault(preTwoMonth, new ArrayList<>());
  
111a930a   xianpengcheng   阅读过去代码加的一些注释
179
180
181
          /**
           * 获取绩效排名组数据
           */
f1e68b31   姜超   feature(*): 报表修改
182
183
184
185
186
187
188
189
190
191
192
193
194
          List<KpiGroupRank> kpiGroupRanks = kpiGroupRankService.list(Wrappers.<KpiGroupRank>lambdaQuery()
                  .eq(KpiGroupRank::getYn, Boolean.TRUE)
                  .eq(KpiGroupRank::getGroupId, groupId)
          );
  
          GroupCalKpiRatioDTO calDTO = new GroupCalKpiRatioDTO();
          calDTO.setCurMonthPools(curMonthPools);
          calDTO.setPreMonthPools(preMonthPools);
          calDTO.setPreTwoMonthPools(preTwoMonthPools);
          calDTO.setGroupId(groupId);
          calDTO.setKpiGroupRanks(kpiGroupRanks);
  
          return calDTO;
60d0b5db   姜超   feature(*): 绩效报表抽取
195
  
f1e68b31   姜超   feature(*): 报表修改
196
      }
60d0b5db   姜超   feature(*): 绩效报表抽取
197
198
199
200
201
  
      /**
       * 计算管理者维度数据 (门店、绩效组)
       *
       * @param calDto
60d0b5db   姜超   feature(*): 绩效报表抽取
202
203
       */
      public void calManagerData(GroupCalKpiRatioDTO calDto,
f1e68b31   姜超   feature(*): 报表修改
204
205
206
                                 List<KpiRatio> kpiRatios,
                                 List<ShopDTO> shopDTOs,
                                 Set<Long> shopIds
60d0b5db   姜超   feature(*): 绩效报表抽取
207
208
209
210
211
212
      ) {
          List<KpiPool> curMonthPools = calDto.getCurMonthPools();
          List<KpiPool> preMonthPools = calDto.getPreMonthPools();
          List<KpiPool> preTwoMonthPools = calDto.getPreTwoMonthPools();
          List<KpiGroup> kpiGroups = calDto.getKpiGroups();
  
111a930a   xianpengcheng   阅读过去代码加的一些注释
213
214
215
          /**
           * 绩效组下所有 岗位 对应->门店信息 (1:N)
           */
f1e68b31   姜超   feature(*): 报表修改
216
217
218
219
          Map<Long, Set<Long>> kpiGroupPostShopIds = kpiGroups.stream().collect(Collectors.toMap(
                  KpiGroup::getPostId, kpiGroup -> new HashSet<>(kpiGroup.getShopIds()),
                  (v1, v2) -> {v1.addAll(v2);return v1;}));
          MultiKeyMap<Long, Long> kpiGroupPostShopIdMap = new MultiKeyMap<>();
324b51af   姜超   feature(*): 报表字段修改
220
221
          for (KpiGroup kpiGroup : kpiGroups) {
              for (Long shopId : kpiGroup.getShopIds()) {
111a930a   xianpengcheng   阅读过去代码加的一些注释
222
223
224
                  /**
                   * 岗位 + 门店 :-> 绩效组
                   */
f1e68b31   姜超   feature(*): 报表修改
225
                  kpiGroupPostShopIdMap.put(kpiGroup.getPostId(), shopId, kpiGroup.getId());
324b51af   姜超   feature(*): 报表字段修改
226
227
228
              }
          }
  
111a930a   xianpengcheng   阅读过去代码加的一些注释
229
230
231
          /**
           * 绩效组下所有门店对应的管理者集合
           */
f1e68b31   姜超   feature(*): 报表修改
232
          List<ManagerDTO> managerDTOS = ehrRpcService.getRealTimeShopManager(new ArrayList<>(shopIds));
324b51af   姜超   feature(*): 报表字段修改
233
  
60d0b5db   姜超   feature(*): 绩效报表抽取
234
          for (ManagerDTO manager : managerDTOS) {
91b69450   姜超   feature(mq): 门店名称...
235
              Map<Long, Set<Long>> createShopPostIdMap = new HashMap<>();
f1e68b31   姜超   feature(*): 报表修改
236
237
238
239
240
              Set<Long> createKpiGroupIds = new HashSet<>();
  
              //管理岗位
              for (ManagerStaffDTO managerStaffDTO : manager.getScopeList()) {
                  Long postId = managerStaffDTO.getPostId();
111a930a   xianpengcheng   阅读过去代码加的一些注释
241
                  //绩效组所有岗位,只处理能匹配符合绩效组下的对应岗位的数据,不符合不处理
f1e68b31   姜超   feature(*): 报表修改
242
                  if (! kpiGroupPostShopIds.keySet().contains(postId)) {
ab0e54c3   姜超   feature(mq): 门店名称...
243
244
                      continue;
                  }
f1e68b31   姜超   feature(*): 报表修改
245
246
                  //管理门店
                  for (ManagerStaffShopDTO shopDTO : managerStaffDTO.getShopList()) {
111a930a   xianpengcheng   阅读过去代码加的一些注释
247
                      //绩效组岗位所有门店,只处理能匹配符合绩效组下的岗位对应门店的数据,不符合不处理
f1e68b31   姜超   feature(*): 报表修改
248
249
250
                      if (! kpiGroupPostShopIds.get(postId).contains(shopDTO.getShopId())) {
                          continue;
                      }
91b69450   姜超   feature(mq): 门店名称...
251
252
253
254
255
  
                      Long shopId = shopDTO.getShopId();
                      if (createShopPostIdMap.containsKey(shopId)) {
                          createShopPostIdMap.get(shopId).add(postId);
                      } else {
111a930a   xianpengcheng   阅读过去代码加的一些注释
256
                          //门店: 多岗位 (1:N)
91b69450   姜超   feature(mq): 门店名称...
257
258
259
                          createShopPostIdMap.put(shopId, new HashSet<Long>(){{add(postId);}});
                      }
  
f1e68b31   姜超   feature(*): 报表修改
260
261
262
263
264
265
266
                      if (kpiGroupPostShopIdMap.containsKey(postId, shopDTO.getShopId())) {
                          createKpiGroupIds.add(kpiGroupPostShopIdMap.get(postId, shopDTO.getShopId()));
                      }
                  }
              }
  
              //管理者门店、岗位 与 绩效组门店、岗位没有匹配
91b69450   姜超   feature(mq): 门店名称...
267
              if (PublicUtil.isEmpty(createShopPostIdMap)) {
f1e68b31   姜超   feature(*): 报表修改
268
269
270
                  continue;
              }
  
111a930a   xianpengcheng   阅读过去代码加的一些注释
271
              //管理的所有员工id集合
f1e68b31   姜超   feature(*): 报表修改
272
273
274
              Set<Long> manageStaffIds = manager.getManageStaffList().stream().map(StaffBaseInfoDTO::getId).collect(Collectors.toSet());
  
              kpiGroups.stream().filter(kpiGroup -> createKpiGroupIds.contains(kpiGroup.getId())).forEach(kpiGroup -> {
91b69450   姜超   feature(mq): 门店名称...
275
                  KpiRatio kpiRatio = new KpiRatio(ReportDimensionEnum.MANAGER_KPI_GROUP, calDto.getGroupId());
f1e68b31   姜超   feature(*): 报表修改
276
277
278
279
                  kpiRatio.setS1(manager.getStaffName());
                  kpiRatio.setL1(manager.getStaffId());
                  kpiRatio.setS4(kpiGroup.getName());
                  kpiRatio.setL4(kpiGroup.getId());
1efe930e   姜超   fix(*): 修改bug
280
281
                  kpiRatio.setS3(kpiGroup.getPostName());
                  kpiRatio.setL3(kpiGroup.getPostId());
f1e68b31   姜超   feature(*): 报表修改
282
283
284
285
286
287
288
289
                  Predicate<KpiPool> predicate = pool -> {
                      return kpiGroup.getId().equals(pool.getKpiGroupId()) && manageStaffIds.contains(pool.getUserId())
                              && Boolean.TRUE.equals(pool.getInclusion());
                  };
                  kpiRatio.setB1(averageRatio(curMonthPools, predicate));
                  kpiRatio.setB2(monthRatio(curMonthPools, predicate));
                  kpiRatio.setB3(monthRatio(preMonthPools, predicate));
                  kpiRatio.setB4(monthRatio(preTwoMonthPools, predicate));
1efe930e   姜超   fix(*): 修改bug
290
291
  
                  kpiRatio.setS8(String.join(",", kpiGroup.getShopIds().stream().map(String::valueOf).collect(Collectors.toList())));
f1e68b31   姜超   feature(*): 报表修改
292
293
294
                  kpiRatios.add(kpiRatio);
              });
  
91b69450   姜超   feature(mq): 门店名称...
295
              Set<Long> createShopIds = createShopPostIdMap.keySet();
f1e68b31   姜超   feature(*): 报表修改
296
              shopDTOs.stream().filter(shopDTO -> createShopIds.contains(shopDTO.getId())).forEach(shopDTO -> {
91b69450   姜超   feature(mq): 门店名称...
297
                  KpiRatio kpiRatio = new KpiRatio(ReportDimensionEnum.MANAGER_SHOP, calDto.getGroupId());
f1e68b31   姜超   feature(*): 报表修改
298
299
300
301
302
303
                  Long shopId = shopDTO.getId();
                  String shopName = shopDTO.getShopName();
                  kpiRatio.setS1(manager.getStaffName());
                  kpiRatio.setL1(manager.getStaffId());
                  kpiRatio.setL2(shopId);
                  kpiRatio.setS2(shopName);
91b69450   姜超   feature(mq): 门店名称...
304
305
306
307
308
309
  
                  Set<Long> postIds = createShopPostIdMap.get(shopDTO.getId());
                  if (PublicUtil.isNotEmpty(postIds)) {
                      kpiRatio.setS8(String.join(",", postIds.stream().map(String::valueOf).collect(Collectors.toList())));
                  }
  
f1e68b31   姜超   feature(*): 报表修改
310
311
312
313
314
315
316
317
                  Predicate<KpiPool> predicate = pool -> {
                      return shopId.equals(pool.getShopId()) && manageStaffIds.contains(pool.getUserId())
                              && Boolean.TRUE.equals(pool.getInclusion());
                  };
                  kpiRatio.setB1(averageRatio(curMonthPools, predicate));
                  kpiRatio.setB2(monthRatio(curMonthPools, predicate));
                  kpiRatio.setB3(monthRatio(preMonthPools, predicate));
                  kpiRatio.setB4(monthRatio(preTwoMonthPools, predicate));
84f9d303   姜超   feature(*): 定时任务修改
318
                  kpiRatio.setB7(countStaffNum(curMonthPools, predicate));
f1e68b31   姜超   feature(*): 报表修改
319
320
321
322
                  kpiRatios.add(kpiRatio);
              });
  
  
91b69450   姜超   feature(mq): 门店名称...
323
              KpiRatio kpiRatio = new KpiRatio(ReportDimensionEnum.MANAGER, calDto.getGroupId());
f1e68b31   姜超   feature(*): 报表修改
324
325
326
327
328
329
330
331
332
333
334
              kpiRatio.setS1(manager.getStaffName());
              kpiRatio.setL1(manager.getStaffId());
              Set<String> roleCodes = manager.getScopeList().stream()
                      .flatMap(managerStaffVo -> managerStaffVo.getRoleList().stream())
                      .map(ManagerStaffRoleDTO::getRoleCode)
                      .collect(Collectors.toSet());
              Set<String> roleNames = manager.getScopeList().stream()
                      .flatMap(managerStaffVo -> managerStaffVo.getRoleList().stream())
                      .map(ManagerStaffRoleDTO::getRoleName)
                      .collect(Collectors.toSet());
              if (PublicUtil.isNotEmpty(roleCodes)) {
91b69450   姜超   feature(mq): 门店名称...
335
                  kpiRatio.setS6(String.join(",", roleCodes));
f1e68b31   姜超   feature(*): 报表修改
336
337
              }
              if (PublicUtil.isNotEmpty(roleNames)) {
91b69450   姜超   feature(mq): 门店名称...
338
339
340
341
                  kpiRatio.setS7(String.join(",", roleNames));
              }
              if (PublicUtil.isNotEmpty(createShopIds)) {
                  kpiRatio.setS9(String.join(",", createShopIds.stream().map(String::valueOf).collect(Collectors.toList())));
60d0b5db   姜超   feature(*): 绩效报表抽取
342
              }
f1e68b31   姜超   feature(*): 报表修改
343
344
345
346
347
348
349
350
              Predicate<KpiPool> predicate = pool -> {
                  return manageStaffIds.contains(pool.getUserId()) && Boolean.TRUE.equals(pool.getInclusion());
              };
              kpiRatio.setB1(averageRatio(curMonthPools, predicate));
              kpiRatio.setB2(monthRatio(curMonthPools, predicate));
              kpiRatio.setB3(monthRatio(preMonthPools, predicate));
              kpiRatio.setB4(monthRatio(preTwoMonthPools, predicate));
              kpiRatios.add(kpiRatio);
60d0b5db   姜超   feature(*): 绩效报表抽取
351
  
60d0b5db   姜超   feature(*): 绩效报表抽取
352
353
          }
      }
9ddefeb7   姜超   feature(*): 报表相关实体类
354
  
60d0b5db   姜超   feature(*): 绩效报表抽取
355
356
357
358
359
360
      /**
       * 计算绩效排名组-门店维度数据
       *
       * @param calDto
       * @param kpiRatios
       */
f1e68b31   姜超   feature(*): 报表修改
361
362
363
      public void calKpiRankData(GroupCalKpiRatioDTO calDto,
                                 List<KpiRatio> kpiRatios,
                                 List<ShopDTO> shopDTOs
60d0b5db   姜超   feature(*): 绩效报表抽取
364
365
366
367
368
369
370
      ) {
          List<KpiPool> curMonthPools = calDto.getCurMonthPools();
          List<KpiPool> preMonthPools = calDto.getPreMonthPools();
          List<KpiPool> preTwoMonthPools = calDto.getPreTwoMonthPools();
          List<KpiGroup> kpiGroups = calDto.getKpiGroups();
  
          for (KpiGroupRank rank : calDto.getKpiGroupRanks()) {
a92022b7   姜超   feature(*): 绩效不再使...
371
              List<Long> kpiGroupIds = rank.getKpiGroupIds();
111a930a   xianpengcheng   阅读过去代码加的一些注释
372
              //绩效排名组下对应的绩效组集合
60d0b5db   姜超   feature(*): 绩效报表抽取
373
              List<KpiGroup> rankKpiGroups = kpiGroups.stream()
a92022b7   姜超   feature(*): 绩效不再使...
374
                      .filter(kpiGroup -> kpiGroupIds.contains(kpiGroup.getId()))
60d0b5db   姜超   feature(*): 绩效报表抽取
375
                      .collect(Collectors.toList());
91b69450   姜超   feature(mq): 门店名称...
376
              Set<Long> createShopIds = rankKpiGroups.stream().flatMap(kpiGroup -> kpiGroup.getShopIds().stream()).collect(Collectors.toSet());
60d0b5db   姜超   feature(*): 绩效报表抽取
377
  
91b69450   姜超   feature(mq): 门店名称...
378
379
              shopDTOs.stream().filter(shop -> createShopIds.contains(shop.getId())).forEach(shop -> {
                  KpiRatio kpiRatio = new KpiRatio(ReportDimensionEnum.KPI_RANK_SHOP, calDto.getGroupId());;
60d0b5db   姜超   feature(*): 绩效报表抽取
380
381
382
  
                  Long shopId = shop.getId();
                  Predicate<KpiPool> predicate = pool -> {
a92022b7   姜超   feature(*): 绩效不再使...
383
                      return shopId.equals(pool.getShopId()) && kpiGroupIds.contains(pool.getKpiGroupId()) && Boolean.TRUE.equals(pool.getInclusion());
60d0b5db   姜超   feature(*): 绩效报表抽取
384
385
386
387
388
389
                  };
                  kpiRatio.setS5(rank.getName());
                  kpiRatio.setL5(rank.getId());
                  kpiRatio.setL2(shopId);
                  kpiRatio.setS2(shop.getShopName());
                  kpiRatio.setB1(averageRatio(curMonthPools, predicate));
84f9d303   姜超   feature(*): 定时任务修改
390
                  kpiRatio.setB7(countStaffNum(curMonthPools, predicate));
60d0b5db   姜超   feature(*): 绩效报表抽取
391
392
393
394
395
                  kpiRatio.setB2(monthRatio(curMonthPools, predicate));
                  kpiRatio.setB3(monthRatio(preMonthPools, predicate));
                  kpiRatio.setB4(monthRatio(preTwoMonthPools, predicate));
                  kpiRatios.add(kpiRatio);
              });
f1e68b31   姜超   feature(*): 报表修改
396
  
91b69450   姜超   feature(mq): 门店名称...
397
              KpiRatio kpiRatio = new KpiRatio(ReportDimensionEnum.KPI_RANK, calDto.getGroupId());;
f1e68b31   姜超   feature(*): 报表修改
398
              Predicate<KpiPool> predicate = pool -> {
a92022b7   姜超   feature(*): 绩效不再使...
399
                  return kpiGroupIds.contains(pool.getKpiGroupId()) && Boolean.TRUE.equals(pool.getInclusion());
f1e68b31   姜超   feature(*): 报表修改
400
401
402
              };
              kpiRatio.setS5(rank.getName());
              kpiRatio.setL5(rank.getId());
91b69450   姜超   feature(mq): 门店名称...
403
404
405
406
              if (PublicUtil.isNotEmpty(createShopIds)) {
                  kpiRatio.setS9(String.join(",", createShopIds.stream().map(String::valueOf).collect(Collectors.toList())));
              }
  
f1e68b31   姜超   feature(*): 报表修改
407
408
409
410
411
412
              kpiRatio.setB1(averageRatio(curMonthPools, predicate));
              kpiRatio.setB2(monthRatio(curMonthPools, predicate));
              kpiRatio.setB3(monthRatio(preMonthPools, predicate));
              kpiRatio.setB4(monthRatio(preTwoMonthPools, predicate));
              kpiRatios.add(kpiRatio);
  
60d0b5db   姜超   feature(*): 绩效报表抽取
413
414
415
416
417
418
419
420
421
          }
      }
  
      /**
       * 计算绩效组门店维度数据
       *
       * @param calDto
       * @param kpiRatios
       */
f1e68b31   姜超   feature(*): 报表修改
422
423
424
      public void calShopData(GroupCalKpiRatioDTO calDto,
                              List<KpiRatio> kpiRatios,
                              List<ShopDTO> shopDTOs
60d0b5db   姜超   feature(*): 绩效报表抽取
425
426
427
428
429
430
      ) {
          List<KpiPool> curMonthPools = calDto.getCurMonthPools();
          List<KpiPool> preMonthPools = calDto.getPreMonthPools();
          List<KpiPool> preTwoMonthPools = calDto.getPreTwoMonthPools();
          List<KpiGroup> kpiGroups = calDto.getKpiGroups();
  
f1e68b31   姜超   feature(*): 报表修改
431
          shopDTOs.stream().forEach(shop -> {
91b69450   姜超   feature(mq): 门店名称...
432
              KpiRatio kpiRatio = new KpiRatio(ReportDimensionEnum.SHOP, calDto.getGroupId());
f1e68b31   姜超   feature(*): 报表修改
433
434
435
436
437
438
439
              Long shopId = shop.getId();
              Predicate<KpiPool> predicate = pool -> {
                  return shopId.equals(pool.getShopId()) && Boolean.TRUE.equals(pool.getInclusion());
              };
              kpiRatio.setL2(shopId);
              kpiRatio.setS2(shop.getShopName());
              kpiRatio.setB1(averageRatio(curMonthPools, predicate));
84f9d303   姜超   feature(*): 定时任务修改
440
              kpiRatio.setB7(countStaffNum(curMonthPools, predicate));
f1e68b31   姜超   feature(*): 报表修改
441
442
443
444
445
446
447
448
449
450
              kpiRatio.setB2(monthRatio(curMonthPools, predicate));
              kpiRatio.setB3(monthRatio(preMonthPools, predicate));
              kpiRatio.setB4(monthRatio(preTwoMonthPools, predicate));
              kpiRatios.add(kpiRatio);
  
              for (KpiGroup kpiGroup : kpiGroups) {
                  List<Long> shopIds = kpiGroup.getShopIds();
                  if (! shopIds.contains(shopId)) {
                      continue;
                  }
60d0b5db   姜超   feature(*): 绩效报表抽取
451
  
91b69450   姜超   feature(mq): 门店名称...
452
                  KpiRatio kpiRatioKpiGroup = new KpiRatio(ReportDimensionEnum.SHOP_KPI_GROUP, calDto.getGroupId());
f1e68b31   姜超   feature(*): 报表修改
453
                  Predicate<KpiPool> predicateKpiGroup = pool -> {
91b69450   姜超   feature(mq): 门店名称...
454
                      return shopId.equals(pool.getShopId()) && kpiGroup.getId().equals(pool.getKpiGroupId()) && Boolean.TRUE.equals(pool.getInclusion());
f1e68b31   姜超   feature(*): 报表修改
455
456
457
458
459
460
461
462
463
464
                  };
                  kpiRatioKpiGroup.setL2(shopId);
                  kpiRatioKpiGroup.setS2(shop.getShopName());
                  kpiRatioKpiGroup.setS4(kpiGroup.getName());
                  kpiRatioKpiGroup.setL4(kpiGroup.getId());
                  kpiRatioKpiGroup.setB1(averageRatio(curMonthPools, predicateKpiGroup));
                  kpiRatioKpiGroup.setB2(monthRatio(curMonthPools, predicateKpiGroup));
                  kpiRatioKpiGroup.setB3(monthRatio(preMonthPools, predicateKpiGroup));
                  kpiRatioKpiGroup.setB4(monthRatio(preTwoMonthPools, predicateKpiGroup));
                  kpiRatios.add(kpiRatioKpiGroup);
60d0b5db   姜超   feature(*): 绩效报表抽取
465
  
60d0b5db   姜超   feature(*): 绩效报表抽取
466
  
f1e68b31   姜超   feature(*): 报表修改
467
468
469
              }
  
          });
60d0b5db   姜超   feature(*): 绩效报表抽取
470
  
60d0b5db   姜超   feature(*): 绩效报表抽取
471
  
39abadd4   姜超   feature(mq): 门店名称...
472
  
39abadd4   姜超   feature(mq): 门店名称...
473
  
60d0b5db   姜超   feature(*): 绩效报表抽取
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
      }
  
      /**
       * 计算员工维度数据
       *
       * @param calDto
       */
      public void calStaffData(GroupCalKpiRatioDTO calDto,
                             List<KpiRatio> kpiRatios
      ) {
          List<KpiPool> curMonthPools = calDto.getCurMonthPools();
          List<KpiPool> preMonthPools = calDto.getPreMonthPools();
          List<KpiPool> preTwoMonthPools = calDto.getPreTwoMonthPools();
          List<KpiGroup> kpiGroups = calDto.getKpiGroups();
          List<KpiGroupRank> kpiGroupRanks = calDto.getKpiGroupRanks();
  
          Map<Long, String> kpiGroupNameMap = kpiGroups.stream().collect(Collectors.toMap(KpiGroup::getId, KpiGroup::getName, (v1, v2) -> v1));
a92022b7   姜超   feature(*): 绩效不再使...
491
          Map<Long, KpiGroupRank> kpiGroupRankMap = new HashMap<>();
60d0b5db   姜超   feature(*): 绩效报表抽取
492
          for (KpiGroupRank rank : kpiGroupRanks) {
a92022b7   姜超   feature(*): 绩效不再使...
493
494
              for (Long kpiGroupId : rank.getKpiGroupIds()) {
                  kpiGroupRankMap.put(kpiGroupId, rank);
60d0b5db   姜超   feature(*): 绩效报表抽取
495
496
497
498
              }
          }
  
          for (KpiPool pool : curMonthPools) {
91b69450   姜超   feature(mq): 门店名称...
499
              KpiRatio kpiRatio = new KpiRatio(ReportDimensionEnum.STAFF, calDto.getGroupId());;
60d0b5db   姜超   feature(*): 绩效报表抽取
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
              Long staffId = pool.getUserId();
  
              kpiRatio.setS1(pool.getUserName());
              kpiRatio.setS2(pool.getShopName());
              kpiRatio.setS3(pool.getPostName());
              kpiRatio.setI2(pool.getRank());
              kpiRatio.setB5(pool.getInclusion());
              kpiRatio.setI1(pool.getActualStar().getValue());
              kpiRatio.setL1(pool.getUserId());
              kpiRatio.setL2(pool.getShopId());
              kpiRatio.setL3(pool.getPostId());
              kpiRatio.setL6(pool.getId());
              kpiRatio.setL4(pool.getKpiGroupId());
              kpiRatio.setS4(kpiGroupNameMap.getOrDefault(pool.getKpiGroupId(), " "));
  
a92022b7   姜超   feature(*): 绩效不再使...
515
516
              if (kpiGroupRankMap.containsKey(pool.getKpiGroupId())) {
                  KpiGroupRank rank = kpiGroupRankMap.get(pool.getKpiGroupId());
60d0b5db   姜超   feature(*): 绩效报表抽取
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
                  kpiRatio.setL5(rank.getId());
                  kpiRatio.setS5(rank.getName());
              }
  
              Predicate<KpiPool> predicate = poolDto -> staffId.equals(poolDto.getUserId()) && Boolean.TRUE.equals(pool.getInclusion());
              kpiRatio.setB1(averageRatio(curMonthPools, predicate));
  
              Optional<BigDecimal> curMonthOp = curMonthPools.stream()
                      .filter(poolDto -> poolDto.getUserId().equals(staffId) && Boolean.TRUE.equals(pool.getInclusion()))
                      .findFirst()
                      .map(KpiPool::getKpiScoreRatio);
  
              Optional<BigDecimal> preMonthOp = preMonthPools.stream()
                      .filter(poolDto -> poolDto.getUserId().equals(staffId) && Boolean.TRUE.equals(pool.getInclusion()))
                      .findFirst()
                      .map(KpiPool::getKpiScoreRatio);
  
              Optional<BigDecimal> preTwoMonthOp = preTwoMonthPools.stream()
                      .filter(poolDto -> poolDto.getUserId().equals(staffId) && Boolean.TRUE.equals(pool.getInclusion()))
                      .findFirst()
                      .map(KpiPool::getKpiScoreRatio);
  
              if (curMonthOp.isPresent()) {
                  kpiRatio.setB2(curMonthOp.get().multiply(new BigDecimal("100")).setScale(2, RoundingMode.DOWN));
              }
              if (preMonthOp.isPresent()) {
                  kpiRatio.setB3(preMonthOp.get().multiply(new BigDecimal("100")).setScale(2, RoundingMode.DOWN));
              }
              if (preTwoMonthOp.isPresent()) {
                  kpiRatio.setB4(preTwoMonthOp.get().multiply(new BigDecimal("100")).setScale(2, RoundingMode.DOWN));
              }
  
              kpiRatios.add(kpiRatio);
          }
      }
  
84f9d303   姜超   feature(*): 定时任务修改
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
      /**
       * 绩效池平均绩效得分率
       *
       * @param pools
       * @return
       */
      public BigDecimal countStaffNum(Collection<KpiPool> pools, Predicate<KpiPool> predicate) {
          if (CollectionUtils.isEmpty(pools)) {
              return BigDecimal.ZERO;
          }
          Long staffNum = pools.stream()
                  .filter(predicate)
                  .count();
          return new BigDecimal(staffNum);
      }
60d0b5db   姜超   feature(*): 绩效报表抽取
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
  
      /**
       * 绩效池平均绩效得分率
       *
       * @param pools
       * @return
       */
      public BigDecimal averageRatio(Collection<KpiPool> pools, Predicate<KpiPool> predicate) {
          if (CollectionUtils.isEmpty(pools)) {
              return BigDecimal.ZERO;
          }
          Double averageRatioDouble = pools.stream()
                  .filter(predicate)
                  .mapToDouble(r -> Optional.ofNullable(r.getAverageKpiScoreRatio()).orElse(BigDecimal.ZERO).doubleValue())
                  .average()
                  .orElse(0);
          BigDecimal averageRatio = new BigDecimal(averageRatioDouble.toString());
          return averageRatio.multiply(new BigDecimal("100")).setScale(2, RoundingMode.DOWN);
      }
  
      /**
       * 当月绩效池平均绩效得分率
       *
       * @param pools
       * @return
       */
      public BigDecimal monthRatio(Collection<KpiPool> pools, Predicate<KpiPool> predicate) {
          if (CollectionUtils.isEmpty(pools)) {
              return BigDecimal.ZERO;
          }
          Double averageRatioDouble = pools.stream()
                  .filter(predicate)
                  .mapToDouble(r -> Optional.ofNullable(r.getKpiScoreRatio()).orElse(BigDecimal.ZERO).doubleValue())
                  .average()
                  .orElse(0);
          BigDecimal averageRatio = new BigDecimal(averageRatioDouble.toString());
          return averageRatio.multiply(new BigDecimal("100")).setScale(2, RoundingMode.DOWN);
      }
  
  }