package com.pollex.pam.service;
|
|
import java.time.Instant;
|
import java.util.List;
|
import java.util.Objects;
|
import java.util.Optional;
|
import java.util.stream.Collectors;
|
|
import com.pollex.pam.config.ApplicationProperties;
|
import com.pollex.pam.service.dto.AppointmentUpdateDTO;
|
import com.pollex.pam.web.rest.errors.SendEmailFailException;
|
import com.pollex.pam.web.rest.errors.SendSMSFailException;
|
import io.jsonwebtoken.lang.Assert;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import com.pollex.pam.domain.Appointment;
|
import com.pollex.pam.domain.AppointmentCustomerView;
|
import com.pollex.pam.enums.ContactStatusEnum;
|
import com.pollex.pam.repository.AppointmentCustomerViewRepository;
|
import com.pollex.pam.repository.AppointmentRepository;
|
import com.pollex.pam.security.SecurityUtils;
|
import com.pollex.pam.service.dto.AppointmentCreateDTO;
|
import com.pollex.pam.service.dto.AppointmentCustomerViewDTO;
|
import com.pollex.pam.service.mapper.AppointmentCustomerViewMapper;
|
import com.pollex.pam.service.mapper.AppointmentDTOMapper;
|
import com.pollex.pam.web.rest.errors.AppointmentNotFoundException;
|
import org.springframework.util.StringUtils;
|
import org.thymeleaf.context.Context;
|
import org.thymeleaf.spring5.SpringTemplateEngine;
|
|
import static com.pollex.pam.enums.AppointmentStatusEnum.AVAILABLE;
|
import static com.pollex.pam.enums.AppointmentStatusEnum.DELETED;
|
|
@Service
|
@Transactional
|
public class AppointmentService {
|
|
private static final Logger log = LoggerFactory.getLogger(AppointmentService.class);
|
|
private static final String NOTIFY_EMAIL_SUBJECT = "保誠媒合平台系統通知:新預約單";
|
|
@Autowired
|
AppointmentRepository appointmentRepository;
|
|
@Autowired
|
AppointmentDTOMapper appointmentDTOMapper;
|
|
@Autowired
|
ConsultantService consultantService;
|
|
@Autowired
|
AppointmentCustomerViewMapper appointmentCustomerViewMapper;
|
|
@Autowired
|
AppointmentCustomerViewRepository appointmentCustomerViewRepository;
|
|
@Autowired
|
SatisfactionService satisfactionService;
|
|
@Autowired
|
SendMsgService sendMsgService;
|
|
@Autowired
|
ApplicationProperties applicationProperties;
|
|
@Autowired
|
SpringTemplateEngine springTemplateEngine;
|
|
public Appointment customerCreateAppointment(AppointmentCreateDTO appointmentCreateDTO) {
|
Appointment appointment = appointmentDTOMapper.toAppointment(appointmentCreateDTO);
|
appointment.setStatus(AVAILABLE);
|
appointment.setCustomerId(SecurityUtils.getCustomerDBId());
|
appointment.setCommunicateStatus(ContactStatusEnum.RESERVED);
|
return appointmentRepository.save(appointment);
|
}
|
|
public void updateAppointment(AppointmentUpdateDTO updateAppointmentDTO) {
|
Appointment appointment = appointmentRepository.findById(updateAppointmentDTO.getId()).get();
|
|
appointment.setPhone(updateAppointmentDTO.getPhone());
|
appointment.setEmail(updateAppointmentDTO.getEmail());
|
appointment.setContactType(updateAppointmentDTO.getContactType());
|
appointment.setGender(updateAppointmentDTO.getGender());
|
appointment.setAge(updateAppointmentDTO.getAge());
|
appointment.setJob(updateAppointmentDTO.getJob());
|
appointment.setRequirement(updateAppointmentDTO.getRequirement());
|
appointment.setHopeContactTime(updateAppointmentDTO.getHopeContactTime());
|
appointment.setOtherRequirement(updateAppointmentDTO.getOtherRequirement());
|
appointment.setLastModifiedDate(Instant.now());
|
|
appointmentRepository.save(appointment);
|
}
|
|
public void markAppointmentDeleted(Long appointmentId) {
|
Appointment appointment = appointmentRepository.findById(appointmentId).get();
|
appointment.setStatus(DELETED);
|
appointment.setLastModifiedDate(Instant.now());
|
appointmentRepository.save(appointment);
|
}
|
|
public List<Appointment> findByAgentNo(String agentNo) {
|
return appointmentRepository.findByAgentNo(agentNo);
|
}
|
|
public Appointment markAsContacted(Long appointmentId) {
|
Appointment appointment = appointmentRepository.findById(appointmentId).get();
|
appointment.setCommunicateStatus(ContactStatusEnum.CONTACTED);
|
appointment.setContactTime(Instant.now());
|
appointment.setLastModifiedDate(Instant.now());
|
return appointmentRepository.save(appointment);
|
}
|
|
public AppointmentCustomerViewDTO getAppointmentDetail(Long appointmentId) {
|
AppointmentCustomerView appointment = appointmentCustomerViewRepository.findById(appointmentId)
|
.orElseThrow(AppointmentNotFoundException::new);
|
|
AppointmentCustomerViewDTO dto = appointmentCustomerViewMapper.toAppointmentCustomerViewDTO(appointment);
|
setSatisfactionScore(dto, appointmentId);
|
return dto;
|
}
|
|
public List<AppointmentCustomerViewDTO> getConsultantAvailableAppointments(String agentNo) {
|
return appointmentCustomerViewRepository.findByAgentNo(agentNo).stream()
|
.filter(appointment -> appointment.getStatus() == AVAILABLE)
|
.map(appointmentCustomerView -> {
|
AppointmentCustomerViewDTO dto = appointmentCustomerViewMapper.toAppointmentCustomerViewDTO(appointmentCustomerView);
|
setSatisfactionScore(dto, appointmentCustomerView.getId());
|
return dto;
|
})
|
.collect(Collectors.toList());
|
}
|
|
public void setSatisfactionScore(AppointmentCustomerViewDTO dto, Long appointmentId) {
|
satisfactionService.getByAppointmentId(appointmentId).ifPresent(satisfaction -> {
|
dto.setSatisfactionScore(satisfaction.getScore());
|
});
|
}
|
|
public List<AppointmentCustomerView> findAvailableByAgentNoAndCustomerId(String agentNo, Long customerId) {
|
return appointmentCustomerViewRepository.findByAgentNoAndCustomerId(agentNo, customerId)
|
.stream()
|
.filter(appointmentCustomerView -> appointmentCustomerView.getStatus() == AVAILABLE)
|
.collect(Collectors.toList());
|
}
|
|
public Optional<Appointment> findLatestAppointmentByAgentNoAndCustomerId(String agentNo, Long customerId) {
|
return appointmentRepository.findTopByAgentNoAndCustomerIdOrderByAppointmentDateDesc(agentNo, customerId);
|
}
|
|
public void recordConsultantReadTime(Long appointmentId) {
|
Appointment appointment = appointmentRepository.findById(appointmentId).get();
|
|
if(appointment.getConsultantReadTime() == null) {
|
appointment.setConsultantReadTime(Instant.now());
|
appointmentRepository.save(appointment);
|
}
|
else {
|
log.debug("this appointment was read, read time = {}", appointment.getConsultantReadTime());
|
}
|
}
|
|
public void recordAllAppointmentsView(String agentNo) {
|
List<Appointment> consultantNotViewAppointments = findByAgentNo(agentNo)
|
.stream()
|
.filter(appointment -> Objects.isNull(appointment.getConsultantViewTime()))
|
.collect(Collectors.toList());
|
|
consultantNotViewAppointments.forEach(appointment -> appointment.setConsultantViewTime(Instant.now()));
|
appointmentRepository.saveAll(consultantNotViewAppointments);
|
}
|
|
public void sendAppointmentNotify(Appointment appointment) {
|
Assert.notNull(appointment, "appointment entity cannot be null");
|
|
log.debug("is need send appointment notify msg? = {}", applicationProperties.isSendNotifyMsg());
|
if(applicationProperties.isSendNotifyMsg()) {
|
log.debug("sending appointment notify, appointmentId = {}", appointment.getId());
|
sendAppointmentNotifyBySMS(appointment);
|
sendAppointmentNotifyByHtmlEmail(appointment);
|
}
|
}
|
|
private void sendAppointmentNotifyBySMS(Appointment appointment) {
|
String msg = getAppointmentNotifyWording(appointment);
|
String consultantMobile = consultantService.findByAgentNo(appointment.getAgentNo()).getPhoneNumber();
|
|
try {
|
if(!StringUtils.hasText(consultantMobile)) {
|
throw new SendSMSFailException("the consultant does not have mobile!");
|
}
|
|
sendMsgService.sendMsgBySMS(consultantMobile, msg);
|
} catch (SendSMSFailException e) {
|
log.warn("send appointment notify by sms was fail, appointment Id = {}", appointment.getId(), e);
|
}
|
}
|
|
private String getAppointmentNotifyWording(Appointment appointment) {
|
String normalContent;
|
if(StringUtils.hasText(appointment.getPhone())) {
|
normalContent = "親愛的顧問您好,您有一筆來自保誠人壽媒合平台的預約,預約客戶手機號碼為" + appointment.getPhone();
|
}
|
else {
|
normalContent = "親愛的顧問您好,您有一筆來自保誠人壽媒合平台的預約";
|
}
|
|
String urlContent = ",請點擊網址:" + getAppointmentDetailUrl(appointment.getId()) + "查看,並安排聯絡訪談,謝謝!";
|
return normalContent + urlContent;
|
}
|
|
private void sendAppointmentNotifyByHtmlEmail(Appointment appointment) {
|
String senderEmail = applicationProperties.getEmail().getSenderEmail();
|
String consultantEmail = consultantService.findByAgentNo(appointment.getAgentNo()).getEmail();
|
String customerMobile = appointment.getPhone();
|
String normalContent;
|
|
if(StringUtils.hasText(customerMobile)) {
|
normalContent = "親愛的顧問您好:您有一筆來自保誠人壽媒合平台的預約,預約客戶手機號碼為" + customerMobile + ",";
|
}
|
else {
|
normalContent = "親愛的顧問您好:您有一筆來自保誠人壽媒合平台的預約,";
|
}
|
|
Context context = new Context();
|
context.setVariable("content", normalContent);
|
context.setVariable("urlHint", getAppointmentDetailUrl(appointment.getId()));
|
String content = springTemplateEngine.process("mail/appointmentNotifyEmail", context);
|
|
try {
|
if(!StringUtils.hasText(consultantEmail)) {
|
throw new SendEmailFailException("the consultant does not have email!");
|
}
|
|
sendMsgService.sendMsgByEmail(senderEmail, consultantEmail, NOTIFY_EMAIL_SUBJECT, content, true);
|
} catch (SendEmailFailException e) {
|
log.warn("send appointment notify by email was fail, appointment Id = {}", appointment.getId(), e);
|
}
|
}
|
|
public String getAppointmentDetailUrl(Long appointmentId) {
|
return applicationProperties.getFrontEndDomain() + "/myAppointmentList/contactedList?appointmentId=" + appointmentId;
|
}
|
}
|