Bläddra i källkod

feat:VIP课活动增加课程数量限制范围

Joburgess 4 år sedan
förälder
incheckning
fa4a6592b9

+ 11 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CourseScheduleTeacherSalaryDao.java

@@ -532,4 +532,15 @@ public interface CourseScheduleTeacherSalaryDao extends BaseDAO<Long, CourseSche
 	 */
 	List<CourseScheduleTeacherSalary> getIsSalaryWithDate(@Param("startDate") String startDate, @Param("endDate") String endDate);
 
+	/**
+	 * @describe 获取教师收入总览
+	 * @author Joburgess
+	 * @date 2021/4/16 0016
+	 * @param teacherId:
+	 * @param monthStr:
+	 * @return com.ym.mec.biz.dal.dto.TeacherIncomeDto
+	 */
+	TeacherIncomeDto getTeacherSalaryOverview(@Param("teacherId") Integer teacherId,
+											  @Param("monthStr") String monthStr);
+
 }

+ 22 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/VipGroupActivity.java

@@ -80,6 +80,28 @@ public class VipGroupActivity {
 	@ApiModelProperty(value = "线下课是否参与梯度奖励")
 	private Integer offlineClassJoinGradientRewards;
 
+	@ApiModelProperty(value = "最少课程数量")
+	private Integer minCourseNum;
+
+	@ApiModelProperty(value = "最多可排课数量")
+	private Integer maxCourseNum;
+
+	public Integer getMinCourseNum() {
+		return minCourseNum;
+	}
+
+	public void setMinCourseNum(Integer minCourseNum) {
+		this.minCourseNum = minCourseNum;
+	}
+
+	public Integer getMaxCourseNum() {
+		return maxCourseNum;
+	}
+
+	public void setMaxCourseNum(Integer maxCourseNum) {
+		this.maxCourseNum = maxCourseNum;
+	}
+
 	public Integer getOnlineClassJoinGradientRewards() {
 		return onlineClassJoinGradientRewards;
 	}

+ 43 - 4
mec-biz/src/main/java/com/ym/mec/biz/service/CourseScheduleTeacherSalaryService.java

@@ -1,10 +1,7 @@
 package com.ym.mec.biz.service;
 
 import com.ym.mec.biz.dal.dto.*;
-import com.ym.mec.biz.dal.entity.CourseSchedule;
-import com.ym.mec.biz.dal.entity.CourseScheduleTeacherSalary;
-import com.ym.mec.biz.dal.entity.MusicGroup;
-import com.ym.mec.biz.dal.entity.VipGroup;
+import com.ym.mec.biz.dal.entity.*;
 import com.ym.mec.biz.dal.page.CourseSalaryQueryInfo4Web;
 import com.ym.mec.biz.dal.page.CourseScheduleTeacherSalaryQueryInfo;
 import com.ym.mec.biz.dal.page.ExportTeacherSalaryQueryInfo;
@@ -217,5 +214,47 @@ public interface CourseScheduleTeacherSalaryService extends BaseService<Long, Co
      */
     List<BigDecimal> salaryComposition(List<BigDecimal> salaries, BigDecimal targetSalary);
 
+    /**
+     * @describe 计算乐团课教师实际课酬
+     * @author Joburgess
+     * @date 2021/4/16 0016
+     * @param courseScheduleTeacherSalary:
+     * @param teacherAttendances:
+     * @return void
+     */
+    void calMusicCourseTeacherActualSalary(CourseSchedule courseSchedule, CourseScheduleTeacherSalary courseScheduleTeacherSalary,
+                                           List<TeacherAttendance> teacherAttendances, School school, Teacher teacher, double attendanceRange);
+
+    /**
+     * @describe 计算VIP课教师实际课酬
+     * @author Joburgess
+     * @date 2021/4/16 0016
+     * @param courseScheduleTeacherSalary:
+     * @param teacherAttendances:
+     * @return void
+     */
+    void calVipCourseTeacherActualSalary(CourseSchedule courseSchedule, CourseScheduleTeacherSalary courseScheduleTeacherSalary,
+                                         List<TeacherAttendance> teacherAttendances, School school, Teacher teacher, double attendanceRange);
+
+    /**
+     * @describe 计算网管课教师实际课酬
+     * @author Joburgess
+     * @date 2021/4/16 0016
+     * @param courseScheduleTeacherSalary:
+     * @param teacherAttendances:
+     * @return void
+     */
+    void calPracticeTeacherActualSalary(CourseSchedule courseSchedule, CourseScheduleTeacherSalary courseScheduleTeacherSalary,
+                                        List<TeacherAttendance> teacherAttendances, School school, Teacher teacher);
+
+    /**
+     * @describe
+     * @author Joburgess
+     * @date 2021/4/16 0016
+     * @param teacherId: 获取教师收入总览
+     * @return com.ym.mec.biz.dal.dto.TeacherIncomeDto
+     */
+    TeacherIncomeDto getTeacherSalaryOverview(Integer teacherId);
+
     void queryTeacherIncomeList(QueryInfo queryInfo);
 }

