保誠-保戶業務員媒合平台
wayne
2022-01-22 8fb0516d2d4791ce41a541407ce3a6fe82541455
pamapi/src/main/java/com/pollex/pam/service/ScheduleTaskService.java
@@ -1,15 +1,13 @@
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.domain.Satisfaction;
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;
@@ -21,8 +19,6 @@
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;
@@ -31,25 +27,6 @@
@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);
@@ -61,7 +38,7 @@
    AppointmentService appointmentService;
    @Autowired
    AppointmentRepository appointmentRepository;
    AppointmentCustomerViewRepository appointmentCustomerViewRepository;
    @Autowired
    SendMsgService sendMsgService;
@@ -85,11 +62,13 @@
    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();
@@ -109,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());
@@ -151,25 +132,11 @@
        );
    }
    private boolean isAppointmentInInterval(Appointment appointment, int phoneInterval, int emailInterval) {
        final boolean isHavePhone = StringUtils.hasText(appointment.getPhone());
        final boolean isHaveEmail = StringUtils.hasText(appointment.getEmail());
        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;
    }
    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) {