From 8fb0516d2d4791ce41a541407ce3a6fe82541455 Mon Sep 17 00:00:00 2001 From: wayne <wayne8692wayne8692@gmail.com> Date: 星期六, 22 一月 2022 14:52:54 +0800 Subject: [PATCH] [update] [todo 134622, 134623] 顧問/客戶 未處理預約單平台通知 --- pamapi/src/doc/預約單/顧問取得所有自己的預約單API.txt | 89 ++++++++---- pamapi/src/main/resources/config/application-dev.yml | 2 pamapi/src/main/java/com/pollex/pam/config/Constants.java | 19 ++ pamapi/src/main/java/com/pollex/pam/service/AppointmentService.java | 58 ++++++-- pamapi/src/main/java/com/pollex/pam/web/rest/AppointmentResource.java | 40 ++++- pamapi/src/doc/預約單/標記為已聯絡API.txt | 67 +++++++-- pamapi/src/main/java/com/pollex/pam/repository/AppointmentCustomerViewRepository.java | 4 pamapi/src/doc/預約單/顧問取得未處理預約單數量通知.txt | 5 pamapi/src/main/java/com/pollex/pam/web/rest/errors/NotFoundExpiringAppointmentException.java | 8 + pamapi/src/main/java/com/pollex/pam/service/ScheduleTaskService.java | 67 ++------- pamapi/src/doc/預約單/客戶取得最新預約的未處理預約單.txt | 61 ++++++++ 11 files changed, 293 insertions(+), 127 deletions(-) diff --git "a/pamapi/src/doc/\351\240\220\347\264\204\345\226\256/\345\256\242\346\210\266\345\217\226\345\276\227\346\234\200\346\226\260\351\240\220\347\264\204\347\232\204\346\234\252\350\231\225\347\220\206\351\240\220\347\264\204\345\226\256.txt" "b/pamapi/src/doc/\351\240\220\347\264\204\345\226\256/\345\256\242\346\210\266\345\217\226\345\276\227\346\234\200\346\226\260\351\240\220\347\264\204\347\232\204\346\234\252\350\231\225\347\220\206\351\240\220\347\264\204\345\226\256.txt" new file mode 100644 index 0000000..d31a4ea --- /dev/null +++ "b/pamapi/src/doc/\351\240\220\347\264\204\345\226\256/\345\256\242\346\210\266\345\217\226\345\276\227\346\234\200\346\226\260\351\240\220\347\264\204\347\232\204\346\234\252\350\231\225\347\220\206\351\240\220\347\264\204\345\226\256.txt" @@ -0,0 +1,61 @@ +http get : + +http://localhost:8080/api/appointment/customer/expiring/newest + +蝪∟��mail��誑閰脩雯���脣擐�� -> http://localhost:3000?notContactAppointmentId={���銝�蝑�����} + +response body: ����200銝衣策隞乩�����(���遙雿�暹������嚗����404) +{ + "id": 385, + "phone": "0911223344", + "email": "SDD", + "contactType": "phone", + "gender": "female", + "age": "21-30", + "job": "��", + "requirement": "�摨瑁����", + "communicateStatus": "done", + "hopeContactTime": "'����,�����,�����,�����,�����,���,�����9:00~12:00,12:00~14:00,14:00~18:00,18:00~21:00'", + "otherRequirement": null, + "appointmentDate": "2021-12-16T07:11:05.400Z", + "lastModifiedDate": "2022-01-19T10:57:51.380Z", + "agentNo": "A568420", + "customerId": 139, + "name": "Angula-test", + "consultantViewTime": "2021-12-27T02:02:18.711Z", + "consultantReadTime": "2021-12-28T07:16:01.295Z", + "contactTime": "2021-12-28T07:16:37.004Z", + "satisfactionScore": null, + "appointmentMemoList": [], + "interviewRecordDTOs": [], + "appointmentNoticeLogs": [ + { + "id": 4, + "phone": "0912345678", + "email": "pollex@gmail.com", + "appointmentId": 385, + "content": "notice customer invterview time", + "createdDate": "2022-01-11T09:33:57.754Z", + "interviewDate": null + }, + { + "id": 6, + "phone": "0912345678", + "email": "pollex@gmail.com", + "appointmentId": 385, + "content": "notice customer invterview time", + "createdDate": "2022-01-19T10:38:42.187Z", + "interviewDate": "2022-11-01T08:00:00.000+00:00" + } + ], + "appointmentClosedInfo": { + "id": 9, + "policyholderIdentityId": "A123456789", + "planCode": "ATMdd", + "policyEntryDate": "2022-01-12T00:00:00.000+00:00", + "remark": "test remark", + "closedReason": "other2", + "closedOtherReason": "敹��末銝鞎�2", + "appointmentId": 385 + } +} diff --git "a/pamapi/src/doc/\351\240\220\347\264\204\345\226\256/\346\250\231\350\250\230\347\202\272\345\267\262\350\201\257\347\265\241API.txt" "b/pamapi/src/doc/\351\240\220\347\264\204\345\226\256/\346\250\231\350\250\230\347\202\272\345\267\262\350\201\257\347\265\241API.txt" index d4f900c..ad86aac 100644 --- "a/pamapi/src/doc/\351\240\220\347\264\204\345\226\256/\346\250\231\350\250\230\347\202\272\345\267\262\350\201\257\347\265\241API.txt" +++ "b/pamapi/src/doc/\351\240\220\347\264\204\345\226\256/\346\250\231\350\250\230\347\202\272\345\267\262\350\201\257\347\265\241API.txt" @@ -3,25 +3,56 @@ response body: { - "id": 401, - "phone": "0912345678", - "email": "wayne@pollex.com.tw", - "contactType": "EMAIL", - "gender": "male", - "age": "under_20", - "job": "123", - "requirement": "�摨瑁����,靽�瑼�/閬��", - "communicateStatus": "contacted", + "id": 385, + "phone": "0911223344", + "email": "SDD", + "contactType": "phone", + "gender": "female", + "age": "21-30", + "job": "��", + "requirement": "�摨瑁����", + "communicateStatus": "done", "hopeContactTime": "'����,�����,�����,�����,�����,���,�����9:00~12:00,12:00~14:00,14:00~18:00,18:00~21:00'", "otherRequirement": null, - "appointmentDate": "2021-12-21T08:13:50.154Z", - "lastModifiedDate": "2022-01-04T09:40:13.715Z", - "agentNo": "J149388015", - "customerId": 155, - "name": "123", - "consultantViewTime": "2021-12-24T07:27:48.681Z", - "consultantReadTime": null, - "contactTime": "2022-01-04T09:40:13.715Z", + "appointmentDate": "2021-12-16T07:11:05.400Z", + "lastModifiedDate": "2022-01-19T10:57:51.380Z", + "agentNo": "A568420", + "customerId": 139, + "name": "Angula-test", + "consultantViewTime": "2021-12-27T02:02:18.711Z", + "consultantReadTime": "2021-12-28T07:16:01.295Z", + "contactTime": "2021-12-28T07:16:37.004Z", "satisfactionScore": null, - "appointmentMemoList": [] + "appointmentMemoList": [], + "interviewRecordDTOs": [], + "appointmentNoticeLogs": [ + { + "id": 4, + "phone": "0912345678", + "email": "pollex@gmail.com", + "appointmentId": 385, + "content": "notice customer invterview time", + "createdDate": "2022-01-11T09:33:57.754Z", + "interviewDate": null + }, + { + "id": 6, + "phone": "0912345678", + "email": "pollex@gmail.com", + "appointmentId": 385, + "content": "notice customer invterview time", + "createdDate": "2022-01-19T10:38:42.187Z", + "interviewDate": "2022-11-01T08:00:00.000+00:00" + } + ], + "appointmentClosedInfo": { + "id": 9, + "policyholderIdentityId": "A123456789", + "planCode": "ATMdd", + "policyEntryDate": "2022-01-12T00:00:00.000+00:00", + "remark": "test remark", + "closedReason": "other2", + "closedOtherReason": "敹��末銝鞎�2", + "appointmentId": 385 + } } diff --git "a/pamapi/src/doc/\351\240\220\347\264\204\345\226\256/\351\241\247\345\225\217\345\217\226\345\276\227\346\211\200\346\234\211\350\207\252\345\267\261\347\232\204\351\240\220\347\264\204\345\226\256API.txt" "b/pamapi/src/doc/\351\240\220\347\264\204\345\226\256/\351\241\247\345\225\217\345\217\226\345\276\227\346\211\200\346\234\211\350\207\252\345\267\261\347\232\204\351\240\220\347\264\204\345\226\256API.txt" index c863f36..9072a0f 100644 --- "a/pamapi/src/doc/\351\240\220\347\264\204\345\226\256/\351\241\247\345\225\217\345\217\226\345\276\227\346\211\200\346\234\211\350\207\252\345\267\261\347\232\204\351\240\220\347\264\204\345\226\256API.txt" +++ "b/pamapi/src/doc/\351\240\220\347\264\204\345\226\256/\351\241\247\345\225\217\345\217\226\345\276\227\346\211\200\346\234\211\350\207\252\345\267\261\347\232\204\351\240\220\347\264\204\345\226\256API.txt" @@ -5,36 +5,59 @@ appointmentMemoList : ��酉鞈�� interviewRecordDTOs : 蝝赤蝝���� -[ { - "id" : 385, - "phone" : "0911223344", - "email" : "SDD", - "contactType" : "phone", - "gender" : "female", - "age" : "21-30", - "job" : "��", - "requirement" : "�摨瑁����", - "communicateStatus" : "contacted", - "hopeContactTime" : "'����,�����,�����,�����,�����,���,�����9:00~12:00,12:00~14:00,14:00~18:00,18:00~21:00'", - "otherRequirement" : null, - "appointmentDate" : "2021-12-16T07:11:05.400Z", - "lastModifiedDate" : "2021-12-28T07:16:37.004Z", - "agentNo" : "A568420", - "customerId" : 139, - "name" : "Angula-test", - "consultantViewTime" : "2021-12-27T02:02:18.711Z", - "consultantReadTime" : "2021-12-28T07:16:01.295Z", - "contactTime" : "2021-12-28T07:16:37.004Z", - "satisfactionScore" : null, - "appointmentMemoList" : [ ], - "interviewRecordDTOs" : [ { - "id" : 6, - "content" : "test record content", - "createdDate" : "2022-01-07T07:38:05.976Z", - "lastModifiedDate" : "2022-01-07T07:38:05.976Z", - "createdBy" : "A568420", - "lastModifiedBy" : "A568420", - "interviewDate" : "2021-01-01T08:00:00.000+00:00", - "appointmentId" : 385 - } ] -} ] \ No newline at end of file +[ + { + "id": 385, + "phone": "0911223344", + "email": "SDD", + "contactType": "phone", + "gender": "female", + "age": "21-30", + "job": "��", + "requirement": "�摨瑁����", + "communicateStatus": "done", + "hopeContactTime": "'����,�����,�����,�����,�����,���,�����9:00~12:00,12:00~14:00,14:00~18:00,18:00~21:00'", + "otherRequirement": null, + "appointmentDate": "2021-12-16T07:11:05.400Z", + "lastModifiedDate": "2022-01-19T10:57:51.380Z", + "agentNo": "A568420", + "customerId": 139, + "name": "Angula-test", + "consultantViewTime": "2021-12-27T02:02:18.711Z", + "consultantReadTime": "2021-12-28T07:16:01.295Z", + "contactTime": "2021-12-28T07:16:37.004Z", + "satisfactionScore": null, + "appointmentMemoList": [], + "interviewRecordDTOs": [], + "appointmentNoticeLogs": [ + { + "id": 4, + "phone": "0912345678", + "email": "pollex@gmail.com", + "appointmentId": 385, + "content": "notice customer invterview time", + "createdDate": "2022-01-11T09:33:57.754Z", + "interviewDate": null + }, + { + "id": 6, + "phone": "0912345678", + "email": "pollex@gmail.com", + "appointmentId": 385, + "content": "notice customer invterview time", + "createdDate": "2022-01-19T10:38:42.187Z", + "interviewDate": "2022-11-01T08:00:00.000+00:00" + } + ], + "appointmentClosedInfo": { + "id": 9, + "policyholderIdentityId": "A123456789", + "planCode": "ATMdd", + "policyEntryDate": "2022-01-12T00:00:00.000+00:00", + "remark": "test remark", + "closedReason": "other2", + "closedOtherReason": "敹��末銝鞎�2", + "appointmentId": 385 + } + } +] diff --git "a/pamapi/src/doc/\351\240\220\347\264\204\345\226\256/\351\241\247\345\225\217\345\217\226\345\276\227\346\234\252\350\231\225\347\220\206\351\240\220\347\264\204\345\226\256\346\225\270\351\207\217\351\200\232\347\237\245.txt" "b/pamapi/src/doc/\351\240\220\347\264\204\345\226\256/\351\241\247\345\225\217\345\217\226\345\276\227\346\234\252\350\231\225\347\220\206\351\240\220\347\264\204\345\226\256\346\225\270\351\207\217\351\200\232\347\237\245.txt" new file mode 100644 index 0000000..4582f1e --- /dev/null +++ "b/pamapi/src/doc/\351\240\220\347\264\204\345\226\256/\351\241\247\345\225\217\345\217\226\345\276\227\346\234\252\350\231\225\347\220\206\351\240\220\347\264\204\345\226\256\346\225\270\351\207\217\351\200\232\347\237\245.txt" @@ -0,0 +1,5 @@ +http get : +http://localhost:8080/api/appointment/consultant/pending/sum + +response body: +2 diff --git a/pamapi/src/main/java/com/pollex/pam/config/Constants.java b/pamapi/src/main/java/com/pollex/pam/config/Constants.java index ead5fc8..aae9b67 100644 --- a/pamapi/src/main/java/com/pollex/pam/config/Constants.java +++ b/pamapi/src/main/java/com/pollex/pam/config/Constants.java @@ -11,5 +11,24 @@ public static final String SYSTEM = "system"; public static final String DEFAULT_LANGUAGE = "zh-tw"; + /** + * �閰勗�mail�撱箇���(T)敺�憭抵������� + * �����摰2 + */ + public static final int APPOINTMENT_PENDING_PHONE_INTERVAL = 2; + public static final int APPOINTMENT_PENDING_EMAIL_INTERVAL = 2; + + /** + * �閰勗�mail�撱箇���(T)敺�憭拇�◤閬������嚗憭拇甈⊥����策憿批�� + * �敺�憭�(T+N+1)嚗停���甈∠策摰X�� 閰脤“���敹�瘜������閬��� + */ + public static final int APPOINTMENT_EXPIRING_PHONE_INTERVAL = APPOINTMENT_PENDING_PHONE_INTERVAL + 1; + public static final int APPOINTMENT_EXPIRING_EMAIL_INTERVAL = APPOINTMENT_PENDING_EMAIL_INTERVAL + 1; + + /** + * �摰X��活��� + */ + public static final int SEND_EXPIRING_NOTIFY_LIMIT = 1; + private Constants() {} } diff --git a/pamapi/src/main/java/com/pollex/pam/repository/AppointmentCustomerViewRepository.java b/pamapi/src/main/java/com/pollex/pam/repository/AppointmentCustomerViewRepository.java index b3499c6..61b5a04 100644 --- a/pamapi/src/main/java/com/pollex/pam/repository/AppointmentCustomerViewRepository.java +++ b/pamapi/src/main/java/com/pollex/pam/repository/AppointmentCustomerViewRepository.java @@ -2,6 +2,9 @@ import java.util.List; +import com.pollex.pam.domain.Appointment; +import com.pollex.pam.enums.AppointmentStatusEnum; +import com.pollex.pam.enums.ContactStatusEnum; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @@ -11,4 +14,5 @@ public interface AppointmentCustomerViewRepository extends JpaRepository<AppointmentCustomerView, Long>{ List<AppointmentCustomerView> findByAgentNo(String agentNo); List<AppointmentCustomerView> findByAgentNoAndCustomerId(String agentNo, Long customerId); + List<AppointmentCustomerView> findAllByCommunicateStatusAndStatus(ContactStatusEnum contactStatus, AppointmentStatusEnum status); } diff --git a/pamapi/src/main/java/com/pollex/pam/service/AppointmentService.java b/pamapi/src/main/java/com/pollex/pam/service/AppointmentService.java index dcac303..6d5ded6 100644 --- a/pamapi/src/main/java/com/pollex/pam/service/AppointmentService.java +++ b/pamapi/src/main/java/com/pollex/pam/service/AppointmentService.java @@ -1,6 +1,9 @@ package com.pollex.pam.service; import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.Comparator; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -8,10 +11,9 @@ import com.pollex.pam.appointment.process.AppointmentProcess; import com.pollex.pam.config.ApplicationProperties; -import com.pollex.pam.service.dto.AppointmentUpdateDTO; -import com.pollex.pam.service.dto.ClosedProcessDTO; -import com.pollex.pam.service.dto.DoneProcessDTO; -import com.pollex.pam.service.dto.InterviewRecordDTO; +import com.pollex.pam.config.Constants; +import com.pollex.pam.service.dto.*; +import com.pollex.pam.web.rest.errors.NotFoundExpiringAppointmentException; import com.pollex.pam.web.rest.errors.SendEmailFailException; import com.pollex.pam.web.rest.errors.SendSMSFailException; import io.jsonwebtoken.lang.Assert; @@ -24,15 +26,11 @@ import com.pollex.pam.domain.Appointment; import com.pollex.pam.domain.AppointmentCustomerView; -import com.pollex.pam.domain.InterviewRecord; import com.pollex.pam.enums.ContactStatusEnum; import com.pollex.pam.enums.InterviewRecordStatusEnum; import com.pollex.pam.repository.AppointmentCustomerViewRepository; import com.pollex.pam.repository.AppointmentRepository; import com.pollex.pam.security.SecurityUtils; -import com.pollex.pam.service.dto.AppointmentCloseDTO; -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; @@ -77,13 +75,13 @@ @Autowired SpringTemplateEngine springTemplateEngine; - + @Autowired InterviewRecordService interviewRecordService; - + @Autowired AppointmentProcess abstractAppointmentProcess; - + @Autowired PersonalNotificationService personalNotificationService; @@ -119,7 +117,7 @@ appointment.setCommunicateStatus(ContactStatusEnum.CANCEL); appointmentRepository.save(appointment); personalNotificationService.createMarkAppointmentDeletedToConsultant(appointment); - + } public List<Appointment> findByAgentNo(String agentNo) { @@ -203,7 +201,7 @@ Assert.notNull(appointment, "appointment entity cannot be null"); log.debug("is need send appointment notify msg? = {}", applicationProperties.isSendNotifyMsg()); - + log.debug("sending appointment notify, appointmentId = {}", appointment.getId()); sendAppointmentNotifyBySMS(appointment); sendAppointmentNotifyByHtmlEmail(appointment); @@ -268,7 +266,7 @@ public String getAppointmentDetailUrl(Long appointmentId) { return applicationProperties.getFrontEndDomain() + "/myAppointmentList/contactedList?appointmentId=" + appointmentId; } - + public Appointment findById(Long id) { return appointmentRepository.findById(id) .orElseThrow(AppointmentNotFoundException::new); @@ -285,4 +283,36 @@ abstractAppointmentProcess.process(dto); } } + + public Long getConsultantPendingAppointmentSum(String agentNo) { + return appointmentCustomerViewRepository.findAllByCommunicateStatusAndStatus(ContactStatusEnum.RESERVED, AVAILABLE) + .stream() + .filter(appointment -> agentNo.equals(appointment.getAgentNo())) + .filter(appointment -> isAppointmentDateNotInIntervalFromNow(appointment, Constants.APPOINTMENT_PENDING_PHONE_INTERVAL, Constants.APPOINTMENT_PENDING_EMAIL_INTERVAL)) + .count(); + } + + public AppointmentCustomerViewDTO getCustomerNewestExpiringAppointment(Long customerId) { + return appointmentCustomerViewRepository.findAllByCommunicateStatusAndStatus(ContactStatusEnum.RESERVED, AVAILABLE) + .stream() + .filter(appointment -> customerId.equals(appointment.getCustomerId())) + .filter(appointment -> isAppointmentDateNotInIntervalFromNow(appointment, Constants.APPOINTMENT_EXPIRING_PHONE_INTERVAL, Constants.APPOINTMENT_EXPIRING_EMAIL_INTERVAL)) + .max(Comparator.comparing(AppointmentCustomerView::getAppointmentDate)) + .map(appointmentCustomerView -> appointmentCustomerViewMapper.toAppointmentCustomerViewDTO(appointmentCustomerView)) + .orElse(null); + } + + public boolean isAppointmentDateNotInIntervalFromNow(AppointmentCustomerView 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; + } } diff --git a/pamapi/src/main/java/com/pollex/pam/service/ScheduleTaskService.java b/pamapi/src/main/java/com/pollex/pam/service/ScheduleTaskService.java index 60bb60a..604479e 100644 --- a/pamapi/src/main/java/com/pollex/pam/service/ScheduleTaskService.java +++ b/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 { - - /** - * �閰勗�mail�撱箇���(T)敺�憭抵������� - * �����摰2 - */ - private static final int APPOINTMENT_PENDING_PHONE_INTERVAL = 2; - private static final int APPOINTMENT_PENDING_EMAIL_INTERVAL = 2; - - /** - * �閰勗�mail�撱箇���(T)敺�憭拇�◤閬������嚗憭拇甈⊥����策憿批�� - * �敺�憭�(T+N+1)嚗停���甈∠策摰X�� 閰脤“���敹�瘜������閬��� - */ - 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; - - /** - * �摰X��活��� - */ - 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) { diff --git a/pamapi/src/main/java/com/pollex/pam/web/rest/AppointmentResource.java b/pamapi/src/main/java/com/pollex/pam/web/rest/AppointmentResource.java index ca378b3..ac19b72 100644 --- a/pamapi/src/main/java/com/pollex/pam/web/rest/AppointmentResource.java +++ b/pamapi/src/main/java/com/pollex/pam/web/rest/AppointmentResource.java @@ -2,16 +2,13 @@ import com.pollex.pam.appointment.process.AppointmentProcess; import com.pollex.pam.domain.Appointment; -import com.pollex.pam.enums.ContactStatusEnum; +import com.pollex.pam.security.SecurityUtils; import com.pollex.pam.service.SendMsgService; import com.pollex.pam.service.dto.AppointmentUpdateDTO; -import com.pollex.pam.service.dto.ClosedProcessDTO; -import com.pollex.pam.service.dto.DoneProcessDTO; -import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import com.pollex.pam.service.AppointmentService; @@ -20,6 +17,8 @@ import com.pollex.pam.service.dto.AppointmentCloseDTO; import com.pollex.pam.service.dto.AppointmentCreateDTO; import com.pollex.pam.service.dto.AppointmentCustomerViewDTO; + +import java.util.Objects; @RestController @RequestMapping("/api/appointment") @@ -33,10 +32,10 @@ @Autowired SendMsgService sendMsgService; - + @Autowired AppointmentProcess abstractAppointmentProcess; - + @Autowired PersonalNotificationService personalNotificationService; @@ -75,16 +74,35 @@ appointmentService.recordConsultantReadTime(appointmentId); return ResponseEntity.noContent().build(); } - + @PostMapping("/close") public ResponseEntity<Void> closeAppointment(@RequestBody AppointmentCloseDTO closeDTO) { appointmentService.closeAppointment(closeDTO); return ResponseEntity.noContent().build(); } - + + @GetMapping("/customer/expiring/newest") + public ResponseEntity<AppointmentCustomerViewDTO> getNewestExpiringAppointment() { + Long customerId = SecurityUtils.getCustomerDBId(); + AppointmentCustomerViewDTO customerNewestExpiringAppointment = appointmentService.getCustomerNewestExpiringAppointment(customerId); + + if(Objects.nonNull(customerNewestExpiringAppointment)) { + return new ResponseEntity<>(customerNewestExpiringAppointment, HttpStatus.OK); + } + else { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + } + + @GetMapping("/consultant/pending/sum") + public ResponseEntity<Long> getConsultantPendingAppointmentSum() { + String agentNo = SecurityUtils.getAgentNo(); + return new ResponseEntity<>(appointmentService.getConsultantPendingAppointmentSum(agentNo), HttpStatus.OK); + } + // @PostMapping("/close/info/edit") // public ResponseEntity<Void> editAppointmentClosedInfo(@RequestBody AppointmentCloseDTO closeDTO) { -// +// // if(closeDTO.getContactStatus() == ContactStatusEnum.DONE) { // DoneProcessDTO dto = new DoneProcessDTO(); // BeanUtils.copyProperties(closeDTO, dto); @@ -96,7 +114,7 @@ // }else { // return ResponseEntity.notFound().build(); // } -// +// // return ResponseEntity.noContent().build(); // } } diff --git a/pamapi/src/main/java/com/pollex/pam/web/rest/errors/NotFoundExpiringAppointmentException.java b/pamapi/src/main/java/com/pollex/pam/web/rest/errors/NotFoundExpiringAppointmentException.java new file mode 100644 index 0000000..a2a02f0 --- /dev/null +++ b/pamapi/src/main/java/com/pollex/pam/web/rest/errors/NotFoundExpiringAppointmentException.java @@ -0,0 +1,8 @@ +package com.pollex.pam.web.rest.errors; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "not found any expiring appointment") +public class NotFoundExpiringAppointmentException extends RuntimeException { +} diff --git a/pamapi/src/main/resources/config/application-dev.yml b/pamapi/src/main/resources/config/application-dev.yml index 90c15aa..ced80df 100644 --- a/pamapi/src/main/resources/config/application-dev.yml +++ b/pamapi/src/main/resources/config/application-dev.yml @@ -33,7 +33,7 @@ datasource: type: com.zaxxer.hikari.HikariDataSource url: jdbc:postgresql://dev.pollex.com.tw:5433/pam_p2 - #url: jdbc:postgresql://localhost:5432/omo?currentSchema=omo + #url: jdbc:postgresql://localhost:5432/omo?currentSchema=public username: pamadmin password: pamadmin hikari: -- Gitblit v1.8.0