|
@@ -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);
|
|
|
}
|
|
|
}
|
|
|
|