+ 403 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleTeacherSalaryServiceImpl.java

@@ -1481,6 +1481,409 @@ public class CourseScheduleTeacherSalaryServiceImpl extends BaseServiceImpl<Long
     }
 
     @Override
+    public void calMusicCourseTeacherActualSalary(CourseSchedule courseSchedule, CourseScheduleTeacherSalary courseScheduleTeacherSalary,
+                                                  List<TeacherAttendance> teacherAttendances, School school, Teacher teacher, double attendanceRange) {
+
+        BigDecimal teacherSalary = courseScheduleTeacherSalary.getExpectSalary();
+
+        if(CourseSchedule.CourseScheduleType.MUSIC_NETWORK.equals(courseSchedule.getType())||CourseSchedule.CourseScheduleType.HIGH_ONLINE.equals(courseSchedule.getType())){
+            List<String> deductReasons = new ArrayList<>();
+
+            BigDecimal subsidy = school.getSubsidy();
+            if (Objects.isNull(subsidy)) {
+                subsidy = new BigDecimal(0);
+            }
+            if (Objects.isNull(subsidy)) {
+                subsidy = new BigDecimal(0);
+            }
+            teacherSalary = teacherSalary.add(subsidy);
+            if(BigDecimal.ZERO.compareTo(subsidy)!=0){
+                deductReasons.add("教学点补贴:" + subsidy);
+            }
+
+            //判断课程是否在试用期内
+            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"));
+                deductReasons.add("未转正");
+            }
+
+            //扣除费用
+            BigDecimal deductCost = new BigDecimal(0);
+
+            TeacherAttendance teacherAttendance = teacherAttendances.get(0);
+            if(CollectionUtils.isEmpty(teacherAttendances)||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(teacherAttendances)||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);
+            }
+
+            //更新教师结算信息
+            courseScheduleTeacherSalary.setSubsidy(subsidy);
+            courseScheduleTeacherSalary.setActualSalary(finalSalary.compareTo(BigDecimal.ZERO)<0?BigDecimal.ZERO:finalSalary);
+        }else{
+            List<String> deductReasons = new ArrayList<>();
+
+            BigDecimal subsidy = school.getSubsidy();
+            if (Objects.isNull(subsidy)) {
+                subsidy = new BigDecimal(0);
+            }
+            teacherSalary = teacherSalary.add(subsidy);
+            if(BigDecimal.ZERO.compareTo(subsidy)!=0){
+                deductReasons.add("教学点补贴:" + subsidy);
+            }
+
+            //判断课程是否在试用期内
+            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"));
+                deductReasons.add("未转正");
+            }
+
+            //扣除费用
+            BigDecimal deductCost = BigDecimal.ZERO;
+
+            TeacherAttendance teacherAttendance = null;
+            if(!CollectionUtils.isEmpty(teacherAttendances)){
+                teacherAttendance = teacherAttendances.get(0);
+            }
+
+            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("未签到扣除全部课酬");
+            }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;
+            }
+
+            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元");
+                }
+            }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);
+
+            if(BigDecimal.ZERO.compareTo(deductCost)<0){
+                deductReasons.add("扣除总费用:" + deductCost);
+            }
+
+            //更新教师结算信息
+            courseScheduleTeacherSalary.setSubsidy(subsidy);
+            courseScheduleTeacherSalary.setActualSalary(finalSalary.compareTo(BigDecimal.ZERO)<0?BigDecimal.ZERO:finalSalary);
+        }
+    }
+
+    @Override
+    public void calVipCourseTeacherActualSalary(CourseSchedule courseSchedule, CourseScheduleTeacherSalary courseScheduleTeacherSalary,
+                                                List<TeacherAttendance> teacherAttendances, School school, Teacher teacher, double attendanceRange) {
+        List<String> deductReasons = new ArrayList<>();
+
+        BigDecimal expectSalary = courseScheduleTeacherSalary.getExpectSalary();
+
+        BigDecimal subsidy = school.getSubsidy();
+        if (Objects.isNull(subsidy)) {
+            subsidy = new BigDecimal(0);
+        }
+        courseScheduleTeacherSalary.setSubsidy(subsidy);
+        expectSalary = expectSalary.add(subsidy);
+        if(BigDecimal.ZERO.compareTo(subsidy)!=0){
+            deductReasons.add("教学点补贴:" + subsidy);
+        }
+
+        //判断课程是否在试用期内
+        boolean trail = false;
+
+        if(Objects.nonNull(teacher)&&Objects.nonNull(teacher.getEntryDate())&&courseScheduleTeacherSalary.getCourseSchedule().getClassDate().compareTo(teacher.getEntryDate())>=0){
+            trail = true;
+        }
+        if(Objects.nonNull(teacher)&&Objects.nonNull(teacher.getFormalStaffDate())&&courseScheduleTeacherSalary.getCourseSchedule().getClassDate().compareTo(teacher.getFormalStaffDate())>=0){
+            trail = false;
+        }
+
+        //如果上课日期在试用期内按80%结算
+        if(trail){
+            expectSalary = expectSalary.multiply(new BigDecimal("0.8"));
+            deductReasons.add("未转正");
+        }
+
+        //扣除费用
+        BigDecimal deductCost = new BigDecimal(0);
+
+        if(CollectionUtils.isEmpty(teacherAttendances)||Objects.isNull(teacherAttendances.get(0).getSignInStatus())){
+            //未签到扣除全部课酬
+            deductCost = deductCost.add(expectSalary.abs());
+            deductReasons.add("未签到扣除全部课酬");
+        }else if(YesOrNoEnum.NO.equals(teacherAttendances.get(0).getSignInStatus())&&TeachModeEnum.ONLINE.equals(courseScheduleTeacherSalary.getCourseSchedule().getTeachMode())){
+            //异常签到
+            int signCourseTimeBetweenSeconds = DateUtil.secondsBetween(teacherAttendances.get(0).getSignInTime(), courseScheduleTeacherSalary.getCourseSchedule().getStartClassTime());
+            float signCourseTimeBetween = (float)signCourseTimeBetweenSeconds/(float)60;
+            if(signCourseTimeBetween<=1&&signCourseTimeBetween>-3){
+                //课程开始前1分钟至开始后3分钟进入教室
+                deductCost = deductCost.add(expectSalary.divide(new BigDecimal(2)).abs());
+                deductReasons.add("课程开始前1分钟至开始后3分钟进入教室扣除一半课酬");
+            }else if(signCourseTimeBetween<=-3){
+                //课程开始后3分钟后进入教室
+                deductCost = deductCost.add(expectSalary.abs());
+                deductReasons.add("课程开始后3分钟进入教室扣除全部课酬");
+            }
+        }else if(YesOrNoEnum.NO.equals(teacherAttendances.get(0).getSignInStatus())&&TeachModeEnum.OFFLINE.equals(courseScheduleTeacherSalary.getCourseSchedule().getTeachMode())){
+            deductCost = deductCost.add(expectSalary.abs());
+            deductReasons.add("点名时经纬度不在范围内扣除全部课酬");
+        }
+
+        if(CollectionUtils.isEmpty(teacherAttendances)||Objects.isNull(teacherAttendances.get(0).getSignOutStatus())){
+            //未签退扣除全部课酬
+            deductCost = deductCost.add(expectSalary.abs());
+            deductReasons.add("未签退扣除全部课酬");
+        }else if(YesOrNoEnum.NO.equals(teacherAttendances.get(0).getSignOutStatus())&&TeachModeEnum.ONLINE.equals(courseScheduleTeacherSalary.getCourseSchedule().getTeachMode())){
+            //异常签退
+            int signOutCourseTimeBetweenSeconds = DateUtil.secondsBetween(teacherAttendances.get(0).getSignOutTime(), courseScheduleTeacherSalary.getCourseSchedule().getEndClassTime());
+            float signOutCourseTimeBetween = (float)signOutCourseTimeBetweenSeconds/(float)60;
+
+            if(signOutCourseTimeBetween>3){
+                //课程开始前20分钟至开始后3分钟退出教室
+                deductCost = deductCost.add(expectSalary.abs());
+                deductReasons.add("课程结束前3分钟之前退出教室扣除全部课酬");
+            }else if(signOutCourseTimeBetween<=3&&signOutCourseTimeBetween>0){
+                //课程结束前3分钟后至课程结束前退出教室
+                deductCost = deductCost.add(expectSalary.divide(new BigDecimal(2)).abs());
+                deductReasons.add("课程结束前3分钟后至课程结束前退出教室扣除一半课酬");
+            }
+        }else if(YesOrNoEnum.NO.equals(teacherAttendances.get(0).getSignInStatus())&&TeachModeEnum.OFFLINE.equals(courseScheduleTeacherSalary.getCourseSchedule().getTeachMode())){
+            deductCost = deductCost.add(expectSalary.abs());
+            deductReasons.add("点名时经纬度不在范围内扣除全部课酬");
+        }
+
+        if(BigDecimal.ZERO.compareTo(deductCost)<0){
+            deductReasons.add("扣除总费用:" + deductCost);
+        }
+
+        BigDecimal finalSalary = expectSalary.subtract(deductCost).setScale(BigDecimal.ZERO.intValue(), BigDecimal.ROUND_HALF_UP);
+        courseScheduleTeacherSalary.setActualSalary(finalSalary.compareTo(BigDecimal.ZERO)<0?BigDecimal.ZERO:finalSalary);
+    }
+
+    @Override
+    public void calPracticeTeacherActualSalary(CourseSchedule courseSchedule, CourseScheduleTeacherSalary courseScheduleTeacherSalary,
+                                               List<TeacherAttendance> teacherAttendances, School school, Teacher teacher) {
+        List<String> deductReasons = new ArrayList<>();
+
+        BigDecimal expectSalary = courseScheduleTeacherSalary.getExpectSalary();
+
+        BigDecimal subsidy = school.getSubsidy();
+        if (Objects.isNull(subsidy)) {
+            subsidy = new BigDecimal(0);
+        }
+        courseScheduleTeacherSalary.setSubsidy(subsidy);
+        expectSalary = expectSalary.add(subsidy);
+
+        if(BigDecimal.ZERO.compareTo(subsidy)!=0){
+            deductReasons.add("教学点补贴:" + subsidy);
+        }
+
+        //判断课程是否在试用期内
+        boolean trail = false;
+
+        if(Objects.nonNull(teacher)&&Objects.nonNull(teacher.getEntryDate())&&courseScheduleTeacherSalary.getCourseSchedule().getClassDate().compareTo(teacher.getEntryDate())>=0){
+            trail = true;
+        }
+        if(Objects.nonNull(teacher)&&Objects.nonNull(teacher.getFormalStaffDate())&&courseScheduleTeacherSalary.getCourseSchedule().getClassDate().compareTo(teacher.getFormalStaffDate())>=0){
+            trail = false;
+        }
+
+        //如果上课日期在试用期内按80%结算
+        if(trail){
+            expectSalary = expectSalary.multiply(new BigDecimal("0.8"));
+            deductReasons.add("未转正");
+        }
+
+        //扣除费用
+        BigDecimal deductCost = new BigDecimal(0);
+
+        TeacherAttendance teacherAttendance = null;
+        if(!CollectionUtils.isEmpty(teacherAttendances)){
+            teacherAttendance = teacherAttendances.get(0);
+        }
+        if(CollectionUtils.isEmpty(teacherAttendances)||Objects.isNull(teacherAttendance.getSignInStatus())){
+            //未签到扣除全部课酬
+            deductCost = deductCost.add(expectSalary.abs());
+            deductReasons.add("未签到扣除全部课酬");
+        }else if(YesOrNoEnum.NO.equals(teacherAttendance.getSignInStatus())){
+            //异常签到
+            int signCourseTimeBetweenSeconds = DateUtil.secondsBetween(teacherAttendance.getSignInTime(), courseScheduleTeacherSalary.getCourseSchedule().getStartClassTime());
+            float signCourseTimeBetween = (float)signCourseTimeBetweenSeconds/(float)60;
+            if(signCourseTimeBetween<=1&&signCourseTimeBetween>-3){
+                //课程开始前1分钟至开始后3分钟进入教室
+                deductCost = deductCost.add(expectSalary.divide(new BigDecimal(2)).abs());
+                deductReasons.add("课程开始前1分钟至开始后3分钟进入教室扣除一半课酬");
+            }else if(signCourseTimeBetween<=-3){
+                //课程开始后3分钟后进入教室
+                deductCost = deductCost.add(expectSalary.abs());
+                deductReasons.add("课程开始后3分钟进入教室扣除全部课酬");
+            }
+        }
+
+        if(CollectionUtils.isEmpty(teacherAttendances)||Objects.isNull(teacherAttendance.getSignOutStatus())){
+            //未签退扣除全部课酬
+            deductCost = deductCost.add(expectSalary.abs());
+            deductReasons.add("未签退扣除全部课酬");
+        }else if(YesOrNoEnum.NO.equals(teacherAttendance.getSignOutStatus())){
+            //异常签退
+            int signOutCourseTimeBetweenSeconds = DateUtil.secondsBetween(teacherAttendance.getSignOutTime(), courseScheduleTeacherSalary.getCourseSchedule().getEndClassTime());
+            float signOutCourseTimeBetween = (float)signOutCourseTimeBetweenSeconds/(float)60;
+
+            if(signOutCourseTimeBetween>3){
+                //课程开始前20分钟至开始后3分钟退出教室
+                deductCost = deductCost.add(expectSalary.abs());
+                deductReasons.add("课程结束前3分钟之前退出教室扣除全部课酬");
+            }else if(signOutCourseTimeBetween<=3&&signOutCourseTimeBetween>0){
+                //课程结束前3分钟后至课程结束前退出教室
+                deductCost = deductCost.add(expectSalary.divide(new BigDecimal(2)).abs());
+                deductReasons.add("课程结束前3分钟后至课程结束前退出教室扣除一半课酬");
+            }
+        }
+
+        BigDecimal finalSalary = expectSalary.subtract(deductCost).setScale(BigDecimal.ZERO.intValue(), BigDecimal.ROUND_HALF_UP);
+
+        if(BigDecimal.ZERO.compareTo(deductCost)<0){
+            deductReasons.add("扣除总费用:" + deductCost);
+        }
+
+        courseScheduleTeacherSalary.setActualSalary(finalSalary.compareTo(BigDecimal.ZERO)<0?BigDecimal.ZERO:finalSalary);
+    }
+
+    @Override
+    public TeacherIncomeDto getTeacherSalaryOverview(Integer teacherId) {
+        Date now = new Date();
+        String monthStr = DateUtil.dateToString(now, "yyyy-MM");
+        TeacherIncomeDto teacherSalaryOverview = courseScheduleTeacherSalaryDao.getTeacherSalaryOverview(teacherId, monthStr);
+
+//        courseScheduleDao.findTeacherCoursesWithDateRangeWithoutMusicGroup()
+
+        return teacherSalaryOverview;
+    }
+
+    @Override
     public void queryTeacherIncomeList(QueryInfo queryInfo) {
         
     }

