保誠-保戶業務員媒合平台
Jack
2022-01-24 f8ab133a7dc20562c25a092a402266f5e7b0b296
pamapi/src/main/java/com/pollex/pam/service/ScheduleTaskService.java
@@ -1,51 +1,32 @@
package com.pollex.pam.service;
import com.pollex.pam.config.ApplicationProperties;
import com.pollex.pam.domain.Appointment;
import com.pollex.pam.domain.AppointmentExpiringNotifyRecord;
import com.pollex.pam.domain.Consultant;
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 com.pollex.pam.repository.AppointmentRepository;
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.time.LocalDate;
import java.time.ZoneId;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
@Service
@Transactional
public class ScheduleTaskService {
    /**
     * 電話及email在建立預約單(T)後的N天視為未處理預約單
     * 目前N皆暫定為2
     */
    private static final int APPOINTMENT_PENDING_PHONE_INTERVAL = 2;
    private static final int APPOINTMENT_PENDING_EMAIL_INTERVAL = 2;
    /**
     * 電話及email在建立預約單(T)後的N天會被視為未處理預約單,當天批次會發送提醒給顧問
     * 而在後一天(T+N+1),就會發送批次給客戶告知 該顧問可能忙碌無法處理,是否需要取消
     */
    private static final int APPOINTMENT_EXPIRING_PHONE_INTERVAL = APPOINTMENT_PENDING_PHONE_INTERVAL + 1;
    private static final int APPOINTMENT_EXPIRING_EMAIL_INTERVAL = APPOINTMENT_PENDING_EMAIL_INTERVAL + 1;
    /**
     * 通知客戶的次數限制
     */
    private static final int SEND_EXPIRING_NOTIFY_LIMIT = 1;
    private static final String NOT_CONTACTED_NOTIFY_SUBJECT = "預約單未進行聯繫通知";
    private static final Logger log = LoggerFactory.getLogger(ScheduleTaskService.class);
@@ -57,7 +38,7 @@
    AppointmentService appointmentService;
    @Autowired
    AppointmentRepository appointmentRepository;
    AppointmentCustomerViewRepository appointmentCustomerViewRepository;
    @Autowired
    SendMsgService sendMsgService;
@@ -71,15 +52,23 @@
    @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<Appointment>> consultantWithPendingAppointments =
            appointmentRepository.findAllByCommunicateStatusAndStatus(ContactStatusEnum.RESERVED, AppointmentStatusEnum.AVAILABLE)
        Map<String, List<AppointmentCustomerView>> consultantWithPendingAppointments =
            appointmentCustomerViewRepository.findAllByCommunicateStatusAndStatus(ContactStatusEnum.RESERVED, AppointmentStatusEnum.AVAILABLE)
                .stream()
                .filter(appointment -> isAppointmentInInterval(appointment, APPOINTMENT_PENDING_PHONE_INTERVAL, APPOINTMENT_PENDING_EMAIL_INTERVAL))
                .collect(Collectors.groupingBy(Appointment::getAgentNo));
                .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();
@@ -99,10 +88,12 @@
    public void sendAppointmentExpiringNotifyToCustomer() {
        log.info("Starting send appointment expiring notify to customer");
        List<Appointment> allByCommunicateStatus =
            appointmentRepository.findAllByCommunicateStatusAndStatus(ContactStatusEnum.RESERVED, AppointmentStatusEnum.AVAILABLE)
        List<AppointmentCustomerView> allByCommunicateStatus =
            appointmentCustomerViewRepository.findAllByCommunicateStatusAndStatus(ContactStatusEnum.RESERVED, AppointmentStatusEnum.AVAILABLE)
                .stream()
                .filter(appointment -> isAppointmentInInterval(appointment, APPOINTMENT_EXPIRING_PHONE_INTERVAL, APPOINTMENT_EXPIRING_EMAIL_INTERVAL))
                .filter(appointment ->
                    appointmentService.isAppointmentDateNotInIntervalFromNow(appointment, Constants.APPOINTMENT_EXPIRING_PHONE_INTERVAL, Constants.APPOINTMENT_EXPIRING_EMAIL_INTERVAL)
                )
                .filter(this::isAppointmentNotifyNotOnLimit)
                .collect(Collectors.toList());
@@ -129,25 +120,23 @@
        log.info("Sending appointment expiring notify to customer finish");
    }
    private boolean isAppointmentInInterval(Appointment appointment, int phoneInterval, int emailInterval) {
        final boolean isHavePhone = StringUtils.hasText(appointment.getPhone());
        final boolean isHaveEmail = StringUtils.hasText(appointment.getEmail());
    // todo 需確認該時間, otis todo=134497
    @Scheduled(cron = "0 0 9 * * *")
    public void sendNotFillSatisfactionToPersonalNotification() {
        Map<Long, List<Satisfaction>> customerNotFillSatisfactions = satisfactionService.getByStatus(SatisfactionStatusEnum.UNFILLED)
                .stream()
                .collect(Collectors.groupingBy(Satisfaction::getCustomerId));
        LocalDate appointmentDate = appointment.getAppointmentDate().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate nowDate = Instant.now().atZone(ZoneId.systemDefault()).toLocalDate();
        long intervalDays = nowDate.toEpochDay() - appointmentDate.toEpochDay();
        final boolean isAppointmentExpiringByPhone = isHavePhone && intervalDays >= phoneInterval;
        final boolean isAppointmentExpiringByEmail = isHaveEmail && intervalDays >= emailInterval;
        return isAppointmentExpiringByPhone || isAppointmentExpiringByEmail;
        customerNotFillSatisfactions.forEach((customerId, notFillSatisfactions) ->
            personalNotificationService.createNotFillSatisfactionSumToCustomer(customerId, notFillSatisfactions.size())
        );
    }
    private boolean isAppointmentNotifyNotOnLimit(Appointment appointment) {
    private boolean isAppointmentNotifyNotOnLimit(AppointmentCustomerView appointment) {
        int sendNotifyToCustomerRecordSum =
            appointmentExpiringNotifyRecordRepository.findAllByAppointmentId(appointment.getId()).size();
        return sendNotifyToCustomerRecordSum < SEND_EXPIRING_NOTIFY_LIMIT;
        return sendNotifyToCustomerRecordSum < Constants.SEND_EXPIRING_NOTIFY_LIMIT;
    }
    private String getAppointmentUrl(Long appointmentId) {