Min 11 hónapja
szülő
commit
4caeeff936

+ 99 - 135
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserWithBeisenController.java

@@ -12,6 +12,7 @@ import com.management.platform.mapper.UserMapper;
 import com.management.platform.mapper.UserWithBeisenMapper;
 import com.management.platform.service.*;
 import com.management.platform.util.BeiSenUtils;
+import com.management.platform.util.DateTimeUtil;
 import com.management.platform.util.HttpRespMsg;
 import com.management.platform.util.WorkDayCalculateUtils;
 import org.springframework.transaction.annotation.Transactional;
@@ -194,29 +195,27 @@ public class UserWithBeisenController {
                 Stream<JSONObject> timeStream1 = times.stream().map(time -> (JSONObject) time);
                 //获取最早上班打卡时间
                 List<LocalTime> minLocalTimeList = timeStream.filter(t -> t.getIntValue("Type") == 1).map(i -> LocalDateTime.parse(i.getString("ActualTime"),df1).toLocalTime()).collect(Collectors.toList());
-                Optional<LocalTime> min = minLocalTimeList.stream().min(LocalTime::compareTo);
+                Optional<LocalTime> minOp = minLocalTimeList.stream().min(LocalTime::compareTo);
                 //获取最晚下班时间
                 List<LocalTime> maxLocalTimeList = timeStream1.filter(t -> t.getIntValue("Type") == 9).map(i -> LocalDateTime.parse(i.getString("ActualTime"),df1).toLocalTime()).collect(Collectors.toList());
-                Optional<LocalTime> max = maxLocalTimeList.stream().max(LocalTime::compareTo);
+                Optional<LocalTime> maxOp = maxLocalTimeList.stream().max(LocalTime::compareTo);
                 if(first.isPresent()){
-                    boolean workDay = WorkDayCalculateUtils.isWorkDay(localDate)&&!holidaySettings.stream().anyMatch(h->h.getHolidayDate().isEqual(localDate));
+                    boolean workDay = WorkDayCalculateUtils.isWorkDay(localDate);
                     //todo:针对景昱 工作日默认以8小时工作制度加上加班时长 非工作日以加班时长为准
-                    Duration between = Duration.between(min.get(), max.get());
                     Double workTime;
-                    if(timeType.getCompanyId()==5978){
-                        if(workDay){
-                            workTime=8.0;
-                        }else {
-                            workTime=0.0;
-                        }
+                    LocalTime min = minOp.get();
+                    LocalTime max = maxOp.get();
+                    Duration between = Duration.between(min,max);
+                    if(between.toHours()<=0){
+                        continue;
                     }else {
-                        if(between.toHours()<0){
-                            workTime=0.0;
-                        }else {
-                            BigDecimal decimal = new BigDecimal(between.toMinutes());
-                            decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
-                            workTime=decimal.doubleValue();
-                        }
+                        //去掉休息时长
+                        long rest1 = DateTimeUtil.calculateOverlap(min, max, LocalTime.parse("12:00:00", df4), LocalTime.parse("13:00:00", df4));
+                        long rest2 = DateTimeUtil.calculateOverlap(min, max, LocalTime.parse("17:30:00", df4), LocalTime.parse("18:00:00", df4));
+                        long lastWorkMinute = between.toMinutes() - rest1-rest2;
+                        BigDecimal decimal = new BigDecimal(lastWorkMinute);
+                        decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_DOWN);
+                        workTime=decimal.doubleValue();
                     }
                     Stream<JSONObject> overTimeStream = allOverTimeList.stream().map(elment -> (JSONObject) elment);
                     Stream<JSONObject> vacationStream = allVacationList.stream().map(elment -> (JSONObject) elment);
@@ -229,22 +228,31 @@ public class UserWithBeisenController {
                         List<JSONObject> overTimeList = overTimeStream.filter(a -> a.getString("StaffId").equals(beisen.get().getUserId())
                                 && (a.getIntValue("ApproveStatus") == 2||a.getIntValue("ApproveStatus") == 1)).collect(Collectors.toList());
                         //加班数据可能存在结束日期是当前日期的情况的情况
-                        BigDecimal overTimeBigDecimal= new BigDecimal(0);;
+                        BigDecimal overTimeBigDecimal= new BigDecimal(0);
+                        //计算加班时长 工作日打卡超过19:00:00算加班那 非工作日全天算加班
+                        if(workDay){
+                            //工作日打卡超过19:00:00算加班那 非工作日全天算加班
+                            if(max.isAfter(LocalTime.parse("19:00:00", df4))){
+                                overTimeBigDecimal = new BigDecimal(Duration.between(LocalTime.parse("18:00:00", df4),max).toMinutes());
+                            }
+                        }else {
+                            //非工作日全天 去掉休息时长 都算加班
+                            overTimeBigDecimal=new BigDecimal(Duration.between(min, max).toMinutes()) ;
+                            long rest1 = DateTimeUtil.calculateOverlap(min, max, LocalTime.parse("12:00:00", df4), LocalTime.parse("13:00:00", df4));
+                            long rest2 = DateTimeUtil.calculateOverlap(min, max, LocalTime.parse("17:30:00", df4), LocalTime.parse("18:00:00", df4));
+                            overTimeBigDecimal=overTimeBigDecimal.subtract(new BigDecimal(rest1)).subtract(new BigDecimal(rest2));
+                        }
                         for (JSONObject o : overTimeList) {
                             //存在开始日期为当前日期的数据以及结束日期为当天日期的数据 分开计算
                             if(LocalDateTime.parse(o.getString("StartDate"),df1).toLocalDate().isEqual(localDate)){
                                 //存在开始日期为当天的数据
                                 if(LocalDateTime.parse(o.getString("StartDate"),df1).toLocalDate().isEqual(LocalDateTime.parse(o.getString("StopDate"),df1).toLocalDate())){
                                     //开始日期和结束日期是相同的情况 说明是加班区间只存在于当天的情况
-                                    //判断打卡时间是不是大于19:00 大于才算加班 通过打卡计算加班时长 与加班单作比较 取小
-                                    Duration timeDurantion = Duration.between(LocalTime.parse(workDay?"18:00:00":"08:30:00", df4), max.get());
-                                    BigDecimal decimal = new BigDecimal(timeDurantion.toMinutes());
-                                    decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
-                                    double l = decimal.doubleValue();
-                                    if(l<o.getDouble("OverTimeDuration")){
-                                        overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l<0?0:l));
-                                    }else {
-                                        overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(o.getDouble("OverTimeDuration")));
+                                    //对比打卡体现的加班时长和加班单时长取小
+                                    BigDecimal divide = overTimeBigDecimal.divide(new BigDecimal(60), 1, RoundingMode.HALF_DOWN);
+                                    if(divide.doubleValue()>o.getDouble("OverTimeDuration")){
+                                        //打卡获取到的加班时长大于加班单时长 需要在打卡体现的时长-打卡体现的加班时长+加班单时长
+                                        workTime=workTime-divide.doubleValue()+o.getDouble("OverTimeDuration");
                                     }
                                 }else {
                                     //开始日期和结束日期是不相同的情况 说明是加班区间存在加班到第二天的情况
@@ -252,17 +260,13 @@ public class UserWithBeisenController {
                                     LocalDateTime stop = start.toLocalDate().atTime(LocalTime.MAX);
                                     Duration duration = Duration.between(start, stop);
                                     BigDecimal decimal = new BigDecimal(duration.toMinutes());
-                                    decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                                    decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_DOWN);
                                     double l = decimal.doubleValue();
-                                    //判断打卡时间是不是大于19:00 通过打卡计算加班时长 与加班单作比较 取小
-                                    Duration timeDurantion = Duration.between(LocalTime.parse(workDay?"18:00:00":"08:30:00", df4), max.get());
-                                    BigDecimal decimal1 = new BigDecimal(timeDurantion.toMinutes());
-                                    decimal1=decimal1.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
-                                    double l1 = decimal1.doubleValue();
-                                    if(l1<l){
-                                        overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l1<0?0:l1));
-                                    }else {
-                                        overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l));
+                                    //对比打卡体现的加班时长和加班单时长取小
+                                    BigDecimal divide = overTimeBigDecimal.divide(new BigDecimal(60), 1, RoundingMode.HALF_DOWN);
+                                    if(divide.doubleValue()>l){
+                                        //打卡获取到的加班时长大于加班单时长 需要在打卡体现的时长-打卡体现的加班时长+加班单时长
+                                        workTime=workTime-divide.doubleValue()+l;
                                     }
                                 }
                             }else if(LocalDateTime.parse(o.getString("StopDate"),df1).toLocalDate().isEqual(localDate)){
@@ -270,14 +274,10 @@ public class UserWithBeisenController {
                                 if(LocalDateTime.parse(o.getString("StartDate"),df1).toLocalDate().isEqual(LocalDateTime.parse(o.getString("StopDate"),df1).toLocalDate())){
                                     //开始日期和结束日期是相同的情况 说明是加班区间只存在于当天的情况
                                     //判断打卡时间是不是大于19:00 通过打卡计算加班时长 与加班单作比较 取小
-                                    Duration timeDurantion = Duration.between(LocalTime.parse(workDay?"18:00:00":"08:30:00", df4), max.get());
-                                    BigDecimal decimal = new BigDecimal(timeDurantion.toMinutes());
-                                    decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
-                                    double l = decimal.doubleValue();
-                                    if(l<o.getDouble("OverTimeDuration")){
-                                        overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l<0?0:l));
-                                    }else {
-                                        overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(o.getDouble("OverTimeDuration")));
+                                    BigDecimal divide = overTimeBigDecimal.divide(new BigDecimal(60), 1, RoundingMode.HALF_DOWN);
+                                    if(divide.doubleValue()>o.getDouble("OverTimeDuration")){
+                                        //打卡获取到的加班时长大于加班单时长 需要在打卡体现的时长-打卡体现的加班时长+加班单时长
+                                        workTime=workTime-divide.doubleValue()+o.getDouble("OverTimeDuration");
                                     }
                                 }else {
                                     //开始日期和结束日期是不相同的情况 说明是加班区间存在加班到第二天的情况
@@ -285,34 +285,17 @@ public class UserWithBeisenController {
                                     LocalDateTime start = stop.toLocalDate().atTime(LocalTime.MIN);
                                     Duration duration = Duration.between(start, stop);
                                     BigDecimal decimal = new BigDecimal(duration.toMinutes());
-                                    decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                                    decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_DOWN);
                                     double l = decimal.doubleValue();
-                                    //判断打卡时间是不是大于19:00 通过打卡计算加班时长 与加班单作比较 取小
-                                    Duration timeDurantion = Duration.between(LocalTime.parse(workDay?"18:00:00":"08:30:00", df4), max.get());
-                                    BigDecimal decimal1 = new BigDecimal(timeDurantion.toMinutes());
-                                    decimal1=decimal1.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
-                                    double l1 = decimal1.doubleValue();
-                                    if(l1<l){
-                                        overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l1<0?0:l1));
-                                    }else {
-                                        overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l));
+                                    //对比打卡体现的加班时长和加班单时长取小
+                                    BigDecimal divide = overTimeBigDecimal.divide(new BigDecimal(60), 1, RoundingMode.HALF_DOWN);
+                                    if(divide.doubleValue()>l){
+                                        //打卡获取到的加班时长大于加班单时长 需要在打卡体现的时长-打卡体现的加班时长+加班单时长
+                                        workTime=workTime-divide.doubleValue()+l;
                                     }
                                 }
                             }
                         }
