|
@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
|
|
|
import com.alibaba.fastjson.JSONArray;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import com.qmth.sop.business.bean.dto.RegionCoordinatorDingTimeDto;
|
|
|
import com.qmth.sop.business.bean.result.CrmProjectResult;
|
|
|
import com.qmth.sop.business.bean.result.UserArchivesResult;
|
|
|
import com.qmth.sop.business.entity.*;
|
|
@@ -59,8 +60,15 @@ public class TBDingStatisticServiceImpl extends ServiceImpl<TBDingStatisticMappe
|
|
|
private TBDingSubmitService tbDingSubmitService;
|
|
|
|
|
|
@Override
|
|
|
- public TBDingStatistic findBySopNoAndUserArchivesId(String sopNo, Long userArchivesId) {
|
|
|
- return this.getOne(new QueryWrapper<TBDingStatistic>().lambda().eq(TBDingStatistic::getSopNo, sopNo).eq(TBDingStatistic::getUserArchivesId, userArchivesId).last(SystemConstant.LIMIT1));
|
|
|
+ public TBDingStatistic findBySopNoAndUserArchivesId(Long serviceId, String sopNo, Long userArchivesId) {
|
|
|
+ QueryWrapper<TBDingStatistic> queryWrapper = new QueryWrapper<>();
|
|
|
+ queryWrapper.lambda().eq(TBDingStatistic::getServiceId, serviceId).eq(TBDingStatistic::getUserArchivesId, userArchivesId).last(SystemConstant.LIMIT1);
|
|
|
+ if (SystemConstant.strNotNull(sopNo)) {
|
|
|
+ queryWrapper.lambda().eq(TBDingStatistic::getSopNo, sopNo);
|
|
|
+ } else {
|
|
|
+ queryWrapper.lambda().isNull(TBDingStatistic::getSopNo);
|
|
|
+ }
|
|
|
+ return this.getOne(queryWrapper);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -132,6 +140,22 @@ public class TBDingStatisticServiceImpl extends ServiceImpl<TBDingStatisticMappe
|
|
|
log.error(String.format("sopNo[%s]未找到派单详情信息", sopNo));
|
|
|
throw ExceptionResultEnum.ERROR.exception("未找到派单详情信息");
|
|
|
}
|
|
|
+ Long scanActualStartTime = tbCrmDetail.getScanActualStartTime();
|
|
|
+ Long scanActualEndTime = tbCrmDetail.getScanActualEndTime();
|
|
|
+ Long markPaperActualStartTime = tbCrmDetail.getMarkPaperActualStartTime();
|
|
|
+ Long markPaperActualEndTime = tbCrmDetail.getMarkPaperActualEndTime();
|
|
|
+ if (Objects.nonNull(scanActualStartTime)) {
|
|
|
+ scanActualStartTime = DateDisposeUtils.getEarliestTime(scanActualStartTime);
|
|
|
+ }
|
|
|
+ if (Objects.nonNull(scanActualEndTime)) {
|
|
|
+ scanActualEndTime = DateDisposeUtils.getLatestTime(scanActualEndTime);
|
|
|
+ }
|
|
|
+ if (Objects.nonNull(markPaperActualStartTime)) {
|
|
|
+ markPaperActualStartTime = DateDisposeUtils.getEarliestTime(markPaperActualStartTime);
|
|
|
+ }
|
|
|
+ if (Objects.nonNull(markPaperActualEndTime)) {
|
|
|
+ markPaperActualEndTime = DateDisposeUtils.getLatestTime(markPaperActualEndTime);
|
|
|
+ }
|
|
|
|
|
|
String crmNo = tbCrmDetail.getCrmNo();
|
|
|
TBCrm tbCrm = tbCrmService.findByCrmNo(crmNo);
|
|
@@ -147,8 +171,7 @@ public class TBDingStatisticServiceImpl extends ServiceImpl<TBDingStatisticMappe
|
|
|
Long markPaperStartTime = tbCrmDetail.getMarkPaperStartTime();
|
|
|
Long markPaperEndTime = tbCrmDetail.getMarkPaperEndTime();
|
|
|
// 该sop计划有效的日期
|
|
|
-
|
|
|
- List<Long> userArchivesIdList = datasource.stream().filter(e -> Objects.equals(sopNo, e.getSopNo())).map(TBDing::getUserArchivesId).distinct().collect(Collectors.toList());
|
|
|
+ List<Long> userArchivesIdList = datasource.stream().map(TBDing::getUserArchivesId).distinct().collect(Collectors.toList());
|
|
|
|
|
|
for (Long userArchivesId : userArchivesIdList) {
|
|
|
UserArchivesResult tbUserArchives = tbUserArchivesService.findUserArchivesByArchivesIdORUserId(
|
|
@@ -159,10 +182,31 @@ public class TBDingStatisticServiceImpl extends ServiceImpl<TBDingStatisticMappe
|
|
|
Long userId = tbUserArchives.getUserId();
|
|
|
// 打卡数据集合
|
|
|
List<TBDing> dingList = datasource.stream()
|
|
|
- .filter(e -> Objects.equals(sopNo, e.getSopNo()) && Objects.equals(userArchivesId, e.getUserArchivesId())).collect(Collectors.toList());
|
|
|
+ .filter(e -> Objects.equals(userArchivesId, e.getUserArchivesId())).collect(Collectors.toList());
|
|
|
|
|
|
- // 非异常打卡(打卡时间在计划时间范围内 以及 缺少签到或签退的)
|
|
|
- List<TBDing> effectDingList = dingList.stream().filter(e -> !e.getDingException()).collect(Collectors.toList());
|
|
|
+ // 非异常打卡(打卡时间在计划时间范围内 以及签到签退完整的)
|
|
|
+ Long finalScanActualStartTime = scanActualStartTime;
|
|
|
+ Long finalScanActualEndTime = scanActualEndTime;
|
|
|
+ Long finalMarkPaperActualStartTime = markPaperActualStartTime;
|
|
|
+ Long finalMarkPaperActualEndTime = markPaperActualEndTime;
|
|
|
+ List<TBDing> effectDingList = dingList.stream()
|
|
|
+ .filter(e -> !SystemConstant.isOneNull(e.getSignInTime(), e.getSignOutTime())).filter(e -> {
|
|
|
+ // 在区协打卡时间范围内
|
|
|
+ Long signInTime = e.getSignInTime();
|
|
|
+ Long signOutTime = e.getSignOutTime();
|
|
|
+ boolean inScan = false;
|
|
|
+ boolean inMarkPaper = false;
|
|
|
+ if (!SystemConstant.isOneNull(finalScanActualStartTime, finalScanActualEndTime)) {
|
|
|
+ inScan = signInTime >= finalScanActualStartTime && signInTime <= finalScanActualEndTime
|
|
|
+ && signOutTime >= finalScanActualStartTime && signOutTime <= finalScanActualEndTime;
|
|
|
+ }
|
|
|
+ if (!SystemConstant.isOneNull(finalMarkPaperActualStartTime, finalMarkPaperActualEndTime)) {
|
|
|
+ inMarkPaper = signInTime >= finalMarkPaperActualStartTime && signInTime <= finalMarkPaperActualEndTime
|
|
|
+ && signOutTime >= finalMarkPaperActualStartTime && signOutTime <= finalMarkPaperActualEndTime;
|
|
|
+ }
|
|
|
+
|
|
|
+ return inScan || inMarkPaper;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
|
|
|
List<SopRoleTypeEnum> sopRoleTypeList = dingList.stream().flatMap(e -> {
|
|
|
String sopRoleTypeStr = e.getSopRoleType();
|
|
@@ -225,14 +269,14 @@ public class TBDingStatisticServiceImpl extends ServiceImpl<TBDingStatisticMappe
|
|
|
new QueryWrapper<TBDingApply>().lambda().eq(TBDingApply::getSopNo, sopNo).isNull(TBDingApply::getApprove));
|
|
|
|
|
|
TBDingStatistic tbDingStatistic;
|
|
|
- tbDingStatistic = this.findBySopNoAndUserArchivesId(sopNo, userArchivesId);
|
|
|
+ tbDingStatistic = this.findBySopNoAndUserArchivesId(serviceUnitId, sopNo, userArchivesId);
|
|
|
if (Objects.isNull(tbDingStatistic)) {
|
|
|
// 新增考勤统计
|
|
|
tbDingStatistic = new TBDingStatistic();
|
|
|
tbDingStatistic.insertInfo(requestUserId);
|
|
|
} else {
|
|
|
// 更新考勤统计
|
|
|
- if (!tbDingSubmitService.canUpdateDingSetting(sopNo, userId)) {
|
|
|
+ if (!tbDingSubmitService.canUpdateDingSetting(serviceUnitId, sopNo, userId)) {
|
|
|
// 已提交的考勤不再计算了
|
|
|
continue;
|
|
|
}
|
|
@@ -248,10 +292,134 @@ public class TBDingStatisticServiceImpl extends ServiceImpl<TBDingStatisticMappe
|
|
|
tbDingStatistic.setUserArchivesId(userArchivesId);
|
|
|
tbDingStatistic.setUserArchivesName(tbUserArchives.getName());
|
|
|
tbDingStatistic.setUserArchivesCode(tbUserArchives.getCode());
|
|
|
- tbDingStatistic.setScanStartTime(scanStartTime);
|
|
|
- tbDingStatistic.setScanEndTime(scanEndTime);
|
|
|
- tbDingStatistic.setMarkPaperStartTime(markPaperStartTime);
|
|
|
- tbDingStatistic.setMarkPaperEndTime(markPaperEndTime);
|
|
|
+ tbDingStatistic.setScanStartTime(tbCrmDetail.getScanActualStartTime());
|
|
|
+ tbDingStatistic.setScanEndTime(tbCrmDetail.getScanActualEndTime());
|
|
|
+ tbDingStatistic.setMarkPaperStartTime(tbCrmDetail.getMarkPaperActualStartTime());
|
|
|
+ tbDingStatistic.setMarkPaperEndTime(tbCrmDetail.getMarkPaperActualEndTime());
|
|
|
+ tbDingStatistic.setRoleName(sopRoleType);
|
|
|
+ tbDingStatistic.setSupplierId(tbUserArchives.getSupplierId());
|
|
|
+ tbDingStatistic.setSupplierName(tbUserArchives.getSupplierName());
|
|
|
+ tbDingStatistic.setActualDays(actualDays);
|
|
|
+ tbDingStatistic.setWeekdays(weekDays);
|
|
|
+ tbDingStatistic.setWeekends(weekends);
|
|
|
+ tbDingStatistic.setLegalHolidays(legalHolidays);
|
|
|
+ tbDingStatistic.setWorkHours(workHours);
|
|
|
+ tbDingStatistic.setViolationDays(violationDays);
|
|
|
+ tbDingStatistic.setDingExceptionCount(dingExceptionCount);
|
|
|
+ tbDingStatistic.setRemainCount(remainCount);
|
|
|
+ tbDingStatistic.setExceptionCount(exceptionCount);
|
|
|
+ tbDingStatisticList.add(tbDingStatistic);
|
|
|
+ }
|
|
|
+ this.saveOrUpdateBatch(tbDingStatisticList);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void buildDingStatisticByService(Long serviceId, List<TBDing> datasource, Long requestUserId) {
|
|
|
+ RegionCoordinatorDingTimeDto dingTimeDto = tbDingService.findRegionCoordinatorDingTime();
|
|
|
+ Long startTime = dingTimeDto.getStartTime();
|
|
|
+ Long endTime = dingTimeDto.getEndTime();
|
|
|
+
|
|
|
+ List<TBDingStatistic> tbDingStatisticList = new ArrayList<>();
|
|
|
+ List<Long> userArchivesIdList = datasource.stream().map(TBDing::getUserArchivesId).distinct().collect(Collectors.toList());
|
|
|
+
|
|
|
+ for (Long userArchivesId : userArchivesIdList) {
|
|
|
+ UserArchivesResult tbUserArchives = tbUserArchivesService.findUserArchivesByArchivesIdORUserId(
|
|
|
+ userArchivesId, null);
|
|
|
+ if (Objects.isNull(tbUserArchives)) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("人员档案不存在");
|
|
|
+ }
|
|
|
+ Long userId = tbUserArchives.getUserId();
|
|
|
+ // 打卡数据集合
|
|
|
+ List<TBDing> dingList = datasource.stream()
|
|
|
+ .filter(e -> Objects.equals(userArchivesId, e.getUserArchivesId())).collect(Collectors.toList());
|
|
|
+
|
|
|
+ // 非异常打卡(打卡时间在计划时间范围内 以及签到签退完整的)
|
|
|
+ List<TBDing> effectDingList = dingList.stream()
|
|
|
+ .filter(e -> !SystemConstant.isOneNull(e.getSignInTime(), e.getSignOutTime())).filter(e -> {
|
|
|
+ // 在区协打卡时间范围内
|
|
|
+ Long signInTime = e.getSignInTime();
|
|
|
+ Long signOutTime = e.getSignOutTime();
|
|
|
+ return signInTime > startTime && signInTime < endTime && signOutTime > startTime && signOutTime < endTime;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+
|
|
|
+ List<SopRoleTypeEnum> sopRoleTypeList = dingList.stream().flatMap(e -> {
|
|
|
+ String sopRoleTypeStr = e.getSopRoleType();
|
|
|
+ List<SopRoleTypeEnum> list = JSONArray.parseArray(sopRoleTypeStr, SopRoleTypeEnum.class);
|
|
|
+ return list.stream();
|
|
|
+ }).distinct().collect(Collectors.toList());
|
|
|
+ String sopRoleType = JSON.toJSONString(sopRoleTypeList);
|
|
|
+
|
|
|
+ // 根据非异常打卡数据统计
|
|
|
+ int actualDays = 0;
|
|
|
+ int weekDays = 0;
|
|
|
+ int weekends = 0;
|
|
|
+ int legalHolidays = 0;
|
|
|
+ BigDecimal workHours = BigDecimal.ZERO;
|
|
|
+ BigDecimal var = new BigDecimal(3600000);
|
|
|
+ for (TBDing effectDing : effectDingList) {
|
|
|
+ // 有效天数
|
|
|
+ actualDays++;
|
|
|
+ DingDateTypeEnum dateType = effectDing.getDateType();
|
|
|
+ switch (dateType) {
|
|
|
+ case WEEKEND:
|
|
|
+ weekends++;
|
|
|
+ break;
|
|
|
+ case LEGAL_HOLIDAYS:
|
|
|
+ legalHolidays++;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ weekDays++;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ // 累计工时
|
|
|
+ workHours = workHours.add(
|
|
|
+ new BigDecimal(effectDing.getSignOutTime() - effectDing.getSignInTime()).divide(var, 1,
|
|
|
+ RoundingMode.HALF_UP));
|
|
|
+ }
|
|
|
+ // 违规工时
|
|
|
+ int violationDays = Math.toIntExact(
|
|
|
+ dingList.stream().filter(e -> SystemConstant.isOneNull(e.getSignInTime(), e.getSignOutTime()))
|
|
|
+ .count());
|
|
|
+ // 考勤异常数
|
|
|
+ int dingExceptionCount = 0;
|
|
|
+ for (TBDing tbDing : dingList) {
|
|
|
+ Long signInTime = tbDing.getSignInTime();
|
|
|
+ Long signOutTime = tbDing.getSignOutTime();
|
|
|
+ if (!SystemConstant.longNotNull(signInTime)) {
|
|
|
+ dingExceptionCount++;
|
|
|
+ }
|
|
|
+ if (!SystemConstant.longNotNull(signOutTime)) {
|
|
|
+ dingExceptionCount++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 剩余补卡数
|
|
|
+ int remainCount = tbDingService.findRemainCount(userId, serviceId, null);
|
|
|
+
|
|
|
+ // 待处理异常数
|
|
|
+ int exceptionCount = tbDingApplyService.count(
|
|
|
+ new QueryWrapper<TBDingApply>().lambda().eq(TBDingApply::getServiceId, serviceId)
|
|
|
+ .eq(TBDingApply::getCreateId, userId).isNull(TBDingApply::getApprove));
|
|
|
+
|
|
|
+ TBDingStatistic tbDingStatistic;
|
|
|
+ tbDingStatistic = this.findBySopNoAndUserArchivesId(serviceId, null, userArchivesId);
|
|
|
+ if (Objects.isNull(tbDingStatistic)) {
|
|
|
+ // 新增考勤统计
|
|
|
+ tbDingStatistic = new TBDingStatistic();
|
|
|
+ tbDingStatistic.insertInfo(requestUserId);
|
|
|
+ } else {
|
|
|
+ // 更新考勤统计
|
|
|
+ if (!tbDingSubmitService.canUpdateDingSetting(serviceId, null, userId)) {
|
|
|
+ // 已提交的考勤不再计算了
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ tbDingStatistic.updateInfo(requestUserId);
|
|
|
+ }
|
|
|
+ tbDingStatistic.setServiceId(serviceId);
|
|
|
+ tbDingStatistic.setUserId(userId);
|
|
|
+ tbDingStatistic.setUserArchivesId(userArchivesId);
|
|
|
+ tbDingStatistic.setUserArchivesName(tbUserArchives.getName());
|
|
|
+ tbDingStatistic.setUserArchivesCode(tbUserArchives.getCode());
|
|
|
tbDingStatistic.setRoleName(sopRoleType);
|
|
|
tbDingStatistic.setSupplierId(tbUserArchives.getSupplierId());
|
|
|
tbDingStatistic.setSupplierName(tbUserArchives.getSupplierName());
|