package com.ym.mec.biz.service.impl;

import com.ym.mec.auth.api.client.SysUserFeignService;
import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.auth.api.entity.SysUserRole;
import com.ym.mec.biz.dal.dao.*;
import com.ym.mec.biz.dal.dto.CalenderPushDto;
import com.ym.mec.biz.dal.dto.MusicGroupPaymentCalenderAuditDetailDto;
import com.ym.mec.biz.dal.dto.MusicGroupPaymentCalenderAuditDto;
import com.ym.mec.biz.dal.entity.CourseSchedule.CourseScheduleType;
import com.ym.mec.biz.dal.entity.*;
import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PayUserType;
import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PaymentCalenderStatusEnum;
import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PaymentType;
import com.ym.mec.biz.dal.entity.MusicGroupStudentFee.PaymentStatus;
import com.ym.mec.biz.dal.enums.MessageTypeEnum;
import com.ym.mec.biz.dal.enums.MusicGroupStatusEnum;
import com.ym.mec.biz.dal.enums.PaymentStatusEnum;
import com.ym.mec.biz.dal.enums.StudentMusicGroupStatusEnum;
import com.ym.mec.biz.dal.page.MusicGroupPaymentCalenderQueryInfo;
import com.ym.mec.biz.service.ClassGroupService;
import com.ym.mec.biz.service.MusicGroupPaymentCalenderService;
import com.ym.mec.biz.service.SysConfigService;
import com.ym.mec.biz.service.SysMessageService;
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.page.PageInfo;
import com.ym.mec.common.service.IdGeneratorService;
import com.ym.mec.common.service.impl.BaseServiceImpl;
import com.ym.mec.thirdparty.message.MessageSenderPluginContext;
import com.ym.mec.util.collection.MapUtil;
import com.ym.mec.util.date.DateUtil;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;

import static com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PayUserType.SCHOOL;
import static com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PayUserType.STUDENT;
import static com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PaymentType.*;

@Service
public class MusicGroupPaymentCalenderServiceImpl extends BaseServiceImpl<Long, MusicGroupPaymentCalender> implements MusicGroupPaymentCalenderService {

	@Autowired
	private MusicGroupPaymentCalenderDao musicGroupPaymentCalenderDao;
	@Autowired
	private MusicGroupPaymentCalenderDetailDao musicGroupPaymentCalenderDetailDao;
	@Autowired
	private MusicGroupStudentFeeDao musicGroupStudentFeeDao;
	
	@Autowired
	private MusicGroupPaymentCalenderCourseSettingsDao musicGroupPaymentCalenderCourseSettingsDao;
	
	@Autowired
	private MusicGroupOrganizationCourseSettingsDetailDao musicGroupOrganizationCourseSettingsDetailDao;

	@Autowired
	private MusicGroupOrganizationCourseSettingsDao musicGroupOrganizationCourseSettingsDao;
	
	@Autowired
	private OrganizationCourseUnitPriceSettingsDao organizationCourseUnitPriceSettingsDao;
	
	@Autowired
	private MusicGroupPaymentStudentCourseDetailDao musicGroupPaymentStudentCourseDetailDao;
	
	@Autowired
	private IdGeneratorService idGeneratorService;
	
	@Autowired
	private ClassGroupService classGroupService;
	
	@Autowired
	private MusicGroupDao musicGroupDao;
	@Autowired
	private MusicGroupBuildLogDao musicGroupBuildLogDao;
	@Autowired
	private SysConfigDao sysConfigDao;
	@Autowired
	private OrganizationDao organizationDao;
	@Autowired
	private StudentRegistrationDao studentRegistrationDao;
	@Autowired
	private SysMessageService sysMessageService;
	@Autowired
	private SysUserFeignService sysUserFeignService;
	@Autowired
	private CourseScheduleStudentPaymentServiceImpl courseScheduleStudentPaymentService;

