package com.pollex.pam.service;
|
|
import com.pollex.pam.config.ApplicationProperties;
|
import com.pollex.pam.config.Constants;
|
import com.pollex.pam.domain.*;
|
import com.pollex.pam.enums.AppointmentStatusEnum;
|
import com.pollex.pam.enums.ContactStatusEnum;
|
import com.pollex.pam.enums.SatisfactionStatusEnum;
|
import com.pollex.pam.repository.AppointmentCustomerViewRepository;
|
import com.pollex.pam.repository.AppointmentExpiringNotifyRecordRepository;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.util.StringUtils;
|
import org.thymeleaf.context.Context;
|
import org.thymeleaf.spring5.SpringTemplateEngine;
|
|
import java.time.Instant;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.Optional;
|
import java.util.stream.Collectors;
|
|
@Service
|
@Transactional
|
public class ScheduleTaskService {
|
|
private static final String NOT_CONTACTED_NOTIFY_SUBJECT = "預約單未進行聯繫通知";
|
private static final Logger log = LoggerFactory.getLogger(ScheduleTaskService.class);
|
|
@Autowired
|
ConsultantService consultantService;
|
|
@Autowired
|
AppointmentService appointmentService;
|
|
@Autowired
|
AppointmentCustomerViewRepository appointmentCustomerViewRepository;
|
|
@Autowired
|
SendMsgService sendMsgService;
|
|
@Autowired
|
SpringTemplateEngine springTemplateEngine;
|
|
@Autowired
|
ApplicationProperties applicationProperties;
|
|
@Autowired
|
AppointmentExpiringNotifyRecordRepository appointmentExpiringNotifyRecordRepository;
|
|
@Autowired
|
SatisfactionService satisfactionService;
|
|
@Autowired
|
PersonalNotificationService personalNotificationService;
|
|
@Scheduled(cron = "0 30 8 * * *")
|
public void sendAppointmentPendingNotifyToConsultant() {
|
log.info("Starting send appointment pending notify to consultant");
|
|
Map<String, List<AppointmentCustomerView>> consultantWithPendingAppointments =
|
appointmentCustomerViewRepository.findAllByCommunicateStatusAndStatus(ContactStatusEnum.RESERVED, AppointmentStatusEnum.AVAILABLE)
|
.stream()
|
.filter(appointment ->
|
appointmentService.isAppointmentDateNotInIntervalFromNow(appointment, Constants.APPOINTMENT_PENDING_PHONE_INTERVAL, Constants.APPOINTMENT_PENDING_EMAIL_INTERVAL)
|
)
|
.collect(Collectors.groupingBy(AppointmentCustomerView::getAgentNo));
|
|
consultantWithPendingAppointments.forEach((agentNo, pendingAppointments) -> {
|
int pendingAppointmentsSum = pendingAppointments.size();
|
Consultant consultant = consultantService.findByAgentNo(agentNo);
|
Optional<String> optionalPhone = Optional.ofNullable(consultant.getPhoneNumber()).filter(StringUtils::hasText);
|
Optional<String> optionalEmail = Optional.ofNullable(consultant.getEmail()).filter(StringUtils::hasText);
|
|
String emailContent = getAppointmentPendingNotifyEmailContent(pendingAppointmentsSum);
|
|
optionalPhone.ifPresent(phone -> {
|
sendMsgService.sendMsgBySMS(phone, String.format("您有%s則預約單未進行聯繫,請盡速處理", pendingAppointmentsSum));
|
});
|
optionalEmail.ifPresent(email -> {
|
sendMsgService.sendMsgByEmail(email, NOT_CONTACTED_NOTIFY_SUBJECT, emailContent, true);
|
});
|
});
|
|
log.info("Sending appointment pending notify to consultant finish");
|
}
|
|
@Scheduled(cron = "0 30 8 * * *")
|
public void sendAppointmentExpiringNotifyToCustomer() {
|
log.info("Starting send appointment expiring notify to customer");
|
|
List<AppointmentCustomerView> allByCommunicateStatus =
|
appointmentCustomerViewRepository.findAllByCommunicateStatusAndStatus(ContactStatusEnum.RESERVED, AppointmentStatusEnum.AVAILABLE)
|
.stream()
|
.filter(appointment ->
|
appointmentService.isAppointmentDateNotInIntervalFromNow(appointment, Constants.APPOINTMENT_EXPIRING_PHONE_INTERVAL, Constants.APPOINTMENT_EXPIRING_EMAIL_INTERVAL)
|
)
|
.filter(this::isAppointmentExpiringNotifyNotOnLimit)
|
.collect(Collectors.toList());
|
|
allByCommunicateStatus.forEach(appointment -> {
|
Consultant consultant = consultantService.findByAgentNo(appointment.getAgentNo());
|
Optional<String> optionalPhone = Optional.ofNullable(appointment.getPhone()).filter(StringUtils::hasText);
|
Optional<String> optionalEmail = Optional.ofNullable(appointment.getEmail()).filter(StringUtils::hasText);
|
|
optionalPhone.ifPresent(phone ->
|
sendMsgService.sendMsgBySMS(phone, String.format("很抱歉!您預約%s顧問正忙碌中,請您取消預約並改選其他顧問,請點擊網址:%s"
|
, consultant.getName(), getAppointmentExpiringNotifyUrl(appointment.getId())))
|
);
|
optionalEmail.ifPresent(email ->
|
sendMsgService.sendMsgByEmail(email, NOT_CONTACTED_NOTIFY_SUBJECT, getAppointmentExpiringNotifyEmail(consultant.getName(), getAppointmentExpiringNotifyUrl(appointment.getId())), true)
|
);
|
|
AppointmentExpiringNotifyRecord record = new AppointmentExpiringNotifyRecord();
|
record.setAppointmentId(appointment.getId());
|
record.setSendTime(Instant.now());
|
|
appointmentExpiringNotifyRecordRepository.save(record);
|
});
|
|
log.info("Sending appointment expiring notify to customer finish");
|
}
|
|
// todo 需確認該時間, otis todo=134497
|
@Scheduled(cron = "0 30 8 * * *")
|
public void sendNotFillSatisfactionToPersonalNotification() {
|
Map<Long, List<Satisfaction>> customerNotFillSatisfactions = satisfactionService.getByStatus(SatisfactionStatusEnum.UNFILLED)
|
.stream()
|
.collect(Collectors.groupingBy(Satisfaction::getCustomerId));
|
|
customerNotFillSatisfactions.forEach((customerId, notFillSatisfactions) ->
|
personalNotificationService.createNotFillSatisfactionSumToCustomer(customerId, notFillSatisfactions.size())
|
);
|
}
|
|
private boolean isAppointmentExpiringNotifyNotOnLimit(AppointmentCustomerView appointment) {
|
int sendNotifyToCustomerRecordSum =
|
appointmentExpiringNotifyRecordRepository.findAllByAppointmentId(appointment.getId()).size();
|
|
return sendNotifyToCustomerRecordSum < Constants.SEND_EXPIRING_NOTIFY_LIMIT;
|
}
|
|
private String getAppointmentExpiringNotifyUrl(Long appointmentId) {
|
return applicationProperties.getFrontEndDomain() + "?notContactAppointmentId=" + appointmentId;
|
}
|
|
private String getAppointmentPendingNotifyEmailContent(int sum) {
|
Context context = new Context();
|
context.setVariable("pendingAppointmentSum", sum);
|
return springTemplateEngine.process("mail/appointmentPendingNotifyEmail", context);
|
}
|
|
private String getAppointmentExpiringNotifyEmail(String consultantName, String notifyUrl) {
|
Context context = new Context();
|
context.setVariable("consultantName", consultantName);
|
context.setVariable("notifyUrl", notifyUrl);
|
return springTemplateEngine.process("mail/appointmentExpiringNotifyEmail", context);
|
}
|
}
|