+ 3 - 4
mec-biz/src/main/java/com/ym/mec/biz/service/impl/VipGroupServiceImpl.java

@@ -260,11 +260,10 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 			}
 		}
 
-		if(Objects.nonNull(vipGroupActivity)&&Objects.nonNull(vipGroupActivity.getAttribute3())&&StringUtils.isNotBlank(vipGroupActivity.getAttribute3())){
-			Integer maxCourseNum = Integer.parseInt(vipGroupActivity.getAttribute3());
+		if(Objects.nonNull(vipGroupActivity)&&Objects.nonNull(vipGroupActivity.getMinCourseNum())&&Objects.nonNull(vipGroupActivity.getMaxCourseNum())){
 			Integer requestCourseNum = vipGroupApplyBaseInfoDto.getOnlineClassesNum() + vipGroupApplyBaseInfoDto.getOfflineClassesNum();
-			if(requestCourseNum.compareTo(maxCourseNum)!=0){
-				throw new BizException("该活动课时数为{}节", maxCourseNum);
+			if(requestCourseNum.compareTo(vipGroupActivity.getMinCourseNum())>=0&&requestCourseNum.compareTo(vipGroupActivity.getMaxCourseNum())<=0){
+				throw new BizException("该活动课时数为{}节~{}节", vipGroupActivity.getMinCourseNum(), vipGroupActivity.getMaxCourseNum());
 			}
 		}
 

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

@@ -1072,4 +1072,15 @@
 		  AND ( cs.del_flag_ IS NULL OR cs.del_flag_ = 0 )
 		  AND csts.settlement_time_ IS NOT NULL
 	</select>
+
+    <select id="getTeacherSalaryOverview" resultType="com.ym.mec.biz.dal.dto.TeacherIncomeDto">
+		SELECT
+			SUM(csts.expect_salary_) totalIncome,
+			SUM(CASE DATE_FORMAT(cs.class_date_, '%Y-%m') WHEN #{monthStr} THEN csts.expect_salary_ ELSE 0 END) thisMonthExpectIncome
+		FROM
+			course_schedule_teacher_salary csts
+				LEFT JOIN course_schedule cs ON csts.course_schedule_id_ = cs.id_
+		WHERE
+			csts.user_id_ = #{teacherId}
+	</select>
 </mapper>

+ 35 - 22
mec-biz/src/main/resources/config/mybatis/VipGroupActivityMapper.xml

@@ -31,6 +31,8 @@
 		<result property="delFlag" column="del_flag_"/>
 		<result property="onlineClassJoinGradientRewards" column="online_class_join_gradient_rewards_"/>
 		<result property="offlineClassJoinGradientRewards" column="offline_class_join_gradient_rewards_"/>
+		<result property="minCourseNum" column="min_course_num_"/>
+		<result property="maxCourseNum" column="max_course_num_"/>
 	</resultMap>
 	
 	<!-- 根据主键查询一条记录 -->
@@ -50,66 +52,71 @@
 		SELECT SEQ_WSDEFINITION_ID.nextval AS ID FROM DUAL 
 		</selectKey>
 		-->
-		INSERT INTO vip_group_activity (id_,name_,description_,vip_group_category_id_list_,start_time_,end_time_,organ_id_,courses_start_time_,courses_end_time_,type_,attribute1_,attribute2_,attribute3_,salary_readonly_flag_,give_class_pay_salary_flag_,create_time_,update_time_,salary_settlement_json_,del_flag_,payment_readonly_flag_,online_class_join_gradient_rewards_,offline_class_join_gradient_rewards_)
-		VALUES(#{id},#{name},#{description},#{vipGroupCategoryIdList},#{startTime},#{endTime},#{organId},#{coursesStartTime},#{coursesEndTime},#{type},#{attribute1},#{attribute2},#{attribute3},#{salaryReadonlyFlag},#{giveClassPaySalaryFlag},now(),now(),#{salarySettlementJson},#{delFlag},#{paymentReadonlyFlag},#{onlineClassJoinGradientRewards},#{offlineClassJoinGradientRewards})
+		INSERT INTO vip_group_activity (id_,name_,description_,vip_group_category_id_list_,start_time_,end_time_,organ_id_,courses_start_time_,courses_end_time_,type_,
+		                                attribute1_,attribute2_,attribute3_,salary_readonly_flag_,give_class_pay_salary_flag_,create_time_,update_time_,salary_settlement_json_,del_flag_,
+		                                payment_readonly_flag_,online_class_join_gradient_rewards_,offline_class_join_gradient_rewards_,min_course_num_,max_course_num_)
+		VALUES(#{id},#{name},#{description},#{vipGroupCategoryIdList},#{startTime},#{endTime},#{organId},#{coursesStartTime},#{coursesEndTime},#{type},#{attribute1},#{attribute2},#{attribute3},
+		       #{salaryReadonlyFlag},#{giveClassPaySalaryFlag},now(),now(),#{salarySettlementJson},#{delFlag},#{paymentReadonlyFlag},#{onlineClassJoinGradientRewards},
+		       #{offlineClassJoinGradientRewards},#{minCourseNum},#{maxCourseNum})
 	</insert>
 	
 	<!-- 根据主键查询一条记录 -->
 	<update id="update" parameterType="com.ym.mec.biz.dal.entity.VipGroupActivity">
-		UPDATE vip_group_activity <set>
+		UPDATE vip_group_activity
+		<set>
 			<if test="salaryReadonlyFlag != null">
-			salary_readonly_flag_ = #{salaryReadonlyFlag},
+				salary_readonly_flag_ = #{salaryReadonlyFlag},
 			</if>
 			<if test="organId != null">
-			organ_id_ = #{organId},
+				organ_id_ = #{organId},
 			</if>
 			<if test="id != null">
-			id_ = #{id},
+				id_ = #{id},
 			</if>
 			<if test="giveClassPaySalaryFlag != null">
-			give_class_pay_salary_flag_ = #{giveClassPaySalaryFlag},
+				give_class_pay_salary_flag_ = #{giveClassPaySalaryFlag},
 			</if>
 			<if test="coursesEndTime != null">
-			courses_end_time_ = #{coursesEndTime},
+				courses_end_time_ = #{coursesEndTime},
 			</if>
 			<if test="attribute1 != null">
-			attribute1_ = #{attribute1},
+				attribute1_ = #{attribute1},
 			</if>
 			<if test="endTime != null">
-			end_time_ = #{endTime},
+				end_time_ = #{endTime},
 			</if>
 			<if test="attribute2 != null">
-			attribute2_ = #{attribute2},
+				attribute2_ = #{attribute2},
 			</if>
 			<if test="name != null">
-			name_ = #{name},
+				name_ = #{name},
 			</if>
 			<if test="startTime != null">
-			start_time_ = #{startTime},
+				start_time_ = #{startTime},
 			</if>
 			<if test="attribute3 != null">
-			attribute3_ = #{attribute3},
+				attribute3_ = #{attribute3},
 			</if>
 			<if test="createTime != null">
-			create_time_ = #{createTime},
+				create_time_ = #{createTime},
 			</if>
 			<if test="vipGroupCategoryIdList != null">
-			vip_group_category_id_list_ = #{vipGroupCategoryIdList},
+				vip_group_category_id_list_ = #{vipGroupCategoryIdList},
 			</if>
 			<if test="description != null">
-			description_ = #{description},
+				description_ = #{description},
 			</if>
 			<if test="salarySettlementJson != null">
-			salary_settlement_json_ = #{salarySettlementJson},
+				salary_settlement_json_ = #{salarySettlementJson},
 			</if>
 			<if test="coursesStartTime != null">
-			courses_start_time_ = #{coursesStartTime},
+				courses_start_time_ = #{coursesStartTime},
 			</if>
 			<if test="type != null">
-			type_ = #{type},
+				type_ = #{type},
 			</if>
 			<if test="delFlag != null">
-			del_flag_ = #{delFlag},
+				del_flag_ = #{delFlag},
 			</if>
 			<if test="paymentReadonlyFlag != null">
 				payment_readonly_flag_ = #{paymentReadonlyFlag},
@@ -120,8 +127,14 @@
 			<if test="offlineClassJoinGradientRewards!=null">
 				offline_class_join_gradient_rewards_=#{offlineClassJoinGradientRewards},
 			</if>
+			<if test="minCourseNum!=null">
+				min_course_num_=#{minCourseNum},
+			</if>
+			<if test="maxCourseNum!=null">
+				max_course_num_=#{maxCourseNum},
+			</if>
 			update_time_ = NOW(),
-			</set> WHERE id_ = #{id}
+		</set>WHERE id_ = #{id}
 	</update>
 
 	<!-- 根据主键删除一条记录 -->