From 348cadc7096df5ed641de68e06f41cea07b77de2 Mon Sep 17 00:00:00 2001 From: sankaviv1 <95748224+sankaviv1@users.noreply.github.com> Date: Fri, 14 Jul 2023 16:09:44 +0100 Subject: [PATCH] CIV-7965 Notify claimant of hearing HMC (#2906) * modify handler for notify claimant hmc event * Setup the hearing notice process handlers and events * update commons version * check payment details field --------- Co-authored-by: GarethLancaster <31533575+Gareth40342@users.noreply.github.com> Co-authored-by: Gareth Lancaster <90632240+Gareth40343@users.noreply.github.com> Co-authored-by: Harry H <33700332+HarryH96@users.noreply.github.com> --- build.gradle | 2 +- .../NotificationClaimantOfHearingHandler.java | 82 +++++++++-- ...ificationClaimantOfHearingHandlerTest.java | 137 ++++++++++++++++++ 3 files changed, 210 insertions(+), 11 deletions(-) diff --git a/build.gradle b/build.gradle index b642fc9b7e2..cd3110b2724 100644 --- a/build.gradle +++ b/build.gradle @@ -332,7 +332,7 @@ configurations.all { } dependencies { - implementation 'com.github.hmcts:civil-commons:1.0.0' + implementation 'com.github.hmcts:civil-commons:1.0.4' implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web' implementation group: 'org.springframework.boot', name: 'spring-boot-starter-actuator' diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotificationClaimantOfHearingHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotificationClaimantOfHearingHandler.java index c6020324387..72b8ea4efda 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotificationClaimantOfHearingHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotificationClaimantOfHearingHandler.java @@ -1,18 +1,25 @@ package uk.gov.hmcts.reform.civil.handler.callback.camunda.notification; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import uk.gov.hmcts.reform.ccd.client.model.AboutToStartOrSubmitCallbackResponse; import uk.gov.hmcts.reform.ccd.client.model.CallbackResponse; import uk.gov.hmcts.reform.civil.callback.Callback; +import uk.gov.hmcts.reform.civil.callback.CallbackException; import uk.gov.hmcts.reform.civil.callback.CallbackHandler; import uk.gov.hmcts.reform.civil.callback.CallbackParams; import uk.gov.hmcts.reform.civil.callback.CaseEvent; +import uk.gov.hmcts.reform.civil.model.Fee; import uk.gov.hmcts.reform.civil.notify.NotificationsProperties; import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.notify.NotificationService; +import uk.gov.hmcts.reform.civil.service.hearingnotice.HearingNoticeCamundaService; +import uk.gov.hmcts.reform.civil.service.hearings.HearingFeesService; import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.HashMap; @@ -22,17 +29,26 @@ import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.NOTIFY_CLAIMANT_HEARING; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.NOTIFY_CLAIMANT_HEARING_HMC; -import static uk.gov.hmcts.reform.civil.utils.NotificationUtils.isEvent; +import static uk.gov.hmcts.reform.civil.enums.PaymentStatus.SUCCESS; +import static uk.gov.hmcts.reform.civil.utils.HearingFeeUtils.calculateAndApplyFee; +import static uk.gov.hmcts.reform.civil.utils.HearingFeeUtils.calculateHearingDueDate; @Service @RequiredArgsConstructor +@Slf4j public class NotificationClaimantOfHearingHandler extends CallbackHandler implements NotificationData { private final NotificationService notificationService; + private final HearingFeesService hearingFeesService; private final NotificationsProperties notificationsProperties; + private final HearingNoticeCamundaService camundaService; private static final List EVENTS = List.of(NOTIFY_CLAIMANT_HEARING, NOTIFY_CLAIMANT_HEARING_HMC); private static final String REFERENCE_TEMPLATE_HEARING = "notification-of-hearing-%s"; public static final String TASK_ID_CLAIMANT = "NotifyClaimantHearing"; + public static final String TASK_ID_CLAIMANT_HMC = "NotifyClaimantSolicitorHearing"; + private static final String EVENT_NOT_FOUND_MESSAGE = "Callback handler received illegal event: %s"; + private static final String DATE_FORMAT = "dd-MM-yyyy"; + private static final String TIME_FORMAT = "hh:mma"; @Override protected Map callbacks() { @@ -43,20 +59,26 @@ protected Map callbacks() { @Override public String camundaActivityId(CallbackParams callbackParams) { - return TASK_ID_CLAIMANT; + CaseEvent caseEvent = CaseEvent.valueOf(callbackParams.getRequest().getEventId()); + if (NOTIFY_CLAIMANT_HEARING.equals(caseEvent)) { + return TASK_ID_CLAIMANT; + } else if (NOTIFY_CLAIMANT_HEARING_HMC.equals(caseEvent)) { + return TASK_ID_CLAIMANT_HMC; + } else { + throw new CallbackException(String.format(EVENT_NOT_FOUND_MESSAGE, caseEvent)); + } } private CallbackResponse notifyClaimantHearing(CallbackParams callbackParams) { CaseData caseData = callbackParams.getCaseData(); - - //ToDo: Replace with AHN logic - if (isEvent(callbackParams, NOTIFY_CLAIMANT_HEARING_HMC)) { - return AboutToStartOrSubmitCallbackResponse.builder() - .build(); - } - String recipient = caseData.getApplicantSolicitor1UserDetails().getEmail(); - sendEmail(caseData, recipient); + CaseEvent caseEvent = CaseEvent.valueOf(callbackParams.getRequest().getEventId()); + if (NOTIFY_CLAIMANT_HEARING.equals(caseEvent)) { + sendEmail(caseData, recipient); + } + if (NOTIFY_CLAIMANT_HEARING_HMC.equals(caseEvent)) { + sendEmailHMC(caseData, recipient); + } return AboutToStartOrSubmitCallbackResponse.builder() .build(); } @@ -74,6 +96,21 @@ private void sendEmail(CaseData caseData, String recipient) { ); } + private void sendEmailHMC(CaseData caseData, String recipient) { + String emailTemplate; + if (caseData.getHearingFeePaymentDetails() != null + && SUCCESS.equals(caseData.getHearingFeePaymentDetails().getStatus())) { + emailTemplate = notificationsProperties.getHearingListedNoFeeClaimantLrTemplateHMC(); + } else { + emailTemplate = notificationsProperties.getHearingListedFeeClaimantLrTemplateHMC(); + } + String hearingId = camundaService + .getProcessVariables(caseData.getBusinessProcess().getProcessInstanceId()).getHearingId(); + notificationService.sendMail(recipient, emailTemplate, addPropertiesHMC(caseData), + String.format(REFERENCE_TEMPLATE_HEARING, hearingId) + ); + } + @Override public List handledEvents() { return EVENTS; @@ -108,4 +145,29 @@ public Map addProperties(final CaseData caseData) { )); } + + public Map addPropertiesHMC(final CaseData caseData) { + Fee fee = calculateAndApplyFee(hearingFeesService, caseData, caseData.getAllocatedTrack()); + LocalDateTime hearingStartDateTime = camundaService + .getProcessVariables(caseData.getBusinessProcess().getProcessInstanceId()).getHearingStartDateTime(); + + LocalDate hearingDate = hearingStartDateTime.toLocalDate(); + LocalTime hearingTime = hearingStartDateTime.toLocalTime(); + + return Map.of( + CLAIM_REFERENCE_NUMBER, + caseData.getLegacyCaseReference(), + HEARING_FEE, + fee == null ? "£0.00" : String.valueOf(fee.formData()), + HEARING_DATE, + hearingDate.format(DateTimeFormatter.ofPattern(DATE_FORMAT)), + HEARING_TIME, + hearingTime.format(DateTimeFormatter.ofPattern(TIME_FORMAT)).replace("AM", "am").replace( + "PM", + "pm" + ), + HEARING_DUE_DATE, + calculateHearingDueDate(LocalDate.now(), hearingDate).format(DateTimeFormatter.ofPattern(DATE_FORMAT)) + ); + } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotificationClaimantOfHearingHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotificationClaimantOfHearingHandlerTest.java index 936a5c9468a..3eaedd68cf7 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotificationClaimantOfHearingHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotificationClaimantOfHearingHandlerTest.java @@ -4,12 +4,15 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import uk.gov.hmcts.reform.ccd.client.model.CallbackRequest; import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.model.BusinessProcess; +import uk.gov.hmcts.reform.civil.model.PaymentDetails; import uk.gov.hmcts.reform.civil.model.SolicitorReferences; import uk.gov.hmcts.reform.civil.notify.NotificationsProperties; import uk.gov.hmcts.reform.civil.enums.YesOrNo; @@ -20,16 +23,26 @@ import uk.gov.hmcts.reform.civil.sampledata.CallbackParamsBuilder; import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; import uk.gov.hmcts.reform.civil.notify.NotificationService; +import uk.gov.hmcts.reform.civil.service.hearingnotice.HearingNoticeCamundaService; +import uk.gov.hmcts.reform.civil.service.hearingnotice.HearingNoticeVariables; +import uk.gov.hmcts.reform.civil.service.hearings.HearingFeesService; import java.math.BigDecimal; import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.CALLS_REAL_METHODS; +import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; +import static uk.gov.hmcts.reform.civil.enums.PaymentStatus.SUCCESS; import static uk.gov.hmcts.reform.civil.handler.callback.camunda.notification.NotificationClaimantOfHearingHandler.TASK_ID_CLAIMANT; +import static uk.gov.hmcts.reform.civil.handler.callback.camunda.notification.NotificationClaimantOfHearingHandler.TASK_ID_CLAIMANT_HMC; import static uk.gov.hmcts.reform.civil.handler.callback.camunda.notification.NotificationData.CLAIM_REFERENCE_NUMBER; @SpringBootTest(classes = { @@ -41,7 +54,11 @@ public class NotificationClaimantOfHearingHandlerTest { @MockBean private NotificationService notificationService; @MockBean + private HearingFeesService hearingFeesService; + @MockBean NotificationsProperties notificationsProperties; + @MockBean + HearingNoticeCamundaService hearingNoticeCamundaService; @Autowired private NotificationClaimantOfHearingHandler handler; @@ -54,6 +71,10 @@ void setup() { .thenReturn("test-template-fee-claimant-id"); when(notificationsProperties.getHearingListedNoFeeClaimantLrTemplate()) .thenReturn("test-template-no-fee-claimant-id"); + when(notificationsProperties.getHearingListedFeeClaimantLrTemplateHMC()) + .thenReturn("test-template-fee-claimant-id-hmc"); + when(notificationsProperties.getHearingListedNoFeeClaimantLrTemplateHMC()) + .thenReturn("test-template-no-fee-claimant-id-hmc"); } @Test @@ -83,6 +104,44 @@ void shouldNotifyApplicantSolicitor_whenInvokedWithFeeAnd1v1() { ); } + @Test + void shouldNotifyApplicantSolicitor_whenInvokedWithFeeAnd1v1HMC() { + // Given + CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build().toBuilder() + .applicantSolicitor1UserDetails(IdamUserDetails.builder().email("applicantemail@hmcts.net").build()) + .respondentSolicitor1EmailAddress("respondent1email@hmcts.net") + .addApplicant2(YesOrNo.NO) + .addRespondent2(YesOrNo.NO) + .businessProcess(BusinessProcess.builder().processInstanceId("").build()) + .build(); + + when(hearingFeesService.getFeeForHearingFastTrackClaims(any())) + .thenReturn(Fee.builder().calculatedAmountInPence(BigDecimal.valueOf(30000)).build()); + when(hearingNoticeCamundaService.getProcessVariables(any())) + .thenReturn(HearingNoticeVariables.builder() + .hearingId("HER1234") + .hearingStartDateTime(LocalDateTime.of( + LocalDate.of(2022, 10, 7), + LocalTime.of(15, 30))) + .build()); + + LocalDate now = LocalDate.of(2022, 9, 29); + try (MockedStatic mock = mockStatic(LocalDate.class, CALLS_REAL_METHODS)) { + mock.when(LocalDate::now).thenReturn(now); + CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData) + .request(CallbackRequest.builder().eventId("NOTIFY_CLAIMANT_HEARING_HMC").build()).build(); + // When + handler.handle(params); + // Then + verify(notificationService).sendMail( + "applicantemail@hmcts.net", + "test-template-fee-claimant-id-hmc", + getNotificationFeeDataMapHMC(caseData), + "notification-of-hearing-HER1234" + ); + } + } + @Test void shouldNotifyApplicantSolicitor_whenInvokedWithFeeAnd1v1WithNoFee() { // Given @@ -111,6 +170,47 @@ void shouldNotifyApplicantSolicitor_whenInvokedWithFeeAnd1v1WithNoFee() { ); } + @Test + void shouldNotifyApplicantSolicitor_whenInvoked1v1WithNoFeeHMC() { + // Given + CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build().toBuilder() + .applicantSolicitor1UserDetails(IdamUserDetails.builder().email("applicantemail@hmcts.net").build()) + .respondentSolicitor1EmailAddress("respondent1email@hmcts.net") + .addApplicant2(YesOrNo.NO) + .addRespondent2(YesOrNo.NO) + .hearingFeePaymentDetails(PaymentDetails.builder() + .status(SUCCESS) + .build()) + .businessProcess(BusinessProcess.builder().processInstanceId("").build()) + .build(); + + when(hearingFeesService.getFeeForHearingFastTrackClaims(any())) + .thenReturn(Fee.builder().calculatedAmountInPence(BigDecimal.valueOf(0)).build()); + when(hearingNoticeCamundaService.getProcessVariables(any())) + .thenReturn(HearingNoticeVariables.builder() + .hearingId("HER1234") + .hearingStartDateTime(LocalDateTime.of( + LocalDate.of(2022, 10, 7), + LocalTime.of(15, 30))) + .build()); + + LocalDate now = LocalDate.of(2022, 9, 29); + try (MockedStatic mock = mockStatic(LocalDate.class, CALLS_REAL_METHODS)) { + mock.when(LocalDate::now).thenReturn(now); + CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData) + .request(CallbackRequest.builder().eventId("NOTIFY_CLAIMANT_HEARING_HMC").build()).build(); + // When + handler.handle(params); + // Then + verify(notificationService).sendMail( + "applicantemail@hmcts.net", + "test-template-no-fee-claimant-id-hmc", + getNotificationNoFeeDatePMDataMapHMC(caseData), + "notification-of-hearing-HER1234" + ); + } + } + @Test void shouldNotifyApplicantSolicitor_whenInvokedWithFeeAnd1v1WithNoSolicitorReferences() { // Given @@ -283,6 +383,14 @@ private Map getNotificationFeeDataMap(CaseData caseData) { ); } + @NotNull + private Map getNotificationFeeDataMapHMC(CaseData caseData) { + return Map.of( + CLAIM_REFERENCE_NUMBER, caseData.getLegacyCaseReference(), "hearingFee", "£300.00", + "hearingDate", "07-10-2022", "hearingTime", "03:30pm", "hearingDueDate", "06-10-2022" + ); + } + @NotNull private Map getNotificationNoFeeDataMap(CaseData caseData) { return Map.of( @@ -292,6 +400,14 @@ private Map getNotificationNoFeeDataMap(CaseData caseData) { ); } + @NotNull + private Map getNotificationNoFeeDataMapHMC(CaseData caseData) { + return Map.of( + CLAIM_REFERENCE_NUMBER, caseData.getLegacyCaseReference(), "hearingFee", "£0.00", + "hearingDate", "07-10-2022", "hearingTime", "08:30am", "hearingDueDate", "06-10-2022" + ); + } + @NotNull private Map getNotificationNoFeeDatePMDataMap(CaseData caseData) { return Map.of( @@ -301,10 +417,31 @@ private Map getNotificationNoFeeDatePMDataMap(CaseData caseData) ); } + @NotNull + private Map getNotificationNoFeeDatePMDataMapHMC(CaseData caseData) { + return Map.of( + CLAIM_REFERENCE_NUMBER, caseData.getLegacyCaseReference(), "hearingFee", "£0.00", + "hearingDate", "07-10-2022", "hearingTime", "03:30pm", "hearingDueDate", "06-10-2022" + ); + } + @Test void shouldReturnCorrectCamundaActivityId_whenInvoked() { + CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build(); + CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData) + .request(CallbackRequest.builder().eventId("NOTIFY_CLAIMANT_HEARING").build()).build(); assertThat(handler.camundaActivityId(CallbackParamsBuilder.builder().request(CallbackRequest .builder().eventId( "NOTIFY_CLAIMANT_HEARING").build()).build())).isEqualTo(TASK_ID_CLAIMANT); } + + @Test + void shouldReturnCorrectCamundaActivityId_whenInvokedHMC() { + CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build(); + CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData) + .request(CallbackRequest.builder().eventId("NOTIFY_CLAIMANT_HEARING").build()).build(); + assertThat(handler.camundaActivityId(CallbackParamsBuilder.builder().request(CallbackRequest + .builder().eventId( + "NOTIFY_CLAIMANT_HEARING_HMC").build()).build())).isEqualTo(TASK_ID_CLAIMANT_HMC); + } }