-                        if(workDay){
-                            //工作日计算按照前面的逻辑计算加班时长计算
-                            workTime= workTime+overTimeBigDecimal.doubleValue();
-                        }else {
-                            //非工作日加班 根据实际打卡时长 比较 加班单时长
-                            BigDecimal decimal = new BigDecimal(between.toMinutes());
-                            decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
-                            if((decimal.doubleValue())>overTimeBigDecimal.doubleValue()){
-                                workTime= workTime+overTimeBigDecimal.doubleValue();
-                            }else {
-                                workTime= workTime+(decimal.doubleValue());
-                            }
-                        }
                         //处理修改
                         List<JSONObject> vacationList = vacationStream.filter(a ->{
                             LocalDate vacationStartDate = LocalDateTime.parse(a.getString("VacationStartDateTime"), df3).toLocalDate();
@@ -332,7 +315,7 @@ public class UserWithBeisenController {
                         if(vacationList.size()>0){
                             double vacationDuration = vacationList.stream().mapToDouble(i -> i.getDouble("VacationDuration")).sum();
                             BigDecimal decimal = new BigDecimal(vacationDuration);
-                            decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                            decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_DOWN);
 //                            //可能存在休假多天 只减去一天
                             if(decimal.doubleValue()>=8){
                                 workTime= workTime-8;
@@ -343,8 +326,8 @@ public class UserWithBeisenController {
                     }
                     UserFvTime userFvTime=new UserFvTime();
                     userFvTime.setWorkDate(localDate);
-                    userFvTime.setStartTime(min.isPresent()?df2.format(min.get()):"08:30");
-                    userFvTime.setEndTime(max.isPresent()?df2.format(max.get()):"17:30");
+                    userFvTime.setStartTime(df2.format(min));
+                    userFvTime.setEndTime(df2.format(max));
                     userFvTime.setUserId(first.get().getId());
                     userFvTime.setCompanyId(companyId);
                     userFvTime.setWorkHours(workTime.floatValue());
@@ -459,20 +442,17 @@ public class UserWithBeisenController {
             Duration between = Duration.between(LocalTime.parse(firstCard, df4), LocalTime.parse(lastCard, df4));
             LocalTime min = LocalTime.parse(firstCard, df4);
             LocalTime max = LocalTime.parse(lastCard, df4);
-            if(timeType.getCompanyId()==5978){
-                if(workDay){
-                    workTime=8.0;
-                }else {
-                    workTime=0.0;
-                }
+            if(between.toHours()<=0){
+                msg.setError("无考勤记录");
+                return msg;
             }else {
-                if(between.toHours()<0){
-                    workTime=0.0;
-                }else {
-                    BigDecimal decimal = new BigDecimal(between.toMinutes());
-                    decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
-                    workTime=decimal.doubleValue();
-                }
+                //去掉休息时长
+                long rest1 = DateTimeUtil.calculateOverlap(min, max, LocalTime.parse("12:00:00", df4), LocalTime.parse("13:00:00", df4));
+                long rest2 = DateTimeUtil.calculateOverlap(min, max, LocalTime.parse("17:30:00", df4), LocalTime.parse("18:00:00", df4));
+                long lastWorkMinute = between.toMinutes() - rest1-rest2;
+                BigDecimal decimal = new BigDecimal(lastWorkMinute);
+                decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_DOWN);
+                workTime=decimal.doubleValue();
             }
             Stream<JSONObject> overTimeStream = allOverTimeList.stream().map(elment -> (JSONObject) elment);
             Stream<JSONObject> vacationStream = vacationList.stream().map(elment -> (JSONObject) elment);
@@ -487,21 +467,30 @@ public class UserWithBeisenController {
                 LocalDate localDate = LocalDate.parse(createDate, df);
                 //加班数据可能存在结束日期是当前日期的情况的情况
                 BigDecimal overTimeBigDecimal= new BigDecimal(0);
+                //计算加班时长 工作日打卡超过19:00:00算加班那 非工作日全天算加班
+                if(workDay){
+                    //工作日打卡超过19:00:00算加班那 非工作日全天算加班
+                    if(max.isAfter(LocalTime.parse("19:00:00", df4))){
+                        overTimeBigDecimal = new BigDecimal(Duration.between(LocalTime.parse("18:00:00", df4), LocalTime.parse(lastCard, df4)).toMinutes());
+                    }
+                }else {
+                    //非工作日全天 去掉休息时长 都算加班
+                    overTimeBigDecimal=new BigDecimal(Duration.between(LocalTime.parse(firstCard, df4), LocalTime.parse(lastCard, df4)).toMinutes()) ;
+                    long rest1 = DateTimeUtil.calculateOverlap(min, max, LocalTime.parse("12:00:00", df4), LocalTime.parse("13:00:00", df4));
+                    long rest2 = DateTimeUtil.calculateOverlap(min, max, LocalTime.parse("17:30:00", df4), LocalTime.parse("18:00:00", df4));
+                    overTimeBigDecimal=overTimeBigDecimal.subtract(new BigDecimal(rest1)).subtract(new BigDecimal(rest2));
+                }
                 for (JSONObject o : overTimeList) {
                     //存在开始日期为当前日期的数据以及结束日期为当天日期的数据 分开计算
                     if(LocalDateTime.parse(o.getString("StartDate"),df1).toLocalDate().isEqual(localDate)){
                         //存在开始日期为当天的数据
                         if(LocalDateTime.parse(o.getString("StartDate"),df1).toLocalDate().isEqual(LocalDateTime.parse(o.getString("StopDate"),df1).toLocalDate())){
                             //开始日期和结束日期是相同的情况 说明是加班区间只存在于当天的情况
-                            //判断打卡时间是不是大于19:00 大于才算加班 通过打卡计算加班时长 与加班单作比较 取小
-                            Duration timeDurantion = Duration.between(LocalTime.parse(workDay?"18:00:00":"08:30:00", df4), max);
-                            BigDecimal decimal = new BigDecimal(timeDurantion.toMinutes());
-                            decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
-                            double l = decimal.doubleValue();
-                            if(l<o.getDouble("OverTimeDuration")){
-                                overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l<0?0:l));
-                            }else {
-                                overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(o.getDouble("OverTimeDuration")));
+                            //对比打卡体现的加班时长和加班单时长取小
+                            BigDecimal divide = overTimeBigDecimal.divide(new BigDecimal(60), 1, RoundingMode.HALF_DOWN);
+                            if(divide.doubleValue()>o.getDouble("OverTimeDuration")){
+                                //打卡获取到的加班时长大于加班单时长 需要在打卡体现的时长-打卡体现的加班时长+加班单时长
+                                workTime=workTime-divide.doubleValue()+o.getDouble("OverTimeDuration");
                             }
                         }else {
                             //开始日期和结束日期是不相同的情况 说明是加班区间存在加班到第二天的情况
@@ -509,17 +498,13 @@ public class UserWithBeisenController {
                             LocalDateTime stop = start.toLocalDate().atTime(LocalTime.MAX);
                             Duration duration = Duration.between(start, stop);
                             BigDecimal decimal = new BigDecimal(duration.toMinutes());
-                            decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                            decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_DOWN);
                             double l = decimal.doubleValue();
-                            //判断打卡时间是不是大于19:00 通过打卡计算加班时长 与加班单作比较 取小
-                            Duration timeDurantion = Duration.between(LocalTime.parse(workDay?"18:00:00":"08:30:00", df4), max);
-                            BigDecimal decimal1 = new BigDecimal(timeDurantion.toMinutes());
-                            decimal1=decimal1.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
-                            double l1 = decimal1.doubleValue();
-                            if(l1<l){
-                                overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l1<0?0:l1));
-                            }else {
-                                overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l));
+                            //对比打卡体现的加班时长和加班单时长取小
+                            BigDecimal divide = overTimeBigDecimal.divide(new BigDecimal(60), 1, RoundingMode.HALF_DOWN);
+                            if(divide.doubleValue()>l){
+                                //打卡获取到的加班时长大于加班单时长 需要在打卡体现的时长-打卡体现的加班时长+加班单时长
+                                workTime=workTime-divide.doubleValue()+l;
                             }
                         }
                     }else if(LocalDateTime.parse(o.getString("StopDate"),df1).toLocalDate().isEqual(localDate)){
@@ -527,14 +512,10 @@ public class UserWithBeisenController {
                         if(LocalDateTime.parse(o.getString("StartDate"),df1).toLocalDate().isEqual(LocalDateTime.parse(o.getString("StopDate"),df1).toLocalDate())){
                             //开始日期和结束日期是相同的情况 说明是加班区间只存在于当天的情况
                             //判断打卡时间是不是大于19:00 通过打卡计算加班时长 与加班单作比较 取小
-                            Duration timeDurantion = Duration.between(LocalTime.parse(workDay?"18:00:00":"08:30:00", df4), max);
-                            BigDecimal decimal = new BigDecimal(timeDurantion.toMinutes());
-                            decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
-                            double l = decimal.doubleValue();
-                            if(l<o.getDouble("OverTimeDuration")){
-                                overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l<0?0:l));
-                            }else {
-                                overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(o.getDouble("OverTimeDuration")));
+                            BigDecimal divide = overTimeBigDecimal.divide(new BigDecimal(60), 1, RoundingMode.HALF_DOWN);
+                            if(divide.doubleValue()>o.getDouble("OverTimeDuration")){
+                                //打卡获取到的加班时长大于加班单时长 需要在打卡体现的时长-打卡体现的加班时长+加班单时长
+                                workTime=workTime-divide.doubleValue()+o.getDouble("OverTimeDuration");
                             }
                         }else {
                             //开始日期和结束日期是不相同的情况 说明是加班区间存在加班到第二天的情况
@@ -542,34 +523,17 @@ public class UserWithBeisenController {
                             LocalDateTime start = stop.toLocalDate().atTime(LocalTime.MIN);
                             Duration duration = Duration.between(start, stop);
                             BigDecimal decimal = new BigDecimal(duration.toMinutes());
-                            decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                            decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_DOWN);
                             double l = decimal.doubleValue();
-                            //判断打卡时间是不是大于19:00 通过打卡计算加班时长 与加班单作比较 取小
-                            Duration timeDurantion = Duration.between(LocalTime.parse(workDay?"18:00:00":"08:30:00", df4), max);
-                            BigDecimal decimal1 = new BigDecimal(timeDurantion.toMinutes());
-                            decimal1=decimal1.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
-                            double l1 = decimal1.doubleValue();
-                            if(l1<l){
-                                overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l1<0?0:l1));
-                            }else {
-                                overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l));
+                            //对比打卡体现的加班时长和加班单时长取小
+                            BigDecimal divide = overTimeBigDecimal.divide(new BigDecimal(60), 1, RoundingMode.HALF_DOWN);
+                            if(divide.doubleValue()>l){
+                                //打卡获取到的加班时长大于加班单时长 需要在打卡体现的时长-打卡体现的加班时长+加班单时长
+                                workTime=workTime-divide.doubleValue()+l;
                             }
                         }
                     }
                 }
