|
@@ -7,6 +7,7 @@ import com.ym.mec.biz.service.*;
|
|
|
import com.ym.mec.common.dal.BaseDAO;
|
|
|
import com.ym.mec.common.exception.BizException;
|
|
|
import com.ym.mec.common.service.impl.BaseServiceImpl;
|
|
|
+import com.ym.mec.util.collection.MapUtil;
|
|
|
import com.ym.mec.util.date.DateUtil;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
@@ -20,235 +21,364 @@ import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
@Service
|
|
|
-public class CourseScheduleTeacherSalaryServiceImpl extends BaseServiceImpl<Long, CourseScheduleTeacherSalary> implements CourseScheduleTeacherSalaryService {
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private CourseScheduleTeacherSalaryDao courseScheduleTeacherSalaryDao;
|
|
|
- @Autowired
|
|
|
- private VipGroupActivityDao vipGroupActivityDao;
|
|
|
- @Autowired
|
|
|
- private CourseScheduleComplaintsDao courseScheduleComplaintsDao;
|
|
|
- @Autowired
|
|
|
- private CourseScheduleStudentPaymentDao courseScheduleStudentPaymentDao;
|
|
|
- @Autowired
|
|
|
- private SysUserCashAccountService sysUserCashAccountService;
|
|
|
- @Autowired
|
|
|
- private VipGroupService vipGroupService;
|
|
|
- @Autowired
|
|
|
- private SchoolService schoolService;
|
|
|
- @Autowired
|
|
|
- private CourseScheduleDao courseScheduleDao;
|
|
|
- @Autowired
|
|
|
- private TeacherDefaultMusicGroupSalaryDao teacherDefaultMusicGroupSalaryDao;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private SysConfigDao sysConfigDao;
|
|
|
-
|
|
|
- private static final Logger LOGGER = LoggerFactory
|
|
|
- .getLogger(CourseScheduleTeacherSalaryServiceImpl.class);
|
|
|
-
|
|
|
- @Override
|
|
|
- public BaseDAO<Long, CourseScheduleTeacherSalary> getDAO() {
|
|
|
- return courseScheduleTeacherSalaryDao;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public int createCourseScheduleTeacherVipSalary(VipGroup vipGroup,
|
|
|
- List<CourseSchedule> vipCourseSchedules,
|
|
|
- BigDecimal onlineTeacherSalary,
|
|
|
- BigDecimal offlineTeacherSalary) {
|
|
|
-
|
|
|
- School school = schoolService.get(vipGroup.getTeacherSchoolId());
|
|
|
- if(Objects.isNull(school)){
|
|
|
- throw new BizException("未找到该教学点");
|
|
|
- }
|
|
|
-
|
|
|
- //获取活动信息
|
|
|
- VipGroupActivity vipGroupActivity = vipGroupActivityDao.get(vipGroup.getVipGroupActivityId().intValue());
|
|
|
-
|
|
|
- List<CourseScheduleTeacherSalary> courseScheduleTeacherSalaries=new ArrayList<>();
|
|
|
- Map<TeachModeEnum, List<CourseSchedule>> courseScheduleGroupByTeachMode = vipCourseSchedules.stream().collect(Collectors.groupingBy(CourseSchedule::getTeachMode));
|
|
|
-
|
|
|
- for(TeachModeEnum teachModeEnum:courseScheduleGroupByTeachMode.keySet()){
|
|
|
- List<CourseSchedule> courseSchedules = courseScheduleGroupByTeachMode.get(teachModeEnum)
|
|
|
- .stream()
|
|
|
- .sorted(Comparator.comparing(CourseSchedule::getStartClassTime)).collect(Collectors.toList());
|
|
|
- for(int i=0;i<courseSchedules.size();i++){
|
|
|
- //创建教师课程薪水记录
|
|
|
- CourseScheduleTeacherSalary courseScheduleTeacherSalary=new CourseScheduleTeacherSalary();
|
|
|
- courseScheduleTeacherSalary.setCourseScheduleId(courseSchedules.get(i).getId());
|
|
|
- courseScheduleTeacherSalary.setTeacherRole(TeachTypeEnum.BISHOP);
|
|
|
- courseScheduleTeacherSalary.setUserId(courseSchedules.get(i).getActualTeacherId().intValue());
|
|
|
- courseScheduleTeacherSalary.setClassGroupId(courseSchedules.get(i).getClassGroupId());
|
|
|
- courseScheduleTeacherSalary.setSubsidy(school.getSubsidy());
|
|
|
-
|
|
|
- Map<String,BigDecimal> feeInfo = vipGroupService.countVipGroupPredictFee(vipGroup,
|
|
|
- courseSchedules.get(i).getActualTeacherId().intValue(),
|
|
|
- onlineTeacherSalary,
|
|
|
- offlineTeacherSalary,
|
|
|
- false,
|
|
|
- false);
|
|
|
-
|
|
|
- if(vipGroupActivity.getType()== VipGroupActivityTypeEnum.GIVE_CLASS
|
|
|
- &&vipGroup.getGiveTeachMode()==teachModeEnum
|
|
|
- &&i>=Integer.parseInt(vipGroupActivity.getAttribute1())
|
|
|
- &&"0".equals(vipGroupActivity.getGiveClassPaySalaryFlag())){
|
|
|
- courseScheduleTeacherSalary.setExpectSalary(new BigDecimal(0));
|
|
|
- }else {
|
|
|
- if(teachModeEnum==TeachModeEnum.ONLINE){
|
|
|
- courseScheduleTeacherSalary.setExpectSalary(feeInfo.get("onlineTeacherSalary"));
|
|
|
- }else{
|
|
|
- courseScheduleTeacherSalary.setExpectSalary(feeInfo.get("offlineTeacherSalary"));
|
|
|
- }
|
|
|
- }
|
|
|
- courseScheduleTeacherSalaries.add(courseScheduleTeacherSalary);
|
|
|
- }
|
|
|
- }
|
|
|
- return courseScheduleTeacherSalaryDao.batchInsert(courseScheduleTeacherSalaries);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- @Transactional(rollbackFor = Exception.class)
|
|
|
- public void teacherSalarySettlement() {
|
|
|
-
|
|
|
- int days = Integer.parseInt(sysConfigDao.findConfigValue(SysConfigService.VIP_SETTLEMENT_CYCLE));
|
|
|
-
|
|
|
- //获取教师未结算课程记录
|
|
|
- List<CourseScheduleTeacherSalary> someDayAgoTeacherCourseSalaryNoSettlement = courseScheduleTeacherSalaryDao.findSomeDayAgoTeacherCourseSalaryNoSettlement(days);
|
|
|
- if(CollectionUtils.isEmpty(someDayAgoTeacherCourseSalaryNoSettlement)){
|
|
|
- LOGGER.info("未获取到未结算课酬记录!");
|
|
|
- return;
|
|
|
- }
|
|
|
- Date now=new Date();
|
|
|
- //获取未结算课程编号列表
|
|
|
- List<Long> courseScheduleIds = someDayAgoTeacherCourseSalaryNoSettlement.stream().map(CourseScheduleTeacherSalary::getCourseScheduleId).collect(Collectors.toList());
|
|
|
- //获取未结算课程投诉记录
|
|
|
- List<CourseScheduleComplaints> courseScheduleComplaints = courseScheduleComplaintsDao.findByCourseScheduleIds(courseScheduleIds);
|
|
|
- //获取未结算课程学生缴费信息
|
|
|
- List<CourseScheduleStudentPayment> courseScheduleStudentPayments = courseScheduleStudentPaymentDao.findByCourseScheduleIds(courseScheduleIds);
|
|
|
-
|
|
|
- //根据课程将投诉信息分组
|
|
|
- Map<Long, List<CourseScheduleComplaints>> complaintsGroupByCourse = courseScheduleComplaints.stream().collect(Collectors.groupingBy(CourseScheduleComplaints::getCourseScheduleId));
|
|
|
- //根据课程将学生缴费信息分组
|
|
|
- Map<Long, List<CourseScheduleStudentPayment>> studentPaymentGroupByCourse = courseScheduleStudentPayments.stream().collect(Collectors.groupingBy(CourseScheduleStudentPayment::getCourseScheduleId));
|
|
|
-
|
|
|
- //需更新教师课程结算记录
|
|
|
- List<CourseScheduleTeacherSalary> updateTeacherSalarys=new ArrayList<>();
|
|
|
- //需更新学生课程缴费记录
|
|
|
- List<CourseScheduleStudentPayment> updateStudentPayments=new ArrayList<>();
|
|
|
-
|
|
|
- //用户账户自己变动信息列表
|
|
|
- List<SysUserCashAccountDetail> userCashAccountDetails=new ArrayList<>();
|
|
|
-
|
|
|
- //处理课酬信息
|
|
|
- someDayAgoTeacherCourseSalaryNoSettlement.forEach(courseScheduleTeacherSalary -> {
|
|
|
- //获取当前课程学生缴费记录
|
|
|
- List<CourseScheduleStudentPayment> studentPaymentsWithCourse = studentPaymentGroupByCourse.get(courseScheduleTeacherSalary.getCourseScheduleId());
|
|
|
- //当前课程缴费学生数量
|
|
|
- BigDecimal courseStudentNum=new BigDecimal(studentPaymentsWithCourse.size());
|
|
|
- //教师预计课酬
|
|
|
- BigDecimal expectSalary=courseScheduleTeacherSalary.getExpectSalary();
|
|
|
- //当前课程每个学生平均课酬
|
|
|
- BigDecimal avgSalary=expectSalary.divide(courseStudentNum);
|
|
|
- //教师当前课程责任总占比,当前课程应得课酬
|
|
|
- BigDecimal teacherLiabilityAllratio;
|
|
|
-
|
|
|
- //当前课程学生投诉记录
|
|
|
- List<CourseScheduleComplaints> courseStudentComplaints=complaintsGroupByCourse.get(courseScheduleTeacherSalary.getCourseScheduleId());
|
|
|
-
|
|
|
- //如果存在投诉记录,需要扣除相应费用
|
|
|
- if(Objects.nonNull(courseStudentComplaints)){
|
|
|
- //获取审批中的投诉
|
|
|
- List<CourseScheduleComplaints> auditIng = courseStudentComplaints.stream().filter(courseScheduleComplaint -> courseScheduleComplaint.getStatus() == AuditStatusEnum.ING).collect(Collectors.toList());
|
|
|
- if(!CollectionUtils.isEmpty(auditIng)){
|
|
|
- //如果当前课程存在未处理的投诉,则不做结算处理
|
|
|
- return;
|
|
|
- }
|
|
|
- //计算教师责任总占比
|
|
|
- double teacherLiabilityRatioSum = courseStudentComplaints.stream().mapToDouble(CourseScheduleComplaints::getTeacherLiabilityRatio).sum();
|
|
|
- teacherLiabilityAllratio=new BigDecimal(teacherLiabilityRatioSum);
|
|
|
- }else{
|
|
|
- //如果没有投诉,则教师和学生的责任占比为0
|
|
|
- teacherLiabilityAllratio=new BigDecimal(0);
|
|
|
- }
|
|
|
-
|
|
|
- //教师应扣除费用
|
|
|
- BigDecimal deductPrice=avgSalary.multiply(teacherLiabilityAllratio);
|
|
|
- //教师实际课酬
|
|
|
- BigDecimal actualSalary=expectSalary.subtract(deductPrice).add(courseScheduleTeacherSalary.getSubsidy());
|
|
|
-
|
|
|
- //更新教师结算信息
|
|
|
- courseScheduleTeacherSalary.setActualSalary(actualSalary);
|
|
|
- courseScheduleTeacherSalary.setSettlementTime(now);
|
|
|
- courseScheduleTeacherSalaryDao.update(courseScheduleTeacherSalary);
|
|
|
- updateTeacherSalarys.add(courseScheduleTeacherSalary);
|
|
|
-
|
|
|
- //生成教师账户资金变动记录
|
|
|
- sysUserCashAccountService.updateBalance(courseScheduleTeacherSalary.getUserId(),actualSalary);
|
|
|
- SysUserCashAccount teacherCashAccount = sysUserCashAccountService.get(courseScheduleTeacherSalary.getUserId().intValue());
|
|
|
- SysUserCashAccountDetail teacherCashAccountDetail=new SysUserCashAccountDetail();
|
|
|
- teacherCashAccountDetail.setUserId(courseScheduleTeacherSalary.getUserId());
|
|
|
- teacherCashAccountDetail.setType(PlatformCashAccountDetailTypeEnum.REFUNDS);
|
|
|
- teacherCashAccountDetail.setStatus(DealStatusEnum.SUCCESS);
|
|
|
- teacherCashAccountDetail.setAmount(actualSalary);
|
|
|
- teacherCashAccountDetail.setBalance(teacherCashAccount.getBalance());
|
|
|
- teacherCashAccountDetail.setAttribute(courseScheduleTeacherSalary.getCourseScheduleId().toString());
|
|
|
-
|
|
|
- userCashAccountDetails.add(teacherCashAccountDetail);
|
|
|
-
|
|
|
- //根据学生进行投诉分组
|
|
|
- Map<Integer, List<CourseScheduleComplaints>> complainsGroupByStudent = courseStudentComplaints.stream().collect(Collectors.groupingBy(CourseScheduleComplaints::getUserId));
|
|
|
-
|
|
|
- //计算学生当前课程应缴费用
|
|
|
- studentPaymentsWithCourse.forEach(studentPayment -> {
|
|
|
- //当前课程学生应缴费用
|
|
|
- BigDecimal studentExpectPrice=studentPayment.getExpectPrice();
|
|
|
- //当前课程学生责任占比
|
|
|
- BigDecimal studentLiabilityRatio;
|
|
|
- List<CourseScheduleComplaints> currentCourseScheduleComplaints = complainsGroupByStudent.get(studentPayment.getUserId());
|
|
|
- if(CollectionUtils.isEmpty(currentCourseScheduleComplaints)){
|
|
|
- Double temp=currentCourseScheduleComplaints.get(0).getStudentLiabilityRatio();
|
|
|
- studentLiabilityRatio=new BigDecimal(temp);
|
|
|
- }else{
|
|
|
- studentLiabilityRatio=new BigDecimal(0);
|
|
|
- }
|
|
|
-
|
|
|
- //当前课程学生应退费用
|
|
|
- BigDecimal returnPrice=studentExpectPrice.multiply(studentLiabilityRatio);
|
|
|
- //当前课程学生实际缴费
|
|
|
- BigDecimal actualPrice=expectSalary.subtract(returnPrice);
|
|
|
- //更新学生结算信息
|
|
|
- studentPayment.setActualPrice(actualPrice);
|
|
|
- studentPayment.setSettlementTime(now);
|
|
|
- courseScheduleStudentPaymentDao.update(studentPayment);
|
|
|
- updateStudentPayments.add(studentPayment);
|
|
|
-
|
|
|
- //生成学生账户资金变动记录
|
|
|
- sysUserCashAccountService.updateBalance(studentPayment.getUserId(),returnPrice);
|
|
|
- SysUserCashAccount studentCashAccount = sysUserCashAccountService.get(studentPayment.getUserId().intValue());
|
|
|
- SysUserCashAccountDetail studentAccountDetail=new SysUserCashAccountDetail();
|
|
|
- studentAccountDetail.setUserId(studentPayment.getUserId());
|
|
|
- studentAccountDetail.setType(PlatformCashAccountDetailTypeEnum.REFUNDS);
|
|
|
- studentAccountDetail.setStatus(DealStatusEnum.SUCCESS);
|
|
|
- studentAccountDetail.setAmount(returnPrice);
|
|
|
- studentAccountDetail.setBalance(studentCashAccount.getBalance());
|
|
|
- studentAccountDetail.setAttribute(courseScheduleTeacherSalary.getCourseScheduleId().toString());
|
|
|
-
|
|
|
- userCashAccountDetails.add(studentAccountDetail);
|
|
|
-
|
|
|
- });
|
|
|
-
|
|
|
- });
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void musicGroupTeacherSalarySettlement() {
|
|
|
- Date now=new Date();
|
|
|
- Date yesterday= DateUtil.addDays1(now,-1);
|
|
|
- List<CourseScheduleTeacherSalary> courseScheduleTeacherSalaryList = new ArrayList<>();
|
|
|
- //获取昨天的课程计划
|
|
|
- List<CourseSchedule> yesterdayCourseSchedules = courseScheduleDao.findCourseScheduleWithDate(yesterday);
|
|
|
-
|
|
|
- }
|
|
|
+public class CourseScheduleTeacherSalaryServiceImpl extends BaseServiceImpl<Long, CourseScheduleTeacherSalary> implements CourseScheduleTeacherSalaryService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private CourseScheduleTeacherSalaryDao courseScheduleTeacherSalaryDao;
|
|
|
+ @Autowired
|
|
|
+ private VipGroupActivityDao vipGroupActivityDao;
|
|
|
+ @Autowired
|
|
|
+ private CourseScheduleComplaintsDao courseScheduleComplaintsDao;
|
|
|
+ @Autowired
|
|
|
+ private CourseScheduleStudentPaymentDao courseScheduleStudentPaymentDao;
|
|
|
+ @Autowired
|
|
|
+ private SysUserCashAccountService sysUserCashAccountService;
|
|
|
+ @Autowired
|
|
|
+ private VipGroupService vipGroupService;
|
|
|
+ @Autowired
|
|
|
+ private SchoolService schoolService;
|
|
|
+ @Autowired
|
|
|
+ private CourseScheduleDao courseScheduleDao;
|
|
|
+ @Autowired
|
|
|
+ private TeacherDefaultMusicGroupSalaryDao teacherDefaultMusicGroupSalaryDao;
|
|
|
+ @Autowired
|
|
|
+ private SysUserCashAccountDetailDao sysUserCashAccountDetailDao;
|
|
|
+ @Autowired
|
|
|
+ private SysConfigService sysConfigDao;
|
|
|
+
|
|
|
+ private static final Logger LOGGER = LoggerFactory
|
|
|
+ .getLogger(CourseScheduleTeacherSalaryServiceImpl.class);
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public BaseDAO<Long, CourseScheduleTeacherSalary> getDAO() {
|
|
|
+ return courseScheduleTeacherSalaryDao;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int createCourseScheduleTeacherVipSalary(VipGroup vipGroup,
|
|
|
+ List<CourseSchedule> vipCourseSchedules,
|
|
|
+ BigDecimal onlineTeacherSalary,
|
|
|
+ BigDecimal offlineTeacherSalary) {
|
|
|
+
|
|
|
+ School school = schoolService.get(vipGroup.getTeacherSchoolId());
|
|
|
+ if (Objects.isNull(school)) {
|
|
|
+ throw new BizException("未找到该教学点");
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取活动信息
|
|
|
+ VipGroupActivity vipGroupActivity = vipGroupActivityDao.get(vipGroup.getVipGroupActivityId().intValue());
|
|
|
+
|
|
|
+ List<CourseScheduleTeacherSalary> courseScheduleTeacherSalaries = new ArrayList<>();
|
|
|
+ Map<TeachModeEnum, List<CourseSchedule>> courseScheduleGroupByTeachMode = vipCourseSchedules.stream().collect(Collectors.groupingBy(CourseSchedule::getTeachMode));
|
|
|
+
|
|
|
+ for (TeachModeEnum teachModeEnum : courseScheduleGroupByTeachMode.keySet()) {
|
|
|
+ List<CourseSchedule> courseSchedules = courseScheduleGroupByTeachMode.get(teachModeEnum)
|
|
|
+ .stream()
|
|
|
+ .sorted(Comparator.comparing(CourseSchedule::getStartClassTime)).collect(Collectors.toList());
|
|
|
+ for (int i = 0; i < courseSchedules.size(); i++) {
|
|
|
+ //创建教师课程薪水记录
|
|
|
+ CourseScheduleTeacherSalary courseScheduleTeacherSalary = new CourseScheduleTeacherSalary();
|
|
|
+ courseScheduleTeacherSalary.setCourseScheduleId(courseSchedules.get(i).getId());
|
|
|
+ courseScheduleTeacherSalary.setTeacherRole(TeachTypeEnum.BISHOP);
|
|
|
+ courseScheduleTeacherSalary.setUserId(courseSchedules.get(i).getActualTeacherId().intValue());
|
|
|
+ courseScheduleTeacherSalary.setClassGroupId(courseSchedules.get(i).getClassGroupId());
|
|
|
+ courseScheduleTeacherSalary.setSubsidy(school.getSubsidy());
|
|
|
+
|
|
|
+ Map<String, BigDecimal> feeInfo = vipGroupService.countVipGroupPredictFee(vipGroup,
|
|
|
+ courseSchedules.get(i).getActualTeacherId().intValue(),
|
|
|
+ onlineTeacherSalary,
|
|
|
+ offlineTeacherSalary,
|
|
|
+ false,
|
|
|
+ false);
|
|
|
+
|
|
|
+ if (vipGroupActivity.getType() == VipGroupActivityTypeEnum.GIVE_CLASS
|
|
|
+ && vipGroup.getGiveTeachMode() == teachModeEnum
|
|
|
+ && i >= Integer.parseInt(vipGroupActivity.getAttribute1())
|
|
|
+ && "0".equals(vipGroupActivity.getGiveClassPaySalaryFlag())) {
|
|
|
+ courseScheduleTeacherSalary.setExpectSalary(new BigDecimal(0));
|
|
|
+ } else {
|
|
|
+ if (teachModeEnum == TeachModeEnum.ONLINE) {
|
|
|
+ courseScheduleTeacherSalary.setExpectSalary(feeInfo.get("onlineTeacherSalary"));
|
|
|
+ } else {
|
|
|
+ courseScheduleTeacherSalary.setExpectSalary(feeInfo.get("offlineTeacherSalary"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ courseScheduleTeacherSalaries.add(courseScheduleTeacherSalary);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return courseScheduleTeacherSalaryDao.batchInsert(courseScheduleTeacherSalaries);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void teacherSalarySettlement() {
|
|
|
+
|
|
|
+ int days = Integer.parseInt(sysConfigDao.findByParamName(SysConfigService.VIP_SETTLEMENT_CYCLE).getParanValue());
|
|
|
+
|
|
|
+ //获取教师未结算课程记录
|
|
|
+ List<CourseScheduleTeacherSalary> someDayAgoTeacherCourseSalaryNoSettlement = courseScheduleTeacherSalaryDao.findSomeDayAgoTeacherCourseSalaryNoSettlement(days);
|
|
|
+ if (CollectionUtils.isEmpty(someDayAgoTeacherCourseSalaryNoSettlement)) {
|
|
|
+ LOGGER.info("未获取到未结算课酬记录!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Date now = new Date();
|
|
|
+ //获取未结算课程编号列表
|
|
|
+ List<Long> courseScheduleIds = someDayAgoTeacherCourseSalaryNoSettlement.stream().map(CourseScheduleTeacherSalary::getCourseScheduleId).collect(Collectors.toList());
|
|
|
+ //获取未结算课程投诉记录
|
|
|
+ List<CourseScheduleComplaints> courseScheduleComplaints = courseScheduleComplaintsDao.findByCourseScheduleIds(courseScheduleIds);
|
|
|
+ //获取未结算课程学生缴费信息
|
|
|
+ List<CourseScheduleStudentPayment> courseScheduleStudentPayments = courseScheduleStudentPaymentDao.findByCourseScheduleIds(courseScheduleIds);
|
|
|
+
|
|
|
+ //根据课程将投诉信息分组
|
|
|
+ Map<Long, List<CourseScheduleComplaints>> complaintsGroupByCourse = courseScheduleComplaints.stream().collect(Collectors.groupingBy(CourseScheduleComplaints::getCourseScheduleId));
|
|
|
+ //根据课程将学生缴费信息分组
|
|
|
+ Map<Long, List<CourseScheduleStudentPayment>> studentPaymentGroupByCourse = courseScheduleStudentPayments.stream().collect(Collectors.groupingBy(CourseScheduleStudentPayment::getCourseScheduleId));
|
|
|
+
|
|
|
+ //需更新教师课程结算记录
|
|
|
+ List<CourseScheduleTeacherSalary> updateTeacherSalarys = new ArrayList<>();
|
|
|
+ //需更新学生课程缴费记录
|
|
|
+ List<CourseScheduleStudentPayment> updateStudentPayments = new ArrayList<>();
|
|
|
+
|
|
|
+ //用户账户自己变动信息列表
|
|
|
+ List<SysUserCashAccountDetail> userCashAccountDetails = new ArrayList<>();
|
|
|
+
|
|
|
+ //处理课酬信息
|
|
|
+ someDayAgoTeacherCourseSalaryNoSettlement.forEach(courseScheduleTeacherSalary -> {
|
|
|
+ //获取当前课程学生缴费记录
|
|
|
+ List<CourseScheduleStudentPayment> studentPaymentsWithCourse = studentPaymentGroupByCourse.get(courseScheduleTeacherSalary.getCourseScheduleId());
|
|
|
+ //当前课程缴费学生数量
|
|
|
+ BigDecimal courseStudentNum = new BigDecimal(studentPaymentsWithCourse.size());
|
|
|
+ //教师预计课酬
|
|
|
+ BigDecimal expectSalary = courseScheduleTeacherSalary.getExpectSalary();
|
|
|
+ //当前课程每个学生平均课酬
|
|
|
+ BigDecimal avgSalary = expectSalary.divide(courseStudentNum);
|
|
|
+ //教师当前课程责任总占比,当前课程应得课酬
|
|
|
+ BigDecimal teacherLiabilityAllratio;
|
|
|
+
|
|
|
+ //当前课程学生投诉记录
|
|
|
+ List<CourseScheduleComplaints> courseStudentComplaints = complaintsGroupByCourse.get(courseScheduleTeacherSalary.getCourseScheduleId());
|
|
|
+
|
|
|
+ //如果存在投诉记录,需要扣除相应费用
|
|
|
+ if (Objects.nonNull(courseStudentComplaints)) {
|
|
|
+ //获取审批中的投诉
|
|
|
+ List<CourseScheduleComplaints> auditIng = courseStudentComplaints.stream().filter(courseScheduleComplaint -> courseScheduleComplaint.getStatus() == AuditStatusEnum.ING).collect(Collectors.toList());
|
|
|
+ if (!CollectionUtils.isEmpty(auditIng)) {
|
|
|
+ //如果当前课程存在未处理的投诉,则不做结算处理
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //计算教师责任总占比
|
|
|
+ double teacherLiabilityRatioSum = courseStudentComplaints.stream().mapToDouble(CourseScheduleComplaints::getTeacherLiabilityRatio).sum();
|
|
|
+ teacherLiabilityAllratio = new BigDecimal(teacherLiabilityRatioSum);
|
|
|
+ } else {
|
|
|
+ //如果没有投诉,则教师和学生的责任占比为0
|
|
|
+ teacherLiabilityAllratio = new BigDecimal(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ //教师应扣除费用
|
|
|
+ BigDecimal deductPrice = avgSalary.multiply(teacherLiabilityAllratio);
|
|
|
+ //教师实际课酬
|
|
|
+ BigDecimal actualSalary = expectSalary.subtract(deductPrice).add(courseScheduleTeacherSalary.getSubsidy());
|
|
|
+
|
|
|
+ //更新教师结算信息
|
|
|
+ courseScheduleTeacherSalary.setActualSalary(actualSalary);
|
|
|
+ courseScheduleTeacherSalary.setSettlementTime(now);
|
|
|
+ courseScheduleTeacherSalaryDao.update(courseScheduleTeacherSalary);
|
|
|
+ updateTeacherSalarys.add(courseScheduleTeacherSalary);
|
|
|
+
|
|
|
+ //生成教师账户资金变动记录
|
|
|
+ sysUserCashAccountService.updateBalance(courseScheduleTeacherSalary.getUserId(), actualSalary);
|
|
|
+ SysUserCashAccount teacherCashAccount = sysUserCashAccountService.get(courseScheduleTeacherSalary.getUserId().intValue());
|
|
|
+ SysUserCashAccountDetail teacherCashAccountDetail = new SysUserCashAccountDetail();
|
|
|
+ teacherCashAccountDetail.setUserId(courseScheduleTeacherSalary.getUserId());
|
|
|
+ teacherCashAccountDetail.setType(PlatformCashAccountDetailTypeEnum.REFUNDS);
|
|
|
+ teacherCashAccountDetail.setStatus(DealStatusEnum.SUCCESS);
|
|
|
+ teacherCashAccountDetail.setAmount(actualSalary);
|
|
|
+ teacherCashAccountDetail.setBalance(teacherCashAccount.getBalance());
|
|
|
+ teacherCashAccountDetail.setAttribute(courseScheduleTeacherSalary.getCourseScheduleId().toString());
|
|
|
+
|
|
|
+ userCashAccountDetails.add(teacherCashAccountDetail);
|
|
|
+
|
|
|
+ //根据学生进行投诉分组
|
|
|
+ Map<Integer, List<CourseScheduleComplaints>> complainsGroupByStudent = courseStudentComplaints.stream().collect(Collectors.groupingBy(CourseScheduleComplaints::getUserId));
|
|
|
+
|
|
|
+ //计算学生当前课程应缴费用
|
|
|
+ studentPaymentsWithCourse.forEach(studentPayment -> {
|
|
|
+ //当前课程学生应缴费用
|
|
|
+ BigDecimal studentExpectPrice = studentPayment.getExpectPrice();
|
|
|
+ //当前课程学生责任占比
|
|
|
+ BigDecimal studentLiabilityRatio;
|
|
|
+ List<CourseScheduleComplaints> currentCourseScheduleComplaints = complainsGroupByStudent.get(studentPayment.getUserId());
|
|
|
+ if (CollectionUtils.isEmpty(currentCourseScheduleComplaints)) {
|
|
|
+ Double temp = currentCourseScheduleComplaints.get(0).getStudentLiabilityRatio();
|
|
|
+ studentLiabilityRatio = new BigDecimal(temp);
|
|
|
+ } else {
|
|
|
+ studentLiabilityRatio = new BigDecimal(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ //当前课程学生应退费用
|
|
|
+ BigDecimal returnPrice = studentExpectPrice.multiply(studentLiabilityRatio);
|
|
|
+ //当前课程学生实际缴费
|
|
|
+ BigDecimal actualPrice = expectSalary.subtract(returnPrice);
|
|
|
+ //更新学生结算信息
|
|
|
+ studentPayment.setActualPrice(actualPrice);
|
|
|
+ studentPayment.setSettlementTime(now);
|
|
|
+ courseScheduleStudentPaymentDao.update(studentPayment);
|
|
|
+ updateStudentPayments.add(studentPayment);
|
|
|
+
|
|
|
+ //生成学生账户资金变动记录
|
|
|
+ sysUserCashAccountService.updateBalance(studentPayment.getUserId(), returnPrice);
|
|
|
+ SysUserCashAccount studentCashAccount = sysUserCashAccountService.get(studentPayment.getUserId().intValue());
|
|
|
+ SysUserCashAccountDetail studentAccountDetail = new SysUserCashAccountDetail();
|
|
|
+ studentAccountDetail.setUserId(studentPayment.getUserId());
|
|
|
+ studentAccountDetail.setType(PlatformCashAccountDetailTypeEnum.REFUNDS);
|
|
|
+ studentAccountDetail.setStatus(DealStatusEnum.SUCCESS);
|
|
|
+ studentAccountDetail.setAmount(returnPrice);
|
|
|
+ studentAccountDetail.setBalance(studentCashAccount.getBalance());
|
|
|
+ studentAccountDetail.setAttribute(courseScheduleTeacherSalary.getCourseScheduleId().toString());
|
|
|
+
|
|
|
+ userCashAccountDetails.add(studentAccountDetail);
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+ });
|
|
|
+ sysUserCashAccountDetailDao.batchInsert(userCashAccountDetails);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void musicGroupTeacherSalarySettlement() {
|
|
|
+ Date now = new Date();
|
|
|
+ Date yesterday = DateUtil.addDays1(now, -1);
|
|
|
+ Integer settlementClassMinutes = Integer.parseInt(sysConfigDao.findByParamName(SysConfigService.MUSIC_GROUP_SETTLEMENT_CLASS_MINUTES).getParanValue());
|
|
|
+ Integer singleClassTime = Integer.parseInt(sysConfigDao.findByParamName(SysConfigService.MUSIC_GROUP_SETTLEMENT_SINGLE_CLASS_MINUTES).getParanValue());
|
|
|
+ //获取昨天的课程计划
|
|
|
+ List<CourseSchedule> yesterdayCourseSchedules = courseScheduleDao.findCourseScheduleWithDate(yesterday);
|
|
|
+ //课程编号列表
|
|
|
+ List<Long> courseScheduleIds = yesterdayCourseSchedules.stream().map(CourseSchedule::getId).collect(Collectors.toList());
|
|
|
+ //获取课程对应教学点补贴
|
|
|
+ List<Map<Integer, BigDecimal>> courseSubsidyByCourses = courseScheduleTeacherSalaryDao.findCourseSubsidyByCourses(courseScheduleIds);
|
|
|
+ Map<Integer, BigDecimal> courseSubsidyMap = MapUtil.convertMybatisMap(courseSubsidyByCourses);
|
|
|
+
|
|
|
+ //课程编号与课程对应集合
|
|
|
+ Map<Long, CourseSchedule> courseScheduleIdMap = yesterdayCourseSchedules.stream()
|
|
|
+ .collect(Collectors.toMap(CourseSchedule::getId, courseSchedule -> courseSchedule));
|
|
|
+
|
|
|
+ //课程教师课酬
|
|
|
+ List<CourseScheduleTeacherSalary> courseScheduleTeacherSalaries = courseScheduleTeacherSalaryDao.findByCourseSchedules(courseScheduleIds);
|
|
|
+
|
|
|
+ //课程对应乐团结算方式集合
|
|
|
+ List<Map<String, String>> musicGroupSettlementTypeByCourse = courseScheduleTeacherSalaryDao.findMusicGroupSettlementTypeByCourse(courseScheduleIds);
|
|
|
+ Map<String, String> musicGroupSettlementsMap = MapUtil.convertMybatisMap(musicGroupSettlementTypeByCourse);
|
|
|
+
|
|
|
+ //教师对应课程列表集合
|
|
|
+ Map<Integer, List<CourseScheduleTeacherSalary>> teacherSalarysByTeacher = courseScheduleTeacherSalaries.stream()
|
|
|
+ .collect(Collectors.groupingBy(CourseScheduleTeacherSalary::getUserId));
|
|
|
+
|
|
|
+ //所有老师编号
|
|
|
+ List<Integer> allTeacherIds = courseScheduleTeacherSalaries.stream()
|
|
|
+ .map(CourseScheduleTeacherSalary::getUserId)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ //所有老师默认乐团课酬
|
|
|
+ List<TeacherDefaultMusicGroupSalary> teacherDefaultMusicGroupSalaries = teacherDefaultMusicGroupSalaryDao.findByTeacher(allTeacherIds);
|
|
|
+ Map<CourseSchedule.CourseScheduleType, List<TeacherDefaultMusicGroupSalary>> teacherDefaultMusicGroupSalariesGroupByCourseType = teacherDefaultMusicGroupSalaries.stream().collect(Collectors.groupingBy(TeacherDefaultMusicGroupSalary::getCourseScheduleType));
|
|
|
+
|
|
|
+
|
|
|
+ //教师对应的每个教学点的总课时
|
|
|
+ Map<Integer, Map<Integer, Integer>> teacherClassMinutesMap = new HashMap<>();
|
|
|
+ //计算老师对应的总课时
|
|
|
+ teacherSalarysByTeacher.forEach((teacherId, teacherSalarys) -> {
|
|
|
+ //当前老师所在课程的编号列表
|
|
|
+ List<Long> currentTeacherCourscheduleIds = teacherSalarys.stream()
|
|
|
+ .map(CourseScheduleTeacherSalary::getCourseScheduleId)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ //当前老师的课程列表
|
|
|
+ List<CourseSchedule> currentTeacherCourseSchedules = yesterdayCourseSchedules.stream()
|
|
|
+ .filter(courseSchedule -> currentTeacherCourscheduleIds.contains(courseSchedule.getId()))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ //根据教学点将当前老师的课程分组
|
|
|
+ Map<Integer, List<CourseSchedule>> schoolCourseSchedules = currentTeacherCourseSchedules.stream()
|
|
|
+ .collect(Collectors.groupingBy(CourseSchedule::getSchoolId));
|
|
|
+ Map<Integer, Integer> schoolClassMinutesMap = new HashMap<>();
|
|
|
+ for (Integer schoolId : schoolCourseSchedules.keySet()) {
|
|
|
+ Integer classMinutes = 0;
|
|
|
+ //当前教学点的课程
|
|
|
+ List<CourseSchedule> currentSchoolCourseSchedules = schoolCourseSchedules.get(schoolId);
|
|
|
+ for (CourseSchedule courseSchedule : currentSchoolCourseSchedules) {
|
|
|
+ //如果课程为单机课或者为合奏课,则算入总课时长
|
|
|
+ if (courseSchedule.getType().equals(CourseSchedule.CourseScheduleType.SINGLE)
|
|
|
+ || courseSchedule.getType().equals(CourseSchedule.CourseScheduleType.MIX)) {
|
|
|
+ classMinutes += DateUtil.minutesBetween(courseSchedule.getStartClassTime(), courseSchedule.getEndClassTime());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ schoolClassMinutesMap.put(schoolId, classMinutes);
|
|
|
+ }
|
|
|
+ teacherClassMinutesMap.put(teacherId, schoolClassMinutesMap);
|
|
|
+ });
|
|
|
+ //用户账户自己变动信息列表
|
|
|
+ List<SysUserCashAccountDetail> userCashAccountDetails = new ArrayList<>();
|
|
|
+ //计算课酬
|
|
|
+ courseScheduleTeacherSalaries.forEach(courseScheduleTeacherSalary -> {
|
|
|
+ //当前课酬对应的课程信息
|
|
|
+ CourseSchedule courseSchedule = courseScheduleIdMap.get(courseScheduleTeacherSalary.getCourseScheduleId());
|
|
|
+ Map<Integer, Integer> schoolClassMinutesMap = teacherClassMinutesMap.get(courseScheduleTeacherSalary.getUserId());
|
|
|
+ Integer schoolClassMinutes = schoolClassMinutesMap.get(courseSchedule.getSchoolId());
|
|
|
+ //当前课程的时长
|
|
|
+ int duration = DateUtil.minutesBetween(courseSchedule.getStartClassTime(), courseSchedule.getEndClassTime());
|
|
|
+ //如果是单技课或者合奏课
|
|
|
+ if (courseSchedule.getType().equals(CourseSchedule.CourseScheduleType.SINGLE)
|
|
|
+ || courseSchedule.getType().equals(CourseSchedule.CourseScheduleType.MIX)) {
|
|
|
+ if (schoolClassMinutes >= settlementClassMinutes && duration < singleClassTime) {
|
|
|
+ duration = singleClassTime;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //根据课程类型获取对应的默认课酬设置列表
|
|
|
+ List<TeacherDefaultMusicGroupSalary> teacherDefaultMusicGroupSalariesWithCourseType = teacherDefaultMusicGroupSalariesGroupByCourseType.get(courseSchedule.getType());
|
|
|
+ if (CollectionUtils.isEmpty(teacherDefaultMusicGroupSalariesWithCourseType)) {
|
|
|
+ throw new BizException("存在未指定结算方式的课程类型");
|
|
|
+ }
|
|
|
+
|
|
|
+ //根据教师编号将对应结算方式下的默认课酬设置分组
|
|
|
+ Map<Integer, TeacherDefaultMusicGroupSalary> teacherDefaultMusicGroupSalariesGroupByTeacherId = teacherDefaultMusicGroupSalariesWithCourseType.stream().collect(Collectors.toMap(TeacherDefaultMusicGroupSalary::getUserId,teacherDefaultMusicGroupSalary -> teacherDefaultMusicGroupSalary));
|
|
|
+
|
|
|
+ TeacherDefaultMusicGroupSalary teacherDefaultMusicGroupSalaryWithTeacherId=teacherDefaultMusicGroupSalariesGroupByTeacherId.get(courseScheduleTeacherSalary.getUserId());
|
|
|
+
|
|
|
+ //教师课酬
|
|
|
+ BigDecimal teacherSalary = new BigDecimal(0);
|
|
|
+
|
|
|
+ String settlementType=musicGroupSettlementsMap.get(courseScheduleTeacherSalary.getCourseScheduleId());
|
|
|
+ //如果结算方式是教师默认课酬
|
|
|
+ if (settlementType.equals(SalarySettlementTypeEnum.TEACHER_DEFAULT)) {
|
|
|
+ //课程时长与结算单位时长占比
|
|
|
+ BigDecimal classTimeDuty = new BigDecimal(duration).divide(new BigDecimal(30));
|
|
|
+ BigDecimal teacherDefaultSalary = courseScheduleTeacherSalary.getTeacherRole().equals(TeachTypeEnum.BISHOP) ? teacherDefaultMusicGroupSalaryWithTeacherId.getMainTeacher30MinSalary() : teacherDefaultMusicGroupSalaryWithTeacherId.getAssistantTeacher30MinSalary();
|
|
|
+ teacherSalary = teacherDefaultSalary.multiply(classTimeDuty).setScale(2, BigDecimal.ROUND_HALF_UP);
|
|
|
+ } else if (settlementType.equals(SalarySettlementTypeEnum.GRADIENT_SALARY)) {
|
|
|
+ //课程时长与结算单位时长占比
|
|
|
+ BigDecimal classTimeDuty = new BigDecimal(duration).divide(new BigDecimal(90));
|
|
|
+ BigDecimal teacherDefaultSalary = courseScheduleTeacherSalary.getTeacherRole().equals(TeachTypeEnum.BISHOP) ? teacherDefaultMusicGroupSalaryWithTeacherId.getMainTeacher90MinSalary() : teacherDefaultMusicGroupSalaryWithTeacherId.getAssistantTeacher90MinSalary();
|
|
|
+ teacherSalary = teacherDefaultSalary.multiply(classTimeDuty).setScale(2, BigDecimal.ROUND_HALF_UP);
|
|
|
+ }
|
|
|
+ BigDecimal subsidy = courseSubsidyMap.get(courseSchedule.getSchoolId());
|
|
|
+ teacherSalary=teacherSalary.add(subsidy);
|
|
|
+ //更新教师结算信息
|
|
|
+ courseScheduleTeacherSalary.setActualSalary(teacherSalary);
|
|
|
+ courseScheduleTeacherSalary.setSettlementTime(now);
|
|
|
+ courseScheduleTeacherSalaryDao.update(courseScheduleTeacherSalary);
|
|
|
+
|
|
|
+ //生成教师账户资金变动记录
|
|
|
+ sysUserCashAccountService.updateBalance(courseScheduleTeacherSalary.getUserId(), teacherSalary);
|
|
|
+ SysUserCashAccount teacherCashAccount = sysUserCashAccountService.get(courseScheduleTeacherSalary.getUserId().intValue());
|
|
|
+ SysUserCashAccountDetail teacherCashAccountDetail = new SysUserCashAccountDetail();
|
|
|
+ teacherCashAccountDetail.setUserId(courseScheduleTeacherSalary.getUserId());
|
|
|
+ teacherCashAccountDetail.setType(PlatformCashAccountDetailTypeEnum.REFUNDS);
|
|
|
+ teacherCashAccountDetail.setStatus(DealStatusEnum.SUCCESS);
|
|
|
+ teacherCashAccountDetail.setAmount(teacherSalary);
|
|
|
+ teacherCashAccountDetail.setBalance(teacherCashAccount.getBalance());
|
|
|
+ teacherCashAccountDetail.setAttribute(courseScheduleTeacherSalary.getCourseScheduleId().toString());
|
|
|
+ userCashAccountDetails.add(teacherCashAccountDetail);
|
|
|
+
|
|
|
+ });
|
|
|
+ sysUserCashAccountDetailDao.batchInsert(userCashAccountDetails);
|
|
|
+ }
|
|
|
}
|