	@Override
	public BaseDAO<Long, MusicGroupPaymentCalender> getDAO() {
		return musicGroupPaymentCalenderDao;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Long create(MusicGroupPaymentCalender musicGroupPaymentCalender) {

		String musicGroupId = musicGroupPaymentCalender.getMusicGroupId();

		MusicGroup musicGroup = musicGroupDao.getLocked(musicGroupId);

		if (musicGroup == null) {
			throw new BizException("乐团查询失败，请检查参数");
		}
		SysUser sysUser = sysUserFeignService.queryUserInfo();
		if (sysUser == null) {
			throw new BizException("请登录");
		}
		//不是进行中，只能创建一次缴费
		if(musicGroup.getStatus() != MusicGroupStatusEnum.PROGRESS){
			List<MusicGroupPaymentCalender> list = musicGroupPaymentCalenderDao.findByMusicGroupId(musicGroupId);
			if(list.size() > 0){
				throw new BizException("创建失败，已经存在缴费信息");
			}
		}
		
		Date date = new Date();
		List<MusicGroupPaymentCalenderDetail> musicGroupPaymentCalenderDetailList = new ArrayList<>();
		musicGroupPaymentCalender.setOperator(sysUser.getId());
		musicGroupPaymentCalender.setCreateTime(date);
		musicGroupPaymentCalender.setUpdateTime(date);
		musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.NO);

		if (musicGroupPaymentCalender.getDeadlinePaymentDate() == null && musicGroupPaymentCalender.getPayUserType() == PayUserType.STUDENT) {
			musicGroupPaymentCalender.setDeadlinePaymentDate(DateUtil.addDays(musicGroupPaymentCalender.getStartPaymentDate(), 3));
		}
		if(musicGroupPaymentCalender.getPaymentType() != ADD_STUDENT){
			int count = musicGroupPaymentCalenderDao.queryIntersectionByValidDate(musicGroupId, musicGroupPaymentCalender.getPayUserType(), musicGroupPaymentCalender.getPaymentValidStartDate(),
					musicGroupPaymentCalender.getPaymentValidEndDate(), null);
			if (count > 0) {
				throw new BizException("缴费有效期存在冲突，请修改缴费有效期");
			}
		}
		// 获取设置的课程
		List<MusicGroupPaymentCalenderCourseSettings> musicGroupPaymentCalenderCourseSettingsList = musicGroupPaymentCalender
				.getMusicGroupPaymentCalenderCourseSettingsList();
		if (musicGroupPaymentCalenderCourseSettingsList == null) {
			musicGroupPaymentCalenderCourseSettingsList = new ArrayList<>();
		}
		if (musicGroupPaymentCalender.getPayUserType() == SCHOOL) {
			musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.AUDITING);
		} else {
			if (musicGroupPaymentCalender.getPaymentType() == MUSIC_APPLY || musicGroupPaymentCalender.getPaymentType() == MUSIC_RENEW) {
				// 当前缴费的课程费用
				Map<CourseScheduleType, BigDecimal> currentCoursePrice = musicGroupPaymentCalenderCourseSettingsList.stream().collect(
						Collectors
								.toMap(MusicGroupPaymentCalenderCourseSettings::getCourseType, MusicGroupPaymentCalenderCourseSettings::getCourseCurrentPrice));

				// 查询默认课程费用
				Integer musicGroupOrganizationCourseSettingId = musicGroupPaymentCalender.getMusicGroupOrganizationCourseSettingId();
				Map<CourseScheduleType, BigDecimal> defaultCoursePrice = musicGroupOrganizationCourseSettingsDetailDao
						.queryByMusicGroupOrganizationCourseSettingsId(musicGroupOrganizationCourseSettingId)
						.stream()
						.collect(
								Collectors.toMap(MusicGroupOrganizationCourseSettingsDetail::getCourseType,
										MusicGroupOrganizationCourseSettingsDetail::getCourseCurrentPrice));

				// 相同类型的课程如果修改了课程费用，需要走审批
				for (Entry<CourseScheduleType, BigDecimal> entry : currentCoursePrice.entrySet()) {
					if (defaultCoursePrice.get(entry.getKey()).compareTo(entry.getValue()) != 0) {
						musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.AUDITING);
						break;
					}
				}
			} else if (musicGroupPaymentCalender.getPaymentType() == PaymentType.ADD_COURSE || musicGroupPaymentCalender.getPaymentType() == PaymentType
					.ADD_STUDENT) {
				// 如果是临时加课，是否审核是根据单价判断
				for (MusicGroupPaymentCalenderCourseSettings courseSettings : musicGroupPaymentCalenderCourseSettingsList) {
					OrganizationCourseUnitPriceSettings defaultUnitPrice = organizationCourseUnitPriceSettingsDao.queryByOrganIdAndCourseTypeAndChargeType(
							musicGroup.getOrganId(), courseSettings.getCourseType(), musicGroup.getChargeTypeId());
					if (defaultUnitPrice == null) {
						throw new BizException("请先设置分部课程类型单价");
					}
					if (courseSettings.getCourseCurrentPrice().divide(new BigDecimal(courseSettings.getCourseTotalMinuties()), CommonConstants.DECIMAL_FINAL_PLACE, BigDecimal.ROUND_DOWN)
							.compareTo(defaultUnitPrice.getUnitPrice()) != 0) {
						musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.AUDITING);
						break;
					}
				}
			}
		}
		if (musicGroupPaymentCalender.getPaymentType() == PaymentType.ADD_STUDENT) {
			musicGroupPaymentCalender.setPayUserType(STUDENT);
			musicGroupPaymentCalender.setIsGiveMusicNetwork(false);
			if(musicGroupPaymentCalender.getStatus() != PaymentCalenderStatusEnum.AUDITING){
				musicGroupPaymentCalender.setExpectNum(1);
			}
		}
		if (musicGroupPaymentCalender.getStatus() != PaymentCalenderStatusEnum.AUDITING) {
			if (date.after(musicGroupPaymentCalender.getStartPaymentDate())) {
				musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.OPEN);
			}else if (date.after(musicGroupPaymentCalender.getDeadlinePaymentDate())) {
				musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.OVER);
			}else {
				musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.NO);
			}
		}else {
            Set<Integer> roleIds = new HashSet<>(1);
            roleIds.add(SysUserRole.ADMINISTRATOR);
            Organization organization = organizationDao.get(musicGroup.getOrganId());
            sysMessageService.batchSeoMessage(musicGroupDao.queryUserIdByRoleId(roleIds, musicGroup.getOrganId()), MessageTypeEnum.BACKSTAGE_PAYMENT_CALENDER_AUDIT, "", organization.getName(),musicGroup.getName());
		}

		// 如果是报名，需要修改乐团状态
		if (musicGroupPaymentCalender.getPaymentType() == MUSIC_APPLY) {
			int countAuditReject = musicGroupPaymentCalenderDao.countAuditReject(musicGroupPaymentCalender.getMusicGroupId(),null);
			if(countAuditReject == 0){
				if (musicGroup.getStatus() != MusicGroupStatusEnum.DRAFT) {
					throw new BizException("创建失败：缴费项目类型不匹配");
				}
				if(musicGroupPaymentCalender.getStatus() != PaymentCalenderStatusEnum.AUDITING){
					musicGroup.setStatus(MusicGroupStatusEnum.AUDIT);
					// 记录操作日志
					musicGroupBuildLogDao.insert(new MusicGroupBuildLog(musicGroupId, "报名缴费项目创建成功（草稿 -> 基础信息审核中）", sysUser.getId(), ""));
				}else{
					musicGroup.setStatus(MusicGroupStatusEnum.FEE_AUDIT);
					// 记录操作日志
					musicGroupBuildLogDao.insert(new MusicGroupBuildLog(musicGroupId, "报名缴费项目创建成功（草稿 -> 费用审核中）", sysUser.getId(), ""));
				}
				musicGroup.setUpdateTime(date);
				musicGroupDao.update(musicGroup);
			}
		}
		// 设置批次号
		musicGroupPaymentCalender.setBatchNo(idGeneratorService.generatorId() + "");
		musicGroupPaymentCalenderDao.insert(musicGroupPaymentCalender);
		
		if (musicGroupPaymentCalender.getStatus() != PaymentCalenderStatusEnum.AUDITING) {
			// 如果是进行中加学生
			if (musicGroupPaymentCalender.getPaymentType() == PaymentType.ADD_STUDENT) {
				addStudent(musicGroupPaymentCalender, musicGroupPaymentCalenderCourseSettingsList);
			}
		}

		if (musicGroupPaymentCalenderCourseSettingsList.size() > 0) {
			MusicGroupOrganizationCourseSettings courseSettings = musicGroupOrganizationCourseSettingsDao.get(musicGroupPaymentCalender
					.getMusicGroupOrganizationCourseSettingId());
			for (MusicGroupPaymentCalenderCourseSettings musicGroupPaymentCalenderCourseSettings : musicGroupPaymentCalenderCourseSettingsList) {
				musicGroupPaymentCalenderCourseSettings.setMusicGroupPaymentCalenderId(musicGroupPaymentCalender.getId());
				if (courseSettings != null) {
					musicGroupPaymentCalenderCourseSettings.setName(courseSettings.getName());
				}
			}
			musicGroupPaymentCalenderCourseSettingsDao.batchInsert(musicGroupPaymentCalenderCourseSettingsList);
		}

		if (musicGroupPaymentCalenderDetailList.size() > 0) {
			musicGroupPaymentCalenderDetailDao.batchInsert(musicGroupPaymentCalenderDetailList);
		}
		return musicGroupPaymentCalender.getId();
	}

	@Override
	public Object getDetail(Long id) {
		MusicGroupPaymentCalender calender = musicGroupPaymentCalenderDao.get(id);
		Map<Long, Long> expectNumMap = MapUtil.convertIntegerMap(musicGroupPaymentCalenderDao.countExpectNum(id));
		Map<Long, Long> actualNumMap = MapUtil.convertIntegerMap(musicGroupPaymentCalenderDao.countActualNum(id));
		calender.setActualNum(actualNumMap.get(id) == null ? 0 : actualNumMap.get(id).intValue());
		calender.setExpectNum(expectNumMap.get(id) == null ? 0 : expectNumMap.get(id).intValue());
		BigDecimal sumActualAmount = musicGroupPaymentCalenderDetailDao.sumActualAmount(id);
		//收费标准名称
		String name = musicGroupPaymentCalenderDao.getCalenderSettingsName(id);
		List<MusicGroupPaymentCalenderCourseSettings> musicGroupPaymentCalenderCourseSettings = musicGroupPaymentCalenderCourseSettingsDao.queryCalenderCourseSettings(id);
		Map<String, Object> result = new HashMap<>(4);
		result.put("musicGroupPaymentCalenderCourseSettings", musicGroupPaymentCalenderCourseSettings);
		result.put("calender", calender);
		result.put("calenderSettingsName", name);
		result.put("sumActualAmount", sumActualAmount);
		return result;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Long merge(MusicGroupPaymentCalender musicGroupPaymentCalender) {
		
		MusicGroupPaymentCalender originMusicGroupPaymentCalender = musicGroupPaymentCalenderDao.get(musicGroupPaymentCalender.getId());
		if(originMusicGroupPaymentCalender == null){
			throw new BizException("查询不到缴费记录");
		}
		SysUser sysUser = sysUserFeignService.queryUserInfo();
		if (sysUser == null) {
			throw new BizException("请登录");
		}
		//只有“拒绝”才能修改
		if(originMusicGroupPaymentCalender.getStatus() != PaymentCalenderStatusEnum.REJECT){
			throw new BizException("缴费记录只有被“审核拒绝”才能修改");
		}
		
		String musicGroupId = musicGroupPaymentCalender.getMusicGroupId();

		MusicGroup musicGroup = musicGroupDao.getLocked(musicGroupId);
		
		if(musicGroup == null){
			throw new BizException("乐团查询失败，请检查参数");
		}
		//如果是进行中加学生,查看学员是否在团
		if (musicGroupPaymentCalender.getPaymentType() == PaymentType.ADD_STUDENT) {
			musicGroupPaymentCalender.setStudentIds(originMusicGroupPaymentCalender.getStudentIds());
			StudentRegistration studentRegistration = studentRegistrationDao.queryByUserIdAndMusicGroupId(Integer.parseInt(musicGroupPaymentCalender.getStudentIds()),musicGroupId);
			if(studentRegistration == null){
				throw new BizException("修改失败：学员不存在或已退团");
			}
		}
		
		Date date = new Date();
		
		musicGroupPaymentCalender.setUpdateTime(date);
		if (musicGroupPaymentCalender.getDeadlinePaymentDate() == null && musicGroupPaymentCalender.getPayUserType() == PayUserType.STUDENT) {
			musicGroupPaymentCalender.setDeadlinePaymentDate(DateUtil.addDays(musicGroupPaymentCalender.getStartPaymentDate(), 3));
		}
		if(musicGroupPaymentCalender.getPaymentType() != ADD_STUDENT){
			int count = musicGroupPaymentCalenderDao.queryIntersectionByValidDate(musicGroupId, musicGroupPaymentCalender.getPayUserType(), musicGroupPaymentCalender.getPaymentValidStartDate(),
					musicGroupPaymentCalender.getPaymentValidEndDate(), musicGroupPaymentCalender.getId());
			if (count > 0) {
				throw new BizException("缴费有效期存在冲突，请修改缴费有效期");
			}
		}
		
		//获取设置的课程
		List<MusicGroupPaymentCalenderCourseSettings> musicGroupPaymentCalenderCourseSettingsList = musicGroupPaymentCalender.getMusicGroupPaymentCalenderCourseSettingsList();
		if (musicGroupPaymentCalenderCourseSettingsList == null) {
			musicGroupPaymentCalenderCourseSettingsList = new ArrayList<>();
		}
		if (musicGroupPaymentCalender.getPayUserType() == SCHOOL) {
			musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.AUDITING);
		} else {
			if (musicGroupPaymentCalender.getPaymentType() == MUSIC_APPLY || musicGroupPaymentCalender.getPaymentType() == MUSIC_RENEW) {
				// 当前缴费的课程费用
				Map<CourseScheduleType, BigDecimal> currentCoursePrice = musicGroupPaymentCalenderCourseSettingsList.stream().collect(
						Collectors
								.toMap(MusicGroupPaymentCalenderCourseSettings::getCourseType, MusicGroupPaymentCalenderCourseSettings::getCourseCurrentPrice));

				// 查询默认课程费用
				Integer musicGroupOrganizationCourseSettingId = musicGroupPaymentCalender.getMusicGroupOrganizationCourseSettingId();
				Map<CourseScheduleType, BigDecimal> defaultCoursePrice = musicGroupOrganizationCourseSettingsDetailDao
						.queryByMusicGroupOrganizationCourseSettingsId(musicGroupOrganizationCourseSettingId)
						.stream()
						.collect(
								Collectors.toMap(MusicGroupOrganizationCourseSettingsDetail::getCourseType,
										MusicGroupOrganizationCourseSettingsDetail::getCourseCurrentPrice));

				// 相同类型的课程如果修改了课程费用，需要走审批
				for (Entry<CourseScheduleType, BigDecimal> entry : currentCoursePrice.entrySet()) {
					if (defaultCoursePrice.get(entry.getKey()).compareTo(entry.getValue()) != 0) {
						musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.AUDITING);
						break;
					}
				}
			} else if (musicGroupPaymentCalender.getPaymentType() == PaymentType.ADD_COURSE || musicGroupPaymentCalender.getPaymentType() == PaymentType.ADD_STUDENT) {
				// 如果是临时加课，是否审核是根据单价判断
				for (MusicGroupPaymentCalenderCourseSettings courseSettings : musicGroupPaymentCalenderCourseSettingsList) {
					OrganizationCourseUnitPriceSettings defaultUnitPrice = organizationCourseUnitPriceSettingsDao.queryByOrganIdAndCourseTypeAndChargeType(
							musicGroup.getOrganId(), courseSettings.getCourseType(), musicGroup.getChargeTypeId());
					if (defaultUnitPrice == null) {
						throw new BizException("请先设置分部课程类型单价");
					}
					if (courseSettings.getCourseCurrentPrice().divide(new BigDecimal(courseSettings.getCourseTotalMinuties()), CommonConstants.DECIMAL_FINAL_PLACE, BigDecimal.ROUND_DOWN)
							.compareTo(defaultUnitPrice.getUnitPrice()) != 0) {
						musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.AUDITING);
						break;
					}
				}
			}
		}

		if (musicGroupPaymentCalender.getStatus() != PaymentCalenderStatusEnum.AUDITING) {
			if (date.after(musicGroupPaymentCalender.getStartPaymentDate())) {
				musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.OPEN);
			}else if (date.after(musicGroupPaymentCalender.getDeadlinePaymentDate())) {
				musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.OVER);
			}else {
				musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.NO);
			}
			
			//如果是进行中加学生
			if (musicGroupPaymentCalender.getPaymentType() == PaymentType.ADD_STUDENT) {
				addStudent(musicGroupPaymentCalender,musicGroupPaymentCalenderCourseSettingsList);
			}

		}else {
			if(musicGroupPaymentCalender.getPaymentType() == PaymentType.ADD_STUDENT){
				musicGroupPaymentCalender.setExpectNum(1);
			}
            Set<Integer> roleIds = new HashSet<>(1);
            roleIds.add(SysUserRole.ADMINISTRATOR);
            Organization organization = organizationDao.get(musicGroup.getOrganId());
            sysMessageService.batchSeoMessage(musicGroupDao.queryUserIdByRoleId(roleIds, musicGroup.getOrganId()), MessageTypeEnum.BACKSTAGE_PAYMENT_CALENDER_AUDIT, "", organization.getName(),musicGroup.getName());
        }

		// 如果是报名，需要修改乐团状态
		if (musicGroupPaymentCalender.getPaymentType() == MUSIC_APPLY) {
			int countAuditReject = musicGroupPaymentCalenderDao.countAuditReject(musicGroupPaymentCalender.getMusicGroupId(),musicGroupPaymentCalender.getId());
			if(countAuditReject == 0){
				if (musicGroup.getStatus() != MusicGroupStatusEnum.DRAFT && musicGroup.getStatus() != MusicGroupStatusEnum.AUDIT_FAILED) {
					throw new BizException("创建失败：缴费项目类型不匹配");
				}
				if(musicGroupPaymentCalender.getStatus() != PaymentCalenderStatusEnum.AUDITING){
					musicGroup.setStatus(MusicGroupStatusEnum.AUDIT);
					// 记录操作日志
					musicGroupBuildLogDao.insert(new MusicGroupBuildLog(musicGroupId, "报名缴费项目创建成功（草稿 -> 基础信息审核中）", sysUser.getId(), ""));
					Set<Integer> roleIds = new HashSet<>(1);
					roleIds.add(SysUserRole.SECTION_MANAGER);
					sysMessageService.batchSeoMessage(musicGroupDao.queryUserIdByRoleId(roleIds, musicGroup.getOrganId()), MessageTypeEnum.BACKSTAGE_CREATE_MUSIC_GROUP_APPLY, "", sysUser.getUsername());
				}else{
					musicGroup.setStatus(MusicGroupStatusEnum.FEE_AUDIT);
					// 记录操作日志
					musicGroupBuildLogDao.insert(new MusicGroupBuildLog(musicGroupId, "报名缴费项目创建成功（草稿 -> 费用审核中）", sysUser.getId(), ""));
				}
				musicGroup.setUpdateTime(date);
				musicGroupDao.update(musicGroup);
			}
		}
		
		musicGroupPaymentCalenderDao.update(musicGroupPaymentCalender);

		musicGroupPaymentCalenderCourseSettingsDao.deleteByMusicGroupPaymentCalenderId(musicGroupPaymentCalender.getId());
		
		if(musicGroupPaymentCalenderCourseSettingsList.size() > 0){
			MusicGroupOrganizationCourseSettings courseSettings = musicGroupOrganizationCourseSettingsDao.get(musicGroupPaymentCalender
					.getMusicGroupOrganizationCourseSettingId());
			for (MusicGroupPaymentCalenderCourseSettings musicGroupPaymentCalenderCourseSettings : musicGroupPaymentCalenderCourseSettingsList) {
				musicGroupPaymentCalenderCourseSettings.setMusicGroupPaymentCalenderId(musicGroupPaymentCalender.getId());
				if (courseSettings != null) {
					musicGroupPaymentCalenderCourseSettings.setName(courseSettings.getName());
				}
			}
			musicGroupPaymentCalenderCourseSettingsDao.batchInsert(musicGroupPaymentCalenderCourseSettingsList);
		}
		
		return musicGroupPaymentCalender.getId();
	}

	@Override
	public boolean makesureSchoolePaid(Long id, String memo) {
		MusicGroupPaymentCalender musicGroupPaymentCalender = musicGroupPaymentCalenderDao.get(id);
		if(musicGroupPaymentCalender == null){
			throw new BizException("查询缴费信息失败");
		}
		
		if(musicGroupPaymentCalender.getPayUserType() != PayUserType.SCHOOL){
			throw new BizException("只有学校缴费才能确认缴费状态");
		}
		
		musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.PAID);
		musicGroupPaymentCalender.setMemo(memo);
		musicGroupPaymentCalender.setUpdateTime(new Date());
		musicGroupPaymentCalenderDao.update(musicGroupPaymentCalender);
		
		return true;
	}

	public void addStudent(MusicGroupPaymentCalender musicGroupPaymentCalender,List<MusicGroupPaymentCalenderCourseSettings> musicGroupPaymentCalenderCourseSettingsList){
		//如果是进行中加学生
		Date date = new Date();
		String studentIdStr = musicGroupPaymentCalender.getStudentIds();
		if (StringUtils.isNoneBlank(studentIdStr)) {
			//计算总费用
			BigDecimal totalPrice = new BigDecimal(0);
			for(MusicGroupPaymentCalenderCourseSettings musicGroupPaymentCalenderCourseSettings : musicGroupPaymentCalenderCourseSettingsList){
				totalPrice = totalPrice.add(musicGroupPaymentCalenderCourseSettings.getCourseCurrentPrice());
			}

			List<MusicGroupPaymentStudentCourseDetail> musicGroupPaymentStudentCourseDetailList = new ArrayList<MusicGroupPaymentStudentCourseDetail>();
			MusicGroupPaymentStudentCourseDetail musicGroupPaymentStudentCourseDetail = null;

			for (String studentId : studentIdStr.split(",")) {
				// 学生加到calenderDetail
				MusicGroupPaymentCalenderDetail musicGroupPaymentCalenderDetail = new MusicGroupPaymentCalenderDetail();
				musicGroupPaymentCalenderDetail.setMusicGroupPaymentCalenderId(musicGroupPaymentCalender.getId());
				musicGroupPaymentCalenderDetail.setCreateTime(date);
				musicGroupPaymentCalenderDetail.setExpectAmount(totalPrice);
				musicGroupPaymentCalenderDetail.setPaymentStatus(PaymentStatus.NON_PAYMENT);
				musicGroupPaymentCalenderDetail.setUpdateTime(date);
				musicGroupPaymentCalenderDetail.setUserId(Integer.parseInt(studentId));
				musicGroupPaymentCalenderDetail.setStartPaymentDate(musicGroupPaymentCalender.getStartPaymentDate());
				musicGroupPaymentCalenderDetail.setDeadlinePaymentDate(musicGroupPaymentCalender.getDeadlinePaymentDate());

				musicGroupPaymentCalenderDetailDao.insert(musicGroupPaymentCalenderDetail);

				// 学生加课程明细
				for(MusicGroupPaymentCalenderCourseSettings courseSettings : musicGroupPaymentCalenderCourseSettingsList){
					if (courseSettings.getIsStudentOptional() == true) {
						continue;
					}
					musicGroupPaymentStudentCourseDetail = new MusicGroupPaymentStudentCourseDetail();
					musicGroupPaymentStudentCourseDetail.setCourseType(courseSettings.getCourseType());
					musicGroupPaymentStudentCourseDetail.setCreateTime(date);
					musicGroupPaymentStudentCourseDetail.setMusicGroupPaymentCalenderId(musicGroupPaymentCalender.getId());
					musicGroupPaymentStudentCourseDetail.setMusicGroupPaymentCalenderDetailId(musicGroupPaymentCalenderDetail.getId());
					musicGroupPaymentStudentCourseDetail.setTotalCourseMinutes(courseSettings.getCourseTotalMinuties());
					musicGroupPaymentStudentCourseDetail.setUpdateTime(date);
					musicGroupPaymentStudentCourseDetail.setUsedCourseMinutes(0);
					musicGroupPaymentStudentCourseDetail.setUserId(Integer.parseInt(studentId));

					musicGroupPaymentStudentCourseDetailList.add(musicGroupPaymentStudentCourseDetail);
				}

				if(musicGroupPaymentStudentCourseDetailList.size() > 0){
					musicGroupPaymentStudentCourseDetailDao.batchInsert(musicGroupPaymentStudentCourseDetailList);
				}

				// 学生加到班级
				String classGroupIdStr = musicGroupPaymentCalender.getAttribute1();
				if(StringUtils.isNotBlank(classGroupIdStr)){
					classGroupService.addStudentToClassGroupAndCourseArranging(Integer.parseInt(studentId), classGroupIdStr, musicGroupPaymentCalender.getBatchNo(), musicGroupPaymentCalenderCourseSettingsList);
				}
			}
		}
	}

	@Override
	public void autoUpdateMusicGroupStudentFeeStatus() {
		Date date = new Date();
		String format = DateUtil.format(date, DateUtil.DEFAULT_PATTERN);
		// 获取距离缴费开启指定天数后的缴费明细
		String configValue = sysConfigDao.findConfigValue("push_payment_detail");
		Map<Long, Long> maps = MapUtil.convertIntegerMap(musicGroupPaymentCalenderDao.queryCalenderByDay(configValue, format));
		if (maps != null && maps.size() > 0) {
			Set<Long> calenderId = maps.keySet();
			List<CalenderPushDto> calenderPushDtos = musicGroupPaymentCalenderDao.getCalenderPushDto(calenderId);
			Map<Long, List<CalenderPushDto>> collect = calenderPushDtos.stream().collect(Collectors.groupingBy(CalenderPushDto::getCalenderId));
			calenderId.forEach(e -> {
				CalenderPushDto calenderPushDto = collect.get(e).get(0);
				Map<Integer, String> receivers = new HashMap<>(1);
				receivers.put(calenderPushDto.getTeacherId(), calenderPushDto.getTeacherPhone());
				sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, MessageTypeEnum.SMS_PAYMENT_DETAIL, receivers, null, 0,
						null, null, calenderPushDto.getMusicGroupName(), calenderPushDto.getPaymentValidStartDate(), calenderPushDto.getPaymentValidEndDate(),
						maps.get(e));
			});
		}
		// 获取离截止还有指定时间的缴费项，并发送推送消息给指定老师
		String configValue1 = sysConfigDao.findConfigValue("push_create_payment_calender");
		List<Long> calenderIds = musicGroupPaymentCalenderDao.queryEndIds(configValue1, format);
		if (calenderIds != null && calenderIds.size() > 0) {
			List<CalenderPushDto> calenderPushDtos = musicGroupPaymentCalenderDao.getCalenderPushDto(calenderIds);
			Map<Long, List<CalenderPushDto>> collect = calenderPushDtos.stream().collect(Collectors.groupingBy(CalenderPushDto::getCalenderId));
			calenderIds.forEach(e -> {
				CalenderPushDto calenderPushDto = collect.get(e).get(0);
				Map<Integer, String> receivers = new HashMap<>(1);
				receivers.put(calenderPushDto.getTeacherId(), calenderPushDto.getTeacherPhone());
				sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, MessageTypeEnum.SMS_PAYMENT_CREATE, receivers, null, 0,
						null, null, calenderPushDto.getMusicGroupName(), calenderPushDto.getPaymentValidStartDate(), calenderPushDto.getPaymentValidEndDate());
			});
		}

		// 乐团报名到期，提醒教务老师创建缴费
		List<CalenderPushDto> calenderPushDtos = musicGroupPaymentCalenderDao.getMusicCalenderPushDto(configValue1, format);
		if (calenderPushDtos != null && calenderPushDtos.size() > 0) {
			calenderPushDtos.forEach(e -> {
				Map<Integer, String> receivers = new HashMap<>(1);
				receivers.put(e.getTeacherId(), e.getTeacherPhone());
				sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, MessageTypeEnum.SMS_PAYMENT_CREATE, receivers, null, 0,
						null, null, e.getMusicGroupName(), e.getPaymentValidStartDate(), e.getPaymentValidEndDate());
			});
		}
	}

	@Override
	public PageInfo<MusicGroupPaymentCalenderAuditDto> auditList(MusicGroupPaymentCalenderQueryInfo queryInfo) {
		PageInfo<MusicGroupPaymentCalenderAuditDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
		Map<String, Object> params = new HashMap<>();
		MapUtil.populateMap(params, queryInfo);

		List<MusicGroupPaymentCalenderAuditDto> dataList = null;
		int count = musicGroupPaymentCalenderDao.countAuditList(params);
		if (count > 0) {
			pageInfo.setTotal(count);
			params.put("offset", pageInfo.getOffset());
			dataList = musicGroupPaymentCalenderDao.queryAuditList(params);
			List<Integer> collect = dataList.stream().map(e -> e.getOrganId()).collect(Collectors.toList());
			collect.removeAll(Collections.singleton(null));
			Map<Integer, String> organNameMap = getMap("organization", "id_", "name_", collect, Integer.class, String.class);
			List<Integer> operatorIds = dataList.stream().map(e -> e.getOperator()).collect(Collectors.toList());
			operatorIds.removeAll(Collections.singleton(null));
			Map<Integer, String> realNameMap = getMap("sys_user", "id_", "real_name_", operatorIds, Integer.class, String.class);
			dataList.forEach(e->{
				e.setOrganName(organNameMap.get(e.getOrganId()));
				e.setOperatorName(realNameMap.get(e.getOperator()));
			});
		}
		if (count == 0) {
			dataList = new ArrayList<>();
		}
		pageInfo.setRows(dataList);
		return pageInfo;
	}

	@Override
	public MusicGroupPaymentCalenderAuditDetailDto auditListDetail(Long calenderId) {
		MusicGroupPaymentCalenderAuditDetailDto calenderAuditDetailDto = new MusicGroupPaymentCalenderAuditDetailDto();
		MusicGroupPaymentCalenderAuditDto auditDto = musicGroupPaymentCalenderDao.getAuditDetail(calenderId);
		if(auditDto.getOrganId() != null){
			Organization organization = organizationDao.get(auditDto.getOrganId());
			auditDto.setOrganName(organization.getName());
		}
		calenderAuditDetailDto.setAuditDto(auditDto);

		//获取收费标准
		calenderAuditDetailDto.setMusicGroupPaymentCalenderCourseSettings(musicGroupPaymentCalenderCourseSettingsDao.queryCalenderCourseSettings(calenderId));
		//获取学员列表
		calenderAuditDetailDto.setBasicUserDtos(musicGroupPaymentCalenderDetailDao.querySimpleUserDto(calenderId,auditDto.getMusicGroupId()));
		calenderAuditDetailDto.setStudentNum(calenderAuditDetailDto.getSimpleUserDto().size());
		return calenderAuditDetailDto;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void auditPass(Long calenderId,String auditMemo) {
		MusicGroupPaymentCalender musicGroupPaymentCalender = musicGroupPaymentCalenderDao.get(calenderId);
		Date date = new Date();
		//如果是报名项目，将乐团改为审核中，缴费项目修改状态，审核状态改为审核通过
		if(musicGroupPaymentCalender.getPayUserType() == SCHOOL){
			musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.OPEN);
		}else if (date.after(musicGroupPaymentCalender.getStartPaymentDate())) {
			musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.OPEN);
		}else if (date.after(musicGroupPaymentCalender.getDeadlinePaymentDate())) {
			musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.OVER);
		}else {
			musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.NO);
		}
		musicGroupPaymentCalender.setAuditMemo(auditMemo);
		musicGroupPaymentCalender.setUpdateTime(date);

		//如果是报名，并且所有的报名都审核通过，需要修改乐团状态
		if (musicGroupPaymentCalender.getPaymentType() == MUSIC_APPLY) {
			int count = musicGroupPaymentCalenderDao.countAuditReject(musicGroupPaymentCalender.getMusicGroupId(),calenderId);
			if(count == 0){
				MusicGroup musicGroup = musicGroupDao.get(musicGroupPaymentCalender.getMusicGroupId());
				musicGroup.setStatus(MusicGroupStatusEnum.AUDIT);
				musicGroup.setUpdateTime(date);
				musicGroupDao.update(musicGroup);
				SysUser sysUser = sysUserFeignService.queryUserInfo();
				if(sysUser == null || sysUser.getId() == null){
					throw new BizException("请重新登录");
				}
				//记录操作日志
				musicGroupBuildLogDao.insert(new MusicGroupBuildLog(musicGroup.getId(), "报名缴费项目通过（草稿 -> 审核中）", sysUser.getId(), ""));
				Set<Integer> roleIds = new HashSet<>(1);
				roleIds.add(SysUserRole.SECTION_MANAGER);
				sysMessageService.batchSeoMessage(musicGroupDao.queryUserIdByRoleId(roleIds, musicGroup.getOrganId()), MessageTypeEnum.BACKSTAGE_CREATE_MUSIC_GROUP_APPLY, "", sysUser.getUsername());
			}
		}else if (musicGroupPaymentCalender.getPaymentType() == PaymentType.ADD_STUDENT) {
			musicGroupPaymentCalender.setExpectNum(1);
			List<MusicGroupPaymentCalenderCourseSettings> musicGroupPaymentCalenderCourseSettings = musicGroupPaymentCalenderCourseSettingsDao.queryCalenderCourseSettings(calenderId);
			addStudent(musicGroupPaymentCalender,musicGroupPaymentCalenderCourseSettings);
		}
		musicGroupPaymentCalenderDao.update(musicGroupPaymentCalender);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void auditRefuse(Long calenderId,String auditMemo) {
		MusicGroupPaymentCalender musicGroupPaymentCalender = musicGroupPaymentCalenderDao.get(calenderId);
		Date date = new Date();
		musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.REJECT);
		musicGroupPaymentCalender.setUpdateTime(date);
		musicGroupPaymentCalender.setAuditMemo(auditMemo);
		musicGroupPaymentCalenderDao.update(musicGroupPaymentCalender);
		if (musicGroupPaymentCalender.getPaymentType() == MUSIC_APPLY) {
			MusicGroup musicGroup = musicGroupDao.get(musicGroupPaymentCalender.getMusicGroupId());
			musicGroup.setStatus(MusicGroupStatusEnum.DRAFT);
			musicGroup.setUpdateTime(date);
			musicGroupDao.update(musicGroup);
			SysUser sysUser = sysUserFeignService.queryUserInfo();
			if(sysUser == null || sysUser.getId() == null){
				throw new BizException("请重新登录");
			}
			//记录操作日志
			musicGroupBuildLogDao.insert(new MusicGroupBuildLog(musicGroup.getId(), "报名缴费项目失败（费用审核中 -> 草稿）", sysUser.getId(), ""));
		}
	}

	//推送待续费通知
	public void pushWaitRenewMessage(Long calenderId,MusicGroup musicGroup){
		Set<Integer> studentIds = musicGroupPaymentCalenderDetailDao.queryNoPaymentStudentIds(calenderId);
		if (studentIds.size() > 0) {
			Map<Integer, String> push = new HashMap<>();
			for (Integer userId : studentIds) {
				push.put(userId, userId + "");
			}
			String baseUrl = sysConfigDao.findConfigValue(SysConfigService.BASE_API_URL);
			String memo = "4?" + baseUrl + "/#/renew?musicGroupId=" + musicGroup.getId();
			// 发送续费通知
			sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.STUDENT_PUSH_WAIT_RENEW_MESSAGE, push,
					null, 0, memo, "STUDENT", musicGroup.getName());
		}
	}

    @Override
	@Transactional(rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED)
	public boolean autoUpdateMusicGroupPaymentCalenderStatus() {
		Date date = new Date();
		List<PaymentStatusEnum> statusList = new ArrayList<PaymentStatusEnum>();
		statusList.add(PaymentStatusEnum.NO);
		statusList.add(PaymentStatusEnum.OPEN);
		List<MusicGroupPaymentCalender> musicGroupPaymentCalenderList = musicGroupPaymentCalenderDao.queryByPaymentStatus(statusList,PayUserType.STUDENT.getCode());

		List<MusicGroupPaymentCalender> updateMusicGroupPaymentCalenderList = new ArrayList<MusicGroupPaymentCalender>();
		for (MusicGroupPaymentCalender mgpc : musicGroupPaymentCalenderList) {
			if (mgpc.getDeadlinePaymentDate() != null && date.after(mgpc.getDeadlinePaymentDate()) && mgpc.getStatus() == PaymentCalenderStatusEnum.OPEN) {
				// “进行中”更新至“已结束”
				mgpc.setUpdateTime(date);
				mgpc.setStatus(PaymentCalenderStatusEnum.OVER);
				updateMusicGroupPaymentCalenderList.add(mgpc);

			} else if (mgpc.getStartPaymentDate() != null && date.after(mgpc.getStartPaymentDate()) && mgpc.getStatus() == PaymentCalenderStatusEnum.NO) {
				MusicGroup musicGroup = musicGroupDao.get(mgpc.getMusicGroupId());
				//如果乐团还在审核中
				if(musicGroup.getStatus() == MusicGroupStatusEnum.DRAFT || musicGroup.getStatus() == MusicGroupStatusEnum.AUDIT|| musicGroup.getStatus() == MusicGroupStatusEnum.AUDIT_FAILED){
					continue;
				}
				// “未开始”更新至“进行中”
				mgpc.setUpdateTime(date);
				mgpc.setStatus(PaymentCalenderStatusEnum.OPEN);
				updateMusicGroupPaymentCalenderList.add(mgpc);
				//推送待续费通知
				pushWaitRenewMessage(mgpc.getId(),musicGroup);
			}
		}
		if (updateMusicGroupPaymentCalenderList.size() > 0) {
			musicGroupPaymentCalenderDao.batchUpdate(updateMusicGroupPaymentCalenderList);
		}
		return true;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void batchInsert(List<MusicGroupPaymentCalender> musicGroupPaymentCalenders) {
		if (musicGroupPaymentCalenders != null && musicGroupPaymentCalenders.size() > 0) {
			musicGroupPaymentCalenderDao.delByGroupId(musicGroupPaymentCalenders.get(0).getMusicGroupId());
			musicGroupPaymentCalenders.forEach(e -> {
				musicGroupPaymentCalenderDao.insert(e);
			});
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateStartTime(MusicGroupPaymentCalender paymentCalender) {
		// if (startTime == null || id == null || endTime == null) {
		// throw new BizException("参数校验失败");
		// }
		MusicGroupPaymentCalender calender = musicGroupPaymentCalenderDao.get(paymentCalender.getId());
		if (calender == null) {
			throw new BizException("缴费信息不存在");
		}
		if (calender.getStatus() == null || calender.getStatus() != PaymentCalenderStatusEnum.NO) {
			throw new BizException("修改失败,缴费状态不匹配");
		}
		Date date = new Date();
		// 判断缴费开始时间、结束时间是否被其他缴费记录占用
//		int count = musicGroupPaymentCalenderDao.queryIntersectionByPaymentDate(calender.getMusicGroupId(), paymentCalender.getStartPaymentDate(),
//				paymentCalender.getDeadlinePaymentDate(), paymentCalender.getId());
		// String format = DateUtil.format(startTime, DateUtil.DEFAULT_PATTERN);
		// String format1 = DateUtil.format(endTime, DateUtil.DEFAULT_PATTERN);
		// int count = musicGroupPaymentCalenderDao.queryIntersectionByDate(calender.getMusicGroupId(), format,format1);
		/*if (count > 0) {
			throw new BizException("缴费时间存在冲突，请修改缴费开始日期");
		}*/
		if(paymentCalender.getPaymentType() != ADD_STUDENT){
			int count = musicGroupPaymentCalenderDao.queryIntersectionByValidDate(paymentCalender.getMusicGroupId(), paymentCalender.getPayUserType(), paymentCalender.getPaymentValidStartDate(),
					paymentCalender.getPaymentValidEndDate(), paymentCalender.getId());
			if (count > 0) {
				throw new BizException("缴费有效期存在冲突，请修改缴费有效期");
			}
		}
		calender.setStartPaymentDate(paymentCalender.getStartPaymentDate());
		calender.setDeadlinePaymentDate(paymentCalender.getDeadlinePaymentDate());
		calender.setPaymentValidStartDate(paymentCalender.getPaymentValidStartDate());
		calender.setPaymentValidEndDate(paymentCalender.getPaymentValidEndDate());
		calender.setPaymentPattern(paymentCalender.getPaymentPattern());
		calender.setUpdateTime(date);
		if (paymentCalender.getDeadlinePaymentDate().before(date) && !DateUtil.isSameDay(date, paymentCalender.getDeadlinePaymentDate())) {
			calender.setStatus(PaymentCalenderStatusEnum.OVER);
		} else if (date.after(paymentCalender.getStartPaymentDate()) || DateUtil.isSameDay(date, paymentCalender.getStartPaymentDate())) {
			calender.setStatus(PaymentCalenderStatusEnum.OPEN);
			// 修改Fee缴费状态为未缴费
			musicGroupStudentFeeDao.updatePaymentStatus(calender.getId(), "NON_PAYMENT");
			List<MusicGroupPaymentCalenderDetail> details = musicGroupPaymentCalenderDetailDao.queryByCalenderId(calender.getId(),null);
			Set<Integer> studentIds = details.stream().map(e -> e.getUserId()).collect(Collectors.toSet());
			if (studentIds.size() > 0) {
				Map<Integer, String> push = new HashMap<>();
				for (Integer userId : studentIds) {
					push.put(userId, userId + "");
				}
				MusicGroup musicGroup = musicGroupDao.get(calender.getMusicGroupId());
				String configValue = sysConfigDao.findConfigValue(SysConfigService.BASE_API_URL);
				String memo = "4?" + configValue + "/#/renew?musicGroupId=" + musicGroup.getId();
				// 发送续费通知
				sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.STUDENT_PUSH_WAIT_RENEW_MESSAGE, push,
						null, 0, memo, "STUDENT", musicGroup.getName());
			}
		} else {
			calender.setStatus(PaymentCalenderStatusEnum.NO);
		}
		musicGroupPaymentCalenderDao.update(calender);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void del(Long id) {
		if (id == null) {
			throw new BizException("参数校验失败");
		}
		MusicGroupPaymentCalender calender = musicGroupPaymentCalenderDao.get(id);
		if (calender == null) {
			throw new BizException("缴费信息不存在");
		}
		if (calender.getStatus() != PaymentCalenderStatusEnum.NO || calender.getStatus() != PaymentCalenderStatusEnum.REJECT) {
			throw new BizException("删除失败,只有“拒绝”或“未开启缴费”状态才能删除");
		}

		List<MusicGroupPaymentCalenderDetail> musicGroupPaymentCalenderDetailList = musicGroupPaymentCalenderDetailDao.queryByCalenderId(id,null);
		if (musicGroupPaymentCalenderDetailList != null && musicGroupPaymentCalenderDetailList.size() > 0) {
			List<MusicGroupPaymentCalenderDetail> paidList = musicGroupPaymentCalenderDetailList.stream()
					.filter(MusicGroupPaymentCalenderDetail -> MusicGroupPaymentCalenderDetail.getPaymentStatus() != PaymentStatus.NON_PAYMENT)
					.collect(Collectors.toList());
			if (paidList.size() > 0) {
				throw new BizException("存在已缴费的学生不能删除");
			}
		}

		musicGroupPaymentCalenderDao.delete(id);
		musicGroupPaymentCalenderDetailDao.deleteByCalenderId(id);
		musicGroupPaymentCalenderCourseSettingsDao.deleteByMusicGroupPaymentCalenderId(id);
	}

	@Override
	public void paymentPush(Long id, String userIds) {
		// 推送所有
		if (StringUtils.isEmpty(userIds)) {
			List<MusicGroupPaymentCalenderDetail> details = musicGroupPaymentCalenderDetailDao.queryCanPushList(id);
			if (details == null || details.size() == 0) {
				return;
			}
			String musicGroupId = details.get(0).getMusicGroupId();
			Set<Integer> studentIds = details.stream().map(e -> e.getUserId()).collect(Collectors.toSet());
			// 推送消息
			if (studentIds.size() > 0) {
				Map<Integer, String> push = new HashMap<>();
				for (Integer userId : studentIds) {
					push.put(userId, userId + "");
				}
				MusicGroup musicGroup = musicGroupDao.get(musicGroupId);
				String baseUrl = sysConfigDao.findConfigValue(SysConfigService.BASE_API_URL);
				String memo = "4?" + baseUrl + "/#/renew?musicGroupId=" + musicGroupId;
				// 发送续费通知
				sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.STUDENT_PUSH_WAIT_RENEW_MESSAGE, push,
						null, 0, memo, "STUDENT", musicGroup.getName());
			}
		} else {
			// 获取课推送列表
			// 批量推送
			MusicGroupPaymentCalender calender = musicGroupPaymentCalenderDao.get(id);
			Set<String> studentIds = new HashSet<>(Arrays.asList(userIds.split(",")));
			if (studentIds.size() > 0) {
				Map<Integer, String> push = new HashMap<>();
				for (String userId : studentIds) {
					push.put(Integer.parseInt(userId), userId + "");
				}
				MusicGroup musicGroup = musicGroupDao.get(calender.getMusicGroupId());
				String baseUrl = sysConfigDao.findConfigValue(SysConfigService.BASE_API_URL);
				String memo = "4?" + baseUrl + "/#/renew?musicGroupId=" + calender.getMusicGroupId();
				// 发送续费通知
				sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.STUDENT_PUSH_WAIT_RENEW_MESSAGE, push,
						null, 0, memo, "STUDENT", musicGroup.getName());
			}
		}
	}

	@Override
	public MusicGroupPaymentCalender findByMusicGroupRegCalender(String musicGroupId) {
		return musicGroupPaymentCalenderDao.findByMusicGroupRegCalender(musicGroupId);
	}

	@Transactional(rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED)
	public MusicGroupStudentFee updateCalender(Long calenderDetailId,Integer userId){
		Date date = new Date();
		MusicGroupPaymentCalenderDetail calenderDetail = musicGroupPaymentCalenderDetailDao.get(calenderDetailId);
		MusicGroupPaymentCalender calender = this.get(calenderDetail.getMusicGroupPaymentCalenderId());
		MusicGroupStudentFee musicGroupStudentFee = musicGroupStudentFeeDao.findByUser(userId, calender.getMusicGroupId());
		if(calender.getIsGiveMusicNetwork()){
			//赠送网管课
			musicGroupStudentFee.setRemainNetworkClassTimes(musicGroupStudentFee.getRemainNetworkClassTimes() + 1);
		}
		//更新学生的缴费记录状态
		calenderDetail.setPaymentStatus(MusicGroupStudentFee.PaymentStatus.PAID_COMPLETED);
		calenderDetail.setActualAmount(calenderDetail.getExpectAmount());
		calenderDetail.setPayTime(date);
		calenderDetail.setUpdateTime(date);
		musicGroupPaymentCalenderDetailDao.update(calenderDetail);

		//更新实际缴费人数
		Integer actualNum = calender.getActualNum() == null ? 0 : calender.getActualNum();
		calender.setActualNum(actualNum + 1);
		calender.setUpdateTime(date);
		musicGroupPaymentCalenderDao.update(calender);
		courseScheduleStudentPaymentService.updateForMusicGroupWithPaymentCalender(calender.getBatchNo());
		return musicGroupStudentFee;
	}

}
