LogStandardService.java 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. package com.galaxis.manatee.service;
  2. import com.fasterxml.jackson.databind.ObjectMapper;
  3. import com.galaxis.manatee.constant.ChuanYunConstant;
  4. import com.galaxis.manatee.dao.*;
  5. import com.galaxis.manatee.entity.chuanyun.data.object.*;
  6. import com.galaxis.manatee.entity.chuanyun.dto.Filter;
  7. import com.galaxis.manatee.manager.ChuanYunManager;
  8. import com.galaxis.manatee.mapper.WorkHourMapper;
  9. import lombok.extern.slf4j.Slf4j;
  10. import org.springframework.beans.factory.annotation.Autowired;
  11. import org.springframework.scheduling.annotation.Async;
  12. import org.springframework.stereotype.Service;
  13. import org.springframework.util.StringUtils;
  14. import java.math.BigDecimal;
  15. import java.math.RoundingMode;
  16. import java.time.Instant;
  17. import java.time.LocalDate;
  18. import java.time.LocalDateTime;
  19. import java.time.format.DateTimeFormatter;
  20. import java.util.*;
  21. import java.util.stream.Collectors;
  22. /**
  23. * 更新日志中所用到的服务
  24. *
  25. * @author zcj
  26. * @version 0.1
  27. * @date 2021/3/4 1:54 上午
  28. */
  29. @Slf4j
  30. @Service
  31. public class LogStandardService {
  32. @Autowired
  33. private ChuanYunManager chuanYunManager;
  34. @Autowired
  35. private WorkHourMapper workHourMapper;
  36. @Autowired
  37. private WorkGroupService workGroupService;
  38. @Autowired
  39. private ChuanyunProjectDao chuanyunProjectDao;
  40. private final DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  41. private final ChuanyunWorkHourDao chuanyunWorkHourDao;
  42. private final ChuanyunSelfCostDao chuanyunSelfCostDao;
  43. private final ChuanyunSelfWorkHourDao chuanyunSelfWorkHourDao;
  44. private final ChuanyunGroupProjectDao chuanyunGroupProjectDao;
  45. private final ChuanyunWeekMemberHourDao chuanyunWeekMemberHourDao;
  46. private final ChuanyunUserCompanyDao chuanyunUserCompanyDao;
  47. private final DataArcherService dataArcherService;
  48. public LogStandardService(ChuanyunWorkHourDao chuanyunWorkHourDao, ChuanyunSelfCostDao chuanyunSelfCostDao, ChuanyunSelfWorkHourDao chuanyunSelfWorkHourDao, ChuanyunGroupProjectDao chuanyunGroupProjectDao, ChuanyunWeekMemberHourDao chuanyunWeekMemberHourDao, ChuanyunUserCompanyDao chuanyunUserCompanyDao, DataArcherService dataArcherService) {
  49. this.chuanyunWorkHourDao = chuanyunWorkHourDao;
  50. this.chuanyunSelfCostDao = chuanyunSelfCostDao;
  51. this.chuanyunSelfWorkHourDao = chuanyunSelfWorkHourDao;
  52. this.chuanyunGroupProjectDao = chuanyunGroupProjectDao;
  53. this.chuanyunWeekMemberHourDao = chuanyunWeekMemberHourDao;
  54. this.chuanyunUserCompanyDao = chuanyunUserCompanyDao;
  55. this.dataArcherService = dataArcherService;
  56. }
  57. /**
  58. * 员工单日、各个项目工时标准化,并保存
  59. *
  60. * @param isRecent 是否只标准化最近一个月的数据
  61. * @param chuanyunUserCompanyDO 员工信息
  62. */
  63. @Async("threadPoolTaskExecutor")
  64. public void standardHourByUserCompanyAndIsRecent(ChuanyunUserCompanyDO chuanyunUserCompanyDO, boolean isRecent) {
  65. if (!StringUtils.isEmpty(chuanyunUserCompanyDO.getUserId())) {
  66. long start = Instant.now().getEpochSecond();
  67. //从日志原始数据中获取每人每个项目每天工时。
  68. //由isRecent判断是否只获取最近30天的数据
  69. List<ChuanyunWorkHourDO> selfList = isRecent ? chuanyunWorkHourDao.getSelfWorkHourRecently(chuanyunUserCompanyDO.getUserId()) : chuanyunWorkHourDao.getSelfWorkHour(chuanyunUserCompanyDO.getUserId());
  70. this.generateSelfWorkHourByWorkHourList(selfList);
  71. log.info("每日工时标准化" + chuanyunUserCompanyDO.getUserName() + (Instant.now().getEpochSecond() - start) + "秒");
  72. } else {
  73. log.warn("用户信息中userId缺失");
  74. }
  75. }
  76. /**
  77. * 标准化最近一个月每周工时
  78. */
  79. @Async("threadPoolTaskExecutor")
  80. public void standardWeekMemberHourRecent() {
  81. List<ChuanyunWeekMemberHourDO> list = chuanyunWeekMemberHourDao.getWeekMemberHourRecently();
  82. this.generateWeekMemberHourByWeekMemberHourList(list);
  83. }
  84. /**
  85. * 根据用户Id标准化某个人的日工时
  86. *
  87. * @param userId 用户Id
  88. */
  89. @Async("threadPoolTaskExecutor")
  90. public void standardSelfWorkHourByUserId(String userId) {
  91. if (!Objects.isNull(userId) && !userId.isBlank()) {
  92. log.info("标准化用户日工时 userId: {}", userId);
  93. //从日志原始数据中获取每人每个项目每天工时。
  94. List<ChuanyunWorkHourDO> selfList = chuanyunWorkHourDao.getSelfWorkHour(userId);
  95. this.generateSelfWorkHourByWorkHourList(selfList);
  96. } else {
  97. log.warn("用户信息中userId缺失");
  98. }
  99. }
  100. /**
  101. * 根据用户Id标准化某个人所有的周工时
  102. *
  103. * @param userId 用户Id
  104. */
  105. public void standardAllWeekMemberHourByUserId(String userId) {
  106. if (!StringUtils.hasLength(userId)) {
  107. long start = Instant.now().getEpochSecond();
  108. //更新数据库
  109. List<ChuanyunWeekMemberHourDO> list = chuanyunWeekMemberHourDao.getWeekMemberHourByUserId(userId);
  110. this.generateWeekMemberHourByWeekMemberHourList(list);
  111. log.info(userId + "统一周工时标准化" + (Instant.now().getEpochSecond() - start) + "秒");
  112. } else {
  113. log.warn("用户信息中userId缺失");
  114. }
  115. }
  116. /**
  117. * 根据用户Id标准化某个人一年内的周工时
  118. *
  119. * @param userId 用户Id
  120. */
  121. public void standardWeekMemberHourByUserId(String userId) {
  122. if (!StringUtils.isEmpty(userId)) {
  123. long start = Instant.now().getEpochSecond();
  124. //更新数据库
  125. List<ChuanyunWeekMemberHourDO> list = chuanyunWeekMemberHourDao.getOneYearAgoWeekMemberHourByUserId(userId);
  126. this.generateWeekMemberHourByWeekMemberHourList(list);
  127. log.info(userId + "统一周工时标准化" + (Instant.now().getEpochSecond() - start) + "秒");
  128. } else {
  129. log.warn("用户信息中userId缺失");
  130. }
  131. }
  132. /**
  133. * 根据用户Id标准化某个人的月工时
  134. * 1.删除审核中的月工时
  135. * 2.将新工时数据保存在manatee中
  136. *
  137. * @param userId 用户Id
  138. */
  139. public void standardSelfCostByUserId(String userId) {
  140. long start = Instant.now().getEpochSecond();
  141. //删除上一次状态为审核中,但本次已经审核通过的数据
  142. chuanyunSelfCostDao.findAllByStatusAndUserId(ChuanYunConstant.IN_PROCESS, userId).forEach(chuanyunSelfCostDO -> {
  143. List<ChuanyunSelfWorkHourDO> chuanyunSelfWorkHourList = chuanyunSelfWorkHourDao.findAllByUserIdAndProjectIdAndProjectTypeAndStatusAndDayLogDateBetween(
  144. chuanyunSelfCostDO.getUserId(),
  145. chuanyunSelfCostDO.getProjectId(),
  146. chuanyunSelfCostDO.getProjectType(),
  147. ChuanYunConstant.IN_PROCESS,
  148. chuanyunSelfCostDO.getDayLogDate(),
  149. chuanyunSelfCostDO.getDayLogDate().plusMonths(1L));
  150. //如果没有仍在审批中的每日工时,则将该月、该项目的审核中的月工时统计删除,manatee数据库与氚云
  151. if (chuanyunSelfWorkHourList.size() == 0) {
  152. //删除manatee中的在审核工时
  153. chuanyunSelfCostDao.delete(chuanyunSelfCostDO);
  154. dataArcherService.deleteSelfCostInProcess(chuanyunSelfCostDO);
  155. }
  156. });
  157. // 获取单人月度各项目总工时
  158. // List<ChuanyunSelfWorkHourDO> userAllSelfWorkHours = chuanyunSelfWorkHourDao.findByUserId(userId);
  159. // 修改为获取一年内的记录
  160. // 获取一年前的时间节点
  161. // LocalDateTime aYearAgo = LocalDateTime.now().minusYears(1);
  162. // List<ChuanyunSelfWorkHourDO> userAllSelfWorkHours = chuanyunSelfWorkHourDao.findByUserIdAndDayLogDateAfter(userId, aYearAgo);
  163. List<ChuanyunSelfWorkHourDO> userAllSelfWorkHours = chuanyunSelfWorkHourDao.findByUserId(userId);
  164. Map<LocalDate, Map<String, Map<String, Map<String, BigDecimal>>>> map = userAllSelfWorkHours.stream().filter(selfWorkHourDO ->
  165. StringUtils.hasLength(selfWorkHourDO.getProjectId()) &&
  166. StringUtils.hasLength(selfWorkHourDO.getProjectType()) &&
  167. StringUtils.hasLength(selfWorkHourDO.getStatus()) &&
  168. selfWorkHourDO.getStandardWorkHour() != null &&
  169. selfWorkHourDO.getDayLogDate() != null).collect(
  170. Collectors.groupingBy(chuanyunSelfWorkHourDO -> LocalDate.of(chuanyunSelfWorkHourDO.getDayLogDate().getYear(), chuanyunSelfWorkHourDO.getDayLogDate().getMonth(), 1),
  171. Collectors.groupingBy(ChuanyunSelfWorkHourDO::getProjectId,
  172. Collectors.groupingBy(ChuanyunSelfWorkHourDO::getProjectType,
  173. Collectors.groupingBy(ChuanyunSelfWorkHourDO::getStatus, Collectors.reducing(BigDecimal.ZERO, ChuanyunSelfWorkHourDO::getStandardWorkHour, BigDecimal::add)
  174. )))));
  175. // 每月每项目工时,按月-项目-用户分组统计标准工时
  176. // List<ChuanyunSelfWorkHourDO> list = chuanyunSelfWorkHourDao.getMonthProjectHour(userId);
  177. ArrayList<ChuanyunSelfWorkHourDO> list1 = new ArrayList<>();
  178. map.forEach((localDate, projectIdMapMap) ->
  179. projectIdMapMap.forEach((projectId, projectTypeMapMap) ->
  180. projectTypeMapMap.forEach((projectType, statusBigDecimalMap) ->
  181. statusBigDecimalMap.forEach((status, standardWorkHour) -> {
  182. ChuanyunSelfWorkHourDO chuanyunSelfWorkHourDO = new ChuanyunSelfWorkHourDO();
  183. chuanyunSelfWorkHourDO.setStandardWorkHour(standardWorkHour);
  184. chuanyunSelfWorkHourDO.setStatus(status);
  185. chuanyunSelfWorkHourDO.setProjectId(projectId);
  186. // 设置项目类型
  187. chuanyunSelfWorkHourDO.setProjectType(projectType);
  188. chuanyunSelfWorkHourDO.setDayLogDate(localDate.atStartOfDay());
  189. chuanyunSelfWorkHourDO.setUserId(userId);
  190. list1.add(chuanyunSelfWorkHourDO);
  191. }))));
  192. list1.forEach(projectMonth -> {
  193. ChuanyunSelfCostDO chuanyunSelfCostDO = this.fromChuanyunSelfWorkHourDO(projectMonth);
  194. //获取人员-月度-相同工时状态标准工时汇总
  195. ChuanyunSelfCostDO oldSelfDO = chuanyunSelfCostDao.getOldSelfDO(userId,
  196. projectMonth.getProjectId(),
  197. projectMonth.getProjectType(),
  198. df.format(projectMonth.getDayLogDate()),
  199. projectMonth.getStatus());
  200. if (oldSelfDO != null) {
  201. chuanyunSelfCostDao.delete(oldSelfDO);
  202. }
  203. chuanyunSelfCostDao.saveAndFlush(chuanyunSelfCostDO);
  204. });
  205. log.info(userId + "统一月工时标准化" + (Instant.now().getEpochSecond() - start) + "秒");
  206. }
  207. /**
  208. * 根据日工时列表生成
  209. *
  210. * @param updateList 待更新列表
  211. */
  212. private void generateSelfWorkHourByWorkHourList(List<ChuanyunWorkHourDO> updateList) {
  213. //逐一将原始工时数据标准化后,更新到标准化工时表和氚云中
  214. updateList.parallelStream().forEach(self -> {
  215. try {
  216. //新建标准化工时对象,并将原始数据更新到此对象中,并计算标准化之后的工时
  217. ChuanyunSelfWorkHourDO chuanyunSelfWorkHourDO = this.fromChuanyunWorkHourDO(self);
  218. // 设置工作组和子工作组
  219. String workGroupId = self.getWorkGroupId();
  220. if (!Objects.isNull(workGroupId) && !workGroupId.isBlank()) {
  221. ChuanyunWorkGroupDO workGroupDO = workGroupService.findByObjectId(workGroupId);
  222. if (!Objects.isNull(workGroupDO)) {
  223. chuanyunSelfWorkHourDO.setWorkGroupName(workGroupDO.getWorkGroupName());
  224. chuanyunSelfWorkHourDO.setSubWorkGroupName(workGroupDO.getSubWorkGroup());
  225. } else {
  226. // 从历史数据中查找
  227. ChuanyunHistoryWorkGroupDO historyWorkGroup = workGroupService.findInHistoryByObjectId(workGroupId);
  228. if (!Objects.isNull(historyWorkGroup)) {
  229. chuanyunSelfWorkHourDO.setWorkGroupName(historyWorkGroup.getWorkGroupName());
  230. chuanyunSelfWorkHourDO.setSubWorkGroupName(historyWorkGroup.getSubWorkGroup());
  231. }
  232. }
  233. }
  234. //查询系统中是否有重复的标准化工时数据,如果有重复的人、天、项目数据,将原数据删除后更新为最新的数据
  235. try {
  236. List<ChuanyunSelfWorkHourDO> list;
  237. if (self.getStatus().equals("3")) {
  238. list = chuanyunSelfWorkHourDao.findByUserIdAndProjectIdAndDayLogDateAndProjectTypeAndStatus(chuanyunSelfWorkHourDO.getUserId(), ChuanYunConstant.PRODUCTION_PROJECT.equals(self.getProjectType()) ? ChuanYunConstant.PRODUCTION_PROJECT_ID : self.getProjectId(), self.getDayLogDate(), self.getProjectType(), self.getStatus());
  239. } else {
  240. list = chuanyunSelfWorkHourDao.findByUserIdAndProjectIdAndDayLogDateAndProjectType(chuanyunSelfWorkHourDO.getUserId(), ChuanYunConstant.PRODUCTION_PROJECT.equals(self.getProjectType()) ? ChuanYunConstant.PRODUCTION_PROJECT_ID : self.getProjectId(), self.getDayLogDate(), self.getProjectType());
  241. }
  242. if (list != null && list.size() > 0) {
  243. chuanyunSelfWorkHourDao.deleteAll(list);
  244. }
  245. chuanyunSelfWorkHourDao.saveAndFlush(chuanyunSelfWorkHourDO);
  246. } catch (Exception e) {
  247. log.error(e.getMessage());
  248. }
  249. } catch (Exception e) {
  250. log.error(e.getMessage());
  251. log.error("" + self);
  252. }
  253. });
  254. }
  255. /**
  256. * 根据周工时列表
  257. *
  258. * @param updateList 待更新的周工时列表
  259. */
  260. private void generateWeekMemberHourByWeekMemberHourList(List<ChuanyunWeekMemberHourDO> updateList) {
  261. updateList.forEach(chuanyunWeekMemberHourDO -> {
  262. try {
  263. if (chuanyunWeekMemberHourDO != null) {
  264. ChuanyunWeekMemberHourDO weekMemberHourDO = ChuanyunWeekMemberHourDO.fromChuanyunWeekMemberHourDO(chuanyunWeekMemberHourDO);
  265. ChuanyunWeekMemberHourDO oldWeekHour = chuanyunWeekMemberHourDao.findByProjectIdAndUserIdAndWeekAndStatusAndProjectTypeAndYear(chuanyunWeekMemberHourDO.getProjectId(), chuanyunWeekMemberHourDO.getUserId(), chuanyunWeekMemberHourDO.getWeek(), chuanyunWeekMemberHourDO.getStatus(), chuanyunWeekMemberHourDO.getProjectType(), chuanyunWeekMemberHourDO.getYear());
  266. if (oldWeekHour != null) {
  267. chuanyunWeekMemberHourDao.delete(oldWeekHour);
  268. }
  269. chuanyunWeekMemberHourDao.saveAndFlush(weekMemberHourDO);
  270. //搜索是否还有处于审批中的数据
  271. ChuanyunWeekMemberHourDO processWeekHour = chuanyunWeekMemberHourDao.getProcessWeekHour(chuanyunWeekMemberHourDO.getProjectId(), chuanyunWeekMemberHourDO.getUserId(), chuanyunWeekMemberHourDO.getYear(), chuanyunWeekMemberHourDO.getWeek(), chuanyunWeekMemberHourDO.getProjectType());
  272. if (processWeekHour == null) {
  273. chuanyunWeekMemberHourDao.deleteByProjectIdAndUserIdAndYearAndWeekAndStatusAndProjectType(chuanyunWeekMemberHourDO.getProjectId(), chuanyunWeekMemberHourDO.getUserId(), chuanyunWeekMemberHourDO.getYear(), chuanyunWeekMemberHourDO.getWeek(), "2", chuanyunWeekMemberHourDO.getProjectType());
  274. //同时删除氚云钟数据
  275. dataArcherService.deleteExamineStatus(ChuanyunProjectMemberWeekHourDO.SCHEMA_CODE, "F0000007", "F0000001", chuanyunWeekMemberHourDO.getProjectId(), "F0000002", chuanyunWeekMemberHourDO.getUserId(), "F0000008", chuanyunWeekMemberHourDO.getYear(), "", "", "F0000006", chuanyunWeekMemberHourDO.getWeek(), "F0000003", chuanyunWeekMemberHourDO.getProjectType());
  276. }
  277. }
  278. } catch (Exception e) {
  279. log.error("chuanyunWeekMemberHourDO: {}", chuanyunWeekMemberHourDO);
  280. log.error(e.getMessage() + "周工时标准化异常");
  281. }
  282. });
  283. }
  284. /**
  285. * 根据日志原始数据统计的每日每人工时获取工时标准化后的标准化对象
  286. *
  287. * @param chuanyunWorkHourDO 日志原始统计数据
  288. * @return 工时标准化对象
  289. */
  290. private ChuanyunSelfWorkHourDO fromChuanyunWorkHourDO(ChuanyunWorkHourDO chuanyunWorkHourDO) throws Exception {
  291. //由于日志原始工时可能存在项目类型不准确的情况,需要根据项目ID获取真实的项目类型
  292. String projectType;
  293. String projectCode = null;
  294. try {
  295. var chuanyunGroupProject = chuanyunGroupProjectDao.findByObjectId(chuanyunWorkHourDO.getProjectId());
  296. if (chuanyunGroupProject == null) {
  297. log.info("没有找到该项目");
  298. // 查询总况表中的数据
  299. Optional<ChuanyunProjectDO> projectDO = chuanyunProjectDao.findById(chuanyunWorkHourDO.getProjectId());
  300. if (projectDO.isPresent()){
  301. projectCode = projectDO.get().getProjectCode();
  302. ChuanyunGroupProjectDO projectByCode = chuanyunGroupProjectDao.findByProjectCode(projectCode);
  303. projectType = projectByCode.getProjectType();
  304. }else {
  305. throw new Exception("没有找到对应的项目");
  306. }
  307. }else {
  308. //如果找到相应的项目,则使用项目实际的项目类型
  309. projectType = chuanyunGroupProject.getProjectType();
  310. projectCode = chuanyunGroupProject.getProjectCode();
  311. }
  312. } catch (Exception e) {
  313. //没有找到对应项目,使用原项目类型
  314. projectType = chuanyunWorkHourDO.getProjectType();
  315. }
  316. ChuanyunSelfWorkHourDO chuanyunSelfWorkHourDO = ChuanyunSelfWorkHourDO.fromChuanyunWorkHourDO(chuanyunWorkHourDO, projectType);
  317. if (projectCode != null) {
  318. chuanyunSelfWorkHourDO.setProjectCode(projectCode);
  319. }
  320. //获取每人每天总工时
  321. // ChuanyunWorkHourDO oneDayTotalHour = chuanyunWorkHourDao.getDayWorkHour(chuanyunWorkHourDO.getUserId(), chuanyunWorkHourDO.getDayLogDate());
  322. // 获取每天总工时
  323. // ChuanyunWorkHourDO oneDayTotalHour = chuanyunWorkHourDao.getOneDayTotalHour(chuanyunWorkHourDO.getUserId(), chuanyunWorkHourDO.getDayLogDate());
  324. ChuanyunWorkHourDO oneDayTotalHour = workHourMapper.selectByUserIdAndDayLogDate(chuanyunWorkHourDO.getUserId(), chuanyunWorkHourDO.getDayLogDate());
  325. //工时标准化
  326. if (oneDayTotalHour != null) {
  327. BigDecimal hoursWorked = oneDayTotalHour.getHoursWorked();
  328. if (hoursWorked.compareTo(BigDecimal.ZERO) == 0) {
  329. throw new Exception("每日工时为0");
  330. }
  331. BigDecimal standard = new BigDecimal("8.00");
  332. if (hoursWorked.compareTo(standard) <= 0) {
  333. chuanyunSelfWorkHourDO.setStandardWorkHour(chuanyunWorkHourDO.getHoursWorked());
  334. } else {
  335. BigDecimal worked = chuanyunWorkHourDO.getHoursWorked();
  336. BigDecimal divide = worked.divide(hoursWorked, 2, RoundingMode.HALF_UP);
  337. BigDecimal personDays = divide.multiply(standard);
  338. chuanyunSelfWorkHourDO.setStandardWorkHour(personDays);
  339. }
  340. } else {
  341. throw new Exception("获取每日总工时失败");
  342. }
  343. //获取人员所属BG
  344. if (StringUtils.isEmpty(chuanyunWorkHourDO.getBgName())) {
  345. List<ChuanyunSelfWorkHourDO> list = chuanyunSelfWorkHourDao.findByUserIdAndProjectIdAndDayLogDateAndProjectType(chuanyunWorkHourDO.getUserId(), chuanyunWorkHourDO.getProjectId(), chuanyunWorkHourDO.getDayLogDate(), chuanyunWorkHourDO.getProjectType());
  346. if (!Objects.isNull(list) && !list.isEmpty()) {
  347. chuanyunSelfWorkHourDO.setBg(list.get(0).getBg());
  348. }
  349. } else {
  350. chuanyunSelfWorkHourDO.setBg(chuanyunWorkHourDO.getBgName());
  351. }
  352. return chuanyunSelfWorkHourDO;
  353. }
  354. /**
  355. * 根据ChuanyunSelfWorkHourDO获取ChuanyunSelfCostDO对象
  356. *
  357. * @param chuanyunSelfWorkHourDO 统计月工时对象
  358. * @return 待保存的月工时对象
  359. */
  360. private ChuanyunSelfCostDO fromChuanyunSelfWorkHourDO(ChuanyunSelfWorkHourDO chuanyunSelfWorkHourDO) {
  361. ChuanyunSelfCostDO chuanyunSelfCostDO = new ChuanyunSelfCostDO();
  362. chuanyunSelfCostDO.setStatus(chuanyunSelfWorkHourDO.getStatus());
  363. if (chuanyunSelfWorkHourDO.getStandardWorkHour() != null) {
  364. chuanyunSelfCostDO.setMonthlyTotalHour(chuanyunSelfWorkHourDO.getStandardWorkHour());
  365. }
  366. chuanyunSelfCostDO.setProjectId(chuanyunSelfWorkHourDO.getProjectId());
  367. chuanyunSelfCostDO.setProjectType(chuanyunSelfWorkHourDO.getProjectType());
  368. chuanyunSelfCostDO.setUserId(chuanyunSelfWorkHourDO.getUserId());
  369. chuanyunSelfCostDO.setDayLogDate(chuanyunSelfWorkHourDO.getDayLogDate().withDayOfMonth(1));
  370. chuanyunSelfCostDO.setTotalHour(chuanyunSelfWorkHourDO.getStandardWorkHour());
  371. Optional<ChuanyunUserCompanyDO> chuanyunUserCompanyDO = chuanyunUserCompanyDao.findAllByUserIdOrderByModifiedTimeDesc(chuanyunSelfWorkHourDO.getUserId()).stream().findFirst();
  372. chuanyunUserCompanyDO.ifPresent(userCompanyDO -> chuanyunSelfCostDO.setDepartmentId(userCompanyDO.getDepartmentId()));
  373. return chuanyunSelfCostDO;
  374. }
  375. /**
  376. * 标准化半年内每日工时
  377. */
  378. public void standardHalfYearWorkHour() {
  379. // chuanyunUserCompanyDao.findAll().parallelStream().forEach(chuanyunUserCompanyDO -> this.standardHalfYearDayWorkHour(chuanyunUserCompanyDO.getUserId()));
  380. List<String> userIdList = chuanyunUserCompanyDao.findAll().stream().map(ChuanyunUserCompanyDO::getUserId).collect(Collectors.toList());
  381. List<String> distinctUserIdList = userIdList.stream().distinct().collect(Collectors.toList());
  382. distinctUserIdList.parallelStream().forEach(this::standardHalfYearDayWorkHour);
  383. }
  384. public void standardHalfYearWorkHourByUserId(String userId) {
  385. this.standardHalfYearDayWorkHour(userId);
  386. }
  387. /**
  388. * 标准化半年内日志
  389. *
  390. * @param userId 用户id
  391. */
  392. private void standardHalfYearDayWorkHour(String userId) {
  393. //逐一将原始工时数据标准化后,更新到标准化工时表和氚云中
  394. log.info("标准化用户日工时 userId: {}", userId);
  395. List<ChuanyunWorkHourDO> halfYearSelfWorkHour = chuanyunWorkHourDao.getHalfYearSelfWorkHour(userId);
  396. halfYearSelfWorkHour.forEach(self -> {
  397. try {
  398. //新建标准化工时对象,并将原始数据更新到此对象中,并计算标准化之后的工时
  399. ChuanyunSelfWorkHourDO chuanyunSelfWorkHourDO = this.fromChuanyunWorkHourDO(self);
  400. // 设置工作组和子工作组
  401. String workGroupId = self.getWorkGroupId();
  402. if (!Objects.isNull(workGroupId) && !workGroupId.isBlank()) {
  403. ChuanyunWorkGroupDO workGroupDO = workGroupService.findByObjectId(workGroupId);
  404. if (!Objects.isNull(workGroupDO)) {
  405. chuanyunSelfWorkHourDO.setWorkGroupName(workGroupDO.getWorkGroupName());
  406. chuanyunSelfWorkHourDO.setSubWorkGroupName(workGroupDO.getSubWorkGroup());
  407. } else {
  408. // 从历史数据中查找
  409. ChuanyunHistoryWorkGroupDO historyWorkGroup = workGroupService.findInHistoryByObjectId(workGroupId);
  410. if (!Objects.isNull(historyWorkGroup)) {
  411. chuanyunSelfWorkHourDO.setWorkGroupName(historyWorkGroup.getWorkGroupName());
  412. chuanyunSelfWorkHourDO.setSubWorkGroupName(historyWorkGroup.getSubWorkGroup());
  413. }
  414. }
  415. }
  416. //查询系统中是否有重复的标准化工时数据,如果有重复的人、天、项目数据,将原数据删除后更新为最新的数据
  417. try {
  418. List<ChuanyunSelfWorkHourDO> list;
  419. if (self.getStatus().equals("3")) {
  420. list = chuanyunSelfWorkHourDao.findByUserIdAndProjectIdAndDayLogDateAndProjectTypeAndStatus(chuanyunSelfWorkHourDO.getUserId(), ChuanYunConstant.PRODUCTION_PROJECT.equals(self.getProjectType()) ? ChuanYunConstant.PRODUCTION_PROJECT_ID : self.getProjectId(), self.getDayLogDate(), self.getProjectType(), self.getStatus());
  421. } else {
  422. list = chuanyunSelfWorkHourDao.findByUserIdAndProjectIdAndDayLogDateAndProjectType(chuanyunSelfWorkHourDO.getUserId(), ChuanYunConstant.PRODUCTION_PROJECT.equals(self.getProjectType()) ? ChuanYunConstant.PRODUCTION_PROJECT_ID : self.getProjectId(), self.getDayLogDate(), self.getProjectType());
  423. }
  424. if (list != null && list.size() > 0) {
  425. chuanyunSelfWorkHourDao.deleteAll(list);
  426. }
  427. chuanyunSelfWorkHourDao.saveAndFlush(chuanyunSelfWorkHourDO);
  428. } catch (Exception e) {
  429. log.error(e.getMessage());
  430. }
  431. } catch (Exception e) {
  432. log.error(e.getMessage());
  433. log.error("" + self);
  434. e.printStackTrace();
  435. }
  436. });
  437. log.info("标准化用户日工时完成 userId: {}", userId);
  438. }
  439. }