-                if(workDay){
-                    //工作日计算按照前面的逻辑计算加班时长计算
-                    workTime= workTime+overTimeBigDecimal.doubleValue();
-                }else {
-                    //非工作日加班 根据实际打卡时长 比较 加班单时长
-                    BigDecimal decimal = new BigDecimal(between.toMinutes());
-                    decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
-                    if((decimal.doubleValue())>overTimeBigDecimal.doubleValue()){
-                        workTime= workTime+overTimeBigDecimal.doubleValue();
-                    }else {
-                        workTime= workTime+(decimal.doubleValue());
-                    }
-                }
                 //处理修改
                 List<JSONObject> lastVacationList = vacationStream.filter(a ->{
                     LocalDate vacationStartDate = LocalDateTime.parse(a.getString("VacationStartDateTime"), df3).toLocalDate();
@@ -589,7 +553,7 @@ public class UserWithBeisenController {
                 if(lastVacationList.size()>0){
                     double vacationDuration = lastVacationList.stream().mapToDouble(i -> i.getDouble("VacationDuration")).sum();
                     BigDecimal decimal = new BigDecimal(vacationDuration);
-                    decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                    decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_DOWN);
 //                            //可能存在休假多天 只减去一天
                     if(decimal.doubleValue()>=8){
                         workTime= workTime-8;

+ 53 - 71
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java

@@ -2144,30 +2144,28 @@ public class TimingTask {
                 Stream<JSONObject> timeStream1 = times.stream().map(time -> (JSONObject) time);
                 //获取最早上班打卡时间
                 List<LocalTime> minLocalTimeList = timeStream.filter(t -> t.getIntValue("Type") == 1).map(i -> LocalDateTime.parse(i.getString("ActualTime"),df1).toLocalTime()).collect(Collectors.toList());
-                Optional<LocalTime> min = minLocalTimeList.stream().min(LocalTime::compareTo);
+                Optional<LocalTime> minOp = minLocalTimeList.stream().min(LocalTime::compareTo);
                 //获取最早上班打卡时间
                 List<LocalTime> maxLocalTimeList = timeStream1.filter(t -> t.getIntValue("Type") == 9).map(i -> LocalDateTime.parse(i.getString("ActualTime"),df1).toLocalTime()).collect(Collectors.toList());
-                Optional<LocalTime> max = maxLocalTimeList.stream().max(LocalTime::compareTo);
+                Optional<LocalTime> maxOp = maxLocalTimeList.stream().max(LocalTime::compareTo);
                 //获取最晚下班时间
                 if(first.isPresent()){
-                    boolean workDay = WorkDayCalculateUtils.isWorkDay(localDate)&&!holidaySettings.stream().anyMatch(h->h.getHolidayDate().isEqual(localDate));
+                    boolean workDay = WorkDayCalculateUtils.isWorkDay(localDate);
                     //todo:针对景昱 工作日默认以8小时工作制度加上加班时长 非工作日以加班时长为准
-                    Duration between = Duration.between(min.get(), max.get());
                     Double workTime;
-                    if(beisenConfig.getCompanyId()==5978){
-                        if(workDay){
-                            workTime=8.0;
-                        }else {
-                            workTime=0.0;
-                        }
+                    LocalTime min = minOp.get();
+                    LocalTime max = maxOp.get();
+                    Duration between = Duration.between(min,max);
+                    if(between.toHours()<=0){
+                        continue;
                     }else {
-                        if(between.toHours()<0){
-                            workTime=0.0;
-                        }else {
-                            BigDecimal decimal = new BigDecimal(between.toMinutes());
-                            decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
-                            workTime=decimal.doubleValue();
-                        }
+                        //去掉休息时长
+                        long rest1 = DateTimeUtil.calculateOverlap(min, max, LocalTime.parse("12:00:00", df4), LocalTime.parse("13:00:00", df4));
+                        long rest2 = DateTimeUtil.calculateOverlap(min, max, LocalTime.parse("17:30:00", df4), LocalTime.parse("18:00:00", df4));
+                        long lastWorkMinute = between.toMinutes() - rest1-rest2;
+                        BigDecimal decimal = new BigDecimal(lastWorkMinute);
+                        decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_DOWN);
+                        workTime=decimal.doubleValue();
                     }
                     Stream<JSONObject> overTimeStream = allOverTimeList.stream().map(elment -> (JSONObject) elment);
                     Stream<JSONObject> vacationStream = allVacationList.stream().map(elment -> (JSONObject) elment);
@@ -2180,22 +2178,31 @@ public class TimingTask {
                         List<JSONObject> overTimeList = overTimeStream.filter(a -> a.getString("StaffId").equals(beisen.get().getUserId())
                                 && (a.getIntValue("ApproveStatus") == 2||a.getIntValue("ApproveStatus") == 1)).collect(Collectors.toList());
                         //加班数据可能存在结束日期是当前日期的情况的情况
-                        BigDecimal overTimeBigDecimal= new BigDecimal(0);;
+                        BigDecimal overTimeBigDecimal= new BigDecimal(0);
+                        //计算加班时长 工作日打卡超过19:00:00算加班那 非工作日全天算加班
+                        if(workDay){
+                            //工作日打卡超过19:00:00算加班那 非工作日全天算加班
+                            if(max.isAfter(LocalTime.parse("19:00:00", df4))){
+                                overTimeBigDecimal = new BigDecimal(Duration.between(LocalTime.parse("18:00:00", df4),max).toMinutes());
+                            }
+                        }else {
+                            //非工作日全天 去掉休息时长 都算加班
+                            overTimeBigDecimal=new BigDecimal(Duration.between(min, max).toMinutes()) ;
+                            long rest1 = DateTimeUtil.calculateOverlap(min, max, LocalTime.parse("12:00:00", df4), LocalTime.parse("13:00:00", df4));
+                            long rest2 = DateTimeUtil.calculateOverlap(min, max, LocalTime.parse("17:30:00", df4), LocalTime.parse("18:00:00", df4));
+                            overTimeBigDecimal=overTimeBigDecimal.subtract(new BigDecimal(rest1)).subtract(new BigDecimal(rest2));
+                        }
                         for (JSONObject o : overTimeList) {
                             //存在开始日期为当前日期的数据以及结束日期为当天日期的数据 分开计算
                             if(LocalDateTime.parse(o.getString("StartDate"),df1).toLocalDate().isEqual(localDate)){
                                 //存在开始日期为当天的数据
                                 if(LocalDateTime.parse(o.getString("StartDate"),df1).toLocalDate().isEqual(LocalDateTime.parse(o.getString("StopDate"),df1).toLocalDate())){
                                     //开始日期和结束日期是相同的情况 说明是加班区间只存在于当天的情况
-                                    //判断打卡时间是不是大于19:00 大于才算加班 通过打卡计算加班时长 与加班单作比较 取小
-                                    Duration timeDurantion = Duration.between(LocalTime.parse(workDay?"18:00:00":"08:30:00", df4), max.get());
-                                    BigDecimal decimal = new BigDecimal(timeDurantion.toMinutes());
-                                    decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
-                                    double l = decimal.doubleValue();
-                                    if(l<o.getDouble("OverTimeDuration")){
-                                        overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l<0?0:l));
-                                    }else {
-                                        overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(o.getDouble("OverTimeDuration")));
+                                    //对比打卡体现的加班时长和加班单时长取小
+                                    BigDecimal divide = overTimeBigDecimal.divide(new BigDecimal(60), 1, RoundingMode.HALF_DOWN);
+                                    if(divide.doubleValue()>o.getDouble("OverTimeDuration")){
+                                        //打卡获取到的加班时长大于加班单时长 需要在打卡体现的时长-打卡体现的加班时长+加班单时长
+                                        workTime=workTime-divide.doubleValue()+o.getDouble("OverTimeDuration");
                                     }
                                 }else {
                                     //开始日期和结束日期是不相同的情况 说明是加班区间存在加班到第二天的情况
@@ -2203,17 +2210,13 @@ public class TimingTask {
                                     LocalDateTime stop = start.toLocalDate().atTime(LocalTime.MAX);
                                     Duration duration = Duration.between(start, stop);
                                     BigDecimal decimal = new BigDecimal(duration.toMinutes());
-                                    decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                                    decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_DOWN);
                                     double l = decimal.doubleValue();
-                                    //判断打卡时间是不是大于19:00 通过打卡计算加班时长 与加班单作比较 取小
-                                    Duration timeDurantion = Duration.between(LocalTime.parse(workDay?"18:00:00":"08:30:00", df4), max.get());
-                                    BigDecimal decimal1 = new BigDecimal(timeDurantion.toMinutes());
-                                    decimal1=decimal1.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
-                                    double l1 = decimal1.doubleValue();
-                                    if(l1<l){
-                                        overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l1<0?0:l1));
-                                    }else {
-                                        overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l));
+                                    //对比打卡体现的加班时长和加班单时长取小
+                                    BigDecimal divide = overTimeBigDecimal.divide(new BigDecimal(60), 1, RoundingMode.HALF_DOWN);
+                                    if(divide.doubleValue()>l){
+                                        //打卡获取到的加班时长大于加班单时长 需要在打卡体现的时长-打卡体现的加班时长+加班单时长
+                                        workTime=workTime-divide.doubleValue()+l;
                                     }
                                 }
                             }else if(LocalDateTime.parse(o.getString("StopDate"),df1).toLocalDate().isEqual(localDate)){
@@ -2221,14 +2224,10 @@ public class TimingTask {
                                 if(LocalDateTime.parse(o.getString("StartDate"),df1).toLocalDate().isEqual(LocalDateTime.parse(o.getString("StopDate"),df1).toLocalDate())){
                                     //开始日期和结束日期是相同的情况 说明是加班区间只存在于当天的情况
                                     //判断打卡时间是不是大于19:00 通过打卡计算加班时长 与加班单作比较 取小
-                                    Duration timeDurantion = Duration.between(LocalTime.parse(workDay?"18:00:00":"08:30:00", df4), max.get());
-                                    BigDecimal decimal = new BigDecimal(timeDurantion.toMinutes());
-                                    decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
-                                    double l = decimal.doubleValue();
-                                    if(l<o.getDouble("OverTimeDuration")){
-                                        overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l<0?0:l));
-                                    }else {
-                                        overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(o.getDouble("OverTimeDuration")));
+                                    BigDecimal divide = overTimeBigDecimal.divide(new BigDecimal(60), 1, RoundingMode.HALF_DOWN);
+                                    if(divide.doubleValue()>o.getDouble("OverTimeDuration")){
+                                        //打卡获取到的加班时长大于加班单时长 需要在打卡体现的时长-打卡体现的加班时长+加班单时长
+                                        workTime=workTime-divide.doubleValue()+o.getDouble("OverTimeDuration");
                                     }
                                 }else {
                                     //开始日期和结束日期是不相同的情况 说明是加班区间存在加班到第二天的情况
@@ -2236,34 +2235,17 @@ public class TimingTask {
                                     LocalDateTime start = stop.toLocalDate().atTime(LocalTime.MIN);
                                     Duration duration = Duration.between(start, stop);
                                     BigDecimal decimal = new BigDecimal(duration.toMinutes());
-                                    decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                                    decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_DOWN);
                                     double l = decimal.doubleValue();
-                                    //判断打卡时间是不是大于19:00 通过打卡计算加班时长 与加班单作比较 取小
-                                    Duration timeDurantion = Duration.between(LocalTime.parse(workDay?"18:00:00":"08:30:00", df4), max.get());
-                                    BigDecimal decimal1 = new BigDecimal(timeDurantion.toMinutes());
-                                    decimal1=decimal1.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
-                                    double l1 = decimal1.doubleValue();
-                                    if(l1<l){
-                                        overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l1<0?0:l1));
-                                    }else {
-                                        overTimeBigDecimal=overTimeBigDecimal.add(new BigDecimal(l));
+                                    //对比打卡体现的加班时长和加班单时长取小
+                                    BigDecimal divide = overTimeBigDecimal.divide(new BigDecimal(60), 1, RoundingMode.HALF_DOWN);
+                                    if(divide.doubleValue()>l){
+                                        //打卡获取到的加班时长大于加班单时长 需要在打卡体现的时长-打卡体现的加班时长+加班单时长
+                                        workTime=workTime-divide.doubleValue()+l;
                                     }
                                 }
                             }
                         }
