Browse Source

课酬调整,未完成

zouxuan 3 years ago
parent
commit
27718c51de

+ 3 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CourseScheduleTeacherSalaryDao.java

@@ -87,7 +87,9 @@ public interface CourseScheduleTeacherSalaryDao extends BaseDAO<Long, CourseSche
 	 * @params [days:天数]
 	 * @describe 获取多少天之前的未结算教师课酬记录(陪练课课)
 	 */
-	List<CourseScheduleTeacherSalary> findTeacherCourseSalaryNoSettlement(@Param("startDate") String startDate,@Param("endDate") String endDate);
+	List<CourseScheduleTeacherSalary> findTeacherCourseSalaryNoSettlement(@Param("startDate") String startDate,
+																		  @Param("endDate") String endDate,
+																		  @Param("groupType") String groupType);
 
 	/**
 	 * 查询老师指定课程的课酬

+ 64 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SalarySettlementDto.java

@@ -0,0 +1,64 @@
+package com.ym.mec.biz.dal.entity;
+
+import com.ym.mec.biz.dal.enums.TeachModeEnum;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.Date;
+
+//课酬结算工具类
+public class SalarySettlementDto {
+
+	@ApiModelProperty(value = "签到时间",required = false)
+	private Date signInTime;
+
+	@ApiModelProperty(value = "签退时间")
+	private Date signOutTime;
+
+	@ApiModelProperty(value = "课程开始时间",required = false)
+	private Date courseStartTime;
+
+	@ApiModelProperty(value = "课程结算时间")
+	private Date courseEndTime;
+
+	private TeachModeEnum teachModeEnum;
+
+	public Date getSignInTime() {
+		return signInTime;
+	}
+
+	public void setSignInTime(Date signInTime) {
+		this.signInTime = signInTime;
+	}
+
+	public Date getSignOutTime() {
+		return signOutTime;
+	}
+
+	public void setSignOutTime(Date signOutTime) {
+		this.signOutTime = signOutTime;
+	}
+
+	public Date getCourseStartTime() {
+		return courseStartTime;
+	}
+
+	public void setCourseStartTime(Date courseStartTime) {
+		this.courseStartTime = courseStartTime;
+	}
+
+	public Date getCourseEndTime() {
+		return courseEndTime;
+	}
+
+	public void setCourseEndTime(Date courseEndTime) {
+		this.courseEndTime = courseEndTime;
+	}
+
+	public TeachModeEnum getTeachModeEnum() {
+		return teachModeEnum;
+	}
+
+	public void setTeachModeEnum(TeachModeEnum teachModeEnum) {
+		this.teachModeEnum = teachModeEnum;
+	}
+}

+ 35 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SalarySettlementSignEnum.java

@@ -0,0 +1,35 @@
+package com.ym.mec.biz.dal.entity;
+
+import com.ym.mec.common.enums.BaseEnum;
+
+//课酬结算考勤状态枚举
+public enum SalarySettlementSignEnum implements BaseEnum<String,SalarySettlementSignEnum> {
+	NORMAL_IN("正常签到"),
+	ERR_IN("异常签到"),
+	LATE("迟到"),
+	TRUANTING("旷课"),
+	NOT_IN("未签到"),
+	NORMAL_OUT("正常签退"),
+	ERR_OUT("异常签退"),
+	LEAVE_EARLY("早退"),
+	NOT_OUT("未签退");
+
+	SalarySettlementSignEnum(String name) {
+		this.name = name;
+	}
+
+	private String name;
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	@Override
+	public String getCode() {
+		return null;
+	}
+}

+ 11 - 4
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/TeacherAttendance.java

@@ -1,9 +1,6 @@
 package com.ym.mec.biz.dal.entity;
 
-import com.ym.mec.biz.dal.enums.ComplaintsStatusEnum;
-import com.ym.mec.biz.dal.enums.GroupType;
-import com.ym.mec.biz.dal.enums.UpdateAttendanceEnum;
-import com.ym.mec.biz.dal.enums.YesOrNoEnum;
+import com.ym.mec.biz.dal.enums.*;
 import io.swagger.annotations.ApiModelProperty;
 import org.apache.commons.lang3.builder.ToStringBuilder;
 
@@ -113,6 +110,16 @@ public class TeacherAttendance {
 
 	private String deviceNum;
 
+	private TeachModeEnum teachModeEnum;
+
+	public TeachModeEnum getTeachModeEnum() {
+		return teachModeEnum;
+	}
+
+	public void setTeachModeEnum(TeachModeEnum teachModeEnum) {
+		this.teachModeEnum = teachModeEnum;
+	}
+
 	public UpdateAttendanceEnum getComplaintsType() {
 		return complaintsType;
 	}

+ 79 - 4
mec-biz/src/main/java/com/ym/mec/biz/service/SysConfigService.java

@@ -26,12 +26,87 @@ public interface SysConfigService extends BaseService<Long, SysConfig> {
     String MEMBER_GROUP_TERM_GIVE_COURSE_TIME = "member_group_term_give_course_time";
     //提醒老师创建新的缴费项目,距离缴费项有效期前{}天
     String PUSH_CREATE_PAYMENT_CALENDER = "push_create_payment_calender";
+
+    //考勤和课酬规则
+
+    //线下课课程开始前指定时间打卡为正常签到
+    String OFFLINE_ADVANCE_SIGN_IN_MINUTES = "offline_advance_sign_in_minutes";
+    //线下课课程开始后指定时间内签到为迟到
+    String OFFLINE_ADVANCE_SIGN_IN_LATE_MINUTES = "offline_advance_sign_in_late_minutes";
+    //线下课课程结束前指定时间签退为异常
+    String OFFLINE_ADVANCE_SIGN_OUT_MINUTES = "offline_advance_sign_out_minutes";
+
+    //线上课课程开始前指定时间打卡为正常签到
+    String ONLINE_ADVANCE_SIGN_IN_MINUTES = "online_advance_sign_in_minutes";
+    //线上课课程开始后指定时间内签到为迟到
+    String ONLINE_ADVANCE_SIGN_IN_LATE_MINUTES = "online_advance_sign_in_late_minutes";
+    //线上课课程结束前指定时间内签退为早退
+    String ONLINE_EARLY_SIGN_OUT_MINUTES = "online_early_sign_out_minutes";
+
+    //线下课老师异常签到扣减课酬金额
+    String OFFLINE_ERROR_SIGN_IN_CUT_SALARY = "offline_error_sign_in_cut_salary";
+    //线下课老师异常签到扣减课酬单位(1、元,2、百分比)
+    String OFFLINE_ERROR_SIGN_IN_CUT_SALARY_UNIT = "offline_error_sign_in_cut_salary_unit";
+    //线下课老师迟到扣减课酬金额
+    String OFFLINE_LATE_CUT_SALARY = "offline_late_cut_salary";
+    //线下课老师迟到扣减课酬单位(1、元,2、百分比)
+    String OFFLINE_LATE_CUT_SALARY_UNIT = "offline_late_cut_salary_unit";
+    //线下课老师旷课扣减课酬金额
+    String OFFLINE_LEVEL_SIGN_IN_CUT_SALARY = "offline_level_sign_in_cut_salary";
+    //线下课老师旷课扣减课酬单位(1、元,2、百分比)
+    String OFFLINE_LEVEL_SIGN_IN_CUT_SALARY_UNIT = "offline_level_sign_in_cut_salary_unit";
+    //线下课老师旷课扣减课酬金额
+    String OFFLINE_NO_SIGN_IN_CUT_SALARY = "offline_no_sign_in_cut_salary";
+    //线下课老师旷课扣减课酬单位(1、元,2、百分比)
+    String OFFLINE_NO_SIGN_IN_CUT_SALARY_UNIT = "offline_no_sign_in_cut_salary_unit";
+    //线下课老师异常签退扣减课酬金额
+    String OFFLINE_ERROR_SIGN_OUT_CUT_SALARY = "offline_error_sign_out_cut_salary";
+    //线下课老师异常签退扣减课酬单位(1、元,2、百分比)
+    String OFFLINE_ERROR_SIGN_OUT_CUT_SALARY_UNIT = "offline_error_sign_out_cut_salary_unit";
+    //线下课老师异常签退扣减课酬金额
+    String OFFLINE_EARLY_SIGN_OUT_CUT_SALARY = "offline_early_sign_out_cut_salary";
+    //线下课老师异常签退扣减课酬单位(1、元,2、百分比)
+    String OFFLINE_EARLY_SIGN_OUT_CUT_SALARY_UNIT = "offline_early_sign_out_cut_salary_unit";
+    //线下课老师异常签退扣减课酬金额
+    String OFFLINE_NO_SIGN_OUT_CUT_SALARY = "offline_no_sign_out_cut_salary";
+    //线下课老师异常签退扣减课酬单位(1、元,2、百分比)
+    String OFFLINE_NO_SIGN_OUT_CUT_SALARY_UNIT = "offline_no_sign_out_cut_salary_unit";
+
+    //线上课老师迟到扣减课酬金额
+    String ONLINE_LATE_CUT_SALARY = "online_late_cut_salary";
+    //线上课老师迟到扣减课酬单位(1、元,2、百分比)
+    String ONLINE_LATE_CUT_SALARY_UNIT = "online_late_cut_salary_unit";
+    //线下课老师旷课扣减课酬金额
+    String ONLINE_LEVEL_SIGN_IN_CUT_SALARY = "online_level_sign_in_cut_salary";
+    //线下课老师旷课扣减课酬单位(1、元,2、百分比)
+    String ONLINE_LEVEL_SIGN_IN_CUT_SALARY_UNIT = "online_level_sign_in_cut_salary_unit";
+    //线下课老师旷课扣减课酬金额
+    String ONLINE_NO_SIGN_IN_CUT_SALARY = "online_no_sign_in_cut_salary";
+    //线下课老师旷课扣减课酬单位(1、元,2、百分比)
+    String ONLINE_NO_SIGN_IN_CUT_SALARY_UNIT = "online_no_sign_in_cut_salary_unit";
+    //线上课老师异常签退扣减课酬金额
+    String ONLINE_ERROR_SIGN_OUT_CUT_SALARY = "online_error_sign_out_cut_salary";
+    //线上课老师异常签退扣减课酬单位(1、元,2、百分比)
+    String ONLINE_ERROR_SIGN_OUT_CUT_SALARY_UNIT = "online_error_sign_out_cut_salary_unit";
+    //线上课老师早退扣减课酬金额
+    String ONLINE_EARLY_SIGN_OUT_CUT_SALARY = "online_early_sign_out_cut_salary";
+    //线上课老师早退扣减课酬单位(1、元,2、百分比)
+    String ONLINE_EARLY_SIGN_OUT_CUT_SALARY_UNIT = "online_early_sign_out_cut_salary_unit";
+    //线上课老师未签退扣减课酬金额
+    String ONLINE_NO_SIGN_OUT_CUT_SALARY = "online_no_sign_out_cut_salary";
+    //线上课老师未签退扣减课酬单位(1、元,2、百分比)
+    String ONLINE_NO_SIGN_OUT_CUT_SALARY_UNIT = "online_no_sign_out_cut_salary_unit";
+
     //线下课老师可以打卡范围,GPS定位距离教学点距离
     String ATTENDANCE_RANGE = "attendance_range";
-    //线下课定位异常扣除金额
-    String OFFLINE_GPS_ERROR_CUT_SALARY = "offline_gps_error_cut_salary";
-    //线下课定位异常扣除金额
-    String OFFLINE_GPS_ERROR_CUT_SALARY_UNIT = "offline_gps_error_cut_salary_unit";
+    //线下课签到定位异常扣除金额
+    String OFFLINE_SIGN_IN_GPS_ERROR_CUT_SALARY = "offline_sign_in_gps_error_cut_salary";
+    //线下课签到定位异常扣除金额
+    String OFFLINE_SIGN_IN_GPS_ERROR_CUT_SALARY_UNIT = "offline_sign_in_gps_error_cut_salary_unit";
+    //线下课签退定位异常扣除金额
+    String OFFLINE_SIGN_OUT_GPS_ERROR_CUT_SALARY = "offline_sign_out_gps_error_cut_salary";
+    //线下课签退定位异常扣除金额
+    String OFFLINE_SIGN_OUT_GPS_ERROR_CUT_SALARY_UNIT = "offline_sign_out_gps_error_cut_salary_unit";
     //试用期老师课酬发放百分比
     String PROBATION_TEACHER_SALARY = "probation_teacher_salary";
     //兼职老师考勤申诉时间限制

+ 367 - 239
mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleTeacherSalaryServiceImpl.java

@@ -6,6 +6,7 @@ import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.biz.dal.dao.*;
 import com.ym.mec.biz.dal.dto.*;
 import com.ym.mec.biz.dal.entity.*;
+import com.ym.mec.biz.dal.entity.SalarySettlementDto;
 import com.ym.mec.biz.dal.enums.*;
 import com.ym.mec.biz.dal.page.CourseSalaryQueryInfo4Web;
 import com.ym.mec.biz.dal.page.CourseScheduleTeacherSalaryQueryInfo;
@@ -15,6 +16,7 @@ import com.ym.mec.biz.service.*;
 import com.ym.mec.common.constant.CommonConstants;
 import com.ym.mec.common.dal.BaseDAO;
 import com.ym.mec.common.exception.BizException;
+import com.ym.mec.common.filters.TenantIdThreadLocal;
 import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.common.service.impl.BaseServiceImpl;
 import com.ym.mec.thirdparty.message.MessageSenderPluginContext;
@@ -41,6 +43,8 @@ import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoField;
 import java.time.temporal.TemporalAdjusters;
 import java.util.*;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
 import java.util.stream.Collectors;
 
 @Service
@@ -210,6 +214,132 @@ public class CourseScheduleTeacherSalaryServiceImpl extends BaseServiceImpl<Long
         }
     }
 
+//    public void teacherSalarySettlement(List<CourseScheduleTeacherSalary> courseScheduleTeacherSalaries,Integer tenantId){
+//        if (CollectionUtils.isEmpty(courseScheduleTeacherSalaries)) {
+//            return;
+//        }
+//        List<Long> courseScheduleIds = courseScheduleTeacherSalaries.stream().map(CourseScheduleTeacherSalary::getCourseScheduleId).collect(Collectors.toList());
+//        //定位范围
+//        String gpsRange = sysTenantConfigService.getTenantConfigValue(SysConfigService.ATTENDANCE_RANGE,tenantId);
+//        double attendanceRange = 0;
+//        if(StringUtils.isNotEmpty(gpsRange)){
+//            attendanceRange = Double.valueOf(gpsRange);
+//        }
+//        //试用期课酬规则
+//        String configValue2 = sysTenantConfigService.getTenantConfigValue(SysConfigService.PROBATION_TEACHER_SALARY,tenantId);
+//        Integer probationTeacherSalary = 100;
+//        if(StringUtils.isNotEmpty(configValue2)){
+//            probationTeacherSalary = Integer.parseInt(configValue2);
+//        }
+//
+//        //教师签到记录
+//        List<TeacherAttendance> allTeacherAttendances = teacherAttendanceDao.findByCourseSchedules(courseScheduleIds);
+//        Map<String, List<TeacherAttendance>> teacherCourseAttendanceMap = allTeacherAttendances.stream().collect(Collectors.groupingBy(ta -> org.apache.commons.lang3.StringUtils.joinWith(":", ta.getCourseScheduleId(), ta.getTeacherId())));
+//
+//        Set<Integer> teacherIds = courseScheduleTeacherSalaries.stream().map(CourseScheduleTeacherSalary::getUserId).collect(Collectors.toSet());
+//        List<Teacher> teachers = teacherDao.findByTeacherIds(new ArrayList<>(teacherIds));
+//        Map<Integer, Teacher> idTeacherMap = teachers.stream().collect(Collectors.toMap(Teacher::getId, t -> t, (t1, t2) -> t1));
+//
+//        //计算课酬
+//        for (CourseScheduleTeacherSalary courseScheduleTeacherSalary : courseScheduleTeacherSalaries) {
+//            //当前课酬对应的课程信息
+//            CourseSchedule courseSchedule = courseScheduleIdMap.get(courseScheduleTeacherSalary.getCourseScheduleId());
+//            //教师课酬
+//            BigDecimal teacherSalary = courseScheduleTeacherSalary.getExpectSalary();
+//
+//            Teacher teacher = idTeacherMap.get(courseScheduleTeacherSalary.getUserId());
+//
+//            if(Objects.isNull(teacher)||(Objects.nonNull(teacher.getIsSettlementSalary())&&!teacher.getIsSettlementSalary())){
+//                courseScheduleTeacherSalary.setDeductionReason("不结算课酬");
+//
+//                courseScheduleTeacherSalary.setActualSalary(BigDecimal.ZERO);
+//                courseScheduleTeacherSalary.setSubsidy(BigDecimal.ZERO);
+//                courseScheduleTeacherSalary.setBelongToDaya(false);
+//                courseScheduleTeacherSalary.setSettlementTime(now);
+//                continue;
+//            }
+//
+//            List<String> deductReasons = new ArrayList<>();
+//
+//            if(Objects.isNull(courseScheduleTeacherSalary.getSubsidy())){
+//                courseScheduleTeacherSalary.setSubsidy(BigDecimal.ZERO);
+//            }
+//
+//            if(BigDecimal.ZERO.compareTo(courseScheduleTeacherSalary.getSubsidy()) != 0){
+//                teacherSalary = teacherSalary.add(courseScheduleTeacherSalary.getSubsidy());
+//                deductReasons.add("课程补贴:" + courseScheduleTeacherSalary.getSubsidy());
+//            }
+//
+//            //如果上课日期在试用期内按80%结算
+//            if(isTrail(teacher,courseSchedule.getClassDate())){
+//                teacherSalary = teacherSalary.multiply(new BigDecimal(probationTeacherSalary/100));
+//                deductReasons.add("未转正");
+//            }
+//
+//            //扣除费用
+//            BigDecimal deductCost = BigDecimal.ZERO;
+//
+//            List<TeacherAttendance> courseTeacherAttendances = teacherCourseAttendanceMap.get(org.apache.commons.lang3.StringUtils.joinWith(":", courseScheduleTeacherSalary.getCourseScheduleId(), courseScheduleTeacherSalary.getUserId()));
+//
+//            TeacherAttendance teacherAttendance = courseTeacherAttendances.get(0);
+//            //获取签到状态
+//            TeachModeEnum teachMode = courseScheduleTeacherSalary.getCourseSchedule().getTeachMode();
+//            SalarySettlementSignEnum signInStatus = getSignInStatus(teacherAttendance.getSignInTime(), courseSchedule.getStartClassTime(), teachMode,tenantId);
+//            BigDecimal signInDeductCost = getSignInDeduce(teacherSalary, signInStatus, teachMode);
+//            if(signInDeductCost.compareTo(BigDecimal.ZERO) > 0){
+//                deductCost = deductCost.add(signInDeductCost);
+//                deductReasons.add("签到状态异常扣除课酬" + signInDeductCost);
+//            }
+//            SalarySettlementSignEnum signOutStatus = getSignInStatus(teacherAttendance.getSignInTime(), courseSchedule.getStartClassTime(), teachMode,tenantId);
+//            BigDecimal signOutDeductCost = getSignInDeduce(teacherSalary, signOutStatus, teachMode);
+//            if(signOutDeductCost.compareTo(BigDecimal.ZERO) > 0){
+//                deductCost = deductCost.add(signOutDeductCost);
+//                deductReasons.add("签退状态异常扣除课酬" + signOutDeductCost);
+//            }
+//            //经纬度是否正常
+//            if(teachMode == TeachModeEnum.OFFLINE){
+//                School school = idSchoolMap.get(courseSchedule.getSchoolId());
+//                if(school != null){
+//                    Boolean signInRange = getSignRange(school.getLongitudeLatitude(),teacherAttendance.getSignInLongitudeLatitude(),attendanceRange);
+//                    Boolean signOutRange = getSignRange(school.getLongitudeLatitude(),teacherAttendance.getSignOutLongitudeLatitude(),attendanceRange);
+//
+//                    if(!signInRange){
+//                        String c = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_SIGN_IN_GPS_ERROR_CUT_SALARY, tenantId);
+//                        String c1 = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_SIGN_IN_GPS_ERROR_CUT_SALARY_UNIT, tenantId);
+//                        BigDecimal signInGpsCutAmount = getCutAmount(c, c1, teacherSalary);
+//                        if(signInGpsCutAmount.compareTo(BigDecimal.ZERO) > 0){
+//                            deductReasons.add("签到经纬度异常扣除" + signInGpsCutAmount);
+//                        }
+//                    }
+//                    if(!signOutRange){
+//                        String c = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_SIGN_OUT_GPS_ERROR_CUT_SALARY, tenantId);
+//                        String c1 = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_SIGN_OUT_GPS_ERROR_CUT_SALARY_UNIT, tenantId);
+//                        BigDecimal signOutGpsCutAmount = getCutAmount(c, c1, teacherSalary);
+//                        if(signOutGpsCutAmount.compareTo(BigDecimal.ZERO) > 0){
+//                            deductReasons.add("签退经纬度异常扣除" + signOutGpsCutAmount);
+//                        }
+//                    }
+//                }
+//            }
+//
+//            BigDecimal finalSalary = teacherSalary.subtract(deductCost).setScale(BigDecimal.ZERO.intValue(), BigDecimal.ROUND_HALF_UP);
+//
+//            if(BigDecimal.ZERO.compareTo(deductCost)<0){
+//                deductReasons.add("扣除总费用:" + deductCost);
+//            }
+//            if(!CollectionUtils.isEmpty(deductReasons))
+//                courseScheduleTeacherSalary.setDeductionReason(org.apache.commons.lang3.StringUtils.join(deductReasons, ";"));
+//
+//            //更新教师结算信息
+//            courseScheduleTeacherSalary.setActualSalary(finalSalary.compareTo(BigDecimal.ZERO)<0?BigDecimal.ZERO:finalSalary);
+//            courseScheduleTeacherSalary.setBelongToDaya(false);
+//            courseScheduleTeacherSalary.setSettlementTime(now);
+//        }
+//        if(courseScheduleTeacherSalaries != null && courseScheduleTeacherSalaries.size() > 0){
+//            courseScheduleTeacherSalaryDao.batchUpdate(courseScheduleTeacherSalaries);
+//        }
+//    }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void practiceTeacherSalarySettlement(Integer tenantId) {
@@ -218,7 +348,7 @@ public class CourseScheduleTeacherSalaryServiceImpl extends BaseServiceImpl<Long
         Date date = DateUtil.addMonths(now, -1);
         String startDate = DateUtil.format(DateUtil.getFirstDayOfMonth(date),DateUtil.DEFAULT_PATTERN);
         String endDate = DateUtil.format(DateUtil.getLastDayOfMonth(date),DateUtil.DEFAULT_PATTERN);
-        List<CourseScheduleTeacherSalary> someDayAgoTeacherCourseSalaryNoSettlement = courseScheduleTeacherSalaryDao.findTeacherCourseSalaryNoSettlement(startDate,endDate);
+        List<CourseScheduleTeacherSalary> someDayAgoTeacherCourseSalaryNoSettlement = courseScheduleTeacherSalaryDao.findTeacherCourseSalaryNoSettlement(startDate,endDate,"PRACTICE");
 
         if(CollectionUtils.isEmpty(someDayAgoTeacherCourseSalaryNoSettlement)){
             return;
@@ -490,6 +620,189 @@ public class CourseScheduleTeacherSalaryServiceImpl extends BaseServiceImpl<Long
         return trail;
     }
 
+    //获取签退状态
+    public SalarySettlementSignEnum getSignOutStatus(Date signOutTime,Date courseEndTime,TeachModeEnum teachModeEnum){
+        if(signOutTime == null){
+            return SalarySettlementSignEnum.NOT_OUT;
+        }
+        int signOutCourseTimeBetweenSeconds = DateUtil.secondsBetween(signOutTime, courseEndTime);
+        float signOutCourseTimeBetween = (float)signOutCourseTimeBetweenSeconds/(float)60;
+
+        //是否正常签退
+        if(signOutCourseTimeBetween <= 0){
+            return SalarySettlementSignEnum.NORMAL_OUT;
+        }
+        Integer tenantId = TenantIdThreadLocal.get();
+        //异常签退规则
+        String configValue = null;
+        if(teachModeEnum == TeachModeEnum.ONLINE){
+            configValue = sysTenantConfigService.getTenantConfigValue(SysConfigService.ONLINE_EARLY_SIGN_OUT_MINUTES, tenantId);
+        }else {
+            configValue = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_ADVANCE_SIGN_OUT_MINUTES, tenantId);
+        }
+        if(StringUtils.isEmpty(configValue)){
+            return SalarySettlementSignEnum.NORMAL_OUT;
+        }else {
+            int i = Integer.parseInt(configValue);
+            //是否异常签退
+            if(signOutCourseTimeBetween > 0 && signOutCourseTimeBetween <= i){
+                return SalarySettlementSignEnum.ERR_OUT;
+            }
+            //是否早退
+            if(signOutCourseTimeBetween > i){
+                return SalarySettlementSignEnum.LEAVE_EARLY;
+            }
+        }
+        return SalarySettlementSignEnum.NORMAL_OUT;
+    }
+
+    //获取签到状态
+    public SalarySettlementSignEnum getSignInStatus(Date signInTime,Date courseStartTime,TeachModeEnum teachModeEnum,Integer tenantId){
+        if(signInTime == null){
+            return SalarySettlementSignEnum.NOT_IN;
+        }
+        int signCourseTimeBetweenSeconds = DateUtil.secondsBetween(signInTime,courseStartTime);
+        float signCourseTimeBetween = (float)signCourseTimeBetweenSeconds/(float)60;
+
+        String configValue = null;
+        if(teachModeEnum == TeachModeEnum.ONLINE){
+            configValue = sysTenantConfigService.getTenantConfigValue(SysConfigService.ONLINE_ADVANCE_SIGN_IN_MINUTES, tenantId);
+        }else {
+            configValue = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_ADVANCE_SIGN_IN_MINUTES, tenantId);
+        }
+        if(StringUtils.isEmpty(configValue)){
+            return SalarySettlementSignEnum.NORMAL_IN;
+        }else {
+            int i = Integer.parseInt(configValue);
+            //是否正常签到
+            if(signCourseTimeBetween >= i){
+                return SalarySettlementSignEnum.NORMAL_IN;
+            }
+            //是否异常签到
+            if(signCourseTimeBetween >= 0 && signCourseTimeBetween < i){
+                return SalarySettlementSignEnum.ERR_IN;
+            }
+        }
+        //迟到规则
+        if(teachModeEnum == TeachModeEnum.ONLINE){
+            configValue = sysTenantConfigService.getTenantConfigValue(SysConfigService.ONLINE_ADVANCE_SIGN_IN_LATE_MINUTES, tenantId);
+        }else {
+            configValue = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_ADVANCE_SIGN_IN_LATE_MINUTES, tenantId);
+        }
+        if(StringUtils.isEmpty(configValue)){
+            return SalarySettlementSignEnum.NORMAL_IN;
+        }else {
+            int i = Integer.parseInt(configValue);
+            //是否迟到
+            if(signCourseTimeBetween < 0 && signCourseTimeBetween >= ~--i){
+                return SalarySettlementSignEnum.LATE;
+            }
+            //是否旷课
+            if(signCourseTimeBetween < ~--i){
+                return SalarySettlementSignEnum.TRUANTING;
+            }
+        }
+        return SalarySettlementSignEnum.NORMAL_IN;
+    }
+
+    //获取签到扣除金额
+    public BigDecimal getSignInDeduce(BigDecimal salary,SalarySettlementSignEnum signEnum,TeachModeEnum teachModeEnum){
+        Integer tenantId = TenantIdThreadLocal.get();
+        String cutSalary = null;
+        String cutSalaryUnit = null;
+        switch (signEnum) {
+            case ERR_IN:
+                if(teachModeEnum == TeachModeEnum.ONLINE){
+                    //线上课没有异常
+                    cutSalary = sysTenantConfigService.getTenantConfigValue(SysConfigService.ONLINE_LATE_CUT_SALARY, tenantId);
+                    cutSalaryUnit = sysTenantConfigService.getTenantConfigValue(SysConfigService.ONLINE_LATE_CUT_SALARY_UNIT, tenantId);
+                }else {
+                    cutSalary = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_ERROR_SIGN_IN_CUT_SALARY, tenantId);
+                    cutSalaryUnit = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_ERROR_SIGN_IN_CUT_SALARY_UNIT, tenantId);
+                }
+                break;
+            case LATE:
+                if(teachModeEnum == TeachModeEnum.ONLINE){
+                    cutSalary = sysTenantConfigService.getTenantConfigValue(SysConfigService.ONLINE_LATE_CUT_SALARY, tenantId);
+                    cutSalaryUnit = sysTenantConfigService.getTenantConfigValue(SysConfigService.ONLINE_LATE_CUT_SALARY_UNIT, tenantId);
+                }else {
+                    cutSalary = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_LATE_CUT_SALARY, tenantId);
+                    cutSalaryUnit = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_LATE_CUT_SALARY_UNIT, tenantId);
+                }
+                break;
+            case TRUANTING:
+                if(teachModeEnum == TeachModeEnum.ONLINE){
+                    cutSalary = sysTenantConfigService.getTenantConfigValue(SysConfigService.ONLINE_LEVEL_SIGN_IN_CUT_SALARY, tenantId);
+                    cutSalaryUnit = sysTenantConfigService.getTenantConfigValue(SysConfigService.ONLINE_LEVEL_SIGN_IN_CUT_SALARY_UNIT, tenantId);
+                }else {
+                    cutSalary = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_LEVEL_SIGN_IN_CUT_SALARY, tenantId);
+                    cutSalaryUnit = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_LEVEL_SIGN_IN_CUT_SALARY_UNIT, tenantId);
+                }
+                break;
+            case NOT_IN:
+                if(teachModeEnum == TeachModeEnum.ONLINE){
+                    cutSalary = sysTenantConfigService.getTenantConfigValue(SysConfigService.ONLINE_NO_SIGN_IN_CUT_SALARY, tenantId);
+                    cutSalaryUnit = sysTenantConfigService.getTenantConfigValue(SysConfigService.ONLINE_NO_SIGN_IN_CUT_SALARY_UNIT, tenantId);
+                }else {
+                    cutSalary = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_NO_SIGN_IN_CUT_SALARY, tenantId);
+                    cutSalaryUnit = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_NO_SIGN_IN_CUT_SALARY_UNIT, tenantId);
+                }
+                break;
+            case ERR_OUT:
+                if(teachModeEnum == TeachModeEnum.ONLINE){
+                    cutSalary = sysTenantConfigService.getTenantConfigValue(SysConfigService.ONLINE_ERROR_SIGN_OUT_CUT_SALARY, tenantId);
+                    cutSalaryUnit = sysTenantConfigService.getTenantConfigValue(SysConfigService.ONLINE_ERROR_SIGN_OUT_CUT_SALARY_UNIT, tenantId);
+                }else {
+                    cutSalary = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_ERROR_SIGN_OUT_CUT_SALARY, tenantId);
+                    cutSalaryUnit = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_ERROR_SIGN_OUT_CUT_SALARY_UNIT, tenantId);
+                }
+                break;
+            case LEAVE_EARLY:
+                if(teachModeEnum == TeachModeEnum.ONLINE){
+                    cutSalary = sysTenantConfigService.getTenantConfigValue(SysConfigService.ONLINE_EARLY_SIGN_OUT_CUT_SALARY, tenantId);
+                    cutSalaryUnit = sysTenantConfigService.getTenantConfigValue(SysConfigService.ONLINE_EARLY_SIGN_OUT_CUT_SALARY_UNIT, tenantId);
+                }else {
+                    cutSalary = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_EARLY_SIGN_OUT_CUT_SALARY, tenantId);
+                    cutSalaryUnit = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_EARLY_SIGN_OUT_CUT_SALARY_UNIT, tenantId);
+                }
+                break;
+            case NOT_OUT:
+                if(teachModeEnum == TeachModeEnum.ONLINE){
+                    cutSalary = sysTenantConfigService.getTenantConfigValue(SysConfigService.ONLINE_NO_SIGN_OUT_CUT_SALARY, tenantId);
+                    cutSalaryUnit = sysTenantConfigService.getTenantConfigValue(SysConfigService.ONLINE_NO_SIGN_OUT_CUT_SALARY_UNIT, tenantId);
+                }else {
+                    cutSalary = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_NO_SIGN_OUT_CUT_SALARY, tenantId);
+                    cutSalaryUnit = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_NO_SIGN_OUT_CUT_SALARY_UNIT, tenantId);
+                }
+                break;
+            default:
+                break;
+        }
+        return getCutAmount(cutSalary,cutSalaryUnit,salary);
+    }
+
+    public Boolean getSignRange(String schoolLongitudeLatitude,String longitudeLatitude,double attendanceRange){
+        Boolean signRange = false;
+        if(Objects.nonNull(schoolLongitudeLatitude) && StringUtils.isNotBlank(longitudeLatitude)){
+            double signInDistance = MapUtil.distance(longitudeLatitude,schoolLongitudeLatitude);
+            if (signInDistance <= attendanceRange) {
+                signRange = true;
+            }
+        }
+        return signRange;
+    }
+
+    public BigDecimal getCutAmount(String cutSalary,String cutSalaryUnit,BigDecimal teacherSalary){
+        if(StringUtils.isEmpty(cutSalary) || StringUtils.isEmpty(cutSalaryUnit)){
+            return BigDecimal.ZERO;
+        }
+        if(cutSalaryUnit.equals("1")){
+            return new BigDecimal(cutSalary);
+        }else {
+            return teacherSalary.multiply(new BigDecimal(Integer.parseInt(cutSalary)/100));
+        }
+    }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void musicGroupTeacherSalarySettlement(Integer tenantId) {
@@ -497,16 +810,16 @@ public class CourseScheduleTeacherSalaryServiceImpl extends BaseServiceImpl<Long
         Date date = DateUtil.addMonths(now, -1);
         String startDate = DateUtil.format(DateUtil.getFirstDayOfMonth(date),DateUtil.DEFAULT_PATTERN);
         String endDate = DateUtil.format(DateUtil.getLastDayOfMonth(date),DateUtil.DEFAULT_PATTERN);
+        //课程教师课酬
+        List<CourseScheduleTeacherSalary> courseScheduleTeacherSalaries = courseScheduleTeacherSalaryDao.findTeacherCourseSalaryNoSettlement(startDate,endDate,"MUSIC");
 
-        //获取上个月的课程计划
-        List<CourseSchedule> yesterdayCourseSchedules = courseScheduleDao.findCourseScheduleWithDate(startDate,endDate);
-        //课程编号列表
-        List<Long> courseScheduleIds = yesterdayCourseSchedules.stream().map(CourseSchedule::getId).collect(Collectors.toList());
-        if (CollectionUtils.isEmpty(courseScheduleIds)) {
+        if (CollectionUtils.isEmpty(courseScheduleTeacherSalaries)) {
             return;
         }
+        List<Long> courseScheduleIds = courseScheduleTeacherSalaries.stream().map(CourseScheduleTeacherSalary::getCourseScheduleId).collect(Collectors.toList());
 
-        BigDecimal zero = new BigDecimal(0);
+        //获取上个月的课程计划
+        List<CourseSchedule> yesterdayCourseSchedules = courseScheduleDao.findCourseScheduleWithDate(startDate,endDate);
 
         Set<Integer> schoolIds = yesterdayCourseSchedules.stream().map(CourseSchedule::getSchoolId).collect(Collectors.toSet());
         List<School> schools = schoolDao.getSchools(new ArrayList<>(schoolIds));
@@ -519,31 +832,12 @@ public class CourseScheduleTeacherSalaryServiceImpl extends BaseServiceImpl<Long
         Map<Long, CourseSchedule> courseScheduleIdMap = yesterdayCourseSchedules.stream()
                 .collect(Collectors.toMap(CourseSchedule::getId, courseSchedule -> courseSchedule));
 
-        //课程教师课酬
-        List<CourseScheduleTeacherSalary> courseScheduleTeacherSalaries = courseScheduleTeacherSalaryDao.findByCourseSchedulesWithNoSettlement(courseScheduleIds);
-
-        if (CollectionUtils.isEmpty(courseScheduleTeacherSalaries)) {
-            return;
-        }
-
         //定位范围
         String gpsRange = sysTenantConfigService.getTenantConfigValue(SysConfigService.ATTENDANCE_RANGE,tenantId);
         double attendanceRange = 0;
         if(StringUtils.isNotEmpty(gpsRange)){
             attendanceRange = Double.valueOf(gpsRange);
         }
-        //签到签退定位异常扣除金额
-//        String configValue = sysTenantConfigService.getConfigValue(SysConfigService.OFFLINE_GPS_ERROR_CUT_SALARY,tenantId);
-//        Integer gpsCutSalary = null;
-//        if(StringUtils.isNotEmpty(configValue)){
-//            gpsCutSalary = Integer.parseInt(configValue);
-//        }
-//        //签到签退定位异常扣除单位
-//        String configValue1 = sysTenantConfigService.getConfigValue(SysConfigService.OFFLINE_GPS_ERROR_CUT_SALARY_UNIT,tenantId);
-//        UnitEnum unitEnum = null;
-//        if(StringUtils.isNotEmpty(configValue1)){
-//            unitEnum = UnitEnum.valueOf(configValue1);
-//        }
           //试用期课酬规则
         String configValue2 = sysTenantConfigService.getTenantConfigValue(SysConfigService.PROBATION_TEACHER_SALARY,tenantId);
         Integer probationTeacherSalary = 100;
@@ -555,23 +849,6 @@ public class CourseScheduleTeacherSalaryServiceImpl extends BaseServiceImpl<Long
         List<TeacherAttendance> allTeacherAttendances = teacherAttendanceDao.findByCourseSchedules(courseScheduleIds);
         Map<String, List<TeacherAttendance>> teacherCourseAttendanceMap = allTeacherAttendances.stream().collect(Collectors.groupingBy(ta -> org.apache.commons.lang3.StringUtils.joinWith(":", ta.getCourseScheduleId(), ta.getTeacherId())));
 
-        //需要根据实际上课学员结算课酬的课程编号
-        List<Long> needStudentAttendanceCourseScheduleIds = yesterdayCourseSchedules.stream()
-                .filter(c -> CourseSchedule.CourseScheduleType.HIGH_ONLINE.equals(c.getType())
-                        || CourseSchedule.CourseScheduleType.MUSIC_NETWORK.equals(c.getType())
-                        || CourseSchedule.CourseScheduleType.HIGH.equals(c.getType()))
-                .map(CourseSchedule::getId).collect(Collectors.toList());
-
-        List<CourseScheduleStudentPayment> studentAttendances = null;
-        if(!CollectionUtils.isEmpty(needStudentAttendanceCourseScheduleIds)){
-            studentAttendances = courseScheduleStudentPaymentDao.findByCourseScheduleIds(needStudentAttendanceCourseScheduleIds);
-        }
-        Map<Long, Long> courseNormalStudentsMap = new HashMap<>();
-        if(!CollectionUtils.isEmpty(studentAttendances)){
-            courseNormalStudentsMap =studentAttendances.stream()
-                    .collect(Collectors.groupingBy(CourseScheduleStudentPayment::getCourseScheduleId, Collectors.counting()));
-        }
-
         Set<Integer> teacherIds = courseScheduleTeacherSalaries.stream().map(CourseScheduleTeacherSalary::getUserId).collect(Collectors.toSet());
         List<Teacher> teachers = teacherDao.findByTeacherIds(new ArrayList<>(teacherIds));
         Map<Integer, Teacher> idTeacherMap = teachers.stream().collect(Collectors.toMap(Teacher::getId, t -> t, (t1, t2) -> t1));
@@ -580,7 +857,6 @@ public class CourseScheduleTeacherSalaryServiceImpl extends BaseServiceImpl<Long
         for (CourseScheduleTeacherSalary courseScheduleTeacherSalary : courseScheduleTeacherSalaries) {
             //当前课酬对应的课程信息
             CourseSchedule courseSchedule = courseScheduleIdMap.get(courseScheduleTeacherSalary.getCourseScheduleId());
-
             //教师课酬
             BigDecimal teacherSalary = courseScheduleTeacherSalary.getExpectSalary();
 
@@ -593,219 +869,70 @@ public class CourseScheduleTeacherSalaryServiceImpl extends BaseServiceImpl<Long
                 courseScheduleTeacherSalary.setSubsidy(BigDecimal.ZERO);
                 courseScheduleTeacherSalary.setBelongToDaya(false);
                 courseScheduleTeacherSalary.setSettlementTime(now);
-                courseScheduleTeacherSalaryDao.update(courseScheduleTeacherSalary);
                 continue;
             }
 
-            if(CourseSchedule.CourseScheduleType.MUSIC_NETWORK.equals(courseSchedule.getType())||CourseSchedule.CourseScheduleType.HIGH_ONLINE.equals(courseSchedule.getType())){
-                Long normalStudentNum = courseNormalStudentsMap.get(courseSchedule.getId());
-                if(Objects.isNull(normalStudentNum)){
-                    normalStudentNum = Long.valueOf(0);
-                }
-                if(normalStudentNum>5){
-                    normalStudentNum=Long.valueOf(5);
-                }
-
-                List<String> deductReasons = new ArrayList<>();
-
-                if(Objects.isNull(courseScheduleTeacherSalary.getSubsidy())){
-                    courseScheduleTeacherSalary.setSubsidy(zero);
-                }
-
-                if(BigDecimal.ZERO.compareTo(courseScheduleTeacherSalary.getSubsidy())!=0){
-                    teacherSalary = teacherSalary.add(courseScheduleTeacherSalary.getSubsidy());
-                    deductReasons.add("课程补贴:" + courseScheduleTeacherSalary.getSubsidy());
-                }
-
-                //如果上课日期在试用期内按80%结算
-                if(isTrail(teacher,courseSchedule.getClassDate())){
-                    teacherSalary = teacherSalary.multiply(new BigDecimal(probationTeacherSalary/100));
-                    deductReasons.add("未转正");
-                }
-
-                //扣除费用
-                BigDecimal deductCost = new BigDecimal(0);
-                deductReasons.add("课程应到人数:" + normalStudentNum);
-                List<TeacherAttendance> courseTeacherAttendances = teacherCourseAttendanceMap.get(org.apache.commons.lang3.StringUtils.joinWith(":", courseScheduleTeacherSalary.getCourseScheduleId(), courseScheduleTeacherSalary.getUserId()));
-
-                TeacherAttendance teacherAttendance = courseTeacherAttendances.get(0);
-                if(CollectionUtils.isEmpty(courseTeacherAttendances)||Objects.isNull(teacherAttendance.getSignInStatus())){
-                    //未签到扣除全部课酬
-                    deductCost = deductCost.add(teacherSalary.abs());
-                    deductReasons.add("未签到扣除全部课酬");
-                }else if(YesOrNoEnum.NO.equals(teacherAttendance.getSignInStatus())){
-                    //异常签到
-                    int signCourseTimeBetweenSeconds = DateUtil.secondsBetween(teacherAttendance.getSignInTime(), courseSchedule.getStartClassTime());
-                    float signCourseTimeBetween = (float)signCourseTimeBetweenSeconds/(float)60;
-                    if(signCourseTimeBetween<=1&&signCourseTimeBetween>-3){
-                        //课程开始前1分钟至开始后3分钟进入教室
-                        deductCost = deductCost.add(teacherSalary.divide(new BigDecimal(2)).abs());
-                        deductReasons.add("课程开始前1分钟至开始后3分钟进入教室扣除一半课酬");
-                    }else if(signCourseTimeBetween<=-3){
-                        //课程开始后3分钟后进入教室
-                        deductCost = deductCost.add(teacherSalary.abs());
-                        deductReasons.add("课程开始后3分钟进入教室扣除全部课酬");
-                    }
-                }
-
-                if(CollectionUtils.isEmpty(courseTeacherAttendances)||Objects.isNull(teacherAttendance.getSignOutStatus())){
-                    //未签退扣除一半课酬
-                    deductCost = deductCost.add(teacherSalary.divide(new BigDecimal(2)).abs());
-                    deductReasons.add("未签退扣除一半课酬");
-                }else if(YesOrNoEnum.NO.equals(teacherAttendance.getSignOutStatus())){
-                    //异常签退
-                    int signOutCourseTimeBetweenSeconds = DateUtil.secondsBetween(teacherAttendance.getSignOutTime(), courseSchedule.getEndClassTime());
-                    float signOutCourseTimeBetween = (float)signOutCourseTimeBetweenSeconds/(float)60;
-
-                    if(signOutCourseTimeBetween>3){
-                        //课程开始前20分钟至开始后3分钟退出教室
-                        deductCost = deductCost.add(teacherSalary.abs());
-                        deductReasons.add("课程结束前3分钟之前退出教室扣除全部课酬");
-                    }else if(signOutCourseTimeBetween<=3&&signOutCourseTimeBetween>0){
-                        //课程结束前3分钟后至课程结束前退出教室
-                        deductCost = deductCost.add(teacherSalary.divide(new BigDecimal(2)).abs());
-                        deductReasons.add("课程结束前3分钟后至课程结束前退出教室扣除一半课酬");
-                    }
-                }
-
-                BigDecimal finalSalary = teacherSalary.subtract(deductCost).setScale(BigDecimal.ZERO.intValue(), BigDecimal.ROUND_HALF_UP);
-
-                if(BigDecimal.ZERO.compareTo(deductCost)<0){
-                    deductReasons.add("扣除总费用:" + deductCost);
-                }
-                if(!CollectionUtils.isEmpty(deductReasons))
-                    courseScheduleTeacherSalary.setDeductionReason(org.apache.commons.lang3.StringUtils.join(deductReasons, ";"));
-
-                //更新教师结算信息
-                courseScheduleTeacherSalary.setActualSalary(finalSalary.compareTo(BigDecimal.ZERO)<0?BigDecimal.ZERO:finalSalary);
-                courseScheduleTeacherSalary.setBelongToDaya(false);
-                courseScheduleTeacherSalary.setSettlementTime(now);
-                courseScheduleTeacherSalaryDao.update(courseScheduleTeacherSalary);
-
-                continue;
-            }else{
-                teacherSalary=courseScheduleTeacherSalary.getExpectSalary();
-            }
-
             List<String> deductReasons = new ArrayList<>();
 
             if(Objects.isNull(courseScheduleTeacherSalary.getSubsidy())){
-                courseScheduleTeacherSalary.setSubsidy(zero);
+                courseScheduleTeacherSalary.setSubsidy(BigDecimal.ZERO);
             }
 
-            if(BigDecimal.ZERO.compareTo(courseScheduleTeacherSalary.getSubsidy())!=0){
+            if(BigDecimal.ZERO.compareTo(courseScheduleTeacherSalary.getSubsidy()) != 0){
                 teacherSalary = teacherSalary.add(courseScheduleTeacherSalary.getSubsidy());
                 deductReasons.add("课程补贴:" + courseScheduleTeacherSalary.getSubsidy());
             }
 
-            //判断课程是否在试用期内
-            boolean trail = false;
-
-            if(Objects.nonNull(teacher)&&Objects.nonNull(teacher.getEntryDate())&&courseSchedule.getClassDate().compareTo(teacher.getEntryDate())>=0){
-                trail = true;
-            }
-            if(Objects.nonNull(teacher)&&Objects.nonNull(teacher.getFormalStaffDate())&&courseSchedule.getClassDate().compareTo(teacher.getFormalStaffDate())>=0){
-                trail = false;
-            }
-
             //如果上课日期在试用期内按80%结算
-            if(trail){
-                teacherSalary = teacherSalary.multiply(new BigDecimal("0.8"));
+            if(isTrail(teacher,courseSchedule.getClassDate())){
+                teacherSalary = teacherSalary.multiply(new BigDecimal(probationTeacherSalary/100));
                 deductReasons.add("未转正");
             }
 
             //扣除费用
             BigDecimal deductCost = BigDecimal.ZERO;
-            List<TeacherAttendance> courseTeacherAttendances = teacherCourseAttendanceMap.get(org.apache.commons.lang3.StringUtils.joinWith(":", courseScheduleTeacherSalary.getCourseScheduleId(), courseScheduleTeacherSalary.getUserId()));
-
-            TeacherAttendance teacherAttendance = null;
-            if(!CollectionUtils.isEmpty(courseTeacherAttendances)){
-                teacherAttendance = courseTeacherAttendances.get(0);
-            }
-
-            School school = idSchoolMap.get(courseSchedule.getSchoolId());
-            boolean signInInRange = false;
-            boolean signOutInRange = false;
-            if(Objects.nonNull(school)&&Objects.nonNull(school.getLongitudeLatitude())
-                    &&Objects.nonNull(teacherAttendance)
-                    &&StringUtils.isNotBlank(teacherAttendance.getSignInLongitudeLatitude())
-                    &&StringUtils.isNotBlank(teacherAttendance.getSignOutLongitudeLatitude())){
-                double signInDistance = MapUtil.distance(teacherAttendance.getSignInLongitudeLatitude(),
-                        school.getLongitudeLatitude());
-                if (signInDistance <= attendanceRange) {
-                    signInInRange = true;
-                }
-                double signOutDistance = MapUtil.distance(teacherAttendance.getSignOutLongitudeLatitude(),
-                        school.getLongitudeLatitude());
-                if (signOutDistance <= attendanceRange) {
-                    signOutInRange = true;
-                }
-            }
-            //签到状态
-            if(Objects.isNull(teacherAttendance) || Objects.isNull(teacherAttendance.getSignInStatus())){
-                //无签到记录扣除全部课酬
-                deductCost = deductCost.add(teacherSalary.abs());
-                deductReasons.add("未签到扣除全部课酬");
-            }
-
 
-            if(Objects.isNull(teacherAttendance)||Objects.isNull(teacherAttendance.getSignInStatus())){
-                //无签到记录扣除全部课酬
-                deductCost = deductCost.add(teacherSalary.abs());
-                deductReasons.add("未签到扣除全部课酬");
-            }else if(YesOrNoEnum.NO.equals(teacherAttendance.getSignInStatus())){
-                int signCourseTimeBetweenSeconds = DateUtil.secondsBetween(teacherAttendance.getSignInTime(), courseSchedule.getStartClassTime());
-                float signCourseTimeBetween = (float)signCourseTimeBetweenSeconds/(float)60;
-                if(signCourseTimeBetween>0&&signCourseTimeBetween<=20){
-                    //未提前20分钟打卡扣除50元
-                    deductCost = deductCost.add(new BigDecimal(50));
-                    deductReasons.add("未提前20分钟打卡扣除50元");
-                }else if(signCourseTimeBetween<=0&&signCourseTimeBetween>-30){
-                    //迟到30分钟内扣除一半课酬
-                    deductCost = deductCost.add(teacherSalary.divide(new BigDecimal(2)).abs());
-                    deductReasons.add("迟到30分钟内扣除一半课酬");
-                }else if(signCourseTimeBetween<=-30){
-                    //迟到30分钟及以上扣除全部课酬
-                    deductCost = deductCost.add(teacherSalary.abs());
-                    deductReasons.add("迟到30分钟及以上扣除全部课酬");
-                }
-                if(!signInInRange){
-                    //签到经纬度异常扣除50
-                    deductCost = deductCost.add(new BigDecimal(50));
-                    deductReasons.add("签到经纬度异常扣除50");
-                }
-            }else{
-                signInInRange = true;
-            }
+            List<TeacherAttendance> courseTeacherAttendances = teacherCourseAttendanceMap.get(org.apache.commons.lang3.StringUtils.joinWith(":", courseScheduleTeacherSalary.getCourseScheduleId(), courseScheduleTeacherSalary.getUserId()));
 
-            if(Objects.isNull(teacherAttendance)||Objects.isNull(teacherAttendance.getSignOutStatus())){
-                //未签退扣除全部课酬
-                deductCost = deductCost.add(teacherSalary.abs());
-                deductReasons.add("未签退扣除全部课酬");
-            }else if(YesOrNoEnum.NO.equals(teacherAttendance.getSignOutStatus())){
-                int signOutCourseTimeBetweenSeconds = DateUtil.secondsBetween(teacherAttendance.getSignOutTime(), courseSchedule.getEndClassTime());
-                float signOutCourseTimeBetween = (float)signOutCourseTimeBetweenSeconds/(float) 60;
-                if(signOutCourseTimeBetween>3){
-                    //早退
-                    deductCost = deductCost.add(teacherSalary.abs());
-                    deductReasons.add("早退扣除全部课酬");
-                }else if((signOutCourseTimeBetween<=3&&signOutCourseTimeBetween>0)||signOutCourseTimeBetween>=3600){
-                    //异常签退,扣除50元
-                    deductCost = deductCost.add(new BigDecimal(50));
-                    deductReasons.add("异常签退,扣除50元");
-                }else{
-                    //签退经纬度异常,扣除50元
-                    deductCost = deductCost.add(new BigDecimal(50));
-                    deductReasons.add("签退经纬度异常,扣除50元");
+            TeacherAttendance teacherAttendance = courseTeacherAttendances.get(0);
+            //获取签到状态
+            TeachModeEnum teachMode = courseScheduleTeacherSalary.getCourseSchedule().getTeachMode();
+            SalarySettlementSignEnum signInStatus = getSignInStatus(teacherAttendance.getSignInTime(), courseSchedule.getStartClassTime(), teachMode,tenantId);
+            BigDecimal signInDeductCost = getSignInDeduce(teacherSalary, signInStatus, teachMode);
+            if(signInDeductCost.compareTo(BigDecimal.ZERO) > 0){
+                deductCost = deductCost.add(signInDeductCost);
+                deductReasons.add("签到状态异常扣除课酬" + signInDeductCost);
+            }
+            SalarySettlementSignEnum signOutStatus = getSignInStatus(teacherAttendance.getSignInTime(), courseSchedule.getStartClassTime(), teachMode,tenantId);
+            BigDecimal signOutDeductCost = getSignInDeduce(teacherSalary, signOutStatus, teachMode);
+            if(signOutDeductCost.compareTo(BigDecimal.ZERO) > 0){
+                deductCost = deductCost.add(signOutDeductCost);
+                deductReasons.add("签退状态异常扣除课酬" + signOutDeductCost);
+            }
+            //经纬度是否正常
+            if(teachMode == TeachModeEnum.OFFLINE){
+                School school = idSchoolMap.get(courseSchedule.getSchoolId());
+                if(school != null){
+                    Boolean signInRange = getSignRange(school.getLongitudeLatitude(),teacherAttendance.getSignInLongitudeLatitude(),attendanceRange);
+                    Boolean signOutRange = getSignRange(school.getLongitudeLatitude(),teacherAttendance.getSignOutLongitudeLatitude(),attendanceRange);
+
+                    if(!signInRange){
+                        String c = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_SIGN_IN_GPS_ERROR_CUT_SALARY, tenantId);
+                        String c1 = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_SIGN_IN_GPS_ERROR_CUT_SALARY_UNIT, tenantId);
+                        BigDecimal signInGpsCutAmount = getCutAmount(c, c1, teacherSalary);
+                        if(signInGpsCutAmount.compareTo(BigDecimal.ZERO) > 0){
+                            deductReasons.add("签到经纬度异常扣除" + signInGpsCutAmount);
+                        }
+                    }
+                    if(!signOutRange){
+                        String c = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_SIGN_OUT_GPS_ERROR_CUT_SALARY, tenantId);
+                        String c1 = sysTenantConfigService.getTenantConfigValue(SysConfigService.OFFLINE_SIGN_OUT_GPS_ERROR_CUT_SALARY_UNIT, tenantId);
+                        BigDecimal signOutGpsCutAmount = getCutAmount(c, c1, teacherSalary);
+                        if(signOutGpsCutAmount.compareTo(BigDecimal.ZERO) > 0){
+                            deductReasons.add("签退经纬度异常扣除" + signOutGpsCutAmount);
+                        }
+                    }
                 }
-            }else{
-                signOutInRange = true;
-            }
-
-            if(!signInInRange&&!signOutInRange){
-                //签到签退GPS定位在指定距离外
-                deductCost = deductCost.add(teacherSalary.abs());
-                deductReasons.add("签到签退GPS定位在指定距离外,扣除全部课酬");
             }
 
             BigDecimal finalSalary = teacherSalary.subtract(deductCost).setScale(BigDecimal.ZERO.intValue(), BigDecimal.ROUND_HALF_UP);
@@ -813,15 +940,16 @@ public class CourseScheduleTeacherSalaryServiceImpl extends BaseServiceImpl<Long
             if(BigDecimal.ZERO.compareTo(deductCost)<0){
                 deductReasons.add("扣除总费用:" + deductCost);
             }
-            if(!CollectionUtils.isEmpty(deductReasons)){
+            if(!CollectionUtils.isEmpty(deductReasons))
                 courseScheduleTeacherSalary.setDeductionReason(org.apache.commons.lang3.StringUtils.join(deductReasons, ";"));
-            }
 
             //更新教师结算信息
             courseScheduleTeacherSalary.setActualSalary(finalSalary.compareTo(BigDecimal.ZERO)<0?BigDecimal.ZERO:finalSalary);
             courseScheduleTeacherSalary.setBelongToDaya(false);
             courseScheduleTeacherSalary.setSettlementTime(now);
-            courseScheduleTeacherSalaryDao.update(courseScheduleTeacherSalary);
+        }
+        if(courseScheduleTeacherSalaries != null && courseScheduleTeacherSalaries.size() > 0){
+            courseScheduleTeacherSalaryDao.batchUpdate(courseScheduleTeacherSalaries);
         }
     }
 

+ 1 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/SysConfigServiceImpl.java

@@ -35,6 +35,7 @@ public class SysConfigServiceImpl extends BaseServiceImpl<Long, SysConfig>  impl
     @Override
     public void batchUpdate(List<SysConfig> configList) {
 		sysConfigDao.batchUpdate(configList);
+		applicationEventPublisher.publishEvent(new TenantConfigChangeEvent(this));
     }
 
 	@Override

+ 1 - 1
mec-biz/src/main/resources/config/mybatis/CourseScheduleTeacherSalaryMapper.xml

@@ -335,7 +335,7 @@
 		<if test="startDate != null">
 			AND cs.class_date_ BETWEEN #{startDate} AND #{endDate}
 		</if>
-		AND cs.type_ = 'PRACTICE'
+		AND cs.type_ = #{groupType}
 		AND csts.settlement_time_ IS NULL
 		AND (cs.del_flag_ IS NULL OR cs.del_flag_=0)
     </select>

+ 9 - 0
mec-web/src/main/java/com/ym/mec/web/controller/SysConfigController.java

@@ -49,6 +49,15 @@ public class SysConfigController extends BaseController {
 		return succeed();
 	}
 
+	@ApiOperation(value = "修改参数")
+	@PostMapping(value = "batchUpdate")
+    @PreAuthorize("@pcs.hasPermissions('sysConfig/batchUpdate')")
+	@AuditLogAnnotation(operateName = "修改参数")
+	public Object batchUpdate(@RequestBody List<SysConfig> configList) {
+		sysConfigService.batchUpdate(configList);
+		return succeed();
+	}
+
 	@ApiOperation(value = "新增参数")
 	@PostMapping(value = "add")
     @PreAuthorize("@pcs.hasPermissions('sysConfig/add')")