|  | @@ -1,5 +1,6 @@
 | 
	
		
			
				|  |  |  package com.ym.mec.biz.service.impl;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +import com.ym.mec.auth.api.entity.SysUser;
 | 
	
		
			
				|  |  |  import com.ym.mec.biz.dal.dao.*;
 | 
	
		
			
				|  |  |  import com.ym.mec.biz.dal.dto.VipGroupGiveCourseSortDto;
 | 
	
		
			
				|  |  |  import com.ym.mec.biz.dal.entity.*;
 | 
	
	
		
			
				|  | @@ -46,6 +47,10 @@ public class CourseScheduleStudentPaymentServiceImpl extends BaseServiceImpl<Lon
 | 
	
		
			
				|  |  |  	private MusicGroupPaymentCalenderCourseSettingsDao musicGroupPaymentCalenderCourseSettingsDao;
 | 
	
		
			
				|  |  |  	@Autowired
 | 
	
		
			
				|  |  |  	private StudentPaymentOrderDetailDao studentPaymentOrderDetailDao;
 | 
	
		
			
				|  |  | +	@Autowired
 | 
	
		
			
				|  |  | +	private MusicGroupPaymentStudentCourseDetailDao musicGroupPaymentStudentCourseDetailDao;
 | 
	
		
			
				|  |  | +	@Autowired
 | 
	
		
			
				|  |  | +	private TeacherDao teacherDao;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	@Override
 | 
	
		
			
				|  |  |  	public BaseDAO<Long, CourseScheduleStudentPayment> getDAO() {
 | 
	
	
		
			
				|  | @@ -282,103 +287,83 @@ public class CourseScheduleStudentPaymentServiceImpl extends BaseServiceImpl<Lon
 | 
	
		
			
				|  |  |  	@Override
 | 
	
		
			
				|  |  |  	@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
 | 
	
		
			
				|  |  |  	public void createForMusicGroup(String musicGroupId, List<CourseSchedule> courseSchedules, List<Integer> studentIds) {
 | 
	
		
			
				|  |  | -		MusicGroupPaymentCalender musicGroupUnusedFirstPaymentCalender = musicGroupPaymentCalenderDao.getMusicGroupUnusedFirstPaymentCalender(musicGroupId, studentIds);
 | 
	
		
			
				|  |  | -		if(Objects.isNull(musicGroupUnusedFirstPaymentCalender)){
 | 
	
		
			
				|  |  | -			throw new BizException("当前乐团暂无新缴费设置");
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		List<MusicGroupPaymentCalenderDetail> unusedPaymentCalenderDetail = musicGroupPaymentCalenderDetailDao.getCalenderDetailWithCalender(musicGroupUnusedFirstPaymentCalender.getId());
 | 
	
		
			
				|  |  | -		if(CollectionUtils.isEmpty(unusedPaymentCalenderDetail)){
 | 
	
		
			
				|  |  | -			throw new BizException("当前乐团无学员缴费信息");
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		Map<Integer, List<MusicGroupPaymentCalenderDetail>> studentPaymentCalenderMap = unusedPaymentCalenderDetail.stream().collect(Collectors.groupingBy(MusicGroupPaymentCalenderDetail::getUserId));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		List<MusicGroupPaymentCalenderCourseSettings> calenderCourseSettings = musicGroupPaymentCalenderCourseSettingsDao.getWithPaymentCalender(musicGroupUnusedFirstPaymentCalender.getId());
 | 
	
		
			
				|  |  | -		if(CollectionUtils.isEmpty(calenderCourseSettings)){
 | 
	
		
			
				|  |  | -			throw new BizException("课程收费标准设置异常");
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		Set<Long> paymentOrderIds = unusedPaymentCalenderDetail.stream().map(MusicGroupPaymentCalenderDetail::getPaymentOrderId).collect(Collectors.toSet());
 | 
	
		
			
				|  |  | -		List<StudentPaymentOrderDetail> allStudentPaymentOrderDetails = new ArrayList<>();
 | 
	
		
			
				|  |  | -		if(!CollectionUtils.isEmpty(paymentOrderIds)){
 | 
	
		
			
				|  |  | -			allStudentPaymentOrderDetails = studentPaymentOrderDetailDao.getWithIds(new ArrayList<>(paymentOrderIds));
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		Map<Long, List<StudentPaymentOrderDetail>> orderIdOrderDetailMap = allStudentPaymentOrderDetails.stream().collect(Collectors.groupingBy(StudentPaymentOrderDetail::getPaymentOrderId));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		Map<CourseSchedule.CourseScheduleType, MusicGroupPaymentCalenderCourseSettings> courseTypeCourseSettingMap = calenderCourseSettings.stream().collect(Collectors.toMap(MusicGroupPaymentCalenderCourseSettings::getCourseType, cs -> cs, (c1, c2) -> c1));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  		List<CourseScheduleStudentPayment> baseCourseScheduleStudentPayments = new ArrayList<>();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +		Map<CourseSchedule.CourseScheduleType, Integer> courseTypeCourseDurationMap = new HashMap<>();
 | 
	
		
			
				|  |  |  		Map<CourseSchedule.CourseScheduleType, List<CourseSchedule>> typeCourseMap = courseSchedules.stream().collect(Collectors.groupingBy(CourseSchedule::getType));
 | 
	
		
			
				|  |  |  		for (Map.Entry<CourseSchedule.CourseScheduleType, List<CourseSchedule>> typeCoursesEntry : typeCourseMap.entrySet()) {
 | 
	
		
			
				|  |  | -			MusicGroupPaymentCalenderCourseSettings musicGroupPaymentCalenderCourseSettings = courseTypeCourseSettingMap.get(typeCoursesEntry.getKey());
 | 
	
		
			
				|  |  | -			if(musicGroupPaymentCalenderCourseSettings.getIsStudentOptional()){
 | 
	
		
			
				|  |  | -				//如果可选,则必须缴费才能排课
 | 
	
		
			
				|  |  | -				long paymentStudentNum = allStudentPaymentOrderDetails.stream().filter(spd -> musicGroupPaymentCalenderCourseSettings.getCourseType().getCode().equals(spd.getType().getCode())).count();
 | 
	
		
			
				|  |  | -				if(paymentStudentNum<studentIds.size()){
 | 
	
		
			
				|  |  | -					throw new BizException("部分学员未完成自选课程缴费");
 | 
	
		
			
				|  |  | -				}
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -			List<CourseScheduleStudentPayment> typeCourseStudentPayments = new ArrayList<>();
 | 
	
		
			
				|  |  | -			BigDecimal typeCourseTotalOriginalPrice = new BigDecimal("0"), typeCourseTotalCurrentPrice = new BigDecimal("0");
 | 
	
		
			
				|  |  | -			typeCoursesEntry.getValue().sort(Comparator.comparing(CourseSchedule::getStartClassTime));
 | 
	
		
			
				|  |  | +			int totalCourseDuration = 0;
 | 
	
		
			
				|  |  |  			for (CourseSchedule courseSchedule : typeCoursesEntry.getValue()) {
 | 
	
		
			
				|  |  | -				//课程每分钟原价
 | 
	
		
			
				|  |  | -				BigDecimal unitMinuteOriginalPrice = musicGroupPaymentCalenderCourseSettings.getCourseOriginalPrice().divide(new BigDecimal(musicGroupPaymentCalenderCourseSettings.getCourseTotalMinuties()), CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN);
 | 
	
		
			
				|  |  | -				//课程每分钟现价
 | 
	
		
			
				|  |  | -				BigDecimal unitMinuteCurrentPrice = musicGroupPaymentCalenderCourseSettings.getCourseCurrentPrice().divide(new BigDecimal(musicGroupPaymentCalenderCourseSettings.getCourseTotalMinuties()), CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  				//课程时长
 | 
	
		
			
				|  |  |  				int courseDuration = DateUtil.minutesBetween(courseSchedule.getStartClassTime(), courseSchedule.getEndClassTime());
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -				//课程原价
 | 
	
		
			
				|  |  | -				BigDecimal courseOriginalPrice = unitMinuteOriginalPrice.multiply(new BigDecimal(courseDuration)).setScale(CommonConstants.DECIMAL_FINAL_PLACE, BigDecimal.ROUND_DOWN);
 | 
	
		
			
				|  |  | -				typeCourseTotalOriginalPrice = typeCourseTotalOriginalPrice.add(courseOriginalPrice);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -				//课程现价
 | 
	
		
			
				|  |  | -				BigDecimal courseCurrentPrice = unitMinuteCurrentPrice.multiply(new BigDecimal(courseDuration)).setScale(CommonConstants.DECIMAL_FINAL_PLACE, BigDecimal.ROUND_DOWN);
 | 
	
		
			
				|  |  | -				typeCourseTotalCurrentPrice = typeCourseTotalCurrentPrice.add(courseCurrentPrice);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -				CourseScheduleStudentPayment cssp = new CourseScheduleStudentPayment();
 | 
	
		
			
				|  |  | -				cssp.setGroupType(courseSchedule.getGroupType());
 | 
	
		
			
				|  |  | -				cssp.setMusicGroupId(courseSchedule.getMusicGroupId());
 | 
	
		
			
				|  |  | -				cssp.setCourseScheduleId(courseSchedule.getId());
 | 
	
		
			
				|  |  | -				cssp.setClassGroupId(courseSchedule.getClassGroupId());
 | 
	
		
			
				|  |  | -				cssp.setBatchNo(musicGroupUnusedFirstPaymentCalender.getBatchNo());
 | 
	
		
			
				|  |  | -				cssp.setOriginalPrice(courseOriginalPrice);
 | 
	
		
			
				|  |  | -				cssp.setExpectPrice(courseCurrentPrice);
 | 
	
		
			
				|  |  | -				cssp.setActualPrice(BigDecimal.ZERO);
 | 
	
		
			
				|  |  | -				typeCourseStudentPayments.add(cssp);
 | 
	
		
			
				|  |  | +				totalCourseDuration += courseDuration;
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  | -			typeCourseStudentPayments.get(0).setOriginalPrice(typeCourseStudentPayments.get(0).getOriginalPrice().add(musicGroupPaymentCalenderCourseSettings.getCourseOriginalPrice().subtract(typeCourseTotalOriginalPrice)));
 | 
	
		
			
				|  |  | -			typeCourseStudentPayments.get(0).setExpectPrice(typeCourseStudentPayments.get(0).getExpectPrice().add(musicGroupPaymentCalenderCourseSettings.getCourseCurrentPrice().subtract(typeCourseTotalCurrentPrice)));
 | 
	
		
			
				|  |  | -			baseCourseScheduleStudentPayments.addAll(typeCourseStudentPayments);
 | 
	
		
			
				|  |  | +			courseTypeCourseDurationMap.put(typeCoursesEntry.getKey(), totalCourseDuration);
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -		List<MusicGroupPaymentCalenderDetail> needUpdateCalenderDetails = new ArrayList<>();
 | 
	
		
			
				|  |  |  		List<CourseScheduleStudentPayment> courseScheduleStudentPayments = new ArrayList<>();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  		for (Integer studentId : studentIds) {
 | 
	
		
			
				|  |  | -			List<MusicGroupPaymentCalenderDetail> musicGroupPaymentCalenderDetails = studentPaymentCalenderMap.get(studentId);
 | 
	
		
			
				|  |  | -			if(CollectionUtils.isEmpty(musicGroupPaymentCalenderDetails)){
 | 
	
		
			
				|  |  | -				throw new BizException("部分学员无缴费信息");
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -			MusicGroupPaymentCalenderDetail musicGroupPaymentCalenderDetail = musicGroupPaymentCalenderDetails.stream().min(Comparator.comparing(MusicGroupPaymentCalenderDetail::getCreateTime)).get();
 | 
	
		
			
				|  |  | -			if(!musicGroupPaymentCalenderDetail.getMusicGroupPaymentCalenderId().equals(musicGroupUnusedFirstPaymentCalender.getId())){
 | 
	
		
			
				|  |  | -				throw new BizException("缴费信息异常");
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -			musicGroupPaymentCalenderDetail.setUseInCourse(1);
 | 
	
		
			
				|  |  | -			needUpdateCalenderDetails.add(musicGroupPaymentCalenderDetail);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -			for (CourseScheduleStudentPayment baseCourseScheduleStudentPayment : baseCourseScheduleStudentPayments) {
 | 
	
		
			
				|  |  | -				CourseScheduleStudentPayment cssp = new CourseScheduleStudentPayment();
 | 
	
		
			
				|  |  | -				BeanUtils.copyProperties(baseCourseScheduleStudentPayment, cssp);
 | 
	
		
			
				|  |  | -				cssp.setUserId(studentId);
 | 
	
		
			
				|  |  | -				courseScheduleStudentPayments.add(cssp);
 | 
	
		
			
				|  |  | +			for (Map.Entry<CourseSchedule.CourseScheduleType, List<CourseSchedule>> courseScheduleTypeListEntry : typeCourseMap.entrySet()) {
 | 
	
		
			
				|  |  | +				//当前课程类型总课程时长
 | 
	
		
			
				|  |  | +				Integer typeCourseDuration = courseTypeCourseDurationMap.get(courseScheduleTypeListEntry.getKey());
 | 
	
		
			
				|  |  | +				MusicGroupPaymentStudentCourseDetail musicGroupPaymentStudentCourseDetail = musicGroupPaymentStudentCourseDetailDao.getUnUseWithStudentAndCourseTypeAndCourseMinutes(studentId, courseScheduleTypeListEntry.getKey(), typeCourseDuration);
 | 
	
		
			
				|  |  | +				if(Objects.isNull(musicGroupPaymentStudentCourseDetail)){
 | 
	
		
			
				|  |  | +					SysUser user = teacherDao.getUser(studentId);
 | 
	
		
			
				|  |  | +					throw new BizException("{}在{}课程类型上的课程时长不足", user.getUsername(), courseScheduleTypeListEntry.getKey().getMsg());
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +				MusicGroupPaymentCalender musicGroupPaymentCalender = musicGroupPaymentCalenderDao.get(musicGroupPaymentStudentCourseDetail.getMusicGroupPaymentCalenderId());
 | 
	
		
			
				|  |  | +				if(Objects.isNull(musicGroupPaymentCalender)){
 | 
	
		
			
				|  |  | +					throw new BizException("缴费设置异常");
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +				MusicGroupPaymentCalenderCourseSettings musicGroupPaymentCalenderCourseSettings = musicGroupPaymentCalenderCourseSettingsDao.getWithPaymentCalenderAndCourseType(musicGroupPaymentStudentCourseDetail.getMusicGroupPaymentCalenderId(), courseScheduleTypeListEntry.getKey());
 | 
	
		
			
				|  |  | +				if(Objects.isNull(musicGroupPaymentCalenderCourseSettings)){
 | 
	
		
			
				|  |  | +					throw new BizException("缴费设置异常");
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +				//课程每分钟原价
 | 
	
		
			
				|  |  | +				BigDecimal unitMinuteOriginalPrice = musicGroupPaymentCalenderCourseSettings.getCourseOriginalPrice().divide(new BigDecimal(musicGroupPaymentCalenderCourseSettings.getCourseTotalMinuties()), CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN);
 | 
	
		
			
				|  |  | +				//课程每分钟现价
 | 
	
		
			
				|  |  | +				BigDecimal unitMinuteCurrentPrice = musicGroupPaymentCalenderCourseSettings.getCourseCurrentPrice().divide(new BigDecimal(musicGroupPaymentCalenderCourseSettings.getCourseTotalMinuties()), CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +				List<CourseScheduleStudentPayment> typeCourseStudentPayments = new ArrayList<>();
 | 
	
		
			
				|  |  | +				courseScheduleTypeListEntry.getValue().sort(Comparator.comparing(CourseSchedule::getStartClassTime));
 | 
	
		
			
				|  |  | +				BigDecimal typeCourseTotalOriginalPrice = new BigDecimal("0"), typeCourseTotalCurrentPrice = new BigDecimal("0");
 | 
	
		
			
				|  |  | +				for (CourseSchedule courseSchedule : courseScheduleTypeListEntry.getValue()) {
 | 
	
		
			
				|  |  | +					//课程时长
 | 
	
		
			
				|  |  | +					int courseDuration = DateUtil.minutesBetween(courseSchedule.getStartClassTime(), courseSchedule.getEndClassTime());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +					//课程原价
 | 
	
		
			
				|  |  | +					BigDecimal courseOriginalPrice = unitMinuteOriginalPrice.multiply(new BigDecimal(courseDuration)).setScale(CommonConstants.DECIMAL_FINAL_PLACE, BigDecimal.ROUND_DOWN);
 | 
	
		
			
				|  |  | +					typeCourseTotalOriginalPrice = typeCourseTotalOriginalPrice.add(courseOriginalPrice);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +					//课程现价
 | 
	
		
			
				|  |  | +					BigDecimal courseCurrentPrice = unitMinuteCurrentPrice.multiply(new BigDecimal(courseDuration)).setScale(CommonConstants.DECIMAL_FINAL_PLACE, BigDecimal.ROUND_DOWN);
 | 
	
		
			
				|  |  | +					typeCourseTotalCurrentPrice = typeCourseTotalCurrentPrice.add(courseCurrentPrice);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +					CourseScheduleStudentPayment cssp = new CourseScheduleStudentPayment();
 | 
	
		
			
				|  |  | +					cssp.setGroupType(courseSchedule.getGroupType());
 | 
	
		
			
				|  |  | +					cssp.setMusicGroupId(courseSchedule.getMusicGroupId());
 | 
	
		
			
				|  |  | +					cssp.setCourseScheduleId(courseSchedule.getId());
 | 
	
		
			
				|  |  | +					cssp.setClassGroupId(courseSchedule.getClassGroupId());
 | 
	
		
			
				|  |  | +					cssp.setBatchNo(musicGroupPaymentCalender.getBatchNo());
 | 
	
		
			
				|  |  | +					cssp.setOriginalPrice(courseOriginalPrice);
 | 
	
		
			
				|  |  | +					cssp.setExpectPrice(courseCurrentPrice);
 | 
	
		
			
				|  |  | +					cssp.setActualPrice(BigDecimal.ZERO);
 | 
	
		
			
				|  |  | +					typeCourseStudentPayments.add(cssp);
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +				if(musicGroupPaymentCalenderCourseSettings.getCourseCurrentPrice().compareTo(typeCourseTotalCurrentPrice)<0){
 | 
	
		
			
				|  |  | +					throw new BizException("{}课程类型时长不足", courseScheduleTypeListEntry.getKey().getMsg());
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +				typeCourseStudentPayments.get(0).setOriginalPrice(typeCourseStudentPayments.get(0).getOriginalPrice().add(musicGroupPaymentCalenderCourseSettings.getCourseOriginalPrice().subtract(typeCourseTotalOriginalPrice)));
 | 
	
		
			
				|  |  | +				typeCourseStudentPayments.get(0).setExpectPrice(typeCourseStudentPayments.get(0).getExpectPrice().add(musicGroupPaymentCalenderCourseSettings.getCourseCurrentPrice().subtract(typeCourseTotalCurrentPrice)));
 | 
	
		
			
				|  |  | +				baseCourseScheduleStudentPayments.addAll(typeCourseStudentPayments);
 | 
	
		
			
				|  |  | +				musicGroupPaymentStudentCourseDetail.setUsedCourseMinutes(typeCourseDuration);
 | 
	
		
			
				|  |  | +				musicGroupPaymentStudentCourseDetailDao.update(musicGroupPaymentStudentCourseDetail);
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  		courseScheduleStudentPaymentDao.batchInsert(courseScheduleStudentPayments);
 | 
	
		
			
				|  |  | -		musicGroupPaymentCalenderDetailDao.batchUpdate(needUpdateCalenderDetails);
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	@Override
 |