-                        if(workDay){
-                            //工作日计算按照前面的逻辑计算加班时长计算
-                            workTime= workTime+overTimeBigDecimal.doubleValue();
-                        }else {
-                            //非工作日加班 根据实际打卡时长 比较 加班单时长
-                            BigDecimal decimal = new BigDecimal(between.toMinutes());
-                            decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
-                            if((decimal.doubleValue())>overTimeBigDecimal.doubleValue()){
-                                workTime= workTime+overTimeBigDecimal.doubleValue();
-                            }else {
-                                workTime= workTime+(decimal.doubleValue());
-                            }
-                        }
                         List<JSONObject> vacationList = vacationStream.filter(a ->{
                             LocalDate vacationStartDate = LocalDateTime.parse(a.getString("VacationStartDateTime"), df3).toLocalDate();
                             LocalDate vacationStopDate = LocalDateTime.parse(a.getString("VacationStopDateTime"), df3).toLocalDate();
@@ -2282,7 +2264,7 @@ public class TimingTask {
                         if(vacationList.size()>0){
                             double vacationDuration = vacationList.stream().mapToDouble(i -> i.getDouble("VacationDuration")).sum();
                             BigDecimal decimal = new BigDecimal(vacationDuration);
-                            decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_UP);
+                            decimal=decimal.divide(new BigDecimal(60),1,RoundingMode.HALF_DOWN);
 //                            //可能存在休假多天 只减去一天
                             if(decimal.doubleValue()>=8){
                                 workTime= workTime-8;
@@ -2293,8 +2275,8 @@ public class TimingTask {
                     }
                     UserFvTime userFvTime=new UserFvTime();
                     userFvTime.setWorkDate(localDate);
-                    userFvTime.setStartTime(min.isPresent()?df2.format(min.get()):"08:30:00");
-                    userFvTime.setEndTime(max.isPresent()?df2.format(max.get()):"17:30:00");
+                    userFvTime.setStartTime(df2.format(min));
+                    userFvTime.setEndTime(df2.format(max));
                     userFvTime.setUserId(first.get().getId());
                     userFvTime.setCompanyId(5978);
                     userFvTime.setWorkHours(workTime.floatValue());

+ 12 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/DateTimeUtil.java

@@ -5,6 +5,7 @@ import org.apache.tomcat.jni.Local;
 import java.math.BigDecimal;
 import java.time.*;
 import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
 import java.time.temporal.TemporalAccessor;
 import java.util.Arrays;
 import java.util.Date;
@@ -37,6 +38,17 @@ public class DateTimeUtil {
         return hours;
     }
 
+    public static long calculateOverlap(LocalTime start1, LocalTime end1, LocalTime start2, LocalTime end2) {
+        if (start1.isAfter(end2) || start2.isAfter(end1)) {
+            return 0;
+        }
+
+        LocalTime overlapStart = start1.isBefore(start2) ? start2 : start1;
+        LocalTime overlapEnd = end1.isAfter(end2) ? end2 : end1;
+
+        return ChronoUnit.MINUTES.between(overlapStart, overlapEnd);
+    }
+
     /**
      * 返回四舍五入到整数的部分
      */