From 6a8b2ca90c8f099afe1c2a403e8ee91ec6e2e27e Mon Sep 17 00:00:00 2001 From: Pablo Ortiz Date: Mon, 6 Nov 2023 10:05:32 +0100 Subject: [PATCH 01/28] CIV-8291 Manual Determination (#3412) * added changes for claimant response cui event. * CIV-8291 : Functional code - Need to refactor * CIV-8291 : Refactor duplicated methods to a common service * CIV-8291 : Handler Test * CIV-8291 : Fix checkStyle * CIV-8291 : Fix checkStyle * CIV-8291 : Adding mocks * CIV-8291 : Adding mocks * CIV-8291 : Adding mocks * CIV-8291 : Change final state to PROCEEDS_IN_HERITAGE_SYSTEM * CIV-8291 : Dev comments * CIV-8291 : Dev comments * CIV-8291 : Dev comments * CIV-8291 : Dev comments --------- Co-authored-by: neeta-hmcts Co-authored-by: sankhajuria Co-authored-by: hmcts-version1-pablo <107927784+hmcts-version1-pablo@users.noreply.github.com> --- .../ClaimantResponseCuiCallbackHandler.java | 19 +++++- .../RespondToDefenceSpecCallbackHandler.java | 61 ++----------------- .../gov/hmcts/reform/civil/model/Party.java | 5 ++ .../ResponseOneVOneShowTagService.java | 55 +++++++++++++++++ ...laimantResponseCuiCallbackHandlerTest.java | 45 +++++++++++++- ...spondToDefenceSpecCallbackHandlerTest.java | 7 ++- .../hmcts/reform/civil/model/PartyTest.java | 24 ++++++++ 7 files changed, 155 insertions(+), 61 deletions(-) create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/service/citizenui/ResponseOneVOneShowTagService.java diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandler.java index 8ae14dc9eee..e00acfdeb49 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandler.java @@ -13,6 +13,7 @@ import uk.gov.hmcts.reform.civil.enums.CaseState; import uk.gov.hmcts.reform.civil.model.BusinessProcess; import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.service.citizenui.ResponseOneVOneShowTagService; import java.time.LocalDateTime; import java.util.Collections; @@ -31,12 +32,14 @@ public class ClaimantResponseCuiCallbackHandler extends CallbackHandler { private static final List EVENTS = Collections.singletonList(CLAIMANT_RESPONSE_CUI); + private final ResponseOneVOneShowTagService responseOneVOneService; + private final ObjectMapper objectMapper; @Override protected Map callbacks() { return Map.of( - callbackKey(ABOUT_TO_START), this::emptyCallbackResponse, + callbackKey(ABOUT_TO_START), this::populateCaseData, callbackKey(ABOUT_TO_SUBMIT), this::aboutToSubmit, callbackKey(SUBMITTED), this::emptySubmittedCallbackResponse ); @@ -47,6 +50,16 @@ public List handledEvents() { return EVENTS; } + private CallbackResponse populateCaseData(CallbackParams callbackParams) { + var caseData = callbackParams.getCaseData(); + CaseData.CaseDataBuilder updatedCaseData = caseData.toBuilder(); + updatedCaseData.showResponseOneVOneFlag(responseOneVOneService.setUpOneVOneFlow(caseData)); + + return AboutToStartOrSubmitCallbackResponse.builder() + .data(updatedCaseData.build().toMap(objectMapper)) + .build(); + } + private CallbackResponse aboutToSubmit(CallbackParams callbackParams) { CaseData caseData = callbackParams.getCaseData(); CaseData updatedData = caseData.toBuilder() @@ -64,11 +77,13 @@ private CallbackResponse aboutToSubmit(CallbackParams callbackParams) { } private void updateClaimEndState(AboutToStartOrSubmitCallbackResponse.AboutToStartOrSubmitCallbackResponseBuilder response, CaseData updatedData) { - if (updatedData.hasClaimantAgreedToFreeMediation()) { response.state(CaseState.IN_MEDIATION.name()); + } else if (updatedData.hasApplicantRejectedRepaymentPlan() && updatedData.getRespondent1().isCompanyOROrganisation()) { + response.state(CaseState.PROCEEDS_IN_HERITAGE_SYSTEM.name()); } else { response.state(CaseState.JUDICIAL_REFERRAL.name()); } } + } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandler.java index 121a605dc71..9a9bad9f366 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandler.java @@ -22,7 +22,6 @@ import uk.gov.hmcts.reform.civil.handler.callback.user.spec.RespondToResponseConfirmationHeaderGenerator; import uk.gov.hmcts.reform.civil.handler.callback.user.spec.RespondToResponseConfirmationTextGenerator; import uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag; -import uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.ResponseOneVOneShowTag; import uk.gov.hmcts.reform.civil.helpers.LocationHelper; import uk.gov.hmcts.reform.civil.model.BusinessProcess; import uk.gov.hmcts.reform.civil.model.CaseData; @@ -41,6 +40,7 @@ import uk.gov.hmcts.reform.civil.service.PaymentDateService; import uk.gov.hmcts.reform.civil.service.Time; import uk.gov.hmcts.reform.civil.service.citizenui.RespondentMediationService; +import uk.gov.hmcts.reform.civil.service.citizenui.ResponseOneVOneShowTagService; import uk.gov.hmcts.reform.civil.utils.CaseFlagsInitialiser; import uk.gov.hmcts.reform.civil.utils.CourtLocationUtils; import uk.gov.hmcts.reform.civil.utils.MonetaryConversions; @@ -71,7 +71,6 @@ import static uk.gov.hmcts.reform.civil.callback.CallbackVersion.V_1; import static uk.gov.hmcts.reform.civil.callback.CallbackVersion.V_2; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.CLAIMANT_RESPONSE_SPEC; -import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_ONE; import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.TWO_V_ONE; import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.getMultiPartyScenario; import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.isOneVOne; @@ -109,6 +108,7 @@ public class RespondToDefenceSpecCallbackHandler extends CallbackHandler private static final String datePattern = "dd MMMM yyyy"; private final RespondentMediationService respondentMediationService; private final PaymentDateService paymentDateService; + private final ResponseOneVOneShowTagService responseOneVOneShowTagService; @Override public List handledEvents() { @@ -415,7 +415,7 @@ private CallbackResponse populateCaseData(CallbackParams callbackParams) { if (isDefendantFullAdmitPayImmediately(caseData)) { LocalDate whenBePaid = paymentDateService.getPaymentDateAdmittedClaim(caseData); - updatedCaseData.showResponseOneVOneFlag(setUpOneVOneFlow(caseData)); + updatedCaseData.showResponseOneVOneFlag(responseOneVOneShowTagService.setUpOneVOneFlow(caseData)); updatedCaseData.whenToBePaidText(formatLocalDate(whenBePaid, DATE)); } @@ -431,7 +431,7 @@ private CallbackResponse populateCaseData(CallbackParams callbackParams) { ).build()); if (V_2.equals(callbackParams.getVersion()) && featureToggleService.isPinInPostEnabled()) { - updatedCaseData.showResponseOneVOneFlag(setUpOneVOneFlow(caseData)); + updatedCaseData.showResponseOneVOneFlag(responseOneVOneShowTagService.setUpOneVOneFlow(caseData)); updatedCaseData.respondent1PaymentDateToStringSpec(setUpPayDateToString(caseData)); Optional howMuchWasPaid = Optional.ofNullable(caseData.getRespondToAdmittedClaim()) @@ -553,27 +553,6 @@ private String getDefaultConfirmationHeader(CaseData caseData) { } } - private ResponseOneVOneShowTag setUpOneVOneFlow(CaseData caseData) { - if (ONE_V_ONE.equals(getMultiPartyScenario(caseData))) { - if (caseData.getRespondent1ClaimResponseTypeForSpec() == null) { - return null; - } - switch (caseData.getRespondent1ClaimResponseTypeForSpec()) { - case FULL_DEFENCE: - return ResponseOneVOneShowTag.ONE_V_ONE_FULL_DEFENCE; - case FULL_ADMISSION: - return setUpOneVOneFlowForFullAdmit(caseData); - case PART_ADMISSION: - return setUpOneVOneFlowForPartAdmit(caseData); - case COUNTER_CLAIM: - return ResponseOneVOneShowTag.ONE_V_ONE_COUNTER_CLAIM; - default: - return null; - } - } - return null; - } - private String setUpPayDateToString(CaseData caseData) { if (caseData.getRespondToClaimAdmitPartLRspec() != null && caseData.getRespondToClaimAdmitPartLRspec().getWhenWillThisAmountBePaid() != null) { @@ -592,38 +571,6 @@ private String setUpPayDateToString(CaseData caseData) { return null; } - private ResponseOneVOneShowTag setUpOneVOneFlowForPartAdmit(CaseData caseData) { - if (YES.equals(caseData.getSpecDefenceAdmittedRequired())) { - return ResponseOneVOneShowTag.ONE_V_ONE_PART_ADMIT_HAS_PAID; - } - switch (caseData.getDefenceAdmitPartPaymentTimeRouteRequired()) { - case IMMEDIATELY: - return ResponseOneVOneShowTag.ONE_V_ONE_PART_ADMIT_PAY_IMMEDIATELY; - case BY_SET_DATE: - return ResponseOneVOneShowTag.ONE_V_ONE_PART_ADMIT_PAY_BY_SET_DATE; - case SUGGESTION_OF_REPAYMENT_PLAN: - return ResponseOneVOneShowTag.ONE_V_ONE_PART_ADMIT_PAY_INSTALMENT; - default: - return ResponseOneVOneShowTag.ONE_V_ONE_PART_ADMIT; - } - } - - private ResponseOneVOneShowTag setUpOneVOneFlowForFullAdmit(CaseData caseData) { - if (YES.equals(caseData.getSpecDefenceFullAdmittedRequired())) { - return ResponseOneVOneShowTag.ONE_V_ONE_FULL_ADMIT_HAS_PAID; - } - switch (caseData.getDefenceAdmitPartPaymentTimeRouteRequired()) { - case IMMEDIATELY: - return ResponseOneVOneShowTag.ONE_V_ONE_FULL_ADMIT_PAY_IMMEDIATELY; - case BY_SET_DATE: - return ResponseOneVOneShowTag.ONE_V_ONE_FULL_ADMIT_PAY_BY_SET_DATE; - case SUGGESTION_OF_REPAYMENT_PLAN: - return ResponseOneVOneShowTag.ONE_V_ONE_FULL_ADMIT_PAY_INSTALMENT; - default: - return ResponseOneVOneShowTag.ONE_V_ONE_FULL_ADMIT; - } - } - private CallbackResponse validatePaymentDate(CallbackParams callbackParams) { CaseData caseData = callbackParams.getCaseData(); diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/Party.java b/src/main/java/uk/gov/hmcts/reform/civil/model/Party.java index 48edc3146ae..32382122fad 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/Party.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/Party.java @@ -103,6 +103,11 @@ public boolean isOrganisation() { return ORGANISATION.equals(getType()); } + @JsonIgnore + public boolean isCompanyOROrganisation() { + return this.isCompany() || this.isOrganisation(); + } + @JsonIgnore public LocalDate getDateOfBirth() { return Optional.ofNullable(individualDateOfBirth).orElse(soleTraderDateOfBirth); diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/citizenui/ResponseOneVOneShowTagService.java b/src/main/java/uk/gov/hmcts/reform/civil/service/citizenui/ResponseOneVOneShowTagService.java new file mode 100644 index 00000000000..f639722d4b1 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/citizenui/ResponseOneVOneShowTagService.java @@ -0,0 +1,55 @@ +package uk.gov.hmcts.reform.civil.service.citizenui; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.ResponseOneVOneShowTag; +import uk.gov.hmcts.reform.civil.model.CaseData; + +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_ONE; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.getMultiPartyScenario; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; + +@Service +@RequiredArgsConstructor +public class ResponseOneVOneShowTagService { + + public ResponseOneVOneShowTag setUpOneVOneFlow(CaseData caseData) { + if (ONE_V_ONE.equals(getMultiPartyScenario(caseData))) { + if (caseData.getRespondent1ClaimResponseTypeForSpec() == null) { + return null; + } + return switch (caseData.getRespondent1ClaimResponseTypeForSpec()) { + case FULL_DEFENCE -> ResponseOneVOneShowTag.ONE_V_ONE_FULL_DEFENCE; + case FULL_ADMISSION -> setUpOneVOneFlowForFullAdmit(caseData); + case PART_ADMISSION -> setUpOneVOneFlowForPartAdmit(caseData); + case COUNTER_CLAIM -> ResponseOneVOneShowTag.ONE_V_ONE_COUNTER_CLAIM; + default -> null; + }; + } + return null; + } + + private ResponseOneVOneShowTag setUpOneVOneFlowForPartAdmit(CaseData caseData) { + if (YES.equals(caseData.getSpecDefenceAdmittedRequired())) { + return ResponseOneVOneShowTag.ONE_V_ONE_PART_ADMIT_HAS_PAID; + } + return switch (caseData.getDefenceAdmitPartPaymentTimeRouteRequired()) { + case IMMEDIATELY -> ResponseOneVOneShowTag.ONE_V_ONE_PART_ADMIT_PAY_IMMEDIATELY; + case BY_SET_DATE -> ResponseOneVOneShowTag.ONE_V_ONE_PART_ADMIT_PAY_BY_SET_DATE; + case SUGGESTION_OF_REPAYMENT_PLAN -> ResponseOneVOneShowTag.ONE_V_ONE_PART_ADMIT_PAY_INSTALMENT; + default -> ResponseOneVOneShowTag.ONE_V_ONE_PART_ADMIT; + }; + } + + private ResponseOneVOneShowTag setUpOneVOneFlowForFullAdmit(CaseData caseData) { + if (YES.equals(caseData.getSpecDefenceFullAdmittedRequired())) { + return ResponseOneVOneShowTag.ONE_V_ONE_FULL_ADMIT_HAS_PAID; + } + return switch (caseData.getDefenceAdmitPartPaymentTimeRouteRequired()) { + case IMMEDIATELY -> ResponseOneVOneShowTag.ONE_V_ONE_FULL_ADMIT_PAY_IMMEDIATELY; + case BY_SET_DATE -> ResponseOneVOneShowTag.ONE_V_ONE_FULL_ADMIT_PAY_BY_SET_DATE; + case SUGGESTION_OF_REPAYMENT_PLAN -> ResponseOneVOneShowTag.ONE_V_ONE_FULL_ADMIT_PAY_INSTALMENT; + default -> ResponseOneVOneShowTag.ONE_V_ONE_FULL_ADMIT; + }; + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandlerTest.java index 787f6d63f1f..d2dfccfe6ee 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandlerTest.java @@ -7,6 +7,7 @@ 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 org.springframework.test.context.junit.jupiter.SpringExtension; import uk.gov.hmcts.reform.ccd.client.model.AboutToStartOrSubmitCallbackResponse; import uk.gov.hmcts.reform.civil.callback.CallbackParams; @@ -14,20 +15,25 @@ import uk.gov.hmcts.reform.civil.enums.MediationDecision; import uk.gov.hmcts.reform.civil.handler.callback.BaseCallbackHandlerTest; import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.Party; import uk.gov.hmcts.reform.civil.model.citizenui.CaseDataLiP; import uk.gov.hmcts.reform.civil.model.citizenui.ClaimantMediationLip; import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; +import uk.gov.hmcts.reform.civil.service.citizenui.ResponseOneVOneShowTagService; import static org.assertj.core.api.Assertions.assertThat; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_START; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.CLAIMANT_RESPONSE_CUI; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; +import static uk.gov.hmcts.reform.civil.model.Party.Type.COMPANY; +import static uk.gov.hmcts.reform.civil.model.Party.Type.ORGANISATION; @ExtendWith(SpringExtension.class) @SpringBootTest(classes = { ClaimantResponseCuiCallbackHandler.class, - JacksonAutoConfiguration.class + JacksonAutoConfiguration.class, + ResponseOneVOneShowTagService.class }) class ClaimantResponseCuiCallbackHandlerTest extends BaseCallbackHandlerTest { @@ -37,6 +43,9 @@ class ClaimantResponseCuiCallbackHandlerTest extends BaseCallbackHandlerTest { @Autowired private final ObjectMapper mapper = new ObjectMapper(); + @MockBean + private ResponseOneVOneShowTagService responseOneVOneShowTagService; + @Nested class AboutToStartCallback { @@ -120,5 +129,39 @@ void shouldChangeCaseState_whenApplicantRejectClaimSettlementAndAgreeToMediation assertThat(response.getState()).isEqualTo(CaseState.IN_MEDIATION.name()); } + + @Test + void shouldChangeCaseState_whenApplicantRejectRepaymentPlanAndIsCompany_toAllFinalOrdersIssued() { + CaseData caseData = CaseDataBuilder.builder() + .atStateClaimIssued() + .applicant1AcceptPartAdmitPaymentPlanSpec(NO) + .respondent1(Party.builder() + .type(COMPANY) + .companyName("Test Inc") + .build()) + .build(); + + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + assertThat(response.getState()).isEqualTo(CaseState.PROCEEDS_IN_HERITAGE_SYSTEM.name()); + } + + @Test + void shouldChangeCaseState_whenApplicantRejectRepaymentPlanAndIsOrganisation_toAllFinalOrdersIssued() { + CaseData caseData = CaseDataBuilder.builder() + .atStateClaimIssued() + .applicant1AcceptPartAdmitPaymentPlanSpec(NO) + .respondent1(Party.builder() + .type(ORGANISATION) + .companyName("Test Inc") + .build()) + .build(); + + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + assertThat(response.getState()).isEqualTo(CaseState.PROCEEDS_IN_HERITAGE_SYSTEM.name()); + } } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandlerTest.java index 22ab7c93da4..19edb10eacf 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandlerTest.java @@ -68,6 +68,7 @@ import uk.gov.hmcts.reform.civil.service.PaymentDateService; import uk.gov.hmcts.reform.civil.service.Time; import uk.gov.hmcts.reform.civil.service.citizenui.RespondentMediationService; +import uk.gov.hmcts.reform.civil.service.citizenui.ResponseOneVOneShowTagService; import uk.gov.hmcts.reform.civil.service.flowstate.FlowState; import uk.gov.hmcts.reform.civil.utils.CaseFlagsInitialiser; import uk.gov.hmcts.reform.civil.utils.CourtLocationUtils; @@ -128,7 +129,8 @@ LocationHelper.class, LocationRefDataService.class, JudgementService.class, - PaymentDateService.class + PaymentDateService.class, + ResponseOneVOneShowTagService.class }) class RespondToDefenceSpecCallbackHandlerTest extends BaseCallbackHandlerTest { @@ -144,6 +146,9 @@ class RespondToDefenceSpecCallbackHandlerTest extends BaseCallbackHandlerTest { @Autowired private PaymentDateService paymentDateService; + @Autowired + private ResponseOneVOneShowTagService responseOneVOneShowTagService; + @MockBean private UnavailableDateValidator unavailableDateValidator; diff --git a/src/test/java/uk/gov/hmcts/reform/civil/model/PartyTest.java b/src/test/java/uk/gov/hmcts/reform/civil/model/PartyTest.java index 87ee19e09cc..177d6930853 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/model/PartyTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/model/PartyTest.java @@ -61,4 +61,28 @@ void shouldGetSoulTraderPartyNameExcludingTitle_whenInstantiated() { assertThat(party.getPartyName(true)).isEqualTo("James Carver"); } + @Test + void shouldReturnTrueWhenPartyIsCompany() { + Party party = Party.builder().type(Party.Type.COMPANY) + .build(); + + assertThat(party.isCompanyOROrganisation()).isTrue(); + } + + @Test + void shouldReturnTrueWhenPartyIsOrganisation() { + Party party = Party.builder().type(Party.Type.ORGANISATION) + .build(); + + assertThat(party.isCompanyOROrganisation()).isTrue(); + } + + @Test + void shouldReturnTrueWhenPartyIsNOTOrganisationOrCompany() { + Party party = Party.builder().type(Party.Type.INDIVIDUAL) + .build(); + + assertThat(party.isCompanyOROrganisation()).isFalse(); + } + } From 9557ac3d429d91ef26f3d53cb0e22cdebbf1eab5 Mon Sep 17 00:00:00 2001 From: dtortolaV1 <93722198+dtortolaV1@users.noreply.github.com> Date: Mon, 6 Nov 2023 11:39:31 +0100 Subject: [PATCH 02/28] CIV-10437 spec and unspec can add notes to offline cases (#3484) * CIV-10437 spec and unspec can add notes to offline cases * CIV-10437 spec and unspec can add notes to offline cases * CIV-10437 spec and unspec can add notes to offline cases --------- Co-authored-by: kdaHMCTS <128375235+kdaHMCTS@users.noreply.github.com> --- .../FlowStateAllowedEventService.java | 118 ++++++++++++++---- .../FlowStateAllowedEventServiceTest.java | 2 + 2 files changed, 96 insertions(+), 24 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventService.java b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventService.java index f38fd3c46ce..2b39e00bdd3 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventService.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventService.java @@ -6,7 +6,6 @@ import uk.gov.hmcts.reform.civil.callback.CaseEvent; import uk.gov.hmcts.reform.civil.helpers.CaseDetailsConverter; import uk.gov.hmcts.reform.civil.model.CaseData; -import uk.gov.hmcts.reform.civil.service.FeatureToggleService; import uk.gov.hmcts.reform.civil.stateflow.StateFlow; import java.util.List; @@ -29,68 +28,69 @@ import static uk.gov.hmcts.reform.civil.callback.CaseEvent.APPLICATION_OFFLINE_UPDATE_CLAIM; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.APPLY_NOC_DECISION; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.BUNDLE_CREATION_NOTIFICATION; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.LIP_CLAIM_SETTLED; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.CLAIMANT_RESPONSE_CUI; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.CREATE_CLAIM_SPEC_AFTER_PAYMENT; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.CREATE_CLAIM_AFTER_PAYMENT; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.CASE_PROCEEDS_IN_CASEMAN; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.CHANGE_SOLICITOR_EMAIL; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.CLAIMANT_RESPONSE; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.CLAIMANT_RESPONSE_CUI; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.CLAIMANT_RESPONSE_SPEC; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.CREATE_CLAIM; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.CREATE_CLAIM_AFTER_PAYMENT; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.CREATE_CLAIM_SPEC; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.CREATE_CLAIM_SPEC_AFTER_PAYMENT; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.CREATE_LIP_CLAIM; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.CREATE_SDO; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.DEFAULT_JUDGEMENT; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.MANAGE_CONTACT_INFORMATION; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.NOTIFY_HEARING_PARTIES; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.REQUEST_JUDGEMENT_ADMISSION_SPEC; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.DEFAULT_JUDGEMENT_SPEC; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.DEFENDANT_RESPONSE; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.DEFENDANT_RESPONSE_CUI; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.DEFENDANT_RESPONSE_SPEC; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.DISCONTINUE_CLAIM; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.DISMISS_CLAIM; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.ENTER_BREATHING_SPACE_SPEC; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.ENTER_BREATHING_SPACE_LIP; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.ENTER_BREATHING_SPACE_SPEC; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.EVIDENCE_UPLOAD_APPLICANT; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.EVIDENCE_UPLOAD_JUDGE; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.EVIDENCE_UPLOAD_RESPONDENT; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.EXTEND_RESPONSE_DEADLINE; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.HEARING_FEE_UNPAID; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.GENERATE_DIRECTIONS_ORDER; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.HEARING_FEE_PAID; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.HEARING_FEE_UNPAID; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.HEARING_SCHEDULED; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.INFORM_AGREED_EXTENSION_DATE; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.INFORM_AGREED_EXTENSION_DATE_SPEC; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.INITIATE_GENERAL_APPLICATION; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.JUDGMENT_PAID_IN_FULL; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.LIFT_BREATHING_SPACE_SPEC; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.LIP_CLAIM_SETTLED; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.MANAGE_CONTACT_INFORMATION; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.MEDIATION_SUCCESSFUL; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.MEDIATION_UNSUCCESSFUL; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.RESET_PIN; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.TRIAL_READINESS; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.UPLOAD_TRANSLATED_DOCUMENT; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.migrateCase; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.MOVE_TO_DECISION_OUTCOME; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.NOC_REQUEST; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.NOTIFY_DEFENDANT_CUI_FOR_DEADLINE_EXTENSION; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.NOTIFY_CLAIMANT_CUI_FOR_DEADLINE_EXTENSION; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.NOTIFY_DEFENDANT_CUI_FOR_DEADLINE_EXTENSION; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.NOTIFY_DEFENDANT_OF_CLAIM; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.NOTIFY_DEFENDANT_OF_CLAIM_DETAILS; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.NOTIFY_HEARING_PARTIES; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.NotSuitable_SDO; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.RECORD_JUDGMENT; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.REFER_TO_JUDGE; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.REQUEST_JUDGEMENT_ADMISSION_SPEC; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.RESET_PIN; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.RESUBMIT_CLAIM; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.SERVICE_REQUEST_RECEIVED; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.SET_ASIDE_JUDGMENT; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.STANDARD_DIRECTION_ORDER_DJ; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.TAKE_CASE_OFFLINE; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.TRIAL_READY_NOTIFICATION; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.TRANSFER_ONLINE_CASE; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.TRIAL_READINESS; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.TRIAL_READY_CHECK; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.GENERATE_DIRECTIONS_ORDER; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.TRIAL_READY_NOTIFICATION; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.UPLOAD_TRANSLATED_DOCUMENT; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.WITHDRAW_CLAIM; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.SET_ASIDE_JUDGMENT; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.JUDGMENT_PAID_IN_FULL; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.RECORD_JUDGMENT; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.TRANSFER_ONLINE_CASE; -import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PREPARE_FOR_HEARING_CONDUCT_HEARING; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.asyncStitchingComplete; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.migrateCase; +import static uk.gov.hmcts.reform.civil.enums.CaseCategory.SPEC_CLAIM; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.AWAITING_RESPONSES_FULL_DEFENCE_RECEIVED; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.AWAITING_RESPONSES_NOT_FULL_DEFENCE_RECEIVED; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.CLAIM_DETAILS_NOTIFIED; @@ -123,17 +123,18 @@ import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PAST_CLAIM_DISMISSED_DEADLINE_AWAITING_CAMUNDA; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PAST_CLAIM_NOTIFICATION_DEADLINE_AWAITING_CAMUNDA; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT; +import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PREPARE_FOR_HEARING_CONDUCT_HEARING; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.RESPONDENT_RESPONSE_LANGUAGE_IS_BILINGUAL; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.SPEC_DRAFT; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.TAKEN_OFFLINE_AFTER_CLAIM_DETAILS_NOTIFIED; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.TAKEN_OFFLINE_AFTER_CLAIM_NOTIFIED; +import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.TAKEN_OFFLINE_AFTER_SDO; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.TAKEN_OFFLINE_BY_STAFF; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.TAKEN_OFFLINE_PAST_APPLICANT_RESPONSE_DEADLINE; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.TAKEN_OFFLINE_SDO_NOT_DRAWN; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.TAKEN_OFFLINE_UNREGISTERED_DEFENDANT; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.TAKEN_OFFLINE_UNREPRESENTED_DEFENDANT; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.TAKEN_OFFLINE_UNREPRESENTED_UNREGISTERED_DEFENDANT; -import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.TAKEN_OFFLINE_AFTER_SDO; @Service @RequiredArgsConstructor @@ -141,7 +142,6 @@ public class FlowStateAllowedEventService { private final StateFlowEngine stateFlowEngine; private final CaseDetailsConverter caseDetailsConverter; - private final FeatureToggleService toggleService; private static final Map> ALLOWED_EVENTS_ON_FLOW_STATE = Map.ofEntries( entry( @@ -1335,6 +1335,76 @@ public class FlowStateAllowedEventService { List.of( asyncStitchingComplete ) + ), + entry( + TAKEN_OFFLINE_BY_STAFF.fullName(), + List.of( + ADD_CASE_NOTE, + APPLICATION_OFFLINE_UPDATE_CLAIM, + migrateCase + ) + ), + entry( + TAKEN_OFFLINE_UNREGISTERED_DEFENDANT.fullName(), + List.of( + ADD_CASE_NOTE, + APPLICATION_OFFLINE_UPDATE_CLAIM, + migrateCase + ) + ), + entry( + TAKEN_OFFLINE_UNREPRESENTED_DEFENDANT.fullName(), + List.of( + ADD_CASE_NOTE, + APPLICATION_OFFLINE_UPDATE_CLAIM, + migrateCase + ) + ), + entry( + TAKEN_OFFLINE_UNREPRESENTED_UNREGISTERED_DEFENDANT.fullName(), + List.of( + ADD_CASE_NOTE, + APPLICATION_OFFLINE_UPDATE_CLAIM, + migrateCase + ) + ), + entry( + TAKEN_OFFLINE_PAST_APPLICANT_RESPONSE_DEADLINE.fullName(), + List.of( + ADD_CASE_NOTE, + APPLICATION_OFFLINE_UPDATE_CLAIM, + migrateCase + ) + ), + entry( + TAKEN_OFFLINE_AFTER_CLAIM_DETAILS_NOTIFIED.fullName(), + List.of( + ADD_CASE_NOTE, + APPLICATION_OFFLINE_UPDATE_CLAIM, + migrateCase + ) + ), + entry( + TAKEN_OFFLINE_AFTER_CLAIM_NOTIFIED.fullName(), + List.of( + ADD_CASE_NOTE, + APPLICATION_OFFLINE_UPDATE_CLAIM, + migrateCase + ) + ), + entry( + TAKEN_OFFLINE_SDO_NOT_DRAWN.fullName(), + List.of( + ADD_CASE_NOTE, + migrateCase + ) + ), + entry( + TAKEN_OFFLINE_AFTER_SDO.fullName(), + List.of( + ADD_CASE_NOTE, + AMEND_PARTY_DETAILS + ) ) ); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventServiceTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventServiceTest.java index cae90e7ca58..3046d377756 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventServiceTest.java @@ -137,6 +137,8 @@ class FlowStateAllowedEventServiceTest { @Autowired FlowStateAllowedEventService flowStateAllowedEventService; + // used by StateFlowEngine bean + @SuppressWarnings("unused") @MockBean private FeatureToggleService toggleService; From 2d2b36c519189610edcdcdca214f248fa8b7cfbc Mon Sep 17 00:00:00 2001 From: pliao-hmcts <113367232+pliao-hmcts@users.noreply.github.com> Date: Mon, 6 Nov 2023 12:24:06 +0000 Subject: [PATCH 03/28] CIV-11132 Particulars of Claim (#3499) * CIV-11132 add Particulars of Claim to bundle * CIV-11132 add Particulars of Claim to bundle * CIV-11132 rename method * CIV-11132 change section --------- Co-authored-by: vasudevganesanhmcts <100689363+vasudevganesanhmcts@users.noreply.github.com> --- .../caseprogression/BundleFileNameList.java | 3 +- .../helpers/bundle/BundleRequestMapper.java | 29 +++++++++++++++++++ .../civil/model/bundle/BundlingCaseData.java | 2 ++ .../bundle/BundleRequestMapperTest.java | 28 +++++++++++++----- 4 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/enums/caseprogression/BundleFileNameList.java b/src/main/java/uk/gov/hmcts/reform/civil/enums/caseprogression/BundleFileNameList.java index 9847205b2b4..ec628a0643f 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/enums/caseprogression/BundleFileNameList.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/enums/caseprogression/BundleFileNameList.java @@ -26,7 +26,8 @@ public enum BundleFileNameList { QUESTIONS_TO("Questions to %s %s"), REPLIES_FROM("Replies from %s %s"), JOINT_STATEMENTS_OF_EXPERTS("Joint statement of experts %s %s %s"), - SKELETON_ARGUMENT("%s Skeleton argument %s"); + SKELETON_ARGUMENT("%s Skeleton argument %s"), + PARTICULARS_OF_CLAIM("Particulars Of Claim %s"); String displayName; public String getDisplayName() { diff --git a/src/main/java/uk/gov/hmcts/reform/civil/helpers/bundle/BundleRequestMapper.java b/src/main/java/uk/gov/hmcts/reform/civil/helpers/bundle/BundleRequestMapper.java index 549965f3176..717887a0472 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/helpers/bundle/BundleRequestMapper.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/helpers/bundle/BundleRequestMapper.java @@ -35,6 +35,7 @@ import java.util.Comparator; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.TreeMap; @@ -43,6 +44,7 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; +import static uk.gov.hmcts.reform.civil.enums.CaseCategory.SPEC_CLAIM; import static uk.gov.hmcts.reform.civil.helpers.bundle.BundleFileNameHelper.getEvidenceUploadDocsByPartyAndDocType; import static uk.gov.hmcts.reform.civil.helpers.bundle.BundleFileNameHelper.getExpertDocsByPartyAndDocType; import static uk.gov.hmcts.reform.civil.helpers.bundle.BundleFileNameHelper.getWitnessDocsByPartyAndDocType; @@ -116,6 +118,32 @@ private BundlingCaseData mapCaseData(CaseData caseData, String bundleConfigFileN return bundlingCaseData; } + private List mapParticularsOfClaimDocs(CaseData caseData) { + List bundlingRequestDocuments = new ArrayList<>(); + if (Objects.nonNull(caseData.getServedDocumentFiles()) + && Objects.nonNull((caseData.getServedDocumentFiles().getParticularsOfClaimDocument()))) { + caseData.getServedDocumentFiles() + .getParticularsOfClaimDocument() + .forEach(poc -> bundlingRequestDocuments.add( + buildBundlingRequestDoc(getParticularsOfClaimName(caseData), + poc.getValue(), ""))); + } + return bundlingRequestDocuments; + } + + private String getParticularsOfClaimName(CaseData caseData) { + LocalDate pocDate; + if (SPEC_CLAIM.equals(caseData.getCaseAccessCategory())) { + pocDate = caseData.getIssueDate(); + } else if (Objects.nonNull(caseData.getClaimDetailsNotificationDate())) { + pocDate = caseData.getClaimDetailsNotificationDate().toLocalDate(); + } else { + pocDate = caseData.getSubmittedDate().toLocalDate(); + } + return generateDocName(BundleFileNameList.PARTICULARS_OF_CLAIM.getDisplayName(), + null, null, pocDate); + } + private List> mapJointStatementOfExperts(CaseData caseData) { List bundlingRequestDocuments = new ArrayList<>(); Arrays.stream(PartyType.values()).toList().forEach(partyType -> { @@ -518,6 +546,7 @@ private List> mapStatementOfcaseDocs(CaseData c && caseDocumentElement.getValue().getDocumentLink().getCategoryID().equals("detailsOfClaim")) .collect(Collectors.toList()), BundleFileNameList.CLAIM_FORM.getDisplayName())); + bundlingRequestDocuments.addAll(mapParticularsOfClaimDocs(caseData)); List> clAndDfDocList = caseData.getDefendantResponseDocuments(); clAndDfDocList.addAll(caseData.getClaimantResponseDocuments()); List> sortedDefendantDefenceAndClaimantReply = diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/bundle/BundlingCaseData.java b/src/main/java/uk/gov/hmcts/reform/civil/model/bundle/BundlingCaseData.java index 80340c02507..f37439ded9c 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/bundle/BundlingCaseData.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/bundle/BundlingCaseData.java @@ -22,6 +22,8 @@ public class BundlingCaseData { private final List> trialDocuments; @JsonProperty("statementsOfCaseDocuments") private final List> statementsOfCaseDocuments; + @JsonProperty("particularsOfClaim") + private final List> particularsOfClaim; @JsonProperty("ordersDocuments") private final List> ordersDocuments; @JsonProperty("claimant1WitnessStatements") diff --git a/src/test/java/uk/gov/hmcts/reform/civil/helpers/bundle/BundleRequestMapperTest.java b/src/test/java/uk/gov/hmcts/reform/civil/helpers/bundle/BundleRequestMapperTest.java index bc6d8bfe685..1e4665f1f00 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/helpers/bundle/BundleRequestMapperTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/helpers/bundle/BundleRequestMapperTest.java @@ -8,6 +8,7 @@ import uk.gov.hmcts.reform.civil.enums.caseprogression.TypeOfDocDocumentaryEvidenceOfTrial; import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.model.Party; +import uk.gov.hmcts.reform.civil.model.ServedDocumentFiles; import uk.gov.hmcts.reform.civil.model.bundle.BundleCreateRequest; import uk.gov.hmcts.reform.civil.model.caseprogression.UploadEvidenceDocumentType; import uk.gov.hmcts.reform.civil.model.caseprogression.UploadEvidenceExpert; @@ -76,20 +77,22 @@ void testBundleRequestMapperWithAllDocs() { bundleCreateRequest.getCaseDetails().getCaseData().getTrialDocuments().get(11).getValue().getDocumentFileName()); assertEquals("Claim Form 10/02/2023", bundleCreateRequest.getCaseDetails().getCaseData().getStatementsOfCaseDocuments().get(0).getValue().getDocumentFileName()); - assertEquals("DF 1 Defence 10/02/2023", + assertEquals("Particulars Of Claim 10/02/2023", bundleCreateRequest.getCaseDetails().getCaseData().getStatementsOfCaseDocuments().get(1).getValue().getDocumentFileName()); - assertEquals("CL's reply 10/02/2023", + assertEquals("DF 1 Defence 10/02/2023", bundleCreateRequest.getCaseDetails().getCaseData().getStatementsOfCaseDocuments().get(2).getValue().getDocumentFileName()); - assertEquals("CL 1 reply to part 18 request 12/01/2023", + assertEquals("CL's reply 10/02/2023", bundleCreateRequest.getCaseDetails().getCaseData().getStatementsOfCaseDocuments().get(3).getValue().getDocumentFileName()); - assertEquals("CL 2 reply to part 18 request 12/01/2023", + assertEquals("CL 1 reply to part 18 request 12/01/2023", bundleCreateRequest.getCaseDetails().getCaseData().getStatementsOfCaseDocuments().get(4).getValue().getDocumentFileName()); - assertEquals("DF 1 reply to part 18 request 12/01/2023", + assertEquals("CL 2 reply to part 18 request 12/01/2023", bundleCreateRequest.getCaseDetails().getCaseData().getStatementsOfCaseDocuments().get(5).getValue().getDocumentFileName()); - assertEquals("DF 2 reply to part 18 request 12/01/2023", + assertEquals("DF 1 reply to part 18 request 12/01/2023", bundleCreateRequest.getCaseDetails().getCaseData().getStatementsOfCaseDocuments().get(6).getValue().getDocumentFileName()); - assertEquals("Directions Questionnaire 10/02/2023", + assertEquals("DF 2 reply to part 18 request 12/01/2023", bundleCreateRequest.getCaseDetails().getCaseData().getStatementsOfCaseDocuments().get(7).getValue().getDocumentFileName()); + assertEquals("Directions Questionnaire 10/02/2023", + bundleCreateRequest.getCaseDetails().getCaseData().getStatementsOfCaseDocuments().get(8).getValue().getDocumentFileName()); assertEquals("Directions Order 10/02/2023", bundleCreateRequest.getCaseDetails().getCaseData().getOrdersDocuments().get(0).getValue().getDocumentFileName()); assertEquals("Order 10/02/2023", @@ -148,6 +151,7 @@ void testBundleRequestMapperWithAllDocs() { bundleCreateRequest.getCaseDetails().getCaseData().getDefendant1CostsBudgets().get(0).getValue().getDocumentFileName()); assertEquals("testFileName 12/12/2023", bundleCreateRequest.getCaseDetails().getCaseData().getDefendant2CostsBudgets().get(0).getValue().getDocumentFileName()); + } private CaseData getCaseData() { @@ -213,9 +217,19 @@ private CaseData getCaseData() { .respondent2(Party.builder().individualLastName("lastname").individualFirstName("df2Fname").partyName( "respondent2").type(Party.Type.INDIVIDUAL).build()) .hearingDate(LocalDate.now()) + .submittedDate(LocalDateTime.of(2023, 2, 10, 2, + 2, 2)) + .servedDocumentFiles(setupParticularsOfClaimDocs()) .build(); } + private ServedDocumentFiles setupParticularsOfClaimDocs() { + List> particularsOfClaim = new ArrayList<>(); + Document document = Document.builder().documentFileName(TEST_FILE_NAME).documentUrl(TEST_URL).build(); + particularsOfClaim.add(ElementUtils.element(document)); + return ServedDocumentFiles.builder().particularsOfClaimDocument(particularsOfClaim).build(); + } + private List> getExpertOtherPartyQuestionDocs(String partyName) { String expertName = ""; String otherParty = ""; From f5a23fd0f43daec97d80f9a7108e06ac3c2be874 Mon Sep 17 00:00:00 2001 From: asthamalviya <104994907+asthamalviya@users.noreply.github.com> Date: Mon, 6 Nov 2023 12:56:12 +0000 Subject: [PATCH 04/28] CIV-10257 10287_CIV-10168 Adding property for email (#3523) CIV-10168 Update Part admit defendant email notification CIV-10257 Update defendant email when claimant submits intention to proceed for full defence, no mediation cases CIV-10287 Update claimant when claimant submits intention to proceed for full defence, no mediation cases --------- Co-authored-by: kdaHMCTS <128375235+kdaHMCTS@users.noreply.github.com> --- build.gradle | 2 +- ...oProceedRespondentNotificationHandler.java | 62 ++++++++++++++-- ...tResponseApplicantNotificationHandler.java | 39 ++++++++-- src/main/resources/application.yaml | 3 + ...ceedRespondentNotificationHandlerTest.java | 66 ++++++++++++++--- ...ponseApplicantNotificationHandlerTest.java | 72 ++++++++++++++++--- 6 files changed, 213 insertions(+), 31 deletions(-) diff --git a/build.gradle b/build.gradle index 6a518150b2d..7035befae45 100644 --- a/build.gradle +++ b/build.gradle @@ -369,7 +369,7 @@ configurations.all { } dependencies { - implementation 'com.github.hmcts:civil-commons:1.0.31' + implementation 'com.github.hmcts:civil-commons:1.0.33' implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web' implementation group: 'org.springframework.boot', name: 'spring-boot-starter-actuator' implementation group: 'org.springframework.boot', name: 'spring-boot-starter-aop' diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimantResponseConfirmsToProceedRespondentNotificationHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimantResponseConfirmsToProceedRespondentNotificationHandler.java index fb660ca4694..3f80be153d4 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimantResponseConfirmsToProceedRespondentNotificationHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimantResponseConfirmsToProceedRespondentNotificationHandler.java @@ -9,14 +9,20 @@ import uk.gov.hmcts.reform.civil.callback.CallbackParams; import uk.gov.hmcts.reform.civil.callback.CaseEvent; import uk.gov.hmcts.reform.civil.notify.NotificationsProperties; +import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec; +import uk.gov.hmcts.reform.civil.enums.YesOrNo; import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.SmallClaimMedicalLRspec; import uk.gov.hmcts.reform.civil.notify.NotificationService; -import uk.gov.hmcts.reform.civil.service.OrganisationService; +import uk.gov.hmcts.reform.civil.notify.NotificationsProperties; import uk.gov.hmcts.reform.civil.prd.model.Organisation; +import uk.gov.hmcts.reform.civil.service.OrganisationService; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; +import java.util.stream.Stream; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.NOTIFY_RESPONDENT_SOLICITOR1_FOR_CLAIMANT_CONFIRMS_TO_PROCEED; @@ -70,7 +76,7 @@ public List handledEvents() { private CallbackResponse notifyRespondentSolicitorForClaimantConfirmsToProceed(CallbackParams callbackParams) { CaseData caseData = callbackParams.getCaseData(); - String template = null; + String template; var recipient = isCcNotification(callbackParams) ? caseData.getApplicantSolicitor1UserDetails().getEmail() : caseData.getRespondentSolicitor1EmailAddress(); @@ -103,9 +109,7 @@ private CallbackResponse notifyRespondentSolicitorForClaimantConfirmsToProceed(C return AboutToStartOrSubmitCallbackResponse.builder().build(); } if (SPEC_CLAIM.equals(caseData.getCaseAccessCategory())) { - template = isCcNotification(callbackParams) - ? notificationsProperties.getClaimantSolicitorConfirmsToProceedSpec() - : notificationsProperties.getRespondentSolicitorNotifyToProceedSpec(); + template = getSpecTemplate(callbackParams, caseData); } else { template = notificationsProperties.getClaimantSolicitorConfirmsToProceed(); } @@ -123,6 +127,50 @@ private CallbackResponse notifyRespondentSolicitorForClaimantConfirmsToProceed(C return AboutToStartOrSubmitCallbackResponse.builder().build(); } + private String getSpecTemplate(CallbackParams callbackParams, CaseData caseData) { + String template; + if (isCcNotification(callbackParams)) { + if (rejectedAll(caseData) && mediationRejected(caseData)) { + template = notificationsProperties.getClaimantSolicitorConfirmsToProceedSpecWithAction(); + } else { + template = notificationsProperties.getClaimantSolicitorConfirmsToProceedSpec(); + } + } else { + if (rejectedAll(caseData) && mediationRejected(caseData)) { + template = notificationsProperties.getRespondentSolicitorNotifyToProceedSpecWithAction(); + } else { + template = notificationsProperties.getRespondentSolicitorNotifyToProceedSpec(); + } + } + return template; + } + + /** + * Consider that reject all is true if any respondent rejected all the claim. + * + * @param caseData the case data of a spec claim + * @return true if and only if at least one respondent rejected all the claim + */ + private boolean rejectedAll(CaseData caseData) { + return caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.FULL_DEFENCE + || caseData.getRespondent2ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.FULL_DEFENCE; + } + + /** + * Mediation is applicable only when all parties are willing to try it. + * + * @param caseData a spec claim + * @return true if and only if at least one party did not agree to mediation + */ + private boolean mediationRejected(CaseData caseData) { + return Stream.of( + caseData.getResponseClaimMediationSpecRequired(), + caseData.getResponseClaimMediationSpec2Required(), + Optional.ofNullable(caseData.getApplicant1ClaimMediationSpecRequired()) + .map(SmallClaimMedicalLRspec::getHasAgreedFreeMediation).orElse(null) + ).filter(Objects::nonNull).anyMatch(YesOrNo.NO::equals); + } + @Override public Map addProperties(CaseData caseData) { return Map.of( @@ -158,12 +206,12 @@ private boolean isRespondentSolicitor2Notification(CallbackParams callbackParams } //finding legal org name - private String getLegalOrganisationName(CaseData caseData, CaseEvent caseEvent) { + private String getLegalOrganisationName(CaseData caseData, CaseEvent caseEvent) { String organisationID; if (caseEvent.equals(NOTIFY_RESPONDENT_SOLICITOR1_FOR_CLAIMANT_CONFIRMS_TO_PROCEED_CC)) { organisationID = caseData.getApplicant1OrganisationPolicy().getOrganisation().getOrganisationID(); } else { - organisationID = caseEvent.equals(NOTIFY_RESPONDENT_SOLICITOR1_FOR_CLAIMANT_CONFIRMS_TO_PROCEED) + organisationID = caseEvent.equals(NOTIFY_RESPONDENT_SOLICITOR1_FOR_CLAIMANT_CONFIRMS_TO_PROCEED) ? caseData.getRespondent1OrganisationPolicy().getOrganisation().getOrganisationID() : caseData.getRespondent2OrganisationPolicy().getOrganisation().getOrganisationID(); } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/DefendantResponseApplicantNotificationHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/DefendantResponseApplicantNotificationHandler.java index b047d927cf9..cf52061b65c 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/DefendantResponseApplicantNotificationHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/DefendantResponseApplicantNotificationHandler.java @@ -33,7 +33,9 @@ import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_TWO_LEGAL_REP; import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.TWO_V_ONE; import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.getMultiPartyScenario; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec.BY_SET_DATE; import static uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec.IMMEDIATELY; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec.SUGGESTION_OF_REPAYMENT_PLAN; import static uk.gov.hmcts.reform.civil.utils.PartyUtils.buildPartiesReferences; import static uk.gov.hmcts.reform.civil.utils.PartyUtils.getPartyNameBasedOnType; @@ -159,7 +161,11 @@ private void sendNotificationToSolicitorSpec(CaseData caseData, String recipient String.format(REFERENCE_TEMPLATE, caseData.getLegacyCaseReference()) ); } else if (caseEvent.equals(NOTIFY_APPLICANT_SOLICITOR1_FOR_DEFENDANT_RESPONSE_CC)) { - emailTemplate = notificationsProperties.getRespondentSolicitorDefendantResponseForSpec(); + if (MultiPartyScenario.getMultiPartyScenario(caseData).equals(ONE_V_TWO_TWO_LEGAL_REP)) { + emailTemplate = notificationsProperties.getRespondentSolicitorDefendantResponseForSpec(); + } else { + emailTemplate = getTemplateForSpecOtherThan1v2DS(caseData); + } if (caseData.getRespondent1ResponseDate() == null || !MultiPartyScenario.getMultiPartyScenario(caseData) .equals(ONE_V_TWO_TWO_LEGAL_REP)) { notificationService.sendMail( @@ -171,7 +177,11 @@ private void sendNotificationToSolicitorSpec(CaseData caseData, String recipient } } else { - emailTemplate = notificationsProperties.getRespondentSolicitorDefendantResponseForSpec(); + if (MultiPartyScenario.getMultiPartyScenario(caseData).equals(ONE_V_TWO_TWO_LEGAL_REP)) { + emailTemplate = notificationsProperties.getRespondentSolicitorDefendantResponseForSpec(); + } else { + emailTemplate = getTemplateForSpecOtherThan1v2DS(caseData); + } notificationService.sendMail( recipient, emailTemplate, @@ -181,6 +191,23 @@ private void sendNotificationToSolicitorSpec(CaseData caseData, String recipient } } + private String getTemplateForSpecOtherThan1v2DS(CaseData caseData) { + + String emailTemplate; + if ((caseData.getDefenceAdmitPartPaymentTimeRouteRequired() == IMMEDIATELY + || caseData.getDefenceAdmitPartPaymentTimeRouteRequired() == BY_SET_DATE + || caseData.getDefenceAdmitPartPaymentTimeRouteRequired() == SUGGESTION_OF_REPAYMENT_PLAN) + && + (RespondentResponseTypeSpec.PART_ADMISSION.equals(caseData.getRespondent1ClaimResponseTypeForSpec())) + ) { + emailTemplate = notificationsProperties.getRespondentSolicitorDefResponseSpecWithClaimantAction(); + } else { + emailTemplate = notificationsProperties.getRespondentSolicitorDefendantResponseForSpec(); + } + + return emailTemplate; + } + @Override public Map addProperties(CaseData caseData) { if (getMultiPartyScenario(caseData).equals(ONE_V_ONE) || getMultiPartyScenario(caseData).equals(TWO_V_ONE)) { @@ -216,10 +243,10 @@ public Map addPropertiesSpec(CaseData caseData, CaseEvent caseEv + " " + caseData.getRespondToClaimAdmitPartLRspec().getWhenWillThisAmountBePaid().getMonth() + " " + caseData.getRespondToClaimAdmitPartLRspec().getWhenWillThisAmountBePaid().getYear(); return Map.of( - CLAIM_LEGAL_ORG_NAME_SPEC, getLegalOrganisationName(caseData, caseEvent), - CLAIM_REFERENCE_NUMBER, caseData.getLegacyCaseReference(), - RESPONDENT_NAME, getPartyNameBasedOnType(caseData.getApplicant1()), - WHEN_WILL_BE_PAID_IMMEDIATELY, shouldBePaidBy + CLAIM_LEGAL_ORG_NAME_SPEC, getLegalOrganisationName(caseData, caseEvent), + CLAIM_REFERENCE_NUMBER, caseData.getLegacyCaseReference(), + RESPONDENT_NAME, getPartyNameBasedOnType(caseData.getApplicant1()), + WHEN_WILL_BE_PAID_IMMEDIATELY, shouldBePaidBy ); } else { return Map.of( diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 485b2ee98f1..187c0e2b2f9 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -215,6 +215,7 @@ notifications: claimantSolicitorDefendantResponseForSpec: "28ea1d53-93b1-4e48-a7e5-7a876f910f86" claimantSolicitorImmediatelyDefendantResponseForSpec: "263d7737-933d-4d0b-9f08-23847613f6a4" respondentSolicitorDefendantResponseForSpec: "9527f77e-b346-4527-b93c-c2affd39fa51" + respondentSolicitorDefResponseSpecWithClaimantAction: "efbd38e8-3fe7-4db6-ad55-b751b96477b1" respondentDefendantResponseForSpec: "94c71894-9590-4995-aae0-edea94fc4594" sdoOrdered: "90667080-6b20-48f2-b9ea-349fa8ec78e4" sdoOrderedSpec: "1c1a200c-b3c1-45eb-9768-aeea56857420" @@ -228,6 +229,8 @@ notifications: respondentSolicitorNotifyNotToProceedSpec: "4dc0b5bb-674f-401e-8a39-05686dc0302e" claimantSolicitorConfirmsToProceedSpec: "99786d26-ab90-43c7-aa20-9d450d8ce4eb" respondentSolicitorNotifyToProceedSpec: "ea6cb18e-ebba-4759-8df3-426e00f2f09c" + claimantSolicitorConfirmsToProceedSpecWithAction: "d454e5a9-8c56-4a1d-acce-53a1686376bc" + respondentSolicitorNotifyToProceedSpecWithAction: "c1bb435e-0300-4e51-89ec-56dd7f77ef27" applicantSolicitor1DefaultJudgmentReceived: "14a43ad4-e337-490a-bf8b-1288520dc9eb" claimantSolicitorCounterClaimForSpec: "256b6cf4-6201-48f0-bf1e-88a187712196" respondentSolicitorCounterClaimForSpec: "6cb3b3d5-f1aa-4236-ad03-685605a9235e" diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimantResponseConfirmsToProceedRespondentNotificationHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimantResponseConfirmsToProceedRespondentNotificationHandlerTest.java index c9cf92fd0e1..9f67e39cac1 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimantResponseConfirmsToProceedRespondentNotificationHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimantResponseConfirmsToProceedRespondentNotificationHandlerTest.java @@ -12,17 +12,17 @@ import uk.gov.hmcts.reform.civil.callback.CallbackParams; import uk.gov.hmcts.reform.civil.callback.CaseEvent; import uk.gov.hmcts.reform.civil.enums.CaseCategory; -import uk.gov.hmcts.reform.civil.notify.NotificationsProperties; +import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec; import uk.gov.hmcts.reform.civil.enums.YesOrNo; import uk.gov.hmcts.reform.civil.handler.callback.BaseCallbackHandlerTest; -import uk.gov.hmcts.reform.civil.sampledata.PartyBuilder; -import uk.gov.hmcts.reform.civil.service.FeatureToggleService; import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.notify.NotificationService; +import uk.gov.hmcts.reform.civil.notify.NotificationsProperties; +import uk.gov.hmcts.reform.civil.prd.model.Organisation; 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.sampledata.PartyBuilder; import uk.gov.hmcts.reform.civil.service.OrganisationService; -import uk.gov.hmcts.reform.civil.prd.model.Organisation; import java.util.Map; import java.util.Optional; @@ -60,8 +60,6 @@ class ClaimantResponseConfirmsToProceedRespondentNotificationHandlerTest extends private NotificationsProperties notificationsProperties; @Autowired private ClaimantResponseConfirmsToProceedRespondentNotificationHandler handler; - @MockBean - private FeatureToggleService featureToggleService; @Nested class AboutToSubmitCallback { @@ -72,6 +70,8 @@ void setup() { when(notificationsProperties.getClaimantSolicitorConfirmsNotToProceed()).thenReturn("template-id"); when(notificationsProperties.getRespondentSolicitorNotifyToProceedSpec()).thenReturn("spec-template-id"); when(notificationsProperties.getClaimantSolicitorConfirmsToProceedSpec()).thenReturn("spec-template-id"); + when(notificationsProperties.getRespondentSolicitorNotifyToProceedSpecWithAction()).thenReturn("spec-template-no-mediation"); + when(notificationsProperties.getClaimantSolicitorConfirmsToProceedSpecWithAction()).thenReturn("spec-template-no-mediation"); when(notificationsProperties.getRespondent1LipClaimUpdatedTemplate()).thenReturn("spec-template-id"); } @@ -113,6 +113,30 @@ void shouldNotifyRespondentSolicitor_whenInvoked_spec() { ); } + @Test + void shouldNotifyRespondentSolicitor_whenSpecRejectAllNoMediation() { + CaseData caseData = CaseDataBuilder.builder() + .atStateClaimDetailsNotified() + .setClaimTypeToSpecClaim() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .build().toBuilder() + .responseClaimMediationSpecRequired(YesOrNo.NO) + .build(); + CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData).request( + CallbackRequest.builder().eventId("NOTIFY_RESPONDENT_SOLICITOR1_FOR_CLAIMANT_CONFIRMS_TO_PROCEED") + .build()).build(); + + handler.handle(params); + + verify(notificationService).sendMail( + "respondentsolicitor@example.com", + "spec-template-no-mediation", + getNotificationDataMapSpec(caseData, + CaseEvent.NOTIFY_RESPONDENT_SOLICITOR1_FOR_CLAIMANT_CONFIRMS_TO_PROCEED), + "claimant-confirms-to-proceed-respondent-notification-000DC001" + ); + } + @Test void shouldNotifyRespondentSolicitor2_whenInvoked_spec() { CaseData caseData = CaseDataBuilder.builder() @@ -155,6 +179,30 @@ void shouldNotifyApplicantSolicitor_whenInvoked_spec() { ); } + @Test + void shouldNotifyApplicantSolicitor_whenSpecRejectAllNoMediation() { + CaseData caseData = CaseDataBuilder.builder() + .atStateClaimDetailsNotified() + .setClaimTypeToSpecClaim() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .build().toBuilder() + .responseClaimMediationSpecRequired(YesOrNo.NO) + .build(); + CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData).request( + CallbackRequest.builder().eventId("NOTIFY_RESPONDENT_SOLICITOR1_FOR_CLAIMANT_CONFIRMS_TO_PROCEED_CC") + .build()).build(); + + handler.handle(params); + + verify(notificationService).sendMail( + "applicantsolicitor@example.com", + "spec-template-no-mediation", + getNotificationDataMapSpec(caseData, + CaseEvent.NOTIFY_RESPONDENT_SOLICITOR1_FOR_CLAIMANT_CONFIRMS_TO_PROCEED_CC), + "claimant-confirms-to-proceed-respondent-notification-000DC001" + ); + } + @Test void shouldNotifyRespondentSolicitor2withNoIntentionToProceed_whenInvoked() { CaseData caseData = CaseDataBuilder.builder() @@ -316,11 +364,11 @@ void shouldReturnCorrectCamundaActivityId_whenInvoked() { "NOTIFY_RESPONDENT_SOLICITOR1_FOR_CLAIMANT_CONFIRMS_TO_PROCEED").build()).build())).isEqualTo(TASK_ID); assertThat(handler.camundaActivityId(CallbackParamsBuilder.builder().request(CallbackRequest.builder().eventId( - "NOTIFY_RESPONDENT_SOLICITOR2_FOR_CLAIMANT_CONFIRMS_TO_PROCEED").build()) + "NOTIFY_RESPONDENT_SOLICITOR2_FOR_CLAIMANT_CONFIRMS_TO_PROCEED").build()) .build())).isEqualTo(Task_ID_RESPONDENT_SOL2); assertThat(handler.camundaActivityId(CallbackParamsBuilder.builder().request(CallbackRequest.builder().eventId( "NOTIFY_RESPONDENT_SOLICITOR1_FOR_CLAIMANT_CONFIRMS_TO_PROCEED_CC").build()).build())).isEqualTo( - TASK_ID_CC); + TASK_ID_CC); } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/DefendantResponseApplicantNotificationHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/DefendantResponseApplicantNotificationHandlerTest.java index b0f44a92d31..b9c5d6e3dee 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/DefendantResponseApplicantNotificationHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/DefendantResponseApplicantNotificationHandlerTest.java @@ -85,7 +85,7 @@ void setup() { when(organisationService.findOrganisationById(anyString())) .thenReturn(Optional.of(Organisation.builder().name("Signer Name").build())); when(notificationsProperties.getClaimantSolicitorImmediatelyDefendantResponseForSpec()).thenReturn("templateImm-id"); - + when(notificationsProperties.getRespondentSolicitorDefResponseSpecWithClaimantAction()).thenReturn("spec-respondent-template-id-action"); } @Nested @@ -168,17 +168,17 @@ void shouldNotifyApplicantSolicitorSpec_whenInvoked() { LocalDate whenWillPay = LocalDate.now().plusMonths(1); CaseData caseData = CaseDataBuilder.builder() - .atStateNotificationAcknowledged() - .build().toBuilder() - .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .atStateNotificationAcknowledged() + .build().toBuilder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) .defenceAdmitPartPaymentTimeRouteRequired(RespondentResponsePartAdmissionPaymentTimeLRspec.BY_SET_DATE) - .respondToClaimAdmitPartLRspec( - RespondToClaimAdmitPartLRspec.builder() + .respondToClaimAdmitPartLRspec( + RespondToClaimAdmitPartLRspec.builder() .whenWillThisAmountBePaid(whenWillPay) .build() - ) - .build(); + ) + .build(); caseData = caseData.toBuilder().caseAccessCategory(SPEC_CLAIM).build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData).request( CallbackRequest.builder().eventId("NOTIFY_APPLICANT_SOLICITOR1_FOR_DEFENDANT_RESPONSE").build()) @@ -341,6 +341,29 @@ void shouldNotifyRespondentSolicitorSpecDef1_whenInvokedWithCcEvent() { handler.handle(params); + verify(notificationService).sendMail( + "respondentsolicitor@example.com", + "spec-respondent-template-id", + getNotificationDataMapPartAdmissionSpec(caseData), + "defendant-response-applicant-notification-000DC001" + ); + } + + @Test + void sendNotificationToSolicitorSpec_shouldNotifyRespondentSolicitorSpecDef1v1() { + CaseData caseData = CaseDataBuilder.builder() + .atStateNotificationAcknowledged().build(); + caseData = caseData.toBuilder().caseAccessCategory(SPEC_CLAIM) + .respondent1DQ(Respondent1DQ.builder().build()) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .build(); + CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData).request( + CallbackRequest.builder().eventId("NOTIFY_APPLICANT_SOLICITOR1_FOR_DEFENDANT_RESPONSE_CC") + .build()) + .build(); + + handler.handle(params); + verify(notificationService).sendMail( "respondentsolicitor@example.com", "spec-respondent-template-id", @@ -349,6 +372,30 @@ void shouldNotifyRespondentSolicitorSpecDef1_whenInvokedWithCcEvent() { ); } + @Test + void sendNotificationToSolicitorSpecPart_shouldNotifyRespondentSolicitorSpecDef1v1() { + CaseData caseData = CaseDataBuilder.builder() + .atStateNotificationAcknowledged().build(); + caseData = caseData.toBuilder().caseAccessCategory(SPEC_CLAIM) + .respondent1DQ(Respondent1DQ.builder().build()) + .defenceAdmitPartPaymentTimeRouteRequired(RespondentResponsePartAdmissionPaymentTimeLRspec.IMMEDIATELY) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .build(); + CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData).request( + CallbackRequest.builder().eventId("NOTIFY_APPLICANT_SOLICITOR1_FOR_DEFENDANT_RESPONSE_CC") + .build()) + .build(); + + handler.handle(params); + + verify(notificationService).sendMail( + "respondentsolicitor@example.com", + "spec-respondent-template-id-action", + getNotificationDataMapSpec(caseData), + "defendant-response-applicant-notification-000DC001" + ); + } + @Test void shouldNotifyRespondentSolicitorSpecDef1SecondScenerio_whenInvokedWithCcEvent() { CaseData caseData = CaseDataBuilder.builder() @@ -546,6 +593,15 @@ private Map getNotificationDataMapImmediatelySpec(CaseData caseD ); } + + private Map getNotificationDataMapPartAdmissionSpec(CaseData caseData) { + return Map.of( + "defendantName", "Mr. Sole Trader", + CLAIM_LEGAL_ORG_NAME_SPEC, "Signer Name", + CLAIM_REFERENCE_NUMBER, LEGACY_CASE_REFERENCE + ); + } + } @Test From 61943ed6c6fa035e59b349c4f99c6d67f39e8ec1 Mon Sep 17 00:00:00 2001 From: MMNycz <94067802+MMNycz@users.noreply.github.com> Date: Mon, 6 Nov 2023 15:11:37 +0000 Subject: [PATCH 05/28] CIV-10986 case not proceeding to judicial referral (#3411) * CIV-10986 fix one_v_two_two_rep validation * Update suppressions.xml * Remove updated supressions * CIV-10986 update spec shouldMoveToJudicialReferral * refactor shouldMoveToJudicialReferral method --------- Co-authored-by: mfallonhmcts <114912573+mfallonhmcts@users.noreply.github.com> --- .../user/RespondToDefenceCallbackHandler.java | 51 +--------------- .../RespondToDefenceSpecCallbackHandler.java | 3 +- .../service/flowstate/StateFlowEngine.java | 20 +++---- .../civil/utils/JudicialReferralUtils.java | 58 +++++++++++++++++++ ...spondToDefenceSpecCallbackHandlerTest.java | 2 + .../utils/JudicialReferralUtilsTest.java | 53 +++++++++++++++++ 6 files changed, 127 insertions(+), 60 deletions(-) create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/utils/JudicialReferralUtils.java create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/utils/JudicialReferralUtilsTest.java diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceCallbackHandler.java index add98412f45..7b1599b7eb8 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceCallbackHandler.java @@ -14,12 +14,10 @@ import uk.gov.hmcts.reform.civil.config.ToggleConfiguration; import uk.gov.hmcts.reform.civil.documentmanagement.model.CaseDocument; import uk.gov.hmcts.reform.civil.documentmanagement.model.DocumentType; -import uk.gov.hmcts.reform.civil.enums.AllocatedTrack; import uk.gov.hmcts.reform.civil.enums.CaseCategory; import uk.gov.hmcts.reform.civil.enums.CaseState; import uk.gov.hmcts.reform.civil.enums.DocCategory; import uk.gov.hmcts.reform.civil.enums.MultiPartyScenario; -import uk.gov.hmcts.reform.civil.enums.YesOrNo; import uk.gov.hmcts.reform.civil.helpers.LocationHelper; import uk.gov.hmcts.reform.civil.model.BusinessProcess; import uk.gov.hmcts.reform.civil.model.CaseData; @@ -36,6 +34,7 @@ import uk.gov.hmcts.reform.civil.service.Time; import uk.gov.hmcts.reform.civil.utils.AssignCategoryId; import uk.gov.hmcts.reform.civil.utils.CaseFlagsInitialiser; +import uk.gov.hmcts.reform.civil.utils.JudicialReferralUtils; import uk.gov.hmcts.reform.civil.utils.LocationRefDataUtil; import uk.gov.hmcts.reform.civil.utils.UnavailabilityDatesUtils; import uk.gov.hmcts.reform.civil.validation.UnavailableDateValidator; @@ -56,7 +55,6 @@ import static uk.gov.hmcts.reform.civil.callback.CallbackType.MID; import static uk.gov.hmcts.reform.civil.callback.CallbackType.SUBMITTED; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.CLAIMANT_RESPONSE; -import static uk.gov.hmcts.reform.civil.enums.AllocatedTrack.getAllocatedTrack; import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_ONE_LEGAL_REP; import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_TWO_LEGAL_REP; import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.TWO_V_ONE; @@ -288,57 +286,12 @@ private CallbackResponse aboutToSubmit(CallbackParams callbackParams) { return AboutToStartOrSubmitCallbackResponse.builder() .data(builder.build().toMap(objectMapper)) - .state((shouldMoveToJudicialReferral(caseData) + .state((JudicialReferralUtils.shouldMoveToJudicialReferral(caseData) ? CaseState.JUDICIAL_REFERRAL : CaseState.PROCEEDS_IN_HERITAGE_SYSTEM).name()) .build(); } - /** - * Computes whether the case data should move to judicial referral or not. - * - * @param caseData a case data such that defendants rejected the claim, and claimant(s) wants to proceed - * vs all the defendants - * @return true if and only if the case should move to judicial referral - */ - public static boolean shouldMoveToJudicialReferral(CaseData caseData) { - CaseCategory caseCategory = caseData.getCaseAccessCategory(); - - if (CaseCategory.SPEC_CLAIM.equals(caseCategory)) { - MultiPartyScenario multiPartyScenario = getMultiPartyScenario(caseData); - boolean addRespondent2 = YES.equals(caseData.getAddRespondent2()); - - return switch (multiPartyScenario) { - case ONE_V_ONE -> caseData.getApplicant1ProceedWithClaim() == YesOrNo.YES; - case TWO_V_ONE -> caseData.getApplicant1ProceedWithClaimSpec2v1() == YesOrNo.YES; - case ONE_V_TWO_ONE_LEGAL_REP -> addRespondent2 - && YES.equals(caseData.getRespondentResponseIsSame()); - case ONE_V_TWO_TWO_LEGAL_REP -> addRespondent2 - && caseData.getRespondentResponseIsSame() == null; - }; - } else { - AllocatedTrack allocatedTrack = - getAllocatedTrack( - CaseCategory.UNSPEC_CLAIM.equals(caseCategory) - ? caseData.getClaimValue().toPounds() - : caseData.getTotalClaimAmount(), - caseData.getClaimType() - ); - if (AllocatedTrack.MULTI_CLAIM.equals(allocatedTrack)) { - return false; - } - MultiPartyScenario multiPartyScenario = getMultiPartyScenario(caseData); - return switch (multiPartyScenario) { - case ONE_V_ONE -> caseData.getApplicant1ProceedWithClaim() == YesOrNo.YES; - case TWO_V_ONE -> caseData.getApplicant1ProceedWithClaimMultiParty2v1() == YES - && caseData.getApplicant2ProceedWithClaimMultiParty2v1() == YES; - case ONE_V_TWO_ONE_LEGAL_REP, ONE_V_TWO_TWO_LEGAL_REP -> - caseData.getApplicant1ProceedWithClaimAgainstRespondent1MultiParty1v2() == YES - && caseData.getApplicant1ProceedWithClaimAgainstRespondent2MultiParty1v2() == YES; - }; - } - } - private void updateApplicants(CaseData caseData, CaseData.CaseDataBuilder builder, StatementOfTruth statementOfTruth) { if (caseData.getApplicant1DQ() != null && caseData.getApplicant1DQ().getApplicant1DQFileDirectionsQuestionnaire() != null) { diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandler.java index 9a9bad9f366..bc39dbf86fe 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandler.java @@ -43,6 +43,7 @@ import uk.gov.hmcts.reform.civil.service.citizenui.ResponseOneVOneShowTagService; import uk.gov.hmcts.reform.civil.utils.CaseFlagsInitialiser; import uk.gov.hmcts.reform.civil.utils.CourtLocationUtils; +import uk.gov.hmcts.reform.civil.utils.JudicialReferralUtils; import uk.gov.hmcts.reform.civil.utils.MonetaryConversions; import uk.gov.hmcts.reform.civil.utils.UnavailabilityDatesUtils; import uk.gov.hmcts.reform.civil.validation.UnavailableDateValidator; @@ -384,7 +385,7 @@ private void updateDQCourtLocations(CallbackParams callbackParams, CaseData case private void putCaseStateInJudicialReferral(CaseData caseData, AboutToStartOrSubmitCallbackResponse.AboutToStartOrSubmitCallbackResponseBuilder response) { if (caseData.isRespondentResponseFullDefence() - && RespondToDefenceCallbackHandler.shouldMoveToJudicialReferral(caseData)) { + && JudicialReferralUtils.shouldMoveToJudicialReferral(caseData)) { response.state(CaseState.JUDICIAL_REFERRAL.name()); } } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngine.java b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngine.java index 03ad14f2cee..39f82bb7088 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngine.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngine.java @@ -3,13 +3,13 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import uk.gov.hmcts.reform.ccd.client.model.CaseDetails; -import uk.gov.hmcts.reform.civil.handler.callback.user.RespondToDefenceCallbackHandler; import uk.gov.hmcts.reform.civil.helpers.CaseDetailsConverter; import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.service.FeatureToggleService; import uk.gov.hmcts.reform.civil.stateflow.StateFlow; import uk.gov.hmcts.reform.civil.stateflow.StateFlowBuilder; import uk.gov.hmcts.reform.civil.stateflow.model.State; +import uk.gov.hmcts.reform.civil.utils.JudicialReferralUtils; import java.util.Map; @@ -18,8 +18,8 @@ import static uk.gov.hmcts.reform.civil.service.flowstate.FlowFlag.BULK_CLAIM_ENABLED; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowFlag.GENERAL_APPLICATION_ENABLED; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowLipPredicate.agreedToMediation; -import static uk.gov.hmcts.reform.civil.service.flowstate.FlowLipPredicate.declinedMediation; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowLipPredicate.ccjRequestJudgmentByAdmission; +import static uk.gov.hmcts.reform.civil.service.flowstate.FlowLipPredicate.declinedMediation; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowLipPredicate.isLipCase; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowLipPredicate.isTranslatedDocumentUploaded; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowLipPredicate.partAdmitPayImmediately; @@ -40,9 +40,9 @@ import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.caseDismissedAfterDetailNotifiedExtension; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.caseDismissedPastHearingFeeDue; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.casemanMarksMediationUnsuccessful; -import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimDismissalOutOfTime; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.certificateOfServiceEnabled; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimDetailsNotified; +import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimDismissalOutOfTime; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimDismissedByCamunda; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimIssued; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimNotified; @@ -72,8 +72,8 @@ import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.fullDefenceSpec; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.isClaimantNotSettlePartAdmitClaim; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.isInHearingReadiness; -import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.isRespondentResponseLangIsBilingual; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.isPayImmediately; +import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.isRespondentResponseLangIsBilingual; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.multipartyCase; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.noticeOfChangeEnabled; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.notificationAcknowledged; @@ -137,11 +137,11 @@ import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.FLOW_NAME; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.FULL_ADMISSION; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.FULL_ADMIT_AGREE_REPAYMENT; +import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.FULL_ADMIT_JUDGMENT_ADMISSION; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.FULL_ADMIT_NOT_PROCEED; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.FULL_ADMIT_PAY_IMMEDIATELY; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.FULL_ADMIT_PROCEED; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.FULL_ADMIT_REJECT_REPAYMENT; -import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.FULL_ADMIT_JUDGMENT_ADMISSION; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.FULL_DEFENCE; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.FULL_DEFENCE_NOT_PROCEED; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.FULL_DEFENCE_PROCEED; @@ -153,9 +153,9 @@ import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PART_ADMISSION; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PART_ADMIT_AGREE_REPAYMENT; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PART_ADMIT_AGREE_SETTLE; -import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PART_ADMIT_PAY_IMMEDIATELY; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PART_ADMIT_NOT_PROCEED; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PART_ADMIT_NOT_SETTLED_NO_MEDIATION; +import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PART_ADMIT_PAY_IMMEDIATELY; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PART_ADMIT_PROCEED; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PART_ADMIT_REJECT_REPAYMENT; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PAST_APPLICANT_RESPONSE_DEADLINE_AWAITING_CAMUNDA; @@ -507,20 +507,20 @@ public StateFlow build(FlowState.Main initialState) { .onlyIf(fullDefenceProceed.and(allAgreedToLrMediationSpec).and(agreedToMediation.negate()).and(declinedMediation.negate())) .set((c, flags) -> { flags.put(FlowFlag.AGREED_TO_MEDIATION.name(), true); - flags.put(FlowFlag.SDO_ENABLED.name(), RespondToDefenceCallbackHandler.shouldMoveToJudicialReferral(c)); + flags.put(FlowFlag.SDO_ENABLED.name(), JudicialReferralUtils.shouldMoveToJudicialReferral(c)); }) .transitionTo(FULL_DEFENCE_PROCEED) .onlyIf(fullDefenceProceed.and(allAgreedToLrMediationSpec.negate().and(agreedToMediation.negate())) .or(declinedMediation).and(applicantOutOfTime.negate()).and(demageMultiClaim)) .set((c, flags) -> { flags.put(FlowFlag.IS_MULTI_TRACK.name(), true); - flags.put(FlowFlag.SDO_ENABLED.name(), RespondToDefenceCallbackHandler.shouldMoveToJudicialReferral(c)); + flags.put(FlowFlag.SDO_ENABLED.name(), JudicialReferralUtils.shouldMoveToJudicialReferral(c)); }) .transitionTo(FULL_DEFENCE_PROCEED) .onlyIf(fullDefenceProceed.and(allAgreedToLrMediationSpec.negate().and(agreedToMediation.negate())) .or(declinedMediation).and(applicantOutOfTime.negate()).and(demageMultiClaim.negate())) .setDynamic(Map.of(FlowFlag.SDO_ENABLED.name(), - RespondToDefenceCallbackHandler::shouldMoveToJudicialReferral)) + JudicialReferralUtils::shouldMoveToJudicialReferral)) .transitionTo(FULL_DEFENCE_NOT_PROCEED).onlyIf(fullDefenceNotProceed) .transitionTo(TAKEN_OFFLINE_BY_STAFF).onlyIf(takenOfflineByStaffAfterDefendantResponse) .transitionTo(PAST_APPLICANT_RESPONSE_DEADLINE_AWAITING_CAMUNDA) @@ -554,7 +554,7 @@ public StateFlow build(FlowState.Main initialState) { .transitionTo(PART_ADMIT_NOT_SETTLED_NO_MEDIATION) .onlyIf(isClaimantNotSettlePartAdmitClaim.and(not(agreedToMediation))) .setDynamic(Map.of(FlowFlag.SDO_ENABLED.name(), - RespondToDefenceCallbackHandler::shouldMoveToJudicialReferral)) + JudicialReferralUtils::shouldMoveToJudicialReferral)) .transitionTo(PART_ADMIT_PROCEED).onlyIf(fullDefenceProceed) .transitionTo(PART_ADMIT_NOT_PROCEED).onlyIf(fullDefenceNotProceed) .transitionTo(PART_ADMIT_PAY_IMMEDIATELY).onlyIf(partAdmitPayImmediately) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/utils/JudicialReferralUtils.java b/src/main/java/uk/gov/hmcts/reform/civil/utils/JudicialReferralUtils.java new file mode 100644 index 00000000000..2df4c2c08f1 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/utils/JudicialReferralUtils.java @@ -0,0 +1,58 @@ +package uk.gov.hmcts.reform.civil.utils; + +import uk.gov.hmcts.reform.civil.enums.AllocatedTrack; +import uk.gov.hmcts.reform.civil.enums.CaseCategory; +import uk.gov.hmcts.reform.civil.enums.MultiPartyScenario; +import uk.gov.hmcts.reform.civil.enums.YesOrNo; +import uk.gov.hmcts.reform.civil.model.CaseData; + +import static uk.gov.hmcts.reform.civil.enums.AllocatedTrack.getAllocatedTrack; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.getMultiPartyScenario; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; + +public class JudicialReferralUtils { + + private JudicialReferralUtils() { + //NO-OP + } + + /** + * Computes whether the case data should move to judicial referral or not. + * + * @param caseData a case data such that defendants rejected the claim, and claimant(s) wants to proceed + * vs all the defendants + * @return true if and only if the case should move to judicial referral + */ + public static boolean shouldMoveToJudicialReferral(CaseData caseData) { + CaseCategory caseCategory = caseData.getCaseAccessCategory(); + + if (CaseCategory.SPEC_CLAIM.equals(caseCategory)) { + MultiPartyScenario multiPartyScenario = getMultiPartyScenario(caseData); + + return switch (multiPartyScenario) { + case ONE_V_ONE, ONE_V_TWO_ONE_LEGAL_REP, ONE_V_TWO_TWO_LEGAL_REP -> caseData.getApplicant1ProceedWithClaim() == YesOrNo.YES; + case TWO_V_ONE -> caseData.getApplicant1ProceedWithClaimSpec2v1() == YesOrNo.YES; + }; + } else { + AllocatedTrack allocatedTrack = + getAllocatedTrack( + CaseCategory.UNSPEC_CLAIM.equals(caseCategory) + ? caseData.getClaimValue().toPounds() + : caseData.getTotalClaimAmount(), + caseData.getClaimType() + ); + if (AllocatedTrack.MULTI_CLAIM.equals(allocatedTrack)) { + return false; + } + MultiPartyScenario multiPartyScenario = getMultiPartyScenario(caseData); + return switch (multiPartyScenario) { + case ONE_V_ONE -> caseData.getApplicant1ProceedWithClaim() == YesOrNo.YES; + case TWO_V_ONE -> caseData.getApplicant1ProceedWithClaimMultiParty2v1() == YES + && caseData.getApplicant2ProceedWithClaimMultiParty2v1() == YES; + case ONE_V_TWO_ONE_LEGAL_REP, ONE_V_TWO_TWO_LEGAL_REP -> + caseData.getApplicant1ProceedWithClaimAgainstRespondent1MultiParty1v2() == YES + && caseData.getApplicant1ProceedWithClaimAgainstRespondent2MultiParty1v2() == YES; + }; + } + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandlerTest.java index 19edb10eacf..15c778c9771 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandlerTest.java @@ -1084,6 +1084,7 @@ void shouldChangeCaseStateToJudicialReferral_ONE_V_TWO_ONE_REP() { .addRespondent2(YES) .respondentResponseIsSame(YES) .responseClaimTrack(FAST_CLAIM.name()) + .applicant1ProceedWithClaim(YES) .applicant1DQ(Applicant1DQ.builder().applicant1RespondToClaimExperts( ExpertDetails.builder().build()).build()) .respondent1(Party.builder().type(Party.Type.INDIVIDUAL).build()).build(); @@ -1104,6 +1105,7 @@ void shouldChangeCaseStateToJudicialReferral_ONE_V_TWO_TWO_REP() { .respondent2SameLegalRepresentative(NO) .addRespondent2(YES) .responseClaimTrack(FAST_CLAIM.name()) + .applicant1ProceedWithClaim(YES) .applicant1DQ(Applicant1DQ.builder().applicant1RespondToClaimExperts( ExpertDetails.builder().build()).build()) .respondent1(Party.builder().type(Party.Type.INDIVIDUAL).build()).build(); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/utils/JudicialReferralUtilsTest.java b/src/test/java/uk/gov/hmcts/reform/civil/utils/JudicialReferralUtilsTest.java new file mode 100644 index 00000000000..72601e30b71 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/utils/JudicialReferralUtilsTest.java @@ -0,0 +1,53 @@ +package uk.gov.hmcts.reform.civil.utils; + +import org.junit.jupiter.api.Test; +import uk.gov.hmcts.reform.civil.enums.CaseCategory; +import uk.gov.hmcts.reform.civil.enums.YesOrNo; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.ClaimValue; + +import java.math.BigDecimal; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; + +public class JudicialReferralUtilsTest { + + @Test + public void testShouldMoveToJudicialReferralForSpecClaim() { + CaseData caseData = CaseData.builder() + .caseAccessCategory(CaseCategory.SPEC_CLAIM) + .applicant1ProceedWithClaim(YesOrNo.YES) + .build(); + + boolean judicialReferralUtils = JudicialReferralUtils.shouldMoveToJudicialReferral(caseData); + assertTrue(judicialReferralUtils); + } + + @Test + public void testShouldNotMoveToJudicialReferralForSpecClaim() { + CaseData caseData = CaseData.builder() + .caseAccessCategory(CaseCategory.SPEC_CLAIM) + .applicant1ProceedWithClaim(YesOrNo.NO) + .build(); + + boolean judicialReferralUtils = JudicialReferralUtils.shouldMoveToJudicialReferral(caseData); + + assertFalse(judicialReferralUtils); + } + + @Test + public void testShouldMoveToJudicialReferralForUnspecClaim() { + CaseData caseData = CaseData.builder() + .caseAccessCategory(CaseCategory.UNSPEC_CLAIM) + .claimValue(ClaimValue.builder() + .statementOfValueInPennies(BigDecimal.valueOf(10000_00)) + .build()) + .applicant1ProceedWithClaim(YesOrNo.YES) + .build(); + + boolean judicialReferralUtils = JudicialReferralUtils.shouldMoveToJudicialReferral(caseData); + assertTrue(judicialReferralUtils); + } + +} From 29cd440a9280f5b534d1239645ed5c036716ce2e Mon Sep 17 00:00:00 2001 From: LTurkingtonHMCTS <95024266+LTurkingtonHMCTS@users.noreply.github.com> Date: Tue, 7 Nov 2023 08:16:04 +0000 Subject: [PATCH 06/28] CIV-10337 eaCourtLocation WA (#3380) * Added location whitelisting mechanism * Updated unit tests * Updated commons * Added whitelisted location check to create sdo handler * --amend * Update build.gradle * Set location whitelist toggle default value to false * Update build.gradle * Update build.gradle * Update build.gradle * Update FeatureToggleService.java Set default value back to true * Update FeatureToggleService.java * default to true * fix test * change value back to false * adding eaCourtLocation to CaseDataParent * suppress cve * suppressions * update commons version * fix commons version * suppressions * populating epims id * supressions * checkstyle * updating tests * sonar exclusions * DJ eaCourtLocation, DJ tests, checkstyle * sonar exclusions * fix null pointer getEpimmsId DJ * Added early adopters toggle and updated unit tests * Removed supressions and sonar exclusions * Refactored unit tests * updated getEpimmsId to use alternate flags * adding logs * adding logs * getting track from sdoHelper * Fixed unit tests * Removed create sdo logging --------- Co-authored-by: GarethLancaster <31533575+Gareth40342@users.noreply.github.com> Co-authored-by: Gareth Lancaster <90632240+Gareth40343@users.noreply.github.com> Co-authored-by: sankaviv1 <95748224+sankaviv1@users.noreply.github.com> Co-authored-by: sankaviv1 Co-authored-by: AhsanZX97 Co-authored-by: Hemanth Potipati --- .../user/CreateSDOCallbackHandler.java | 47 ++- .../user/StandardDirectionOrderDJ.java | 47 ++- .../reform/civil/model/CaseDataParent.java | 2 + .../civil/model/common/DynamicList.java | 25 +- .../user/CreateSDOCallbackHandlerTest.java | 288 +++++++++++++++++- .../user/StandardDirectionOrderDJTest.java | 143 ++++++++- .../civil/model/common/DynamicListTest.java | 57 ++++ 7 files changed, 586 insertions(+), 23 deletions(-) create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/model/common/DynamicListTest.java diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateSDOCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateSDOCallbackHandler.java index 6aae628746a..32770c5f47a 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateSDOCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateSDOCallbackHandler.java @@ -98,6 +98,9 @@ import static uk.gov.hmcts.reform.civil.callback.CallbackType.SUBMITTED; import static uk.gov.hmcts.reform.civil.callback.CallbackVersion.V_1; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.CREATE_SDO; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; +import static uk.gov.hmcts.reform.civil.enums.sdo.OrderDetailsPagesSectionsToggle.SHOW; +import static uk.gov.hmcts.reform.civil.enums.sdo.OrderType.DISPOSAL; import static uk.gov.hmcts.reform.civil.helpers.DateFormatHelper.DATE; import static uk.gov.hmcts.reform.civil.utils.ElementUtils.element; import static uk.gov.hmcts.reform.civil.utils.HearingUtils.getHearingNotes; @@ -219,7 +222,7 @@ private CallbackResponse prePopulateOrderDetailsPages(CallbackParams callbackPar updatedData.fastTrackMethodInPerson(locationsList); updatedData.smallClaimsMethodInPerson(locationsList); - List checkList = List.of(OrderDetailsPagesSectionsToggle.SHOW); + List checkList = List.of(SHOW); setCheckList(updatedData, checkList); DisposalHearingJudgesRecital tempDisposalHearingJudgesRecital = DisposalHearingJudgesRecital.builder() @@ -711,17 +714,21 @@ private DynamicList getLocationList(CallbackParams callbackParams, )); DynamicList locationsList; if (matchingLocation.isPresent()) { - locationsList = DynamicList.fromList(locations, LocationRefDataService::getDisplayEntry, + locationsList = DynamicList.fromList(locations, this::getLocationEpimms, LocationRefDataService::getDisplayEntry, matchingLocation.get(), true ); } else { - locationsList = DynamicList.fromList(locations, LocationRefDataService::getDisplayEntry, + locationsList = DynamicList.fromList(locations, this::getLocationEpimms, LocationRefDataService::getDisplayEntry, null, true ); } return locationsList; } + private String getLocationEpimms(LocationRefData location) { + return location.getEpimmsId(); + } + private CallbackResponse setOrderDetailsFlags(CallbackParams callbackParams) { CaseData caseData = callbackParams.getCaseData(); CaseData.CaseDataBuilder updatedData = caseData.toBuilder(); @@ -732,9 +739,9 @@ private CallbackResponse setOrderDetailsFlags(CallbackParams callbackParams) { updatedData.setFastTrackFlag(YesOrNo.NO).build(); if (SdoHelper.isSmallClaimsTrack(caseData)) { - updatedData.setSmallClaimsFlag(YesOrNo.YES).build(); + updatedData.setSmallClaimsFlag(YES).build(); } else if (SdoHelper.isFastTrack(caseData)) { - updatedData.setFastTrackFlag(YesOrNo.YES).build(); + updatedData.setFastTrackFlag(YES).build(); } return AboutToStartOrSubmitCallbackResponse.builder() @@ -836,18 +843,38 @@ private CallbackResponse submitSDO(CallbackParams callbackParams) { dataBuilder.hearingNotes(getHearingNotes(caseData)); - if (featureToggleService.isLocationWhiteListedForCaseProgression( - caseData.getCaseManagementLocation().getBaseLocation())) { - log.info("Case {} is whitelisted for case progression.", caseData.getCcdCaseReference()); - } else { - log.info("Case {} is NOT whitelisted for case progression.", caseData.getCcdCaseReference()); + if (featureToggleService.isEarlyAdoptersEnabled()) { + if (featureToggleService.isLocationWhiteListedForCaseProgression( + getEpimmsId(caseData))) { + log.info("Case {} is whitelisted for case progression.", caseData.getCcdCaseReference()); + dataBuilder.eaCourtLocation(YES); + } else { + log.info("Case {} is NOT whitelisted for case progression.", caseData.getCcdCaseReference()); + dataBuilder.eaCourtLocation(YesOrNo.NO); + } } + System.out.println("before about to submit"); + return AboutToStartOrSubmitCallbackResponse.builder() .data(dataBuilder.build().toMap(objectMapper)) .build(); } + private String getEpimmsId(CaseData caseData) { + + if (caseData.getOrderType() != null && caseData.getOrderType().equals(DISPOSAL)) { + return caseData.getDisposalHearingMethodInPerson().getValue().getCode(); + } + if (SdoHelper.isFastTrack(caseData)) { + return caseData.getFastTrackMethodInPerson().getValue().getCode(); + } + if (SdoHelper.isSmallClaimsTrack(caseData)) { + return caseData.getSmallClaimsMethodInPerson().getValue().getCode(); + } + throw new IllegalArgumentException("Could not determine claim track"); + } + private boolean nonNull(Object object) { if (object != null) { return true; diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/StandardDirectionOrderDJ.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/StandardDirectionOrderDJ.java index e5202ab4def..70020cfb326 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/StandardDirectionOrderDJ.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/StandardDirectionOrderDJ.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableMap; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import uk.gov.hmcts.reform.ccd.client.model.AboutToStartOrSubmitCallbackResponse; @@ -17,6 +18,7 @@ import uk.gov.hmcts.reform.civil.documentmanagement.model.CaseDocument; import uk.gov.hmcts.reform.civil.enums.CaseCategory; import uk.gov.hmcts.reform.civil.enums.MultiPartyScenario; +import uk.gov.hmcts.reform.civil.enums.YesOrNo; import uk.gov.hmcts.reform.civil.enums.dj.DisposalAndTrialHearingDJToggle; import uk.gov.hmcts.reform.civil.enums.dj.DisposalHearingMethodDJ; import uk.gov.hmcts.reform.civil.enums.sdo.DateToShowToggle; @@ -57,6 +59,7 @@ import uk.gov.hmcts.reform.civil.referencedata.LocationRefDataService; import uk.gov.hmcts.reform.civil.service.CategoryService; import uk.gov.hmcts.reform.civil.service.DeadlinesCalculator; +import uk.gov.hmcts.reform.civil.service.FeatureToggleService; import uk.gov.hmcts.reform.civil.service.docmosis.dj.DefaultJudgmentOrderFormGenerator; import uk.gov.hmcts.reform.civil.utils.AssignCategoryId; import uk.gov.hmcts.reform.civil.utils.HearingMethodUtils; @@ -88,6 +91,7 @@ import static uk.gov.hmcts.reform.civil.utils.ElementUtils.element; import static uk.gov.hmcts.reform.civil.utils.HearingUtils.getHearingNotes; +@Slf4j @Service @RequiredArgsConstructor public class StandardDirectionOrderDJ extends CallbackHandler { @@ -99,6 +103,7 @@ public class StandardDirectionOrderDJ extends CallbackHandler { private final ObjectMapper objectMapper; private final DefaultJudgmentOrderFormGenerator defaultJudgmentOrderFormGenerator; private final LocationRefDataService locationRefDataService; + private final FeatureToggleService featureToggleService; String participantString; public static final String DISPOSAL_HEARING = "DISPOSAL_HEARING"; public static final String ORDER_1_CLAI = "The directions order has been sent to: " @@ -628,9 +633,22 @@ private DynamicList getLocationList(CallbackParams callbackParams, ); Optional matchingLocation = Optional.ofNullable(preferredCourt) .flatMap(requestedCourt -> locationHelper.getMatching(locations, preferredCourt)); - return DynamicList.fromList(locations, LocationRefDataService::getDisplayEntry, - matchingLocation.orElse(null), true - ); + + DynamicList locationsList; + if (matchingLocation.isPresent()) { + locationsList = DynamicList.fromList(locations, this::getLocationEpimms, LocationRefDataService::getDisplayEntry, + matchingLocation.get(), true + ); + } else { + locationsList = DynamicList.fromList(locations, this::getLocationEpimms, LocationRefDataService::getDisplayEntry, + null, true + ); + } + return locationsList; + } + + private String getLocationEpimms(LocationRefData location) { + return location.getEpimmsId(); } private CallbackResponse generateSDONotifications(CallbackParams callbackParams) { @@ -643,7 +661,6 @@ private CallbackResponse generateSDONotifications(CallbackParams callbackParams) caseDataBuilder.orderSDODocumentDJ(null); assignCategoryId.assignCategoryIdToCollection(caseData.getOrderSDODocumentDJCollection(), document -> document.getValue().getDocumentLink(), "sdo"); caseDataBuilder.businessProcess(BusinessProcess.ready(STANDARD_DIRECTION_ORDER_DJ)); - var state = "CASE_PROGRESSION"; String authToken = callbackParams.getParams().get(BEARER_TOKEN).toString(); List locations = (locationRefDataService .getCourtLocationsForDefaultJudgments(authToken)); @@ -655,15 +672,35 @@ private CallbackResponse generateSDONotifications(CallbackParams callbackParams) .ifPresent(caseDataBuilder::locationName); } - + var state = "CASE_PROGRESSION"; caseDataBuilder.hearingNotes(getHearingNotes(caseData)); + if (featureToggleService.isEarlyAdoptersEnabled()) { + if (featureToggleService.isLocationWhiteListedForCaseProgression( + getEpimmsId(caseData))) { + log.info("Case {} is whitelisted for case progression.", caseData.getCcdCaseReference()); + caseDataBuilder.eaCourtLocation(YesOrNo.YES); + } else { + log.info("Case {} is NOT whitelisted for case progression.", caseData.getCcdCaseReference()); + caseDataBuilder.eaCourtLocation(YesOrNo.NO); + } + } + return AboutToStartOrSubmitCallbackResponse.builder() .data(caseDataBuilder.build().toMap(objectMapper)) .state(state) .build(); } + private String getEpimmsId(CaseData caseData) { + if (caseData.getTrialHearingMethodInPersonDJ() != null) { + return caseData.getTrialHearingMethodInPersonDJ().getValue().getCode(); + } else if (caseData.getDisposalHearingMethodInPersonDJ() != null) { + return caseData.getDisposalHearingMethodInPersonDJ().getValue().getCode(); + } + throw new IllegalArgumentException("Epimms Id is not provided"); + } + private SubmittedCallbackResponse buildConfirmation(CallbackParams callbackParams) { var caseData = callbackParams.getCaseData(); return SubmittedCallbackResponse.builder() diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseDataParent.java b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseDataParent.java index 4c06a057441..9e490085485 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseDataParent.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseDataParent.java @@ -311,6 +311,8 @@ public class CaseDataParent implements MappableObject { private CaseDocument sdoOrderDocument; + private final YesOrNo eaCourtLocation; + // sdo ui flags private final YesOrNo setSmallClaimsFlag; private final YesOrNo setFastTrackFlag; diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/common/DynamicList.java b/src/main/java/uk/gov/hmcts/reform/civil/model/common/DynamicList.java index 1fe3e01a3f6..075db0e94a5 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/common/DynamicList.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/common/DynamicList.java @@ -16,7 +16,7 @@ */ @Data @Jacksonized -@Builder +@Builder(toBuilder = true) public class DynamicList { /** @@ -39,18 +39,20 @@ public static DynamicList fromList(List list) { } /** - * Sometimes a dynamic list can be prepopulated with a value. + * A dynamic list can be pre-populated with a code and value. * * @param list the original list of items + * @param toCode (optional) how to populate the DynamicListElement code, defaults to random UUID * @param toLabel how to create the label * @param value (optional) value to be selected * @param type of element * @return dynamic list, possibly with value set */ - public static DynamicList fromList(List list, Function toLabel, T value, boolean sort) { + public static DynamicList fromList(List list, Function toCode, Function toLabel, T value, boolean sort) { List items = list.stream() - .map(toLabel) - .map(DynamicListElement::dynamicElement) + .map(item -> toCode != null + ? DynamicListElement.dynamicElementFromCode(toCode.apply(item), toLabel.apply(item)) + : DynamicListElement.dynamicElement(toLabel.apply(item))) .collect(toList()); int index = value != null ? list.indexOf(value) : -1; @@ -68,6 +70,19 @@ public static DynamicList fromList(List list, Function toLabel return DynamicList.builder().listItems(items).value(chosen).build(); } + /** + * Sometimes a dynamic list can be pre-populated with a value. + * + * @param list the original list of items + * @param toLabel how to create the label + * @param value (optional) value to be selected + * @param type of element + * @return dynamic list, possibly with value set + */ + public static DynamicList fromList(List list, Function toLabel, T value, boolean sort) { + return fromList(list, null, toLabel, value, sort); + } + public static DynamicList fromDynamicListElementList(List list) { return DynamicList.builder().listItems(list).value(DynamicListElement.EMPTY).build(); } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateSDOCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateSDOCallbackHandlerTest.java index 208f29cbf58..505d72475f1 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateSDOCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateSDOCallbackHandlerTest.java @@ -1,9 +1,12 @@ package uk.gov.hmcts.reform.civil.handler.callback.user; import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.SneakyThrows; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import org.mockito.ArgumentMatchers; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; @@ -65,9 +68,11 @@ import java.util.stream.Collectors; import static java.lang.String.format; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.when; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_START; @@ -76,6 +81,8 @@ import static uk.gov.hmcts.reform.civil.callback.CallbackType.SUBMITTED; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.CREATE_SDO; import static uk.gov.hmcts.reform.civil.enums.CaseCategory.SPEC_CLAIM; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; import static uk.gov.hmcts.reform.civil.handler.callback.user.CreateSDOCallbackHandler.CONFIRMATION_HEADER; import static uk.gov.hmcts.reform.civil.handler.callback.user.CreateSDOCallbackHandler.CONFIRMATION_SUMMARY_1v1; import static uk.gov.hmcts.reform.civil.handler.callback.user.CreateSDOCallbackHandler.CONFIRMATION_SUMMARY_1v2; @@ -142,6 +149,49 @@ void setup() { .thenReturn(LocalDate.now().plusDays(7)); } + @Test + void shouldPopulateLocationListsWithPreselectedCourt() { + Category category = Category.builder().categoryKey("HearingChannel").key("INTER").valueEn("In Person").activeFlag("Y").build(); + CategorySearchResult categorySearchResult = CategorySearchResult.builder().categories(List.of(category)).build(); + String preSelectedCourt = "214320"; + List locations = List.of( + LocationRefData.builder().epimmsId("00001").courtLocationCode("00001") + .siteName("court 1").courtAddress("1 address").postcode("Y01 7RB").build(), + LocationRefData.builder().epimmsId(preSelectedCourt).courtLocationCode(preSelectedCourt) + .siteName("court 2").courtAddress("2 address").postcode("Y02 7RB").build(), + LocationRefData.builder().epimmsId("00003").courtLocationCode("00003") + .siteName("court 3").courtAddress("3 address").postcode("Y03 7RB").build() + ); + when(locationRefDataService.getCourtLocationsForDefaultJudgments(anyString())).thenReturn(locations); + when(categoryService.findCategoryByCategoryIdAndServiceId(any(), any(), any())).thenReturn(Optional.of(categorySearchResult)); + + CaseData caseData = CaseDataBuilder.builder().atStateClaimDraft() + .atStateClaimIssuedDisposalHearingSDOInPersonHearing().build(); + + CallbackParams params = callbackParamsOf(CallbackVersion.V_1, caseData, ABOUT_TO_START); + CaseDocument order = CaseDocument.builder().documentLink( + Document.builder().documentUrl("url").build()) + .build(); + when(sdoGeneratorService.generate(any(), any())).thenReturn(order); + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + CaseData responseCaseData = objectMapper.convertValue(response.getData(), CaseData.class); + + DynamicList expected = DynamicList.builder() + .listItems(List.of( + DynamicListElement.builder().code("00001").label("court 1 - 1 address - Y01 7RB").build(), + DynamicListElement.builder().code(preSelectedCourt).label("court 2 - 2 address - Y02 7RB").build(), + DynamicListElement.builder().code("00003").label("court 3 - 3 address - Y03 7RB").build() + ) + ) + .value(DynamicListElement.builder().code(preSelectedCourt).label("court 2 - 2 address - Y02 7RB").build()) + .build(); + + assertThat(responseCaseData.getDisposalHearingMethodInPerson()).isEqualTo(expected); + assertThat(responseCaseData.getFastTrackMethodInPerson()).isEqualTo(expected); + assertThat(responseCaseData.getSmallClaimsMethodInPerson()).isEqualTo(expected); + } + @Test void shouldGenerateDynamicListsCorrectly() { Category category = Category.builder().categoryKey("HearingChannel").key("INTER").valueEn("In Person").activeFlag("Y").build(); @@ -194,8 +244,15 @@ class AboutToSubmitCallback { @BeforeEach void setup() { + List items = List.of("label 1", "label 2", "label 3"); + DynamicList options = DynamicList.fromList(items, Object::toString, items.get(0), false); caseData = CaseDataBuilder.builder().atStateClaimDraft() .caseManagementLocation(CaseLocationCivil.builder().baseLocation("00000").build()) + .build().toBuilder() + .disposalHearingMethodInPerson(options) + .fastTrackMethodInPerson(options) + .smallClaimsMethodInPerson(options) + .setFastTrackFlag(YES) .build(); params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); userId = UUID.randomUUID().toString(); @@ -206,11 +263,20 @@ void setup() { given(time.now()).willReturn(submittedDate); given(featureToggleService.isLocationWhiteListedForCaseProgression(anyString())).willReturn(true); + + given(featureToggleService.isEarlyAdoptersEnabled()).willReturn(true); } @Test void shouldUpdateBusinessProcess_whenInvoked() { - var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle( + params.toBuilder() + .caseData(params.getCaseData().toBuilder() + .claimsTrack(ClaimsTrack.smallClaimsTrack) + .drawDirectionsOrderRequired(NO) + .build()) + .build() + ); assertThat(response.getData()) .extracting("businessProcess") @@ -249,6 +315,8 @@ void shouldNotUpdateCaseLocation_whenDisposal() { .caseManagementLocation(CaseLocationCivil.builder().baseLocation("00000").build()) .disposalHearingMethod(DisposalHearingMethod.disposalHearingMethodInPerson) .disposalHearingMethodInPerson(options) + .fastTrackMethodInPerson(options) + .smallClaimsMethodInPerson(options) .disposalHearingMethodToggle(Collections.singletonList(OrderDetailsPagesSectionsToggle.SHOW)) .caseManagementLocation(previousManagementLocation) .build(); @@ -314,6 +382,8 @@ void shouldNotUpdateCaseLocation_whenSmallClaims() { CaseData caseData = CaseDataBuilder.builder().atStateClaimDraft().build().toBuilder() .caseManagementLocation(CaseLocationCivil.builder().baseLocation("00000").build()) .smallClaimsMethod(SmallClaimsMethod.smallClaimsMethodInPerson) + .disposalHearingMethodInPerson(options) + .fastTrackMethodInPerson(options) .smallClaimsMethodInPerson(options) .claimsTrack(ClaimsTrack.smallClaimsTrack) .caseManagementLocation(previousManagementLocation) @@ -372,7 +442,7 @@ void shouldNotUpdateCaseLocation_whenFastTrackAndOrderRequired() { @Test void shouldNotUpdateCaseLocation_whenSmallClaimsAndOrderRequired() { List items = List.of("label 1", "label 2", "label 3"); - DynamicList options = DynamicList.fromList(items, Object::toString, items.get(0), false); + DynamicList options = DynamicList.fromList(items, Object::toString, Object::toString, items.get(0), false); CaseLocationCivil previousManagementLocation = CaseLocationCivil.builder() .region("previous region") .baseLocation("previous base location") @@ -380,6 +450,8 @@ void shouldNotUpdateCaseLocation_whenSmallClaimsAndOrderRequired() { CaseData caseData = CaseDataBuilder.builder().atStateClaimDraft().build().toBuilder() .caseManagementLocation(CaseLocationCivil.builder().baseLocation("00000").build()) .smallClaimsMethod(SmallClaimsMethod.smallClaimsMethodInPerson) + .fastTrackMethodInPerson(options) + .disposalHearingMethodInPerson(options) .smallClaimsMethodInPerson(options) .drawDirectionsOrderRequired(YesOrNo.YES) .drawDirectionsOrderSmallClaims(YesOrNo.YES) @@ -404,8 +476,14 @@ void shouldNotUpdateCaseLocation_whenSmallClaimsAndOrderRequired() { @Test void shouldReturnNullDocument_whenInvokedAboutToSubmit() { + List items = List.of("label 1", "label 2", "label 3"); + DynamicList options = DynamicList.fromList(items, Object::toString, Object::toString, items.get(0), false); CaseData caseData = CaseDataBuilder.builder().atStateClaimDraft().build().toBuilder() .caseManagementLocation(CaseLocationCivil.builder().baseLocation("00000").build()) + .build().toBuilder() + .fastTrackMethodInPerson(options) + .disposalHearingMethodInPerson(options) + .smallClaimsMethodInPerson(options) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); @@ -415,6 +493,212 @@ void shouldReturnNullDocument_whenInvokedAboutToSubmit() { } } + @ParameterizedTest + @CsvSource({"true", "false"}) + void shouldSetEarlyAdoptersFlag_whenDisposal(Boolean isLocationWhiteListed) { + DynamicList options = DynamicList.builder() + .listItems(List.of( + DynamicListElement.builder().code("00001").label("court 1 - 1 address - Y01 7RB").build(), + DynamicListElement.builder().code("00002").label("court 2 - 2 address - Y02 7RB").build(), + DynamicListElement.builder().code("00003").label("court 3 - 3 address - Y03 7RB").build() + ) + ) + .build(); + + DynamicListElement selectedCourt = DynamicListElement.builder() + .code("00002").label("court 2 - 2 address - Y02 7RB").build(); + + CaseData caseData = CaseDataBuilder.builder().atStateClaimDraft().build().toBuilder() + .caseManagementLocation(CaseLocationCivil.builder().baseLocation("00000").build()) + .disposalHearingMethod(DisposalHearingMethod.disposalHearingMethodInPerson) + .disposalHearingMethodInPerson(options.toBuilder().value(selectedCourt).build()) + .fastTrackMethodInPerson(options) + .smallClaimsMethodInPerson(options) + .disposalHearingMethodInPerson(options.toBuilder().value(selectedCourt).build()) + .disposalHearingMethodToggle(Collections.singletonList(OrderDetailsPagesSectionsToggle.SHOW)) + .orderType(OrderType.DISPOSAL) + .build(); + + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + when(featureToggleService.isEarlyAdoptersEnabled()).thenReturn(true); + when(featureToggleService.isLocationWhiteListedForCaseProgression(eq(selectedCourt.getCode()))).thenReturn( + isLocationWhiteListed); + when(locationRefDataService.getLocationMatchingLabel(selectedCourt.getCode(), params.getParams().get( + CallbackParams.Params.BEARER_TOKEN).toString())) + .thenReturn(Optional.of(LocationRefData.builder() + .regionId("region id") + .epimmsId("epimms id") + .siteName("site name") + .build())); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + CaseData responseCaseData = objectMapper.convertValue(response.getData(), CaseData.class); + + assertThat(responseCaseData.getEaCourtLocation()).isEqualTo(isLocationWhiteListed ? YES : NO); + } + + @ParameterizedTest + @CsvSource({"true", "false"}) + void shouldSetEarlyAdoptersFlag_whenSmallClaims(Boolean isLocationWhiteListed) { + DynamicList options = DynamicList.builder() + .listItems(List.of( + DynamicListElement.builder().code("00001").label("court 1 - 1 address - Y01 7RB").build(), + DynamicListElement.builder().code("00002").label("court 2 - 2 address - Y02 7RB").build(), + DynamicListElement.builder().code("00003").label("court 3 - 3 address - Y03 7RB").build() + ) + ) + .build(); + + DynamicListElement selectedCourt = DynamicListElement.builder() + .code("00002").label("court 2 - 2 address - Y02 7RB").build(); + + CaseData caseData = CaseDataBuilder.builder().atStateClaimDraft().build().toBuilder() + .caseManagementLocation(CaseLocationCivil.builder().baseLocation("00000").build()) + .smallClaimsMethod(SmallClaimsMethod.smallClaimsMethodInPerson) + .disposalHearingMethodInPerson(options) + .fastTrackMethodInPerson(options) + .smallClaimsMethodInPerson(options.toBuilder().value(selectedCourt).build()) + .claimsTrack(ClaimsTrack.smallClaimsTrack) + .setSmallClaimsFlag(YES) + .drawDirectionsOrderRequired(NO) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + when(featureToggleService.isEarlyAdoptersEnabled()).thenReturn(true); + when(featureToggleService.isLocationWhiteListedForCaseProgression(eq(selectedCourt.getCode()))).thenReturn( + isLocationWhiteListed); + when(locationRefDataService.getLocationMatchingLabel("label 1", params.getParams().get( + CallbackParams.Params.BEARER_TOKEN).toString())).thenReturn( + Optional.of(LocationRefData.builder() + .regionId("region id") + .epimmsId("epimms id") + .siteName("location name") + .build())); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + CaseData responseCaseData = objectMapper.convertValue(response.getData(), CaseData.class); + + assertThat(responseCaseData.getEaCourtLocation()).isEqualTo(isLocationWhiteListed ? YES : NO); + } + + @ParameterizedTest + @CsvSource({"true", "false"}) + void shouldSetEarlyAdoptersFlag_whenFastTrack(Boolean isLocationWhiteListed) { + DynamicList options = DynamicList.builder() + .listItems(List.of( + DynamicListElement.builder().code("00001").label("court 1 - 1 address - Y01 7RB").build(), + DynamicListElement.builder().code("00002").label("court 2 - 2 address - Y02 7RB").build(), + DynamicListElement.builder().code("00003").label("court 3 - 3 address - Y03 7RB").build() + ) + ) + .build(); + + DynamicListElement selectedCourt = DynamicListElement.builder() + .code("00002").label("court 2 - 2 address - Y02 7RB").build(); + + CaseData caseData = CaseDataBuilder.builder().atStateClaimDraft().build().toBuilder() + .caseManagementLocation(CaseLocationCivil.builder().baseLocation("00000").build()) + .fastTrackMethod(FastTrackMethod.fastTrackMethodInPerson) + .smallClaimsMethodInPerson(options) + .fastTrackMethodInPerson(options.toBuilder().value(selectedCourt).build()) + .disposalHearingMethodInPerson(options) + .claimsTrack(ClaimsTrack.fastTrack) + .setFastTrackFlag(YES) + .drawDirectionsOrderRequired(NO) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + when(featureToggleService.isEarlyAdoptersEnabled()).thenReturn(true); + when(featureToggleService.isLocationWhiteListedForCaseProgression(eq(selectedCourt.getCode()))).thenReturn( + isLocationWhiteListed); + when(locationRefDataService.getLocationMatchingLabel("label 1", params.getParams().get( + CallbackParams.Params.BEARER_TOKEN).toString())).thenReturn( + Optional.of(LocationRefData.builder() + .regionId("region id") + .epimmsId("epimms id") + .siteName("location name") + .build())); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + CaseData responseCaseData = objectMapper.convertValue(response.getData(), CaseData.class); + + assertThat(responseCaseData.getEaCourtLocation()).isEqualTo(isLocationWhiteListed ? YES : NO); + } + + @Test + @SneakyThrows + void shouldThrowIllegalArgumentException_whenClaimTrackCannotDefined() { + DynamicList options = DynamicList.builder() + .listItems(List.of( + DynamicListElement.builder().code("00001").label("court 1 - 1 address - Y01 7RB").build(), + DynamicListElement.builder().code("00002").label("court 2 - 2 address - Y02 7RB").build(), + DynamicListElement.builder().code("00003").label("court 3 - 3 address - Y03 7RB").build() + ) + ) + .build(); + + CaseData caseData = CaseDataBuilder.builder().atStateClaimDraft().build().toBuilder() + .caseManagementLocation(CaseLocationCivil.builder().baseLocation("00000").build()) + .fastTrackMethod(FastTrackMethod.fastTrackMethodInPerson) + .smallClaimsMethodInPerson(options) + .fastTrackMethodInPerson(options) + .disposalHearingMethodInPerson(options) + .claimsTrack(ClaimsTrack.fastTrack) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + when(featureToggleService.isEarlyAdoptersEnabled()).thenReturn(true); + when(locationRefDataService.getLocationMatchingLabel("label 1", params.getParams().get( + CallbackParams.Params.BEARER_TOKEN).toString())).thenReturn( + Optional.of(LocationRefData.builder() + .regionId("region id") + .epimmsId("epimms id") + .siteName("location name") + .build())); + + assertThrows(IllegalArgumentException.class, () -> handler.handle(params), + "Epimms Id is not provided" + ); + } + + @ParameterizedTest + @CsvSource({"true", "false"}) + void shouldNotSetEarlyAdoptersFlag_whenEarlyAdoptersToggleIsOff(Boolean isLocationWhiteListed) { + DynamicList options = DynamicList.builder() + .listItems(List.of( + DynamicListElement.builder().code("00001").label("court 1 - 1 address - Y01 7RB").build(), + DynamicListElement.builder().code("00002").label("court 2 - 2 address - Y02 7RB").build(), + DynamicListElement.builder().code("00003").label("court 3 - 3 address - Y03 7RB").build() + ) + ) + .build(); + + DynamicListElement selectedCourt = DynamicListElement.builder() + .code("00002").label("court 2 - 2 address - Y02 7RB").build(); + + CaseData caseData = CaseDataBuilder.builder().atStateClaimDraft().build().toBuilder() + .caseManagementLocation(CaseLocationCivil.builder().baseLocation("00000").build()) + .fastTrackMethod(FastTrackMethod.fastTrackMethodInPerson) + .fastTrackMethodInPerson(options.toBuilder().value(selectedCourt).build()) + .smallClaimsMethodInPerson(options) + .disposalHearingMethodInPerson(options) + .claimsTrack(ClaimsTrack.fastTrack) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + when(featureToggleService.isEarlyAdoptersEnabled()).thenReturn(false); + when(featureToggleService.isLocationWhiteListedForCaseProgression(eq(selectedCourt.getCode()))).thenReturn( + isLocationWhiteListed); + when(locationRefDataService.getLocationMatchingLabel("label 1", params.getParams().get( + CallbackParams.Params.BEARER_TOKEN).toString())).thenReturn( + Optional.of(LocationRefData.builder() + .regionId("region id") + .epimmsId("epimms id") + .siteName("location name") + .build())); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + CaseData responseCaseData = objectMapper.convertValue(response.getData(), CaseData.class); + + assertThat(responseCaseData.getEaCourtLocation()).isNull(); + } + @Nested class MidEventDisposalHearingLocationRefDataCallback extends LocationRefSampleDataBuilder { diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/StandardDirectionOrderDJTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/StandardDirectionOrderDJTest.java index 4f94e09294f..3fea6f64824 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/StandardDirectionOrderDJTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/StandardDirectionOrderDJTest.java @@ -5,6 +5,8 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; @@ -49,6 +51,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.when; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_START; @@ -57,6 +61,7 @@ import static uk.gov.hmcts.reform.civil.callback.CallbackType.SUBMITTED; import static uk.gov.hmcts.reform.civil.documentmanagement.model.DocumentType.ACKNOWLEDGEMENT_OF_CLAIM; import static uk.gov.hmcts.reform.civil.enums.CaseCategory.UNSPEC_CLAIM; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; import static uk.gov.hmcts.reform.civil.utils.ElementUtils.element; @@ -544,6 +549,44 @@ void shouldPrePopulateDJTrialHearingToggle() { var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); assertThat(response.getData()).extracting("trialHearingVariationsDirectionsDJToggle").isNotNull(); + assertThat(response.getData()).extracting("trialHearingVariationsDirectionsDJToggle").isNotNull(); + } + + @Test + void shouldPopulateLocationListsWithPreselectedCourt() { + CaseData caseData = CaseDataBuilder.builder() + .atStateClaimDraft() + .atStateClaimIssuedTrialHearing() + .build(); + + String preSelectedCourt = "214320"; + + CallbackParams params = callbackParamsOf(caseData, MID, PAGE_ID); + List locations = List.of( + LocationRefData.builder().epimmsId("00001").courtLocationCode("00001") + .siteName("court 1").courtAddress("1 address").postcode("Y01 7RB").build(), + LocationRefData.builder().epimmsId(preSelectedCourt).courtLocationCode(preSelectedCourt) + .siteName("court 2").courtAddress("2 address").postcode("Y02 7RB").build(), + LocationRefData.builder().epimmsId("00003").courtLocationCode("00003") + .siteName("court 3").courtAddress("3 address").postcode("Y03 7RB").build() + ); + + when(locationRefDataService.getCourtLocationsForDefaultJudgments(anyString())).thenReturn(locations); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + CaseData responseCaseData = mapper.convertValue(response.getData(), CaseData.class); + DynamicList expected = DynamicList.builder() + .listItems(List.of( + DynamicListElement.builder().code("00001").label("court 1 - 1 address - Y01 7RB").build(), + DynamicListElement.builder().code(preSelectedCourt).label("court 2 - 2 address - Y02 7RB").build(), + DynamicListElement.builder().code("00003").label("court 3 - 3 address - Y03 7RB").build() + ) + ) + .value(DynamicListElement.builder().code(preSelectedCourt).label("court 2 - 2 address - Y02 7RB").build()) + .build(); + + assertThat(responseCaseData.getTrialHearingMethodInPersonDJ()).isEqualTo(expected); + assertThat(responseCaseData.getDisposalHearingMethodInPersonDJ()).isEqualTo(expected); } @Test @@ -693,9 +736,21 @@ void shouldCreateAndSaveSDOOrder_whenStateClaimIssuedDisposalSDOVideoCall() { @Nested class AboutToSubmitCallback { + + @BeforeEach + void setup() { + given(featureToggleService.isEarlyAdoptersEnabled()).willReturn(true); + } + @Test void shouldFinishBusinessProcess() { - CaseData caseData = CaseDataBuilder.builder().atStateClaimDraft().build(); + List items = List.of("label 1", "label 2", "label 3"); + DynamicList options = DynamicList.fromList(items, Object::toString, Object::toString, items.get(0), false); + CaseData caseData = CaseDataBuilder.builder().atStateClaimDraft().build() + .toBuilder() + .disposalHearingMethodInPersonDJ(options) + .trialHearingMethodInPersonDJ(options) + .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); assertThat(response.getData()).extracting("businessProcess").isNotNull(); @@ -717,9 +772,13 @@ void shouldAssignCategoryId_whenInvoked() { .build(); List> documentList = new ArrayList<>(); documentList.add(element(testDocument)); + List items = List.of("label 1", "label 2", "label 3"); + DynamicList options = DynamicList.fromList(items, Object::toString, items.get(0), false); //Given when(featureToggleService.isCaseFileViewEnabled()).thenReturn(true); CaseData caseData = CaseDataBuilder.builder().atStateClaimDraft().build().toBuilder() + .trialHearingMethodInPersonDJ(options) + .disposalHearingMethodInPersonDJ(options) .orderSDODocumentDJCollection(documentList) .build(); @@ -730,6 +789,88 @@ void shouldAssignCategoryId_whenInvoked() { //Then assertThat(updatedData.getOrderSDODocumentDJCollection().get(0).getValue().getDocumentLink().getCategoryID()).isEqualTo("sdo"); } + + @ParameterizedTest + @CsvSource({"true", "false"}) + void shouldPopulateEarlyAdoptersFlag_whenDisposalHearingMethodInPersonDJIsSet(Boolean isLocationWhiteListed) { + DynamicList options = DynamicList.builder() + .listItems(List.of( + DynamicListElement.builder().code("00001").label("court 1 - 1 address - Y01 7RB").build(), + DynamicListElement.builder().code("00002").label("court 2 - 2 address - Y02 7RB").build(), + DynamicListElement.builder().code("00003").label("court 3 - 3 address - Y03 7RB").build() + ) + ) + .value(DynamicListElement.builder().code("00002").label("court 2 - 2 address - Y02 7RB").build()) + .build(); + + CaseData caseData = CaseDataBuilder.builder().atStateClaimDraft().build() + .toBuilder() + .disposalHearingMethodInPersonDJ(options) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + when(featureToggleService.isLocationWhiteListedForCaseProgression(eq(options.getValue().getCode()))).thenReturn( + isLocationWhiteListed); + + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + CaseData responseCaseData = mapper.convertValue(response.getData(), CaseData.class); + + assertThat(responseCaseData.getEaCourtLocation()).isEqualTo(isLocationWhiteListed ? YES : NO); + } + + @Test + void shouldNotPopulateEarlyAdoptersFlag_whenEarlyAdoptersToggleIsOff() { + DynamicList options = DynamicList.builder() + .listItems(List.of( + DynamicListElement.builder().code("00001").label("court 1 - 1 address - Y01 7RB").build(), + DynamicListElement.builder().code("00002").label("court 2 - 2 address - Y02 7RB").build(), + DynamicListElement.builder().code("00003").label("court 3 - 3 address - Y03 7RB").build() + ) + ) + .value(DynamicListElement.builder().code("00002").label("court 2 - 2 address - Y02 7RB").build()) + .build(); + + CaseData caseData = CaseDataBuilder.builder().atStateClaimDraft().build() + .toBuilder() + .disposalHearingMethodInPersonDJ(options) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + when(featureToggleService.isEarlyAdoptersEnabled()).thenReturn(false); + when(featureToggleService.isLocationWhiteListedForCaseProgression(eq(options.getValue().getCode()))) + .thenReturn(true); + + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + CaseData responseCaseData = mapper.convertValue(response.getData(), CaseData.class); + + assertThat(responseCaseData.getEaCourtLocation()).isNull(); + } + } + + @ParameterizedTest + @CsvSource({"true", "false"}) + void shouldPopulateEarlyAdoptersFlag_whenTrialHearingMethodInPersonDJIsSet(Boolean isLocationWhiteListed) { + DynamicList options = DynamicList.builder() + .listItems(List.of( + DynamicListElement.builder().code("00001").label("court 1 - 1 address - Y01 7RB").build(), + DynamicListElement.builder().code("00002").label("court 2 - 2 address - Y02 7RB").build(), + DynamicListElement.builder().code("00003").label("court 3 - 3 address - Y03 7RB").build() + ) + ) + .value(DynamicListElement.builder().code("00002").label("court 2 - 2 address - Y02 7RB").build()) + .build(); + + CaseData caseData = CaseDataBuilder.builder().atStateClaimDraft().build() + .toBuilder() + .trialHearingMethodInPersonDJ(options) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + when(featureToggleService.isEarlyAdoptersEnabled()).thenReturn(true); + when(featureToggleService.isLocationWhiteListedForCaseProgression(eq(options.getValue().getCode()))).thenReturn( + isLocationWhiteListed); + + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + CaseData responseCaseData = mapper.convertValue(response.getData(), CaseData.class); + + assertThat(responseCaseData.getEaCourtLocation()).isEqualTo(isLocationWhiteListed ? YES : NO); } @Nested diff --git a/src/test/java/uk/gov/hmcts/reform/civil/model/common/DynamicListTest.java b/src/test/java/uk/gov/hmcts/reform/civil/model/common/DynamicListTest.java new file mode 100644 index 00000000000..1aef0b2539b --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/model/common/DynamicListTest.java @@ -0,0 +1,57 @@ +package uk.gov.hmcts.reform.civil.model.common; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class DynamicListTest { + + private List listItems; + + @BeforeEach + public void setUp() { + listItems = Arrays.asList("Item1", "Item2", "Item3"); + } + + @Test + public void shouldPopulateDynamicListFromList_whenCodeFunctionIsProvided() { + Function toCode = item -> item + "_code"; + Function toLabel = item -> item + "_label"; + String value = "Item2"; + + DynamicList actual = DynamicList.fromList(listItems, toCode, toLabel, value, true); + + DynamicList expected = DynamicList.builder() + .listItems(List.of( + DynamicListElement.builder().code("Item1_code").label("Item1_label").build(), + DynamicListElement.builder().code("Item2_code").label("Item2_label").build(), + DynamicListElement.builder().code("Item3_code").label("Item3_label").build() + )) + .value(DynamicListElement.builder().code("Item2_code").label("Item2_label").build()) + .build(); + + assertEquals(expected, actual); + } + + @Test + public void shouldPopulateDynamicListFromList_whenCodeFunctionIsNotProvided() { + Function toLabel = item -> item + "_label"; + String value = "Item2"; + + DynamicList actual = DynamicList.fromList(listItems, null, toLabel, value, true); + + assertNotNull(actual.getListItems().get(0).getCode()); + assertEquals("Item1_label", actual.getListItems().get(0).getLabel()); + assertNotNull(actual.getListItems().get(1).getCode()); + assertEquals("Item2_label", actual.getListItems().get(1).getLabel()); + assertNotNull(actual.getListItems().get(2).getCode()); + assertEquals("Item3_label", actual.getListItems().get(2).getLabel()); + assertNotNull(actual.getValue().getCode()); + assertEquals("Item2_label", actual.getValue().getLabel()); + } +} From 3e31b4940a7871b5d55823a80ab855d6e2cdd117 Mon Sep 17 00:00:00 2001 From: m-meulendijks-v1 <107135537+m-meulendijks-v1@users.noreply.github.com> Date: Tue, 7 Nov 2023 09:18:42 +0000 Subject: [PATCH 07/28] CIV-11414 - Updated trial ready WA search services (#3528) * CIV-11414 - Updated trial ready WA search services * CIV-11414 - updated tests --------- Co-authored-by: vasudevganesanhmcts <100689363+vasudevganesanhmcts@users.noreply.github.com> --- .../service/search/TrialReadyCheckSearchService.java | 6 +++++- .../search/TrialReadyNotificationSearchService.java | 8 ++++++-- .../service/search/TrialReadyCheckSearchServiceTest.java | 5 ++++- .../search/TrialReadyNotificationSearchServiceTest.java | 7 +++++-- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/search/TrialReadyCheckSearchService.java b/src/main/java/uk/gov/hmcts/reform/civil/service/search/TrialReadyCheckSearchService.java index d23f38cf85b..b418a6a16fd 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/search/TrialReadyCheckSearchService.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/search/TrialReadyCheckSearchService.java @@ -13,6 +13,7 @@ import static org.elasticsearch.index.query.QueryBuilders.boolQuery; import static org.elasticsearch.index.query.QueryBuilders.matchQuery; import static org.elasticsearch.index.query.QueryBuilders.rangeQuery; +import static uk.gov.hmcts.reform.civil.enums.CaseState.HEARING_READINESS; import static uk.gov.hmcts.reform.civil.enums.CaseState.PREPARE_FOR_HEARING_CONDUCT_HEARING; @Service @@ -30,7 +31,10 @@ public Query query(int startIndex) { .must(rangeQuery("data.hearingDate").lt(LocalDate.now() .atTime(LocalTime.MIN).plusWeeks(3) .toString())) - .must(beState(PREPARE_FOR_HEARING_CONDUCT_HEARING)) + .must(boolQuery() + .minimumShouldMatch(1) + .should(beState(PREPARE_FOR_HEARING_CONDUCT_HEARING)) + .should(beState(HEARING_READINESS))) .mustNot(matchQuery("data.allocatedTrack", "SMALL_CLAIM")) .mustNot(matchQuery("data.trialReadyChecked", "Yes"))), List.of("reference"), diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/search/TrialReadyNotificationSearchService.java b/src/main/java/uk/gov/hmcts/reform/civil/service/search/TrialReadyNotificationSearchService.java index 878b2f73638..53a26cd55e1 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/search/TrialReadyNotificationSearchService.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/search/TrialReadyNotificationSearchService.java @@ -15,6 +15,7 @@ import static org.elasticsearch.index.query.QueryBuilders.boolQuery; import static org.elasticsearch.index.query.QueryBuilders.matchQuery; import static org.elasticsearch.index.query.QueryBuilders.rangeQuery; +import static uk.gov.hmcts.reform.civil.enums.CaseState.HEARING_READINESS; import static uk.gov.hmcts.reform.civil.enums.CaseState.PREPARE_FOR_HEARING_CONDUCT_HEARING; @Service @@ -32,10 +33,13 @@ public Query query(int startIndex) { .must(rangeQuery("data.hearingDate").lt(LocalDate.now() .atTime(LocalTime.MIN) .plusWeeks(6).toString())) - .must(beState(PREPARE_FOR_HEARING_CONDUCT_HEARING))) + .must(boolQuery() + .minimumShouldMatch(1) + .should(beState(PREPARE_FOR_HEARING_CONDUCT_HEARING)) + .should(beState(HEARING_READINESS))) .mustNot(matchQuery("data.allocatedTrack", "SMALL_CLAIM")) .mustNot(matchQuery("data.listingOrRelisting", ListingOrRelisting.RELISTING)) - .mustNot(matchQuery("data.trialReadyNotified", YesOrNo.YES)), + .mustNot(matchQuery("data.trialReadyNotified", YesOrNo.YES))), List.of("reference"), startIndex ); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/search/TrialReadyCheckSearchServiceTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/search/TrialReadyCheckSearchServiceTest.java index 0aefcb6a5c2..24a6e6b3716 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/search/TrialReadyCheckSearchServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/search/TrialReadyCheckSearchServiceTest.java @@ -26,7 +26,10 @@ protected Query buildQuery(int fromValue) { .should(boolQuery() .must(rangeQuery("data.hearingDate").lt(LocalDate.now().atTime(LocalTime.MIN).plusWeeks(3) .toString())) - .must(boolQuery().must(matchQuery("state", "PREPARE_FOR_HEARING_CONDUCT_HEARING"))) + .must(boolQuery() + .minimumShouldMatch(1) + .should(boolQuery().must(matchQuery("state", "PREPARE_FOR_HEARING_CONDUCT_HEARING"))) + .should(boolQuery().must(matchQuery("state", "HEARING_READINESS")))) .mustNot(matchQuery("data.allocatedTrack", "SMALL_CLAIM")) .mustNot(matchQuery("data.trialReadyChecked", "Yes"))); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/search/TrialReadyNotificationSearchServiceTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/search/TrialReadyNotificationSearchServiceTest.java index 961b2c67253..f94d49c3430 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/search/TrialReadyNotificationSearchServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/search/TrialReadyNotificationSearchServiceTest.java @@ -28,10 +28,13 @@ protected Query buildQuery(int fromValue) { .should(boolQuery() .must(rangeQuery("data.hearingDate").lt(LocalDate.now().atTime(LocalTime.MIN).plusWeeks(6) .toString())) - .must(boolQuery().must(matchQuery("state", "PREPARE_FOR_HEARING_CONDUCT_HEARING")))) + .must(boolQuery() + .minimumShouldMatch(1) + .should(boolQuery().must(matchQuery("state", "PREPARE_FOR_HEARING_CONDUCT_HEARING"))) + .should(boolQuery().must(matchQuery("state", "HEARING_READINESS")))) .mustNot(matchQuery("data.allocatedTrack", "SMALL_CLAIM")) .mustNot(matchQuery("data.listingOrRelisting", ListingOrRelisting.RELISTING)) - .mustNot(matchQuery("data.trialReadyNotified", YesOrNo.YES)); + .mustNot(matchQuery("data.trialReadyNotified", YesOrNo.YES))); return new Query(query, List.of("reference"), fromValue); } From 1a2b55e0b4083e4537d9be8b8233092c4371ac7b Mon Sep 17 00:00:00 2001 From: m-meulendijks-v1 <107135537+m-meulendijks-v1@users.noreply.github.com> Date: Tue, 7 Nov 2023 10:22:51 +0000 Subject: [PATCH 08/28] CIV-11226 - Clear evidence upload judge with documents (#3496) * CIV-10946 - fixed times for document & document+note casenotes * CIV-11226 - Clear evidence upload judge documents for event * CIV-11226 - point to ccd PR * CIV-11226 remove pointer to ccd definition * Update Jenkinsfile_CNP * CIV-11226 - remove temp documents at start of method --------- Co-authored-by: vasudevganesanhmcts <100689363+vasudevganesanhmcts@users.noreply.github.com> --- .../user/EvidenceUploadJudgeHandler.java | 49 ++++++++- .../hmcts/reform/civil/model/CaseData.java | 2 + .../model/documents/DocumentAndNote.java | 3 +- .../model/documents/DocumentWithName.java | 3 +- .../user/EvidenceUploadJudgeHandlerTest.java | 101 +++++++++++++++++- 5 files changed, 148 insertions(+), 10 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadJudgeHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadJudgeHandler.java index d41aacdabc6..12ca69bdb86 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadJudgeHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadJudgeHandler.java @@ -14,6 +14,8 @@ import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.model.CaseNote; import uk.gov.hmcts.reform.civil.model.common.Element; +import uk.gov.hmcts.reform.civil.model.documents.DocumentAndNote; +import uk.gov.hmcts.reform.civil.model.documents.DocumentWithName; import uk.gov.hmcts.reform.civil.service.CaseNoteService; import java.util.Collections; @@ -59,7 +61,11 @@ private AboutToStartOrSubmitCallbackResponse removeCaseNoteType(CallbackParams c var caseData = callbackParams.getCaseData(); CaseData.CaseDataBuilder caseDataBuilder = caseData.toBuilder(); - caseDataBuilder.caseNoteType(null).build(); + caseDataBuilder + .caseNoteType(null) + .documentAndNameToAdd(null) + .documentAndNoteToAdd(null) + .build(); return AboutToStartOrSubmitCallbackResponse.builder() .data(caseDataBuilder.build().toMap(objectMapper)) @@ -84,6 +90,39 @@ private AboutToStartOrSubmitCallbackResponse populateSubmittedDateTime(CallbackP .build(); } + if (caseData.getCaseNoteType().equals(CaseNoteType.DOCUMENT_ONLY)) { + List> documentAndNameToAdd = caseData.getDocumentAndNameToAdd(); + List> documentAndNameCurrent = caseData.getDocumentAndName(); + + if (documentAndNameCurrent == null) { + documentAndNameCurrent = documentAndNameToAdd; + } else { + for (Element document : documentAndNameToAdd) { + documentAndNameCurrent.add(document); + } + } + caseDataBuilder + .documentAndName(documentAndNameCurrent) + .build(); + } + + if (caseData.getCaseNoteType().equals(CaseNoteType.DOCUMENT_AND_NOTE)) { + List> documentAndNoteToAdd = caseData.getDocumentAndNoteToAdd(); + List> documentAndNoteCurrent = caseData.getDocumentAndNote(); + + if (documentAndNoteCurrent == null) { + documentAndNoteCurrent = documentAndNoteToAdd; + } else { + for (Element document : documentAndNoteToAdd) { + documentAndNoteCurrent.add(document); + } + } + caseDataBuilder + .documentAndNote(documentAndNoteCurrent) + .build(); + + } + return AboutToStartOrSubmitCallbackResponse.builder() .data(caseDataBuilder.build().toMap(objectMapper)) .build(); @@ -115,16 +154,16 @@ private String getHeader(CaseData caseData) { private String getBody(CaseData caseData) { StringBuilder stringBuilder = new StringBuilder(); if (null != caseData.getCaseNoteType() && caseData.getCaseNoteType().equals(CaseNoteType.DOCUMENT_ONLY)) { - IntStream.range(0, caseData.getDocumentAndName() + IntStream.range(0, caseData.getDocumentAndNameToAdd() .size()).forEachOrdered(i -> stringBuilder.append("* ").append( - caseData.getDocumentAndName().get(i).getValue().getDocument().getDocumentFileName()).append("\n")); + caseData.getDocumentAndNameToAdd().get(i).getValue().getDocument().getDocumentFileName()).append("\n")); return format(EVIDENCE_UPLOAD_BODY_ONE, stringBuilder); } if (caseData.getCaseNoteType().equals(CaseNoteType.DOCUMENT_AND_NOTE)) { - IntStream.range(0, caseData.getDocumentAndNote() + IntStream.range(0, caseData.getDocumentAndNoteToAdd() .size()).forEachOrdered(i -> stringBuilder.append("* ").append( - caseData.getDocumentAndNote().get(i) + caseData.getDocumentAndNoteToAdd().get(i) .getValue() .getDocument() .getDocumentFileName()).append("\n")); diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java index c8b8a40bc85..7a65369a8b0 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java @@ -572,7 +572,9 @@ public boolean hasNoOngoingBusinessProcess() { //case progression private final List> documentAndName; + private final List> documentAndNameToAdd; private final List> documentAndNote; + private final List> documentAndNoteToAdd; private final CaseNoteType caseNoteType; private final String caseNoteTA; private final List> caseNotesTA; diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/documents/DocumentAndNote.java b/src/main/java/uk/gov/hmcts/reform/civil/model/documents/DocumentAndNote.java index 33cb4c343cf..fee4c6e850a 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/documents/DocumentAndNote.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/documents/DocumentAndNote.java @@ -7,6 +7,7 @@ import uk.gov.hmcts.reform.civil.documentmanagement.model.Document; import java.time.LocalDateTime; +import java.time.ZoneId; @Data @Builder(toBuilder = true) @@ -18,6 +19,6 @@ public class DocumentAndNote { private Document document; private String documentNote; @Builder.Default - private LocalDateTime createdDateTime = LocalDateTime.now(); + private LocalDateTime createdDateTime = LocalDateTime.now(ZoneId.of("Europe/London")); } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/documents/DocumentWithName.java b/src/main/java/uk/gov/hmcts/reform/civil/model/documents/DocumentWithName.java index 3538f61d331..9aabf622994 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/documents/DocumentWithName.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/documents/DocumentWithName.java @@ -7,6 +7,7 @@ import uk.gov.hmcts.reform.civil.documentmanagement.model.Document; import java.time.LocalDateTime; +import java.time.ZoneId; @Data @Builder(toBuilder = true) @@ -17,5 +18,5 @@ public class DocumentWithName { private Document document; private String documentName; @Builder.Default - private LocalDateTime createdDateTime = LocalDateTime.now(); + private LocalDateTime createdDateTime = LocalDateTime.now(ZoneId.of("Europe/London")); } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadJudgeHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadJudgeHandlerTest.java index ddc7d79823c..d37c56db259 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadJudgeHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadJudgeHandlerTest.java @@ -97,20 +97,115 @@ void shouldPopulateNoteDateTime_whenNoteIsAddedToCase() { assertThat(response.getData()).extracting("caseNotesTA") .isEqualTo(objectMapper.convertValue(updatedCaseNotes, new TypeReference<>() {})); + assertThat(response.getData()).extracting("documentAndName").isNull(); + assertThat(response.getData()).extracting("documentAndNote").isNull(); + } + + @Test + void shouldCopyDocumentAndNameToAdd_whenDocumentWithNameIsNull() { + Document document = Document.builder().documentFileName("fileName").build(); + DocumentWithName testDocument = DocumentWithName.builder() + .documentName("testDocument") + .document(document) + .build(); + List> documentWithNameToAdd = wrapElements(testDocument); + + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() + .caseNoteType(CaseNoteType.DOCUMENT_ONLY) + .documentAndNameToAdd(documentWithNameToAdd) + .caseNoteTA(null) + .build(); + + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + assertThat(response.getData()).extracting("documentAndName") + .isEqualTo(objectMapper.convertValue(documentWithNameToAdd, new TypeReference<>() {})); + assertThat(response.getData()).extracting("caseNotesTA").isNull(); + assertThat(response.getData()).extracting("documentAndNote").isNull(); } @Test - void shouldNotPopulateNoteDateTime_whenNoteIsAddedToCase() { + void shouldAddDocument_whenDocumentWithNameIsNotNull() { + Document document = Document.builder().documentFileName("fileName").build(); + DocumentWithName testDocument = DocumentWithName.builder() + .documentName("testDocument") + .document(document) + .build(); + List> documentWithNameToAdd = wrapElements(testDocument); + List> documentWithNameStart = wrapElements(testDocument); + List> documentWithNameEnd = wrapElements(testDocument, testDocument); + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .caseNoteType(CaseNoteType.DOCUMENT_ONLY) + .documentAndNameToAdd(documentWithNameToAdd) + .documentAndName(documentWithNameStart) .caseNoteTA(null) .build(); + + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + assertThat(response.getData()).extracting("documentAndName") + .isEqualTo(objectMapper.convertValue(documentWithNameEnd, new TypeReference<>() {})); + assertThat(response.getData()).extracting("caseNotesTA").isNull(); + assertThat(response.getData()).extracting("documentAndNote").isNull(); + + } + + @Test + void shouldAddNote_whenDocumentWithNoteIsNotNull() { + Document document = Document.builder().documentFileName("fileName").build(); + DocumentAndNote testDocument = DocumentAndNote.builder() + .documentName("testDocument") + .document(document) + .documentNote("Note") + .build(); + List> documentAndNoteToAdd = wrapElements(testDocument); + List> documentAndNoteStart = wrapElements(testDocument); + List> documentAndNoteEnd = wrapElements(testDocument, testDocument); + + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() + .caseNoteType(CaseNoteType.DOCUMENT_AND_NOTE) + .documentAndNoteToAdd(documentAndNoteToAdd) + .documentAndNote(documentAndNoteStart) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + assertThat(response.getData()).extracting("documentAndNote") + .isEqualTo(objectMapper.convertValue(documentAndNoteEnd, new TypeReference<>() {})); + assertThat(response.getData()).extracting("caseNotesTA").isNull(); + assertThat(response.getData()).extracting("documentAndName").isNull(); + + } + + @Test + void shouldCopyDocumentAndNoteToAdd_whenDocumentWithNoteIsNull() { + Document document = Document.builder().documentFileName("fileName").build(); + DocumentAndNote testDocument = DocumentAndNote.builder() + .documentName("testDocument") + .document(document) + .documentNote("Note") + .build(); + List> documentAndNoteToAdd = wrapElements(testDocument); + + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() + .caseNoteType(CaseNoteType.DOCUMENT_AND_NOTE) + .documentAndNoteToAdd(documentAndNoteToAdd) + .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + assertThat(response.getData()).extracting("documentAndNote") + .isEqualTo(objectMapper.convertValue(documentAndNoteToAdd, new TypeReference<>() {})); assertThat(response.getData()).extracting("caseNotesTA").isNull(); + assertThat(response.getData()).extracting("documentAndName").isNull(); } } @@ -133,7 +228,7 @@ void shouldPopulateConfirmation_DocumentAndNote() { documentList.add(Element.builder().value(documentAndNote).build()); CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() - .documentAndNote(documentList) + .documentAndNoteToAdd(documentList) .caseNoteType(CaseNoteType.DOCUMENT_AND_NOTE) .build(); CallbackParams params = callbackParamsOf(caseData, CallbackType.SUBMITTED); @@ -162,7 +257,7 @@ void submittedCallback_documentOnly() { documentList.add(Element.builder().value(documentAndNote).build()); CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() - .documentAndName(documentList) + .documentAndNameToAdd(documentList) .caseNoteType(CaseNoteType.DOCUMENT_ONLY) .build(); CallbackParams params = callbackParamsOf(caseData, CallbackType.SUBMITTED); From 65b1ee89113d513e539ee6380151a10e8c222b1e Mon Sep 17 00:00:00 2001 From: drummondjm <93932689+drummondjm@users.noreply.github.com> Date: Tue, 7 Nov 2023 12:42:51 +0000 Subject: [PATCH 09/28] CIV-11361 add hearing notes (#3527) * add hearing notes for free form, and populate listing notes tab with notes * Update Jenkinsfile_CNP --- ...GenerateDirectionOrderCallbackHandler.java | 25 +++++++++---- .../hmcts/reform/civil/model/CaseData.java | 1 + ...rateDirectionOrderCallbackHandlerTest.java | 37 ++++++++++++++++++- 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandler.java index 877a60ee0f6..b1756291e23 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandler.java @@ -128,7 +128,8 @@ private CallbackResponse nullPreviousSelections(CallbackParams callbackParams) { caseDataBuilder .freeFormRecordedTextArea(null) .freeFormOrderedTextArea(null) - .orderOnCourtsList(null); + .orderOnCourtsList(null) + .freeFormHearingNotes(null); // Assisted orders caseDataBuilder .finalOrderMadeSelection(null).finalOrderDateHeardComplex(null) @@ -426,12 +427,22 @@ private CallbackResponse addGeneratedDocumentToCollection(CallbackParams callbac state = CASE_PROGRESSION; } - if (caseData.getFinalOrderFurtherHearingComplex() != null - && caseData.getFinalOrderFurtherHearingComplex().getHearingNotesText() != null) { - caseDataBuilder.hearingNotes(HearingNotes.builder() - .date(LocalDate.now()) - .notes(caseData.getFinalOrderFurtherHearingComplex().getHearingNotesText()) - .build()); + // populate hearing notes in listing tab with hearing notes from either assisted or freeform order, if either exist. + if (caseData.getFinalOrderSelection().equals(ASSISTED_ORDER)) { + if (caseData.getFinalOrderFurtherHearingComplex() != null + && caseData.getFinalOrderFurtherHearingComplex().getHearingNotesText() != null) { + caseDataBuilder.hearingNotes(HearingNotes.builder() + .date(LocalDate.now()) + .notes(caseData.getFinalOrderFurtherHearingComplex().getHearingNotesText()) + .build()); + } + } else { + if (nonNull(caseData.getFreeFormHearingNotes())) { + caseDataBuilder.hearingNotes(HearingNotes.builder() + .date(LocalDate.now()) + .notes(caseData.getFreeFormHearingNotes()) + .build()); + } } return AboutToStartOrSubmitCallbackResponse.builder() diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java index 7a65369a8b0..64f19a58e04 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java @@ -607,6 +607,7 @@ public boolean hasNoOngoingBusinessProcess() { private final FreeFormOrderValues orderOnCourtInitiative; private final FreeFormOrderValues orderWithoutNotice; private final OrderOnCourtsList orderOnCourtsList; + private final String freeFormHearingNotes; private Document finalOrderDocument; @Builder.Default diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandlerTest.java index f4405df2cfd..6c8917b9b9c 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandlerTest.java @@ -334,7 +334,7 @@ void shouldPopulateFields_whenIsCalledAfterSdoDiffSol() { } } - + @Nested class MidEventValidateAndGenerateOrderDocumentPreview { private static final String PAGE_ID = "validate-and-generate-document"; @@ -846,6 +846,23 @@ void shouldRePopulateHearingNotes_whenAssistedHearingNotesExist() { assertThat(response.getData()).extracting("hearingNotes").extracting("notes").isEqualTo("test text hearing notes assisted order"); } + @Test + void shouldRePopulateHearingNotes_whenFreeFormHearingNotesExist() { + // Given + List toggle = new ArrayList<>(); + toggle.add(FinalOrderToggle.SHOW); + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() + .finalOrderSelection(FinalOrderSelection.FREE_FORM_ORDER) + .freeFormHearingNotes("test text hearing notes free form order") + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + // When + when(judgeFinalOrderGenerator.generate(any(), any())).thenReturn(finalOrder); + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + // Then + assertThat(response.getData()).extracting("hearingNotes").extracting("notes").isEqualTo("test text hearing notes free form order"); + } + @Test void shouldNotRePopulateHearingNotes_whenAssistedHearingNotesDoNotExist() { // Given @@ -863,6 +880,24 @@ void shouldNotRePopulateHearingNotes_whenAssistedHearingNotesDoNotExist() { // Then assertThat(response.getData()).extracting("hearingNotes").extracting("notes").isEqualTo("preexisting hearing notes"); } + + @Test + void shouldNotRePopulateHearingNotes_whenFreeFormHearingNotesDoNotExist() { + // Given + List toggle = new ArrayList<>(); + toggle.add(FinalOrderToggle.SHOW); + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() + .finalOrderSelection(FinalOrderSelection.FREE_FORM_ORDER) + .finalOrderFurtherHearingToggle(toggle) + .hearingNotes(HearingNotes.builder().notes("preexisting hearing notes").build()) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + // When + when(judgeFinalOrderGenerator.generate(any(), any())).thenReturn(finalOrder); + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + // Then + assertThat(response.getData()).extracting("hearingNotes").extracting("notes").isEqualTo("preexisting hearing notes"); + } } @Nested From fb9eb2a6fcc2f858759924f0061c7674e19c2662 Mon Sep 17 00:00:00 2001 From: pliao-hmcts <113367232+pliao-hmcts@users.noreply.github.com> Date: Tue, 7 Nov 2023 15:02:13 +0000 Subject: [PATCH 10/28] CIV-11472 add more allowed states for asyncStitchingComplete (#3534) --- .../FlowStateAllowedEventService.java | 21 ++++++++++++------- .../FlowStateAllowedEventServiceTest.java | 6 ++++-- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventService.java b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventService.java index 2b39e00bdd3..85c31fb7330 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventService.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventService.java @@ -282,7 +282,8 @@ public class FlowStateAllowedEventService { GENERATE_DIRECTIONS_ORDER, TRIAL_READINESS, BUNDLE_CREATION_NOTIFICATION, - TRANSFER_ONLINE_CASE + TRANSFER_ONLINE_CASE, + asyncStitchingComplete ) ), @@ -542,7 +543,8 @@ public class FlowStateAllowedEventService { SET_ASIDE_JUDGMENT, JUDGMENT_PAID_IN_FULL, RECORD_JUDGMENT, - TRANSFER_ONLINE_CASE + TRANSFER_ONLINE_CASE, + asyncStitchingComplete ) ), @@ -864,7 +866,8 @@ public class FlowStateAllowedEventService { EVIDENCE_UPLOAD_RESPONDENT, BUNDLE_CREATION_NOTIFICATION, CHANGE_SOLICITOR_EMAIL, - LIP_CLAIM_SETTLED + LIP_CLAIM_SETTLED, + asyncStitchingComplete ) ), entry( @@ -903,7 +906,8 @@ public class FlowStateAllowedEventService { EVIDENCE_UPLOAD_RESPONDENT, BUNDLE_CREATION_NOTIFICATION, CHANGE_SOLICITOR_EMAIL, - LIP_CLAIM_SETTLED + LIP_CLAIM_SETTLED, + asyncStitchingComplete ) ), entry( @@ -1100,7 +1104,8 @@ public class FlowStateAllowedEventService { JUDGMENT_PAID_IN_FULL, RECORD_JUDGMENT, LIP_CLAIM_SETTLED, - TRANSFER_ONLINE_CASE + TRANSFER_ONLINE_CASE, + asyncStitchingComplete ) ), @@ -1285,7 +1290,8 @@ public class FlowStateAllowedEventService { ADD_CASE_NOTE, CHANGE_SOLICITOR_EMAIL, ADD_UNAVAILABLE_DATES, - LIP_CLAIM_SETTLED + LIP_CLAIM_SETTLED, + asyncStitchingComplete ) ), entry( @@ -1327,7 +1333,8 @@ public class FlowStateAllowedEventService { TRIAL_READINESS, BUNDLE_CREATION_NOTIFICATION, CHANGE_SOLICITOR_EMAIL, - ADD_UNAVAILABLE_DATES + ADD_UNAVAILABLE_DATES, + asyncStitchingComplete ) ), entry( diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventServiceTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventServiceTest.java index 3046d377756..f1dd6858eae 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventServiceTest.java @@ -320,7 +320,8 @@ public Stream provideArguments(ExtensionContext context) { GENERATE_DIRECTIONS_ORDER, TRIAL_READINESS, BUNDLE_CREATION_NOTIFICATION, - TRANSFER_ONLINE_CASE + TRANSFER_ONLINE_CASE, + asyncStitchingComplete } ), of( @@ -569,7 +570,8 @@ public Stream provideArguments(ExtensionContext context) { SET_ASIDE_JUDGMENT, JUDGMENT_PAID_IN_FULL, RECORD_JUDGMENT, - TRANSFER_ONLINE_CASE + TRANSFER_ONLINE_CASE, + asyncStitchingComplete } ), of( From d5294013b859792345287d77a9e0de4544a79347 Mon Sep 17 00:00:00 2001 From: drummondjm <93932689+drummondjm@users.noreply.github.com> Date: Wed, 8 Nov 2023 12:45:02 +0000 Subject: [PATCH 11/28] CIV-10947 evidence upload notifications (#3517) * initial * Add documents uploaded during evidence upload to String, to populate email notification * Tests * Tests * reverted FeatureToggleService * checkstyle * update to populate notificationText, to be based on case data if existing * checkstyle * Additional tests * improved sonar changes * point at civil-ccd * point at civil-ccd * improved coverage * Testing * Testing * Testing * revert featuretoggle push * updated to remove unnecessary notification content * updated string creation * removed logging and PR pointing --------- Co-authored-by: Madhan Mahadevan --- .../notification/NotificationData.java | 3 + .../user/EvidenceUploadHandlerBase.java | 253 +++++++++++++----- ...videnceUploadNotificationEventHandler.java | 21 ++ .../reform/civil/model/CaseDataParent.java | 1 + ...nceUploadApplicantNotificationHandler.java | 19 +- ...ceUploadRespondentNotificationHandler.java | 8 +- .../EvidenceUploadApplicantHandlerTest.java | 160 ++++++++++- .../EvidenceUploadRespondentHandlerTest.java | 104 ++++++- ...nceUploadNotificationEventHandlerTest.java | 8 + ...ploadApplicantNotificationHandlerTest.java | 42 ++- ...loadRespondentNotificationHandlerTest.java | 48 +++- 11 files changed, 570 insertions(+), 97 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotificationData.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotificationData.java index d55b1b7339b..811456c2cc9 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotificationData.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotificationData.java @@ -84,6 +84,9 @@ public interface NotificationData { String OTHER_SOL_NAME = "other solicitor name"; String EXTERNAL_ID = "externalId"; + // evidence upload + String UPLOADED_DOCUMENTS = "uploaded documents"; + Map addProperties(CaseData caseData); } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadHandlerBase.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadHandlerBase.java index 3de0019be4b..e69ffd03ba7 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadHandlerBase.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadHandlerBase.java @@ -2,6 +2,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; @@ -44,6 +45,7 @@ import uk.gov.hmcts.reform.civil.utils.ElementUtils; import uk.gov.hmcts.reform.idam.client.models.UserInfo; +import static java.lang.String.format; import static java.util.Objects.nonNull; import static uk.gov.hmcts.reform.civil.callback.CallbackParams.Params.BEARER_TOKEN; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_START; @@ -133,6 +135,24 @@ abstract class EvidenceUploadHandlerBase extends CallbackHandler { protected static final String APPLICANT_TWO_PRECEDENT_H = "ApplicantTwoUploadedPrecedentH"; protected static final String APPLICANT_TWO_ANY_PRECEDENT_H = "ApplicantTwoAnyPrecedentH"; + // Notification Strings used for email + protected static StringBuilder notificationString = new StringBuilder(); + protected static final String DISCLOSURE_LIST_TEXT = "%s - Disclosure list"; + protected static final String DISCLOSURE_TEXT = "%s - Documents for disclosure"; + protected static final String WITNESS_STATEMENT_TEXT = "%s - Witness statement"; + protected static final String WITNESS_SUMMARY_TEXT = "%s - Witness summary"; + protected static final String WITNESS_HEARSAY_TEXT = "%s - Notice of the intention to rely on hearsay evidence"; + protected static final String WITNESS_REFERRED_TEXT = "%s - Documents referred to in the statement"; + protected static final String EXPERT_REPORT_TEXT = "%s - Expert's report"; + protected static final String EXPERT_JOINT_STATEMENT_TEXT = "%s - Joint Statement of Experts / Single Joint Expert Report"; + protected static final String EXPERT_QUESTIONS_TEXT = "%s - Questions for other party's expert or joint experts"; + protected static final String EXPERT_ANSWERS_TEXT = "%s - Answer to questions asked"; + protected static final String PRE_TRIAL_SUMMARY_TEXT = "%s - Case Summary"; + protected static final String TRIAL_SKELETON_TEXT = "%s - Skeleton argument"; + protected static final String TRIAL_AUTHORITIES_TEXT = "%s - Authorities"; + protected static final String TRIAL_COSTS_TEXT = "%s - Costs"; + protected static final String TRIAL_DOC_CORRESPONDENCE_TEXT = "%s - Documentary evidence for trial"; + protected static final String OPTION_APP1 = "Claimant 1 - "; protected static final String OPTION_APP2 = "Claimant 2 - "; protected static final String OPTION_APP_BOTH = "Claimants 1 and 2"; @@ -166,8 +186,6 @@ protected EvidenceUploadHandlerBase(UserService userService, CoreCaseUserService abstract void applyDocumentUploadDate(CaseData.CaseDataBuilder caseDataBuilder, LocalDateTime now); - abstract void updateDocumentListUploadedAfterBundle(CaseData.CaseDataBuilder caseDataBuilder, CaseData caseData); - @Override public List handledEvents() { return events; @@ -208,6 +226,11 @@ CallbackResponse setOptions(CallbackParams callbackParams) { caseDataBuilder.caseProgAllocatedTrack(getAllocatedTrack(caseData.getClaimValue().toPounds(), caseData.getClaimType()).name()); } caseDataBuilder.evidenceUploadOptions(DynamicList.fromList(dynamicListOptions)); + // was unable to null value properly in EvidenceUploadNotificationEventHandler after emails are sent, + // so do it here if required. + if (nonNull(caseData.getNotificationText()) && caseData.getNotificationText().equals("NULLED")) { + caseDataBuilder.notificationText(null); + } return AboutToStartOrSubmitCallbackResponse.builder() .data(caseDataBuilder.build().toMap(objectMapper)) .build(); @@ -399,14 +422,23 @@ void checkDateCorrectness(Time time, List errors, List> d } public void setCategoryIdAndRenameDoc(List> documentUpload, Function, - Document> documentExtractor, String theID) { + Document> documentExtractor, String theID, String docNotificationText, Function, + LocalDateTime> documentDateTimeExtractor, String claimantDefendantString) { if (documentUpload == null || documentUpload.isEmpty()) { return; } + LocalDateTime midnight = LocalDateTime.of(LocalDate.now(), LocalTime.MIDNIGHT); renameDocuments(documentUpload, theID); documentUpload.forEach(document -> { Document documentToAddId = documentExtractor.apply(document); documentToAddId.setCategoryID(theID); + LocalDateTime dateTime = documentDateTimeExtractor.apply(document); + if (dateTime.isAfter(midnight)) { + String updateNotificationText = format(docNotificationText, claimantDefendantString); + if (!notificationString.toString().contains(updateNotificationText)) { + notificationString.append("\n").append(updateNotificationText); + } + } }); } @@ -548,92 +580,175 @@ private void renameUploadEvidenceDocumentType(final List> documen }); } - CallbackResponse documentUploadTime(CallbackParams callbackParams) { - CaseData caseData = callbackParams.getCaseData(); - CaseData.CaseDataBuilder caseDataBuilder = caseData.toBuilder(); + static void getNotificationText(CaseData caseData) { + notificationString = new StringBuilder(); + if (caseData.getNotificationText() != null) { + notificationString = new StringBuilder(caseData.getNotificationText()); + } + } - String selectedRole = getSelectedRole(callbackParams); + abstract void updateDocumentListUploadedAfterBundle(CaseData.CaseDataBuilder caseDataBuilder, CaseData caseData); - applyDocumentUploadDate(caseDataBuilder, time.now()); + private void updateDocumentListUploadedAfterBundle(CaseData caseData, CaseData.CaseDataBuilder caseDataBuilder) { if (nonNull(caseData.getCaseBundles()) && !caseData.getCaseBundles().isEmpty()) { updateDocumentListUploadedAfterBundle(caseDataBuilder, caseData); } + } + + CallbackResponse documentUploadTime(CallbackParams callbackParams) { + CaseData caseData = callbackParams.getCaseData(); + CaseData.CaseDataBuilder caseDataBuilder = caseData.toBuilder(); + // If notification has already been populated in current day, we want to append to that existing notification + getNotificationText(caseData); + applyDocumentUploadDate(caseDataBuilder, time.now()); + updateDocumentListUploadedAfterBundle(caseData, caseDataBuilder); + String selectedRole = getSelectedRole(callbackParams); if (selectedRole.equals(RESPONDENTSOLICITORONE.name()) || selectedRole.equals(SELECTED_VALUE_DEF_BOTH)) { - setCategoryIdAndRenameDoc(caseData.getDocumentDisclosureListRes(), document -> document.getValue().getDocumentUpload(), RESPONDENT_ONE_DISCLOSURE_LIST); - setCategoryIdAndRenameDoc(caseData.getDocumentForDisclosureRes(), document -> document.getValue().getDocumentUpload(), RESPONDENT_ONE_DISCLOSURE); - setCategoryIdAndRenameDoc(caseData.getDocumentWitnessStatementRes(), document -> document.getValue().getWitnessOptionDocument(), RESPONDENT_ONE_WITNESS_STATEMENT); - setCategoryIdAndRenameDoc(caseData.getDocumentWitnessSummaryRes(), document -> document.getValue().getWitnessOptionDocument(), RESPONDENT_ONE_WITNESS_SUMMARY); - setCategoryIdAndRenameDoc(caseData.getDocumentHearsayNoticeRes(), document -> document.getValue().getWitnessOptionDocument(), RESPONDENT_ONE_WITNESS_HEARSAY); - setCategoryIdAndRenameDoc(caseData.getDocumentReferredInStatementRes(), document -> document.getValue().getDocumentUpload(), RESPONDENT_ONE_WITNESS_REFERRED); - setCategoryIdAndRenameDoc(caseData.getDocumentExpertReportRes(), document -> document.getValue().getExpertDocument(), RESPONDENT_ONE_EXPERT_REPORT); - setCategoryIdAndRenameDoc(caseData.getDocumentJointStatementRes(), document -> document.getValue().getExpertDocument(), RESPONDENT_ONE_EXPERT_JOINT_STATEMENT); - setCategoryIdAndRenameDoc(caseData.getDocumentQuestionsRes(), document -> document.getValue().getExpertDocument(), RESPONDENT_ONE_EXPERT_QUESTIONS); - setCategoryIdAndRenameDoc(caseData.getDocumentAnswersRes(), document -> document.getValue().getExpertDocument(), RESPONDENT_ONE_EXPERT_ANSWERS); - setCategoryIdAndRenameDoc(caseData.getDocumentCaseSummaryRes(), document -> document.getValue().getDocumentUpload(), RESPONDENT_ONE_PRE_TRIAL_SUMMARY); - setCategoryIdAndRenameDoc(caseData.getDocumentSkeletonArgumentRes(), document -> document.getValue().getDocumentUpload(), RESPONDENT_ONE_TRIAL_SKELETON); - setCategoryIdAndRenameDoc(caseData.getDocumentAuthoritiesRes(), document -> document.getValue().getDocumentUpload(), RESPONDENT_ONE_PRECEDENT_H); - setCategoryIdAndRenameDoc(caseData.getDocumentCostsRes(), document -> document.getValue().getDocumentUpload(), RESPONDENT_ONE_ANY_PRECEDENT_H); - setCategoryIdAndRenameDoc(caseData.getDocumentEvidenceForTrialRes(), document -> document.getValue().getDocumentUpload(), RESPONDENT_ONE_TRIAL_DOC_CORRESPONDENCE); + String defendantString = "Defendant 1"; + if (selectedRole.equals(SELECTED_VALUE_DEF_BOTH)) { + defendantString = "Both defendants"; + } + setCategoryIdAndRenameDoc(caseData.getDocumentDisclosureListRes(), document -> document.getValue().getDocumentUpload(), RESPONDENT_ONE_DISCLOSURE_LIST, + DISCLOSURE_LIST_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentForDisclosureRes(), document -> document.getValue().getDocumentUpload(), RESPONDENT_ONE_DISCLOSURE, + DISCLOSURE_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentWitnessStatementRes(), document -> document.getValue().getWitnessOptionDocument(), RESPONDENT_ONE_WITNESS_STATEMENT, + WITNESS_STATEMENT_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentWitnessSummaryRes(), document -> document.getValue().getWitnessOptionDocument(), RESPONDENT_ONE_WITNESS_SUMMARY, + WITNESS_SUMMARY_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentHearsayNoticeRes(), document -> document.getValue().getWitnessOptionDocument(), RESPONDENT_ONE_WITNESS_HEARSAY, + WITNESS_HEARSAY_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentReferredInStatementRes(), document -> document.getValue().getDocumentUpload(), RESPONDENT_ONE_WITNESS_REFERRED, + WITNESS_REFERRED_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentExpertReportRes(), document -> document.getValue().getExpertDocument(), RESPONDENT_ONE_EXPERT_REPORT, + EXPERT_REPORT_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentJointStatementRes(), document -> document.getValue().getExpertDocument(), RESPONDENT_ONE_EXPERT_JOINT_STATEMENT, + EXPERT_JOINT_STATEMENT_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentQuestionsRes(), document -> document.getValue().getExpertDocument(), RESPONDENT_ONE_EXPERT_QUESTIONS, + EXPERT_QUESTIONS_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentAnswersRes(), document -> document.getValue().getExpertDocument(), RESPONDENT_ONE_EXPERT_ANSWERS, + EXPERT_ANSWERS_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentCaseSummaryRes(), document -> document.getValue().getDocumentUpload(), RESPONDENT_ONE_PRE_TRIAL_SUMMARY, + PRE_TRIAL_SUMMARY_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentSkeletonArgumentRes(), document -> document.getValue().getDocumentUpload(), RESPONDENT_ONE_TRIAL_SKELETON, + TRIAL_SKELETON_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentAuthoritiesRes(), document -> document.getValue().getDocumentUpload(), RESPONDENT_ONE_PRECEDENT_H, + TRIAL_AUTHORITIES_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentCostsRes(), document -> document.getValue().getDocumentUpload(), RESPONDENT_ONE_ANY_PRECEDENT_H, + TRIAL_COSTS_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentEvidenceForTrialRes(), document -> document.getValue().getDocumentUpload(), RESPONDENT_ONE_TRIAL_DOC_CORRESPONDENCE, + TRIAL_DOC_CORRESPONDENCE_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); if (selectedRole.equals(SELECTED_VALUE_DEF_BOTH)) { caseData = copyResp1ChangesToResp2(caseData, caseDataBuilder); } } if (selectedRole.equals(RESPONDENTSOLICITORTWO.name())) { - setCategoryIdAndRenameDoc(caseData.getDocumentDisclosureListRes2(), document -> document.getValue().getDocumentUpload(), RESPONDENT_TWO_DISCLOSURE_LIST); - setCategoryIdAndRenameDoc(caseData.getDocumentForDisclosureRes2(), document -> document.getValue().getDocumentUpload(), RESPONDENT_TWO_DISCLOSURE); - setCategoryIdAndRenameDoc(caseData.getDocumentWitnessStatementRes2(), document -> document.getValue().getWitnessOptionDocument(), RESPONDENT_TWO_WITNESS_STATEMENT); - setCategoryIdAndRenameDoc(caseData.getDocumentWitnessSummaryRes2(), document -> document.getValue().getWitnessOptionDocument(), RESPONDENT_TWO_WITNESS_SUMMARY); - setCategoryIdAndRenameDoc(caseData.getDocumentHearsayNoticeRes2(), document -> document.getValue().getWitnessOptionDocument(), RESPONDENT_TWO_WITNESS_HEARSAY); - setCategoryIdAndRenameDoc(caseData.getDocumentReferredInStatementRes2(), document -> document.getValue().getDocumentUpload(), RESPONDENT_TWO_WITNESS_REFERRED); - setCategoryIdAndRenameDoc(caseData.getDocumentExpertReportRes2(), document -> document.getValue().getExpertDocument(), RESPONDENT_TWO_EXPERT_REPORT); - setCategoryIdAndRenameDoc(caseData.getDocumentJointStatementRes2(), document -> document.getValue().getExpertDocument(), RESPONDENT_TWO_EXPERT_JOINT_STATEMENT); - setCategoryIdAndRenameDoc(caseData.getDocumentQuestionsRes2(), document -> document.getValue().getExpertDocument(), RESPONDENT_TWO_EXPERT_QUESTIONS); - setCategoryIdAndRenameDoc(caseData.getDocumentAnswersRes2(), document -> document.getValue().getExpertDocument(), RESPONDENT_TWO_EXPERT_ANSWERS); - setCategoryIdAndRenameDoc(caseData.getDocumentCaseSummaryRes2(), document -> document.getValue().getDocumentUpload(), RESPONDENT_TWO_PRE_TRIAL_SUMMARY); - setCategoryIdAndRenameDoc(caseData.getDocumentSkeletonArgumentRes2(), document -> document.getValue().getDocumentUpload(), RESPONDENT_TWO_TRIAL_SKELETON); - setCategoryIdAndRenameDoc(caseData.getDocumentAuthoritiesRes2(), document -> document.getValue().getDocumentUpload(), RESPONDENT_TWO_PRECEDENT_H); - setCategoryIdAndRenameDoc(caseData.getDocumentCostsRes2(), document -> document.getValue().getDocumentUpload(), RESPONDENT_TWO_ANY_PRECEDENT_H); - setCategoryIdAndRenameDoc(caseData.getDocumentEvidenceForTrialRes2(), document -> document.getValue().getDocumentUpload(), RESPONDENT_TWO_TRIAL_DOC_CORRESPONDENCE); + String defendantString = "Defendant 2"; + setCategoryIdAndRenameDoc(caseData.getDocumentDisclosureListRes2(), document -> document.getValue().getDocumentUpload(), RESPONDENT_TWO_DISCLOSURE_LIST, + DISCLOSURE_LIST_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentForDisclosureRes2(), document -> document.getValue().getDocumentUpload(), RESPONDENT_TWO_DISCLOSURE, + DISCLOSURE_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentWitnessStatementRes2(), document -> document.getValue().getWitnessOptionDocument(), RESPONDENT_TWO_WITNESS_STATEMENT, + WITNESS_STATEMENT_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentWitnessSummaryRes2(), document -> document.getValue().getWitnessOptionDocument(), RESPONDENT_TWO_WITNESS_SUMMARY, + WITNESS_SUMMARY_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentHearsayNoticeRes2(), document -> document.getValue().getWitnessOptionDocument(), RESPONDENT_TWO_WITNESS_HEARSAY, + WITNESS_HEARSAY_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentReferredInStatementRes2(), document -> document.getValue().getDocumentUpload(), RESPONDENT_TWO_WITNESS_REFERRED, + WITNESS_REFERRED_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentExpertReportRes2(), document -> document.getValue().getExpertDocument(), RESPONDENT_TWO_EXPERT_REPORT, + EXPERT_REPORT_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentJointStatementRes2(), document -> document.getValue().getExpertDocument(), RESPONDENT_TWO_EXPERT_JOINT_STATEMENT, + EXPERT_JOINT_STATEMENT_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentQuestionsRes2(), document -> document.getValue().getExpertDocument(), RESPONDENT_TWO_EXPERT_QUESTIONS, + EXPERT_QUESTIONS_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentAnswersRes2(), document -> document.getValue().getExpertDocument(), RESPONDENT_TWO_EXPERT_ANSWERS, + EXPERT_ANSWERS_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentCaseSummaryRes2(), document -> document.getValue().getDocumentUpload(), RESPONDENT_TWO_PRE_TRIAL_SUMMARY, + PRE_TRIAL_SUMMARY_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentSkeletonArgumentRes2(), document -> document.getValue().getDocumentUpload(), RESPONDENT_TWO_TRIAL_SKELETON, + TRIAL_SKELETON_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentAuthoritiesRes2(), document -> document.getValue().getDocumentUpload(), RESPONDENT_TWO_PRECEDENT_H, + TRIAL_AUTHORITIES_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentCostsRes2(), document -> document.getValue().getDocumentUpload(), RESPONDENT_TWO_ANY_PRECEDENT_H, + TRIAL_COSTS_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); + setCategoryIdAndRenameDoc(caseData.getDocumentEvidenceForTrialRes2(), document -> document.getValue().getDocumentUpload(), RESPONDENT_TWO_TRIAL_DOC_CORRESPONDENCE, + TRIAL_DOC_CORRESPONDENCE_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); } if (selectedRole.equals(CaseRole.APPLICANTSOLICITORONE.name()) || selectedRole.equals(SELECTED_VALUE_APP_BOTH)) { - setCategoryIdAndRenameDoc(caseData.getDocumentDisclosureList(), document -> document.getValue().getDocumentUpload(), APPLICANT_DISCLOSURE_LIST); - setCategoryIdAndRenameDoc(caseData.getDocumentForDisclosure(), document -> document.getValue().getDocumentUpload(), APPLICANT_DISCLOSURE); - setCategoryIdAndRenameDoc(caseData.getDocumentWitnessStatement(), document -> document.getValue().getWitnessOptionDocument(), APPLICANT_WITNESS_STATEMENT); - setCategoryIdAndRenameDoc(caseData.getDocumentWitnessSummary(), document -> document.getValue().getWitnessOptionDocument(), APPLICANT_WITNESS_SUMMARY); - setCategoryIdAndRenameDoc(caseData.getDocumentHearsayNotice(), document -> document.getValue().getWitnessOptionDocument(), APPLICANT_WITNESS_HEARSAY); - setCategoryIdAndRenameDoc(caseData.getDocumentReferredInStatement(), document -> document.getValue().getDocumentUpload(), APPLICANT_WITNESS_REFERRED); - setCategoryIdAndRenameDoc(caseData.getDocumentExpertReport(), document -> document.getValue().getExpertDocument(), APPLICANT_EXPERT_REPORT); - setCategoryIdAndRenameDoc(caseData.getDocumentJointStatement(), document -> document.getValue().getExpertDocument(), APPLICANT_EXPERT_JOINT_STATEMENT); - setCategoryIdAndRenameDoc(caseData.getDocumentQuestions(), document -> document.getValue().getExpertDocument(), APPLICANT_EXPERT_QUESTIONS); - setCategoryIdAndRenameDoc(caseData.getDocumentAnswers(), document -> document.getValue().getExpertDocument(), APPLICANT_EXPERT_ANSWERS); - setCategoryIdAndRenameDoc(caseData.getDocumentCaseSummary(), document -> document.getValue().getDocumentUpload(), APPLICANT_PRE_TRIAL_SUMMARY); - setCategoryIdAndRenameDoc(caseData.getDocumentSkeletonArgument(), document -> document.getValue().getDocumentUpload(), APPLICANT_TRIAL_SKELETON); - setCategoryIdAndRenameDoc(caseData.getDocumentAuthorities(), document -> document.getValue().getDocumentUpload(), APPLICANT_PRECEDENT_H); - setCategoryIdAndRenameDoc(caseData.getDocumentCosts(), document -> document.getValue().getDocumentUpload(), APPLICANT_ANY_PRECEDENT_H); - setCategoryIdAndRenameDoc(caseData.getDocumentEvidenceForTrial(), document -> document.getValue().getDocumentUpload(), APPLICANT_TRIAL_DOC_CORRESPONDENCE); + String claimantString = "Claimant 1"; + if (selectedRole.equals(SELECTED_VALUE_APP_BOTH)) { + claimantString = "Both claimants"; + } + setCategoryIdAndRenameDoc(caseData.getDocumentDisclosureList(), document -> document.getValue().getDocumentUpload(), APPLICANT_DISCLOSURE_LIST, + DISCLOSURE_LIST_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentForDisclosure(), document -> document.getValue().getDocumentUpload(), APPLICANT_DISCLOSURE, + DISCLOSURE_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentWitnessStatement(), document -> document.getValue().getWitnessOptionDocument(), APPLICANT_WITNESS_STATEMENT, + WITNESS_STATEMENT_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentWitnessSummary(), document -> document.getValue().getWitnessOptionDocument(), APPLICANT_WITNESS_SUMMARY, + WITNESS_SUMMARY_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentHearsayNotice(), document -> document.getValue().getWitnessOptionDocument(), APPLICANT_WITNESS_HEARSAY, + WITNESS_HEARSAY_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentReferredInStatement(), document -> document.getValue().getDocumentUpload(), APPLICANT_WITNESS_REFERRED, + WITNESS_REFERRED_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentExpertReport(), document -> document.getValue().getExpertDocument(), APPLICANT_EXPERT_REPORT, + EXPERT_REPORT_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentJointStatement(), document -> document.getValue().getExpertDocument(), APPLICANT_EXPERT_JOINT_STATEMENT, + EXPERT_JOINT_STATEMENT_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentQuestions(), document -> document.getValue().getExpertDocument(), APPLICANT_EXPERT_QUESTIONS, + EXPERT_QUESTIONS_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentAnswers(), document -> document.getValue().getExpertDocument(), APPLICANT_EXPERT_ANSWERS, + EXPERT_ANSWERS_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentCaseSummary(), document -> document.getValue().getDocumentUpload(), APPLICANT_PRE_TRIAL_SUMMARY, + PRE_TRIAL_SUMMARY_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentSkeletonArgument(), document -> document.getValue().getDocumentUpload(), APPLICANT_TRIAL_SKELETON, + TRIAL_SKELETON_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentAuthorities(), document -> document.getValue().getDocumentUpload(), APPLICANT_PRECEDENT_H, + TRIAL_AUTHORITIES_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentCosts(), document -> document.getValue().getDocumentUpload(), APPLICANT_ANY_PRECEDENT_H, + TRIAL_COSTS_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentEvidenceForTrial(), document -> document.getValue().getDocumentUpload(), APPLICANT_TRIAL_DOC_CORRESPONDENCE, + TRIAL_DOC_CORRESPONDENCE_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); if (selectedRole.equals(SELECTED_VALUE_APP_BOTH)) { caseData = copyApp1ChangesToApp2(caseData, caseDataBuilder); } } if (selectedRole.equals("APPLICANTSOLICITORTWO")) { - setCategoryIdAndRenameDoc(caseData.getDocumentDisclosureListApp2(), document -> document.getValue().getDocumentUpload(), APPLICANT_TWO_DISCLOSURE_LIST); - setCategoryIdAndRenameDoc(caseData.getDocumentForDisclosureApp2(), document -> document.getValue().getDocumentUpload(), APPLICANT_TWO_DISCLOSURE); - setCategoryIdAndRenameDoc(caseData.getDocumentWitnessStatementApp2(), document -> document.getValue().getWitnessOptionDocument(), APPLICANT_TWO_WITNESS_STATEMENT); - setCategoryIdAndRenameDoc(caseData.getDocumentWitnessSummaryApp2(), document -> document.getValue().getWitnessOptionDocument(), APPLICANT_TWO_WITNESS_SUMMARY); - setCategoryIdAndRenameDoc(caseData.getDocumentHearsayNoticeApp2(), document -> document.getValue().getWitnessOptionDocument(), APPLICANT_TWO_WITNESS_HEARSAY); - setCategoryIdAndRenameDoc(caseData.getDocumentReferredInStatementApp2(), document -> document.getValue().getDocumentUpload(), APPLICANT_TWO_WITNESS_REFERRED); - setCategoryIdAndRenameDoc(caseData.getDocumentExpertReportApp2(), document -> document.getValue().getExpertDocument(), APPLICANT_TWO_EXPERT_REPORT); - setCategoryIdAndRenameDoc(caseData.getDocumentJointStatementApp2(), document -> document.getValue().getExpertDocument(), APPLICANT_TWO_EXPERT_JOINT_STATEMENT); - setCategoryIdAndRenameDoc(caseData.getDocumentQuestionsApp2(), document -> document.getValue().getExpertDocument(), APPLICANT_TWO_EXPERT_QUESTIONS); - setCategoryIdAndRenameDoc(caseData.getDocumentAnswersApp2(), document -> document.getValue().getExpertDocument(), APPLICANT_TWO_EXPERT_ANSWERS); - setCategoryIdAndRenameDoc(caseData.getDocumentCaseSummaryApp2(), document -> document.getValue().getDocumentUpload(), APPLICANT_TWO_PRE_TRIAL_SUMMARY); - setCategoryIdAndRenameDoc(caseData.getDocumentSkeletonArgumentApp2(), document -> document.getValue().getDocumentUpload(), APPLICANT_TWO_TRIAL_SKELETON); - setCategoryIdAndRenameDoc(caseData.getDocumentAuthoritiesApp2(), document -> document.getValue().getDocumentUpload(), APPLICANT_TWO_PRECEDENT_H); - setCategoryIdAndRenameDoc(caseData.getDocumentCostsApp2(), document -> document.getValue().getDocumentUpload(), APPLICANT_TWO_ANY_PRECEDENT_H); - setCategoryIdAndRenameDoc(caseData.getDocumentEvidenceForTrialApp2(), document -> document.getValue().getDocumentUpload(), APPLICANT_TWO_TRIAL_DOC_CORRESPONDENCE); + String claimantString = "Claimant 2"; + setCategoryIdAndRenameDoc(caseData.getDocumentDisclosureListApp2(), document -> document.getValue().getDocumentUpload(), APPLICANT_TWO_DISCLOSURE_LIST, + DISCLOSURE_LIST_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentForDisclosureApp2(), document -> document.getValue().getDocumentUpload(), APPLICANT_TWO_DISCLOSURE, + DISCLOSURE_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentWitnessStatementApp2(), document -> document.getValue().getWitnessOptionDocument(), APPLICANT_TWO_WITNESS_STATEMENT, + WITNESS_STATEMENT_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentWitnessSummaryApp2(), document -> document.getValue().getWitnessOptionDocument(), APPLICANT_TWO_WITNESS_SUMMARY, + WITNESS_SUMMARY_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentHearsayNoticeApp2(), document -> document.getValue().getWitnessOptionDocument(), APPLICANT_TWO_WITNESS_HEARSAY, + WITNESS_HEARSAY_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentReferredInStatementApp2(), document -> document.getValue().getDocumentUpload(), APPLICANT_TWO_WITNESS_REFERRED, + WITNESS_REFERRED_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentExpertReportApp2(), document -> document.getValue().getExpertDocument(), APPLICANT_TWO_EXPERT_REPORT, + EXPERT_REPORT_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentJointStatementApp2(), document -> document.getValue().getExpertDocument(), APPLICANT_TWO_EXPERT_JOINT_STATEMENT, + EXPERT_JOINT_STATEMENT_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentQuestionsApp2(), document -> document.getValue().getExpertDocument(), APPLICANT_TWO_EXPERT_QUESTIONS, + EXPERT_QUESTIONS_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentAnswersApp2(), document -> document.getValue().getExpertDocument(), APPLICANT_TWO_EXPERT_ANSWERS, + EXPERT_ANSWERS_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentCaseSummaryApp2(), document -> document.getValue().getDocumentUpload(), APPLICANT_TWO_PRE_TRIAL_SUMMARY, + PRE_TRIAL_SUMMARY_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentSkeletonArgumentApp2(), document -> document.getValue().getDocumentUpload(), APPLICANT_TWO_TRIAL_SKELETON, + TRIAL_SKELETON_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentAuthoritiesApp2(), document -> document.getValue().getDocumentUpload(), APPLICANT_TWO_PRECEDENT_H, + TRIAL_AUTHORITIES_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentCostsApp2(), document -> document.getValue().getDocumentUpload(), APPLICANT_TWO_ANY_PRECEDENT_H, + TRIAL_COSTS_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); + setCategoryIdAndRenameDoc(caseData.getDocumentEvidenceForTrialApp2(), document -> document.getValue().getDocumentUpload(), APPLICANT_TWO_TRIAL_DOC_CORRESPONDENCE, + TRIAL_DOC_CORRESPONDENCE_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); } // null the values of the lists, so that on future retriggers of the event, they are blank @@ -651,7 +766,7 @@ CallbackResponse documentUploadTime(CallbackParams callbackParams) { caseDataBuilder.trialSelectionEvidenceSmallClaim(null); caseDataBuilder.trialSelectionEvidenceRes(null); caseDataBuilder.trialSelectionEvidenceSmallClaimRes(null); - + caseDataBuilder.notificationText(notificationString.toString()); return AboutToStartOrSubmitCallbackResponse.builder() .data(caseDataBuilder.build().toMap(objectMapper)) .build(); diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/event/EvidenceUploadNotificationEventHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/event/EvidenceUploadNotificationEventHandler.java index ed52e4d8582..84adb0d19a8 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/event/EvidenceUploadNotificationEventHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/event/EvidenceUploadNotificationEventHandler.java @@ -4,7 +4,10 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; +import uk.gov.hmcts.reform.ccd.client.model.CaseDataContent; import uk.gov.hmcts.reform.ccd.client.model.CaseDetails; +import uk.gov.hmcts.reform.ccd.client.model.Event; +import uk.gov.hmcts.reform.ccd.client.model.StartEventResponse; import uk.gov.hmcts.reform.civil.event.EvidenceUploadNotificationEvent; import uk.gov.hmcts.reform.civil.helpers.CaseDetailsConverter; import uk.gov.hmcts.reform.civil.model.CaseData; @@ -12,6 +15,10 @@ import uk.gov.hmcts.reform.civil.notification.EvidenceUploadRespondentNotificationHandler; import uk.gov.hmcts.reform.civil.service.CoreCaseDataService; +import java.util.Map; + +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.EVIDENCE_UPLOAD_CHECK; + @Slf4j @Service @RequiredArgsConstructor @@ -50,5 +57,19 @@ public void sendEvidenceUploadNotification(EvidenceUploadNotificationEvent event } catch (Exception e) { log.warn("Failed to send email notification to respondent solicitor2 for case '{}'", event.getCaseId()); } + // null notificationText so it cleared each day, for any future evidence uploads + StartEventResponse startEventResponse = coreCaseDataService.startUpdate(event.getCaseId().toString(), EVIDENCE_UPLOAD_CHECK); + CaseDataContent caseContent = getCaseContent(startEventResponse); + coreCaseDataService.submitUpdate(event.getCaseId().toString(), caseContent); + } + + private CaseDataContent getCaseContent(StartEventResponse startEventResponse) { + Map data = startEventResponse.getCaseDetails().getData(); + data.put("notificationText", "NULLED"); + return CaseDataContent.builder() + .eventToken(startEventResponse.getToken()) + .event(Event.builder().id(startEventResponse.getEventId()).build()) + .data(data) + .build(); } } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseDataParent.java b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseDataParent.java index 9e490085485..e5b1329495e 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseDataParent.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseDataParent.java @@ -443,6 +443,7 @@ public boolean isApplicantNotRepresented() { private final CertificateOfService cosNotifyClaimDefendant1; private final CertificateOfService cosNotifyClaimDefendant2; + private final String notificationText; private final List disclosureSelectionEvidence; private final List disclosureSelectionEvidenceRes; private final List witnessSelectionEvidence; diff --git a/src/main/java/uk/gov/hmcts/reform/civil/notification/EvidenceUploadApplicantNotificationHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/notification/EvidenceUploadApplicantNotificationHandler.java index 5a5c2c8e67d..06d1bcbee18 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/notification/EvidenceUploadApplicantNotificationHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/notification/EvidenceUploadApplicantNotificationHandler.java @@ -11,6 +11,8 @@ import java.util.Map; +import static java.util.Objects.nonNull; + @Service @RequiredArgsConstructor public class EvidenceUploadApplicantNotificationHandler implements NotificationData { @@ -24,12 +26,14 @@ public void notifyApplicantEvidenceUpload(CaseData caseData) throws Notification boolean isApplicantLip = isApplicantLip(caseData); //Send email to Applicant - notificationService.sendMail( - getEmail(caseData, isApplicantLip), - getTemplate(caseData, isApplicantLip), - addProperties(caseData), - getReference(caseData) - ); + if (nonNull(caseData.getNotificationText()) && !caseData.getNotificationText().equals("NULLED")) { + notificationService.sendMail( + getEmail(caseData, isApplicantLip), + getTemplate(caseData, isApplicantLip), + addProperties(caseData), + getReference(caseData) + ); + } } private static String getReference(CaseData caseData) { @@ -53,7 +57,8 @@ private boolean isApplicantLip(CaseData caseData) { @Override public Map addProperties(CaseData caseData) { return Map.of( - CLAIM_REFERENCE_NUMBER, caseData.getLegacyCaseReference() + CLAIM_REFERENCE_NUMBER, caseData.getLegacyCaseReference(), + UPLOADED_DOCUMENTS, caseData.getNotificationText() ); } } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/notification/EvidenceUploadRespondentNotificationHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/notification/EvidenceUploadRespondentNotificationHandler.java index eb6758fa47c..a8a7dc43178 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/notification/EvidenceUploadRespondentNotificationHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/notification/EvidenceUploadRespondentNotificationHandler.java @@ -11,6 +11,7 @@ import java.util.Map; +import static java.util.Objects.nonNull; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; @Service @@ -41,7 +42,7 @@ public void notifyRespondentEvidenceUpload(CaseData caseData, boolean isForRespo isRespondentLip = true; } - if (null != email) { + if (null != email && nonNull(caseData.getNotificationText()) && !caseData.getNotificationText().equals("NULLED")) { notificationService.sendMail( email, getTemplate(isRespondentLip), @@ -62,7 +63,8 @@ public String getTemplate(boolean isRespondentLip) { @Override public Map addProperties(CaseData caseData) { return Map.of( - CLAIM_REFERENCE_NUMBER, caseData.getLegacyCaseReference() - ); + CLAIM_REFERENCE_NUMBER, caseData.getLegacyCaseReference(), + UPLOADED_DOCUMENTS, caseData.getNotificationText() + ); } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandlerTest.java index 5c0d9113902..cda6fc74fc7 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandlerTest.java @@ -96,7 +96,32 @@ class EvidenceUploadApplicantHandlerTest extends BaseCallbackHandlerTest { private final UploadEvidenceExpert uploadEvidenceDate = new UploadEvidenceExpert(); private final UploadEvidenceWitness uploadEvidenceDate2 = new UploadEvidenceWitness(); private final UploadEvidenceDocumentType uploadEvidenceDate3 = new UploadEvidenceDocumentType(); - + private static final String NotificationWhenBothClaimant = "\n" + + "Both claimants - Disclosure list\n" + + "Both claimants - Documents for disclosure\n" + + "Both claimants - Documents referred to in the statement\n" + + "Both claimants - Expert's report\n" + + "Both claimants - Joint Statement of Experts / Single Joint Expert Report\n" + + "Both claimants - Questions for other party's expert or joint experts\n" + + "Both claimants - Answer to questions asked\n" + + "Both claimants - Case Summary\n" + + "Both claimants - Skeleton argument\n" + + "Both claimants - Authorities\n" + + "Both claimants - Costs\n" + + "Both claimants - Documentary evidence for trial"; + private static final String NotificationWhenClaimantTwo = "\n" + + "Claimant 2 - Disclosure list\n" + + "Claimant 2 - Documents for disclosure\n" + + "Claimant 2 - Documents referred to in the statement\n" + + "Claimant 2 - Expert's report\n" + + "Claimant 2 - Joint Statement of Experts / Single Joint Expert Report\n" + + "Claimant 2 - Questions for other party's expert or joint experts\n" + + "Claimant 2 - Answer to questions asked\n" + + "Claimant 2 - Case Summary\n" + + "Claimant 2 - Skeleton argument\n" + + "Claimant 2 - Authorities\n" + + "Claimant 2 - Costs\n" + + "Claimant 2 - Documentary evidence for trial"; private static final String PAGE_ID = "validateValuesApplicant"; @BeforeEach @@ -108,6 +133,7 @@ void setup() { void givenAboutToStart_assignCaseProgAllocatedTrackUnSpec() { // Given CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build().toBuilder() + .notificationText(null) .claimType(ClaimType.CLINICAL_NEGLIGENCE) .claimValue(ClaimValue.builder() .statementOfValueInPennies(BigDecimal.valueOf(5000)) @@ -121,12 +147,14 @@ void givenAboutToStart_assignCaseProgAllocatedTrackUnSpec() { .handle(params); // Then assertThat(response.getData()).extracting("caseProgAllocatedTrack").isEqualTo("SMALL_CLAIM"); + assertThat(response.getData()).extracting("notificationText").isNull(); } @Test void givenAboutToStart_assignCaseProgAllocatedTrackSpec() { // Given CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build().toBuilder() + .notificationText(null) .claimType(null) .totalClaimAmount(BigDecimal.valueOf(12500)) .build(); @@ -138,6 +166,7 @@ void givenAboutToStart_assignCaseProgAllocatedTrackSpec() { .handle(params); // Then assertThat(response.getData()).extracting("caseProgAllocatedTrack").isEqualTo("FAST_CLAIM"); + assertThat(response.getData()).extracting("notificationText").isNull(); } @Test @@ -496,6 +525,7 @@ void shouldAssignCategoryID_whenDocumentExists() { "hash", null); var documentUpload = UploadEvidenceWitness.builder() .witnessOptionUploadDate(LocalDate.of(2023, 2, 10)) + .createdDatetime(LocalDateTime.of(2022, 05, 10, 12, 13, 12)) .witnessOptionDocument(testDocument).build(); List> documentList = new ArrayList<>(); documentList.add(Element.builder().value(documentUpload).build()); @@ -676,7 +706,6 @@ void shouldBreakWhenThereIsAnyCaseBundlesWithNullCreatedDate() { @CsvSource({"0", "2"}) void should_do_naming_convention(String selected) { LocalDateTime createdDate = LocalDateTime.of(2022, 05, 10, 12, 13, 12); - String witnessName = "AppWitness"; LocalDate witnessDate = LocalDate.of(2023, 2, 10); List options = List.of(EvidenceUploadHandlerBase.OPTION_APP1, @@ -815,9 +844,136 @@ void should_do_naming_convention(String selected) { .getDocumentUpload().getDocumentFileName()).isEqualTo(TEST_FILE_NAME); assertThat(updatedData.getDocumentCostsApp2().get(0).getValue() .getDocumentUpload().getCategoryID()).isEqualTo(EvidenceUploadHandlerBase.APPLICANT_TWO_ANY_PRECEDENT_H); + assertThat(updatedData.getNotificationText()).isEqualTo(NotificationWhenBothClaimant); } } + @Test + void should_do_naming_convention_app2() { + LocalDateTime createdDate = LocalDateTime.of(2022, 05, 10, 12, 13, 12); + List> witnessEvidenceDocs = new ArrayList<>(); + String witnessName = "appTwoWitness"; + List options = List.of(EvidenceUploadHandlerBase.OPTION_APP1, + EvidenceUploadHandlerBase.OPTION_APP2, + EvidenceUploadHandlerBase.OPTION_APP_BOTH); + LocalDate witnessDate = LocalDate.of(2023, 2, 10); + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() + .addApplicant2(YES) + .applicant1(PartyBuilder.builder().individual().build()) + .applicant2(PartyBuilder.builder().individual().build()) + .evidenceUploadOptions(DynamicList.fromList(options, Object::toString, options.get(1), false)) + .documentWitnessSummaryApp2(createWitnessDocs(witnessName, createdDate, witnessDate)) + .documentWitnessStatementApp2(createWitnessDocs(witnessName, createdDate, witnessDate)) + .documentHearsayNoticeApp2(createWitnessDocs(witnessName, createdDate, witnessDate)) + .documentExpertReportApp2(createExpertDocs("expertName", witnessDate, "expertise", null, null, null, null)) + .documentJointStatementApp2(createExpertDocs("expertsName", witnessDate, null, "expertises", null, null, null)) + .documentQuestionsApp2(createExpertDocs("expertName", witnessDate, null, null, "other", "question", null)) + .documentAnswersApp2(createExpertDocs("expertName", witnessDate, null, null, "other", null, "answer")) + .documentForDisclosureApp2(createEvidenceDocs("typeDisclosure", witnessDate)) + .documentReferredInStatementApp2(createEvidenceDocs("typeReferred", witnessDate)) + .documentEvidenceForTrialApp2(createEvidenceDocs("typeForTrial", witnessDate)) + .documentDisclosureListApp2(createEvidenceDocs(null, null)) + .documentCaseSummaryApp2(createEvidenceDocs(null, null)) + .documentSkeletonArgumentApp2(createEvidenceDocs(null, null)) + .documentAuthoritiesApp2(createEvidenceDocs(null, null)) + .documentCostsApp2(createEvidenceDocs(null, null)) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); + + // When handle is called + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); + + // Then applicant docs should have name changed + assertThat(updatedData.getDocumentWitnessSummaryApp2().get(0).getValue() + .getWitnessOptionDocument().getDocumentFileName()).isEqualTo("Witness Summary of appTwoWitness.pdf"); + assertThat(updatedData.getDocumentWitnessStatementApp2().get(0).getValue() + .getWitnessOptionDocument().getDocumentFileName()).isEqualTo("Witness Statement of appTwoWitness 10-02-2023.pdf"); + assertThat(updatedData.getDocumentHearsayNoticeApp2().get(0).getValue() + .getWitnessOptionDocument().getDocumentFileName()).isEqualTo("Hearsay evidence appTwoWitness 10-02-2023.pdf"); + assertThat(updatedData.getDocumentExpertReportApp2().get(0).getValue() + .getExpertDocument().getDocumentFileName()).isEqualTo("Experts report expertName expertise 10-02-2023.pdf"); + assertThat(updatedData.getDocumentJointStatementApp2().get(0).getValue() + .getExpertDocument().getDocumentFileName()).isEqualTo("Joint report expertsName expertises 10-02-2023.pdf"); + assertThat(updatedData.getDocumentQuestionsApp2().get(0).getValue() + .getExpertDocument().getDocumentFileName()).isEqualTo("expertName other question.pdf"); + assertThat(updatedData.getDocumentAnswersApp2().get(0).getValue() + .getExpertDocument().getDocumentFileName()).isEqualTo("expertName other answer.pdf"); + assertThat(updatedData.getDocumentForDisclosureApp2().get(0).getValue() + .getDocumentUpload().getDocumentFileName()).isEqualTo("Document for disclosure typeDisclosure 10-02-2023.pdf"); + assertThat(updatedData.getDocumentReferredInStatementApp2().get(0).getValue() + .getDocumentUpload().getDocumentFileName()).isEqualTo("Referred Document typeReferred 10-02-2023.pdf"); + assertThat(updatedData.getDocumentEvidenceForTrialApp2().get(0).getValue() + .getDocumentUpload().getDocumentFileName()).isEqualTo("Documentary Evidence typeForTrial 10-02-2023.pdf"); + assertThat(updatedData.getDocumentDisclosureListApp2().get(0).getValue() + .getDocumentUpload().getDocumentFileName()).isEqualTo(TEST_FILE_NAME); + assertThat(updatedData.getDocumentCaseSummaryApp2().get(0).getValue() + .getDocumentUpload().getDocumentFileName()).isEqualTo(TEST_FILE_NAME); + assertThat(updatedData.getDocumentSkeletonArgumentApp2().get(0).getValue() + .getDocumentUpload().getDocumentFileName()).isEqualTo(TEST_FILE_NAME); + assertThat(updatedData.getDocumentAuthoritiesApp2().get(0).getValue() + .getDocumentUpload().getDocumentFileName()).isEqualTo(TEST_FILE_NAME); + assertThat(updatedData.getDocumentCostsApp2().get(0).getValue() + .getDocumentUpload().getDocumentFileName()).isEqualTo(TEST_FILE_NAME); + assertThat(updatedData.getNotificationText()).isEqualTo(NotificationWhenClaimantTwo); + } + + @Test + void shouldNotAddSameNotificationIfAlreadyAdded_notificationText() { + // If we populate notification string with an entry, we do not want to duplicate that on further uploads of same type. + List options = List.of(EvidenceUploadHandlerBase.OPTION_APP1, + EvidenceUploadHandlerBase.OPTION_APP2, + EvidenceUploadHandlerBase.OPTION_APP_BOTH); + LocalDate witnessDate = LocalDate.of(2023, 2, 10); + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() + .notificationText("Documentation that has been uploaded: \n\n Claimant 1 - Joint Statement of Experts / Single Joint Expert Report \n") + .applicant1(PartyBuilder.builder().individual().build()) + .evidenceUploadOptions(DynamicList.fromList(options, Object::toString, options.get(0), false)) + .documentJointStatement(createExpertDocs("expertsName", witnessDate, null, "expertises", null, null, null)) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); + given(coreCaseDataService.getCase(anyLong())).willReturn(CaseDetails.builder().build()); + // When handle is called + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); + // Then Notificcation should not have a duplicate entry + assertThat(updatedData.getNotificationText()) + .isEqualTo("Documentation that has been uploaded: \n\n Claimant 1 - Joint Statement of Experts / Single Joint Expert Report \n"); + } + + @Test + void shouldNotPopulateNotificationWithOldDocument_whenNewDocumentUploadAdded() { + // When evidence upload is retriggered we do not send a notification for old content i.e uploaded before midnight of current day + List options = List.of(EvidenceUploadHandlerBase.OPTION_APP1, + EvidenceUploadHandlerBase.OPTION_APP2, + EvidenceUploadHandlerBase.OPTION_APP_BOTH); + LocalDate witnessDate = LocalDate.of(2023, 2, 10); + String witnessName = "Witness"; + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() + .notificationText(null) + .evidenceUploadOptions(DynamicList.fromList(options, Object::toString, options.get(0), false)) + .documentWitnessStatement(createWitnessDocs(witnessName, LocalDateTime.now().minusDays(2), witnessDate)) + .documentWitnessSummary(createWitnessDocs(witnessName, LocalDateTime.now(), witnessDate)) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); + given(coreCaseDataService.getCase(anyLong())).willReturn(CaseDetails.builder().build()); + // When handle is called + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); + // Then Notification should not have old entry (witness statement) + assertThat(updatedData.getNotificationText()).isEqualTo("\nClaimant 1 - Witness summary"); + } + private List> createEvidenceDocs(String type, LocalDate issuedDate) { Document document = Document.builder().documentBinaryUrl( TEST_URL) diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandlerTest.java index 82478e5d0af..455cd043a2e 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandlerTest.java @@ -111,7 +111,32 @@ class EvidenceUploadRespondentHandlerTest extends BaseCallbackHandlerTest { private final UploadEvidenceExpert uploadEvidenceDate = new UploadEvidenceExpert(); private final UploadEvidenceWitness uploadEvidenceDate2 = new UploadEvidenceWitness(); private final UploadEvidenceDocumentType uploadEvidenceDate3 = new UploadEvidenceDocumentType(); - + private static final String NotificationWhenBothDefendant = "\n" + + "Both defendants - Disclosure list\n" + + "Both defendants - Documents for disclosure\n" + + "Both defendants - Documents referred to in the statement\n" + + "Both defendants - Expert's report\n" + + "Both defendants - Joint Statement of Experts / Single Joint Expert Report\n" + + "Both defendants - Questions for other party's expert or joint experts\n" + + "Both defendants - Answer to questions asked\n" + + "Both defendants - Case Summary\n" + + "Both defendants - Skeleton argument\n" + + "Both defendants - Authorities\n" + + "Both defendants - Costs\n" + + "Both defendants - Documentary evidence for trial"; + private static final String NotificationWhenDefendantTwo = "\n" + + "Defendant 2 - Disclosure list\n" + + "Defendant 2 - Documents for disclosure\n" + + "Defendant 2 - Documents referred to in the statement\n" + + "Defendant 2 - Expert's report\n" + + "Defendant 2 - Joint Statement of Experts / Single Joint Expert Report\n" + + "Defendant 2 - Questions for other party's expert or joint experts\n" + + "Defendant 2 - Answer to questions asked\n" + + "Defendant 2 - Case Summary\n" + + "Defendant 2 - Skeleton argument\n" + + "Defendant 2 - Authorities\n" + + "Defendant 2 - Costs\n" + + "Defendant 2 - Documentary evidence for trial"; private static final String PAGE_ID = "validateValuesRespondent"; @BeforeEach @@ -123,6 +148,7 @@ void setup() { void givenAboutToStart_assignCaseProgAllocatedTrackUnSpec() { // Given CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build().toBuilder() + .notificationText("NULLED") .claimType(ClaimType.CLINICAL_NEGLIGENCE) .claimValue(ClaimValue.builder() .statementOfValueInPennies(BigDecimal.valueOf(5000)) @@ -136,12 +162,14 @@ void givenAboutToStart_assignCaseProgAllocatedTrackUnSpec() { .handle(params); // Then assertThat(response.getData()).extracting("caseProgAllocatedTrack").isEqualTo("SMALL_CLAIM"); + assertThat(response.getData()).extracting("notificationText").isNull(); } @Test void givenAboutToStart_assignCaseProgAllocatedTrackSpec() { // Given CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build().toBuilder() + .notificationText(null) .claimType(null) .totalClaimAmount(BigDecimal.valueOf(12500)) .build(); @@ -153,12 +181,14 @@ void givenAboutToStart_assignCaseProgAllocatedTrackSpec() { .handle(params); // Then assertThat(response.getData()).extracting("caseProgAllocatedTrack").isEqualTo("FAST_CLAIM"); + assertThat(response.getData()).extracting("notificationText").isNull(); } @Test void givenAboutToStart_1v2SameSolicitor_shouldShowOptions() { // Given CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build().toBuilder() + .notificationText("existing notification") .claimType(null) .totalClaimAmount(BigDecimal.valueOf(12500)) .addRespondent2(YES) @@ -172,6 +202,7 @@ void givenAboutToStart_1v2SameSolicitor_shouldShowOptions() { .handle(params); // Then assertThat(response.getData()).extracting("evidenceUploadOptions").isNotNull(); + assertThat(response.getData()).extracting("notificationText").isEqualTo("existing notification"); } @ParameterizedTest @@ -997,7 +1028,8 @@ void shouldAssignCategoryID_whenDocumentExistsTwoRespondentSpec() { "testBinUrl", "A Fancy Name", "hash", null); var documentUpload = UploadEvidenceDocumentType.builder() - .documentIssuedDate(LocalDate.of(2023, 2, 10)) + .documentIssuedDate(LocalDate.of(2022, 2, 10)) + .createdDatetime(LocalDateTime.of(2022, 05, 10, 12, 13, 12)) .documentUpload(testDocument).build(); List> documentList = new ArrayList<>(); documentList.add(Element.builder().value(documentUpload).build()); @@ -1023,7 +1055,8 @@ void shouldAssignCategoryID_whenDocumentExistsTwoRespondentUnSpec() { "testBinUrl", "A Fancy Name", "hash", null); var documentUpload = UploadEvidenceDocumentType.builder() - .documentIssuedDate(LocalDate.of(2023, 2, 10)) + .documentIssuedDate(LocalDate.of(2022, 2, 10)) + .createdDatetime(LocalDateTime.of(2022, 05, 10, 12, 13, 12)) .documentUpload(testDocument).build(); List> documentList = new ArrayList<>(); documentList.add(Element.builder().value(documentUpload).build()); @@ -1048,7 +1081,10 @@ void shouldAssignCategoryID_whenDocumentExistsOneRespondentSpec() { Document testDocument = new Document("testurl", "testBinUrl", "A Fancy Name", "hash", null); - var documentUpload = UploadEvidenceExpert.builder().expertDocument(testDocument).build(); + var documentUpload = UploadEvidenceExpert.builder() + .expertDocument(testDocument) + .createdDatetime(LocalDateTime.of(2022, 05, 10, 12, 13, 12)) + .build(); List> documentList = new ArrayList<>(); documentList.add(Element.builder().value(documentUpload).build()); // Given @@ -1073,7 +1109,10 @@ void shouldAssignCategoryID_whenDocumentExistsOneRespondentUnSpec() { Document testDocument = new Document("testurl", "testBinUrl", "A Fancy Name", "hash", null); - var documentUpload = UploadEvidenceExpert.builder().expertDocument(testDocument).build(); + var documentUpload = UploadEvidenceExpert.builder() + .expertDocument(testDocument) + .createdDatetime(LocalDateTime.of(2022, 05, 10, 12, 13, 12)) + .build(); List> documentList = new ArrayList<>(); documentList.add(Element.builder().value(documentUpload).build()); // Given @@ -1273,7 +1312,6 @@ void shouldBreakWhenThereIsAnyCaseBundlesWithNullCreatedDate() { @CsvSource({"0", "2"}) void should_do_naming_convention_resp1(String selected) { LocalDateTime createdDate = LocalDateTime.of(2022, 05, 10, 12, 13, 12); - List> witnessEvidenceDocs = new ArrayList<>(); String witnessName = "ResOneWitness"; List options = List.of(EvidenceUploadHandlerBase.OPTION_DEF1, @@ -1414,6 +1452,7 @@ void should_do_naming_convention_resp1(String selected) { .getDocumentUpload().getDocumentFileName()).isEqualTo(TEST_FILE_NAME); assertThat(updatedData.getDocumentCostsRes2().get(0).getValue() .getDocumentUpload().getCategoryID()).isEqualTo(EvidenceUploadHandlerBase.RESPONDENT_TWO_ANY_PRECEDENT_H); + assertThat(updatedData.getNotificationText()).contains(NotificationWhenBothDefendant); } } @@ -1484,6 +1523,59 @@ void should_do_naming_convention_resp2() { .getDocumentUpload().getDocumentFileName()).isEqualTo(TEST_FILE_NAME); assertThat(updatedData.getDocumentCostsRes2().get(0).getValue() .getDocumentUpload().getDocumentFileName()).isEqualTo(TEST_FILE_NAME); + assertThat(updatedData.getNotificationText()).isEqualTo(NotificationWhenDefendantTwo); + } + + @Test + void shouldNotAddSameNotificationIfAlreadyAdded_notificationText() { + // If we populate notification string with an entry, we do not want to duplicate that on further uploads of same type. + List options = List.of(EvidenceUploadHandlerBase.OPTION_DEF1, + EvidenceUploadHandlerBase.OPTION_DEF2, + EvidenceUploadHandlerBase.OPTION_DEF_BOTH); + LocalDate witnessDate = LocalDate.of(2023, 2, 10); + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() + .notificationText("Documentation that has been uploaded: \n\n Defendant 1 - Joint Statement of Experts / Single Joint Expert Report \n") + .applicant1(PartyBuilder.builder().individual().build()) + .evidenceUploadOptions(DynamicList.fromList(options, Object::toString, options.get(0), false)) + .documentJointStatementRes(createExpertDocs("expertsName", witnessDate, null, "expertises", null, null, null)) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(true); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); + given(coreCaseDataService.getCase(anyLong())).willReturn(CaseDetails.builder().build()); + // When handle is called + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); + // Then Notificcation should not have a duplicate entry + assertThat(updatedData.getNotificationText()) + .isEqualTo("Documentation that has been uploaded: \n\n Defendant 1 - Joint Statement of Experts / Single Joint Expert Report \n"); + } + + @Test + void shouldNotPopulateNotificationWithOldDocument_whenNewDocumentUploadAdded() { + // When evidence upload is retriggered we do not send a notification for old content i.e uploaded before midnight of current day + List options = List.of(EvidenceUploadHandlerBase.OPTION_DEF1, + EvidenceUploadHandlerBase.OPTION_DEF2, + EvidenceUploadHandlerBase.OPTION_DEF_BOTH); + LocalDate witnessDate = LocalDate.of(2023, 2, 10); + String witnessName = "Witness"; + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() + .notificationText(null) + .evidenceUploadOptions(DynamicList.fromList(options, Object::toString, options.get(0), false)) + .documentWitnessStatementRes(createWitnessDocs(witnessName, LocalDateTime.now().minusDays(2), witnessDate)) + .documentWitnessSummaryRes(createWitnessDocs(witnessName, LocalDateTime.now(), witnessDate)) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(true); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); + given(coreCaseDataService.getCase(anyLong())).willReturn(CaseDetails.builder().build()); + // When handle is called + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); + // Then Notification should not have old entry (witness statement) + assertThat(updatedData.getNotificationText()).isEqualTo("\nDefendant 1 - Witness summary"); } @Test diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/event/EvidenceUploadNotificationEventHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/event/EvidenceUploadNotificationEventHandlerTest.java index e03aa29680d..7d8eccce7bc 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/event/EvidenceUploadNotificationEventHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/event/EvidenceUploadNotificationEventHandlerTest.java @@ -6,6 +6,7 @@ import org.mockito.Mock; import org.springframework.test.context.junit.jupiter.SpringExtension; import uk.gov.hmcts.reform.ccd.client.model.CaseDetails; +import uk.gov.hmcts.reform.ccd.client.model.StartEventResponse; import uk.gov.hmcts.reform.civil.event.EvidenceUploadNotificationEvent; import uk.gov.hmcts.reform.civil.helpers.CaseDetailsConverter; import uk.gov.hmcts.reform.civil.model.CaseData; @@ -18,6 +19,7 @@ import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.EVIDENCE_UPLOAD_CHECK; @ExtendWith(SpringExtension.class) class EvidenceUploadNotificationEventHandlerTest { @@ -43,6 +45,8 @@ void shouldNotifyAllSolicitors() { CaseDetails caseDetails = CaseDetailsBuilder.builder().data(caseData).build(); when(coreCaseDataService.getCase(caseId)).thenReturn(caseDetails); when(caseDetailsConverter.toCaseData(caseDetails)).thenReturn(caseData); + when(coreCaseDataService.startUpdate(caseId.toString(), EVIDENCE_UPLOAD_CHECK)) + .thenReturn(StartEventResponse.builder().caseDetails(caseDetails).build()); EvidenceUploadNotificationEvent event = new EvidenceUploadNotificationEvent(caseId); //when: Evidence upload Notification handler is called handler.sendEvidenceUploadNotification(event); @@ -62,6 +66,8 @@ void shouldContinueRespondentNotificationIfApplicantFailed() { //when: Exception is thrown from applicant notification handler when(coreCaseDataService.getCase(caseId)).thenReturn(caseDetails); when(caseDetailsConverter.toCaseData(caseDetails)).thenReturn(caseData); + when(coreCaseDataService.startUpdate(caseId.toString(), EVIDENCE_UPLOAD_CHECK)) + .thenReturn(StartEventResponse.builder().caseDetails(caseDetails).build()); doThrow(new RuntimeException()).when(applicantNotificationHandler).notifyApplicantEvidenceUpload(caseData); EvidenceUploadNotificationEvent event = new EvidenceUploadNotificationEvent(caseId); handler.sendEvidenceUploadNotification(event); @@ -80,6 +86,8 @@ void shouldContinueRespondent2IfRespondent1Failed() { //when: Exception is thrown for repondent1 notification handler when(coreCaseDataService.getCase(caseId)).thenReturn(caseDetails); when(caseDetailsConverter.toCaseData(caseDetails)).thenReturn(caseData); + when(coreCaseDataService.startUpdate(caseId.toString(), EVIDENCE_UPLOAD_CHECK)) + .thenReturn(StartEventResponse.builder().caseDetails(caseDetails).build()); doThrow(new RuntimeException()).when(respondentNotificationHandler).notifyRespondentEvidenceUpload(caseData, true); EvidenceUploadNotificationEvent event = new EvidenceUploadNotificationEvent(caseId); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/notification/EvidenceUploadApplicantNotificationHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/notification/EvidenceUploadApplicantNotificationHandlerTest.java index f1ebab3128e..8a90e4fbfd0 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/notification/EvidenceUploadApplicantNotificationHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/notification/EvidenceUploadApplicantNotificationHandlerTest.java @@ -19,8 +19,10 @@ import java.util.Map; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; import static uk.gov.hmcts.reform.civil.handler.callback.camunda.notification.NotificationData.CLAIM_REFERENCE_NUMBER; +import static uk.gov.hmcts.reform.civil.handler.callback.camunda.notification.NotificationData.UPLOADED_DOCUMENTS; @SpringBootTest(classes = { EvidenceUploadApplicantNotificationHandler.class, @@ -47,7 +49,9 @@ void setup() { @Test void shouldNotifyApplicantSolicitor_whenInvoked() { //given: case where applicant solicitor has email as applicantsolicitor@example.com - CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build(); + CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build().toBuilder() + .notificationText("example of uploaded documents") + .build(); //when: ApplicantNotificationhandler is called handler.notifyApplicantEvidenceUpload(caseData); //then: email should be sent to applicant solicitor @@ -62,7 +66,8 @@ void shouldNotifyApplicantSolicitor_whenInvoked() { @Test void shouldNotifyApplicantLip_whenInvoked() { //given: case where applicant litigant in person has email as applicant@example.com - CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified() + CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build().toBuilder() + .notificationText("example of uploaded documents") .applicant1Represented(YesOrNo.NO) .applicant1(Party.builder().partyName("Billy").partyEmail("applicant@example.com").build()) .build(); @@ -77,10 +82,41 @@ void shouldNotifyApplicantLip_whenInvoked() { ); } + @Test + void shouldNotNotifyApplicantLip_whenInvokedAndNoNotificationContent() { + //Once emails are sent, we want to null notificationText, so any future emails will not contain past content. + //unable to null directly in EvidenceUploadNotificationEventHandler, so assigned as NULLED. + //given: case where applicant litigant in person has email as applicant@example.com + CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build().builder() + .notificationText("NULLED") + .applicant1Represented(YesOrNo.NO) + .applicant1(Party.builder().partyName("Billy").partyEmail("applicant@example.com").build()) + .build(); + //when: ApplicantNotificationhandler is called + handler.notifyApplicantEvidenceUpload(caseData); + //then: email should be sent to applicant + verifyNoInteractions(notificationService); + } + + @Test + void shouldNotNotifyApplicantLip_whenInvokedAndNoNotificationContentNull() { + //given: case where applicant litigant in person has email as applicant@example.com + CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build().toBuilder() + .notificationText(null) + .applicant1Represented(YesOrNo.NO) + .applicant1(Party.builder().partyName("Billy").partyEmail("applicant@example.com").build()) + .build(); + //when: ApplicantNotificationhandler is called + handler.notifyApplicantEvidenceUpload(caseData); + //then: email should be sent to applicant + verifyNoInteractions(notificationService); + } + @NotNull private Map getNotificationDataMap(CaseData caseData) { return Map.of( - CLAIM_REFERENCE_NUMBER, caseData.getLegacyCaseReference() + CLAIM_REFERENCE_NUMBER, caseData.getLegacyCaseReference(), + UPLOADED_DOCUMENTS, "example of uploaded documents" ); } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/notification/EvidenceUploadRespondentNotificationHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/notification/EvidenceUploadRespondentNotificationHandlerTest.java index 85d39b3c4b4..db5d359d8d4 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/notification/EvidenceUploadRespondentNotificationHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/notification/EvidenceUploadRespondentNotificationHandlerTest.java @@ -19,8 +19,10 @@ import java.util.Map; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; import static uk.gov.hmcts.reform.civil.handler.callback.camunda.notification.NotificationData.CLAIM_REFERENCE_NUMBER; +import static uk.gov.hmcts.reform.civil.handler.callback.camunda.notification.NotificationData.UPLOADED_DOCUMENTS; @SpringBootTest(classes = { EvidenceUploadRespondentNotificationHandler.class, @@ -47,7 +49,9 @@ void setup() { @Test void shouldNotifyRespondent1Solicitor_whenInvoked() { //given: case data has one respondent solicitor - CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build(); + CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build().toBuilder() + .notificationText("example of uploaded documents") + .build();; //when: RepondentNotificationhandler for solictior1 is called handler.notifyRespondentEvidenceUpload(caseData, true); //then: email should be sent to respondent solicitor1 @@ -62,7 +66,8 @@ void shouldNotifyRespondent1Solicitor_whenInvoked() { @Test void shouldNotifyRespondent1Lip_whenInvoked() { //given: case data has one respondent litigant in person - CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified() + CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build().toBuilder() + .notificationText("example of uploaded documents") .respondent1Represented(YesOrNo.NO) .respondent1(Party.builder().partyName("Billy").partyEmail("respondent@example.com").build()) .build(); @@ -81,8 +86,9 @@ void shouldNotifyRespondent1Lip_whenInvoked() { @Test void shouldNotifyRespondent2Solicitor_whenInvoked() { //given: case data has two respondent solicitor - CaseData caseData = CaseDataBuilder.builder() - .atStateClaimDetailsNotified().addRespondent2(YesOrNo.YES) + CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build().toBuilder() + .notificationText("example of uploaded documents") + .addRespondent2(YesOrNo.YES) .respondentSolicitor2EmailAddress("respondentsolicitor2@example.com") .build(); //when: RepondentNotificationhandler for solictior2 is called @@ -99,8 +105,9 @@ void shouldNotifyRespondent2Solicitor_whenInvoked() { @Test void shouldNotifyRespondent2Lip_whenInvoked() { //given: case data has two respondents, with second being litigant in person - CaseData caseData = CaseDataBuilder.builder() - .atStateClaimDetailsNotified().addRespondent2(YesOrNo.YES) + CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build().toBuilder() + .notificationText("example of uploaded documents") + .addRespondent2(YesOrNo.YES) .respondent2Represented(YesOrNo.NO) .respondent2(Party.builder().partyName("Billy").partyEmail("respondent@example.com").build()) .build(); @@ -115,10 +122,37 @@ void shouldNotifyRespondent2Lip_whenInvoked() { ); } + @Test + void shouldNotNotifyRespondent1Solicitor_whenInvokedAndNoNotificationContent() { + //Once emails are sent, we want to null notificationText, so any future emails will not contain past content. + //unable to null directly in EvidenceUploadNotificationEventHandler, so assigned as NULLED. + //given: case data has one respondent solicitor + CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build().toBuilder() + .notificationText("NULLED") + .build(); + //when: RepondentNotificationhandler for solictior1 is called + handler.notifyRespondentEvidenceUpload(caseData, true); + //then: email should be sent to respondent solicitor1 + verifyNoInteractions(notificationService); + } + + @Test + void shouldNotNotifyRespondent1Solicitor_whenInvokedAndNoContentNull() { + //given: case data has one respondent solicitor + CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build().toBuilder() + .notificationText(null) + .build(); + //when: RepondentNotificationhandler for solictior1 is called + handler.notifyRespondentEvidenceUpload(caseData, true); + //then: email should be sent to respondent solicitor1 + verifyNoInteractions(notificationService); + } + @NotNull private Map getNotificationDataMap(CaseData caseData) { return Map.of( - CLAIM_REFERENCE_NUMBER, caseData.getLegacyCaseReference() + CLAIM_REFERENCE_NUMBER, caseData.getLegacyCaseReference(), + UPLOADED_DOCUMENTS, "example of uploaded documents" ); } } From 44a7429e1f1b0d66fd319bea86c7a5aeb7aea146 Mon Sep 17 00:00:00 2001 From: m-meulendijks-v1 <107135537+m-meulendijks-v1@users.noreply.github.com> Date: Wed, 8 Nov 2023 14:49:25 +0000 Subject: [PATCH 12/28] CIV-10918 - removed final order casedocument duplication (#3539) * CIV-10918 - remove final order casedocument duplication * CIV-10918 - remove final order from bundle * CIV-10918 - point PR back to master --- .../GenerateDirectionOrderCallbackHandler.java | 5 ++--- .../helpers/bundle/BundleRequestMapper.java | 4 +--- .../gov/hmcts/reform/civil/model/CaseData.java | 3 ++- ...enerateDirectionOrderCallbackHandlerTest.java | 16 ++++++++-------- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandler.java index b1756291e23..59d211a4604 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandler.java @@ -179,7 +179,7 @@ private CallbackResponse validateFormAndGeneratePreviewDocument(CallbackParams c CaseDocument finalDocument = judgeFinalOrderGenerator.generate( caseData, callbackParams.getParams().get(BEARER_TOKEN).toString()); - caseDataBuilder.finalOrderDocument(finalDocument.getDocumentLink()); + caseDataBuilder.finalOrderDocument(finalDocument); return AboutToStartOrSubmitCallbackResponse.builder() .data(caseDataBuilder.build().toMap(objectMapper)) @@ -405,8 +405,7 @@ private void checkFieldDate(CaseData caseData, List errors) { private CallbackResponse addGeneratedDocumentToCollection(CallbackParams callbackParams) { CaseData caseData = callbackParams.getCaseData(); - CaseDocument finalDocument = judgeFinalOrderGenerator.generate( - caseData, callbackParams.getParams().get(BEARER_TOKEN).toString()); + CaseDocument finalDocument = caseData.getFinalOrderDocument(); List> finalCaseDocuments = new ArrayList<>(); finalCaseDocuments.add(element(finalDocument)); diff --git a/src/main/java/uk/gov/hmcts/reform/civil/helpers/bundle/BundleRequestMapper.java b/src/main/java/uk/gov/hmcts/reform/civil/helpers/bundle/BundleRequestMapper.java index 717887a0472..8267d327903 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/helpers/bundle/BundleRequestMapper.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/helpers/bundle/BundleRequestMapper.java @@ -531,9 +531,7 @@ private List> mapOrdersDocument(CaseData caseDa bundlingRequestDocuments.addAll(mapSystemGeneratedCaseDocument(caseData.getDirectionOrderDocStaff(), BundleFileNameList.ORDER.getDisplayName())); } - if (caseData.getFinalOrderDocument() != null) { - bundlingRequestDocuments.add(buildBundlingRequestDoc(caseData.getFinalOrderDocument().getDocumentFileName(), caseData.getFinalOrderDocument(), "")); - } + return ElementUtils.wrapElements(bundlingRequestDocuments); } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java index 64f19a58e04..5be7112b21d 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java @@ -609,7 +609,8 @@ public boolean hasNoOngoingBusinessProcess() { private final OrderOnCourtsList orderOnCourtsList; private final String freeFormHearingNotes; - private Document finalOrderDocument; + private CaseDocument finalOrderDocument; + @Builder.Default private final List> finalOrderDocumentCollection = new ArrayList<>(); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandlerTest.java index 6c8917b9b9c..e8bb81dee02 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandlerTest.java @@ -760,10 +760,10 @@ void shouldAddDocumentToCollection_onAboutToSubmit() { CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .finalOrderSelection(FinalOrderSelection.ASSISTED_ORDER) .finalOrderDocumentCollection(finalCaseDocuments) + .finalOrderDocument(finalOrder) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); // When - when(judgeFinalOrderGenerator.generate(any(), any())).thenReturn(finalOrder); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); // Then @@ -780,10 +780,10 @@ void shouldChangeStateToFinalOrder_onAboutToSubmitAndFreeFormOrder() { CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .finalOrderSelection(FinalOrderSelection.FREE_FORM_ORDER) .finalOrderDocumentCollection(finalCaseDocuments) + .finalOrderDocument(finalOrder) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); // When - when(judgeFinalOrderGenerator.generate(any(), any())).thenReturn(finalOrder); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // Then assertThat(response.getState()).isEqualTo("All_FINAL_ORDERS_ISSUED"); @@ -798,10 +798,10 @@ void shouldChangeStateToFinalOrder_onAboutToSubmitAndAssistedOrderAndNoFurtherHe .finalOrderSelection(FinalOrderSelection.ASSISTED_ORDER) .finalOrderFurtherHearingToggle(null) .finalOrderDocumentCollection(finalCaseDocuments) + .finalOrderDocument(finalOrder) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); // When - when(judgeFinalOrderGenerator.generate(any(), any())).thenReturn(finalOrder); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // Then assertThat(response.getState()).isEqualTo("All_FINAL_ORDERS_ISSUED"); @@ -818,10 +818,10 @@ void shouldChangeStateToCaseProgression_onAboutToSubmitAndAssistedOrderWithFurth .finalOrderSelection(FinalOrderSelection.ASSISTED_ORDER) .finalOrderFurtherHearingToggle(toggle) .finalOrderDocumentCollection(finalCaseDocuments) + .finalOrderDocument(finalOrder) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); // When - when(judgeFinalOrderGenerator.generate(any(), any())).thenReturn(finalOrder); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // Then assertThat(response.getState()).isEqualTo("CASE_PROGRESSION"); @@ -835,12 +835,12 @@ void shouldRePopulateHearingNotes_whenAssistedHearingNotesExist() { CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .finalOrderSelection(FinalOrderSelection.ASSISTED_ORDER) .finalOrderFurtherHearingToggle(toggle) + .finalOrderDocument(finalOrder) .finalOrderFurtherHearingComplex(FinalOrderFurtherHearing.builder() .hearingNotesText("test text hearing notes assisted order").build()) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); // When - when(judgeFinalOrderGenerator.generate(any(), any())).thenReturn(finalOrder); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // Then assertThat(response.getData()).extracting("hearingNotes").extracting("notes").isEqualTo("test text hearing notes assisted order"); @@ -854,10 +854,10 @@ void shouldRePopulateHearingNotes_whenFreeFormHearingNotesExist() { CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .finalOrderSelection(FinalOrderSelection.FREE_FORM_ORDER) .freeFormHearingNotes("test text hearing notes free form order") + .finalOrderDocument(finalOrder) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); // When - when(judgeFinalOrderGenerator.generate(any(), any())).thenReturn(finalOrder); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // Then assertThat(response.getData()).extracting("hearingNotes").extracting("notes").isEqualTo("test text hearing notes free form order"); @@ -871,11 +871,11 @@ void shouldNotRePopulateHearingNotes_whenAssistedHearingNotesDoNotExist() { CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .finalOrderSelection(FinalOrderSelection.ASSISTED_ORDER) .finalOrderFurtherHearingToggle(toggle) + .finalOrderDocument(finalOrder) .hearingNotes(HearingNotes.builder().notes("preexisting hearing notes").build()) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); // When - when(judgeFinalOrderGenerator.generate(any(), any())).thenReturn(finalOrder); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // Then assertThat(response.getData()).extracting("hearingNotes").extracting("notes").isEqualTo("preexisting hearing notes"); @@ -890,10 +890,10 @@ void shouldNotRePopulateHearingNotes_whenFreeFormHearingNotesDoNotExist() { .finalOrderSelection(FinalOrderSelection.FREE_FORM_ORDER) .finalOrderFurtherHearingToggle(toggle) .hearingNotes(HearingNotes.builder().notes("preexisting hearing notes").build()) + .finalOrderDocument(finalOrder) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); // When - when(judgeFinalOrderGenerator.generate(any(), any())).thenReturn(finalOrder); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // Then assertThat(response.getData()).extracting("hearingNotes").extracting("notes").isEqualTo("preexisting hearing notes"); From 02031813572fa99e8ed75b28b5e4c70d6b14248e Mon Sep 17 00:00:00 2001 From: mounikahmcts <43175082+mounikahmcts@users.noreply.github.com> Date: Wed, 8 Nov 2023 15:31:53 +0000 Subject: [PATCH 13/28] CIV-0000 Nightly dev (#3535) * Update build.gradle * Update Jenkinsfile_nightly * Update build.gradle --- Jenkinsfile_nightly | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Jenkinsfile_nightly b/Jenkinsfile_nightly index f884081495b..4f66e24d074 100644 --- a/Jenkinsfile_nightly +++ b/Jenkinsfile_nightly @@ -14,6 +14,8 @@ properties([ description: 'The URL of service auth provider'), string(name: 'CCD_DATA_STORE_URL', defaultValue: 'http://ccd-data-store-api-aat.service.core-compute-aat.internal', description: 'The URL of ccd data store'), + string(name: 'AAC_API_URL', defaultValue: 'http://aac-manage-case-assignment-aat.service.core-compute-aat.internal', + description: 'The URL of AAC service'), string(name: 'CIVIL_SERVICE_URL', defaultValue: 'http://civil-service-aat.service.core-compute-aat.internal', description: 'The URL of civil service'), string(name: 'WAIT_FOR_TIMEOUT_MS', @@ -60,6 +62,7 @@ withNightlyPipeline(type, product, component) { env.URL_FOR_SECURITY_SCAN = params.CIVIL_SERVICE_URL env.TESTS_FOR_ACCESSIBILITY = true env.NIGHTLY_RUN = true + env.AAC_API_URL = params.AAC_API_URL overrideVaultEnvironments([ 'aat': params.ENVIRONMENT ]) From c8f01e6092ed6049c6905e990213e4538c8cbdd7 Mon Sep 17 00:00:00 2001 From: m-meulendijks-v1 <107135537+m-meulendijks-v1@users.noreply.github.com> Date: Thu, 9 Nov 2023 08:50:28 +0000 Subject: [PATCH 14/28] CIV-10918 - Performance upgrade for Case Progression classes (#3389) * CIV-9406 LiP roles added to the checks * CIV-9406 New tests added * CIV-9406 Pre-release version of civil-commons added to allow further development of the feature * CIV-9406 User role added to indicate who owns the trial ready document and tests updated * CIV-9406 A new field added to hold the user role used to populate ownedBy in system generated CaseDocument * CIV-9406 Trial Ready document owner assigned using information retrived from case data. * CIV-9406 Tests updated and new added * CIV-9406 Code refactore to avoid unnecessary calls to user services and tests updated * Revert "CIV-9406 Code refactore to avoid unnecessary calls to user services and tests updated" This reverts commit 55ab65f6e00d4a36a1974e1efe6d0257faacec2e. * CIV-9406 Code refactored to limit number of calls to user service * CIV-9406 Tests updated after code refactoring * CIV-9406 Unused import removed * CIV-9406 - Use caching to cache user role for logged in user. * CIV-9406 - Use caching to cache user role for logged in user - checkstyle fixes * CIV-9406 - Use caching to cache user role for logged in user - checkstyle fixes * CIV-9406 - Use caching to cache user role for logged in user - checkstyle fixes * CIV-9406 - Use caching to cache user role for logged in user - checkstyle fixes * CIV-9406 - Use caching to cache user role for logged in user - add test * CIV-9406 - Use caching to cache user role for logged in user - checkstyle fixes * CIV-9406 - Use caching to cache user role for logged in user * CIV-10231 Update Application Type Name (#3264) * CIV-10231 Update Application Type Name * CIV-10231 Fix GA appln type --------- Co-authored-by: vasudevganesanhmcts <100689363+vasudevganesanhmcts@users.noreply.github.com> * CIV-9406 - Use caching to cache user role for logged in user - adding cache evict * CIV-9406 Code refactored to remove commented out code and solve problems indicated by SonarLint * CIV-9406 Update of the pre-release of civil-commons version. * CIV-9406 No longer needed field removed * CIV-9406 Code refactoring to remove commented out code and remove problems indicated by SonarLint * CIV-9406 Tests fixed after changes to main code * CIV-9406 Missing hash character added * CIV-10918 - Increase performance for CP handlers * Update HearingScheduledHandler.java * Update the common version * Change commons released version * Commons version * Fixed timezone issue * changed draft release version * update civil commons * Update RespondToClaimCuiCallbackHandler * FIX CVE ISSUE * fix unit tests * remove extra logs * CIV-10918 sonar code smell * CIV-10918 cve CVE-2023-5072 * CIV-10918 cve CVE-2023-5072 * CIV-10918 cve CVE-2023-44487 * CIV-10918 - added smaller keyToken and reduced caching time * CIV-10918 - added caching to application + controller * CIV-10918 - remove unnecessary log * CIV-10918 - removed unused import * CIV-10918 - updated trial readiness tests without user services * CIV-10918 - Updated GA caching * Update InitiateGeneralApplicationServiceHelper.java * CIV-10918 - user role caching * CIV-10918 - fixed master final order tests * CIV-10918 - updated master tests to match my changes * CIV-10918 - add checkstyle fix * Remove userCacheManager resource --------- Co-authored-by: Maciej Modzelewski Co-authored-by: Maciej Modzelewski <18092228+maciejmodzelewski@users.noreply.github.com> Co-authored-by: KumarSam Co-authored-by: karthick mohanasundaram <92928238+karthick-mohanasundaram-HMCTS@users.noreply.github.com> Co-authored-by: vasudevganesanhmcts <100689363+vasudevganesanhmcts@users.noreply.github.com> Co-authored-by: pats-john <13101669+pats-john@users.noreply.github.com> Co-authored-by: sankhajuria Co-authored-by: Mark Drummond Co-authored-by: pliao-hmcts <113367232+pliao-hmcts@users.noreply.github.com> Co-authored-by: Pijian Liao --- .../gov/hmcts/reform/civil/Application.java | 3 + .../user/EvidenceUploadApplicantHandler.java | 12 +- .../user/EvidenceUploadHandlerBase.java | 176 ++++++++++++------ .../user/EvidenceUploadRespondentHandler.java | 14 +- .../user/HearingScheduledHandler.java | 1 - .../user/TrialReadinessCallbackHandler.java | 43 ++--- .../InitiateGeneralApplicationService.java | 3 +- ...itiateGeneralApplicationServiceHelper.java | 3 +- .../reform/civil/utils/UserRoleCaching.java | 23 ++- .../EvidenceUploadApplicantHandlerTest.java | 53 ++---- .../EvidenceUploadRespondentHandlerTest.java | 104 ++++------- .../TrialReadinessCallbackHandlerTest.java | 106 +++++++---- ...InitiateGeneralApplicationServiceTest.java | 12 +- .../civil/utils/UserRoleCachingTest.java | 42 +++++ 14 files changed, 349 insertions(+), 246 deletions(-) create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/utils/UserRoleCachingTest.java diff --git a/src/main/java/uk/gov/hmcts/reform/civil/Application.java b/src/main/java/uk/gov/hmcts/reform/civil/Application.java index 4fed58056f7..7f27bb76741 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/Application.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/Application.java @@ -3,6 +3,7 @@ import org.camunda.bpm.extension.rest.EnableCamundaRestClient; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cache.annotation.EnableCaching; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication @@ -17,6 +18,8 @@ "uk.gov.hmcts.reform.civil.crd", "uk.gov.hmcts.reform.hmc" }) + +@EnableCaching @SuppressWarnings("HideUtilityClassConstructor") // Spring needs a constructor, its not a utility class public class Application { diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandler.java index 2f1c783db93..7f2ef1da220 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandler.java @@ -22,27 +22,25 @@ import uk.gov.hmcts.reform.civil.model.caseprogression.UploadEvidenceDocumentType; import uk.gov.hmcts.reform.civil.model.common.Element; import uk.gov.hmcts.reform.civil.service.CoreCaseDataService; -import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; import uk.gov.hmcts.reform.civil.service.Time; -import uk.gov.hmcts.reform.civil.service.UserService; -import uk.gov.hmcts.reform.idam.client.models.UserInfo; +import uk.gov.hmcts.reform.civil.utils.UserRoleCaching; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.EVIDENCE_UPLOAD_APPLICANT; @Service public class EvidenceUploadApplicantHandler extends EvidenceUploadHandlerBase { - public EvidenceUploadApplicantHandler(UserService userService, CoreCaseUserService coreCaseUserService, - CaseDetailsConverter caseDetailsConverter, + public EvidenceUploadApplicantHandler(CaseDetailsConverter caseDetailsConverter, CoreCaseDataService coreCaseDataService, + UserRoleCaching userRoleCaching, ObjectMapper objectMapper, Time time) { - super(userService, coreCaseUserService, caseDetailsConverter, coreCaseDataService, + super(caseDetailsConverter, coreCaseDataService, userRoleCaching, objectMapper, time, Collections.singletonList(EVIDENCE_UPLOAD_APPLICANT), "validateValuesApplicant", "createShowCondition"); } @Override - CallbackResponse createShowCondition(CaseData caseData, UserInfo userInfo) { + CallbackResponse createShowCondition(CaseData caseData, List userRoles) { CaseData.CaseDataBuilder caseDataBuilder = caseData.toBuilder(); //For case which are 1v1, 2v1 we show respondent fields for documents to be uploaded, //if a case is 1v2 and different solicitors we want to show separate fields for each respondent solicitor i.e. diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadHandlerBase.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadHandlerBase.java index e69ffd03ba7..c850f6b8bd4 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadHandlerBase.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadHandlerBase.java @@ -39,11 +39,9 @@ import uk.gov.hmcts.reform.civil.model.common.Element; import uk.gov.hmcts.reform.civil.documentmanagement.model.Document; import uk.gov.hmcts.reform.civil.service.CoreCaseDataService; -import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; import uk.gov.hmcts.reform.civil.service.Time; -import uk.gov.hmcts.reform.civil.service.UserService; import uk.gov.hmcts.reform.civil.utils.ElementUtils; -import uk.gov.hmcts.reform.idam.client.models.UserInfo; +import uk.gov.hmcts.reform.civil.utils.UserRoleCaching; import static java.lang.String.format; import static java.util.Objects.nonNull; @@ -57,6 +55,7 @@ import static uk.gov.hmcts.reform.civil.enums.AllocatedTrack.getAllocatedTrack; import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORONE; import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORTWO; +import static uk.gov.hmcts.reform.civil.utils.UserRoleUtils.isRespondentSolicitorTwo; abstract class EvidenceUploadHandlerBase extends CallbackHandler { @@ -65,11 +64,11 @@ abstract class EvidenceUploadHandlerBase extends CallbackHandler { private final String createShowCondition; protected final ObjectMapper objectMapper; private final Time time; - private final CoreCaseUserService coreCaseUserService; - private final UserService userService; private final CaseDetailsConverter caseDetailsConverter; private final CoreCaseDataService coreCaseDataService; + private final UserRoleCaching userRoleCaching; + private static final String SPACE = " "; private static final String END = "."; private static final String DATE_FORMAT = "dd-MM-yyyy"; @@ -164,9 +163,8 @@ abstract class EvidenceUploadHandlerBase extends CallbackHandler { private static final String SELECTED_VALUE_DEF_BOTH = "RESPONDENTBOTH"; private static final String SELECTED_VALUE_APP_BOTH = "APPLICANTBOTH"; - protected EvidenceUploadHandlerBase(UserService userService, CoreCaseUserService coreCaseUserService, - CaseDetailsConverter caseDetailsConverter, - CoreCaseDataService coreCaseDataService, + protected EvidenceUploadHandlerBase(CaseDetailsConverter caseDetailsConverter, + CoreCaseDataService coreCaseDataService, UserRoleCaching userRoleCaching, ObjectMapper objectMapper, Time time, List events, String pageId, String createShowCondition) { this.objectMapper = objectMapper; @@ -174,15 +172,14 @@ protected EvidenceUploadHandlerBase(UserService userService, CoreCaseUserService this.createShowCondition = createShowCondition; this.events = events; this.pageId = pageId; - this.coreCaseUserService = coreCaseUserService; - this.userService = userService; + this.userRoleCaching = userRoleCaching; this.caseDetailsConverter = caseDetailsConverter; this.coreCaseDataService = coreCaseDataService; } abstract CallbackResponse validateValues(CallbackParams callbackParams, CaseData caseData); - abstract CallbackResponse createShowCondition(CaseData caseData, UserInfo userInfo); + abstract CallbackResponse createShowCondition(CaseData caseData, List userRoles); abstract void applyDocumentUploadDate(CaseData.CaseDataBuilder caseDataBuilder, LocalDateTime now); @@ -237,16 +234,20 @@ CallbackResponse setOptions(CallbackParams callbackParams) { } CallbackResponse createShow(CallbackParams callbackParams) { - UserInfo userInfo = userService.getUserInfo(callbackParams.getParams().get(BEARER_TOKEN).toString()); + CaseData caseData = callbackParams.getCaseData(); + String bearerToken = callbackParams.getParams().get(BEARER_TOKEN).toString(); + String ccdCaseRef = callbackParams.getCaseData().getCcdCaseReference().toString(); + String keyToken = userRoleCaching.getCacheKeyToken(bearerToken); + List userRoles = userRoleCaching.getUserRoles(bearerToken, ccdCaseRef, keyToken); - return createShowCondition(callbackParams.getCaseData(), userInfo); + return createShowCondition(callbackParams.getCaseData(), userRoles); } // CCD has limited show hide functionality, we want to show a field based on a fixed listed containing an element, // or a second list containing an element, AND with the addition of the user being respondent2 solicitor, the below // combines the list condition into one single condition, which can then be used in CCD along with the // caseTypeFlag condition - CallbackResponse showCondition(CaseData caseData, UserInfo userInfo, + CallbackResponse showCondition(CaseData caseData, List userRoles, List witnessStatementFastTrack, List witnessStatementSmallTrack, List witnessSummaryFastTrack, @@ -275,24 +276,11 @@ CallbackResponse showCondition(CaseData caseData, UserInfo userInfo, boolean multiParts = Objects.nonNull(caseData.getEvidenceUploadOptions()) && !caseData.getEvidenceUploadOptions().getListItems().isEmpty(); - if (events.get(0).equals(EVIDENCE_UPLOAD_APPLICANT)) { - //2v1, app2 selected - if (multiParts - && caseData.getEvidenceUploadOptions() - .getValue().getLabel().startsWith(OPTION_APP2)) { - caseDataBuilder.caseTypeFlag("ApplicantTwoFields"); - } - } else if (events.get(0).equals(EVIDENCE_UPLOAD_RESPONDENT)) { + if (isApplicantTwoFields(multiParts, caseData)) { + caseDataBuilder.caseTypeFlag("ApplicantTwoFields"); + } else if (isRespondentTwoFields(multiParts, caseData, userRoles)) { //1v2 same sol, def2 selected - if ((multiParts - && caseData.getEvidenceUploadOptions() - .getValue().getLabel().startsWith(OPTION_DEF2)) - //1v2 dif sol, log in as def2 - || (!multiParts && Objects.nonNull(caseData.getCcdCaseReference()) - && coreCaseUserService.userHasCaseRole(caseData.getCcdCaseReference() - .toString(), userInfo.getUid(), RESPONDENTSOLICITORTWO))) { - caseDataBuilder.caseTypeFlag("RespondentTwoFields"); - } + caseDataBuilder.caseTypeFlag("RespondentTwoFields"); } // clears the flag, as otherwise if the user returns to previous screen and unselects an option, @@ -309,36 +297,28 @@ CallbackResponse showCondition(CaseData caseData, UserInfo userInfo, // Based on claim type being fast track or small claims, there will be two different lists to select from // for either list we then want to display a (same) document upload field corresponding, // below combines what would have been two separate show conditions in CCD, into a single flag - if (nonNull(witnessStatementFastTrack) && witnessStatementFastTrack.contains(EvidenceUploadWitness.WITNESS_STATEMENT) - || nonNull(witnessStatementSmallTrack) && witnessStatementSmallTrack.contains(EvidenceUploadWitness.WITNESS_STATEMENT)) { + if (isWitnessStatementFlag(witnessStatementFastTrack, witnessStatementSmallTrack)) { caseDataBuilder.witnessStatementFlag("show_witness_statement"); } - if (nonNull(witnessSummaryFastTrack) && witnessSummaryFastTrack.contains(EvidenceUploadWitness.WITNESS_SUMMARY) - || nonNull(witnessSummarySmallTrack) && witnessSummarySmallTrack.contains(EvidenceUploadWitness.WITNESS_SUMMARY)) { + if (showWitnessSummary(witnessSummaryFastTrack, witnessSummarySmallTrack)) { caseDataBuilder.witnessSummaryFlag("show_witness_summary"); } - if (nonNull(witnessReferredFastTrack) && witnessReferredFastTrack.contains(EvidenceUploadWitness.DOCUMENTS_REFERRED) - || nonNull(witnessReferredSmallTrack) && witnessReferredSmallTrack.contains(EvidenceUploadWitness.DOCUMENTS_REFERRED)) { + if (showWitnessReferred(witnessReferredFastTrack, witnessReferredSmallTrack)) { caseDataBuilder.witnessReferredStatementFlag("show_witness_referred"); } - if (nonNull(expertReportFastTrack) && expertReportFastTrack.contains(EvidenceUploadExpert.EXPERT_REPORT) - || nonNull(expertReportSmallTrack) && expertReportSmallTrack.contains(EvidenceUploadExpert.EXPERT_REPORT)) { + if (showExpertReport(expertReportFastTrack, expertReportSmallTrack)) { caseDataBuilder.expertReportFlag("show_expert_report"); } - if (nonNull(expertJointFastTrack) && expertJointFastTrack.contains(EvidenceUploadExpert.JOINT_STATEMENT) - || nonNull(expertJointSmallTrack) && expertJointSmallTrack.contains(EvidenceUploadExpert.JOINT_STATEMENT)) { + if (showJointExpert(expertJointFastTrack, expertJointSmallTrack)) { caseDataBuilder.expertJointFlag("show_joint_expert"); } - if (nonNull(trialAuthorityFastTrack) && trialAuthorityFastTrack.contains(EvidenceUploadTrial.AUTHORITIES) - || nonNull(trialAuthoritySmallTrack) && trialAuthoritySmallTrack.contains(EvidenceUploadTrial.AUTHORITIES)) { + if (showTrialAuthority(trialAuthorityFastTrack, trialAuthoritySmallTrack)) { caseDataBuilder.trialAuthorityFlag("show_trial_authority"); } - if (nonNull(trialCostsFastTrack) && trialCostsFastTrack.contains(EvidenceUploadTrial.COSTS) - || nonNull(trialCostsSmallTrack) && trialCostsSmallTrack.contains(EvidenceUploadTrial.COSTS)) { + if (showTrialCosts(trialCostsFastTrack, trialCostsSmallTrack)) { caseDataBuilder.trialCostsFlag("show_trial_costs"); } - if (nonNull(trialDocumentaryFastTrack) && trialDocumentaryFastTrack.contains(EvidenceUploadTrial.DOCUMENTARY) - || nonNull(trialDocumentarySmallTrack) && trialDocumentarySmallTrack.contains(EvidenceUploadTrial.DOCUMENTARY)) { + if (showTrialDocumentary(trialDocumentaryFastTrack, trialDocumentarySmallTrack)) { caseDataBuilder.trialDocumentaryFlag("show_trial_documentary"); } @@ -347,6 +327,89 @@ CallbackResponse showCondition(CaseData caseData, UserInfo userInfo, .build(); } + private boolean isApplicantTwoFields(boolean multiParts, + CaseData caseData) { + //2v1, app2 selected + return events.get(0).equals(EVIDENCE_UPLOAD_APPLICANT) && (multiParts + && caseData.getEvidenceUploadOptions() + .getValue().getLabel().startsWith(OPTION_APP2)); + } + + private boolean isRespondentTwoFields(boolean multiParts, + CaseData caseData, + List userRoles) { + //1v2 dif sol, log in as def2 + return events.get(0).equals(EVIDENCE_UPLOAD_RESPONDENT) && ((multiParts + && caseData.getEvidenceUploadOptions() + .getValue().getLabel().startsWith(OPTION_DEF2)) + || (!multiParts && Objects.nonNull(caseData.getCcdCaseReference()) + && isRespondentSolicitorTwo(userRoles))); + } + + private boolean isWitnessStatementFlag(List witnessStatementFastTrack, + List witnessStatementSmallTrack) { + return nonNull(witnessStatementFastTrack) + && witnessStatementFastTrack.contains(EvidenceUploadWitness.WITNESS_STATEMENT) + || nonNull(witnessStatementSmallTrack) + && witnessStatementSmallTrack.contains(EvidenceUploadWitness.WITNESS_STATEMENT); + } + + private boolean showWitnessSummary(List witnessSummaryFastTrack, + List witnessSummarySmallTrack) { + return nonNull(witnessSummaryFastTrack) + && witnessSummaryFastTrack.contains(EvidenceUploadWitness.WITNESS_SUMMARY) + || nonNull(witnessSummarySmallTrack) + && witnessSummarySmallTrack.contains(EvidenceUploadWitness.WITNESS_SUMMARY); + } + + private boolean showWitnessReferred(List witnessReferredFastTrack, + List witnessReferredSmallTrack) { + return nonNull(witnessReferredFastTrack) + && witnessReferredFastTrack.contains(EvidenceUploadWitness.DOCUMENTS_REFERRED) + || nonNull(witnessReferredSmallTrack) + && witnessReferredSmallTrack.contains(EvidenceUploadWitness.DOCUMENTS_REFERRED); + } + + private boolean showExpertReport(List expertReportFastTrack, + List expertReportSmallTrack) { + return nonNull(expertReportFastTrack) + && expertReportFastTrack.contains(EvidenceUploadExpert.EXPERT_REPORT) + || nonNull(expertReportSmallTrack) + && expertReportSmallTrack.contains(EvidenceUploadExpert.EXPERT_REPORT); + } + + private boolean showJointExpert(List expertJointFastTrack, + List expertJointSmallTrack) { + return nonNull(expertJointFastTrack) + && expertJointFastTrack.contains(EvidenceUploadExpert.JOINT_STATEMENT) + || nonNull(expertJointSmallTrack) + && expertJointSmallTrack.contains(EvidenceUploadExpert.JOINT_STATEMENT); + } + + private boolean showTrialAuthority(List trialAuthorityFastTrack, + List trialAuthoritySmallTrack) { + return nonNull(trialAuthorityFastTrack) + && trialAuthorityFastTrack.contains(EvidenceUploadTrial.AUTHORITIES) + || nonNull(trialAuthoritySmallTrack) + && trialAuthoritySmallTrack.contains(EvidenceUploadTrial.AUTHORITIES); + } + + private boolean showTrialCosts(List trialCostsFastTrack, + List trialCostsSmallTrack) { + return nonNull(trialCostsFastTrack) + && trialCostsFastTrack.contains(EvidenceUploadTrial.COSTS) + || nonNull(trialCostsSmallTrack) + && trialCostsSmallTrack.contains(EvidenceUploadTrial.COSTS); + } + + private boolean showTrialDocumentary(List trialDocumentaryFastTrack, + List trialDocumentarySmallTrack) { + return nonNull(trialDocumentaryFastTrack) + && trialDocumentaryFastTrack.contains(EvidenceUploadTrial.DOCUMENTARY) + || nonNull(trialDocumentarySmallTrack) + && trialDocumentarySmallTrack.contains(EvidenceUploadTrial.DOCUMENTARY); + } + CallbackResponse validate(CallbackParams callbackParams) { return validateValues(callbackParams, callbackParams.getCaseData()); } @@ -1103,7 +1166,7 @@ private String getSelectedRole(CallbackParams callbackParams) { CaseData caseData = callbackParams.getCaseData(); boolean multiParts = Objects.nonNull(caseData.getEvidenceUploadOptions()) && !caseData.getEvidenceUploadOptions().getListItems().isEmpty(); - UserInfo userInfo = userService.getUserInfo(callbackParams.getParams().get(BEARER_TOKEN).toString()); + if (events.get(0).equals(EVIDENCE_UPLOAD_APPLICANT)) { if (multiParts && caseData.getEvidenceUploadOptions() .getValue().getLabel().startsWith(OPTION_APP2)) { @@ -1115,11 +1178,11 @@ private String getSelectedRole(CallbackParams callbackParams) { } return CaseRole.APPLICANTSOLICITORONE.name(); } else { - if ((multiParts && caseData.getEvidenceUploadOptions() - .getValue().getLabel().startsWith(OPTION_DEF2)) - || (!multiParts - && coreCaseUserService.userHasCaseRole(caseData.getCcdCaseReference().toString(), - userInfo.getUid(), RESPONDENTSOLICITORTWO))) { + String bearerToken = callbackParams.getParams().get(BEARER_TOKEN).toString(); + String ccdCaseRef = callbackParams.getCaseData().getCcdCaseReference().toString(); + String keyToken = userRoleCaching.getCacheKeyToken(bearerToken); + List userRoles = userRoleCaching.getUserRoles(bearerToken, ccdCaseRef, keyToken); + if (isResp2(multiParts, caseData, userRoles)) { return CaseRole.RESPONDENTSOLICITORTWO.name(); } if (multiParts && caseData.getEvidenceUploadOptions() @@ -1130,6 +1193,13 @@ private String getSelectedRole(CallbackParams callbackParams) { } } + private boolean isResp2(boolean multiParts, CaseData caseData, List userRoles) { + return (multiParts && caseData.getEvidenceUploadOptions() + .getValue().getLabel().startsWith(OPTION_DEF2)) + || (!multiParts + && isRespondentSolicitorTwo(userRoles)); + } + SubmittedCallbackResponse buildConfirmation(CallbackParams callbackParams) { return SubmittedCallbackResponse.builder() .confirmationHeader("# Documents uploaded") diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandler.java index 91c7ee7e416..e4b87694ca5 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandler.java @@ -20,21 +20,19 @@ import uk.gov.hmcts.reform.civil.model.caseprogression.UploadEvidenceDocumentType; import uk.gov.hmcts.reform.civil.model.common.Element; import uk.gov.hmcts.reform.civil.service.CoreCaseDataService; -import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; import uk.gov.hmcts.reform.civil.service.Time; -import uk.gov.hmcts.reform.civil.service.UserService; -import uk.gov.hmcts.reform.idam.client.models.UserInfo; +import uk.gov.hmcts.reform.civil.utils.UserRoleCaching; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.EVIDENCE_UPLOAD_RESPONDENT; @Service public class EvidenceUploadRespondentHandler extends EvidenceUploadHandlerBase { - public EvidenceUploadRespondentHandler(UserService userService, CoreCaseUserService coreCaseUserService, - CaseDetailsConverter caseDetailsConverter, + public EvidenceUploadRespondentHandler(CaseDetailsConverter caseDetailsConverter, CoreCaseDataService coreCaseDataService, + UserRoleCaching userRoleCaching, ObjectMapper objectMapper, Time time) { - super(userService, coreCaseUserService, caseDetailsConverter, coreCaseDataService, + super(caseDetailsConverter, coreCaseDataService, userRoleCaching, objectMapper, time, Collections.singletonList(EVIDENCE_UPLOAD_RESPONDENT), "validateValuesRespondent", "createShowCondition"); } @@ -66,9 +64,9 @@ CallbackResponse validateValues(CallbackParams callbackParams, CaseData caseData } @Override - CallbackResponse createShowCondition(CaseData caseData, UserInfo userInfo) { + CallbackResponse createShowCondition(CaseData caseData, List userRoles) { - return showCondition(caseData, userInfo, caseData.getWitnessSelectionEvidenceRes(), + return showCondition(caseData, userRoles, caseData.getWitnessSelectionEvidenceRes(), caseData.getWitnessSelectionEvidenceSmallClaimRes(), caseData.getWitnessSelectionEvidenceRes(), caseData.getWitnessSelectionEvidenceSmallClaimRes(), diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/HearingScheduledHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/HearingScheduledHandler.java index 08861a88924..7426e988ea5 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/HearingScheduledHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/HearingScheduledHandler.java @@ -144,7 +144,6 @@ private CallbackResponse checkPastDate(CallbackParams callbackParams) { "The Date must be in the past"); CaseData.CaseDataBuilder caseDataBuilder = caseData.toBuilder(); - return AboutToStartOrSubmitCallbackResponse.builder() .data(caseDataBuilder.build().toMap(objectMapper)) .errors(errors) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/TrialReadinessCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/TrialReadinessCallbackHandler.java index fcf84a5bc97..b9258e3f637 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/TrialReadinessCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/TrialReadinessCallbackHandler.java @@ -13,9 +13,7 @@ import uk.gov.hmcts.reform.civil.enums.YesOrNo; import uk.gov.hmcts.reform.civil.model.BusinessProcess; import uk.gov.hmcts.reform.civil.model.CaseData; -import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; -import uk.gov.hmcts.reform.civil.service.UserService; -import uk.gov.hmcts.reform.idam.client.models.UserInfo; +import uk.gov.hmcts.reform.civil.utils.UserRoleCaching; import java.time.LocalDate; import java.util.ArrayList; @@ -66,8 +64,7 @@ public class TrialReadinessCallbackHandler extends CallbackHandler { + "you will need to make an application to the court and pay the appropriate fee."; private final ObjectMapper objectMapper; - private final UserService userService; - private final CoreCaseUserService coreCaseUserService; + private final UserRoleCaching userRoleCaching; @Override protected Map callbacks() { @@ -81,7 +78,11 @@ protected Map callbacks() { private CallbackResponse populateValues(CallbackParams callbackParams) { var caseData = callbackParams.getCaseData(); CaseData.CaseDataBuilder updatedData = caseData.toBuilder(); - List userRoles = getUserRoles(callbackParams); + + String bearerToken = callbackParams.getParams().get(BEARER_TOKEN).toString(); + String ccdCaseRef = callbackParams.getCaseData().getCcdCaseReference().toString(); + String keyToken = userRoleCaching.getCacheKeyToken(bearerToken); + List userRoles = userRoleCaching.getUserRoles(bearerToken, ccdCaseRef, keyToken); var isApplicant = YesOrNo.NO; var isRespondent1 = YesOrNo.NO; @@ -120,15 +121,19 @@ private CallbackResponse populateValues(CallbackParams callbackParams) { private CallbackResponse setBusinessProcess(CallbackParams callbackParams) { var caseData = callbackParams.getCaseData(); CaseData.CaseDataBuilder updatedData = caseData.toBuilder(); - List userRoles = getUserRoles(callbackParams); - if (isApplicantSolicitor(userRoles) || isLIPClaimant(userRoles)) { + String bearerToken = callbackParams.getParams().get(BEARER_TOKEN).toString(); + String ccdCaseRef = callbackParams.getCaseData().getCcdCaseReference().toString(); + String keyToken = userRoleCaching.getCacheKeyToken(bearerToken); + List roles = userRoleCaching.getUserRoles(bearerToken, ccdCaseRef, keyToken); + + if (isApplicantSolicitor(roles) || isLIPClaimant(roles)) { if (caseData.getTrialReadyApplicant() == YesOrNo.YES) { updatedData.businessProcess(BusinessProcess.ready(APPLICANT_TRIAL_READY_NOTIFY_OTHERS)); } else { updatedData.businessProcess(BusinessProcess.ready(GENERATE_TRIAL_READY_DOCUMENT_APPLICANT)); } - } else if (isRespondentSolicitorOne(userRoles) || isLIPDefendant(userRoles)) { + } else if (isRespondentSolicitorOne(roles) || isLIPDefendant(roles)) { if (caseData.getTrialReadyRespondent1() == YesOrNo.YES) { updatedData.businessProcess(BusinessProcess.ready(RESPONDENT1_TRIAL_READY_NOTIFY_OTHERS)); } else { @@ -141,24 +146,27 @@ private CallbackResponse setBusinessProcess(CallbackParams callbackParams) { updatedData.businessProcess(BusinessProcess.ready(GENERATE_TRIAL_READY_DOCUMENT_RESPONDENT2)); } } - return AboutToStartOrSubmitCallbackResponse.builder() .data(updatedData.build().toMap(objectMapper)) .build(); } private SubmittedCallbackResponse buildConfirmation(CallbackParams callbackParams) { - List userRoles = getUserRoles(callbackParams); return SubmittedCallbackResponse.builder() - .confirmationHeader(checkUserReady(callbackParams, userRoles).equals(YesOrNo.YES) ? READY_HEADER : NOT_READY_HEADER) - .confirmationBody(checkUserReady(callbackParams, userRoles).equals(YesOrNo.YES) ? READY_BODY : NOT_READY_BODY) + .confirmationHeader(checkUserReady(callbackParams).equals(YesOrNo.YES) ? READY_HEADER : NOT_READY_HEADER) + .confirmationBody(checkUserReady(callbackParams).equals(YesOrNo.YES) ? READY_BODY : NOT_READY_BODY) .build(); } - private YesOrNo checkUserReady(CallbackParams callbackParams, List userRoles) { + private YesOrNo checkUserReady(CallbackParams callbackParams) { var caseData = callbackParams.getCaseData(); + String bearerToken = callbackParams.getParams().get(BEARER_TOKEN).toString(); + String ccdCaseRef = callbackParams.getCaseData().getCcdCaseReference().toString(); + String keyToken = userRoleCaching.getCacheKeyToken(bearerToken); + List userRoles = userRoleCaching.getUserRoles(bearerToken, ccdCaseRef, keyToken); + if (isApplicantSolicitor(userRoles) || isLIPClaimant(userRoles)) { return caseData.getTrialReadyApplicant(); } else if (isRespondentSolicitorOne(userRoles) || isLIPDefendant(userRoles)) { @@ -168,13 +176,6 @@ private YesOrNo checkUserReady(CallbackParams callbackParams, List userR } } - private List getUserRoles(CallbackParams callbackParams) { - String bearerToken = callbackParams.getParams().get(BEARER_TOKEN).toString(); - String ccdCaseRef = callbackParams.getCaseData().getCcdCaseReference().toString(); - UserInfo userInfo = userService.getUserInfo(bearerToken); - return coreCaseUserService.getUserCaseRoles(ccdCaseRef, userInfo.getUid()); - } - @Override public List handledEvents() { return EVENTS; diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationService.java b/src/main/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationService.java index a6191151527..ded72ad6e41 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationService.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationService.java @@ -297,7 +297,8 @@ private void validateUnavailableDates(List errors, public boolean respondentAssigned(CaseData caseData, String authToken) { String caseId = caseData.getCcdCaseReference().toString(); - List userRoles = userRoleCaching.getUserRoles(authToken, caseId); + String keyToken = userRoleCaching.getCacheKeyToken(authToken); + List userRoles = userRoleCaching.getUserRoles(authToken, caseId, keyToken); List respondentCaseRoles = getRespondentCaseRoles(caseData); return !(userRoles.isEmpty() || !isRespondentSolicitorOne(respondentCaseRoles) || (respondentCaseRoles.size() > 1 && !isRespondentSolicitorTwo(respondentCaseRoles))); diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationServiceHelper.java b/src/main/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationServiceHelper.java index d6d35fe839d..2199f76c58a 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationServiceHelper.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationServiceHelper.java @@ -233,7 +233,8 @@ public String getApplicantPartyName(CaseAssignedUserRolesResource userRoles, Use public boolean isGAApplicantSameAsParentCaseClaimant(CaseData caseData, String authToken) { String parentCaseId = caseData.getCcdCaseReference().toString(); - List userRolesCaching = userRoleCaching.getUserRoles(authToken, parentCaseId); + String keyToken = userRoleCaching.getCacheKeyToken(authToken); + List userRolesCaching = userRoleCaching.getUserRoles(authToken, parentCaseId, keyToken); boolean isApplicantSolicitor = UserRoleUtils.isApplicantSolicitor(userRolesCaching); diff --git a/src/main/java/uk/gov/hmcts/reform/civil/utils/UserRoleCaching.java b/src/main/java/uk/gov/hmcts/reform/civil/utils/UserRoleCaching.java index 3f5a4898b5c..dfdb019f954 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/utils/UserRoleCaching.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/utils/UserRoleCaching.java @@ -2,6 +2,12 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.cache.CacheManager; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.cache.concurrent.ConcurrentMapCacheManager; +import org.springframework.context.annotation.Bean; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; import uk.gov.hmcts.reform.civil.service.UserService; @@ -17,9 +23,24 @@ public class UserRoleCaching { private final UserService userService; private final CoreCaseUserService coreCaseUserService; - public List getUserRoles(String bearerToken, String ccdCaseRef) { + @Cacheable(cacheNames = "UserCache", cacheManager = "userCacheManager", key = "#keyToken") + public List getUserRoles(String bearerToken, String ccdCaseRef, String keyToken) { UserInfo userInfo = userService.getUserInfo(bearerToken); return coreCaseUserService.getUserCaseRoles(ccdCaseRef, userInfo.getUid()); } + public String getCacheKeyToken(String bearerToken) { + return bearerToken.substring(bearerToken.length() - 16); + } + + @Bean(name = "userCacheManager") + public CacheManager getCacheManager() { + return new ConcurrentMapCacheManager(); + } + + @CacheEvict(value = "UserCache", allEntries = true) + @Scheduled(fixedRateString = "1800000") + public void emptyUserCache() { + log.debug("Cache removed"); + } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandlerTest.java index cda6fc74fc7..ec3b2d9d8e2 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandlerTest.java @@ -27,6 +27,7 @@ import uk.gov.hmcts.reform.ccd.client.model.SubmittedCallbackResponse; import uk.gov.hmcts.reform.civil.callback.CallbackHandler; import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.enums.CaseRole; import uk.gov.hmcts.reform.civil.enums.ClaimType; import uk.gov.hmcts.reform.civil.handler.callback.BaseCallbackHandlerTest; import uk.gov.hmcts.reform.civil.helpers.CaseDetailsConverter; @@ -46,7 +47,7 @@ import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; import uk.gov.hmcts.reform.civil.service.Time; import uk.gov.hmcts.reform.civil.utils.ElementUtils; -import uk.gov.hmcts.reform.idam.client.models.UserInfo; +import uk.gov.hmcts.reform.civil.utils.UserRoleCaching; import static java.util.Map.entry; import static org.assertj.core.api.Assertions.assertThat; @@ -54,15 +55,12 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_START; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; import static uk.gov.hmcts.reform.civil.callback.CallbackType.MID; import static uk.gov.hmcts.reform.civil.callback.CallbackType.SUBMITTED; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.EVIDENCE_UPLOAD_APPLICANT; -import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORONE; -import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORTWO; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; import static uk.gov.hmcts.reform.civil.utils.ElementUtils.element; @@ -90,6 +88,9 @@ class EvidenceUploadApplicantHandlerTest extends BaseCallbackHandlerTest { private CoreCaseDataService coreCaseDataService; @MockBean CaseData.CaseDataBuilder caseDataBuilder; + + @MockBean + private UserRoleCaching userRoleCaching; @Autowired private final ObjectMapper mapper = new ObjectMapper(); @@ -127,6 +128,8 @@ class EvidenceUploadApplicantHandlerTest extends BaseCallbackHandlerTest { @BeforeEach void setup() { given(time.now()).willReturn(LocalDateTime.now()); + given(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + .willReturn(List.of(CaseRole.APPLICANTSOLICITORONE.getFormattedName())); } @Test @@ -139,8 +142,7 @@ void givenAboutToStart_assignCaseProgAllocatedTrackUnSpec() { .statementOfValueInPennies(BigDecimal.valueOf(5000)) .build()) .build(); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), any())).willReturn(false); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_START); // When AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler @@ -158,8 +160,7 @@ void givenAboutToStart_assignCaseProgAllocatedTrackSpec() { .claimType(null) .totalClaimAmount(BigDecimal.valueOf(12500)) .build(); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), any())).willReturn(false); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_START); // When AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler @@ -505,9 +506,6 @@ void shouldCallExternalTask_whenAboutToSubmit() { CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -533,9 +531,7 @@ void shouldAssignCategoryID_whenDocumentExists() { CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .documentHearsayNotice(documentList) .build(); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // When @@ -551,9 +547,7 @@ void shouldNotAssignCategoryID_whenDocumentNotExists() { CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .addRespondent2(YES) .build(); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // When @@ -610,9 +604,6 @@ void shouldAddApplicantEvidenceDocWhenBundleCreatedDateIsBeforeEvidenceUploaded( .caseBundles(prepareCaseBundles(LocalDateTime.of(2022, 05, 10, 12, 12, 12))).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); // When handle is called var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -631,9 +622,6 @@ void shouldNotAddApplicantEvidenceDocWhenBundleCreatedDateIsAfterEvidenceUploade .caseBundles(prepareCaseBundles(LocalDateTime.of(2022, 05, 15, 12, 12, 12))).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); // When handle is called var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -662,9 +650,6 @@ void shouldBreakWhenThereIsAnyCaseBundlesWithoutCreatedDate() { .caseBundles(caseBundles) .build(); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); // When: handler is called @@ -690,9 +675,6 @@ void shouldBreakWhenThereIsAnyCaseBundlesWithNullCreatedDate() { .caseBundles(caseBundles) .build(); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); // When: handler is called @@ -740,9 +722,6 @@ void should_do_naming_convention(String selected) { .applicant2(PartyBuilder.builder().individual().build()) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); given(coreCaseDataService.getCase(anyLong())).willReturn(CaseDetails.builder().build()); given(caseDetailsConverter.toCaseData(any(CaseDetails.class))).willReturn(caseDataBefore); @@ -879,10 +858,6 @@ void should_do_naming_convention_app2() { .documentCostsApp2(createEvidenceDocs(null, null)) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); // When handle is called var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -936,9 +911,6 @@ void shouldNotAddSameNotificationIfAlreadyAdded_notificationText() { .documentJointStatement(createExpertDocs("expertsName", witnessDate, null, "expertises", null, null, null)) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); given(coreCaseDataService.getCase(anyLong())).willReturn(CaseDetails.builder().build()); // When handle is called var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -963,9 +935,6 @@ void shouldNotPopulateNotificationWithOldDocument_whenNewDocumentUploadAdded() { .documentWitnessSummary(createWitnessDocs(witnessName, LocalDateTime.now(), witnessDate)) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); given(coreCaseDataService.getCase(anyLong())).willReturn(CaseDetails.builder().build()); // When handle is called var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandlerTest.java index 455cd043a2e..9aef6e555de 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandlerTest.java @@ -30,6 +30,7 @@ import uk.gov.hmcts.reform.ccd.client.model.SubmittedCallbackResponse; import uk.gov.hmcts.reform.civil.callback.CallbackHandler; import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.enums.CaseRole; import uk.gov.hmcts.reform.civil.enums.ClaimType; import uk.gov.hmcts.reform.civil.enums.caseprogression.EvidenceUploadExpert; import uk.gov.hmcts.reform.civil.enums.caseprogression.EvidenceUploadTrial; @@ -52,7 +53,7 @@ import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; import uk.gov.hmcts.reform.civil.service.Time; import uk.gov.hmcts.reform.civil.utils.ElementUtils; -import uk.gov.hmcts.reform.idam.client.models.UserInfo; +import uk.gov.hmcts.reform.civil.utils.UserRoleCaching; import static java.util.Map.entry; import static org.assertj.core.api.Assertions.assertThat; @@ -61,7 +62,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_START; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; @@ -105,6 +105,9 @@ class EvidenceUploadRespondentHandlerTest extends BaseCallbackHandlerTest { @MockBean private CaseDetailsConverter caseDetailsConverter; + @MockBean + private UserRoleCaching userRoleCaching; + @Autowired private final ObjectMapper mapper = new ObjectMapper(); @@ -142,6 +145,9 @@ class EvidenceUploadRespondentHandlerTest extends BaseCallbackHandlerTest { @BeforeEach void setup() { given(time.now()).willReturn(LocalDateTime.now()); + given(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + .willReturn(List.of(RESPONDENTSOLICITORONE.getFormattedName())); + given(userRoleCaching.getCacheKeyToken(anyString())).willReturn("1234"); } @Test @@ -154,8 +160,7 @@ void givenAboutToStart_assignCaseProgAllocatedTrackUnSpec() { .statementOfValueInPennies(BigDecimal.valueOf(5000)) .build()) .build(); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), any())).willReturn(false); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_START); // When AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler @@ -173,8 +178,7 @@ void givenAboutToStart_assignCaseProgAllocatedTrackSpec() { .claimType(null) .totalClaimAmount(BigDecimal.valueOf(12500)) .build(); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), any())).willReturn(false); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_START); // When AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler @@ -238,8 +242,8 @@ void givenCreateShow_1v2DifferentSolicitorsWillChangeToRespondentTwoFlag() { .respondent2(PartyBuilder.builder().individual().build()) .respondent2SameLegalRepresentative(NO) .build(); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(true); + given(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + .willReturn(List.of(RESPONDENTSOLICITORTWO.getFormattedName())); CallbackParams params = callbackParamsOf(caseData, MID, "createShowCondition"); // When AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler @@ -257,8 +261,8 @@ void givenCreateShow_1v2DifferentSolicitorsWillChangeToRespondentTwoFlagSpec() { .respondent2(PartyBuilder.builder().individual().build()) .respondent2SameLegalRepresentative(NO) .build(); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(true); + given(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + .willReturn(List.of(RESPONDENTSOLICITORTWO.getFormattedName())); CallbackParams params = callbackParamsOf(caseData, MID, "createShowCondition"); // When AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler @@ -272,8 +276,7 @@ void givenCreateShow_1v1WillNotChangeToRespondentTwoFlag() { // Given CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build().toBuilder() .build(); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); + CallbackParams params = callbackParamsOf(caseData, MID, "createShowCondition"); // When AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler @@ -333,8 +336,7 @@ static Stream optionsNotSelected() { void shouldSetWitnessFlag_whenWitnessOptionsAreSelected(CaseData caseData) { // Given CallbackParams params = callbackParamsOf(caseData, MID, "createShowCondition"); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); + // When var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // Then @@ -348,8 +350,7 @@ void shouldSetWitnessFlag_whenWitnessOptionsAreSelected(CaseData caseData) { void shouldNotSetWitnessFlag_whenWitnessOptionsAreNotSelected(CaseData caseData) { // Given CallbackParams params = callbackParamsOf(caseData, MID, "createShowCondition"); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); + // When var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // Then @@ -363,8 +364,7 @@ void shouldNotSetWitnessFlag_whenWitnessOptionsAreNotSelected(CaseData caseData) void shouldSetExpertFlag_whenExpertOptionsAreSelected(CaseData caseData) { // Given CallbackParams params = callbackParamsOf(caseData, MID, "createShowCondition"); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); + // When var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // Then @@ -377,8 +377,7 @@ void shouldSetExpertFlag_whenExpertOptionsAreSelected(CaseData caseData) { void shouldNotSetExpertFlag_whenExpertOptionsAreNotSelected(CaseData caseData) { // Given CallbackParams params = callbackParamsOf(caseData, MID, "createShowCondition"); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); + // When var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // Then @@ -391,8 +390,7 @@ void shouldNotSetExpertFlag_whenExpertOptionsAreNotSelected(CaseData caseData) { void shouldSetTrialFlag_whenTrialOptionsAreSelected(CaseData caseData) { // Given CallbackParams params = callbackParamsOf(caseData, MID, "createShowCondition"); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); + // When var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // Then @@ -406,8 +404,7 @@ void shouldSetTrialFlag_whenTrialOptionsAreSelected(CaseData caseData) { void shouldNotSetTrialFlag_whenTrialOptionsAreNotSelected(CaseData caseData) { // Given CallbackParams params = callbackParamsOf(caseData, MID, "createShowCondition"); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); + // When var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // Then @@ -1009,9 +1006,6 @@ void shouldCallExternalTask_whenAboutToSubmit() { CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(true); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -1038,8 +1032,8 @@ void shouldAssignCategoryID_whenDocumentExistsTwoRespondentSpec() { .addRespondent2(YES) .documentForDisclosureRes2(documentList) .build(); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(true); + given(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + .willReturn(List.of(RESPONDENTSOLICITORTWO.getFormattedName())); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // When @@ -1065,8 +1059,8 @@ void shouldAssignCategoryID_whenDocumentExistsTwoRespondentUnSpec() { .addRespondent2(YES) .documentForDisclosureRes2(documentList) .build(); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(true); + given(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + .willReturn(List.of(RESPONDENTSOLICITORTWO.getFormattedName())); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // When @@ -1092,9 +1086,7 @@ void shouldAssignCategoryID_whenDocumentExistsOneRespondentSpec() { .addRespondent2(NO) .documentAnswersRes(documentList) .build(); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(true); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // When @@ -1120,9 +1112,7 @@ void shouldAssignCategoryID_whenDocumentExistsOneRespondentUnSpec() { .addRespondent2(NO) .documentQuestionsRes(documentList) .build(); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(true); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // When @@ -1138,8 +1128,8 @@ void shouldNotAssignCategoryID_whenDocumentNotExistsTwoRespondent() { CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .addRespondent2(YES) .build(); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(true); + given(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + .willReturn(List.of(CaseRole.APPLICANTSOLICITORONE.getFormattedName())); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // When @@ -1154,9 +1144,7 @@ void shouldNotAssignCategoryID_whenDocumentNotExistsOneRespondent() { CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .addRespondent2(NO) .build(); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(true); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // When @@ -1216,9 +1204,6 @@ void shouldAddRespondentEvidenceDocWhenBundleCreatedDateIsBeforeEvidenceUploaded .caseBundles(prepareCaseBundles(LocalDateTime.of(2022, 05, 10, 12, 12, 12))).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); // When handle is called var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -1237,9 +1222,6 @@ void shouldNotAddRespondentEvidenceDocWhenBundleCreatedDateIsAfterEvidenceUpload .caseBundles(prepareCaseBundles(LocalDateTime.of(2022, 05, 15, 12, 12, 12))).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); // When handle is called var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -1268,9 +1250,6 @@ void shouldBreakWhenThereIsAnyCaseBundlesWithoutCreatedDate() { .caseBundles(caseBundles) .build(); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(true); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); // When: handler is called @@ -1296,9 +1275,6 @@ void shouldBreakWhenThereIsAnyCaseBundlesWithNullCreatedDate() { .caseBundles(caseBundles) .build(); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(true); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); // When: handler is called @@ -1347,10 +1323,6 @@ void should_do_naming_convention_resp1(String selected) { .respondent2(PartyBuilder.builder().individual().build()) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(true); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); given(coreCaseDataService.getCase(anyLong())).willReturn(CaseDetails.builder().build()); given(caseDetailsConverter.toCaseData(any(CaseDetails.class))).willReturn(caseDataBefore); @@ -1483,10 +1455,8 @@ void should_do_naming_convention_resp2() { .documentCostsRes2(createEvidenceDocs(null, null)) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(true); + given(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + .willReturn(List.of(RESPONDENTSOLICITORTWO.getFormattedName())); // When handle is called var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -1540,9 +1510,8 @@ void shouldNotAddSameNotificationIfAlreadyAdded_notificationText() { .documentJointStatementRes(createExpertDocs("expertsName", witnessDate, null, "expertises", null, null, null)) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(true); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); + given(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + .willReturn(List.of(RESPONDENTSOLICITORONE.getFormattedName())); given(coreCaseDataService.getCase(anyLong())).willReturn(CaseDetails.builder().build()); // When handle is called var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -1567,9 +1536,8 @@ void shouldNotPopulateNotificationWithOldDocument_whenNewDocumentUploadAdded() { .documentWitnessSummaryRes(createWitnessDocs(witnessName, LocalDateTime.now(), witnessDate)) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(true); - given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); + given(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + .willReturn(List.of(RESPONDENTSOLICITORONE.getFormattedName())); given(coreCaseDataService.getCase(anyLong())).willReturn(CaseDetails.builder().build()); // When handle is called var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/TrialReadinessCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/TrialReadinessCallbackHandlerTest.java index 66dbe5568ee..1385919b3a5 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/TrialReadinessCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/TrialReadinessCallbackHandlerTest.java @@ -19,7 +19,7 @@ import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.sampledata.CallbackParamsBuilder; import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; -import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; +import uk.gov.hmcts.reform.civil.utils.UserRoleCaching; import uk.gov.hmcts.reform.idam.client.models.UserInfo; import java.time.LocalDate; @@ -44,7 +44,7 @@ public class TrialReadinessCallbackHandlerTest extends BaseCallbackHandlerTest { private TrialReadinessCallbackHandler handler; @MockBean - private CoreCaseUserService coreCaseUserService; + private UserRoleCaching userRoleCaching; public static final String READY_HEADER = "## You have said this case is ready for trial or hearing"; public static final String READY_BODY = "### What happens next \n\n" @@ -61,20 +61,22 @@ public class TrialReadinessCallbackHandlerTest extends BaseCallbackHandlerTest { + "If you want the date of the hearing to be changed (or any other order to make the case ready for trial)" + "you will need to make an application to the court and pay the appropriate fee."; + @BeforeEach + public void setup() { + when(userRoleCaching.getCacheKeyToken(anyString())).thenReturn("1234"); + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + } + @Nested class AboutToStartCallback { - @BeforeEach - public void setup() { - when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); - } - @Test void shouldNotReturnError_WhenAboutToStartIsInvoked_ApplicantSolicitor() { //given: applicant solicitor logs in more than 3 weeks before hearing CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_START, caseData).build(); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.APPLICANTSOLICITORONE.getFormattedName())); //when: Event is started @@ -89,7 +91,7 @@ void shouldNotReturnError_WhenAboutToStartIsInvoked_Claimant() { //given: claimant logs in more than 3 weeks before hearing CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_START, caseData).build(); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.CLAIMANT.getFormattedName())); //when: Event is started @@ -104,7 +106,8 @@ void shouldNotReturnError_WhenAboutToStartIsInvoked_RespondentSolicitor1() { //given: respondent 1 solicitor logs in more than 3 weeks before hearing CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_START, caseData).build(); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.RESPONDENTSOLICITORONE.getFormattedName())); //when: Event is started @@ -119,7 +122,7 @@ void shouldNotReturnError_WhenAboutToStartIsInvoked_Defendant() { //given: defendant logs in more than 3 weeks before hearing CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_START, caseData).build(); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.DEFENDANT.getFormattedName())); //when: Event is started @@ -134,7 +137,8 @@ void shouldNotReturnError_WhenAboutToStartIsInvoked_RespondentSolicitor2() { //given: respondent 2 solicitor logs in more than 3 weeks before hearing CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_START, caseData).build(); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.RESPONDENTSOLICITORTWO.getFormattedName())); //when: Event is started @@ -150,7 +154,8 @@ void shouldReturnError_WhenAboutToStartIsInvokedWithinThreeWeeksOfHearingDate_Ap CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck() .hearingDate(LocalDate.now().plusWeeks(2).plusDays(6)).build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_START, caseData).build(); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.APPLICANTSOLICITORONE.getFormattedName())); //when: Event is started @@ -166,7 +171,7 @@ void shouldReturnError_WhenAboutToStartIsInvokedWithinThreeWeeksOfHearingDate_Cl CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck() .hearingDate(LocalDate.now().plusWeeks(2).plusDays(6)).build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_START, caseData).build(); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.CLAIMANT.getFormattedName())); //when: Event is started @@ -182,7 +187,8 @@ void shouldReturnError_WhenAboutToStartIsInvokedWithinThreeWeeksOfHearingDate_Re CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck() .hearingDate(LocalDate.now().plusWeeks(2).plusDays(6)).build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_START, caseData).build(); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.RESPONDENTSOLICITORONE.getFormattedName())); //when: Event is started @@ -198,7 +204,7 @@ void shouldReturnError_WhenAboutToStartIsInvokedWithinThreeWeeksOfHearingDate_De CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck() .hearingDate(LocalDate.now().plusWeeks(2).plusDays(6)).build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_START, caseData).build(); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.DEFENDANT.getFormattedName())); //when: Event is started @@ -214,7 +220,8 @@ void shouldReturnError_WhenAboutToStartIsInvokedWithinThreeWeeksOfHearingDate_Re CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck() .hearingDate(LocalDate.now().plusWeeks(2).plusDays(6)).build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_START, caseData).build(); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.RESPONDENTSOLICITORTWO.getFormattedName())); //when: Event is started @@ -238,7 +245,8 @@ void shouldTriggerApplicantNotifyOthers_WhenAboutToSubmitIsInvoked_ApplicantSoli CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build().toBuilder() .trialReadyApplicant(YesOrNo.YES).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.APPLICANTSOLICITORONE.getFormattedName())); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -254,7 +262,8 @@ void shouldTriggerApplicantNotifyOthers_WhenAboutToSubmitIsInvoked_Claimant() { CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build().toBuilder() .trialReadyApplicant(YesOrNo.YES).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.CLAIMANT.getFormattedName())); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -263,14 +272,17 @@ void shouldTriggerApplicantNotifyOthers_WhenAboutToSubmitIsInvoked_Claimant() { assertThat(response.getData()).extracting("businessProcess") .extracting("camundaEvent", "status") .containsOnly(CaseEvent.APPLICANT_TRIAL_READY_NOTIFY_OTHERS.name(), "READY"); + } @Test + void shouldTriggerRespondent1NotifyOthers_WhenAboutToSubmitIsInvoked_Respondent1Solicitor() { CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build().toBuilder() .trialReadyRespondent1(YesOrNo.YES).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.RESPONDENTSOLICITORONE.getFormattedName())); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -286,7 +298,8 @@ void shouldTriggerRespondent1NotifyOthers_WhenAboutToSubmitIsInvoked_Defendant() CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build().toBuilder() .trialReadyRespondent1(YesOrNo.YES).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.DEFENDANT.getFormattedName())); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -302,7 +315,8 @@ void shouldTriggerRespondent2NotifyOthers_WhenAboutToSubmitIsInvoked_Respondent2 CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build().toBuilder() .trialReadyRespondent2(YesOrNo.YES).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.RESPONDENTSOLICITORTWO.getFormattedName())); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -318,7 +332,8 @@ void shouldTriggerApplicantDocument_WhenAboutToSubmitIsInvoked_ApplicantSolicito CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build().toBuilder() .trialReadyApplicant(YesOrNo.NO).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.APPLICANTSOLICITORONE.getFormattedName())); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -334,7 +349,8 @@ void shouldTriggerApplicantDocument_WhenAboutToSubmitIsInvoked_Claimant() { CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build().toBuilder() .trialReadyApplicant(YesOrNo.NO).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.CLAIMANT.getFormattedName())); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -350,7 +366,8 @@ void shouldTriggerRespondent1Document_WhenAboutToSubmitIsInvoked_Respondent1Soli CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build().toBuilder() .trialReadyRespondent1(YesOrNo.NO).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.RESPONDENTSOLICITORONE.getFormattedName())); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -366,7 +383,8 @@ void shouldTriggerRespondent1Document_WhenAboutToSubmitIsInvoked_Defendant() { CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build().toBuilder() .trialReadyRespondent1(YesOrNo.NO).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.DEFENDANT.getFormattedName())); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -382,7 +400,8 @@ void shouldTriggerRespondent2Document_WhenAboutToSubmitIsInvoked_Respondent2Soli CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build().toBuilder() .trialReadyRespondent2(YesOrNo.NO).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.RESPONDENTSOLICITORTWO.getFormattedName())); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -407,7 +426,8 @@ void shouldReturnConfirmationScreen_when1v1ReadySubmitted_ApplicantSolicitor() { //given: applicant solicitor selects Ready CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyApplicant().build(); CallbackParams params = CallbackParamsBuilder.builder().of(SUBMITTED, caseData).build(); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.APPLICANTSOLICITORONE.getFormattedName())); //when: Event is submitted @@ -426,11 +446,12 @@ void shouldReturnConfirmationScreen_when1v1ReadySubmitted_Claimant() { //given: claimant selects Ready CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyApplicant().build(); CallbackParams params = CallbackParamsBuilder.builder().of(SUBMITTED, caseData).build(); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.CLAIMANT.getFormattedName())); //when: Event is submitted SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); + //then: header + body for the ready status get used in the confirmation assertThat(response).usingRecursiveComparison().isEqualTo( SubmittedCallbackResponse.builder() @@ -445,11 +466,13 @@ void shouldReturnConfirmationScreen_when1v1NotReadySubmitted_ApplicantSolicitor( //given: applicant solicitor selects Not Ready CaseData caseData = CaseDataBuilder.builder().atStateTrialNotReadyApplicant().build(); CallbackParams params = CallbackParamsBuilder.builder().of(SUBMITTED, caseData).build(); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.APPLICANTSOLICITORONE.getFormattedName())); //when: Event is submitted SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); + //then: header + body for the not ready status get used in the confirmation assertThat(response).usingRecursiveComparison().isEqualTo( SubmittedCallbackResponse.builder() @@ -464,11 +487,12 @@ void shouldReturnConfirmationScreen_when1v1NotReadySubmitted_Claimant() { //given: claimant selects Not Ready CaseData caseData = CaseDataBuilder.builder().atStateTrialNotReadyApplicant().build(); CallbackParams params = CallbackParamsBuilder.builder().of(SUBMITTED, caseData).build(); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.CLAIMANT.getFormattedName())); //when: Event is submitted SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); + //then: header + body for the not ready status get used in the confirmation assertThat(response).usingRecursiveComparison().isEqualTo( SubmittedCallbackResponse.builder() @@ -483,11 +507,13 @@ void shouldReturnConfirmationScreen_when1v1ReadySubmitted_Respondent1Solicitor() //given: respondent 1 solicitor selects Ready CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyRespondent1().build(); CallbackParams params = CallbackParamsBuilder.builder().of(SUBMITTED, caseData).build(); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.RESPONDENTSOLICITORONE.getFormattedName())); //when: Event is submitted SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); + //then: header + body for the ready status get used in the confirmation assertThat(response).usingRecursiveComparison().isEqualTo( SubmittedCallbackResponse.builder() @@ -502,11 +528,12 @@ void shouldReturnConfirmationScreen_when1v1ReadySubmitted_Defendant() { //given: defendant selects Ready CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyRespondent1().build(); CallbackParams params = CallbackParamsBuilder.builder().of(SUBMITTED, caseData).build(); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.DEFENDANT.getFormattedName())); //when: Event is submitted SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); + //then: header + body for the ready status get used in the confirmation assertThat(response).usingRecursiveComparison().isEqualTo( SubmittedCallbackResponse.builder() @@ -521,11 +548,13 @@ void shouldReturnConfirmationScreen_when1v1NotReadySubmitted_Respondent1Solicito //given: respondent 1 solicitor selects Not Ready CaseData caseData = CaseDataBuilder.builder().atStateTrialNotReadyRespondent1().build(); CallbackParams params = CallbackParamsBuilder.builder().of(SUBMITTED, caseData).build(); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.RESPONDENTSOLICITORONE.getFormattedName())); //when: Event is submitted SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); + //then: header + body for the not ready status get used in the confirmation assertThat(response).usingRecursiveComparison().isEqualTo( SubmittedCallbackResponse.builder() @@ -540,11 +569,12 @@ void shouldReturnConfirmationScreen_when1v1NotReadySubmitted_Defendant() { //given: defendant selects Not Ready CaseData caseData = CaseDataBuilder.builder().atStateTrialNotReadyRespondent1().build(); CallbackParams params = CallbackParamsBuilder.builder().of(SUBMITTED, caseData).build(); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.DEFENDANT.getFormattedName())); //when: Event is submitted SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); + //then: header + body for the not ready status get used in the confirmation assertThat(response).usingRecursiveComparison().isEqualTo( SubmittedCallbackResponse.builder() @@ -559,7 +589,8 @@ void shouldReturnConfirmationScreen_when1v1ReadySubmitted_Respondent2Solicitor() //given: Respondent 2 selects Ready CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyRespondent2().build(); CallbackParams params = CallbackParamsBuilder.builder().of(SUBMITTED, caseData).build(); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.RESPONDENTSOLICITORTWO.getFormattedName())); //when: Event is submitted @@ -578,7 +609,8 @@ void shouldReturnConfirmationScreen_when1v1NotReadySubmitted_Respondent2Solicito //given: Respondent 2 solicitor selects Not Ready CaseData caseData = CaseDataBuilder.builder().atStateTrialNotReadyRespondent2().build(); CallbackParams params = CallbackParamsBuilder.builder().of(SUBMITTED, caseData).build(); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) + + when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) .thenReturn(List.of(CaseRole.RESPONDENTSOLICITORTWO.getFormattedName())); //when: Event is submitted diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationServiceTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationServiceTest.java index 3eabd89f790..269c35c7add 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationServiceTest.java @@ -196,7 +196,7 @@ void shouldReturnTrue_whenRespondent1SolIsAssigned_1V1() { .respondent1OrganisationPolicy(respondent1Organization) .build(); List userRoles = new ArrayList<>(Arrays.asList("[APPLICANTSOLICITORONE]", "[RESPONDENTSOLICITORONE]")); - when(userRoleCaching.getUserRoles(any(), any())).thenReturn(userRoles); + when(userRoleCaching.getUserRoles(any(), any(), any())).thenReturn(userRoles); when(caseAccessDataStoreApi.getUserRoles(any(), any(), any())) .thenReturn(CaseAssignedUserRolesResource.builder() .caseAssignedUserRoles(applicant1Respondent1SolAssigned()).build()); @@ -227,7 +227,7 @@ void shouldReturnTrue_whenR1SolicitorsIsAssigned_1V2_SAME() { .respondent2OrganisationPolicy(respondent2Organization) .build(); List userRoles = new ArrayList<>(Arrays.asList("[APPLICANTSOLICITORONE]", "[RESPONDENTSOLICITORONE]")); - when(userRoleCaching.getUserRoles(any(), any())).thenReturn(userRoles); + when(userRoleCaching.getUserRoles(any(), any(), any())).thenReturn(userRoles); when(caseAccessDataStoreApi.getUserRoles(any(), any(), any())) .thenReturn(CaseAssignedUserRolesResource.builder() .caseAssignedUserRoles(applicant1Respondent1SolAssigned()).build()); @@ -244,7 +244,7 @@ void shouldReturnTrue_whenR1AndR2AreAssigned_1V2_SAME() { .respondent2OrganisationPolicy(respondent2Organization) .build(); List userRoles = new ArrayList<>(Arrays.asList("[APPLICANTSOLICITORONE]", "[RESPONDENTSOLICITORONE]", "[RESPONDENTSOLICITORTWO]")); - when(userRoleCaching.getUserRoles(any(), any())).thenReturn(userRoles); + when(userRoleCaching.getUserRoles(any(), any(), any())).thenReturn(userRoles); when(caseAccessDataStoreApi.getUserRoles(any(), any(), any())) .thenReturn(CaseAssignedUserRolesResource.builder() .caseAssignedUserRoles(applicant1Respondent1Respondent2SolAssigned()).build()); @@ -293,7 +293,7 @@ void shouldReturnTrue_whenR1R2SolsAreAssigned_1V2_DIFF() { .respondent2OrganisationPolicy(respondent2Organization) .build(); List userRoles = new ArrayList<>(Arrays.asList("[APPLICANTSOLICITORONE]", "[RESPONDENTSOLICITORONE]", "[RESPONDENTSOLICITORTWO]")); - when(userRoleCaching.getUserRoles(any(), any())).thenReturn(userRoles); + when(userRoleCaching.getUserRoles(any(), any(), any())).thenReturn(userRoles); when(caseAccessDataStoreApi.getUserRoles(any(), any(), any())) .thenReturn(CaseAssignedUserRolesResource.builder() .caseAssignedUserRoles(applicant1Respondent1Respondent2SolAssigned()).build()); @@ -868,7 +868,7 @@ void shouldReturnTrue_whenApplicantIsClaimantAtMainCase() { CaseData.CaseDataBuilder builder = caseData.toBuilder(); builder.applicant1OrganisationPolicy(OrganisationPolicy .builder().orgPolicyCaseAssignedRole("[APPLICANTSOLICITORONE]").build()); - when(userRoleCaching.getUserRoles(any(), any())).thenReturn(userRoles); + when(userRoleCaching.getUserRoles(any(), any(), any())).thenReturn(userRoles); when(caseAccessDataStoreApi.getUserRoles(any(), any(), any())) .thenReturn(CaseAssignedUserRolesResource.builder() .caseAssignedUserRoles(onlyApplicantSolicitorAssigned()).build()); @@ -886,7 +886,7 @@ void shouldReturnFalse_whenApplicantIsClaimantAtMainCase() { CaseData.CaseDataBuilder builder = caseData.toBuilder(); builder.applicant1OrganisationPolicy(OrganisationPolicy .builder().orgPolicyCaseAssignedRole("[APPLICANTSOLICITORONE]").build()); - when(userRoleCaching.getUserRoles(any(), any())).thenReturn(userRoles); + when(userRoleCaching.getUserRoles(any(), any(), any())).thenReturn(userRoles); when(caseAccessDataStoreApi.getUserRoles(any(), any(), any())) .thenReturn(CaseAssignedUserRolesResource.builder() .caseAssignedUserRoles(applicant1Respondent2SolAssigned()).build()); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/utils/UserRoleCachingTest.java b/src/test/java/uk/gov/hmcts/reform/civil/utils/UserRoleCachingTest.java new file mode 100644 index 00000000000..dcdcf254035 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/utils/UserRoleCachingTest.java @@ -0,0 +1,42 @@ +package uk.gov.hmcts.reform.civil.utils; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; +import uk.gov.hmcts.reform.civil.service.UserService; +import uk.gov.hmcts.reform.idam.client.models.UserInfo; + +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.when; + +@SpringBootTest(classes = { + UserRoleCaching.class, + CoreCaseUserService.class, + UserService.class +}) +public class UserRoleCachingTest { + + @MockBean + private CoreCaseUserService coreCaseUserService; + @MockBean + private UserService userService; + @Autowired + private UserRoleCaching userRoleCaching; + + @Test + void getUserRolesTest() { + List caseRoles = new ArrayList<>(); + caseRoles.add("[APPLICANTSOLICITORONE]"); + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())).thenReturn(caseRoles); + assertThat(userRoleCaching.getUserRoles("bearerToken", "ccdcase", "keyToken")) + .contains("[APPLICANTSOLICITORONE]"); + } + +} From f416f774e9f1e80a1410e87592164d7760317b22 Mon Sep 17 00:00:00 2001 From: kalachandrasekar1 <114995593+kalachandrasekar1@users.noreply.github.com> Date: Thu, 9 Nov 2023 10:09:46 +0000 Subject: [PATCH 15/28] CIV-9528 Update LR Pay Immediately screen bug fix (#3530) * bug fix changes * bug fix changes * bug fix changes * build issue fixed * review comments fixed --------- Co-authored-by: sankhajuria Co-authored-by: Raja Mani --- ...tByAdmissionForSpecCuiCallbackHandler.java | 7 ++- .../RespondToDefenceSpecCallbackHandler.java | 9 ++- .../hmcts/reform/civil/model/CaseData.java | 5 +- .../ResponseRepaymentDetailsForm.java | 2 +- .../SealedClaimLipResponseForm.java | 2 +- .../SealedClaimLipResponseFormGenerator.java | 39 ++++++++++++- ...dmissionForSpecCuiCallbackHandlerTest.java | 14 ++++- ...spondToDefenceSpecCallbackHandlerTest.java | 12 ++++ ...aledClaimLipResponseFormGeneratorTest.java | 56 +++++++++++++++++++ 9 files changed, 136 insertions(+), 10 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RequestJudgementByAdmissionForSpecCuiCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RequestJudgementByAdmissionForSpecCuiCallbackHandler.java index 911aebf4220..9ebf5ff394e 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RequestJudgementByAdmissionForSpecCuiCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RequestJudgementByAdmissionForSpecCuiCallbackHandler.java @@ -18,7 +18,9 @@ import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.service.FeatureToggleService; import uk.gov.hmcts.reform.civil.service.JudgementService; +import uk.gov.hmcts.reform.civil.service.citizenui.responsedeadline.DeadlineExtensionCalculatorService; +import java.time.LocalDate; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -41,6 +43,7 @@ public class RequestJudgementByAdmissionForSpecCuiCallbackHandler extends Callba private final JudgementService judgementService; private final CaseDetailsConverter caseDetailsConverter; private final FeatureToggleService featureToggleService; + private final DeadlineExtensionCalculatorService deadlineCalculatorService; @Override protected Map callbacks() { @@ -64,7 +67,9 @@ private CallbackResponse validateDefaultJudgementEligibility(CallbackParams call CaseData.CaseDataBuilder caseDataBuilder = caseData.toBuilder(); ArrayList errors = new ArrayList<>(); if (caseData.isJudgementDateNotPermitted()) { - errors.add(format(NOT_VALID_DJ_BY_ADMISSION, caseData.setUpJudgementFormattedPermittedDate())); + LocalDate extendedResponseDate = caseData.getRespondent1ResponseDate().toLocalDate().plusDays(5); + LocalDate extendedRespondent1ResponseDate = deadlineCalculatorService.calculateExtendedDeadline(extendedResponseDate); + errors.add(format(NOT_VALID_DJ_BY_ADMISSION, caseData.setUpJudgementFormattedPermittedDate(extendedRespondent1ResponseDate))); } return AboutToStartOrSubmitCallbackResponse.builder() diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandler.java index bc39dbf86fe..49a3a85d317 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandler.java @@ -41,6 +41,7 @@ import uk.gov.hmcts.reform.civil.service.Time; import uk.gov.hmcts.reform.civil.service.citizenui.RespondentMediationService; import uk.gov.hmcts.reform.civil.service.citizenui.ResponseOneVOneShowTagService; +import uk.gov.hmcts.reform.civil.service.citizenui.responsedeadline.DeadlineExtensionCalculatorService; import uk.gov.hmcts.reform.civil.utils.CaseFlagsInitialiser; import uk.gov.hmcts.reform.civil.utils.CourtLocationUtils; import uk.gov.hmcts.reform.civil.utils.JudicialReferralUtils; @@ -110,6 +111,7 @@ public class RespondToDefenceSpecCallbackHandler extends CallbackHandler private final RespondentMediationService respondentMediationService; private final PaymentDateService paymentDateService; private final ResponseOneVOneShowTagService responseOneVOneShowTagService; + private final DeadlineExtensionCalculatorService deadlineCalculatorService; @Override public List handledEvents() { @@ -566,8 +568,11 @@ private String setUpPayDateToString(CaseData caseData) { .format(DateTimeFormatter.ofPattern(datePattern, Locale.ENGLISH)); } if (caseData.getRespondent1ResponseDate() != null) { - return caseData.getRespondent1ResponseDate().plusDays(5) - .format(DateTimeFormatter.ofPattern(datePattern, Locale.ENGLISH)); + LocalDate extendedResponseDate = caseData.getRespondent1ResponseDate().toLocalDate().plusDays(5); + return deadlineCalculatorService.calculateExtendedDeadline(extendedResponseDate).format(DateTimeFormatter.ofPattern( + datePattern, + Locale.ENGLISH + )); } return null; } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java index 5be7112b21d..63d6365fd37 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java @@ -880,10 +880,9 @@ && getRespondent1ResponseDate() } @JsonIgnore - public String setUpJudgementFormattedPermittedDate() { + public String setUpJudgementFormattedPermittedDate(LocalDate extendedRespondent1ResponseDate) { if (isJudgementDateNotPermitted()) { - return formatLocalDateTime(getRespondent1ResponseDate() - .toLocalDate().plusDays(5).atTime(DeadlinesCalculator.END_OF_BUSINESS_DAY), DATE_TIME_AT); + return formatLocalDateTime(extendedRespondent1ResponseDate.atTime(DeadlinesCalculator.END_OF_BUSINESS_DAY), DATE_TIME_AT); } return null; } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/sealedclaim/ResponseRepaymentDetailsForm.java b/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/sealedclaim/ResponseRepaymentDetailsForm.java index d5ef37d76de..ecacb8ca9f9 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/sealedclaim/ResponseRepaymentDetailsForm.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/sealedclaim/ResponseRepaymentDetailsForm.java @@ -27,7 +27,7 @@ import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.COUNTER_CLAIM; @Getter -@Builder +@Builder(toBuilder = true) @AllArgsConstructor @EqualsAndHashCode public class ResponseRepaymentDetailsForm { diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/sealedclaim/SealedClaimLipResponseForm.java b/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/sealedclaim/SealedClaimLipResponseForm.java index ad5b44ed543..91c0bfdda51 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/sealedclaim/SealedClaimLipResponseForm.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/sealedclaim/SealedClaimLipResponseForm.java @@ -37,7 +37,7 @@ import java.util.stream.Stream; @Getter -@Builder +@Builder(toBuilder = true) @AllArgsConstructor @EqualsAndHashCode public class SealedClaimLipResponseForm implements MappableObject { diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/sealedclaim/SealedClaimLipResponseFormGenerator.java b/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/sealedclaim/SealedClaimLipResponseFormGenerator.java index 754d9ef596a..42a5ae911ac 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/sealedclaim/SealedClaimLipResponseFormGenerator.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/sealedclaim/SealedClaimLipResponseFormGenerator.java @@ -7,12 +7,21 @@ import uk.gov.hmcts.reform.civil.documentmanagement.model.CaseDocument; import uk.gov.hmcts.reform.civil.documentmanagement.model.DocumentType; import uk.gov.hmcts.reform.civil.documentmanagement.model.PDF; +import uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec; +import uk.gov.hmcts.reform.civil.enums.YesOrNo; import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.model.docmosis.DocmosisDocument; +import uk.gov.hmcts.reform.civil.model.docmosis.sealedclaim.ResponseRepaymentDetailsForm; import uk.gov.hmcts.reform.civil.model.docmosis.sealedclaim.SealedClaimLipResponseForm; import uk.gov.hmcts.reform.civil.service.docmosis.DocumentGeneratorService; +import uk.gov.hmcts.reform.civil.service.citizenui.responsedeadline.DeadlineExtensionCalculatorService; import uk.gov.hmcts.reform.civil.service.docmosis.TemplateDataGenerator; +import java.time.LocalDate; +import java.util.Objects; + +import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.FULL_ADMISSION; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.PART_ADMISSION; import static uk.gov.hmcts.reform.civil.service.docmosis.DocmosisTemplates.DEFENDANT_RESPONSE_LIP_SPEC; @Service @@ -21,10 +30,12 @@ public class SealedClaimLipResponseFormGenerator implements TemplateDataGenerato private final DocumentGeneratorService documentGeneratorService; private final DocumentManagementService documentManagementService; + private final DeadlineExtensionCalculatorService deadlineCalculatorService; @Override public SealedClaimLipResponseForm getTemplateData(CaseData caseData) { - return SealedClaimLipResponseForm.toTemplate(caseData); + SealedClaimLipResponseForm templateData = SealedClaimLipResponseForm.toTemplate(caseData); + return getRespondent1RepaymentDate(caseData, templateData); } public CaseDocument generate(final CaseData caseData, final String authorization) { @@ -43,4 +54,30 @@ public CaseDocument generate(final CaseData caseData, final String authorization new PDF(fileName, docmosisDocument.getBytes(), DocumentType.DEFENDANT_DEFENCE) ); } + + private SealedClaimLipResponseForm getRespondent1RepaymentDate(final CaseData caseData, SealedClaimLipResponseForm templateData) { + if (!Objects.isNull(caseData.getRespondent1ClaimResponseTypeForSpec())) { + if (hasPayByDatePayImmediately(caseData)) { + return addPayByDatePayImmediately(caseData, templateData); + } + } + return templateData; + } + + private SealedClaimLipResponseForm addPayByDatePayImmediately(CaseData caseData, SealedClaimLipResponseForm templateData) { + if (caseData.isPayImmediately()) { + LocalDate extendedDate = LocalDate.now().plusDays(RespondentResponsePartAdmissionPaymentTimeLRspec.DAYS_TO_PAY_IMMEDIATELY); + LocalDate payDeadlineDate = deadlineCalculatorService.calculateExtendedDeadline(extendedDate); + ResponseRepaymentDetailsForm responseRepaymentDetailsForm = templateData.getCommonDetails().toBuilder().payBy( + payDeadlineDate).build(); + SealedClaimLipResponseForm.SealedClaimLipResponseFormBuilder templateFormData = templateData.toBuilder(); + return templateFormData.commonDetails(responseRepaymentDetailsForm).build(); + } + return templateData; + } + + private boolean hasPayByDatePayImmediately(CaseData caseData) { + return (FULL_ADMISSION.equals(caseData.getRespondent1ClaimResponseTypeForSpec()) || (PART_ADMISSION.equals( + caseData.getRespondent1ClaimResponseTypeForSpec()) && caseData.getSpecDefenceAdmittedRequired() == YesOrNo.NO)); + } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RequestJudgementByAdmissionForSpecCuiCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RequestJudgementByAdmissionForSpecCuiCallbackHandlerTest.java index c113efe39a6..3f906a4b330 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RequestJudgementByAdmissionForSpecCuiCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RequestJudgementByAdmissionForSpecCuiCallbackHandlerTest.java @@ -11,6 +11,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import uk.gov.hmcts.reform.ccd.client.model.AboutToStartOrSubmitCallbackResponse; import uk.gov.hmcts.reform.ccd.client.model.SubmittedCallbackResponse; +import uk.gov.hmcts.reform.civil.bankholidays.WorkingDayIndicator; import uk.gov.hmcts.reform.civil.callback.CallbackParams; import uk.gov.hmcts.reform.civil.enums.CaseState; import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec; @@ -24,15 +25,19 @@ import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; import uk.gov.hmcts.reform.civil.service.FeatureToggleService; import uk.gov.hmcts.reform.civil.service.JudgementService; +import uk.gov.hmcts.reform.civil.service.citizenui.responsedeadline.DeadlineExtensionCalculatorService; import uk.gov.hmcts.reform.civil.utils.MonetaryConversions; import java.math.BigDecimal; +import java.time.LocalDate; import java.time.LocalDateTime; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; import static java.lang.String.format; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.when; +import static org.mockito.BDDMockito.given; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_START; import static uk.gov.hmcts.reform.civil.callback.CallbackType.MID; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; @@ -65,6 +70,10 @@ public class RequestJudgementByAdmissionForSpecCuiCallbackHandlerTest extends Ba @MockBean private CaseDetailsConverter caseDetailsConverter; + @MockBean + private DeadlineExtensionCalculatorService deadlineCalculatorService; + @MockBean + private WorkingDayIndicator workingDayIndicator; @Nested class AboutToStartCallback { @@ -75,6 +84,9 @@ void shouldReturnError_WhenAboutToStartIsInvoked() { .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) .ccdState(AWAITING_APPLICANT_INTENTION) .build(); + given(workingDayIndicator.isWorkingDay(any())).willReturn(true); + LocalDate proposedExtensionDeadline = LocalDate.now(); + given(deadlineCalculatorService.calculateExtendedDeadline(any())).willReturn(proposedExtensionDeadline); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_START, caseData).build(); AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler .handle(params); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandlerTest.java index 15c778c9771..9eae8beac2d 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandlerTest.java @@ -18,6 +18,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import uk.gov.hmcts.reform.ccd.client.model.AboutToStartOrSubmitCallbackResponse; import uk.gov.hmcts.reform.ccd.client.model.SubmittedCallbackResponse; +import uk.gov.hmcts.reform.civil.bankholidays.WorkingDayIndicator; import uk.gov.hmcts.reform.civil.callback.CallbackParams; import uk.gov.hmcts.reform.civil.callback.CallbackVersion; import uk.gov.hmcts.reform.civil.config.ExitSurveyConfiguration; @@ -69,6 +70,7 @@ import uk.gov.hmcts.reform.civil.service.Time; import uk.gov.hmcts.reform.civil.service.citizenui.RespondentMediationService; import uk.gov.hmcts.reform.civil.service.citizenui.ResponseOneVOneShowTagService; +import uk.gov.hmcts.reform.civil.service.citizenui.responsedeadline.DeadlineExtensionCalculatorService; import uk.gov.hmcts.reform.civil.service.flowstate.FlowState; import uk.gov.hmcts.reform.civil.utils.CaseFlagsInitialiser; import uk.gov.hmcts.reform.civil.utils.CourtLocationUtils; @@ -170,6 +172,10 @@ class RespondToDefenceSpecCallbackHandlerTest extends BaseCallbackHandlerTest { private RespondentMediationService respondentMediationService; @MockBean private DeadlinesCalculator deadlinesCalculator; + @MockBean + private WorkingDayIndicator workingDayIndicator; + @MockBean + private DeadlineExtensionCalculatorService deadlineCalculatorService; @Nested class AboutToStart { @@ -1362,7 +1368,9 @@ class SetUpPaymentDateToStringField { void shouldSetUpPaymentDateToString() { when(featureToggleService.isPinInPostEnabled()).thenReturn(true); + given(workingDayIndicator.isWorkingDay(any())).willReturn(true); LocalDate whenWillPay = LocalDate.now().plusDays(5); + given(deadlineCalculatorService.calculateExtendedDeadline(any())).willReturn(whenWillPay); RespondToClaimAdmitPartLRspec respondToClaimAdmitPartLRspec = RespondToClaimAdmitPartLRspec.builder() @@ -1389,7 +1397,9 @@ void shouldSetUpPaymentDateToString() { void shouldSetUpPaymentDateToStringForPartAdmitPaid() { when(featureToggleService.isPinInPostEnabled()).thenReturn(true); + given(workingDayIndicator.isWorkingDay(any())).willReturn(true); LocalDate whenWillPay = LocalDate.now().plusDays(5); + given(deadlineCalculatorService.calculateExtendedDeadline(any())).willReturn(whenWillPay); RespondToClaim respondToAdmittedClaim = RespondToClaim.builder() @@ -1417,7 +1427,9 @@ void shouldSetUpPaymentDateToStringForPartAdmitPaid() { void shouldSetUpPaymentDateForResponseDateToString() { when(featureToggleService.isPinInPostEnabled()).thenReturn(true); + given(workingDayIndicator.isWorkingDay(any())).willReturn(true); LocalDate whenWillPay = LocalDate.now().plusDays(5); + given(deadlineCalculatorService.calculateExtendedDeadline(any())).willReturn(whenWillPay); CaseData caseData = CaseData.builder() .respondent1ResponseDate(LocalDateTime.now()) diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/sealedclaim/SealedClaimLipResponseFormGeneratorTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/sealedclaim/SealedClaimLipResponseFormGeneratorTest.java index 7d56c033818..299d334a0e7 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/sealedclaim/SealedClaimLipResponseFormGeneratorTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/sealedclaim/SealedClaimLipResponseFormGeneratorTest.java @@ -50,6 +50,7 @@ import uk.gov.hmcts.reform.civil.model.dq.RecurringExpenseLRspec; import uk.gov.hmcts.reform.civil.model.dq.RecurringIncomeLRspec; import uk.gov.hmcts.reform.civil.model.dq.Respondent1DQ; +import uk.gov.hmcts.reform.civil.service.citizenui.responsedeadline.DeadlineExtensionCalculatorService; import uk.gov.hmcts.reform.civil.service.docmosis.DocumentGeneratorService; import uk.gov.hmcts.reform.civil.utils.ElementUtils; @@ -81,6 +82,8 @@ class SealedClaimLipResponseFormGeneratorTest { private DocumentGeneratorService documentGeneratorService; @MockBean private DocumentManagementService documentManagementService; + @MockBean + private DeadlineExtensionCalculatorService deadlineCalculatorService; @Autowired private SealedClaimLipResponseFormGenerator generator; @Captor @@ -334,6 +337,59 @@ void counterClaim() { Assertions.assertEquals(LocalDate.now(), templateData.getGenerationDate()); } + @Test + void shouldGenerateDocumentSuccessfullyForFullAdmit() { + //Given + CaseData caseData = commonData() + .respondent1(company("B")) + .respondent2(individual("C")) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .defenceAdmitPartPaymentTimeRouteRequired(RespondentResponsePartAdmissionPaymentTimeLRspec.IMMEDIATELY) + .build(); + String fileName = "someName"; + DocmosisDocument docmosisDocument = mock(DocmosisDocument.class); + byte[] bytes = {}; + given(docmosisDocument.getBytes()).willReturn(bytes); + CaseDocument caseDocument = CaseDocument.builder().documentName(fileName).build(); + given(documentGeneratorService.generateDocmosisDocument(any(MappableObject.class), any())).willReturn( + docmosisDocument); + given(documentManagementService.uploadDocument(anyString(), any(PDF.class))).willReturn(caseDocument); + SealedClaimLipResponseForm templateData = generator + .getTemplateData(caseData); + //When + CaseDocument result = generator.generate(caseData, AUTHORIZATION); + //Then + assertThat(result).isEqualTo(caseDocument); + } + + @Test + void shouldGenerateDocumentSuccessfullyForPartAdmit() { + //Given + CaseData caseData = commonData() + .respondent1(company("B")) + .respondent2(individual("C")) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .specDefenceAdmittedRequired(YesOrNo.NO) + .respondToAdmittedClaimOwingAmount(BigDecimal.valueOf(2000)) + .detailsOfWhyDoesYouDisputeTheClaim("Reason to dispute the claim") + .defenceAdmitPartPaymentTimeRouteRequired(RespondentResponsePartAdmissionPaymentTimeLRspec.IMMEDIATELY) + .build(); + String fileName = "someName"; + DocmosisDocument docmosisDocument = mock(DocmosisDocument.class); + byte[] bytes = {}; + given(docmosisDocument.getBytes()).willReturn(bytes); + CaseDocument caseDocument = CaseDocument.builder().documentName(fileName).build(); + given(documentGeneratorService.generateDocmosisDocument(any(MappableObject.class), any())).willReturn( + docmosisDocument); + given(documentManagementService.uploadDocument(anyString(), any(PDF.class))).willReturn(caseDocument); + SealedClaimLipResponseForm templateData = generator + .getTemplateData(caseData); + //When + CaseDocument result = generator.generate(caseData, AUTHORIZATION); + //Then + assertThat(result).isEqualTo(caseDocument); + } + private static AccountSimple account(@NotNull AccountType type, @NotNull YesOrNo joint, @NotNull BigDecimal balance) { AccountSimple a = new AccountSimple(); a.setAccountType(type); From 241f9d410766336d1c07bedf576a19b19d27d1b0 Mon Sep 17 00:00:00 2001 From: drummondjm <93932689+drummondjm@users.noreply.github.com> Date: Thu, 9 Nov 2023 11:02:46 +0000 Subject: [PATCH 16/28] sorted alphabetically, hearing court list for hearing notice (#3543) --- .../civil/handler/callback/user/HearingScheduledHandler.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/HearingScheduledHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/HearingScheduledHandler.java index 7426e988ea5..4c962b98090 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/HearingScheduledHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/HearingScheduledHandler.java @@ -131,6 +131,7 @@ private DynamicList getLocationsFromList(final List locations) return fromList(locations.stream().map(location -> new StringBuilder().append(location.getSiteName()) .append(" - ").append(location.getCourtAddress()) .append(" - ").append(location.getPostcode()).toString()) + .sorted() .collect(Collectors.toList())); } From 9cdd7ffc59930b9c7aac58884ae060a0ece30bc7 Mon Sep 17 00:00:00 2001 From: karthick mohanasundaram <92928238+karthick-mohanasundaram-HMCTS@users.noreply.github.com> Date: Thu, 9 Nov 2023 14:21:31 +0000 Subject: [PATCH 17/28] CIV-11262 Judge Order and direction doc (#3521) * CIV-11262 Judge Order and direction doc * CIV-11262 Update GA Order Document Solicitors Name * CIV-11262 Consent order document * CIV-11261 Update Assisted order document cost wording * CIV-11036 Update label to bold * CIV-11308 Show recital text GA assisted order * CIV-11262 Set sensitivity to public * update free form order --- .../templates/CV-UNS-GAP-ENG-01067.docx | Bin 22921 -> 23905 bytes .../templates/CV-UNS-GAP-ENG-01068.docx | Bin 28733 -> 23663 bytes .../templates/CV-UNS-GAP-ENG-01069.docx | Bin 23226 -> 23669 bytes .../templates/CV-UNS-GAP-ENG-01070.docx | Bin 76664 -> 23869 bytes .../templates/CV-UNS-GAP-ENG-01071.docx | Bin 76330 -> 23762 bytes .../templates/CV-UNS-GAP-ENG-01072.docx | Bin 29058 -> 24428 bytes .../templates/CV-UNS-GAP-ENG-01073.docx | Bin 28997 -> 24133 bytes .../templates/CV-UNS-GAP-ENG-01074.docx | Bin 37216 -> 37263 bytes .../templates/CV-UNS-GAP-ENG-01075.docx | Bin 17844 -> 23180 bytes .../templates/CV-UNS-GAP-ENG-01076.docx | Bin 34472 -> 33657 bytes .../templates/CV-UNS-GAP-ENG-01077.docx | Bin 33564 -> 33731 bytes .../templates/CV-UNS-GAP-ENG-01078.docx | Bin 24277 -> 23432 bytes 12 files changed, 0 insertions(+), 0 deletions(-) diff --git a/docker/docmosis/templates/CV-UNS-GAP-ENG-01067.docx b/docker/docmosis/templates/CV-UNS-GAP-ENG-01067.docx index 3709881c7dc07c57cb329321e861a916f1e94bc8..1016e0a18c4e8b1898fa37ba0f047f0dfe7187e2 100644 GIT binary patch delta 11687 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 L0f1qxzgPbcD7p-O delta 10577 zcmZviWmFx@wzhG1cY+fnxVyUqcXxM(g#`DtaCZn0T!Sni5L|-0OK^9)+2?%Y?7Q!G z`bUo*-PKZ6PtU6Nt-19bGP)5GUsVAb1_uHT0s#U7f&!v+-?6$85&}ZL9-jjWfM1F; z+Agb4e}iH31hKQ0+Glp4;7s<+j4I~1rZ&Fvi|ei_gU!nv*^~nAn*+0*ivw1 zBxqRr&hn?j+@Tv^poyRWpf!1DHjMCd*bR!^?(Ea2Fj;SZDseF}i@;#E%r#Ueb_%)X zK>wNPBF59@SRbzs5Iwh9{1ufONAjx$r9Q8sJ_r_q=Ae8k|A`P&p5t8j4#gU zMyP^I;;E}Fv$)o`%Ud7UXF2t@p@&Pwh|vuwTyTFeXkZ`AbSCmU{;<1X{t09RvV0|h z;Z3Kp|AdB(TaHb-p+yi^@F6s5*EPqwm;gE}kE5t?J90m^6U$DUthk*|+`Q=qry@F& zy0L>65~qDARs^L%HWI@F%fVi#(_Cb1&zF3CrmVFNH6GJ2pM$&|C3#E)y=Cqsxqq`t zW8)9*@9)qM|HPl*ol6QC4FaOc5~K)E05CXqTH(ce1NU@?Z5rZm^pwpTHV6#&r0pt) zIPutU2!IKrTewms#fo;?!XWqAyo{amEG95%9`OcSa+Z}>V4CS;ULJCh(a|l-L|%Nz zWu{5TuaaoenfFRpfi~NX9~7n2zvVl_;d?2J@X0}8)qgQ+vEp=o^|`$Vzp|df0mkzC zIk&JxseQe(p3=Xu9oV+6O}w(j%e}Fqy~gc13>iN$IW=yv-q`w&G!%Rri7`l-j(g;s zG!=}b_NI1Db$NSrvJsOmn<9j~Z4sd*EWdY0v2?~LUb9^}7PW)^kff?PU)a=DIL6(e z2R%&;30cKOT}(I)-IqC@H0w!S1t0{rBv|lB=((5sto7>3WBc%0=qmEAS`~XKHY9>> zpn}!=eyp$}J)*E$HilA|Ue!ZV{nn)F*Q?_RolDRarDCp7U9_|Z(yTSSORbTA^_F_S zQoAqs<@BS^C6~MF;PXUP_tK~D*lTO-bvSzV)|^m64bBrSf z0h^5oqTjt?`Yuq>F8HCr_UVa$5E<4gim+)mEwIJi55%CW)(4aU0GxUtjm8&BA)kt$Mr@+TQ;Ii)TrkTWi&ykskFs+)UNbY z0+Clpx8_i32MdOkCxPM4Ln2n$xaOLZls$%0R{-q=*y$&HW&h3Zv5~HWH z$2YIHrvmFj^^~2(MF7Cr-|Bu~+PhLHWo)sUyd_%&shtLq2f#EOZ%34-zJXY=P$~I$ z?NeLh-0^BPt+#ACmkBi4$cx*s$EImaQ3q9@p(lL}7D;jF84UTUK~c3lV547J3_})s zmOWT`66(Nb3dPrjGx$SVD!IIdI0f+3ir}t>U#uDBW?TBMK0puAGg^fX|A`*XesVBK z6}Z!o<#nx+x}~8nI4Q!%`&-;_fHcnMHvhinzPqlx0v{_CFQ^|KbxtSa-TEN1Y~|47 zq}z*9eJJjAdT=Ckh7R? z{LJQ9o^sUf1i*celHfN{Z`|lOetjc0!&iQ*Vfe%H>c#AR{!znC1TQf@VGm>I4Ja3& z&{)&7G;l#_V#jwkVyiL0>F78GSe-SNRW`R3(x3A%m(p2j)?ATtcJ55OL0xlmjpwHV z3l||9cSSu^rTU<)kZ|9ydnjz77030H^A3-g1lR>J0T2=%U&qi*%A_?-aO_Q8<_}lW$fI-Z;<}&hI67-szF@qRl96!a z<7eF+y-xBejgcH3-)iFu$C1szftA0z5Yd*lt9S;Mie(Ad=VS4WO(RB-!_1SiiU7eix*r>6q*5 zgBfp6>E9KWB&4g3Yy5mv{QBqVWsY%GPLrDVNHfA+P-W+U_>?+*CvXFS6%dwIO72EZ%? zED;Pv9P8zR^y`zh9;9>fPCA~y81A5%h0HV&N9`1-Dt4G+g(IehvL5iH`>-P`ynerF z`BdntH!$4zN$!PhGzMpQN@H#6^ZP?EoT;gf;rU{ky#T%OGOYbhFF>%^c{zd^I!>f& zbO>u1C35y4&qmillbX|6LEN#qME?Z`zzhvXMjOs6uOKgrau!7T)RvuGKv~d^Zs-Rj zug@`3REtKXp_FpyH+tFWzOQ_6ssEg@&1Z_J(lziUQaHLOld}kM9HBgf6ZKIiMyx=N z>5+*r0#fP4EE0y~#oN1<1DGHINP>i(WjIX0vs-6>H#f=!JGlgClVmAnaL^6|qV7y4 z53Zj|R(E#D`H!Gd6nK+ORyH6QaA_eq={;w%@KVsE70!A#={eSe8RWfHwb#UiVgxj( zld!U^*H|LRxITUqaG9Q^LAH;Eu|n{Z(~9hfvomCU{6Bbg_QeK z+4K@HHBSsF!8)BPX7jO}5=ufWpj4YWc|f6eptwKM;h-t6+~+Fo`eXL(OI!kFuAsU| zk?veVv2M*)-ca=h){{Ar{`tK@^SKWl&t3A>TjbR#{Au@OC>yKgBqL9cr_0G<+S+mM ze(rcTnn$%#nVC1qid}#apmY9uhKV3(g5n&iwBNL^A%6-$h6Fz|_svwU7?PTP|0v5s zu*A2p6ka{GT+e7?7Exp2^j@iJtTy2crh}QK+%=x=Y5$rPYk()0+SW~VOU~1^NdnfI zUq#eEq4b`(c1(p^g-kb-XYsOL>JD*rcgx%AW#prfcjM@$6laYbz+rYH%(%ZTgJ4B} z9hhf(+CW=^g6#aM~!%STLF` zmf*lutKzLz(L~JMC~|1mX5Z3UQ~< zCj&d!J{*+~7iRZ(p$jqNM0@EB0mY_=%cMfOrHyM<)YQ@dj&k#~Eju`3s>ErfTS+fg zyw|87x!VW=yM0Km^o5^ZcvFg1+#ieI2rW$mM&`PnY+>8AX5c4gHEAH@GZAlGjY2|{?e$NQR}bP>b-;pvRy+e@KcuDR1u7zwtbf=|5eX!Y ziX)Y#BKfKS@a=+O8Rdia@IwO^MkMn_M;0LEM{(1Qfv|z_%8!NNVutCsSUbO(B1gZ_ zEiCQz+^I_T@seq%$${mV2X3wFLYm=Vzq!!aQLG_I@GEGwuWExGqZn|Sbq96J9T#8D zSD*|PqbzmFd+`Rt5X{J%9bH2)dOtMeH}1uoh@hPV<`+b72 zhoQjF;n>wj|CO0^-I)+g^*83mxg@Hq+$Pk0msO9^MJMo0`5W}{8TeZRAL&fWFf{<4 zI!IIykj;9BAWj~7uS!4}_YM7XB9p@o!b*u_?5WfT(Mzhmn61&6LIQC)Jb{(?yr`5vWaZ& z20?6{b(u|~xLkw}5d19<6kbdMHcME3WvAyffG^OL3irbOX?pF6>|V^)2*g4~ds%gm z)z(Csb-E+K96{Kp3z`~aT3yPeAIB3Wj_PQM48O4^#buv6+p%CWk6fk`Dk02SetY_L zl)CvbR~C5LS)K4oI@+#qEHA<)uS8ASotg_Ec=Vi)FFN^}N=K2JNn1q*B_nHc`wE09 z19DwO3fxbPyQmB(xbhqf7j;|;@?_Nl zNV2`USnnGpeo(T-4QIJd#%Iq+ri8yI)d{wbCMs?5h|YpN+dE$lYQca~al?3#R_8)~ z8-X}A_yA~gcYhaY@&qb?+qEV8N#ElnptCU$UuHmi2jL86@w#9s@c5U0^5lR8UND6h zdS?BPdCyc;E}q#jf0%G>`n*COZ9qOnO{3$G-Nkr+tO8kOW9=UuEPh0)Nl%IoU66L9 zv4BlXRblMe+2DuuTY&m3XBy)J1^b%vEs92y%>Zqj-~AGP6!R@o#IXQH{ZVHT;A^Mj zuOs)JW3tAEl$6B7I5)i#j}EMx5IpEG^h~IU+D3k7aJi7V!BB)BuH6XZb+q!UjOQY& zkZLaH*<2UHk$!kS$nJKu6u5G?-0Kj;;+^PSnzCnhpEILde49sWS6e&p^ZLmS)#aJj zc=)K^h$a;~%gfH`7k?@*<4iuU@aWBAbwR6Q84``8W_fJ9deuq?yMLvVM*3VRp4$z} zf0dBLIgVzWe*}3qY$GWl6C_|*`3EbG)V=JB#IBGlRso9LG^+R!ULSnhw1mJ>1Oq^;s~*lKjT*Vq z5M7PLN7_CQyKA2tOoIC|pg-@a-5XZD4v*nO89J{&Z}0i6M|oiMYP{C)T`n)H}o z=L;vPU$Z2^TZF#5{~jwF_^3M+;6B?|{eUrDfWUjV3FTmI{6c9Fz_Vywr$Qd=?SM7& zpveVhGl;Z+=nWV0E|>YDdzmMW1%x~`Dvvznjb2~z!F}R-p*N#@{BYJMj=;23<~_0~ z#{nbs;2G=uUt83&=8>@wlt%mk;Fisb5pgas<89K`3j09t)2qxAsC>q+^b8S`6i@q` z73gr%dLC1ZJ&i)EZah?HCi2>$$6W2CB6yvkK}(^{oUTcBUeYA4XD4WafPD~C{W`0MOJyM|&&O>(5tSwlI6KLZP1toB zM38EqMT`k$rLRdz`$7bb>{QQdwxiAKb|j;~InlcWSsqoQqwi-&xHXqV_+4!D6Fm_` zC_-^vY?eWM7FBsAbQT&^NF|yrcifG#%e84qg@PUmmD2Z;Jyx~y9G}*n(jq8YZ#8#^ zEv<9R!Kb|fX$Y;w2J197fIplSYb{$wbUI{APZh<5oEw*ENSmS!x13#!!81Jb_6T71 zLEzB!(D;>$jPtmaiOD&*#A5^1!*ko)(piZd0%V=Z*nM0(xD z{ciyLO-)^5Xh$1cHu%4y+m&k?TmZ5mBmdv%dc!;fkM~bloV0*ClxKv4DJ_Z-`QxaG zpHDmbNOCrzAAlqV_a&Q)=vBHxPN4CMQU6$;HXlWBj!^ssHQrHR1A*X0 z5Nr3mZ1LQ1Wvxe!$_bPUxslphch9u5pBeHF?mp<}-`{;If-Ym=T{(0xT zgwFc?sQj|P7i?+T4qGIXO|1WXBwR1h;Y_{c&fq}ERbq?gn$l;X$h8)NUfOG+C4oi` zyV-O7)Gi(_q;P8d&Cy*r0&h_!$kR(ugz-It08U7GhJq+j7=X22qszFJ)O*?&Chm^8 zT4#Oz74kDYD^=6MXpz+zBOIlprvTcqt`^rp07Jr$<(>#3|4n~3d6h6D8hC(|DjAtYn|59>F~#Rq6<>wK(zV>?1HU-19k{ZSvYrkWMgn(!QT{Y+c<+Fo zDPMh4KyGyvo1oZJFn^328{E_eKBpUAc9bKe7N(XZ@xUmynfIka6OYb z@7k#YzZbfU8c)>pU8WROS~DT_!ruRbnhx!qB{3Hu2%OLHdg>MW;0l>Ob7kD>uDJ-W zZ+||1^xucE?;-REPM}FDJOJA#A4i9hw3UQ^1z*Nn(xh{2Xue`8?tae+h>=ZAj30OievTdFUyg0=jiy?!XWD|~>&1JgWXP~JetzYxnX1k2=q2&} ziG>MLL~0S|v6>ovx-Q?N;nz70X=VK-^$S(`IFDtBxa6*bN~HNOtwI$BU=+zp_WS#a zh0T<2p5;&>s-u)P0Mks(JSI;wSQ2WN>k^ngnlQpK0@zj=qZyXPZ6!mv{I;05Z($=F za*1be1FF7t)oTrPt5A(q<8jP^p4p3QYpuXMUTp3}qIsq;UU^fXhUQwx{U3DI#3%ls zJJxvB6^o>ow*0QQa@UQ@RTuwacJAY){l><2p?^{)p+N?4q<(3)`uarzZUOloX+l-G8&fr0Pd&^4zC&0(qm{*8Gb(!`9IF87Z$seKX< zO@qj$StLMtOlzmM<@7=!ee_^J5ioOAVyE{+;%MC3A1jdVVS)>LtFyb$$5xB@dFmry z{GAL1m+vS*6f-3fp73l>V6!HP-f75riL14v>&_ri%$`^EV_iIz6z7rzJKTy%J@TM= zivE_dMXqO4MqqAWW?T;OU}kq& z`dYE{+>`@wBP_PNA}KE_5d%_Il`>2}VW%YmV<^o%rYIR+;hVuAGQ-!=!aEb+*1uw? zmGz$(`gruIzT>+ywU7&~1149s?q4yqB(t&u`dlGwxG9uG1gR(aV9uWo*Mq6~y}4!F zlbFZ^|8Z~q@}=^{+-%c(Q7N)Q=)3HL`?x$JAQHt1?+iC9dlQZ{TLl(DKlr01DF6@G z+=!jkv2w+=A;D79wWed6R~LJ+z#RQWe+;#Unp^I?=!>R7{WVQmN&js0S=5Q}XAqJ1 z77v@+^B~ezb{hQLRKuXnN*PVwYWpslmab~6loJ{Dbru$EE^x-C178i)N`fQi>yxx) zZ&VL`h7`RWv7MHS+_7Rmc}vg~3Y`kI!mB0;Vy52lx$)eY%v-3a>jMw*+t=wT=F4QW zn8a^RrM*NYpVwM94lLIy5w}o9uC9;a+?;c_Yynkt))j=XnIeWt$0YW%iuF5`M`LL$jQZ)c~q;7-1uLYPpq zPlT#XfvYJC*IgKfod$P%d7N!vGg4c~RrYlg$ozm-2Uf6vM=X$w6wgD#oZ1!sk*qG-S&KbSrrJ%t6_6zTYCI}uBml_$-B<^eArY3<>eR|(?%%y+b zGj?Yc3mcW$H4vUrw!dE{^jyeJVH)RlW8L#z1e8Qhdh(lHq|(Ouhf-zFsm zyWdi(m7eThOC>sq@B$R<{G$#@_|i;#hb5{OE+4GP_-W?vz$_Waq1{+>Z<wElH^Q&apfeWyExrfT*DaGAEa&stCblHi{A2KZz5f5uq!gQapqlVFa=7Q+((H_>idA@3qT(M-z zo7W(=*K9PyCi4T}YLtaF3AVY8oH5>P&*5=4t!b_?kxnqNG;2S3YYMk~&hK}f$@Dgy z+IxlldR@$rA}Md6Z@er3Iu&(=7-Z$qzbUoZMA>>Zw6LuKfຄp)}6DIQ$3;BFI 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 Q2L%uS1^~>d{dx8O07yus`~Uy| delta 20497 zcmZ^}bC4%N_wL!YZQC}ct!dk~?f$myp0;hbch_UvZt|D0Nv~JD4JOFKHtnurc3^*}etvcc4A?roTw2;j|H$4Zw^5ZA z{HhJ)@Y9UQb>~caDHsFO3xX%0t?#F+IX1U9bI%NKH)x(s)<7OcR5EK8hHQsJ=2t(D z$3yBZDUQzb8$>w*9J##9RqR6Z%a+|CJ*-hy8QPY&`5n&EkJpCFDEipoW>!gKtzg-} z-iyf!XXaWGiCd!~tsHf)%#KmutBz0D%Il@4&9)oL3oEY?&Ykr)~#^bF@uM2KX7wvKchpA+`PU3oJ`g=rhak@p73KONHC&- z=eQ9`_;&Y4EzsnrAcfA6#vpMH*t{-;pdP)*LbD$fKm5;(vUK}gOumn3PkMcaeP)6} zhMA#w{$=c+1zbHmX4W-xqm5^`QV&fnP<;(HxEB^G%6s%9qoxmXcFUVwB&~!^tNbnd z;n1#T1$U=#^09XIc~vKy`$g2-2XbYuA4ZC_$yj;F>sDNQ)^({p?a5HoDXOEqV(wWOpsS`O`>4h~}*k@{&)$Bo8UuwJ`5 zy3)Fh5Sigak`=H~+Lb!-J#1825G%Bbk3te$Mwu4r;^dpJ1iHzlVU|gx> z)(i-!=%uLmJ8D?bc|?KnhmKk1g;<~&IjjZw`(ejXT_{%S1cmL~!p2RHXk`)UWR0B^ zz-aAbQG##{)L}?2C^pvoUB-e_N1lY+3ni^}@G;1`xvYfka0yd_h%HN(2}8S;DmzKQ zSm-cL)O{$_us}fMib=mAu>g2$b_e43z5!p5!ktiV0Z-vC`9la)N?F(j2!jVUb@D=) zHd33!YhY^)RbasP*qJ+%sWz%fi-uCmhMJ_jq=QDeORlb}PeQ&gU%DBRtxZ(MDcP-m z)SYAsG{*|KaI;$d+7MiyYtv7aj2P9FRf@+G8C2tVRM)(p6kuT#f|0NVM zV?jyUaMqWgA_kF$XFyO9y-34LP*aiISwmoBmYKquxtKJUNt6&T`S6LNAB4a2z(FQg z#2c8wgc)e)(Ao(JKhn4C=`L;6!bk0Db>>0eCYT;E&6F+^Z(-u701$AAS`nFdIb<{34s_O> zDyms+{m4VH`)ucGO;ah*j}b*w4(W>`h)VcdgbW?0Ad=A7JUDLks?v>X8j9~Mfy!in zrsD0+=y0&y;0y6*%s2-kTC>#Pv!rRDD07(A*8W0lOPC@2!oIU;Lq%)ev&Q{Ekqa%# zqTvxP>LfP(4d|Es%S~_;G%6ds0*-scYH@dv*PWd{#0){n+gCxk_({e{7&cW(Jl?NV zVt8^zWDMRe1w@)gfMU@`M&`ehNA-#%7nbt-F$IQm=9ydF6t1UeaOUv?Z{E>2gnqYfiK`?sRoR$oMkW|5@1TWKV0$lwtU6|VxF;(+%srDhO2SY;-hyGFS5#O= zwY)^S$|k9!6|T<^aRPY)HzVzctNVvmWi;4p`o|QwJ1NDt`o}Ur>W(JFRG{Grj4D-r z6CJO90Xq7=3CdzuP!snJpLCOumOs^PruByR>R``70$RrEx(r=0C{=@kpWl@B;19Bj zWroH0u(s`^Rc7Ouqe0Ma+{d|+HIjZPw!k+Msz>S{xg{p*eO zaZ!D3%HNw~;?0%s_vVO@*|gSkVDmaYUH9JV!qTdqAwKl2kSfy(G0919XsXjprdy8a zFK4P(y@o+{P={kRlx!}E5ku{Bt0ww&i7`<551^&8-n0Bm_0 zx($b4gyBjyVO3;Xo@yZ;4n>VUGbm{X9J*fHKDg88uLe}-=tWu=Nvp=p|Dv`L>U$g* z(`B%@X)-P6;`(hyR2_fB#A^GOY;xMz5A$`Vg%?~_%FG&qdG)VIZ} zZm=fX=?WEUgv+$JbXP(UH1OW|1K{pRP`9~RYzI?-e{-dmAj?=R+$_YuRHU>4Sx8Zh zrvzUYkZWqaVkY8D9TJ2;Ja^kM2iT}l!1XG(~F$$OB)VIdvQ#VFQXOKbIHwgO|jEFhuGV^ z!{%v5N1}CxuHF2s!Hza(|0}ZF@IF>rMLY4;bMthrWkue~Q5Etf`C4t#Ln!lCnI{a| z20C)MwPvt-UrvkUL*Ttb__)BFR%+`B4VbZ6SDy}ai%JJ}ueqW#1t9M0=3OjO{+B`r zY6o-qeEDkQHdeEF_Cvv8Ej1VKZ=h0OLg1`T5Omdr5@-x_xOx;3vNd6$P8#G@(jHfo zZ?UaSm&{pp=Wdp{0U!A*j*NTn89>;tEtTw?0x#DyXvlMqJJNipu20Rh4@YMll70Dl zV>STd0rOp#nU$P@AmE|#Jt^uWj!KC9)N?DxH+cAUrS2!qiQQ(fuIoC~ch$U|NCQ2) z7VQpUM3-Z+#>kyBi-$kKaYvQDXRJOe-#XMS8vNLI30ek$8I6fFhE=Ug2wjuCeY7$) z1lJ3+9W%9Pmzf^?iZ&=%q}|_~*nFuKl+;0Pn2@ji5ffoZ65w{oI&+eTl3`1ur7k!? zy`olQ67!qz9;VZB^n8oZZ*K{wL66qWfvaS{v&9fXe`qhuV#I+NY_`=GF z657tQb2$Z{eQsLWkz8W+PfmMM__HMj{#Gs@WOp6g0*kNlp!h_Tb_U)E^jnOc?W6E( z+4f3%>wYU+FQBv?QXhL+4CKWdIM}?b`xn0lkRs+Z^ylgP!4ne$dHy#FnG%ZPnHdSY z_-=2Z#jklFol(AYE#L^#1q@iFESv-Z%W$9C5uVvmBiGVhity}l5(oZGrMq5{@Wq)XLgC5UdP%CX9D?n1D}3<^@9WjiiS6xBXIkefuS|-oKKCnoXW=@p zsv{oZ4j{*mha|FOw0PD0>^!Bsy}-;YsbUgtTq63;jR|+x&SZoCQ{Y@VGo~-m6&HYc ze3sTTreAmMh?P{ti(KoGV&9lH8a&#HSep z%(;4%t{atkPgY%VnLI5J;@ve_{pPQf{sB>YMe5r}T)*nGZmet<=WH9b9&B(WJ)Nc! z26Xw#C$rnM4dhnm`P8@P@iFDE);>jqexj6b!3aE`vW{3fihVTo;rh+htk)H_vRO-s zQN|7>cWU)rXi1=lI^&7s>LGm*aL(N)noL z|GDT`y+!j5ZnSCEL85l(=Sm!Ywh7r~VN*{109@kyJ8_PDIJFpuw}Q-gf@CZd4*rFsZ0qBA{t_a=6b%>WQVxR z6RHs-Xo3r3-+K^`xLik5go8=JJ@fWfvhQ2jm%5W16Z7&<_z3F&r ztvpXmG%1mz`QS%`pNs$p#S;vEg`9$3`piDrY62Mm@1(Th@)+p-Sj zW&Y#Ui+I{?OT0t%ejAm@{^%{2faIg89DnQ~b_muxj$g|g?N_7qb{snpY>ma+*l zfLbx7w>TUCB|rCvIv@se`hy;Jk{*eFeRFkP{Uu^+&6jjMN7-<)j9At=ybz7TxZ(`K zhYFse5y$D33J5Z1Wfq<0Qq$_k$~NlF^KU zfW67UN5zKO5AV&9i-Y6}#GKEskHK!N$BblIx#6fW+fc!MqU?yb48d`^2D%f~4wSZ7 zvL^edESA=(XLTPglVTn}VVlBgeOK<2MBM77UHG-;NUxdgnS0%N0|oZQ)d{qcrfiag zGZ*zC(GWa4G3n5gvS_3hz)cl+e@isjeGj$?6|w(4A>&1NbzQ~3V*I%@Y@V!6_FM#H zST=y8UGB@&4u&6c6aW4JNG0*e8 zoW|i2_0oPd^XX7h$_2%d=_GU&Dh{u;RrnX8kY-ftZAll2nhx~?uOX?oYe&(+RAj-T zJFV*A>}PvU)sWEkdVi$q`@dGT{{=gnn`D7c1juAU3ccZ7a5r$dfpYMHLgh_bl%;gf zF7gEu8xu!$!II*5-f$1$ZtI^mV0jAZqkUfJrM()s+R{7hkHwx$*2z1i5d}_CDb}&W zIDM%doyP-TMov%Ek!tw`X*R!gf04RDV#ty_!Hf$eyk0ct62Nle5?Ei1jXI>Z z1-PmyL(!;S$zsu=O4{d&9=Mmo6-#ff+vX&3A1Z*6c=@s@CkE&8-eoVrW{$nm7I$Gb z3ADfMf{ldqCmP^7FBrirELp8Q_pgEcuTQbXc~Cc9u&A&9AD?o|6?pe0o1svwOhE1L z)~*={O>L;f0aZmD)bgDGu7Rc;w2Yxr?LpB3)J2dE9*qXzV3QksvX;@Be`%8@O#l{O zz0bzydpp<&=x$o+=-h+WwvU#VdP?N4W3Oq&S_7rj&ERoULwSj|iHF@V_T#g?G~K$cEl1$4Zy=Zrje+8`P!a3M^4yf{bh1kTjlv+h-xVqYpW zj*|e)x3yDUz`xY2+Ixcswx6W;n!PGIdAzWA#G3#y)Zf7F(A%d}Zr?eiO-ZMCy#<~C z#Oe?6m0`RPhMA*FNMn32?eDVL2edeudj8wyVIo zJ564<+Y@RHlz?WOjf~e?l zFhfD!mK;VIsy4W+4Y{n0rBU9Tv0f-YPqpEOK1GPt?mYiYTx$4Up#$i-qKI5jD+nL~ z8wDOxiaFH7AAxk1yhhZ>+j7!Igg?m&vSR>Vqs45q0!t6|Vp2euF0nzA`A*JLx}{L> z8=q3H=CTua&y3d9Lx2jh{2jwsu#-_?Il$Ysq<>pi%oRb< zNsjj$_vU3xt{0frJq`B=|2*F5`L1k>qPLUiCVCg-kW!ynv*2^{3zZH(|T%1AdUZ-0fWLvN=-UPSDo=xcB~R z)_|3_V}y{Q!wZR=%xZ715Ha9L2o)YxH?y!RhJJ{(8H|lzii(bf8E5vhcWxVAI;2V2 z>h5M#af%Df6fG4V$q*r-JQ2fyXw@_VJ)eSPPud>igRIZKZ{%7M)tn4MGv_J}KFdoN zkCMuELs6kWCe;c=O@3&BRl$n;NdP=)Q1Zbi*Jdy521-RLUypmJx(UDpg9m%}fz0-U zb1NoZwM3@oO?V4lTr)@C^4#bzDCNfvyE))p0L%)db~^UBdy5t>B))G5r!7$)%=d*q zpDg_7ml2`Y`D(Cj0*4jt6aM_7QaFE0OPPO>JyGW#8TjTQ(n*=c8FAKm|1F3L8NIs^ zXN;R8o`q#@NXPBj!wSGP(&7vXOhMMfyp1KJ0cDMpod%V`_wPbwq7x2wN!`zC4cmNC zim|J<0(aVe@^;}P5l$5k6yl`A(Zq26;D*`} zM4Wh1Wa%x7rnRFLa5+BQs1k6oe^>S$Kh>f&fTrNNgmlq@`K16?{si$=CPNMNg&^gC zRs;;8e(t3PNddU$8TG-JA#C8)+?r^^#$b_aKn#1_X@43hAjZ|o0qR|~R9 zY`&{NVzaA=Inc1OmvFUgIyD2->v3O#a0Y5U67o=#JGcRf)FGYT+%A}}*l@$0fx<4m z5ijrayAR#cWQ{rY@BSIT0lgsJ+*Ip;!m%6p-T}jt_YD4n6=%yPS9cu$bekM-$n@tDW zQa+va&r_W6`+6RtStZHGQlWufYQ1VH)&uFo#RVL@Gzls@i5gL8j5mDV$=+ z5Jr`1WZIKqQ`*U{J?N1?BB^ES&Nvs;z5y^+4z8~~#WtVcyYcB4UWMX7CzE%UNnz@G zvVg3*q-Ts_EZLW8KX>Aa03LlBuY{;ZWev=WeFX4E!$C9k{-G3!&9|m$j594hlkI-X z=rUN~%lsHy1i8mE%W4=Q{KZ-&6@fnj1Svy`4+z7%gXgk$hVV?j$`^0q=4tQ)Ir2a; zGp`|y*OyKaNB+Ow;WEy~OI%&|cx<`f8a zTL*#W(#`zQEHm=3N`|PB^14gz<%JpL>@Pos*0_w?=@=U^3FH+Pw3l^;Hs3=2M!1w4 zxcO!NH|g!;FB1nVtnF)!s?lvr86Zu!3wo4ne!DR95%a(0T7}fcD2w+#yali&*8nU$ zMond`$T!dswshUOb(O67J)=dfB?RHc)r|#f6lOio3G0Zxrd>;|73}VBGIR5Zf~x%f z=a$d4Of0)ho)Tj7oOPKAIjj2gqlvi3-#|iZ6N-xG_h=UPO(9>Ph}S&b7yi0>a9%04 zjC|%*j22R?*svWlC5vwQV~?S|e*s%joOrDq7YsP5{s{weOQ6|A?pArrzqcW}nJS@W zMCz-Wm}mGaEatH-6l8wOthP6nCRgBu2A%gijWPHF>gw6f*OALiegW}XE4!UI5F547 zRtT!Hl-!AuH(C_Jo|J7Ms`2|RJ2k={)Lbk$jC{;kt>nt1wY#_97KS)$&;SOM$EvPW zGEslg;^V8wNby;kH|S$7CjZUhfU8zR(;HAivU`eNI0{WzJ@|$x385O=%PoTuXjDjtm|PZZ>HZKo@5CgkFF0k&{B2MEAwnQ-xQ;iM=&$l`9AdK|; z_$f@|C~xSmxL$kYT!&g4Gqo+ZBP?-}k#YMna|y3fMP@Yp0&~!6Exj--$pRIU_cp|3 zkdx!Gn&pgIP{1x)mdxVBt5_+p4wIzSKpoiq+Xa_AT z(YWUF$HM%Ojl`BlVH=>|(`j{a1B|I#9AO>$Vi^x+dChc#7qW*PowD1FLVImoY<1o#yxvS)uJ^AZ)x$ErRZJZIFI!r$@LkX zo!Mu&)??R@784*^Q3K&*E<|H?P|BM5`GmheWn-#dgx2y!VTIAxuS>3pen`esIP{1T7a)%vHmONK8cMZo&CV&o!v4Ej2YZRn#T}!n^flvB zxa#w5Z7g{%Ju4>)30K{Z>1Znol8O73&|=&ww;YR;3IpFl2ZB!U-!CU20D#`>MlL1+ z2b2MvtN_i~_O*4m&sz0%%_+Es`5W`cv}v6vIj61U_0iwFvEEZ$wTg+CUPGxVfwxGaM*U8jKqz(lVDOs54D?uEyz z<>&q-LBH}UL^9w>zYY$L2PF+tAK9YW&Jr;OC9_@jx4=>(p*1#TrXxZmeEYIaUkY)6 zHIOsA0j8d2jD3$M?4c(6zWyY2R!}~Po3b7QIuvxdWb9%ir)6R)YjHT8m*>LSMd z_kJ4#ZZcCd9GopJOTIqt>^qWPhrd_vX>OTjhoi5H`=oK>>!tZg!+PZ}I75mN0}w(3t~F`*;`^^gf^?h@HuL@iHVh$| zN~=z03(V+f{sT66<(3<(tY+A0Vw0L<;k};wdWScGej6n{GDvHDpz~@QNlE`sI*lE> zMrF5l!1OyHb@ix1>ap}xp{MtbZn4%j+M6MFud4{`pm%ymOI!Ivb^0euyfY|1qw5He z2Q@Jm1otul)kaGei94a~#&Dwh9{@LpgP;O)T#`VNaY=-2p0q1->xz@-gz+ubk_BJV zn0f>jYbgd6)^aEj?E~O_`I;_CU$5imK7KYUE&{9^-C8knpGL@m@w}@^PqGbMpx10W z7<+~sY`t^-gA+eLpg{lAsFZ|=1qtApsqDr^00K(+|H2E_{{=7B;?}290ECv`kVDDG zA+-nKa2#(u>UvC-z>R~G$?8mc^)a?s(?0^G6TjR`lgbv-Qxh1fcPo@t1#`c$NB}>L zx82fa!x5+uv#RH?n$;Qs$Qg2VfEotOdsOXe09iRkS_US>vh$M>`4YhIWA^8j*M7rN zCtyM7?+ocdyO-obnJiL-W1SEE+di*29z}k(AG2^Sl4&;b|w-3MIS} z;QlK{9vE2tCO&PJ`0H2O@k#vYi)8gI@zM@yeXfYtiQKn0BqAxTzZh?{FMWt*7o`uq z+w43lkc8IxY3xZ6W*=FmJJvMxro01KDFKw<)~9VS#$H&-(b6=p^s5g4sL+So_n9L> z{Winw4nZ7h%1iyqzy;R;jS{2OjrlrxIk%XjoNW+xS7NnyZRSOK1`s2eKv+i+=#ljb1#7?Kc`^iv z=;wJ?s`4P+z6hB#i|_9TImcFoh!MpL;XOzcoq8(HH3K<#9;>VczQ@HFSuBtS0PQtD zM*n40a=h27aN4N{?V={r9F)R`hfl24JBs$;-}zeWf_C*oht%Qd5vwk6dz@99^Z14XO`SxBg+r5aV~ z6%s)QuAYx=(zpm>RidN56~?y$Ko$toOCvW^LnRJ1@F{G}HKjM6&`3?lCjKdclxncK zx-70$V|r&BiSzWj^UrlF5fV=wWNO~0xx2F8uP^+h85QD+8JuHSVTKPreH2 z@mb?gc&MobO`U7bd;|TRhg&ky=m3`KaCHDd{mZ|78WL)qex%SDe9}Z1o&xz-X({s9 z(@-EFbY+3$_pkNdyO1Z^dA#A~(~Uq=9*wI%qU^&6A|w$7&q1{?WVvS9qPjh8C(fPMa=IVIejM#LWCfAB(Jco1>`w`Y>D3=z{wl>oH3L{W#=m?GplNxV zxuBd63z|{={RVCR?tJP`O#D;$sQ=&v1uI*LBlwZ_oKxN#0EyPZSPUu(M!}#E__m-_ z$VO;&4mR%r z5QuX{hm&FM7v7F#Caz?;Vuz6#QKlLqcAjpN*sGDC;JkgjDq_`s{ zfWw)>rc|V09gxr(R-+Q#0vD2(87@~PbQ)CXpGH{U5l)?yqjUf#+v=Z+l3cHC3UWq(ArzQ1D z#+YhpAm~B~Og_BJ6Qo}MWF}r@OV7JUhQE4zO^i?1BDm)(IKsIS zHvyiSfZWP6U#gO^p*rSh_^6Y+wl1}}Kmhl9bHu=2gpreCRWnxyI74KHqsJ`i&3@}< z6h>mWU@20Q$DLSQE3}-zQ0C>cm!8>LqOwh%M4Sj85Ai12_?+Eo#@_yzGhChCvK*2# zwTUC%vEVtMg5{@rz~+TMwF)E|_bH8IP5i4ROxHK#r*3sH5rkFn9DxEn8o>`^EkGxF zGDh!>DxPC^Y1gzyl{-`}K92$EnYZtyl${2=EXnqA5E zUO;BB>?_2i;2*z8JImL#_t~4f1o(H3jy}GF#T2SG5l$bjOi9@ZZZ+M_1!0oyp+*K# zP6^|J55mGXR~m?2+&kQb{*o{0<_{>qL%Zr$I*d!v-&Jt%oz9s%D1Y4G2oJUCYK3*V^QmFr1w@cR(J)@V z2_WY7(ERHweE%KAbC$26OdJZn(DNepa^O7*0HVR^w?WS2!+xIk`+eKpTrv7oyjhf#PqJ zrE9p4sFXvQhvG7HPir@rRg8^w^6%e!bY4gD^oE;Uxh-oXx~;M4&YRB0`+>la<0CBM zl=mvyGP1egPcmQ$w4dI_cko8rq*NwV0g=({!jH1PyJ!65xZt3Opy%BY7c}?Oz4sG) zI!O&zE@t)}T6$cgfDmQg#4WmW^1sV>=(e(Uj7|6p(#AAYLRE~e!bdm+hNzIk`Erek zgQ~f56qe51tC`K&q*u1yLs~VLG?>iFF84b{vBP1D zR(6-taO7uc(D_WyVI~rV=!{7d9t)r#!$%{ua9qLFk$Ai>NNTk4HpF>zAjy1``Q{g|G3a%D}YVdL{k19!bO4=ljL`V;S zI9g@O>>R9WNhH(Vp{(jvIW0bk;VAj7<1I@BJT2g|AT zfcG5sZPho$6Lu+#zg&egg=OEn4u7Joh^50YhcxHymcq z*U zw0zc9#jRHjrE2Y$&u#1t7%c65u&?li$y$Sw0BjfL%FYcpDY5vmMcs!(Z+{HFth+bL zkr@h)^aQlAuFGdF=*3G>GpoV1V>ak#2iR^hXUH(2LgM~>+f`f#$rVza`sJtabirt{ ztyS;GI&IIWSMDvP*L7`Lr3I~C<&?E=xPHW@+iM>eNuD%%cs{ZX+_Dl|Pjz`f8^}>Q z1H4^QlJnIsGTx}wkDHru+e+-w;kotS6PKsJ=zn9lWoIy?lc%q7zkdE9deu=lY5$wx z*)#b-^>hoVmjRm;RAcx{bZ_2_pqQbb9fW+twY>x3Y|KR=7;Pev5(5-Lg1;G@+lwzhi+G6;@BVuNGb<-! z$jW_jXTs08S27c~Wfh+i7`rsI9cu(5mAZLSJT?g$tAmppA!PwN47gKPsVFX32H=FF z*cv-(M$7JPm#zG1C@srb`MZQ%LhG@i(xQ&FxcwXwxoE7}s#4@{I)^TmJlQsh7yX0pY7_HCLTu+ zcr(alYi+pAA!pwiKU>YO-}KD;b$9w|8@OOrP4yLtd$44xpg# zxXru19w9`V-Td6_@`_)weg6X-Pn5*i82|epxUH#)r6HrGt)aOoGlP|bX(I#G3=)78 zS@V4v3<&7rU)72Hzf+w}U0f{f%$@&JayF^&*za>8`3au=D>)w&?{ULhbdiZRYSuRv z{x0xm4*4$)#o9nl)La94>rqkjdQ>|rdzxl^Sa+gF5AJUF4xBX~-O^wOPF;7po! zv!`FWOEQF#3l64NnT`Ktb-%7+(e z6D31dqY*;wZ#^PIwwGidO1>}e%08x{Ni3ySM0C&eh(~$e%68eI?~K!m7L;g`1>KS| zL1uQrKJM@_t8u&XYWw?`u2SZA@iW(9n?Dv7y0#MZpxQSbuD`Yjpy6Yl!p+q1@ww(9 z^6DCUHV&f}S{_>^%Txo3E3bhG7-gLsK@SPvS3ls!Eh+`#*judf6e7Bn@oaOVA zBi3<}8EjISAh9=wlIK32q2BJ%xjzdjT<3U$v)+TER>U-lY@Nihiexx^2Sdf9i1&|f ztms`vg=L<1!+tm?z`cP!oh9mq!Ld~P4XJ86b z8wJy|gb?=>_G5-Kn5EK(0Cx+FObWxy4ztNx^==$pO~Y&ez@1~iGXp!Dd8lmIh1z6^ zb|ADEdC^@Js6ZXw`kFuux9689Eoe48r%jTX>rh^&bK-%7tB;H)l>^MUPNKbs^uug( zJQ$WM;b#bx9~w}}!~-T(+o(v0a{-u zM1`5)#_pL10KGUjU&YN~E5<9KLg>e}-~hX)blRV)E`Am5v8USXqVl5}A49gW5KW(u zOeYoBV^q#GFWDlPD+xq~(s&v@yBHOm!2|{t!ld)>eKR_hM~{- z%k~_~0BmZX)WnOsv~Y|}0%9po6aGO$py4R!VlbFnK<~Q~T$BYF2hDnzh~f4;+iF4D z#kbFX0#4=b*bnkqOR7QF+!YxumMWV>7WB}`FGXxlinS>tkpoi>AWLjN4F^2(x?a!q z!5l@ox!y$^>C3||x8?jDRl71v6}O-j6(tAN0FGN7D2>I<6lAK=qkJ9LgH=^j4iH<>E`OKW*&M8~v zLd+IXR>)%WbQbU3xaSe_=PPhCU$lCZlDl2Q(Uz-eelK}P44-#K@f6=4OaUqElAlyK z(Y~|rlu36aF%&;7sf(Y|-EWBhrEf`Ua)^L4l1L4me=S2azCb|#rvF#Vkh6=Yjp={i zfScL6?wLFop*QB$Z-{jI(>hJx;l`A@l>C)a85Guu9HnydwWjgLvOu0doa1j#q|k;z zoFFZ8hemcNxT|pjE!*_AeYYDojEbjU1yU0pJ{(xRgz$VgAAAOP2Wz{dgMg*Zq<~a2 zG6cynV=oSm;>M3%U&-ECgkMENNoT2`)}lHf@e5 z8LEELsG(?L>D6)eY$5#kYGMeTH@=*B;o2|bL$`=jrnf9`8>T>S@=qh+F{|vb zAULTA(JOR$f-7v_34aZGzv5`gox1x^HZ*($GG_nu4zRs`?k~i^VH?^1Ho5UlhREmh zntTqSefUAEtG{mK`Cun!vGY0*39b-;VNSrXEN_0Ax)R!0QUsI*#%@>SooS=He5!#@ z{|n##h4*UU)KfnVL>Q1HqLl}R%>L^m%w@>a%;E6U%ofno%#z^K%v8YB%y2GjqfD{$ zc!Nx04lLK1;)a%WgxKQVtgXJWbq6i-&~BU0*nP1Z1h-dhS9e?gf|-B8{Kmha>Tc7g z{AddbkUp$wpIpr~Ym}qNSjhNgNrpj}{JUdsTq=%24(ALgNrHnP`K9Dd)YqPnSi0!> z!IQ$7C9bv$-FuUQ?Ml}X=cj;pM$)fKl#J>Uf^E&rni}O8V4xr|B=7N4;kZvHu-VWA(3c8#?|~ON z4}V&kMpCZ&ZVwoEl!r$v0hr}6eW3;=&g!@(lyIL@%Q`O_W*nF8+~1v5?66HM_F85X z`Ykkle?9j#D1^M;R~T=8ZElH;9sTQOebT5KO$!JA^>Zek%ldRJB}{B!## z*fg`@KH>9tBG8$#HOq;`UvZ& z-E?*`JKf+=J|SFEQrGMpeA1^-arjDwn#eTria%HpGNx_&j;Y?&VSgqevz&-dRjBr? z$A4EmwNIYj$7e&T=anePOBhc^BNfr_c$VzQ|Z;h0Lhv3`u8t zVo)=Z9@vg!4s&dkg|F-7(u@*i;I8}|`pjx7IsTd=gR5{pl#Xok1nBmnL zV3Ft1qRCdH%Y1Z@N-SLuV6w*%?8KX8dOemcv@qAvwpsYKuDJ}~@3}x#AvyeU_;GIq z{3ypcop#k3F=`X1n2;Wrkd*#cQ{7B7sjp{2|M$#gT3-3Y24IUHc)v$W)IBl_VB_hx z-Q(0>{t?$_6rC-TyBc z;QzSi|G!REm+q2S#Uc)srl}Q~rf3xkUFm;q)@;P4lwYQfr!Pz0S%3`9EUBIEE z#^}66k6Z?uyTgzH*i$Zf@i|TWrVs8ggV|lEN!iVsXtEqjr58%%w8c3ym8m<=;t<mP2xuQe%jzrncI_qSQJA0PY85zmE zlbN!!k_aUuiOgIdS0LB{e9;5`+2^v&w6#?Lvn1#sf|Jx zgm@HUge6ZqvLY&z&$p8yz{^NcgyYO@aakS}zW|LO*Vk0;AYd7HcN0Q*&BbY+0l zRl;lVDGd@2xQN`Fa1%6p4YpZA(7^`FBhM?qTZ?HIk=NhWftf1GSLAp(FKv<7C^TFx zIjeN?EB)`b$dkhG6R{1Yyj@@L434wN#B+HFIw~``8rdK|(Pjo2@*+^`s`(pmZidyf z?p$N5xOJ~iu3AcAj<15#7+w+CR9a|d0jAoq#+c8{NxK&w(c?`pB)B?Vfv=`hAx2#U zv-e%wCb&@=IZAFC1oUfgDir_vi*=C`ssC4QopVU5nt|WMAwWvRvc&fnslMYS&0J;` z_dW%T_&@nj-tMUF{|EWs%1GR}pIj&SRAqtuU*ud~DQQCgCujnOKpM8V`!Dj(Ec_rk zY2nvYpnMpI$8TnF2&`XL(jf@4&j^v6nG^-z^vDc)fSg%-y}m2lY3kX>+~J(tGtJzq zeHl)@4ta~rmR}S6+)$_mexGr37mo<4Dye9+%1kYywS^s`Es|#zo#7lYpL()K52Ce{ zLbobxTEmeh>RTr&WGw>c8=Kargc|T>t2*?=NO@sZ$t_qphY`8HKZ8qYPEn8ehw&vr z<&m~ffa2m%#EcZ3_4RnBJy93-v7~*M#!EclPbMj=+zA8xH1u1d8&6j`mYGi%#)a5c zi|@b>SY_1E=-HmBp=}U*RDP_w)aWx0r}^RjZ*?Zqm8BmyTSwhzn!TeoF%-r;(9~@x zG%&AoJ&QP85dy}kQJUwB6 zPM`dC83fS}oWk;RZ|Gjr`G(7PmH+BuIuh+9Zx@6P&Ye~0XYA%|O-fEgF>Kmd#xhl&npTW#uzJ{9bA9>y_ z1@*yq-pA4(C2Sckg7(D6 z@qsp|Yv%N`^rf#B>U6CEWYA6{uIkcqH17=glbpvmHS3biM;|m&eX|0P1f@QQj*of! zH-&bmU`mPRb60|m_6#?*mIMqy>Oq|~xB4Q$0i{BlIUcU;5(xN+?z(MZO5`mn zJ6yr-Inhg915tF}=U493@Qo^PCc3v*_pe9fJzVyHxjG^)$~}usr!)aJtT-P&1!di8 z+#U5tkJ`N=Cg0r`{ppuOEf6Pmca0Qo_mK*#s>6jI_aJ%YwEql`OI+nV><`H>jw#W@ z7P@|^qY!I9iK+orW+ncZcV@=)I|Zh)F(gj!{Lv7SxP zB0G&;B;P&waZ}>jV`($fwD5eImruc?qL zBOgRdxD>z4lsX?8*Iy zSih2B$|u&PWP5c&JL^`=r|QovmDiwafAEfO-Wnpa_!3(5*%VYdbb2KkD?qy;*@d~= zbPsvdyXt{((_rEAx^x_bXh?Y{#t@wrW+=LkNh*$E$~x|`SN-)9CQoIU5lE1lGdu}QRX6^7}{F^V258z@W! zrN$L^y7KD}LPv~mlxs~=+bSJy4dx_JtEF5QWNCT!PDBH40B)m~x@T^fHV}+{VXdZ9 zJZ?x~2eQofZEu9dF$!GG<`xU&PvS~4jJ+PX<_}5?vx@`k(kA!FDxvs;xJBrHWE~}2 z;07nv=Zob^#>2r8y8RzA)J1joe0Kv67IVuD)7)qx@_^brk5tfc`V%#@p&8j?dZq*XOn?1iLQo7}J(NmPfM&UY6d@ zl_bRPF@9PzSVb8P->R6Fl*NITF$t_%_J>Gr9ai(XnxzDY*wqaMB_ZdP(mf= z5Fsc-e-$<`#jN=tGqsyVDY7VQv|=XLf!tyS=?>!DGPu(~{1B7&cF^V#j!wbOL1ul5 z;ss5&{dKUtDwDK_StjO&?-`Q^+->CCmh!Gvb7vXpC{{Ai8p8Gd3$N8OiH_#hzQLL< zs4~%gfp;1>|0jp=mjOb14-)Ww*vBlV1IARY?C_6EhUo)guTK_!;_fOHj?vdynh1f3 zkn@Dz^vQ`|H@ZNKZmWp^2*Ea{OY-YE*lyIzSg7XKbgf#DvmvlCd(Eh%RT^b|#%XlI zg4~>6vau~%4=3YZtenmX4QoEU}&GBe*MKUMp~hY)iAJke5Rgm=1lMa3C?$6~t( zL!&;>xzMsgQ_DwMrtQdMVd!&&7>jSJug}=Foap^o1wt-V z#?!w(bMc%EBYcn?x3D1q;%fA> zK`U_uFZUVwIB87i8+69$K3#sH$BRh**JMlv^5^jFVJUaFp;4EAMX9Gzv}tQ|0QdX)AZG2Va5Qt)P`aUyq`>%oUNUoCO143@f92p7NaC|6mHhkIT1I zLZw%?5H5MyI$DJK*4uvTbTo0H8yR_K-tl~K%!dXxtYj(XI-wX>@2x{0krw=YKgrEc z-h2|dn$DGjkfihP$PD5@;qn-d!sL{>tELrX`4rFGH@NKJH@v&*&2#?TWh%%L zfnkfJX;i~DnF^sPmmM|rmfp4NWxu&nw?HNMsfcwBV%Fbl7_|KbQT=AJIk-N3em#lr z_JoC6r^Ha)SK2D5$aHOb6P7KqN-L4O4deaoiP_GKBH`u(`+J=2sG>G$fgx{@b0fp( zwF{*PF;#cN3RE%9$X*+R+p~eyl$eM|?D?}iNaQzO-KLr4A9XFC{g-qBwGZC&|0rsRd0$jhsnn?f!65yx(>$v=2!+LWwW7*9axc-ePJqERavEk-?T)(`CNxkq; z|2OFL7%+1l+e`xd>)3e=2ouI0nTv@0G}9fIPPzYSq5n17IU8sL$)Eu2@+C0sF}zj{ z8)5OvCWqJT)%IO6aVf_g#*Tl5Bj&n`E#T?X8_vZhq!Knz)_Khg2n{Fg5W_Q5Gg3u_1#n%1PG*9jl%#5_`_8<_UTcF zszmJ=T!8{P5IDR)pP$IAx+xzip#(g}*y)C#=~I0lj1~EM|N6QF74xY$ehm9Iy#}Ej zU3y0Yb6<0!pF5?g`9<)aDoSCUbAG)Vo&MLR+spm*kq;ItPWeqUx_sW9;c$8C{)aTu zygfOhB&f}~nL+pi5)PVppm-YNdl2;%NA9fnFH7O-Fn;;IO6iw2(&pG$ngF|p#S%H( zxdTUXF0pnxS*uGV-$jz3v+XtBWf?zt`=93|Lj7uDc`NRn=4>-3L`PET#4s7j& zeMmyjq40#d8POG9t<*>Rj~nmY?J;j2W*LjVu~-UGS&p=CcHS|*0!ncT^wIaP>UMtN zTZs`cW+1n*V0hG~JAV8=_Dj(OKIn_UexBG>A2i6H#E~Y4eiK5*eE60)EJW$RQ`fzb zFiXy*v5E7$pfMk`ATO`=-TRk}s)hxep)76M-d{a5KTQ^vCMQd&+two@f4yX^QrBF! z&V?UqOqHOHzXU_$3&3ylGE8LO^AUnJ8oCN=I;HhIC6|1zB3+)@SpY~7==Bu}^gqAf z;};8QlDF@-4p|EejSmSVb;&`oqJ^CXouav%j(K3c|I>i;9vf5Q04iqah^uKRgu>?W zrf4dU{&-3}{(dh9XvbsIFSlnFqLt|Rkvg519F%ElZ=gLgx6`w&6_q|=eYBv;$c?#U z8sN?9n@gynbx0Tp2*iEY-EZSbRxkfG@59g!EHaXSBA!@?VC!!axq zl}$3=77yQ_vd?AfPqLkZe*S*;?{LaAlo*g6waeG5-tc9Tq@kq<%CI;!M$WQ525FJg zXhOyf7FBn?$#eTIHL+L(QRi>Y*%fB*tbE2Wkcm1tj0idQvjn7E{X_ckv3OiE5c@p1 zsh~6{lYa}t{x*vNs0ae;h}TL;R(Gs{wgLMJXU5Y=<1^;HwKuf?-?!&K`qTRdItawx z4g$S@TjA;GV$N*tXy$Hj;o!#PWp8(6aOkkagZKz4(57?54;d}k@;hW9@cjsJ) z%>>DxAmYY-yKUPCa_4&j(Bj8^g^gM*_2Nh1WBhS9akFlBX%3(7ZYqI$6Rxvr?pPHC z9yzix*xFwHQ$=`L*yn&My>04x!0gu8_hB|Gwh#(k$bh?Aek4_;!f zMJGGjW&~B5R;t{1e#SeNHG|xWJB7P@!&QuI4kP0uM<$Q2bd*7^E z{5gZBd~p=rWaRq|ZrwsC9yWBNNk^R_CU$0JG0mC24mh#I*RH1rLWf8QnVsbxZc^`$`;!g88Pf86a{Z5rA<>x1V3>MiVVhH&1Rk@lA(XmdgnEIY z+UN9pjz9#-;X#5nfMkFtv?swuq8LtEFmr^lv;BL1mHbDEMsLAd&HtHfUz!=C}9L)cTZ4y$hA zr{#i+2^p4-9$8Kmg)O03p+`NBU+DX}HAfq0>gM6wKq9s6uYpiK`FJ-$F^gbF8f@8QsfiE~J6hEtko#$v{YN3lm9HsU_pvg*;WCk4xLF=E3(;BIU;MY%B)Y<0j;aHBu3`g7s^gJS} z*YjILPCtzsQ-R0(MLxr4!IfVv((MUkK0KDdi5VN$Z%w#saU+r3V;6*20qsFdC^eOFkY|pv4=-kuC~YXvWaGf z7PEe-MIthXDM39sf{PqJ88D@%QZww^4h3_+*MDt{RMkSe(v>@8#d!je*O3zoD^GI` zT>0f2(3@ct(TA-M=dI4hD(O^q%#4c8w~h4fp8wU6Yitw2e!Cf)%75(dp)f$#z6`Jp5io?H!Ft zx00OedU=%d1gors`{q(mE#-U!XzobffYNx)fC!B&ww-LPd@!-0|A2If**E0V(jO+c zvC2p}3g7Q(@6X-&T1nPYAc=?(&HVZx$N8PJj3|^QP1)c#St8!=!QnLvSz4}_o6i=G zwDiVIkGOKcvfNPdjHbDYH)7&bnXghO!w7j5%vawGk8>!L7Qk?aY1Nt-O zEcz+!+3`u^c_c?zNTR+p4zSu^H<3Ov={=|Gb# zMQM>GU5^-?9yP++=-ZcTg`2mJl{T7BieltUO1y;wv~sR)8*v?yP%tdSnOP&grwD}W zaT<$NjZu>swhJ*|_it*JF=0ax0JsYcSVp_MyuR2!vYz;?VGSu4n+hvCip_Ye$k?7MWyw}cP#QHw+3BAKl6H-Z zdf$)DK8cvt!y>c%;oTP(-7oTRZpISLMe31VSmx|IY~&W-Cmy)J;c+ZN?gC#ZFK55> zmW_SMl|T40%wO6o|J4{_*0G#B3z&}aCVF>FQDR`cwA`zP~qtMQ&@!lXOEf`yFP*r@- zU6Nikp9Tj?BMZzyjsq`ENDrv^tD(5~cM}ZTPS)9|v8lhy!TDpfYC5!$b{f5))oG5B z$LYf+^0U$4gn+v=to&fMi0F^avX1@yv}c4UP`?;iW576~8BIi{aN|eId+6YTFMo@4 zs8HE<8KzJPQ!&s3J-K7wXMx!=aXmS4edm$rmf{mJ+1HC~x`|y*DGwCU>DZ6v<-;wZ z!Zf4eJK(teSaW1JEtl;1&EVR@^r`agj63QMiweD4=j()Qne{UI1PV=a{iuZEblL_} z>f(S3-4)J-!C!!((d;}toc+n>-pdtr%RYE8oGaUoFR$!e>ad?5pYYVY)n8P1hI56h zLhEBaV%zuOZcoIV+DG8DPR@F9%kIX_@{F1^x^WHfLU!=XdvE3h+c1L_-&}Z-7uP^F zK#9@PLvU;Fwnvt(Bor3Cv#5VY+M>aMFe&w9;AL!i^!$ZfJsy#Uz<6nlJ=2U z_w}Qj;+%Ks#`S@qf=r1G_WJ#7-ZK-0L8x*=G8_#*kC$9cku|_J!FML$9A0t*Pdq{s z%KBbM=w;I7ci^}EpbD0OgU;8GpS^THx17W0J+n+Zl2R3lQ`Sx|gLYa{N1hsdFCQ`Y zQ6;`Xbb97qx{3lMu_{L-L@yQ#Rf?*1!gBlTKt;xUiZ3C`E7p<+miS`AI{^0yuH_T1 zh}EIY_sgb%Km?#LC;ryVOY%2kt#`lTZMP*q=V8mY7OlswuAIwIR2IX&nQ~-iLlo$O zINQsjZ$O%e54;RI5~tCsuH##v1l&B*7Ji4icY_IE6xR;OC($k3fGyx>Yb@W zZpkq@Klh@;Oy`ydq{(m|)?lG9$fs3ISkT*zd!ydaB>#T2CwB3=l_jVfCJ}Y0^ z2ehK7W-YmNZ_JYPd6@TTaAjr_TRm43YF8D&I-ax=={K6`r&`PrE%gHg0YPj5Fa4VI zJya&~kIX>tTrKhmYew14>%S7-BYk~v##{bMUrw^?Oin=|dg`I=oK--_{^!8UmbjQ@ zkV_rc;9J~uZT+i1zdU`n|bKgYt(-Xd6CII)-tfm&HK1#eJ5TfvDMsElIKEq zo;4xv69kL@D1Tmj4Zu4GhC0H^H(g7GybDT4h4*6fge8F5$7~4JWS6tF?<{F|zC5RZ zpQ>}|sN0qUKK4ejj>7zJ!JynV^}Rn!%4ow6O>`%M-|KU?EhHVa9dRrS{k zEC@PgtR(pXeOm);O0GVvPe>H+T@bne?D-h;4mKr3MIt)4S?ffdVK2|=ypzXlQRK%f zy(c^YW92*qfgaL^%)3~tRGX8`tsM$**KV3d2=O^i;Twaq2N*&SzCcgv@5T$Gb>2oZ z^io57Zg^xOAL$#N%;JxntsBXg5{Q97K@&-f@R}Eghjf*%d%h=M?L)TiYAFZqF8!K2 zq;u^vrU)HK@7vB8@WYCsoI6OU zqw-|Awq=@M(_q$;j%=36zg#!)Xv1&lf&q%znK;z7y@o0GgSA$Uz{#gKV6+9UuTspS5&=nG`b77y$@YEGOYBWrS!G=MeX|e8| zuEF*7!FdThwYJcJ@M~E`^ljF(uF?%YHB{xv+0BNBLTe*WquHW|L=SOas`q!Z#gVY) z70?Q^>#RGHF0QVlprn;CH8Yl#yyGH$agUB?pfcqz%ke*-W$i$tjAlTGE$V!l+S6yX z=g$?-OGUpHD8ME=zl&mqoyQsmK>p!+#6rf84}%^qOI}|51gO*kOuqw>J{0QT^eSN# zpnVwR8Y<+u-gI!*MQ!TEqpMd1Mb=tm92!baszZ|o5t5i1bvq-84JaQWA9#KIW)#LA z84NWdXk2?^@APTUZj}^Bd>HIWb-w4gw8!|4!iZ?FB~?&Nsun?W_HIu`!UiIxpG%X! zl>kfj$sPYww0CZ4y0p^A-g26qG|@3{A>A1ouw63Sg64grlY+bY&NiFo&*%#d9J0`H z0VDkJn#%g35c>!QW*(kv-A&J|-s52<`qseK#n`rYQz$MNt``WviiP1il$;7R-6%C; zig#jCQ&yUoF$hR2@fnODxI#b0EVCC!1G^(6!+Tv68<~AZHS8nA7qy3U z!#PN+&MaP=-(PA0R)apA%BN&g60`|Z*v&-T!>*)4bJRUUn36MvfDlC%6S^qy6am! z$G7hW+>fgp`ChCrE3-NH*FAbJGBsF`EuAa)0=PI3dT^S6Lo-yvVZE$hMoX_PQ9Z=x zs}Cyo0iyv1@CnnLc^l;7jIXxjS}AFFubs@wrMpp6IXcN_RsIicNb2Q;0Nlz4JN(|< z%2a;%KZ6OCK1Yypm$F33D4fQKCZJ%$kC;BvN|XY_z~Vr$fE?rsuMbt@N5_^eP*1f! zIsU|47H9<6_T@C4mTmAk=k>Gs)h)&#)IR8TJR<~CeXK)lbD3ocg3JB%EeMVGWq7oK z^mlo?q)CK`oT#rMw4hxpmGxH{`IyBBY>Ej(o7)rzKA1|-Vf+^^X~PUk>r&+T4Fv7r zaE9#}<0D+3sUM;djgR} zU#mE^oKIPlr~Qgj6ovjRi%J?X=-;9Yav+CBp-qjt;||suA|NWBU#h-n~KqzaXO~O&lb+cl1XjvWDa#< zV%R98{>|)ktJO8PEBzACaB<#p`eUttx{iOvn1$AwI#;_wZ%akK^`Q%78O z^8;e(MhNGSokh0Z5ML?JSiVs-MXEm^HJ-167e}fs`tSW7F{A^JgaPIQDGu-Ksu5ppd*XfQeQxcl|_(3;~`(5za578Xl$;#V`IMxSV&Sx0_O$g1wtpFmCK0y#^t zb!?YH8?p-YN94ePKfgopHrWcjGiNcI&ph=gQeI2WJ*U86;Cjw$qHV3FYMC()E`vb- z@j$4Wzqyif!I{nukF&rU#W}g#T!C{X5Vf$&Tuc0h1jcy$@}XHQR8aodsKVZ#FARHL zI>6mSK$!M59T!$mX_^#29uPu*`BxmJGL@oQYb`$l&MD^ie71h=%RU(1F>fk{-_0+9f8~ck6Za39==?wl>))C=C^wHG}jT$Hn*@vSsUG-%3JD;iedoQTBB`{5SCI+sp)wmZ4(u+$iFlyEJD zUWvyQTwa~ln;VN4S!j0yyfE&Fu_THV?Dk$x=dP`Gefv!lHw_T^ZsTX}P@_-RPNGAi zG-Tvs;owb@#1flxbj#2~-VMqnn4B-qLs1?ytYYz7%y#A}&o@IgUDQYJW@?f6*a#idYR-$4eJ zqWtl|{nNd>X;M%k{}qKiw)HQ5sk6Mey9)Clskqf#?KUb`$>Odbm105VRThp6faMMR zuMa<1(<5&oqB_e+&zyZYO`@6YZ~dbadRdQ5M13h_>#yR3g)DgLik|D@)+}FsCp=q1%wM(z{7^9&S9{d9)z6B{ zg}F&I$|4$99u}q!6OEsCi|Egf2SPgL%2S*M*F82wb9s>*=4Lq>>nz|J{gEf(ZjgA{hiy5}5qT1E#i!bcd@?w0 zTF_ubA3~ycq9Jc)lrPxGSnWhYtzA_b#K-J%$;rx$r!_&#E1TUYX7iL943N>FqOvX1 zD|f~w(445PPKjH4S{^qOZ!s@c(pAbFsX}zAgmN~hJsP{*^CFJyVcsdBbKkz}r}^0D z*|oLETyZv5GsagDFoxBBHf7{03{OnGRp^VSS%mc;(9N>`nW>Z-zZ0~G9E)GqBwdIs zr5TrUChz+}O^3?Ef|CHaZ^~Kk_9&X(r~N1#`+Doag!pJ~d;C-P>5ahuZ+AnluN2h@ zZ1e#eVEx<6C`et3%lM06`fH+uQw%8He2Ox~JdNhEmSZTdSd59yV7tAm8zKx8YisS0 zWn*0S9H5^)c#jz;+nc&bk**IC#-GGnK?SdPvr42Rz`<928&6(BfsJ+^((sEY^GK!9 z?w*xnJ=|)ygry`7O|_OJF2Pq8C54<~4M3j!wn3S4z@d+EEbQCwRAKmZ*VOX3aes7!;u<$P&g^MK+iN4%@HVw`CTxT%^8bLOjaqZ)jR@p zDSm+}_mr@Z!*VPpmn_(!KorbzEM-%G;Yih_q0qVg(ME|u-~eh@0wB~x?Tnhg0t83Z zd|`@&nOG^XNQf{4wI$bs?@YR(UGZw|(9$rQMWh+?x;wP*`TtCgcHq*Xrq=6Yr)HRV zRDY>1taQL=&3KfWBDd_`Rqgp|fhJ9>kW^aAfA)hTT|sW}Pc10ZORL>eOLRo-(a3gb zxgi&}A<^iFXx!lqyRZS#D{c|PKz?k9@EpTm?D}jda|)uP;MppOI31|sX-bawPDLnzp7ZIjCB^keZGnaYYOr0mBH5@T?dI%x;s zkh^=m(XO?(1}CF`Ttk`u=0cV{u`w2myV3S8FRLSh>Kk@rJ>W<=y@7F&_sQXKcqcpj z>pv1`90na1C>vXU-WbG-%JZnuRw0v1ax93lp@e13oqwv5YQ}nzoYj>s`|WkZ_pS@S zE0^)5TBNS(_*nokoVJ#1646FcYpS&5^q0J37YRgOKyatdxV#1)yXU%bZg~; z`+ra=_>>GD=96B!=U+5Z1OEaalU$7rdf{SgX{$e|(iu|EFX1?IwcV_nl<^pG5IKzX z^4?N_-Rsi+OMpO5~}H9XS3 zWrAneRDAR;5|Q=)LmnXm{9 z){@Rid49d}A-umK-&(BBBJJyYw=jh>jBIXE6I3)m6I>3}{IL>Rk5c?^&dg{fHVIVE zGOu?{*1~G@6r&G`Qi@Y;B;OO2+PCCpZZhV zTNIBRPV{BtGZ8YRk!@2&--uJTwDhF&amtvDmb7>r(rHuoepMHSQT`aHu=iaG!=IN5 zsP+_SrG3rBy<_y4CZ&t#LVq!+)p!f}hoQcqyG%`h=*X@*WH+p_obE`Dr@8$H_*hvh|3COXqKMgCWC#9#-W>7lG$d7BPFMqKca`_PGNDTp&jT>r^6(hq3-63cx!Txa3y^6O|t zLFqO3a^v?$_6dwEc(<#p2!e0lsR#F>!Fi?%|4(5 z?EjV#-$1!YrI^xMx+L^@jt7EKXwXCK;{Q-0&bZ}&P$D{v_Gj!C>E}1%6Kr{v=Wxs$M=-A9iALj}aF>i{>w+ zwCL|tvn5mN{e~_*zG78P#mmFLjyoMkMzU9fZ}6fH<$HnJckW<_gSXGZSxp9EeauhS$;G!RNB8YbN@CUAEfg> z186VQwPEhOD#i*c*!&qzc2I^;ZceZr}Ow~dDjUeASG_Vd|o{>yP-Z((k2!fb7CVrjw3WaCuZLOF&8)P?Wou)}~r zf@uHEo8W5U=4S0+>G~JFb=pgB-UKv%BjeYuvrE3&=P;^JcUyIiCCRKlp=oq`j6{jR zf~}_L=UXDVJPUri#JWLwvC%KQgec+cTb`#m2R0WGc+_>x*r z-xi3DSOxNiBbCzce6a41&9amj_*rRux)DKym7XEh$alT$PZW3^(@B3eeaI6OXoiwn zEKuM_6z{oBYG$l>x|hjIx?V`rSZP|VVX!xajZi1~lrEX{zGIB`R>rer0QdZWQg>QB zXDA9Fo$VMRwKyPaS>Z^|)r2__IZ#-?q0aKWV1`zGIZVC#4j$oAaQr6amtU8Cl#g8t zNsNez+mk*<3Hl>DCm#r{BGJ~T`CBtHuN&TDS(+fsrUXlFY9ZMx)+41!x~%XUBaI*# zPr4&=avwIU2K=v7M!L_8xv|D|YCe?D;3#O|043ORQoo!Q3mNN<+2a8QmM!)#?UDBGAlYCW_-EbUZTXa`iHock7lethh8zl>@LxU1 z5s3m5(bq=kjiSUuUEz0={Cc8`p6a%OKxW$fKvysc?`MMMOB|W0NAYOam|m10$FW?% zAscz6jIT6q{!s%hsrH&3d(B5PSOT=cXMP#W?)~=YOX(Ont6s;t)3_}_1kWbKA9Z}2 zv`B2?VJmkZWSh8*igE01H!y}#5u3%Q zTP_$6UQjB!UUYqCQL2-%<8v+*_nU^-bZ!zcWrnYNgbu5hxsI^L^C*|J8yT-}he4Wi z@+U&q%TBTSiPB~7AI4xXu12&8d0rus;}|`mpjZJHJrRw3%-9>3g{z0UIpGRmFXHxo zKZVXkkws^3tfPK@d6X6BZ@8AZ_^ChmZmqVyG0VFlbJ$(Rbm<}D({}>B#r^HbQwlxQ zi)EL`T;o-7748EWl<6Ak8~O!5DtE`kZ$5qSUzdlReVI75j!3CuyR~sY;rm4~c+$g+ zeG=@n)zIWk7KL#`nNgMX%Gh)V8h@OiEyc72!%oYYu-&_DCxKBuk>IY>3$|F69A`wS zv1YZW&%C$pwN#_$U8_hPE)AqTf?nj@Nt2%Kvwk-&gsxK1y8DFZ-q$|eH+s~Ac9dr- zuRC~7WV6&xQqHw|T}PHt!D4}cbEer{S#x4mUk&@~fTe7p1yy4Z9C%X&;98_6W$iD> zeTrw39?DeRrTfA^EI@f#V26YO3O+xB&;#qq-G9}>TG_hTiV()Q7G2k$*{sVUCjDu} zjN30OXa)C$$h=mdAy^le|AnDJ&=FR1(XEGN(1rQQ(W~IV^L6wU zRNKtYi-JgRmJLL~fuCgY0I;ZI1`ForQ}7K5!y3Um1Z(^hjg=_{a1n8f0zZF0 zwC!73rDXN;YzKv>R`dO+s>kKSu3$&}tjQKwaWYi+*i9 z1*b5|HS%;#k=Bs}qsLRAF!{%&CerU!;emlm|deIe*@UWU+j5Cp4R6CDZ2J zj_@P24A_nE>%4FM1PdCp2R_E-QT&`6oKusRN8Cvm9Nx|gViFuIcZ>V5vTz$!xj_m5Ms{B(D{f(<@2JlIjq6$&Z z(z(wk=BUN{^+#%Z64QG8x&Z7HZmmR3by7f|heZ3Pz%UVhM07#b_j_PJ2tv+!-UZbK zRe#$;)xbFz8WH{u^y^u{T)H5MeTqbkA2NA+K2KCWF*cxA(-1jVXOdrCc;$B6gz$xqBkAO&G{F_cV?7s#jiZdV!+8vs zo9ayMb`rXgsG6!z#9BYog`q~BgI_Vyn$f%yBk~^ZqP!p#9LNm=W_RCY?tdeOoWE=w z&b`Sb^R<%7j1WLnFxNh$ZeN1wzKK3mul;zY0(G~!Y=TDq!d!d}&iI1ISLM^hnQ3y` z=+?$DOu?{{tO}iGof^mrm)M5zD8b)3KOA)5W6Z+ZgMR)T$~n)`A?b>YNou_t0F%cM~czZM3?5j7r)`mnWeMYD3<$2l>3ZaCJ)f zSE_4maQNiGud(HY`#52Z#vhl)*6n^`9P6j&LvtrmLLIS2>}~JH8ea0Ioliw4m4ucJ zj)2tnzEP&)NLe0iFuhRjXbQ8%wKtzfn|Dto0#wJh;^{`NO=Z{4LdIBq;HOC_0La=h z4RHvB|MIYdZ#8)c{&7TuKuB*;_-AZ`<+O+i{HLa8KjgX zhY8MkTl1IrqTdeH{o8K;=T6sDz$3ckg#UHwpg^FvI_AHPTy-#_9vRqP4K=IxdLeHc0@AzfVGxb5{@nJrJZ1>M_*nx$W6K1d^{SP z2a}aAQkoe{3&g$#^9JZe=6Uf!?h1xrjYH7LS!%jjtM+Z2t-Z27wwN|dr08PxW2jp< zNFcPJVhQUUCy-)xmK4Y22lQg^f%iOqt9;%>5>_s|#JpZ&s5AqWHwWxaunm9xsHo=W zNRm~lK)68Yh;k*ZERmIGM=9fgi@C7Zu`n@2Po_2e9i(cUkv`F4rYfPaL@{~v?b?&R zu%L`NvG3F2g@ea4oi8$ho4{dnPwc11Ak$JXJmxtx^ z9?L&NLW7?qTp-9_EFH;^-WfFg8=SuP7_n#=nUgiZ>?8hp_;09Hx^DtFJFhM zRkDIot--?zgP7-yw2dzBCfz z;+Fn_Tp4R8~lA|rVCikmZOcW_eY2M7%X{BGIIS3Fftv7OZCQy^yL*+8h4#< zcXs3IFuR!#hs}o<2!FM=wx@TPV{oB`skC(^MWfN3n|s_zz%G3XN=TH<5=8p|!$s!L z0wx{8uvNqT5Ww>2jA4u>v?P(T$}x*)bGy97v_8wNzYQ~7EKY)9Nacbz#jJ^QFw-6{ z2itcN#ZCch2>A9b6`iu!7Iff+t4PA$)^lX*mcdeDI|o+%zaz%X**&+x*gkI zhrF;wK*FN_2DdCSgSM`X9tyW*C|VS?Rw)A01KZI-xZOf@bngSj`bc%i6Noa7l4HdaTv)Q{UD_~buvg+9t% zUR?qS$diblFLpqwNhI`^J=Zgt*Yj0asj@;USC@8Yr6=9;?`YJggi4qumh3>|mS=-? zqR(3qdcb|~6t_hSH6U^1XXQr~2b|)lMyp}lo;S=J*7CH?yEM1F+Zp|`g|z1LG0}@| zpuzbTiHnc&NIPNNou6v8d!(CIKJ^EW=f8!X|6(frr*kNNgH; zW{7^4>j3>u8!kXlY$CxAchEc4E>_p_@8@lOyXI?UI;CF+t0*2Xlm;o%m5OjQ;V#S8 zq~wbSGi}l#R`Q6|LdK2AFeC zL$|ek8mc+8JS6sdrmzyvWIopfX4$X^G7m(6l|$XTOZ&0e1W?b+iLh;&1(u*Hvfoue z49R8oXF~BYnd-{?xyD=advOW7ZzwmnqznLgn~dp)tZj39whqBuC7$qYpQ+*x(m$K& z(^E)i+!yUL1=c$=hHg2KZW;z|=vm!Pyo0MF_H?-r)d?= zyTdsx09)r6vDA%R4|g{m6h@k?tcGUn!hwUIzcEiLyFK5rpOO(czi>OFquYN$i6}7j zL}fB1{9HwG*yt5?l54Y}5#!V*RRu^1)L+~f&=KqXv7)@;03az{XD`bq5F5NEJ8C_p}ehvRdUy<=(#`jLhyd=rbJ@i(mVR7L`7T-D25zEk*V)x;9((2 zyU@81y^)%DMbr6I6XuoXpz<^m2~v;Z$^xVkfrmk@ui)Y@mfz9tr=8-P^?O09zzmau z3ISunSG8F@F#A@d)S?l75HJ zs;on}&LS?#fdMPKhk>BNJGp_@h`s$m?s;#b&Hh)}jho2Bk)U78?>5m{Fr@S8d8O0h ziag*X@wvF%3%!%zG`sWVXI|&?Z|lnSt&LvA{i_c)^1jNlLDrL`%|>H)6+mR6UJ0+m zeF}m+5dKi1>V_m-^abg4ko9TU*h2_fBRJh#`Jk?K<_PZ7wI4<41!*>?xJdOrkVw0jcUcO?K*@)k+=C|arl}Lb zG~srqmX7^=yZ|fNnltFZkwp_BTjC86&uYojcTvl8o6Iz<84B)L;p(Sc3eQgSnNv(o zQ0ci>dv_BSr~lxIKtS&kIj70GJ}=_$Dn9S+kmChccwc2RkG3y0;I#(-wu*c5F`vwb z%UC|(zz5a?3fJ@YH;{b#T- zNO*!%E3pjO?JYm5f@j|BZ}QQ0cRSEV&|KJ^Szwo!o5CWS)6*PIQ>lHY17_fd#v{@( zQC#zZThH2O;>mdxklTG^FR0~Zw6LeRb0AzJ8TnEDmZ@b(!(#b%GSs>8UGJ|yrjQn3 z@Eru>LuiQ+O#}6d&n^{)>EcC3jum#u`L;)e>$4+pGUN3Sz$(B*eM9ySevgu}MnT7F z(nzF8cY(|?@&GiqGjnkiH-y4HK2w)uA`>yZV&LM$4muu^WMo0;!0)Vi1AL@z8yp!6 zJ)-wy(w$Y20!k3`gd(Q6zz@{RsN=(wyrYsPBxof|#hO;*>1PCdhl`#gXStzhK%w%L zv1j>GE$3Wr@L52e(*g{GM~_JjpVE4{R8z6tS2<>i<)84DcI@t6qra-|E%U8rLO*M2 z)W={BX+<3(&srR{V=GDHjK+!0*RJZ9Pe$n-LvPUbslUnYIBhWfA(Cl$_wN!zr{ zw@*h_m>Ut2*l=oySUyg~>X{Cu3`2pY;w*+dQ*R&K4;GNs_W8(d!cwgiX&vu3!uojB znsU_m+iAZQX;RRSW1Bbp3K;!@PI4P=;6?I9=fVo+oV*0JdyjzZht1r}^x;$KvtWY{ z-bF&8;pWd{l^4X7IA?oNuoTLC+xrdlOjYmOJJ5?modeAwy3ei5LAs~#bkOFvwfheG zb*knSH1NWYMn~@97wYC0fm=BOU{9l-O}A}n9?fb|lx#D5Eu8?HUmIN^LXWil&n zWx_Wf(8yjxRmfC*OHGh0>I5I&s@oT-i@f_@9c&5LM${MIUiNc%D3oJipSuEn5bmJg z50pN2R0+KQ3}Ypuam8f)!bX9XL5g?bvEzeP_e;{}EhpE{Ucd84Y{0&&{!zla*F4 z5(>`z(4g<#XYabYVm8W8S1jmzTeRFTFJskm{Nf{jrFHtqnhdRM^+|MSd=faU z+3~=67~4t0O-0u~PSN1SXy7IFMSq{5t+pUNG^Rtp$uNQSp$AUKK412`Vr}~PPBu91 zz>*`wEH{__a!oVaWm#Y=0Cs`wS1H_^vNrG{x0;K5Fv}^z<-@%oM|cuCgL{WF!!S(e z{+6}&P@a9Que247w7-YSk>(38OvE$!W;+0gLp{{FzUvYh$gkQg5*aBs2&p z_0y1CGv4{U^``Kfl3^Vmk?wB(nG&P;J@TiTtJ-L$e7IxYoa8q?`54iK;D>&+H4IZQ zA>q{5B*Km9q4%KzTmn}s$x3p$9@#&x zSP0U+5sYP=U^k3+kPcY>a1XlY&(#W^ z0E?O?`5co3yJGn3Z_$=RO{%9L+T_6{tVDB%u@)KE8QyA};hiSOkc2qY`cm~})l7vW zt`IwM!tTRUy3O-5&7Q)Z2uVL?aJ5U3ug%w8-WBCLAyaQB*#aoZwP>aLI8(ZsGg@HB zFKiJW8ZI2+i4N9<_2tt1BOjH()=PHIz=(H1HSv$_E_>E(+;h3#dQA}}N1)XXZqZPc z7MfhMsL2S?BGLOM!3{q$K|Vn`$RuMQwH=InOY}-&hcDrDSkMKA9Lj2B!8et4FTCk^ zJ<2G%9;PSHCpT0yki;%;%7{h)f02S@E~6ZEXD=(v31e{h@%F^oEr0~G%jpH4T5>^H za(j{SGJUm!ppG|m8h)*HezlgBB`IBFYLGFCyerGShNzhkR_6Ww$a`Fy?Lu@K$L6)~ z=qFWl5>Y-7k3=~enJ%snu-rgBJ*sV}dA(6z{mzmKVQHACx|?9Uw0ngWZQfOewi5UH zCKDS69#-4qVz?iYkAc!E+vSf+F7KxH_=q9Mz%P07o$y4PK&M*=1Sdogk<~`vXMZy? zO4}8m19yVjY`LbG#vM=7Q;KeuJwJASWx2Hba>{i4gL3+2na_(rFjH-%_q+l%ms?VY z<4!N{nx@+wS2)~z6n!!Jaceh}d?MZM&of6zCWA7}r&J3!)Gc0$)G|YNMLfjG&P@h$ zSbR3OLrtiiO$Zu{`ecbd9bf0Z4hFHk@Zv;kY8T!LeER7W@|8;4H;O)uo_oBVz+}Jr zN>W7tul!e}UlCor6!_aoEV2#bykgRY8L-t+t-+9s30Y+kCIeH(O?sd#Lq%*ivApj1iZ42HMKhE{3T!l4@ zzKn3LTpe|{nLPfjbIl!P7RiGK0K`!M0PNQYFK0JP4r^y;4<~02D|dEpkYj!7idz;Z zCOG^YIOApNagKNq$=Ue!z0lEa)l5A`KH?ImctoP5MW??`dI-rXD!qouP_?<}ll~by zD|wvI9lBDMQWPEX55HY5ajT@rHSDM7Tkfa?8&)i&;bK!o4|90o%5MRBxR=@rEJaoW zFyWl8pANB$=RXr#NNNm3w(JniO%HwPCw9U*eOFnMhG;GFq@Q)b(R^c)|i7*h7S_cir^-b zX{~Kp;#6Ox8;eLBFjD7^nU!Z)S9U2+4;=n7o2}bC2ONzISgF7Y#H(3yNVWM1s{{sX zTgcI`!!tsE4euHp9t#!Ne`9vfU(Vzf`BT3y<)!S>YkH>+e7oRX-M&#-Y;&evbEkJC;;Ga_cTMgo%CK*Rp->1Jt`8>_LGB7VxOERh_DNmt)L+^6LuIRu ze>^_*4$yw);=1t7E|KIW_osdAum*n#m4t6X!9X69b_vNHD}@gw>x!w(<%rJ2(n3{Q zIrhx1w9%W(zAooinTO{+T!Pt%ZULnC(H|)%SI4nwP)N=f9hU;&`5{><75|JTkBn#w37(KJ{=vhAYJL@wThgwvHLsNy)CeKxbGg) zYw6Pel#+I;yS%37TQ!(J*Kd=e)AzFoV3tmusauYfZWtUFd?gMy4p|%%4sop|`kGe~ z@KJ%Ky}q(;yduv%%(;E{0Q)}R26U`yFcS_M7HL|`pcuco;m;GQ8i8vdA?ERJ=qg5& z(TZ!hs%XnsUsO6BQF*=!kOe=dputTon#f*nf}IaPSI6^uxmsw0{}$?n_W?$^uTTSD zp~m{ZP+K`!{x8%2iFD1|@*EGh1-oU0ccG5y`Mq+rH5=bpM!V6R;34H4u*Tq;ynrvB z1V4UY2;Kes!!#VS)4!NLgZ?k3Q9LZ+*El)@T3F2Kv8mYJl2e98qDT`kHfZ+~l4QP7 z8AY2YOO~b?1pK7ZfSO=rRsT|pO zI{5}1TtTJb7hTBCND2rh3l}Hg`9{pstD=R#O#}?J?N zsm_q&&DULQ4o%Oe?ry&Ib=_R$W<@0yQ2BApxK5}}*7SEBvE-XeUNJ0h9#|2TD*92b zG^CM1dF4cu`Wfn~N7>j;2zlOPh2l>4Rlo?i$E_)y%+bm5tm2{X$L_aOkHL&;tJ!L6 zfj%{4i1p_qbU#Kk`WfQd7e;_@?!p8f^P!&oi#_OMhO53y=U)DPu&?XfH4}Zx z`zG_c-8_kC|j~LSv@brzJBUCT9;!7*O$i7!$`zjzA##k;1SkBZuq7F>O+NQ*v)oyAaSS1|gZ zzTA1TBR`lroOS3uzbgL!+pZ0$f)V9)hHTQ}gSq~Qa#89^+%hL-_&Lih8TCepJ0LX{ zu>xPJ-)Ig*(RD(I4f0C>sW@-A4h8X^F^6XH6WNHo5KSnxdkb9m0N;Szn6PnU{QoF& zX0(5Bz|(5X{?OahkIA^|)v!kC;v6FrdHAK?HVp{tJ$($)ILUey<}qkvgbdcB?%>bG zi9leDE#Po=!yFYY9vN z1K0mRmjg9~ow=3df6%3%;3JViZYwG^D=JgW#GrXU9qEN*$V_kQ#=ygXPku}8Ua)~- z4{Ivz2!2i_Xz2jV5d8*>2aG#&jFeJ6W!x)sW)B!L>KN4x_kdZw~pBDkr5zkJbRv_IaxRRys$jK0J078 z-_`LQjIOwfj||$d;3F#lUmntIP4GC-k-lj*@_uLQ6ijmCD8fT|3b0PTebk$c`Ox20 z|HWx=*f&*ctmQ}4&MwF_Bv<&tnTrnqS>|qw#-4ZWA5YUw!kVFNrKx?8QYKjq+vt-! zqhJYj)+g6g9HA%#t)zOp9V7u?(OtuD`JgoFAcO0npt5sjET;@!NB$$nf7BSgnT0lr zbxy)Y>66Ro)8^$6c2m< zY<Ks{Ciwu@gm?gOXS@Ms3c_ikA|9QLzzJOE;&r$V-e3 zJVzb}tCx!AkP%<~ZK;L4Jbls#TV`AJ@N6()I)tV%)m2 zP7YazzbnTkVo78cC7TIb6RAl=_r*k-%F)WpFbbmJ6@t62JGNDr#mnZaXYsFb=A9yG z(wypbx8Cv_Y~m*3vPg2E^`4_4P2uR*i+2Ms{meF-)FA6+M75vw^N%Po%j^?-%!VT>3{lkw}&(-4@yY!fCMPgTc|%SSP7HMy8hmeyXp;jkz0$*<_B+ zlkYBvQdXvgsURG8j4Cepgd6hS%T&^iGebLJ#s-SNrrqb9^(n6SXXkul8%Pr7l)7^j zn7WY+R=MdwZ?nT{kR?C@SLrdCC3KJVgh;p(fDJn>uFGEwI8K`SorwZ-Rt0!!<@W|E z^EH*s;~*VY1_$U9uhSrKbPLSkVxJv{!n=MvJrhTlsP{RCsd5jI$PTM1YyEQM}Edj6mMbUXE$P}c(5FmFR&y0bMgUt^7@8qkMX(I6gf-JMcx2!MOR$IgHo}~x$g(tEm?no#qu}GJ<^XBU} z#!FX}LCaIH6z=YP8k68Mb8nsn(ifaL-;7iD+pI8UzcU;r%U;JQ23iBq`r=c1kj zCBK_@u*N(=@kwn+8lzS{S8D2NyU=9y9~EE3&(4bmbza=cgmu?Jdb&T5>gvW~zxcgR zTQpi*NFwLQY5Yh$&lp=@2DwQ-`+QCuuU>AZ7i z{Cb16pZOPzT(c{Y94BiKp4s-{|0HxTwI1ewCG_Jz2|cf@Y{2N3a?I>=&7T@ooTvVj zYq`-blEI6;B}5B<7L=GZ*wl7FC_*DGAIzs3&3(zW2PrxPU@y5p-j^1fBi zns<~%Z|TTjIu!NbYF}1F_t~Ziiu;y0{U-LpEpCKwRo8IKyXg__FI7Yau)Q++`cMI8 zzlfu?A^`w@e)z9%{$Zy;R+e^V9Cjcx8!Ik$dl#!ZAoDmT_*)wpEj}Co(1!6JMXI}% zhlib$%|DHo&W7^}FJ=Hm^-K4~HR(wc+b27-VePB}y$HeHT)W7|$d3hL>aMG1FAs6a zwo6C`v~0hV-rcSFdkK-pAMl-%+wu5x8DeUi#ILc~2=%=0R!~2$8U%0bLGHb2X~CZr zHEW1X;^TE=Haec3n)o85Oqs-$V*(5Ck=UvReVMW>1@ZdHHE64JLmU82F&ea6kn)-?-KW7|_`ZqoZ3m>{YF=EmfqSHc4QHjTqSz$>r zzbFM3k&_}!d{p`NwacqhS{ZJ?s!-=3G2$!DMJ|>UT!0_hVEaLO@SXq$lgS`Xj`vW4 zF5mAO({V&8rje%#T_MOqd95_|St7qyqIus}6lS3*vZDkVwT>ct!9$!Smp*VCa48Ly zEh)=rjDJ}Z6FqqxQ3YI7r~#&mJkB%TmSxlVK-d{Zewo50C`gO84`+yL%Nh4Jml^OK z0$RY9&zF-5sZj9BF6coNB2OZd#q|kGw9UeHRx=m|*6S(G2TsET$Bwn<)-KY-AxGY~ zio;b~RiFzmGtf3qDNlu@Eqr`4x#ZF-Vy7*OY7DEQ;8z;w#}2Azr{UTtLYYysSUGukRJE2+6Cj;IUyayY|PTl z9&@Kdnrik)K1M$_LchR#pQL#NHq+lRL6W902CXq#o?9T? z4MNErF*wDX(Ht%sDxb&Sc!q>6NPnJ$a;0W)I~!UZYd<8B6G5pQqIOI5v^@G+(1PY_ zV@7tW=ZT zVpVy|lGG~RT2J+MAyV1BS!zG7Nmu`A)M(;TgJs*dZk4#(4@+=sG`!Dv*J^&z9C6$j zA)51Q6nFs}xmN6OTlcYWw#J$}w$RjUO*OTp#U}P_<$XuY(=51&W~u3_(ak#1SvX8< zx592I-13|Agm~^)@aQqaL`Su6QYjg1Q!2fEvKEJWllm916fhcf3XQ?mqau8*e0uTX zA$b;l!!(`oLZH@(4?bH-Q0$$imH;;u%pt&59eaxPQu}L#L7x|l^VjY#>ggyVxy`fL zLHEAn%O#Q+qFMLuSyNh7Pw1pNT&*&*pRJ(3Dy>-@K6Uq&V{3=iz&Ca4l8sc&a~ zAsuN~ymuA;u))w)_DjD(%`ZB${7biLEY1P26i=zH| ztCj{^Ba3G2Sx1sga02_p$smJ)6c9R$nI_evIu@RcEBsl!rtPr9Gc2w$g`gE#RVQET{=v7>#1fRa3C-C|Xhy9-j-ubPjKh zIjVs5(5DGVa%`u0oQ6OCgtA^Dw^=(FW4D;`d?NnV`2Kp1R`uzgRwZPK_O{R#dTj=6 z$NSs&!e5=wNtq^V&MydcI${Fo;3rcbB;D5%AocZb(totBoIEtm%pI-%6a=fu%JHwQ ztMK!b-xLYwB&b1-*lcNzL%{&WctGwJS%{wwHl9*c(ag2!7el{{~WTWnT%(8 zBTanm9@bA5u-X%JQ7_;U&QxN_mC$1OjfBC{!G#~8jobc3``~?@wGUuO*%-Z`FQ@8L z1zmVD?01nwGzVtk9hDwC+QY{gZDwWO6uPA*@Oc|_G%8rbH zK1pluWV_UVC*{8I9s>QXA(G6|CEOT0W+!b9nJ00`GXg~0@-iu7e#iQf)sT285Ns6c z6W19_jDDMaP5v-it+pu<$wPn|tmBFJjZu7;B&yHbJVovcxk|<*rF8uPx_aLj_|wo6 z_Y*@D*v~KkZ9Y@3EQPn*s}agc_aehtac7Py}b1UHZV#22PU)4?@VFj0L%Ncb-71P z@CwP<$d8t-<)f|fn3tOyTY~CeubKTH{v7MSZpQgIhga8KzGHv_uf)y#K`zldV(6}X zCwWH3PFsI+U5u`X4ce7&vF?kVUxM(O<2pHmokpeyDE>JHd&LnMpWw+FMKj)Yzt zZe&uSw0_Nbv1!f!Imjxpi`h1(AMJ#zc4hyzLjSiyYoJNUHKClvDE9Dx!f!Mn=6%#P zBZe(yRZ>sMejykIp0U_$LU@SgG%-#3GLD4yomdxw=?@!fAWcek;xq0tRzB?@KAL`% zVI^#*JyJ*{2YO6SXR?gO`K9zxu|P#$VQ!ew!k5-tM&$>TXN!kDGe7&Pv&|H#`B??+ zqVoQd{RK|x%bOEEh0O2nN#;bDLt*<+N}dR<{Q=2_-$TG#vZp`-O{Lyw)?r*3qWV&g z0i+H_+V?1ljYn1S#B)X)e&J#WZ1GF;WL*+M#V81zG`}d0ILR*LF-(fE_zEq@PwKX2 za?5HhHF=hNj{Ho(kM(Uf%6iFG#_bdRV=Boh-WquQ6J~S$k9fA@B#(K`S{cv%kHk~yypoc^9YXeCKl)1*qIhML~a!7jT$ zDTlL`3RPy9R5DE#HOJG> z01sR;$3@ws31lERW~@rofgY)Xmmm$UQ9u`-~q5On%bz zQonnSvvZe9F=Q-wmUcI)-HwP^ysNO3C91EFjJ2X6s=nlcQ#-Ph^WBCS9dWDF=@`Z` z#7DQh5c@T~<|5hddh87Wse=H489^_e>s;X7m<pkv9p-fPj#-n=7bphdwD<*q^5aDFE(8us8E3wk#@M}(v z!is(t8PFYnpWNF$oe4U36>lKCNad>SMI7I#$bF@PMc_&skHh`@H9aS))U!I6tXOOT zH%9EM{wvwfTSuD3oxT%0h$jVhWuhJO95(7g`j;H(g)>}feh9LmgEU;n;gyL=3!ryEI@Y;I+kLL$OR+pUQzpqLD$1p$z5~xc{`tK93 z*On9Me+~mu@E~2f?4B z^{CUF-iZonE7kUt~?~dfEM;of`NQBz=w8J zf(#nakp5fDU;qHjzoK9Nv8zJh4XN4wdlUR;1W+9S_@6BSNzlcGFd7m=*Jwh%Ym-1s U3=z?BUiZ!bEC8^s^=I<`0T$TkZ2$lO diff --git a/docker/docmosis/templates/CV-UNS-GAP-ENG-01070.docx b/docker/docmosis/templates/CV-UNS-GAP-ENG-01070.docx index f2a28ab1f0b9953810c9fc696670a9fb4751e470..3e9445b398d0c286ba8d292ef6435082af7ad8cd 100644 GIT binary patch delta 17467 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 U-}T`S12jPY`&OQz`k$x&3vz8KZvX%Q delta 70546 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
X{T$4fftkP}KOsic#`4^Q^>e zRD>^e(sOC`_~>4rf1z-+^Twl?{F-|B_UWcUn?7uS(KGRbXUal@IKwNAl&f%x_GAAK z1B8|D(PPTV_eP*(O5pBZ4BZ8O21D_#pb*_}kiC91_8$6QKA)EE4vO~Q zDDr#5uW-bO!w;5T3&`pfqd^TNHn?ps>{_7vP{I$*=%xvFX_m)z1Dm%Wk z?Xz=MMV+>CT;%=1uAPgEwwoTrG2dqAv-JpFnQARO*E2IeYQy%(kxu97X&}vH3dmw{ zD|xY)CUw8bfAun@+0DkoUcVD{{3w>{{k_#WT=IDkd-MJF`m~&f>&dn%pZBA#ZuO;M zt2fN+a@1r{lLC(YMT}y1!~0sx^8<6t&#X~$P{q8d)g$%1xNH?gG(5?e3iyJ06{o(Q zvKOeJ23JSyTk6K|4-TohuGK3PaK0R$Hd%NTo3Rsif0EuJALHr1)$cB<&7e77s(PMP zXQ!}MtyOn8m<{VTzX~R{G7`?GZMsO-)kEqXocf5lP{1DE*yiBGo}SiCDX4+^n+%f; z<&TFY3(UO3aOALhQ*u}XLf=$+zR?+`gRtjQK%+B09*5c~yUIiN{M1ahli7aL*0bC@ zEWD=!f7?!@4sLF}V5qOz?S^auc z&TBgR{h($aHD8+>>54^2Xc?+|ZRf(i-kwz;fyYm0t7IMoercg)vg@3f_W zJiql8vCbd2!!ze|$+THv8DkPuvTQqIbFStXe}X7mQy7ZG1A{e%U$EM=I%C7dsI{sb zBvjwq(`$@4uQ=tk%n4fXG_C2JUVBo~Gh;E<(BOMp@$5|ux6K@rP%uyJC1b~x$V@Z! zM|!4!pltQ1sx@T_G-cW%{y_$Jo!)i8FE0i=OSczMFxD5mWVw_FU8hrKyU!JNBVO6= zf5jV)Tbp$kj|)Jg^3&#ljj=m5aBHS)gI<_cq@|%+R#G2l9+S7&6f~&CrX}s%+0&}o zGzJY0R}FG4X%`cGjli&f!ADZC6Zxs-|51iHT=uqf2Mh?FXx#IBU7- zg>%=nX*d&oXSM6kC#urBT*T4BIV@G_e<|eFcB0KGpp}e{tNJ9Gv{S{eNzIkop4JVm zQVTZyxVoM{^>c1H^mNA`r9n&DUwyWQpH`~a!RbcZ4A8WaH#v5@T;UT1w2xJ;uc?_M zG0eQZI!W`koTFpwD0J4zY8EL`6pT_fyBgd1;X3j~Pxq9wwY7jFWLN4(9Vi)2win{dHXvj_2uaxHblZYfb1d zeM82w)2{|c2pf4`kr$W(PHXmbJxtYeAn8djY{SLL2}kYuW^o#-gTxwD=XHnawb;r5 zX*q8~7+ji{p_)4GB#@TMyk8L(e_iX0R92vX&8~M<)9WOy`-h35jW<}-m&aHcEQ1|> z(yP&OGmQDCaJf1}Q>;$5O;fe6@?<*c8|*U4hPbtLYiu`}?ynSZcIespB0jeK-8|V2 z4yy8$tu9$zmi+Z8pS5aXOC42=c-P7-eT&RA+@)E3R`mXKG%?$#8)=L%e>hJLn_8O! zCRgO(owRPvpK*N&^qg3~s$>b2&YKZ`=Fvp{R!xp|5#4@oGRyn4qh zwRrKe+icHvo5PDPGg{zb*6J?O`QXw_maf_AtmOV+7KQyt74TrR7s8N z1pB#OZ8}L?xuVOec}-{Mq!2klj5wOC(|QF7Pv`1pCXSdz&x@@Ef5#cQ

U&S8G`~ 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 ag#CZ8jH{*ak%8f+pwoaML*J|asrz577(ZwL delta 70452 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[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 XD#iB6KQ1T-5Se4jgMXJ3%L4odF?iIM diff --git a/docker/docmosis/templates/CV-UNS-GAP-ENG-01072.docx b/docker/docmosis/templates/CV-UNS-GAP-ENG-01072.docx index 0696e523827636333ca31c072d84facfa339baab..d8f67ebaeec6c87113b397ec5cb30f2e47bfed82 100644 GIT binary patch delta 11050 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 delta 15824 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 diff --git a/docker/docmosis/templates/CV-UNS-GAP-ENG-01073.docx b/docker/docmosis/templates/CV-UNS-GAP-ENG-01073.docx index 227acaf6816e4d561f86eccfa35fad88310a6b48..e44df45adc1521e91b91cc02e27fbbe90742800e 100644 GIT binary patch delta 11499 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 ZKi>b-Ku`;W=}ZGZ00{utX#Z97e*lHIiQ)hN delta 16400 zcmZ9Tb95%n*7jp36FZsMw(U%8+qQF0Y~B-VV%s(+wr$(^<~c9U`9zI#U!8+g3Mmdx+WbudgjaL$-Er*QS=?Uvk$;EmXyM zLe+sB{#p?^9-P3Zyb%cfAVfmi+FrV{h{A}TB2r%$@>+$r*FTSCOPdYn>x zVWedV=2vU$_-yaMEJ|$hYnC|enIS{C@3^^j9x4+OE2B$&~l z)7;-k__lY4EzuRmp@mP8N1$={*u2k#VeY-jLbL9a-hQ4KXX^F1ntmS89(DT-`c4Lg z3^K#;{Oz%O5^!;MpHb7ujXs*yOg%6@NA=NP=aHYUq~O_$f|l0L*{NW923!i8P@OIL z;?SvNh4i3w_O)^GebykG79#5I0lTm;2qQ&aXJ}Hzd=^;Ho8chz%Ul199RC8=Dr3}t zfE$7X90v#q9}z%6AQeGCQ2r*=!@=2<(bU1j&Cbl;mBG`__FUV?VT}X%3((UAo{KmL zMYr(ho0gsONOBgWR6U8@QnyuPQ-e%_(5(Bqk&xifw4J1tw5QTJ}jFeqE36=PQYnaPN_@5d3M1)Mnty zRR-%MG*_XEfs56(55N}LAtsKwK|U+g^^L?m}EX74Taf3)&aCs54LeQ z_O%AFK>RI!9NL>VbWMW*q*G`flIGx3XO}OVq+ zLQ&3g(KJ0Xk1Stwt{I+_E@B<_?zp5XV*2#Kavl~xo2oOj$va$_IH^27#g^%z(sI+* zXMWQ5=y$8cYinF#NU#wiH$=Z(JH}tGdHql?-vF^c56v+NQ23b@ItOsh*!->XDAJ?R z)~x5pcI5pMqN!y70=(6-3sAjn=3i=;?kj*l1dDK=+4iEhPA)hI{uMi~eH2eSSl?)$ z5WRN>e5lf}8juz<5MfaMmSlUV;eP2Ium>qu*}?1XujXi`AtmXVSY|^qDoc__1C>b) zOIt$*i~q29&EAHbIts{y580f}{edoC?9GVFiIm!5p-v6FT>&0U!WkbXJ|3AF9{zc1 zB*Cx7Pr33*KbA3=pg7(+j=QS?=$90nGp1Glat+gC&pM2ue6ndMmk_L}jP;m`SY569 zBw=@eK;@yKDeBf)yI6GZi;tu}y@6G6(E~xLaAy*1-#d@dsRv{U^TNDN61Fxn8fw#; z=eZCW9H#!Xb`d7WP_f2;VA`j%O++lcp1GjNk3v2ClsbEC%jTS>c^)FMTeERLpC z97UA7J(e!ZKDpX*%*YMeRet?56+N}7dq3^)UGN<*H|1K`<=OZBdaL@252xSvS>Sfs zI%Ff@taYOETP45;`-csXj3+vKCt9HA@R2&ZsoiMmlzVBGyM?=_v$R-mmC{Y0M_Rf> z$ilTLZ*^hQ*d@4F7dq3}CAs+PlBpcyppa{HGP1)(cJBJ6?*U$TzXZ@hkyJo|G`yRkQv70~LkLf>!*lB<4-o6#Q zP5}k;_jrMV(Mo?+$X>M9~*DXp7@u%s@7ocd=&CBgUR`m zmVky;go4hlfY4X1$!IQYSeXV$?C@TU(`nBnWOfvEVM#Ia0CG?g>XduKL{b3}>_Xr1 zoOf3oK3c-u>|gt@oS;(OJ7YC6F!FQUxGEBm>TCd!da*&OAVfJ9F)qA-EEW-3!jYAG z&22vU5g`z0?XuPP^(sLM>16PA)meJ9xo+|K&BFFG66fBUwz(GL1zRtDR?AN%EKQMZ~y(Oo& z$!-F8e%jl^H^l6iDxIqc%Qj4?V?rjz0x=;UIUk=MWs?i`b!d3q%M0XYAd*K=82efK zS;@#_RZ@?dSJ5%TMPga(B3^!E0QNw9QC~saJXT^jo*JTo?GE)OEV_ZFSlva$BfN4&#e?TW)R)T)mG=v?R z{CeQMS37hqz}~oCie93&6L#vpTe$`U@g?PpvPI6)>XDlS+j5@Ljc>uM;p3mpXRK?o zf51e59W)|L(QHpUf;@w@>So>RICpEO%gW_8ojT+y3{HRrBqw^M{Gi|x--zxbXD9;b zfgk_o4Qn~JTw=QN_=%gLZ0V*!<6bT-rH3OY36@JW zM=Ise?;^%I_1F$XgB+R&o;=W_D%p?{Z&=gLg3DHgA((pn>6y4$HK*oLK1Oc#4oTu7 zM*%S_@_m7;12exQvMN%_Nw`40EUE*rjN(cgF{^*7Lpi9xpP{Td>4+h~p9eyy;r|N_ky~QoU&@7z4ve9PnY5ynRB#S0qxJ4Z_V(S>bz8nUQ?~pX{EQ9u9&nklt@Q$0~l? zFwNRgS5H`=?V5U>0rz{SO2E5i|6>UdDJsIm8kM2JHpyt;Sa=Zw8Gt1qy@`e}M^`8M z!WV{mIJ`7~1M0CU^_?1f;h~buF{mlV8^2PprSxm$CFeHf5P8a|cdL*4)r7`$_X+V) zkQs(AM*0FrxFSQ4gyfugo7h=!0wY~JQ6kRTWBCes}0c^P# z+`Vf2@JKt8l7JC0d~pKYijwq+YBwCl%BhY_Ltw1rhlLbxLli+LPB$LZ_^-r>@Ya&) zbI)}4ifs;gfiDK241xsP8R`k**hl=jZ0F}mJ~qWZN*o=$&UtJ zI?mKX<+RzzB16D3@qZOJn$@pzgoE+QLn-{QIOk#$#|5`n4r&fYdFA??bXDE7|Ma%v^XRS8^fL(!}ZPLcds>xFENjF>pk ze$;a;U3YB6p-Knf5urY0a!5mpyCzt}EP)p8g!f??H$qq+iC8a|@NBXQYnz#@{i+uA z47^C3q4ve{N1W682H?BFHnun)KGf@q zqeo6Jx?wtIr{5H1t?BR0x(Gx8A)TqzGbqEeI(B**<>x<*0HxD$IEeQA23^tDW1bbO zf^c`uk!WN5Sk{9t8e9F%Zmv6z0js5n-Lph!2ILoeP0YZ8j#sC!+kcYK3znXl|`0BP&XV{LckAegh9c<*)%e6N*HbbAx0fqs#Y$^?c&^#MeSGLvuv{&0I_X)qkdYS%8IJo@}42smci(UT<+BsQng8i9_OYm0r ziwUvSge&z^Fo)mx-zf{@b&`30s7WSf*t#LNkN%lkm6P|E35S4VPz2F{tE!)a)L8L$ zhC522QK`*#sEbCmAoCM;qF5V(#5K-_qn9gwrLZ@HOu`4AtCNc*4dP?GzXSeZCgh^t zW=+1ov?~M!0)h_$0}52q#;-5Neg_o>naCl4pa;Fsq8v2O6uV+r4;}|elx_E$tX`(s z)RXGlgpMHBd6LKC9ZlKgxi5TQ7?8gWX%YPT!?bpL(%WwE{?Gj(i4WuXvVottGyvBt zm>rYU<<@YZ{3VavD@bHKBAP3E>q-pjj(f{s4=L|SylzcDmdJ+k{*dpH}=HlgXZ z)mblJYG1gZu%TS&>RT0f%f%)Md6f5=e8|p~<{3yGZOG_}mco|JEj=&rzo6?#0AJ`wnsApo;fyE~8J9g+d8u`Z-rANW-J0p||8ut-3!md{M!l z{i^eQ#_z0fjAUYmGrP!-up(ba!3=P3bglJx?XTd#03vjVxxAlTzzG6sK;F6vWdKOb zPix$Z`F5)d!X7t-T3o;g2gIiTF!A>aBQ+RYEP1ZUmzS$O7x_9*uIu$R6}wb)S-}o? z-#9oD6^bU=ucxy)%S)dj5E+ol<&ycR#pN9 z;+1kYU28a?48QsnOMs{^*KsDZ`aqa7RWheW0G>c2d&-HgoxItNLR)@V3CP<->b~;Q zCyoK;pLtJ4N4wkD2-&Wh>F7M-j(ZP>7Q5OM&gCy{q}?;&bR-b1(nawLnQ&C(Jhnxx zn9>&FKP*6(?>hXe6pf~o-!yD=a$<8K9}^6+2&NRq1Svy>{~D^udTuDgeCJX%r4tC95s<+UheI~sjDd-iQC(w z-6a}9W+ejmy=V)D9Jr|hZ?B2^J8vP@0WcA}3uq0mxA5mtxyFv|FVR(O|Eo@Qc-2)y)dNk~?gnU*5Hn+qrkj+wH&_N+%E+T9B;fN+ zx5H6hjY8AnX2t@rMi~>1*5#V)6%hm^kp!4Sgb6s;(uvC-N%S|c`U*NAy^xh-#{wU^ zEENE=_3hsJa2}ZWiAYAlJfwdC*cusdSCeyVF7tUbD^#gume%iz4v&5&Nqo7>@xuPa zLfI=2sXw-k)uii80>9$F-}MX2(_m|8@oEeo#GTYgxQg{izF z^wcK27JYv{fn?G;K{9!s+2JG$RQncOWBkP;k_4M@0fF%r8>l~4OjfqFC@8pyHgh)k zy0%x_2P@D_Z>wRF$%p9ZZIIzRox1EWK?2DUZ*ngJ|cEDuNLd>)KNG}nY@7Zl{ zi)8|D&pC%IhZp1vRH!affg*}G)VJTTV(FNI>yxtoG*%@OuJ^_O@sD33_!rGM9*Avm z(~~UK`$iRlmQ6vZ#dcUen%L1&FzR=JW6E_*jPcVIqzJ8W@iWH6myczZh72FDZ6B+~ z9`u1@hHw1fDsUuATs(>h^!6WLwAw36+dF=Btvwc$uMF;TlEs4>PBN+G6xnd>>3mnaq9n zl_OATbMC%N;1`|=zyVxF*n>pCiKo9Q_{LlWXdP0l9$O4NPhpmn3)plrZAvte&=CrH zM*zwklJQ4|?m!ob4san-=3EvEe~oc`b6-rYoFiPq>4R7Uc0{r){9v}wlf{)wVwuva z`~z7_0lA>EXQdFF)G0s&-Ugxz&yTdzaN~{EP5^mxhyE*2l5bEhdYKlmZMbUL+%Nx% zDAwA)?!B4IaN_Dn#np~V-2|CSBKteU&8q=kE^}kDcGjGk^*1KDJ*0*3LrAFfq_CmG z-4xNpxhD&%Ba`K%QCv!0gtEionxhjH#mWdSC3#8jxM)tAsB$|aPiukL?^Rn&r=FI0MfZITmwJWxhs^v&^~a<}DMvrBHu;M$4Vb zi31L$1Y!$NVCR8RMiwV9xauTYtdt~m?l@_u%;bzXX@C6`RDsUiUW;pu`H?UDqmF4N z^RvqZ?^K&JEHF9Z99~Q^5YBk0w(xDc)Nk4YAy%B1cmq&Kc634X)cI?sQjI})vfaNr zXFN7(B7DmL&34;AedTky&BWQEZ8B~Gc5$;K;TiLb;JRIAyN$!raOA+B9hw2Q&_@^EmQSRN?Ctd@rb>1Qs%l@=fc>#0 z-1g?l_Q|sL_%gIX!~(gvtXf>_=J|fUtB2-F-OT0=TgKRDOx}#D(Bm=HgJV@*ofqNn z4WU)8d~&gVR%MDpm{EA63IlYNkcd@2>UddqmeUuFd+x}T%9YLaYj3gw@MwUhHC;ds zX1yi*rfSlh{W9};Hk+k8w3l229)h)Ej}nuD;%?=Oki)C6Wz2Ia|Bt8iRL*(`IM+9-7hY&X&|fb0g6n-IE!-zIj{T%9u$3 zAm<7KT?u6}yNkhvPGOTELD#K zWGW3D1!$-DeP$Y&9G&NVUbJ4Qa)Uj3_CEEsMedAPPFx;O@N(XfElI#rRyfPz{{A|S z*x||_h^D2r^V-1lQVqbqbMyzQv{yQ0VTt=MkW(CC_Z z=#BR6u&p4en|A|}LOAAFF)CU*tvx|jNA4n7hS42Kc!3KS1sf%hSd^T&P3C7W zPQM>id^EEbbc@zZX?+TgIw09vY8b%jT{@kp=;yVnNyd2}VXZ2JK=BB^%FLFW)ZrgZ z)V^2NTGAm!tQr72-?_XfS=uN7vDTjMA-@f>iI4|S7nOxIag#Jvf(4~Kv&@;obg z)Z4CGZns{}mQZV2Z6{ak4<{WRnKqH=6|pZ3)RJ;`n#@4EJ6k+FQ?nTkUP{V^W4Tb1 z@(`ZdNtlm0&+cR$bf!)cEQdlh7bwWH`?{0tzMgE=;SGSgve{u~SGIa}oyA9Vh^9xZ zdWTOGx;PFp4Q{u@Fk8LXO`V>DynIyu9TIEiUT^D4nnnF*VFCkR`HDVG=Ojtb?eWx5SEq=Y$%Pv2X;0k?BJEuVcGYr4#si;hTbud1GB5pT8O5gaOmYql zmeK={z!1R3=eIZ*&l3Xm+|FEZkjWdr`U4}qo6jj*xqJ_T zdWMbencC9D;DP4o_!%~ItCC%dm279;pE{?BqT&WcZt-X?{OUSwNLYp9Q*RoiG_NIv zbME1^)(bd>42=U9Hv37*-U?c7>nPp^E&7Xdvpv8pnq;}y7D$|N`L$>We9CQ?dZiqb zW}?xrdY-hb3~fLj9lBY**bkzxJ!&*@tL)L9x9+vvce02xYlAdbKqv^iI=BB^vLYVXzO?g`%oe4+W0EZcKz}wC?jX*wgb|nqiaz7 zntXc2r>V=z5t!S>g_G9yUC5;hgWC-7#*tYT)Vz(;5BmD>+S$s%`g}YJ3Ht_yJv^(> z*8GNBWZ?d%nbsR=Q_FYU-vx(G@kA~~H^kuERrmhI-WTU{6j3|d%VYOHt7||W9prjZ z(kL(hF$&`V9uf#hG6@I>^8dIV%pDwD&74{PWqQzBiCY~{27I^rgdRvb45{9OLkeQ}EDK2bYAEKTcb?oq0}0a( zbluO}2TOJRK*}fHdV!F1JPp`Zo7j@DRMa=rwqNMThnPBW*>AQ#${{>rKC9e)zqsKt zYW?m*-%%y4<+VFB`eA#I0@%P9F6`m*NzOs8R7yAqBm@@}_+$go%c z`s2&=vJSfJ0piyGYFOK1a?Ob_<{4oh9VCFQ?vdF?gALtDmHc9e1bEL*(*UVWOAXr+ zF}m_Dyw;+hLDGJAbd9$BAXHfgzufJdRciUF7dn>c<@Oa81%xgFq$6-HW&Od=FcqtV z_&!<9525LUf1Kb{er|pvk@E;3{V#UZ1OWu)Z$sl~bLX1qq&UV>1A;WY zEo{TtOZ#P%(*TOOnB=KrwV71xXDo_3(+z3$M=Wx41Vv*t-x5t%R#)WoE0OQ5#0c;9 zcfkZJRfD1#poNXa%}&?0=1nAT)S^EOaUlcrD$sCYs9PL|mQc$Ho?#0#L~Or!)=FIa9z1$~nc7GtP(wwDTHi$BW`p>M1i48Bd zp8Hsw+!e%fDjv5w;D_CH9%I9k36wfIsElAvmmpOu&odLLr6c3Gnz0DVyy_BlkOe@GKmGL{( z5j8?~&0zALe{Hjd;(ga1!h^cX+%DX@m?8@3hHO6oHV=$)2h1(*q6YT;Wyiqen!oHQ z0)P`mLqyZV+iQs8hrn@$NY9o)$4uiwWcg%l@CZu$eU7gEe#aMy6IOs9HV7h?Dr!zc z&dmjbq_r#VL`!iZV{_oXze8!b=U5=kgc?R?`{n{&tdA6?l<8X8L%Y-K!VOkUxobsD z)wt}v6*%foM7l&??fAh7QTAJr5r0=H5pc#m8S?xhmA*y!o=)fL8C$qT@eZYNV2VRC zz=-NSR+D9j);~nVLMKeLx2w&63pjdSq6iJ9j2#v4TFkq~Y~ivV>gA8?h}tq{)DIWk z$rPGS9K_<^q#%1ybf{Z9^GYy-myZY_-fMIfoIq&lihtHBlAi-4Tsc#NFgub4KmD}+eeDTo1q>Ri+PX$b z#x{ahLovEk%rXo4N4E$`tl?#2z6OtEb~7Zy6udzvhv1nIU0C9O~^il|(n)2MDzd58uB+#N;P66He?ep$|6a*lU{}_rdRO!w&bN8Rdoq z?SzD`snz5?cz(4*j*rD1qwMTU(oVCGJ9;oCUxEn+TP}rt|7H_Xcf5|_<;=SMGSa}B$0n*LyFbKagv{~ z^6_A(S#?ZzyJNXD(JKBFPuL2(R(MqZz}2FRxGBiVO6p-+$h*0u zVDZ3KHU$ADHN4&gh$Uf=ORpM0U{N}?Kr>@H58>yGKAp(5dyGx-y%e{!cc@M}ST|5; zM%=NDdrRl8pv?+M#tubn^zH|8^iI0GIZY=dTAZ=eJeL_Jry?NGH$yBEl&`8< zvTkwE53=Y<)O|iCuh(KP2tH%^I2W zKL%Us%Lvbe=bGki(3whVZnX`q>ok=qRt4u+L4!xOn~77RaHa=Zg7&}}FTI1#!u9lBy_4-3b>$2UcF89S=#F{RN-MLX z?nB!Fvmfxv6j>8(-xc6`eovImCdBRrl?`X5wLC!iYgaNpG+9whNQahmh!+1A=4Kgx z{cALl{KIP`XEOW@2Gsysv$bx0|H76YL# z?nO9oZ>m)IMO5jmKm#ZRta37L+_u)D|U5XXucb?Y7`AR`}EHIgKkk(4BfN} z2v1oW3b&c6s}}+JM*1-R&>mU4N1-l|o7&`($>MC6_@g6&Gv_;b{+Q~;S$Z|MgCPpg=xO zZjR)hMvs-(Y^PyM29`C=UxtY`iY_?KnhTf_Ez0n-!pM{NM+B zib%XG|K5JIBBqAeu=K1*m>SzLKm#h;{f9_-3N8WD@?}fQX||OsoiYmM0h&{=+=f{_#z)uxODWm+40mWnMO}q_xNV z)|kFsx6~<~z!m|e00DVuE4G9>s~Sy84E`V*ldFR>K3y@80`z?Ggu|x*fZtZCq;}?6 z!HHUbq?!@Q`6KnjJZY>VxImn-vkB3^XkNolFc`g6-Of!a--_^o^g7Zr1N zq!_$IrMK;)oplUl)lWoR0N|UZuf+1I^Ie_J(b7x^>C|_ySm*t>EW&JeRt%}e9FR-l zw###4-Snzmc3z(H_rO1WPb0k)%uKC}7_ID#EX@8gWq0R=4Er(q$WPibvPv~Dq`NV<&mM3MPbr)sp*~!_L zE7Ay>a_1xNzt2xUpYV8@12~$kJr+_HvmFlaO!-&|1$=#JqIwBkgt4=n2W<_TYxvmaEN5o`2i5BlJGHG^NWHCk~Pc~q!cOL zS~wLD&gc}WzGR0B)SKZpT=R;Gcrt40aK6<`OLT2|#0)L=VkKE-I_aS_L%h--Buy*v z2+d#7kbsHSn9)Epw}{et%2j-P(fZ%JmpB8p!5Ucm#5h3=J z0%o<70*-2?nI=rj?>Z(V)K!A>ZX%v6KS+z_zZ37Cb)1uh)}!7vm~|`&qtKkqA!aLX z+Zw(j;+HkgKD2KqU}wRCN8>mFBW7JbXi+x1*0efgGe{9CnA8&Q9L0fX8@1=gWRXjz za^M@lU!Gt3P;>OCs@9s;Q>(DhFtpW;suaw*1H|M^i<>LDWsV9JxBF!Zpm=EQNsdc#$gDYqn; zN#C^x<4z(|5;dXOPdfrQ;2D4AFnI-zyzdCRDL-j_%=mCSD5!*d<@l6L7Y!H`~!x;`Lbne{Q+A@wDKyF5#32cv$;k$)aYx19NDh=Nfx;5G4wIA9;NqD_(%;LlZufkljWdYh=npUVU{!- zgT<|wXELLW`6W0MjLSE8ZM@@Rs#gq!kAx@mtAq-b3IY7MfFVCK+&X~MTdx9n%e|u# z0Cknrr}OYKP`JrFF6gALf#|(mV!axzg&5o>cZR~K&LJt@gcuK8nhxR~L3)|6V# z+}wK)Wp?^Us9n#MWocyco{#j7C(XeW;7T6)Yf9&mv2{Rg-53 zow?=y46lR+Q7ej}&vpkMh@W4XhiZ#~ph_zR4 zIa8so9!m*vrQOtHNUi*hMOO(oC24%@nMs=a-XFC+Php6LM>qC`<*8SX!q z^M(h_(vWUAlOIL!JOSD91(%`(rejqW|S#6hH4botSQZIJJ)iV-hDaodR1bWfw-G1vGWPH@R|Hw<|5--fKxS+a8GR_ zjjKCAd8AeP04wMRxq&nkS#iQPS!EH?Svk7)#kO!hyzUr&sWX6G%X`q2b??@3SI1exFmPk>f}rUuh;>#=`QfXO)>As>m`$`aM4Gi7kZU0d)F@_vgGQPr zv$nTf8GI6RS#kq{bpaY92y7ig^--huQWoIY6Gq&_?8sWbrX`G@=)N)<6K=Qz^@6=) zyJK*X9y0F;-^Oc{wnZY?u@C|^++n(?g!l0x2Rx0Fq$&yJ({6~w8;+2a2POcyBOh!Z zl##x={)mg|QYA?oy&g@V_L|pe4zha-#7SO_c2K5-{$tTF4!zqz4j43)^#MuJ7hC?6NN94X)IpT`QiLcUoJMK-c zco%;zTX$AZb|$00?(Z$JYMx>Lai2jFg_n6m)Wa%LfdbZq{wgfw6S~&JO9Pc&d<2e+ zJY`WaTvpU!ZX=?z_AzL~3H{@(icF_UlO4)k4CPO0BNf5!E!Gm5#3(6kbLFuS4&Nyif4HlTae(madH zV*l{x(R+H5=Db-QP5i}uo z2UAB53rtg(Njo#dg#x}i9_uMGBN~`V7cq_f<}YNOJT4be z_CU4*UcMG6Z6IB6!Za-1#@nqE(hZojIfAeTY)K8D{ABd@C9zYIPb7Dc51sPK8%tDr zusv(ND{p&i>$I?=9%I4EnQf*Q(^G3i?jBaFK4cVfS>65`pkWkaD6>m&bO^WTIbVD* zu><=8`zIr?wyk;Hi+}B~OZ8LA^q>IeRU!f~@xgfGV(KO4ZJI21MUk-ej}|jkCrO&o&IRhyQ428Fs`*Gc zGd#l#0OQ;emkPH@Q8R)fWk?Yf7{)@jaj*4`3d9&|Qn=HAX6 z7Xl={N11+3>oaQI$dVr)HJbm0NN!V;6)7lN(LO5LpyUQhfu0V!Ve^>`{9dmeA*gS` zQyYi`vwor;{T}0!F7-iSGuGym9`2_%ai>Gg!rbYMImn359^NoX-526HLuUw6K`V=5jprQcNWM2f(@co{hY}*{`uncFSL&+Z~QM6Zi7jg*HB8= z$QjX8f1($xeV8Q953MXVFDN4mWy<1q-C5rI0wG$ zPnVWMn9yBPT%0$bxEUjkcvtf1In^zbws(FS52zK| z=I-jB7ms7{kk?5lb8Q2cK=j1ID;ITHcpdEycw#sb1KQIuX5>g|vd^qZTftBj0X*aj zLxIWuPxN7e_j&a1>UE213KrkT{EqHtpH+P0aAEW0uVn>BZ+%55{c8|d0a9V`g7_gR z0$ED9bb%Ex)ydV^ZXbIfq=N-I{5ENgeJjk4MrPUpE*(aPqh@NBi0kW>TEo?6o6hh` zYy3J)R@*ThPCt-BQhjgU6Kq|17_@e*uhQ^y_1F;IhBLfzYzFgDz5=-g2ZaOqQCrM()VI zw){W;3g+u?p_ig8C>TA+|1A-R{_h%bV33wF=p}GbixBTW3y=Q})qgj6;5ThD{Quu+ z|39&RjxOjx1#JfWe_7@KPCJC*K|oOdZye+X6PTt=_Frb@UTsXUZXDo>HYxtU4Wj?G z>G$tzqVR#(I(%UDG(dG768!(%9Q=1bd3xY49R|vOIPc#rh4;U!rvH=rfX6ztU?Ji_ z3|&h6|75>^Ump1bsHw{jW~c;A(d7l>)Cc;@VghY+k@5dMt@_XBvo{1{>XH4|?+_@c zhY4y7RM#WL|KE@C-%`7OHZ}j+{eQ1MTLb_A diff --git a/docker/docmosis/templates/CV-UNS-GAP-ENG-01074.docx b/docker/docmosis/templates/CV-UNS-GAP-ENG-01074.docx index 411e406ef56e9cc2eab7441ded9f8ece90a2aeb3..d0ee5a8ec54921541978f0199f67aac1ef00ef94 100644 GIT binary patch delta 8666 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 O^uYrF4bgwi=6?V-(GM~J delta 8417 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 delta 9202 zcmZX41yEeewl?nWPH+zrT!TY!$>4-w!QE|e_klqJ1cF;|w;;hKI0J;i-CZB&-v6HS z-u?Hk_3d8$_3B<#z4xwKUv+E)Y<&zYiMkRz0s#yX3C;UXAU3!zv#!&E0Xy$b{ElrJL3Uc}qXl702`p4x_hFcU)J_npnRLbb% z%S#-kFPD#JqgQ{5%4w<~`$PWw>R|rP(!Pz`T2I<&CM;JWtM zFsX^2s8%VBm`B>?cy-bQQ_TsRJh_^F;S=5(?3BCbbguvAHR-%`iE^(J`LS z?QguJZ{Oz?FVr{R~aLH-9Qt9jOVvtPhkRZ8Xu5)%3JRJ z?zga^28e0HaE{g;>`QY6N+}mgUa+^x;)HeQ@aphrG6|3p;s6o6 z_78eO?r9@Agv-(=-Z%A34ysTx$eTv87QPr&sIM%gN5i9JqQv0Jt$FahU>K2B>>N}z z9jV&*j;bE>eX!S6B7&gs`F2_bPidZ>lQuKQBSptWp4R$(FEiy=5Ajd;OaOUS5>;u6 z>6B~_2gRwoy~7jWgYy!$H5X7(VVE9^mg9b!UGONDbmV@;0XJ4LI7Ua2V6#3?`kFOQ zF%2t1<9(}EW`xm4fVsx73t3|R+J%r{$AD}x9PzRp636IS3N}(;33;sZ_}~~tcr71J z2joD%JaC36P%x~l7VQIsEM*F@0s!+35GV*>OT6?*oWuE2AM(9QiU$ah{0*SdJ9<-D zqE%bA#!JW2CG_1pn6!Gkz#;g86Lc5~Kh70Xl`m-8L{VfnW8#z&U>$@@%@>kr1)akg zb&!(Av;B-2mgB+by;MDrJ30Wr|K#H5o)P!v%yRmC&&SB6cRhI4>_Wv$2g{S~7j5(0 znBwT2!n7%c#k-Tl`Y_;tW4!H~`5W#v;i!XvY30SqnPV4w2bOT5Zk5Su^RzyO?Hg(B zP0a78Z!GEfB|m$QlYv5QPyN;b6?!IBwcjpEVN2LxVgv0+*lkDvhy~=MmE>zOPRzE0E$1nbrQ`IF-kv7;vaH1@`Le=XDAXA(B)2R|UjKB|h_QJKW+idVyR!4ggKSt)}LW z7Z~w6j_<@pa=3uPZBIGBIj>Ae7xN)p!{{E8cg%=o+*LLgSy*vQsOI5UPpy(}ihB^) z3Cu4IpN2ExKptsH$lBio*LAQ8`abfpPc==&CYn}S1ANMaA`Icpg}O#A=1+qQXbv*> zN#MKXc)#vUE=Y%CpQR}kcMy%Z1mwj z(N%e-t)|v<*(XrUss$>H=J?Y?eQhhig+$zXt+aBuUEx_Yj~pmuV6(- zSjHt=3oDRT?)%MqMi>f+_1XLCWTUNWt&~R`ko%5nb>Zd@U6qIad3`6F!o_|aWJV*a za_1c>(FZT653y8^g|DIp1Jw6YUFQn%K|)we+pyooAOCWT`|`9YPflbFm1c;|$GF~A z>BukbgPk&cgsP?odRjKep3ReMJN^5~6Jk=V=2W1$5Q{>9itraa<07+nSsS1C(*3)R zX+H8H`xs-mQukUe)y3Lg{3NVcrLdZI4B&1~F|l;BOPx-SuR3Ui zm-2rWid)r6Iy~sGFeTi)8Vy3OtTc-B~+?YCmFFRet=Js7V-SNwijxffu(JSj^ z{xt+-3cna8mEaFhx?U%*-HGD0l3b2=)GzZ<&~dtckXB~r!TW`7XgFfQSqb)%S2T+x zJ?oF3lIx=q;C{K^X~Yxxz@sVrX6HPgtp4_O8qqe$B5yx=;KEMbIS_zO*rL++z-M)Kim+J64xn zRX^Hq5p}rwgG`d-WEH$(U!!D;!T242*SeL|xjgG_Ti(+J>p+zlY(W|WpVb1L-fPv< z!5ePvKCwIj7y{yX->Q8&>e4pBp5gs6kv}^=j$h{8|Ex~YM4>uO)$fJyT=XJ!o=s%{ z={@q}M=$Jm`qwl)0@8a98i#RsIKE#!S~#97Hw`QI*D6m06Wp|jJ=?a9k4df6NHDs_ z=Ga;%T%{l0Zn__qM$H|R^4QqPN&vl&_CxvfNUg%x1Bg|1<>R3b;y&E_#n4a{Spn_- z@YMbrX8=^M)lzoOeQZ~(lK>Gjf_NQxITfG&{gMJefG()=@Y&lYgSajrWkBP@cP`e2 zEf$J5p}$Q4J`!v}PQvSf=G4VK>D#oMtgJj@i0v%PZ$4`~AUn~d$Fn!)){3X`x97rD zCzF63hA5PsMA+cL?GsK4aNDV3X5564O?0qL!oLY0!D7qV^=(TGvy>30=rVg#} zGITFVf=PKV%0^<`udyxfj1e1Fn{tEt>DD#21+~Z841?&r)8u36=Iu$Dg{#0fEL934 z57k6FA0`j%45p&P3fPF+rpO1Ffc-sA0zg1_Yq zSNRarIM9b0(b{rXo`S7wQ4+akKeiA+FR2pBq+wLYj^gU+U zrV`VV$kX*6HZc(PsR&8rM17(Ov(FslC8$2D-^C5}&ua%7b#?%bAqcUHQ_1~tuCs~m zkThObv^or zZ}^mSX1C|BH`{Y)w2ND?|G7r&!5%LjMR0Z`vfp0pK;Wl+rRQq(z%mU-W+(HQSn!bI`+Qrx z*7S~&(R)WuV0+1Etw}JLvqIG0U&yxsp`A@L-12fRF&x97Ld3wrIRU?8e%kale9QV8 ze!@H#g#&zu;nr0HDL4qOS*E<2e+Z?mlds8FV?|*>b#=g+1QCu z+WYA$Zu~yrd9Jg4ex=g4)Kh@|KEiX)_pC67w%oH6=%oa}aHSR3cajW_gx)6GS}0ZD zj~VXz*#7q4ywWaM>hN94k>taSYimIk2VC%4ar6BFxg!FiVkQD8rq5GgE10`DIhi_* zZ`L;(mntC%@((CVo_OMv36?g|4*MM{tI>kABYJA+nr_m^Q4=iezt>q?w=lK^8&9p& z2GJ>ixk8V@8$%8TtH^aoix-ssCXEX*#+bn1#9)L&zoEUiazCe-Zd+jv``J3q86vnj z$xm-pW5?wr%z9`ud(vjrOM`wSiB^NLBX`^va&qSf5L{86@XTxGCBCO{Xv^a>mTjT> zdeLICR~oWk;*QZ^t{HT}hbz;Al4ChOcDzjO! zmX)A$?&!N7pP2#ZO`Qvr_gGf`BxS`52pbSRLhYbaYP zNjqo&wivF>yDA`~HfQ}U)sp9iIQuq*gO+gpoH|2OZ{G%ICa77F<(pf3L`dL(+>pPn zd3Du;^O`)uFF*i%-6azeF3_LVM7#(A24)cx1_t-F&h&J2G3Ru(aC5VE_~QE3%igYD zN5io|5GO!l?^!x!=d~hL2v=gZ9X`UF~T!u33TKxEosMgR+D~*I}T;BFmuTzhM#ib&Q@5 zI$=9qanR5TYO&v&_1;{Cpkxyx1cc|V4shEF4VZY3OP@EL-7-=AW|+GMzD<7zmo(z{ z!btRM)4jqjNye96_2YMvGf42cs+;`MmI6U_X(m!D9gBQBumxm4G|Aq)k{Vl3ALx|l zhU9b)PxLXqWw`g0%%@LaV0R5iJN=83MqZEZoKpo1vs&Yd0(}rI4&ht0 z73W$wx>GL{4+@Q4Lb-f3zaY)lNenVA+}iK z@n>_M;LctsP`{q272UmDWqPVRUxuL3XR2_H{TFL(CTKo4if3}w{$zQ}RUSi_i%FwI+BKzzz{52(hM&`9Q@Z6iat%YFzD!-fhVGX@p5>t-v6L<8!SCjm+qy?I z^Iaavt*gIww$LX$-;S=cnVo;P@y2I5?`6~s^FWcYRCyHd%W0b`n;$ST6nW zo>!}N(a$<79k9wn`r6g3S1QMs7bhEPHH=DDG0V&gAY%cdC|aKq^!kQOB&mEQbKSmplrUdX zmbsdAeAxfvOF=~cvT8Q5PHwJN4d`y>4egU3(>1H!lFmfV@*kgt)x16XQd1H|N2ea2 zMW@mxxn73a{st~H0P$Uf`LYSnYSbenThXG)hTVm{g*al|Z|)iiGF=xva{`zBpwo_- z)a@NZs#VSXloR^y3z@+)vz}a?21)BPb1a?j=0lQ%!Pv^8dFCU;So0$5@LmE0t3-%q zp7|u`g8>7R>jk0~Ck86HLIm-CoftIy2`ZdErb*h0$Zj6UsQqewm??M`n>|EIOM`Bk zJb8`_x!5CyVL{c#Cm=t(VyIELPI%M$g2|iP^?0A%*Q1uRB~`RjFa!zF=$=-WqxBc0 z_V0Rm++JZGL@?BO zcLpu%rTQ(2dOy*w-uaR+vHP;?I7($y=+bP{67`SVp01e)mvQS+M;o%s3`z|DQ1;R% zd2k*ulTESiBq;Y&@!gm9P1dU)HXpn&q;$j6X%CHZ3(25>SEv1{yzQdV{t;QLX)rJ4 zZnOI_wa=g%6$|Ku0yCW`u|aZTGoY)tM1czxoW_)wA^KI#P4p%q+A1oaqUyoD!d|Zj z%>HRfCf;^t2(ASxfehI{ zUwozvkM{lgY6a@h%>;$SWBTFQhLstRonFVrI=yE?ahOD(|eA)W&d)$x4$ynm>tlO($RP>3WlZ8?gK&9Zc={g0l8&CHM5H`Qf6C+7l>zvvEAJ`pONF0VgVp z^n2ox_4F|Si&De1sfgH@mu_5fh0zw#8e}o3y%-$VS;14uWdHbKNSh?tFzalps=_El`2HpQ-Q$dd?Z|W=fC>a-8gNNWJnl zLQRV)wmEx_T;EC)V={f1%KN%npsr04N^qX4Zu$^Z1r*CJ;fH&7+W9+itv1$7weS7| zzG*mLJ3m)Cv@oa#qZ$Ll((ALyU2Iv54Vi}8EN?zmxwXs_pr7eu*Q*ooFK0UZ2GYT7 z3R*wX`}O^$rLA0de*`%M!i|qzDg+cx*Uo*1d8|7?#nY&dbpPlI6qysZJPdeiaf!FA z6>Ck7H`~4%8YzCj{@cYXg5OGeed#oEvjK{WYS&Btw#I-@We&gIHq*xvFdhS#BGcrY z8rL-h;4eXK%=%AJAZTlKgDyOz^=7EFx8*tGHlCX1o%U=I0(K*0Z_8IIWR}{=6eovu z!xMO|Z|^Po-+crF#jqIt!OrZtUNZ98gc%j4W8lYc&WfBvzz+Z=FuE2SAI?+6{Z$-t z4~GG!cwSq2RLX#3?kc@*x%nG<atGvQf~FcGQ|-XhaYe-cnB5cWa#HgABR^>0&~qKse>NU}>FtG<9+zV%jAQt-p}Rg$DZ9t< zQ99i6ehVTOm*ra3?hT3m6dYo|7EWykFYo?ChkL{o+8(+;Rv^60mvHYDK@8+m8{jcW z;Wk393NjZ1HX|jwe~TTVA7e>aI7Pu;I4wy?<1)ucSWC%UR##`%RDZ**J8pl5vDP@iIQ2j z+38o_gNQ`+hGH!^Wd_x_fhGt*CIz-7BSzwT8k`J(fHVG^E1~^#r&=RuN%mvN#876D zUdj=zAl>k~?uUF=TL|ngUH%gz$QR3;MUv&vw)8MRmW{|S@n$ZNG9T|o)6f2yREEa~ z?n@UjUb;j*b}d2>N3$YiUygZ1-(I^HEXci|zQpKn8;=n>4aS4;pAjs;BKfB{6&Zop zdF(+q62~uim?NMZuv6~z6BwfB(tBQC%&@%EmIIb6#vFMo=4ZZWX8R`Fqkp1kz!l+- zwGM%Otbr$lP=S1;5l8eWIzL=HIEHIR2R+a8-g?0PkD921Z*253L2UMN%4(|%T`R&h z(+kVxV7y|cB`~Xv>HR8D0JLkIagm@2*f}C6&c2tJaW7z0wH^-vjBC80>%_5d9RFI~ z8;INe>bV@biaHp#n;Mn9U6Qg{bUCi#Aag>$C6`x6NP+9Lh_hq|o$BaDs?fW%9yowqxL5Bb=qeuK$Xl2ECCZ1>WGXe$NX- z!?pS*g`i(DTM+*IN(+9I@}>SJ6`i0?gZQsJ{xj)ci%0(d`MB0N1*(4&Q!SZXl`lzL zr_)xD{5y|-hrGJ#Qi$8e|75xwJ#mj$2t43_Kz*(#zKDN%POI9Nd$N`owl9dkFPN)z zsk@hmabnpro4j9xCY1`@OZJHp{m#z!Fa$KUY=co|!X_MbR@816E`vCY%5uZF=9OU| zo2wZFi(Qrp&l?$-&*R%@R~ixO#y6@CZ4H7ypEk4Ykr`Dve$eQ}F-tZzQzD6Dqcxn!zEx&|`GBz$1$4=Cax#zPG40J@!->I7t{!1f5aYMN`@>cNY%- zxqHAX@U8l0IkeNk4PX7)&Gac@XV7>#=DIyztzxw zJfGJv?)-;Ed{(Glcr)xGPangVk;wx6+6u99hL|-y4#`iIK>zr1uw8Krs(;50@;`hH>Tp3$m*QJ}Q0v8ysGjE#&_{ z@LyT{uH?Z*s1D3zU}uACz3Dfq^V9nQwxkGMy4PuVCQ*s11)_=Tz2 ze<~55c6{GNr4wBy&<&h>Uk6pGzf(@-pW{H?Kk=K5Q3*L1Y1lqt*Wq*T80+a7nu5+= z);h#U{*((Kq1@!+C^iJ0uY_sR!nl&<+ zbBv3wa&myLoX7nUjjy~c$2|I3h0VWh2|#Rja!=!uHkXO(%u*NmMeZr}S9$eeX?#W2 zV-s2QC^Z|=`4|xSP&+_^x~4WU&g-;xr7t?|N;tVaR<`Uu@)P#EmywBfw0)JEo2WCn zx66IMQ*5CRKp-sJ-0WRL$y_ zjwmkTL*fItbEm8h@Cy?n4nK#jJv)Ca!mO-FUkYP7IGBekDg z1mPztkJw5l@@+I|BP3BIRa`XDQ(ig{c!I`8YjhCMv8l%?ysz!zEQhK1#9H|7?fDwa z02;$D=6zg(K=Wwy7OH}#Eq03hZedoTvD8p*;b2+N;WeX$@aN&~pUjv8s6T?36tlR* z_unM;nm!!E~Cc@W)!;(WFhERZR_we&<^!@z=U;b=CK5(8Rc8X?;xAIEdD zZqjfHw8ZiC5@Kk~ToB9QY*6ckk{*iZjMGOShsJ$JHvP|f;Evi)N>9(Y&t5rQb847j z744>hwJCLdsACGn@ za$w`6SFkgmUiGY(7kC&DiV_y;l5{DJ+v}DL)VSf!(4A42tv0!lE5mzd zOyaC}r_I!UEts*V`%V7=&h&-Kld>?9Tl%=JSVdl|Al0-H8sjcckrJ2b1z)G&HFAbJq9;ZI zySA3)9~6P@4d)%Q_=}<=U&*%^{s3|;E()q9>(CDwhq1^%Dtq}JYkHM+3mpPQXk*;r^R zQzcmU?0^=+q5PxH4JY(Fvz3K2iQR$nr z66oT?ZeVu+%EHndsIHqg#}6j&{O;)-@?F9{D=D2vmFmK51e9m@5rXt} zCE+fpKwov4DE?d5{3q&`0koz|NAZtT00V>l5Bu60V+B#`iNLuDfDHBC!&wV~a`fma z{{Euj{yW715zwk09mU`8*XsbB|1+PTIEYeT6pm361l1-dQddGm`isVVy_Mi$V6>$E G^8N>=6`+^^ diff --git a/docker/docmosis/templates/CV-UNS-GAP-ENG-01076.docx b/docker/docmosis/templates/CV-UNS-GAP-ENG-01076.docx index 6ba92f63f353eaa2fbc05339afb534a92eb66ddc..9d6e2d9cb1d7caa3da3926d6b2ef70c0f6decb01 100644 GIT binary patch delta 18787 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 XTEyRdprjs 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 delta 19700 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

Kxp}o71%3N)k z&Det$DT6H>$@Q`SS)UO|$sBr3KlD4A#iPA9EIjth6Y~l*2z1!WC2>!N<{2Lpm&v?kt zgZ1RJOl1D^M9E9ZW%xiQ9u}IWG%gDdEOdBWT}`y8)04QViGg!Xb$emm$1raS<&4$P zpft<%2S@A9JkG=GoieBCIEm&+gGJWz>4>V;QcycZ|8Bq%dK7W1!NwFq9&^9KeZ7bp zlO6pngaml+*Fo_%FL%Y zj_~J<-mJ8K+~ZootD_w~^?toGZb#bVVpr454d=c0_UrX|Jv}+=XcLeoMTN2PLBK?j6}azD|FL;2a+dd~M~(AzRS z%fi6nGRi1mfmIZ1oXL|!Jg;XBf@8WT40~4Rc+rXAGx=eB!`WQ6|02zsdoQ*wc=u?z}k9??Tx&L;gD$p@FNPgn&TVfvPHIv zSmPq^-Bp?xnm>#5h3aw)rouc*^P*Mf(D%m|M;utrs|EAo|As5(3Y^ZmSsPSE%6&dc zy01zWvjpJrP`HVDk~!$qw%CrCokMtSB@ETRif`mQMmbf>qT$2V zx<{Z4YzFZLOe!2ET&ptU98jTY_*5-uFcUMMn;t(SqglAHjwlwWuQ)dN*hHjVF81JN z{%cyAI7tOp>I^Vfag>O)q=+~KH`v&6GRShHW0SHPxexNpnmUxX8OV7dqGJ@C%$pi7GEW|)Z*W6uXSZbWgT6{XvTs5@w}j}u zt;m-cWlj--1LI2j2!UVm(305T!rB@HRXRbc;4^RMUox;8{)TPrL)}T(3jb)E~+pty5NVNB16uqd#YEwxwg9 z9bfXpAPWYS(=*jNO9miX)cSS^3rj@(KD3mSSgvXv2O zeNP|C!^6vW>%TjyFJm+gTUwcnv(zl3YMLOyW-8pb&57B0%!TTUSfcB_eMfn)%obs% zPbsjl@@|M*gpR0xw2Es|*i-qaIw;Jv+#}q@JhjpzQq>z=%x zpUhHSjsp-x`m-57PEP%dq{+e__C2eMjmh?!F+{JFBSpPMQg$f})i_Lk_cl%f<9>U# zy_NG+^Er&e12AXYZP|>ZYYzcC+CZ0*KXXRL<9N2XCb|yi2%atldln-4N81yfvk7k zKtHwi8&c~F=6^wSScD%3SzcmDCm03h!I&sZ)fsMj@@naq=2N~!pt7;j4dNgg>{KYKTdf$# z8nu6ou)zMIo$E}XlOHHoaa2o@a9!XA};?nJaG}9eolXF>G(!ek!rhqrT|;aLZ>*hAZ|RVnVkC@ z@P-N7zKGA)L%=$ae4$kGU~_|8{Z1P5^rHiioNvxHx53_Ukh!OZJhCFH(a27S3ewALU+@;|0fsY)1yKs-9{`J4_ z0~9hV>1Ce}(7tmXzCrw@qMLRA+;@Zh zrdxN>e3z7Yq)92lWOERpjdW=UOreOvOP{DOF1brtm zw+~)zyJW?IKe8bHzKuB>br#?jIKO$*MAjVh$Za0@D@4h<+w%?m_7RMaQqif z# zlIqcs{Fll9=|cZ>?Eew}&DfwudZMt8_jqmS;y?Yr1^mxb=HWn~f4Tox;6RBCMPMnkp{v>?1Zs-#2>;P={*9n_Adr&I He^&noH@Fm# delta 8013 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 SU;zz6@U$*E?1kpPlK&sC8F#7x diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/caseevents/TriggerGenAppLocationUpdateCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/caseevents/TriggerGenAppLocationUpdateCallbackHandler.java index 6b392415a0c..6a7c730596d 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/caseevents/TriggerGenAppLocationUpdateCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/caseevents/TriggerGenAppLocationUpdateCallbackHandler.java @@ -16,6 +16,7 @@ import java.util.List; import java.util.Map; +import static uk.gov.hmcts.reform.civil.callback.CallbackParams.Params.BEARER_TOKEN; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.TRIGGER_LOCATION_UPDATE; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.TRIGGER_UPDATE_GA_LOCATION; @@ -44,9 +45,10 @@ public List handledEvents() { private CallbackResponse triggerGaEvent(CallbackParams callbackParams) { CaseData caseData = callbackParams.getCaseData(); + String authToken = callbackParams.getParams().get(BEARER_TOKEN).toString(); try { if (caseData.getGeneralApplications() != null && !caseData.getGeneralApplications().isEmpty()) { - caseData = helperService.updateApplicationLocationDetailsInClaim(caseData); + caseData = helperService.updateApplicationLocationDetailsInClaim(caseData, authToken); helperService.triggerEvent(caseData, TRIGGER_LOCATION_UPDATE); } } catch (Exception e) { diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/genapplication/CaseLocationCivil.java b/src/main/java/uk/gov/hmcts/reform/civil/model/genapplication/CaseLocationCivil.java index edc224ba820..20bc4d13f5a 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/genapplication/CaseLocationCivil.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/genapplication/CaseLocationCivil.java @@ -14,4 +14,6 @@ public class CaseLocationCivil { private String region; private String siteName; private String baseLocation; + private String address; + private String postcode; } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/GenAppStateHelperService.java b/src/main/java/uk/gov/hmcts/reform/civil/service/GenAppStateHelperService.java index 2569a7ad87b..f0d0abaf206 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/GenAppStateHelperService.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/GenAppStateHelperService.java @@ -14,6 +14,7 @@ import uk.gov.hmcts.reform.civil.model.genapplication.GADetailsRespondentSol; import uk.gov.hmcts.reform.civil.model.genapplication.GeneralApplication; import uk.gov.hmcts.reform.civil.model.genapplication.GeneralApplicationsDetails; +import uk.gov.hmcts.reform.civil.referencedata.model.LocationRefData; import java.util.ArrayList; import java.util.HashMap; @@ -31,6 +32,7 @@ public class GenAppStateHelperService { private final CoreCaseDataService coreCaseDataService; private final CaseDetailsConverter caseDetailsConverter; + private final InitiateGeneralApplicationService genAppService; private final ObjectMapper objectMapper; @@ -69,16 +71,19 @@ public boolean triggerEvent(CaseData caseData, CaseEvent event) { return true; } - public CaseData updateApplicationLocationDetailsInClaim(CaseData caseData) { + public CaseData updateApplicationLocationDetailsInClaim(CaseData caseData, String authToken) { if (!Collections.isEmpty(caseData.getGeneralApplications())) { List genApps = new ArrayList<>(); CaseData finalCaseData = caseData; + LocationRefData locationDetails = genAppService.getWorkAllocationLocationDetails(finalCaseData.getCaseManagementLocation().getBaseLocation(), authToken); caseData.getGeneralApplications().forEach(generalApplicationElement -> { GeneralApplication generalApplication = generalApplicationElement.getValue(); generalApplication.getCaseManagementLocation().setBaseLocation(finalCaseData.getCaseManagementLocation().getBaseLocation()); generalApplication.getCaseManagementLocation().setRegion(finalCaseData.getCaseManagementLocation().getRegion()); - generalApplication.getCaseManagementLocation().setSiteName(finalCaseData.getLocationName()); + generalApplication.getCaseManagementLocation().setSiteName(locationDetails.getSiteName()); + generalApplication.getCaseManagementLocation().setAddress(locationDetails.getCourtAddress()); + generalApplication.getCaseManagementLocation().setPostcode(locationDetails.getPostcode()); Map genAppMap = generalApplication.toMap(objectMapper); genAppMap.put("isCcmccLocation", YesOrNo.NO); generalApplication = objectMapper.convertValue(genAppMap, GeneralApplication.class); diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationService.java b/src/main/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationService.java index a6191151527..f70a80f9ad5 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationService.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationService.java @@ -179,6 +179,13 @@ private GeneralApplication buildApplication(CaseData.CaseDataBuilder dataBuilder Pair caseLocation = getWorkAllocationLocation(caseData, authToken); //Setting Work Allocation location and location name + if (Objects.isNull(caseLocation.getLeft().getSiteName()) + && Objects.nonNull(caseLocation.getLeft().getBaseLocation())) { + LocationRefData locationDetails = getWorkAllocationLocationDetails(caseLocation.getLeft().getBaseLocation(), authToken); + caseLocation.getLeft().setSiteName(locationDetails.getSiteName()); + caseLocation.getLeft().setAddress(locationDetails.getCourtAddress()); + caseLocation.getLeft().setPostcode(locationDetails.getPostcode()); + } applicationBuilder.caseManagementLocation(caseLocation.getLeft()); applicationBuilder.isCcmccLocation(caseLocation.getRight() ? YES : NO); applicationBuilder.locationName(hasSDOBeenMade(caseData.getCcdState()) @@ -343,6 +350,8 @@ public Pair getWorkAllocationLocation(CaseData caseD .region(ccmccLocation.getRegionId()) .baseLocation(ccmccLocation.getEpimmsId()) .siteName(ccmccLocation.getSiteName()) + .address(ccmccLocation.getCourtAddress()) + .postcode(ccmccLocation.getPostcode()) .build(); return Pair.of(courtLocation, true); } @@ -369,6 +378,15 @@ private CaseLocationCivil getClaimant1PreferredLocation(CaseData caseData) { .build(); } + public LocationRefData getWorkAllocationLocationDetails(String baseLocation, String authToken) { + List locationDetails = locationRefDataService.getCourtLocationsByEpimmsId(authToken, baseLocation); + if (locationDetails != null && !locationDetails.isEmpty()) { + return locationDetails.get(0); + } else { + return LocationRefData.builder().build(); + } + } + private boolean isDefendant1RespondedFirst(CaseData caseData) { return caseData.getRespondent2ResponseDate() == null || (caseData.getRespondent1ResponseDate() != null diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/caseevents/TriggerGenAppLocationUpdateCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/caseevents/TriggerGenAppLocationUpdateCallbackHandlerTest.java index e82e3a302b3..53cd99df257 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/caseevents/TriggerGenAppLocationUpdateCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/caseevents/TriggerGenAppLocationUpdateCallbackHandlerTest.java @@ -46,6 +46,8 @@ class TriggerGenAppLocationUpdateCallbackHandlerTest extends BaseCallbackHandler @MockBean private GenAppStateHelperService helperService; + private static final String authToken = "Bearer TestAuthToken"; + @Test void handleEventsReturnsTheExpectedCallbackEvent() { assertThat(handler.handledEvents()).contains(TRIGGER_UPDATE_GA_LOCATION); @@ -60,12 +62,12 @@ void shouldTriggerGeneralApplicationEvent_whenCaseHasGeneralApplication() { true, true, getOriginalStatusOfGeneralApplication() ); - when(helperService.updateApplicationLocationDetailsInClaim(caseData)).thenReturn(caseData); + when(helperService.updateApplicationLocationDetailsInClaim(any(), any())).thenReturn(caseData); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); assertThat(response.getErrors()).isNull(); - verify(helperService, times(1)).updateApplicationLocationDetailsInClaim(caseData); + verify(helperService, times(1)).updateApplicationLocationDetailsInClaim(any(), any()); verify(helperService, times(1)).triggerEvent(caseData, TRIGGER_LOCATION_UPDATE); verify(helperService, times(1)).triggerEvent(caseData, TRIGGER_LOCATION_UPDATE); verifyNoMoreInteractions(helperService); @@ -93,7 +95,7 @@ void triggerGeneralApplicationEventThrowsException_HandleFailure() { ); String expectedErrorMessage = "Could not trigger event to update location on application under case: " + caseData.getCcdCaseReference(); - when(helperService.updateApplicationLocationDetailsInClaim(caseData)).thenReturn(caseData); + when(helperService.updateApplicationLocationDetailsInClaim(any(), any())).thenReturn(caseData); when(helperService.triggerEvent(any(CaseData.class), eq(TRIGGER_LOCATION_UPDATE))) .thenThrow(new RuntimeException()); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/GenAppStateHelperServiceTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/GenAppStateHelperServiceTest.java index 6aa26270c72..f6626efde69 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/GenAppStateHelperServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/GenAppStateHelperServiceTest.java @@ -18,14 +18,19 @@ import uk.gov.hmcts.reform.civil.model.genapplication.CaseLocationCivil; import uk.gov.hmcts.reform.civil.model.genapplication.GADetailsRespondentSol; import uk.gov.hmcts.reform.civil.model.genapplication.GeneralApplicationsDetails; +import uk.gov.hmcts.reform.civil.referencedata.LocationRefDataService; +import uk.gov.hmcts.reform.civil.referencedata.model.LocationRefData; import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; import uk.gov.hmcts.reform.civil.sampledata.GeneralApplicationDetailsBuilder; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; @@ -50,13 +55,19 @@ class GenAppStateHelperServiceTest { @MockBean private CoreCaseDataService coreCaseDataService; + @MockBean + private InitiateGeneralApplicationService genAppService; @Autowired private CaseDetailsConverter caseDetailsConverter; + @MockBean + private LocationRefDataService locationRefDataService; + private static final String APPLICATION_CLOSED_TEXT = "Application Closed"; private static final String APPLICATION_OFFLINE_TEXT = "Proceeds In Heritage"; private static final String SET_DATE = "2022-08-31T22:50:11.2509019"; + private static final String authToken = "Bearer TestAuthToken"; @Nested class StatusChangeInApplicationDetailsInClaim { @@ -393,6 +404,10 @@ private CaseDetails getCaseDetails( @Test void updateApplicationLocationDetailsLists() { + when(locationRefDataService.getCourtLocationsByEpimmsId(any(), any())) + .thenReturn(getSampleCourLocationsRefObject()); + when(genAppService.getWorkAllocationLocationDetails(any(), any())) + .thenReturn(getSampleCourLocationsRefObject1()); CaseData caseData = GeneralApplicationDetailsBuilder.builder() .getTestCaseDataWithDetails(CaseData.builder().build(), true, @@ -404,8 +419,10 @@ void updateApplicationLocationDetailsLists() { Pair caseLocation = Pair.of(CaseLocationCivil.builder() .region("2") .baseLocation("00000").siteName("locationOfRegion2") + .address("Prince William House, Peel Cross Road, Salford") + .postcode("M5 4RR") .build(), false); - CaseData updatedData = service.updateApplicationLocationDetailsInClaim(caseData); + CaseData updatedData = service.updateApplicationLocationDetailsInClaim(caseData, authToken); assertThat(getGADetailsFromUpdatedCaseData(updatedData, "1234")).isNotNull(); assertThat(updatedData.getGeneralApplications().get(0).getValue().getCaseManagementLocation()).isEqualTo(caseLocation.getLeft()); @@ -416,6 +433,23 @@ void updateApplicationLocationDetailsLists() { assertThat(updatedData.getGeneralApplications().get(2).getValue().getIsCcmccLocation()).isEqualTo(YesOrNo.NO); } + protected List getSampleCourLocationsRefObject() { + return new ArrayList<>(List.of( + LocationRefData.builder() + .epimmsId("00000").siteName("locationOfRegion2").courtAddress("Prince William House, Peel Cross Road, Salford") + .postcode("M5 4RR") + .courtLocationCode("court1").build() + )); + } + + protected LocationRefData getSampleCourLocationsRefObject1() { + return + LocationRefData.builder() + .epimmsId("00000").siteName("locationOfRegion2").courtAddress("Prince William House, Peel Cross Road, Salford") + .postcode("M5 4RR") + .courtLocationCode("court1").build(); + } + @Test void noLocationUpdatesToCaseDataIfThereAreNoGeneralApplications() { setupForApplicationOffline(); @@ -427,8 +461,7 @@ void noLocationUpdatesToCaseDataIfThereAreNoGeneralApplications() { Map.of() ); - CaseData response = service.updateApplicationLocationDetailsInClaim( - caseData); + CaseData response = service.updateApplicationLocationDetailsInClaim(caseData, authToken); CaseData updatedData = mapper.convertValue(response, CaseData.class); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationServiceTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationServiceTest.java index 3eabd89f790..c4e659ce307 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationServiceTest.java @@ -901,7 +901,8 @@ void shouldPopulateApplicantDetails() { CaseData caseData = GeneralApplicationDetailsBuilder.builder() .getTestCaseDataForConsentUnconsentCheck(GARespondentOrderAgreement.builder().hasAgreed(NO).build()); when(locationRefDataService.getCcmccLocation(any())) - .thenReturn(LocationRefData.builder().regionId("9").epimmsId("574546").siteName("CCMCC").build()); + .thenReturn(LocationRefData.builder().regionId("9").epimmsId("574546").siteName("CCMCC") + .courtAddress("Prince William House, Peel Cross Road, Salford").postcode("M5 4RR").build()); CaseData result = service.buildCaseData(caseData.toBuilder(), caseData, UserDetails.builder() .email(APPLICANT_EMAIL_ID_CONSTANT).id(STRING_NUM_CONSTANT).build(), CallbackParams.builder().toString()); @@ -914,11 +915,98 @@ void shouldPopulateApplicantDetails() { assertThat(result.getGeneralApplications().get(0).getValue().getLocationName()) .isEqualTo("CCMCC"); + assertThat(result.getGeneralApplications().get(0).getValue().getCaseManagementLocation().getAddress()) + .isEqualTo("Prince William House, Peel Cross Road, Salford"); + assertThat(result.getGeneralApplications().get(0).getValue().getCaseManagementLocation().getPostcode()) + .isEqualTo("M5 4RR"); assertThat(result.getGeneralApplications().get(0).getValue().getGeneralAppRespondentSolicitors() .stream().filter(e -> STRING_NUM_CONSTANT.equals(e.getValue().getId())).count()).isEqualTo(0); } + @Test + void shouldPopulateLocationDetailsForBaseLocation() { + when(locationRefDataService.getCourtLocationsByEpimmsId(any(), any())).thenReturn(getSampleCourLocationsRefObject()); + CaseData caseData = GeneralApplicationDetailsBuilder.builder() + .getCaseDataForWorkAllocation(null, null, INDIVIDUAL, applicant1DQ, respondent1DQ, + respondent2DQ); + CaseData result = service.buildCaseData(caseData.toBuilder(), caseData, UserDetails.builder() + .email(APPLICANT_EMAIL_ID_CONSTANT).build(), CallbackParams.builder().toString()); + assertThat(result.getGeneralApplications().get(0).getValue().getCaseManagementLocation().getBaseLocation()) + .isEqualTo("11111"); + assertThat(result.getGeneralApplications().get(0).getValue().getCaseManagementLocation().getSiteName()) + .isEqualTo("locationOfRegion2"); + assertThat(result.getGeneralApplications().get(0).getValue().getCaseManagementLocation().getAddress()) + .isEqualTo("Prince William House, Peel Cross Road, Salford"); + assertThat(result.getGeneralApplications().get(0).getValue().getCaseManagementLocation().getPostcode()) + .isEqualTo("M5 4RR"); + } + + protected List getSampleCourLocationsRefObject() { + return new ArrayList<>(List.of( + LocationRefData.builder() + .epimmsId("11111").siteName("locationOfRegion2").courtAddress("Prince William House, Peel Cross Road, Salford") + .postcode("M5 4RR") + .courtLocationCode("court1").build() + )); + } + + protected List getEmptyCourLocationsRefObject() { + return new ArrayList<>(List.of( + LocationRefData.builder().build() + )); + } + + protected List getSampleCourtLocationsRefObjectMultipleValues() { + return new ArrayList<>(List.of( + LocationRefData.builder() + .epimmsId("11111").siteName("locationOfRegion2").courtAddress("Prince William House, Peel Cross Road, Salford") + .postcode("M5 4RR") + .courtLocationCode("court1").build(), + + LocationRefData.builder() + .epimmsId("11111").siteName("locationOfRegion2").courtAddress("Prince William House, Peel Cross Road, Salford") + .postcode("M5 4RR") + .courtLocationCode("court1").build() + )); + } + + @Test + void shouldPopulateLocationDetailsForBaseLocationWhereListIsEmpty() { + when(locationRefDataService.getCourtLocationsByEpimmsId(any(), any())).thenReturn(getEmptyCourLocationsRefObject()); + CaseData caseData = GeneralApplicationDetailsBuilder.builder() + .getCaseDataForWorkAllocation(null, null, INDIVIDUAL, applicant1DQ, respondent1DQ, + respondent2DQ); + CaseData result = service.buildCaseData(caseData.toBuilder(), caseData, UserDetails.builder() + .email(APPLICANT_EMAIL_ID_CONSTANT).build(), CallbackParams.builder().toString()); + assertThat(result.getGeneralApplications().get(0).getValue().getCaseManagementLocation().getBaseLocation()) + .isEqualTo("11111"); + assertThat(result.getGeneralApplications().get(0).getValue().getCaseManagementLocation().getSiteName()) + .isNull(); + assertThat(result.getGeneralApplications().get(0).getValue().getCaseManagementLocation().getAddress()) + .isNull(); + assertThat(result.getGeneralApplications().get(0).getValue().getCaseManagementLocation().getPostcode()) + .isNull(); + } + + @Test + void shouldPopulateLocationDetailsForBaseLocationWithMultipleListValues() { + when(locationRefDataService.getCourtLocationsByEpimmsId(any(), any())).thenReturn(getSampleCourtLocationsRefObjectMultipleValues()); + CaseData caseData = GeneralApplicationDetailsBuilder.builder() + .getCaseDataForWorkAllocation(null, null, INDIVIDUAL, applicant1DQ, respondent1DQ, + respondent2DQ); + CaseData result = service.buildCaseData(caseData.toBuilder(), caseData, UserDetails.builder() + .email(APPLICANT_EMAIL_ID_CONSTANT).build(), CallbackParams.builder().toString()); + assertThat(result.getGeneralApplications().get(0).getValue().getCaseManagementLocation().getBaseLocation()) + .isEqualTo("11111"); + assertThat(result.getGeneralApplications().get(0).getValue().getCaseManagementLocation().getSiteName()) + .isEqualTo("locationOfRegion2"); + assertThat(result.getGeneralApplications().get(0).getValue().getCaseManagementLocation().getAddress()) + .isEqualTo("Prince William House, Peel Cross Road, Salford"); + assertThat(result.getGeneralApplications().get(0).getValue().getCaseManagementLocation().getPostcode()) + .isEqualTo("M5 4RR"); + } + @Test void shouldPopulateWorkAllocationLocationOnAboutToSubmit_beforeSDOHasBeenMade() { when(locationRefDataService.getCcmccLocation(any())) From f8969cd124e507a5239387c1625d8bf051de2914 Mon Sep 17 00:00:00 2001 From: UshaPanneerselvam1 <122611188+UshaPanneerselvam1@users.noreply.github.com> Date: Tue, 14 Nov 2023 10:09:11 +0000 Subject: [PATCH 27/28] CIV-8923 specAoSApplicantCorrespondenceAddressdetails is being updated when defendant updates address (#3547) * CIV-8923 specAoSApplicantCorrespondenceAddressdetails is being updated when defendant updates address --------- Co-authored-by: TortolaNavarroD Co-authored-by: asthamalviya <104994907+asthamalviya@users.noreply.github.com> Co-authored-by: kdaHMCTS <128375235+kdaHMCTS@users.noreply.github.com> Co-authored-by: dtortolaV1 <93722198+dtortolaV1@users.noreply.github.com> --- .../RespondToClaimSpecCallbackHandler.java | 90 +- .../reform/civil/model/CaseDataParent.java | 17 + .../civil/utils/UnavailabilityDatesUtils.java | 2 +- ...RespondToClaimSpecCallbackHandlerTest.java | 1378 ++++++++++++----- 4 files changed, 1024 insertions(+), 463 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandler.java index 5640b94350a..701d9c1c912 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandler.java @@ -184,7 +184,7 @@ protected Map callbacks() { .put(callbackKey(MID, "upload"), this::emptyCallbackResponse) .put(callbackKey(MID, "statement-of-truth"), this::resetStatementOfTruth) .put(callbackKey(MID, "validate-payment-date"), this::validateRespondentPaymentDate) - .put(callbackKey(MID, "specCorrespondenceAddress"), this::validateCorrespondenceApplicantAddress) + .put(callbackKey(MID, "specCorrespondenceAddress"), this::validateCorrespondenceAddress) .put(callbackKey(MID, "determineLoggedInSolicitor"), this::determineLoggedInSolicitor) .put(callbackKey(MID, "track"), this::handleDefendAllClaim) .put(callbackKey(MID, "specHandleResponseType"), this::handleRespondentResponseTypeForSpec) @@ -1060,12 +1060,26 @@ private AllocatedTrack getAllocatedTrack(CaseData caseData) { ); } - private CallbackResponse validateCorrespondenceApplicantAddress(CallbackParams callbackParams) { - if (SpecJourneyConstantLRSpec.DEFENDANT_RESPONSE_SPEC.equals(callbackParams.getRequest().getEventId())) { - return validateCorrespondenceApplicantAddress(callbackParams, postcodeValidator); + private CallbackResponse validateCorrespondenceAddress(CallbackParams callbackParams) { + CaseData caseData = callbackParams.getCaseData(); + if (caseData.getIsRespondent1() == YES + && caseData.getRespondentSolicitor1ServiceAddressRequired() == NO) { + List errors = postcodeValidator.validate( + caseData.getRespondentSolicitor1ServiceAddress().getPostCode()); + + return AboutToStartOrSubmitCallbackResponse.builder() + .errors(errors) + .build(); + } else if (caseData.getIsRespondent2() == YES + && caseData.getRespondentSolicitor2ServiceAddressRequired() == NO) { + List errors = postcodeValidator.validate( + caseData.getRespondentSolicitor2ServiceAddress().getPostCode()); + + return AboutToStartOrSubmitCallbackResponse.builder() + .errors(errors) + .build(); } - return AboutToStartOrSubmitCallbackResponse.builder() - .build(); + return AboutToStartOrSubmitCallbackResponse.builder().build(); } private CallbackResponse determineLoggedInSolicitor(CallbackParams callbackParams) { @@ -1118,6 +1132,10 @@ private CallbackResponse populateRespondent1Copy(CallbackParams callbackParams) .respondent1Copy(caseData.getRespondent1()) .respondent1ClaimResponseTestForSpec(caseData.getRespondent1ClaimResponseTypeForSpec()) .respondent2ClaimResponseTestForSpec(caseData.getRespondent2ClaimResponseTypeForSpec()) + .respondentSolicitor1ServiceAddress(Address.builder().build()) + .respondentSolicitor2ServiceAddress(Address.builder().build()) + .respondentSolicitor1ServiceAddressRequired(null) + .respondentSolicitor2ServiceAddressRequired(null) .showConditionFlags(initialShowTags); updatedCaseData.respondent1DetailsForClaimDetailsTab(caseData.getRespondent1().toBuilder().flags(null).build()); @@ -1265,9 +1283,9 @@ private CallbackResponse validateUnavailableDates(CallbackParams callbackParams) } private CallbackResponse validateDateOfBirth(CallbackParams callbackParams) { - Party respondent = callbackParams.getCaseData().getRespondent1(); - if (respondent == null && callbackParams.getCaseData().getRespondent2() != null) { - respondent = callbackParams.getCaseData().getRespondent2(); + Party respondent = callbackParams.getCaseData().getRespondent1Copy(); + if (respondent == null && callbackParams.getCaseData().getRespondent2Copy() != null) { + respondent = callbackParams.getCaseData().getRespondent2Copy(); } List errors = dateOfBirthValidator.validate(respondent); @@ -1345,9 +1363,9 @@ private CallbackResponse setApplicantResponseDeadline(CallbackParams callbackPar AllocatedTrack allocatedTrack = caseData.getAllocatedTrack(); Party updatedRespondent1; - if (NO.equals(caseData.getSpecAoSApplicantCorrespondenceAddressRequired())) { + if (NO.equals(caseData.getTempAddress1Required())) { updatedRespondent1 = caseData.getRespondent1().toBuilder() - .primaryAddress(caseData.getSpecAoSApplicantCorrespondenceAddressdetails()).build(); + .primaryAddress(caseData.getTempAddress1()).build(); } else { updatedRespondent1 = caseData.getRespondent1().toBuilder() .primaryAddress(caseData.getRespondent1Copy().getPrimaryAddress()) @@ -1424,21 +1442,8 @@ && ifResponseTypeIsPartOrFullAdmission(caseData)) { .businessProcess(BusinessProcess.ready(DEFENDANT_RESPONSE_SPEC)); if (caseData.getRespondent2() != null && caseData.getRespondent2Copy() != null) { - Party updatedRespondent2; - - if (NO.equals(caseData.getSpecAoSRespondent2HomeAddressRequired())) { - updatedRespondent2 = caseData.getRespondent2().toBuilder() - .primaryAddress(caseData.getSpecAoSRespondent2HomeAddressDetails()).build(); - } else { - updatedRespondent2 = caseData.getRespondent2().toBuilder() - .primaryAddress(caseData.getRespondent2Copy().getPrimaryAddress()).build(); - } - - updatedData - .respondent2(updatedRespondent2.toBuilder() - .flags(caseData.getRespondent2Copy().getFlags()).build()) - .respondent2Copy(null); - updatedData.respondent2DetailsForClaimDetailsTab(updatedRespondent2.toBuilder().flags(null).build()); + Party updatedRespondent2 = applyRespondent2Address(caseData, updatedData); + updatedData.respondent2DetailsForClaimDetailsTab(updatedRespondent2); } // moving statement of truth value to correct field, this was not possible in mid event. @@ -1495,8 +1500,10 @@ && ifResponseTypeIsPartOrFullAdmission(caseData)) { .build()); } - UnavailabilityDatesUtils.rollUpUnavailabilityDatesForRespondent(updatedData, - toggleService.isUpdateContactDetailsEnabled()); + UnavailabilityDatesUtils.rollUpUnavailabilityDatesForRespondent( + updatedData, + toggleService.isUpdateContactDetailsEnabled() + ); updatedData.respondent1DetailsForClaimDetailsTab(updatedData.build().getRespondent1().toBuilder().flags(null).build()); if (ofNullable(caseData.getRespondent2()).isPresent()) { @@ -1568,6 +1575,21 @@ && isAwaitingAnotherDefendantResponse(caseData)) { .build(); } + private static Party applyRespondent2Address(CaseData caseData, CaseData.CaseDataBuilder updatedData) { + Party updatedRespondent2; + + if (NO.equals(caseData.getTempAddress2Required())) { + updatedRespondent2 = caseData.getRespondent2().toBuilder() + .primaryAddress(caseData.getTempAddress2()).build(); + } else { + updatedRespondent2 = caseData.getRespondent2().toBuilder() + .primaryAddress(caseData.getRespondent2Copy().getPrimaryAddress()).build(); + } + + updatedData.respondent2(updatedRespondent2).respondent2Copy(null); + return updatedRespondent2; + } + private boolean ifResponseTypeIsPartOrFullAdmission(CaseData caseData) { return (RespondentResponseTypeSpec.PART_ADMISSION.equals(caseData.getRespondent1ClaimResponseTypeForSpec()) || RespondentResponseTypeSpec.PART_ADMISSION.equals( @@ -1582,19 +1604,19 @@ private void updateCorrespondenceAddress(CallbackParams callbackParams, CaseData.CaseDataBuilder updatedCaseData, CaseData caseData) { if (solicitorHasCaseRole(callbackParams, RESPONDENTSOLICITORONE) - && caseData.getSpecAoSRespondentCorrespondenceAddressRequired() == YesOrNo.NO) { - Address newAddress = caseData.getSpecAoSRespondentCorrespondenceAddressdetails(); + && caseData.getRespondentSolicitor1ServiceAddressRequired() == YesOrNo.NO) { + Address newAddress = caseData.getRespondentSolicitor1ServiceAddress(); updatedCaseData.specRespondentCorrespondenceAddressdetails(newAddress) - .specAoSRespondentCorrespondenceAddressdetails(Address.builder().build()); + .respondentSolicitor1ServiceAddress(Address.builder().build()); if (getMultiPartyScenario(caseData) == ONE_V_TWO_ONE_LEGAL_REP) { // to keep with heading tab updatedCaseData.specRespondent2CorrespondenceAddressdetails(newAddress); } } else if (solicitorHasCaseRole(callbackParams, RESPONDENTSOLICITORTWO) - && caseData.getSpecAoSRespondent2CorrespondenceAddressRequired() == YesOrNo.NO) { + && caseData.getRespondentSolicitor2ServiceAddressRequired() == YesOrNo.NO) { updatedCaseData.specRespondent2CorrespondenceAddressdetails( - caseData.getSpecAoSRespondent2CorrespondenceAddressdetails()) - .specAoSRespondent2CorrespondenceAddressdetails(Address.builder().build()); + caseData.getRespondentSolicitor2ServiceAddress()) + .respondentSolicitor2ServiceAddress(Address.builder().build()); } } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseDataParent.java b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseDataParent.java index 7d2a5546ce9..08b9556caf8 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseDataParent.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseDataParent.java @@ -723,6 +723,23 @@ public boolean isApplicantNotRepresented() { private FastTrackAllocation fastTrackAllocation; + /** + * used to temporary hold addresses. + */ + private final Address tempAddress1; + /** + * used with tempAddress1. + */ + private final YesOrNo tempAddress1Required; + /** + * used to temporary hold addresses. + */ + private final Address tempAddress2; + /** + * used with tempAddress1. + */ + private final YesOrNo tempAddress2Required; + @JsonIgnore public boolean isResponseAcceptedByClaimant() { return applicant1AcceptAdmitAmountPaidSpec == YesOrNo.YES diff --git a/src/main/java/uk/gov/hmcts/reform/civil/utils/UnavailabilityDatesUtils.java b/src/main/java/uk/gov/hmcts/reform/civil/utils/UnavailabilityDatesUtils.java index 5c394d09ee5..81a5e845f2e 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/utils/UnavailabilityDatesUtils.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/utils/UnavailabilityDatesUtils.java @@ -76,7 +76,7 @@ public static void rollUpUnavailabilityDatesForRespondent(CaseData.CaseDataBuild .getUnavailableDates(); List> updatedUnavailableDates = addEventAndDate( - caseData.getRespondent1ResponseDate().toLocalDate(), + caseData.getRespondent2ResponseDate().toLocalDate(), DEFENDANT_RESPONSE_EVENT, respondent2DQUnavailableDates ); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandlerTest.java index 6fbfc1fb527..1ae04095de2 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandlerTest.java @@ -19,6 +19,7 @@ import uk.gov.hmcts.reform.ccd.client.model.CallbackRequest; import uk.gov.hmcts.reform.ccd.client.model.CallbackResponse; import uk.gov.hmcts.reform.ccd.client.model.SubmittedCallbackResponse; +import uk.gov.hmcts.reform.civil.callback.CallbackException; import uk.gov.hmcts.reform.civil.callback.CallbackParams; import uk.gov.hmcts.reform.civil.callback.CallbackType; import uk.gov.hmcts.reform.civil.constants.SpecJourneyConstantLRSpec; @@ -55,23 +56,26 @@ import uk.gov.hmcts.reform.civil.model.UnavailableDate; import uk.gov.hmcts.reform.civil.model.common.DynamicList; import uk.gov.hmcts.reform.civil.model.common.Element; -import uk.gov.hmcts.reform.civil.model.dq.RequestedCourt; import uk.gov.hmcts.reform.civil.model.dq.Respondent1DQ; import uk.gov.hmcts.reform.civil.model.dq.Respondent2DQ; -import uk.gov.hmcts.reform.civil.model.dq.SmallClaimHearing; import uk.gov.hmcts.reform.civil.model.dq.Witness; import uk.gov.hmcts.reform.civil.model.dq.Witnesses; +import uk.gov.hmcts.reform.civil.model.dq.RequestedCourt; +import uk.gov.hmcts.reform.civil.model.dq.Expert; +import uk.gov.hmcts.reform.civil.model.dq.Experts; +import uk.gov.hmcts.reform.civil.model.dq.ExpertDetails; +import uk.gov.hmcts.reform.civil.model.dq.SmallClaimHearing; import uk.gov.hmcts.reform.civil.referencedata.LocationRefDataService; import uk.gov.hmcts.reform.civil.referencedata.model.LocationRefData; import uk.gov.hmcts.reform.civil.sampledata.AddressBuilder; import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; import uk.gov.hmcts.reform.civil.sampledata.PartyBuilder; -import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; import uk.gov.hmcts.reform.civil.service.DeadlinesCalculator; import uk.gov.hmcts.reform.civil.service.ExitSurveyContentService; import uk.gov.hmcts.reform.civil.service.FeatureToggleService; import uk.gov.hmcts.reform.civil.service.Time; import uk.gov.hmcts.reform.civil.service.UserService; +import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; import uk.gov.hmcts.reform.civil.service.citizenui.responsedeadline.DeadlineExtensionCalculatorService; import uk.gov.hmcts.reform.civil.service.flowstate.FlowFlag; import uk.gov.hmcts.reform.civil.service.flowstate.StateFlowEngine; @@ -79,8 +83,8 @@ import uk.gov.hmcts.reform.civil.utils.AssignCategoryId; import uk.gov.hmcts.reform.civil.utils.CaseFlagsInitialiser; import uk.gov.hmcts.reform.civil.utils.CourtLocationUtils; -import uk.gov.hmcts.reform.civil.utils.ElementUtils; import uk.gov.hmcts.reform.civil.utils.MonetaryConversions; +import uk.gov.hmcts.reform.civil.utils.ElementUtils; import uk.gov.hmcts.reform.civil.validation.DateOfBirthValidator; import uk.gov.hmcts.reform.civil.validation.PaymentDateValidator; import uk.gov.hmcts.reform.civil.validation.PostcodeValidator; @@ -99,7 +103,9 @@ import static java.lang.String.format; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; @@ -119,6 +125,7 @@ import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORTWO; import static uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec.IMMEDIATELY; import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.FULL_ADMISSION; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.FULL_DEFENCE; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; import static uk.gov.hmcts.reform.civil.helpers.DateFormatHelper.DATE; @@ -198,15 +205,82 @@ public void setup() { ); } + @Test + void whenCallBackEventNotImplementedOrEventInvalid() { + // Given + String postCode = "postCode"; + CaseData caseData = CaseData.builder() + .build().toBuilder() + .respondentSolicitor1ServiceAddressRequired(NO) + .respondentSolicitor1ServiceAddress(Address.builder().postCode(postCode).build()) + .isRespondent1(YES) + .build(); + CallbackParams callbackParams = callbackParamsOf(caseData, CallbackType.MID, " ").toBuilder() + .request(CallbackRequest.builder().eventId(SpecJourneyConstantLRSpec.DEFENDANT_RESPONSE_SPEC) + .build()).build(); + + //When + CallbackException ex = assertThrows(CallbackException.class, () -> handler.handle(callbackParams), + + "A CallbackException was expected to be thrown but wasn't."); + // Then + assertThat(ex.getMessage()).contains("Callback for event"); + } + + @Test + void resetStatementOfTruth() { + CaseData caseData = CaseDataBuilder.builder().build(); + CallbackParams params = callbackParamsOf(caseData, CallbackType.MID, "statement-of-truth"); + CallbackRequest request = CallbackRequest.builder() + .eventId(SpecJourneyConstantLRSpec.DEFENDANT_RESPONSE_SPEC) + .build(); + params = params.toBuilder().request(request).build(); + + // When + CallbackResponse response = handler.handle(params); + + // Then + assertNotNull(response); + } + @Test void midSpecCorrespondenceAddress_checkAddressIfWasIncorrect() { // Given String postCode = "postCode"; CaseData caseData = CaseData.builder() - .specAoSApplicantCorrespondenceAddressRequired(YesOrNo.NO) - .specAoSApplicantCorrespondenceAddressdetails(Address.builder() - .postCode(postCode) - .build()) + .build().toBuilder() + .respondentSolicitor1ServiceAddressRequired(NO) + .respondentSolicitor1ServiceAddress(Address.builder().postCode(postCode).build()) + .isRespondent1(YES) + .build(); + CallbackParams params = callbackParamsOf(caseData, CallbackType.MID, "specCorrespondenceAddress"); + CallbackRequest request = CallbackRequest.builder() + .eventId(SpecJourneyConstantLRSpec.DEFENDANT_RESPONSE_SPEC) + .build(); + params = params.toBuilder().request(request).build(); + + List errors = Collections.singletonList("error 1"); + Mockito.when(postcodeValidator.validate(postCode)).thenReturn(errors); + + // When + CallbackResponse response = handler.handle(params); + + // Then + assertEquals(errors, ((AboutToStartOrSubmitCallbackResponse) response).getErrors()); + } + + @Test + void midSpecCorrespondenceAddress_checkAddressIfWasIncorrectForSol2() { + // Given + String postCode = "postCode"; + CaseData caseData = CaseData.builder() + .build().toBuilder() + .respondentSolicitor1ServiceAddressRequired(YES) + .respondentSolicitor1ServiceAddress(Address.builder().postCode(postCode).build()) + .isRespondent1(YES) + .isRespondent2(YES) + .respondentSolicitor2ServiceAddressRequired(NO) + .respondentSolicitor2ServiceAddress(Address.builder().postCode(postCode).build()) .build(); CallbackParams params = callbackParamsOf(caseData, CallbackType.MID, "specCorrespondenceAddress"); CallbackRequest request = CallbackRequest.builder() @@ -314,10 +388,8 @@ void testSpecDefendantResponseFastTrackOneVTwoLegalRep() { assertThat(response.getData()).isNotNull(); assertThat(response.getData()).containsEntry("responseClaimTrack", AllocatedTrack.FAST_CLAIM.name()); assertThat(response.getData()).containsEntry("specDisputesOrPartAdmission", "No"); - assertThat(response.getData()).containsEntry( - "specPaidLessAmountOrDisputesOrPartAdmission", - "No" - ); + assertThat(response.getData()).containsEntry("specPaidLessAmountOrDisputesOrPartAdmission", + "No"); } @Test @@ -347,10 +419,8 @@ void testSpecDefendantResponseFastTrackOneVTwoSameLegalRep() { assertThat(response.getData()).isNotNull(); assertThat(response.getData()).containsEntry("responseClaimTrack", AllocatedTrack.FAST_CLAIM.name()); assertThat(response.getData()).containsEntry("specDisputesOrPartAdmission", "No"); - assertThat(response.getData()).containsEntry( - "specPaidLessAmountOrDisputesOrPartAdmission", - "No" - ); + assertThat(response.getData()).containsEntry("specPaidLessAmountOrDisputesOrPartAdmission", + "No"); } @Test @@ -376,10 +446,8 @@ void testSpecDefendantResponseFastTrackTwoVOne() { assertThat(response.getData()).isNotNull(); assertThat(response.getData()).containsEntry("responseClaimTrack", AllocatedTrack.FAST_CLAIM.name()); assertThat(response.getData()).containsEntry("specDisputesOrPartAdmission", "No"); - assertThat(response.getData()).containsEntry( - "specPaidLessAmountOrDisputesOrPartAdmission", - "No" - ); + assertThat(response.getData()).containsEntry("specPaidLessAmountOrDisputesOrPartAdmission", + "No"); } @Test @@ -662,9 +730,6 @@ public void testValidateRespondentPaymentDate() { AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler .handle(params); - List expectedErrorArray = new ArrayList<>(); - expectedErrorArray.add("Date for when will the amount be paid must be today or in the future."); - // Then assertThat(response).isNotNull(); /* @@ -723,8 +788,9 @@ void updateRespondent1AddressWhenUpdated() { CaseData caseData = CaseDataBuilder.builder() .respondent1(PartyBuilder.builder().individual().build()) .atStateApplicantRespondToDefenceAndProceed() - .atSpecAoSApplicantCorrespondenceAddressRequired(NO) - .atSpecAoSApplicantCorrespondenceAddressDetails(AddressBuilder.maximal().build()) + .build().toBuilder() + .tempAddress1Required(NO) + .tempAddress1(AddressBuilder.maximal().build()) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); @@ -755,15 +821,21 @@ void updateRespondent2AddressWhenUpdated() { when(stateFlowEngine.evaluate(any(CaseData.class))).thenReturn(mockedStateFlow); when(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).thenReturn(true); + Address newAddress2 = AddressBuilder.defaults().build(); CaseData caseData = CaseDataBuilder.builder().atStateApplicantRespondToDefenceAndProceed() .respondent2DQ() .respondent1Copy(PartyBuilder.builder().individual().build()) - .atSpecAoSApplicantCorrespondenceAddressRequired(YES) .addRespondent2(YES) .respondent2(PartyBuilder.builder().individual().build()) .respondent2Copy(PartyBuilder.builder().individual().build()) - .atSpecAoSRespondent2HomeAddressRequired(NO) - .atSpecAoSRespondent2HomeAddressDetails(AddressBuilder.maximal().build()) + .build().toBuilder() + .tempAddress1Required(YES) + .tempAddress1(Address.builder().build()) + .build().toBuilder() + .tempAddress2Required(NO) + .tempAddress2(newAddress2) + .respondentSolicitor2ServiceAddressRequired(NO) + .respondentSolicitor2ServiceAddress(newAddress2) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); @@ -777,28 +849,52 @@ void updateRespondent2AddressWhenUpdated() { // Then assertThat(response.getData()) .extracting("respondent2").extracting("primaryAddress") - .extracting("AddressLine1").isEqualTo("address line 1"); + .extracting("AddressLine1").isEqualTo(newAddress2.getAddressLine1()); assertThat(response.getData()) .extracting("respondent2").extracting("primaryAddress") - .extracting("AddressLine2").isEqualTo("address line 2"); + .extracting("AddressLine2").isEqualTo(newAddress2.getAddressLine2()); assertThat(response.getData()) .extracting("respondent2").extracting("primaryAddress") - .extracting("AddressLine3").isEqualTo("address line 3"); + .extracting("AddressLine3").isEqualTo(newAddress2.getAddressLine3()); } @Test - void updateRespondent2AddressWhenSpecAoSRespondent2HomeAddressRequiredIsNO() { + void defendantResponsePopulatesWitnessesData() { // Given + LocalDateTime dateTime = LocalDateTime.of(2023, 6, 6, 6, 6, 6); + LocalDate date = dateTime.toLocalDate(); when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + when(time.now()).thenReturn(dateTime); when(mockedStateFlow.isFlagSet(any())).thenReturn(true); when(stateFlowEngine.evaluate(any(CaseData.class))).thenReturn(mockedStateFlow); - - Party partyWithPrimaryAddress = PartyBuilder.builder().individual().build(); - partyWithPrimaryAddress.setPrimaryAddress(AddressBuilder.maximal() - .addressLine1("address line 1") - .addressLine2("address line 2") - .addressLine3("address line 3") - .build()); + when(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).thenReturn(true); + when(toggleService.isHmcEnabled()).thenReturn(true); + + Witnesses res1witnesses = Witnesses.builder().details( + wrapElements( + Witness.builder() + .firstName("Witness") + .lastName("One") + .emailAddress("test-witness-one@example.com") + .phoneNumber("07865456789") + .reasonForWitness("great reasons") + .eventAdded("Defendant Response Event") + .dateAdded(date) + .build()) + ).build(); + + Witnesses res2witnesses = Witnesses.builder().details( + wrapElements( + Witness.builder() + .firstName("Witness") + .lastName("Two") + .emailAddress("test-witness-two@example.com") + .phoneNumber("07532628263") + .reasonForWitness("good reasons") + .eventAdded("Defendant Response Event") + .dateAdded(date) + .build()) + ).build(); CaseData caseData = CaseDataBuilder.builder().atStateApplicantRespondToDefenceAndProceed() .respondent2DQ() @@ -806,422 +902,693 @@ void updateRespondent2AddressWhenSpecAoSRespondent2HomeAddressRequiredIsNO() { .addRespondent2(YES) .respondent2(PartyBuilder.builder().individual().build()) .respondent2Copy(PartyBuilder.builder().individual().build()) - .atSpecAoSRespondent2HomeAddressRequired(NO) - .atSpecAoSRespondent2HomeAddressDetails(AddressBuilder.maximal() - .addressLine1("new address line 1") - .build()) + .build().toBuilder() + .respondent1DQWitnessesSmallClaim(res1witnesses) + .respondent2DQWitnessesSmallClaim(res2witnesses) + .build().toBuilder() + .tempAddress1Required(YES) + .tempAddress1(Address.builder().build()) + .respondent2ResponseDate(dateTime) + .respondent1ResponseDate(dateTime).build().toBuilder() + .tempAddress2Required(NO) + .tempAddress2(AddressBuilder.maximal().build()) .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + when(deadlinesCalculator.calculateApplicantResponseDeadlineSpec(any(), any())) + .thenReturn(LocalDateTime.now()); + // When - AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler.handle( - callbackParamsOf(caseData, ABOUT_TO_SUBMIT)); + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler + .handle(params); + + var objectMapper = new ObjectMapper(); + objectMapper.findAndRegisterModules(); + objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); // Then - assertThat(response.getData()) - .extracting("respondent2") - .extracting("primaryAddress") - .extracting("AddressLine1") - .isEqualTo("new address line 1"); + + Witnesses actualRespondent1DQWitnesses = objectMapper.convertValue(response.getData().get("respondent1DQWitnesses"), new TypeReference<>() {}); + Witness actualRespondent1Witness = unwrapElements(actualRespondent1DQWitnesses.getDetails()).get(0); + assertThat(actualRespondent1Witness.getPartyID()).isNotNull(); + assertThat(actualRespondent1Witness.getFirstName()).isEqualTo("Witness"); + assertThat(actualRespondent1Witness.getLastName()).isEqualTo("One"); + assertThat(actualRespondent1Witness.getEmailAddress()).isEqualTo("test-witness-one@example.com"); + assertThat(actualRespondent1Witness.getPhoneNumber()).isEqualTo("07865456789"); + assertThat(actualRespondent1Witness.getReasonForWitness()).isEqualTo("great reasons"); + assertThat(actualRespondent1Witness.getEventAdded()).isEqualTo("Defendant Response Event"); + assertThat(actualRespondent1Witness.getDateAdded()).isEqualTo(date); + + Witnesses actualRespondent2DQWitnesses = objectMapper.convertValue(response.getData().get("respondent2DQWitnesses"), new TypeReference<>() {}); + Witness respondent2Witness = unwrapElements(actualRespondent2DQWitnesses.getDetails()).get(0); + assertThat(respondent2Witness.getPartyID()).isNotNull(); + assertThat(respondent2Witness.getFirstName()).isEqualTo("Witness"); + assertThat(respondent2Witness.getLastName()).isEqualTo("Two"); + assertThat(respondent2Witness.getEmailAddress()).isEqualTo("test-witness-two@example.com"); + assertThat(respondent2Witness.getPhoneNumber()).isEqualTo("07532628263"); + assertThat(respondent2Witness.getReasonForWitness()).isEqualTo("good reasons"); + assertThat(respondent2Witness.getEventAdded()).isEqualTo("Defendant Response Event"); + assertThat(respondent2Witness.getDateAdded()).isEqualTo(date); + } - @Test - void updateRespondent2AddressWhenSpecAoSRespondent2HomeAddressRequiredIsNotNO() { - // Given - when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); - when(mockedStateFlow.isFlagSet(any())).thenReturn(true); - when(stateFlowEngine.evaluate(any(CaseData.class))).thenReturn(mockedStateFlow); + @Nested + class HandleLocations { + + @Test + void oneVOne() { + // Given + DynamicList locationValues = DynamicList.fromList(List.of("Value 1")); + DynamicList preferredCourt = DynamicList.builder() + .listItems(locationValues.getListItems()) + .value(locationValues.getListItems().get(0)) + .build(); + Party defendant1 = Party.builder() + .type(Party.Type.COMPANY) + .companyName("company") + .build(); + CaseData caseData = CaseData.builder() + .caseAccessCategory(SPEC_CLAIM) + .ccdCaseReference(354L) + .respondent1(defendant1) + .respondent1Copy(defendant1) + .respondent1DQ( + Respondent1DQ.builder() + .respondToCourtLocation( + RequestedCourt.builder() + .responseCourtLocations(preferredCourt) + .reasonForHearingAtSpecificCourt("Reason") + .build() + ) + .build() + ) + .showConditionFlags(EnumSet.of( + DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1 + )) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + List locations = List.of(LocationRefData.builder().build()); + when(locationRefDataService.getCourtLocationsForDefaultJudgments(any())) + .thenReturn(locations); + LocationRefData completePreferredLocation = LocationRefData.builder() + .regionId("regionId") + .epimmsId("epimms") + .courtLocationCode("code") + .build(); + when(courtLocationUtils.findPreferredLocationData( + locations, preferredCourt + )).thenReturn(completePreferredLocation); + StateFlow flow = mock(StateFlow.class); + when(flow.isFlagSet(FlowFlag.TWO_RESPONDENT_REPRESENTATIVES)).thenReturn(false); + when(stateFlowEngine.evaluate(caseData)) + .thenReturn(flow); + when(coreCaseUserService.userHasCaseRole(anyString(), anyString(), any(CaseRole.class))) + .thenReturn(true); + UserInfo userInfo = UserInfo.builder().uid("798").build(); + when(userService.getUserInfo(anyString())).thenReturn(userInfo); + + // When + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler + .handle(params); + + // Then + AbstractObjectAssert sent1 = assertThat(response.getData()) + .extracting("respondent1DQRequestedCourt"); + sent1.extracting("caseLocation") + .extracting("region") + .isEqualTo(completePreferredLocation.getRegionId()); + sent1.extracting("caseLocation") + .extracting("baseLocation") + .isEqualTo(completePreferredLocation.getEpimmsId()); + sent1.extracting("responseCourtCode") + .isEqualTo(completePreferredLocation.getCourtLocationCode()); + sent1.extracting("reasonForHearingAtSpecificCourt") + .isEqualTo("Reason"); + } + + @Test + void oneVTwo_SecondDefendantRepliesSameLegalRep() { + // Given + DynamicList locationValues = DynamicList.fromList(List.of("Value 1")); + DynamicList preferredCourt = DynamicList.builder() + .listItems(locationValues.getListItems()) + .value(locationValues.getListItems().get(0)) + .build(); + Party defendant1 = Party.builder() + .type(Party.Type.COMPANY) + .companyName("company") + .build(); + Party defendant2 = Party.builder() + .type(Party.Type.COMPANY) + .companyName("company2") + .build(); + CaseData caseData = CaseData.builder() + .respondent2SameLegalRepresentative(YES) + .caseAccessCategory(SPEC_CLAIM) + .ccdCaseReference(354L) + .defenceAdmitPartPaymentTimeRouteRequired(IMMEDIATELY) + .respondent2ClaimResponseTypeForSpec(FULL_ADMISSION) + .respondent1(defendant1) + .respondent1Copy(defendant1) + .respondent2(defendant2) + .respondent2Copy(defendant2) + .respondent1DQ( + Respondent1DQ.builder() + .respondToCourtLocation( + RequestedCourt.builder() + .responseCourtLocations(preferredCourt) + .reasonForHearingAtSpecificCourt("Reason") + .build() + ) + .build() + ) + .respondent2DQ( + Respondent2DQ.builder() + .respondToCourtLocation2( + RequestedCourt.builder() + .responseCourtLocations(preferredCourt) + .reasonForHearingAtSpecificCourt("Reason123") + .build() + ) + .build() + ) + .showConditionFlags(EnumSet.of( + DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1, + DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_2 + )) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + List locations = List.of(LocationRefData.builder().build()); + when(locationRefDataService.getCourtLocationsForDefaultJudgments(any())) + .thenReturn(locations); + LocationRefData completePreferredLocation = LocationRefData.builder() + .regionId("regionId") + .epimmsId("epimms") + .courtLocationCode("code") + .build(); + when(courtLocationUtils.findPreferredLocationData( + locations, preferredCourt + )).thenReturn(completePreferredLocation); + StateFlow flow = mock(StateFlow.class); + when(flow.isFlagSet(FlowFlag.TWO_RESPONDENT_REPRESENTATIVES)).thenReturn(true); + when(stateFlowEngine.evaluate(caseData)).thenReturn(flow); + when(coreCaseUserService.userHasCaseRole(anyString(), anyString(), any(CaseRole.class))) + .thenReturn(true); + UserInfo userInfo = UserInfo.builder().uid("798").build(); + when(userService.getUserInfo(anyString())).thenReturn(userInfo); + LocalDate whenWillPay = LocalDate.now().plusDays(5); + given(deadlineExtensionCalculatorService.calculateExtendedDeadline(any(), anyInt())).willReturn(whenWillPay); + // When + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + // Then + AbstractObjectAssert sent2 = assertThat(response.getData()) + .extracting("respondent2DQRequestedCourt"); + sent2.extracting("caseLocation") + .extracting("region") + .isEqualTo(completePreferredLocation.getRegionId()); + sent2.extracting("caseLocation") + .extracting("baseLocation") + .isEqualTo(completePreferredLocation.getEpimmsId()); + sent2.extracting("responseCourtCode") + .isEqualTo(completePreferredLocation.getCourtLocationCode()); + sent2.extracting("reasonForHearingAtSpecificCourt") + .isEqualTo("Reason123"); + } + + @Test + void oneVTwo_SecondDefendantReplies() { + // Given + DynamicList locationValues = DynamicList.fromList(List.of("Value 1")); + DynamicList preferredCourt = DynamicList.builder() + .listItems(locationValues.getListItems()) + .value(locationValues.getListItems().get(0)) + .build(); + Party defendant1 = Party.builder() + .type(Party.Type.COMPANY) + .companyName("company") + .build(); + Party defendant2 = Party.builder() + .type(Party.Type.COMPANY) + .companyName("company 2") + .build(); + CaseData caseData = CaseData.builder() + .caseAccessCategory(SPEC_CLAIM) + .ccdCaseReference(354L) + .respondent1(defendant1) + .respondent1Copy(defendant1) + .respondent2(defendant2) + .respondent2Copy(defendant2) + .respondent1DQ( + Respondent1DQ.builder() + .respondToCourtLocation( + RequestedCourt.builder() + .responseCourtLocations(preferredCourt) + .reasonForHearingAtSpecificCourt("Reason") + .build() + ) + .build() + ) + .respondent2DQ( + Respondent2DQ.builder() + .respondToCourtLocation2( + RequestedCourt.builder() + .responseCourtLocations(preferredCourt) + .reasonForHearingAtSpecificCourt("Reason123") + .build() + ) + .build() + ) + .showConditionFlags(EnumSet.of( + DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1, + DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_2 + )) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + List locations = List.of(LocationRefData.builder().build()); + when(locationRefDataService.getCourtLocationsForDefaultJudgments(any())) + .thenReturn(locations); + LocationRefData completePreferredLocation = LocationRefData.builder() + .regionId("regionId") + .epimmsId("epimms") + .courtLocationCode("code") + .build(); + when(courtLocationUtils.findPreferredLocationData( + locations, preferredCourt + )).thenReturn(completePreferredLocation); + StateFlow flow = mock(StateFlow.class); + when(flow.isFlagSet(FlowFlag.TWO_RESPONDENT_REPRESENTATIVES)).thenReturn(true); + when(stateFlowEngine.evaluate(caseData)).thenReturn(flow); + when(coreCaseUserService.userHasCaseRole(anyString(), anyString(), any(CaseRole.class))) + .thenReturn(true); + UserInfo userInfo = UserInfo.builder().uid("798").build(); + when(userService.getUserInfo(anyString())).thenReturn(userInfo); + + // When + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler + .handle(params); + + // Then + AbstractObjectAssert sent2 = assertThat(response.getData()) + .extracting("respondent2DQRequestedCourt"); + sent2.extracting("caseLocation") + .extracting("region") + .isEqualTo(completePreferredLocation.getRegionId()); + sent2.extracting("caseLocation") + .extracting("baseLocation") + .isEqualTo(completePreferredLocation.getEpimmsId()); + sent2.extracting("responseCourtCode") + .isEqualTo(completePreferredLocation.getCourtLocationCode()); + sent2.extracting("reasonForHearingAtSpecificCourt") + .isEqualTo("Reason123"); + } + } - Party partyWithPrimaryAddress = PartyBuilder.builder().individual().build(); - partyWithPrimaryAddress.setPrimaryAddress(AddressBuilder.maximal() - .addressLine1("address line 1") - .addressLine2("address line 2") - .addressLine3("address line 3") - .build()); + } - CaseData caseData = CaseDataBuilder.builder().atStateApplicantRespondToDefenceAndProceed() - .respondent2DQ() - .respondent1Copy(PartyBuilder.builder().individual().build()) - .addRespondent2(YES) - .respondent2(PartyBuilder.builder().individual().build()) - .respondent2Copy(PartyBuilder.builder().individual().build()) - .atSpecAoSRespondent2HomeAddressRequired(YES) - .build(); + @Test + void shouldNullDocuments_whenInvokedAndCaseFileEnabled() { + // Given + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + when(mockedStateFlow.isFlagSet(any())).thenReturn(true); + when(stateFlowEngine.evaluate(any(CaseData.class))).thenReturn(mockedStateFlow); + when(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).thenReturn(true); + when(toggleService.isCaseFileViewEnabled()).thenReturn(true); + var testDocument = ResponseDocument.builder() + .file(Document.builder().documentUrl("fake-url").documentFileName("file-name").documentBinaryUrl("binary-url").build()).build(); - // When - AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler.handle( - callbackParamsOf(caseData, ABOUT_TO_SUBMIT)); + CaseData caseData = CaseData.builder() + .respondent1(PartyBuilder.builder().individual().build()) + .respondent1Copy(PartyBuilder.builder().individual().build()) + .respondent1DQ(Respondent1DQ.builder().build()) + .respondent2(PartyBuilder.builder().individual().build()) + .respondent2Copy(PartyBuilder.builder().individual().build()) + .respondent2DQ(Respondent2DQ.builder().build()) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .ccdCaseReference(354L) + .respondent1SpecDefenceResponseDocument(testDocument) + .respondent2SpecDefenceResponseDocument(testDocument) + .build(); - // Then - assertThat(response.getData()) - .extracting("respondent2") - .extracting("primaryAddress") - .extracting("AddressLine1") - .isEqualTo("address line 1"); - assertThat(response.getData()) - .extracting("respondent2") - .extracting("primaryAddress") - .extracting("AddressLine2") - .isEqualTo("address line 2"); - assertThat(response.getData()) - .extracting("respondent2") - .extracting("primaryAddress") - .extracting("AddressLine3") - .isEqualTo("address line 3"); - } + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + // When + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler + .handle(params); + + // Then + assertThat(response.getData().get("respondent1SpecDefenceResponseDocument")).isNull(); + assertThat(response.getData().get("respondent2SpecDefenceResponseDocument")).isNull(); } @Test - void defendantResponsePopulatesWitnessesData() { + void shouldUpdateExpertEvents_whenInvokedAndUpdateContactDetailsEnabled_For2DivergeResponse() { // Given LocalDateTime dateTime = LocalDateTime.of(2023, 6, 6, 6, 6, 6); - LocalDate date = dateTime.toLocalDate(); when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); - when(time.now()).thenReturn(dateTime); when(mockedStateFlow.isFlagSet(any())).thenReturn(true); when(stateFlowEngine.evaluate(any(CaseData.class))).thenReturn(mockedStateFlow); when(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).thenReturn(true); - when(toggleService.isHmcEnabled()).thenReturn(true); - - Witnesses res1witnesses = Witnesses.builder().details( - wrapElements( - Witness.builder() - .firstName("Witness") - .lastName("One") - .emailAddress("test-witness-one@example.com") - .phoneNumber("07865456789") - .reasonForWitness("great reasons") - .eventAdded("Defendant Response Event") - .dateAdded(date) - .build()) - ).build(); - - Witnesses res2witnesses = Witnesses.builder().details( - wrapElements( - Witness.builder() - .firstName("Witness") - .lastName("Two") - .emailAddress("test-witness-two@example.com") - .phoneNumber("07532628263") - .reasonForWitness("good reasons") - .eventAdded("Defendant Response Event") - .dateAdded(date) - .build()) - ).build(); - - CaseData caseData = CaseDataBuilder.builder().atStateApplicantRespondToDefenceAndProceed() - .respondent2DQ() + when(toggleService.isUpdateContactDetailsEnabled()).thenReturn(true); + + CaseData caseData = CaseData.builder() + .respondent1(PartyBuilder.builder().individual().build()) .respondent1Copy(PartyBuilder.builder().individual().build()) - .atSpecAoSApplicantCorrespondenceAddressRequired(YES) - .addRespondent2(YES) + .respondent1DQ(Respondent1DQ.builder() + .respondent1DQExperts(Experts.builder() + .details(wrapElements(Expert.builder().build())).build()) + .build()) .respondent2(PartyBuilder.builder().individual().build()) .respondent2Copy(PartyBuilder.builder().individual().build()) - .atSpecAoSRespondent2HomeAddressRequired(NO) - .atSpecAoSRespondent2HomeAddressDetails(AddressBuilder.maximal().build()) - .build().toBuilder() - .respondent1DQWitnessesSmallClaim(res1witnesses) - .respondent2DQWitnessesSmallClaim(res2witnesses) - .build().toBuilder() - .respondent2ResponseDate(dateTime) - .respondent1ResponseDate(dateTime).build(); + .respondent2DQ(Respondent2DQ.builder().build()) + .claimant1ClaimResponseTypeForSpec(FULL_DEFENCE) + .claimant2ClaimResponseTypeForSpec(FULL_ADMISSION) + .ccdCaseReference(354L) + .respondent1ResponseDate(dateTime).build().toBuilder() + .respondent2SameLegalRepresentative(YES) + .build(); + + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + // When + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler + .handle(params); + + // Then + assertThat(response.getData().get("respondent1DQExperts")).isNotNull(); + assertThat(response.getData().get("respondent2DQExperts")).isNull(); + + } + + @Test + void shouldUpdateExpertEvents_whenInvokedAndUpdateContactDetailsEnabled_CanAddApplicant2() { + // Given + LocalDateTime dateTime = LocalDateTime.of(2023, 6, 6, 6, 6, 6); + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + when(mockedStateFlow.isFlagSet(any())).thenReturn(true); + when(stateFlowEngine.evaluate(any(CaseData.class))).thenReturn(mockedStateFlow); + when(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).thenReturn(true); + when(toggleService.isUpdateContactDetailsEnabled()).thenReturn(true); + + CaseData caseData = CaseData.builder() + .respondent1(PartyBuilder.builder().individual().build()) + .respondent1Copy(PartyBuilder.builder().individual().build()) + .respondent1DQ(Respondent1DQ.builder() + .respondent1DQExperts(Experts.builder() + .details(wrapElements(Expert.builder().build())).build()) + .build()) + .respondent2(PartyBuilder.builder().individual().build()) + .respondent2Copy(PartyBuilder.builder().individual().build()) + .respondent2DQ(Respondent2DQ.builder().build()) + .claimant1ClaimResponseTypeForSpec(FULL_DEFENCE) + .claimant2ClaimResponseTypeForSpec(FULL_ADMISSION) + .ccdCaseReference(354L) + .respondent1ResponseDate(dateTime).build().toBuilder() + .addApplicant2(YES) + .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - when(deadlinesCalculator.calculateApplicantResponseDeadlineSpec(any(), any())) - .thenReturn(LocalDateTime.now()); // When AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler .handle(params); - var objectMapper = new ObjectMapper(); - objectMapper.findAndRegisterModules(); - objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); + // Then + assertThat(response.getData().get("respondent1DQExperts")).isNotNull(); + assertThat(response.getData().get("respondent2DQExperts")).isNull(); + + } + + @Test + void shouldUpdateExpertEvents_whenInvokedAndUpdateContactDetailsEnabled_FullAdmission() { + // Given + LocalDateTime dateTime = LocalDateTime.of(2023, 6, 6, 6, 6, 6); + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + when(mockedStateFlow.isFlagSet(any())).thenReturn(true); + when(stateFlowEngine.evaluate(any(CaseData.class))).thenReturn(mockedStateFlow); + when(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).thenReturn(true); + when(toggleService.isUpdateContactDetailsEnabled()).thenReturn(true); + + CaseData caseData = CaseData.builder() + .respondent1(PartyBuilder.builder().individual().build()) + .respondent1Copy(PartyBuilder.builder().individual().build()) + .respondent1DQ(Respondent1DQ.builder() + .respondent1DQExperts(Experts.builder() + .details(wrapElements(Expert.builder().build())).build()) + .build()) + .respondent2(PartyBuilder.builder().individual().build()) + .respondent2Copy(PartyBuilder.builder().individual().build()) + .respondent2DQ(Respondent2DQ.builder().build()) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .ccdCaseReference(354L) + .respondent1ResponseDate(dateTime).build().toBuilder() + .build(); + + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + // When + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler + .handle(params); // Then + assertThat(response.getData().get("respondent1DQExperts")).isNotNull(); + assertThat(response.getData().get("respondent2DQExperts")).isNull(); + + } + + @Test + void shouldUpdateExpertEvents_whenInvokedAndUpdateContactDetailsEnabled() { + // Given + LocalDateTime dateTime = LocalDateTime.of(2023, 6, 6, 6, 6, 6); + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + when(mockedStateFlow.isFlagSet(any())).thenReturn(true); + when(stateFlowEngine.evaluate(any(CaseData.class))).thenReturn(mockedStateFlow); + when(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).thenReturn(true); + when(toggleService.isUpdateContactDetailsEnabled()).thenReturn(true); + + CaseData caseData = CaseData.builder() + .respondent1(PartyBuilder.builder().individual().build()) + .respondent1Copy(PartyBuilder.builder().individual().build()) + .respondent1DQ(Respondent1DQ.builder() + .respondent1DQExperts(Experts.builder() + .details(wrapElements(Expert.builder().build())).build()) + .build()) + .respondent2(PartyBuilder.builder().individual().build()) + .respondent2Copy(PartyBuilder.builder().individual().build()) + .respondent2DQ(Respondent2DQ.builder().build()) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .ccdCaseReference(354L) + .respondent1ResponseDate(dateTime).build().toBuilder() + .build(); - Witnesses actualRespondent1DQWitnesses = objectMapper.convertValue(response.getData().get( - "respondent1DQWitnesses"), new TypeReference<>() { - }); - Witness actualRespondent1Witness = unwrapElements(actualRespondent1DQWitnesses.getDetails()).get(0); - assertThat(actualRespondent1Witness.getPartyID()).isNotNull(); - assertThat(actualRespondent1Witness.getFirstName()).isEqualTo("Witness"); - assertThat(actualRespondent1Witness.getLastName()).isEqualTo("One"); - assertThat(actualRespondent1Witness.getEmailAddress()).isEqualTo("test-witness-one@example.com"); - assertThat(actualRespondent1Witness.getPhoneNumber()).isEqualTo("07865456789"); - assertThat(actualRespondent1Witness.getReasonForWitness()).isEqualTo("great reasons"); - assertThat(actualRespondent1Witness.getEventAdded()).isEqualTo("Defendant Response Event"); - assertThat(actualRespondent1Witness.getDateAdded()).isEqualTo(date); - - Witnesses actualRespondent2DQWitnesses = objectMapper.convertValue(response.getData().get( - "respondent2DQWitnesses"), new TypeReference<>() { - }); - Witness respondent2Witness = unwrapElements(actualRespondent2DQWitnesses.getDetails()).get(0); - assertThat(respondent2Witness.getPartyID()).isNotNull(); - assertThat(respondent2Witness.getFirstName()).isEqualTo("Witness"); - assertThat(respondent2Witness.getLastName()).isEqualTo("Two"); - assertThat(respondent2Witness.getEmailAddress()).isEqualTo("test-witness-two@example.com"); - assertThat(respondent2Witness.getPhoneNumber()).isEqualTo("07532628263"); - assertThat(respondent2Witness.getReasonForWitness()).isEqualTo("good reasons"); - assertThat(respondent2Witness.getEventAdded()).isEqualTo("Defendant Response Event"); - assertThat(respondent2Witness.getDateAdded()).isEqualTo(date); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + // When + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler + .handle(params); + + // Then + assertThat(response.getData().get("respondent1DQExperts")).isNotNull(); + assertThat(response.getData().get("respondent2DQExperts")).isNull(); } - @Nested - class HandleLocations { + @Test + void shouldUpdateExpertEvents_whenInvokedAndUpdateContactDetailsEnabled_V2DraftDirections() { + // Given + LocalDateTime dateTime = LocalDateTime.of(2023, 6, 6, 6, 6, 6); + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + when(mockedStateFlow.isFlagSet(any())).thenReturn(true); + when(stateFlowEngine.evaluate(any(CaseData.class))).thenReturn(mockedStateFlow); + when(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).thenReturn(true); + when(toggleService.isUpdateContactDetailsEnabled()).thenReturn(true); - @Test - void oneVOne() { - // Given - DynamicList locationValues = DynamicList.fromList(List.of("Value 1")); - DynamicList preferredCourt = DynamicList.builder() - .listItems(locationValues.getListItems()) - .value(locationValues.getListItems().get(0)) - .build(); - Party defendant1 = Party.builder() - .type(Party.Type.COMPANY) - .companyName("company") - .build(); - CaseData caseData = CaseData.builder() - .caseAccessCategory(SPEC_CLAIM) - .ccdCaseReference(354L) - .respondent1(defendant1) - .respondent1Copy(defendant1) - .respondent1DQ( - Respondent1DQ.builder() - .respondToCourtLocation( - RequestedCourt.builder() - .responseCourtLocations(preferredCourt) - .reasonForHearingAtSpecificCourt("Reason") - .build() - ) - .build() - ) - .showConditionFlags(EnumSet.of( - DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1 - )) - .build(); - CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + CaseData caseData = CaseData.builder() + .respondent1(PartyBuilder.builder().individual().build()) + .respondent1Copy(PartyBuilder.builder().individual().build()) + .respondent1DQ(Respondent1DQ.builder() + .respondent1DQExperts(Experts.builder() + .details(wrapElements(Expert.builder().build())).build()) + .build()) + .respondent2(PartyBuilder.builder().individual().build()) + .respondent2Copy(PartyBuilder.builder().individual().build()) + .respondent2DQ(Respondent2DQ.builder() + .respondent2DQDraftDirections(Document.builder().build()).build()) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .ccdCaseReference(354L) + .respondent1ResponseDate(dateTime).build().toBuilder() + .build(); - List locations = List.of(LocationRefData.builder().build()); - when(locationRefDataService.getCourtLocationsForDefaultJudgments(any())) - .thenReturn(locations); - LocationRefData completePreferredLocation = LocationRefData.builder() - .regionId("regionId") - .epimmsId("epimms") - .courtLocationCode("code") - .build(); - when(courtLocationUtils.findPreferredLocationData( - locations, preferredCourt - )).thenReturn(completePreferredLocation); - StateFlow flow = mock(StateFlow.class); - when(flow.isFlagSet(FlowFlag.TWO_RESPONDENT_REPRESENTATIVES)).thenReturn(false); - when(stateFlowEngine.evaluate(caseData)) - .thenReturn(flow); - when(coreCaseUserService.userHasCaseRole(anyString(), anyString(), any(CaseRole.class))) - .thenReturn(true); - UserInfo userInfo = UserInfo.builder().uid("798").build(); - when(userService.getUserInfo(anyString())).thenReturn(userInfo); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - // When - AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler - .handle(params); + // When + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler + .handle(params); - // Then - AbstractObjectAssert sent1 = assertThat(response.getData()) - .extracting("respondent1DQRequestedCourt"); - sent1.extracting("caseLocation") - .extracting("region") - .isEqualTo(completePreferredLocation.getRegionId()); - sent1.extracting("caseLocation") - .extracting("baseLocation") - .isEqualTo(completePreferredLocation.getEpimmsId()); - sent1.extracting("responseCourtCode") - .isEqualTo(completePreferredLocation.getCourtLocationCode()); - sent1.extracting("reasonForHearingAtSpecificCourt") - .isEqualTo("Reason"); - } + // Then + assertThat(response.getData().get("respondent1DQExperts")).isNotNull(); + assertThat(response.getData().get("respondent2DQExperts")).isNull(); - @Test - void oneVTwo_SecondDefendantRepliesSameLegalRep() { - // Given - DynamicList locationValues = DynamicList.fromList(List.of("Value 1")); - DynamicList preferredCourt = DynamicList.builder() - .listItems(locationValues.getListItems()) - .value(locationValues.getListItems().get(0)) - .build(); - Party defendant1 = Party.builder() - .type(Party.Type.COMPANY) - .companyName("company") - .build(); - CaseData caseData = CaseData.builder() - .respondent2SameLegalRepresentative(YES) - .caseAccessCategory(SPEC_CLAIM) - .ccdCaseReference(354L) - .defenceAdmitPartPaymentTimeRouteRequired(IMMEDIATELY) - .respondent2ClaimResponseTypeForSpec(FULL_ADMISSION) - .respondent1(defendant1) - .respondent1Copy(defendant1) - .respondent1DQ( - Respondent1DQ.builder() - .respondToCourtLocation( - RequestedCourt.builder() - .responseCourtLocations(preferredCourt) - .reasonForHearingAtSpecificCourt("Reason") - .build() - ) - .build() - ) - .respondent2DQ( - Respondent2DQ.builder() - .respondToCourtLocation2( - RequestedCourt.builder() - .responseCourtLocations(preferredCourt) - .reasonForHearingAtSpecificCourt("Reason123") - .build() - ) - .build() - ) - .showConditionFlags(EnumSet.of( - DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1, - DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_2 - )) - .build(); + } + + @Test + void shouldUpdateWitnessEvents_whenInvokedAndUpdateContactDetailsEnabled() { + // Given + LocalDateTime dateTime = LocalDateTime.of(2023, 6, 6, 6, 6, 6); + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + when(mockedStateFlow.isFlagSet(any())).thenReturn(true); + when(stateFlowEngine.evaluate(any(CaseData.class))).thenReturn(mockedStateFlow); + when(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).thenReturn(true); + when(toggleService.isUpdateContactDetailsEnabled()).thenReturn(true); + + CaseData caseData = CaseData.builder() + .respondent1(PartyBuilder.builder().individual().build()) + .respondent1Copy(PartyBuilder.builder().individual().build()) + .respondent1DQ(Respondent1DQ.builder() + .respondent1DQWitnesses(Witnesses.builder() + .details(wrapElements(Witness.builder().build())).build()) + .build()) + + .respondent2(PartyBuilder.builder().individual().build()) + .respondent2Copy(PartyBuilder.builder().individual().build()) + .respondent2DQ(Respondent2DQ.builder().build()) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .ccdCaseReference(354L) + .respondent1ResponseDate(dateTime).build().toBuilder() + .build(); + + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + // When + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler + .handle(params); + + // Then + assertThat(response.getData().get("respondent1DQWitnesses")).isNotNull(); + assertThat(response.getData().get("respondent2DQWitnesses")).isNull(); + + } + + @Test + void shouldUpdateCorrespondence1_whenProvided() { + // Given + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + when(mockedStateFlow.isFlagSet(any())).thenReturn(true); + when(stateFlowEngine.evaluate(any(CaseData.class))).thenReturn(mockedStateFlow); + when(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).thenReturn(true); + when(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).thenReturn(false); + when(toggleService.isCaseFileViewEnabled()).thenReturn(true); + var testDocument = ResponseDocument.builder() + .file(Document.builder().documentUrl("fake-url").documentFileName("file-name").documentBinaryUrl("binary-url").build()).build(); + + CaseData caseData = CaseData.builder() + .respondent1(PartyBuilder.builder().individual().build()) + .respondent1Copy(PartyBuilder.builder().individual().build()) + .respondent1DQ(Respondent1DQ.builder().build()) + .respondent2DQ(Respondent2DQ.builder().build()) + .ccdCaseReference(354L) + .respondent1SpecDefenceResponseDocument(testDocument) + .respondent2SpecDefenceResponseDocument(testDocument) + .isRespondent1(YesOrNo.YES) + .respondentSolicitor1ServiceAddressRequired(YesOrNo.NO) + .respondentSolicitor1ServiceAddress( + Address.builder() + .postCode("new postcode") + .build() + ) + .build(); - List locations = List.of(LocationRefData.builder().build()); - when(locationRefDataService.getCourtLocationsForDefaultJudgments(any())) - .thenReturn(locations); - LocationRefData completePreferredLocation = LocationRefData.builder() - .regionId("regionId") - .epimmsId("epimms") - .courtLocationCode("code") - .build(); - when(courtLocationUtils.findPreferredLocationData( - locations, preferredCourt - )).thenReturn(completePreferredLocation); - StateFlow flow = mock(StateFlow.class); - when(flow.isFlagSet(FlowFlag.TWO_RESPONDENT_REPRESENTATIVES)).thenReturn(true); - when(stateFlowEngine.evaluate(caseData)).thenReturn(flow); - when(coreCaseUserService.userHasCaseRole(anyString(), anyString(), any(CaseRole.class))) - .thenReturn(true); - UserInfo userInfo = UserInfo.builder().uid("798").build(); - when(userService.getUserInfo(anyString())).thenReturn(userInfo); - LocalDate whenWillPay = LocalDate.now().plusDays(5); - given(deadlineExtensionCalculatorService.calculateExtendedDeadline(any(), anyInt())).willReturn(whenWillPay); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + // When + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler + .handle(params); - // When - AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + // Then + assertThat(response.getData().get("specRespondentCorrespondenceAddressdetails")) + .extracting("PostCode") + .isEqualTo("new postcode"); + assertThat(response.getData().get("respondentSolicitor1ServiceAddress")) + .extracting("PostCode") + .isNull(); + } - // Then - AbstractObjectAssert sent2 = assertThat(response.getData()) - .extracting("respondent2DQRequestedCourt"); - sent2.extracting("caseLocation") - .extracting("region") - .isEqualTo(completePreferredLocation.getRegionId()); - sent2.extracting("caseLocation") - .extracting("baseLocation") - .isEqualTo(completePreferredLocation.getEpimmsId()); - sent2.extracting("responseCourtCode") - .isEqualTo(completePreferredLocation.getCourtLocationCode()); - sent2.extracting("reasonForHearingAtSpecificCourt") - .isEqualTo("Reason123"); - } + @Test + void shouldUpdateCorrespondence1_whenProvided1v2ss() { + // Given + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + when(mockedStateFlow.isFlagSet(any())).thenReturn(true); + when(stateFlowEngine.evaluate(any(CaseData.class))).thenReturn(mockedStateFlow); + when(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).thenReturn(true); + when(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).thenReturn(false); + when(toggleService.isCaseFileViewEnabled()).thenReturn(true); + var testDocument = ResponseDocument.builder() + .file(Document.builder().documentUrl("fake-url").documentFileName("file-name").documentBinaryUrl("binary-url").build()).build(); - @Test - void oneVTwo_SecondDefendantReplies() { - // Given - DynamicList locationValues = DynamicList.fromList(List.of("Value 1")); - DynamicList preferredCourt = DynamicList.builder() - .listItems(locationValues.getListItems()) - .value(locationValues.getListItems().get(0)) - .build(); - Party defendant1 = Party.builder() - .type(Party.Type.COMPANY) - .companyName("company") - .build(); - CaseData caseData = CaseData.builder() - .caseAccessCategory(SPEC_CLAIM) - .ccdCaseReference(354L) - .respondent1(defendant1) - .respondent1Copy(defendant1) - .respondent1DQ( - Respondent1DQ.builder() - .respondToCourtLocation( - RequestedCourt.builder() - .responseCourtLocations(preferredCourt) - .reasonForHearingAtSpecificCourt("Reason") - .build() - ) - .build() - ) - .respondent2DQ( - Respondent2DQ.builder() - .respondToCourtLocation2( - RequestedCourt.builder() - .responseCourtLocations(preferredCourt) - .reasonForHearingAtSpecificCourt("Reason123") - .build() - ) - .build() - ) - .showConditionFlags(EnumSet.of( - DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1, - DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_2 - )) - .build(); - CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + CaseData caseData = CaseData.builder() + .respondent1(PartyBuilder.builder().individual().build()) + .respondent1Copy(PartyBuilder.builder().individual().build()) + .respondent1DQ(Respondent1DQ.builder().build()) + .respondent2DQ(Respondent2DQ.builder().build()) + .ccdCaseReference(354L) + .respondent1SpecDefenceResponseDocument(testDocument) + .respondent2SpecDefenceResponseDocument(testDocument) + .isRespondent1(YesOrNo.YES) + .respondentSolicitor1ServiceAddressRequired(YesOrNo.NO) + .respondentSolicitor1ServiceAddress( + Address.builder() + .postCode("new postcode") + .build() + ) + .respondent2(Party.builder() + .type(Party.Type.COMPANY) + .companyName("Company 3") + .build()) + .respondent2SameLegalRepresentative(YES) + .build(); - List locations = List.of(LocationRefData.builder().build()); - when(locationRefDataService.getCourtLocationsForDefaultJudgments(any())) - .thenReturn(locations); - LocationRefData completePreferredLocation = LocationRefData.builder() - .regionId("regionId") - .epimmsId("epimms") - .courtLocationCode("code") - .build(); - when(courtLocationUtils.findPreferredLocationData( - locations, preferredCourt - )).thenReturn(completePreferredLocation); - StateFlow flow = mock(StateFlow.class); - when(flow.isFlagSet(FlowFlag.TWO_RESPONDENT_REPRESENTATIVES)).thenReturn(true); - when(stateFlowEngine.evaluate(caseData)).thenReturn(flow); - when(coreCaseUserService.userHasCaseRole(anyString(), anyString(), any(CaseRole.class))) - .thenReturn(true); - UserInfo userInfo = UserInfo.builder().uid("798").build(); - when(userService.getUserInfo(anyString())).thenReturn(userInfo); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - // When - AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler - .handle(params); + // When + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler + .handle(params); - // Then - AbstractObjectAssert sent2 = assertThat(response.getData()) - .extracting("respondent2DQRequestedCourt"); - sent2.extracting("caseLocation") - .extracting("region") - .isEqualTo(completePreferredLocation.getRegionId()); - sent2.extracting("caseLocation") - .extracting("baseLocation") - .isEqualTo(completePreferredLocation.getEpimmsId()); - sent2.extracting("responseCourtCode") - .isEqualTo(completePreferredLocation.getCourtLocationCode()); - sent2.extracting("reasonForHearingAtSpecificCourt") - .isEqualTo("Reason123"); - } + // Then + assertThat(response.getData().get("specRespondentCorrespondenceAddressdetails")) + .extracting("PostCode") + .isEqualTo("new postcode"); + assertThat(response.getData().get("respondentSolicitor1ServiceAddress")) + .extracting("PostCode") + .isNull(); + assertEquals( + response.getData().get("specRespondentCorrespondenceAddressdetails"), + response.getData().get("specRespondent2CorrespondenceAddressdetails") + ); + assertEquals( + response.getData().get("specRespondentCorrespondenceAddressRequired"), + response.getData().get("specRespondent2CorrespondenceAddressRequired") + ); } @Test - void shouldNullDocuments_whenInvokedAndCaseFileEnabled() { + void shouldUpdateCorrespondence1_whenProvided1v2ss_withSameResponse() { // Given when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); when(mockedStateFlow.isFlagSet(any())).thenReturn(true); when(stateFlowEngine.evaluate(any(CaseData.class))).thenReturn(mockedStateFlow); - when(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).thenReturn(true); + when(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).thenReturn(true); + when(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).thenReturn(false); when(toggleService.isCaseFileViewEnabled()).thenReturn(true); var testDocument = ResponseDocument.builder() - .file(Document.builder().documentUrl("fake-url").documentFileName("file-name").documentBinaryUrl( - "binary-url").build()).build(); + .file(Document.builder().documentUrl("fake-url").documentFileName("file-name").documentBinaryUrl("binary-url").build()).build(); CaseData caseData = CaseData.builder() .respondent1(PartyBuilder.builder().individual().build()) @@ -1231,6 +1598,19 @@ void shouldNullDocuments_whenInvokedAndCaseFileEnabled() { .ccdCaseReference(354L) .respondent1SpecDefenceResponseDocument(testDocument) .respondent2SpecDefenceResponseDocument(testDocument) + .isRespondent1(YesOrNo.YES) + .respondentResponseIsSame(YES) + .respondentSolicitor1ServiceAddressRequired(YesOrNo.NO) + .respondentSolicitor1ServiceAddress( + Address.builder() + .postCode("new postcode") + .build() + ) + .respondent2(Party.builder() + .type(Party.Type.COMPANY) + .companyName("Company 3") + .build()) + .respondent2SameLegalRepresentative(YES) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); @@ -1240,12 +1620,24 @@ void shouldNullDocuments_whenInvokedAndCaseFileEnabled() { .handle(params); // Then - assertThat(response.getData().get("respondent1SpecDefenceResponseDocument")).isNull(); - assertThat(response.getData().get("respondent2SpecDefenceResponseDocument")).isNull(); + assertThat(response.getData().get("specRespondentCorrespondenceAddressdetails")) + .extracting("PostCode") + .isEqualTo("new postcode"); + assertThat(response.getData().get("respondentSolicitor1ServiceAddress")) + .extracting("PostCode") + .isNull(); + assertEquals( + response.getData().get("specRespondentCorrespondenceAddressdetails"), + response.getData().get("specRespondent2CorrespondenceAddressdetails") + ); + assertEquals( + response.getData().get("specRespondentCorrespondenceAddressRequired"), + response.getData().get("specRespondent2CorrespondenceAddressRequired") + ); } @Test - void shouldUpdateCorrespondence1_whenProvided() { + void shouldUpdateCorrespondence1_whenProvided1v2ss_withSameResponse_withv2copy() { // Given when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); when(mockedStateFlow.isFlagSet(any())).thenReturn(true); @@ -1254,8 +1646,7 @@ void shouldUpdateCorrespondence1_whenProvided() { when(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).thenReturn(false); when(toggleService.isCaseFileViewEnabled()).thenReturn(true); var testDocument = ResponseDocument.builder() - .file(Document.builder().documentUrl("fake-url").documentFileName("file-name").documentBinaryUrl( - "binary-url").build()).build(); + .file(Document.builder().documentUrl("fake-url").documentFileName("file-name").documentBinaryUrl("binary-url").build()).build(); CaseData caseData = CaseData.builder() .respondent1(PartyBuilder.builder().individual().build()) @@ -1266,12 +1657,19 @@ void shouldUpdateCorrespondence1_whenProvided() { .respondent1SpecDefenceResponseDocument(testDocument) .respondent2SpecDefenceResponseDocument(testDocument) .isRespondent1(YesOrNo.YES) - .specAoSRespondentCorrespondenceAddressRequired(YesOrNo.NO) - .specAoSRespondentCorrespondenceAddressdetails( + .respondentResponseIsSame(YES) + .respondentSolicitor1ServiceAddressRequired(YesOrNo.NO) + .respondentSolicitor1ServiceAddress( Address.builder() .postCode("new postcode") .build() ) + .respondent2(Party.builder() + .type(Party.Type.COMPANY) + .companyName("Company 3") + .build()) + .respondent2Copy(PartyBuilder.builder().individual().build()) + .respondent2SameLegalRepresentative(YES) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); @@ -1284,13 +1682,21 @@ void shouldUpdateCorrespondence1_whenProvided() { assertThat(response.getData().get("specRespondentCorrespondenceAddressdetails")) .extracting("PostCode") .isEqualTo("new postcode"); - assertThat(response.getData().get("specAoSRespondentCorrespondenceAddressdetails")) + assertThat(response.getData().get("respondentSolicitor1ServiceAddress")) .extracting("PostCode") .isNull(); + assertEquals( + response.getData().get("specRespondentCorrespondenceAddressdetails"), + response.getData().get("specRespondent2CorrespondenceAddressdetails") + ); + assertEquals( + response.getData().get("specRespondentCorrespondenceAddressRequired"), + response.getData().get("specRespondent2CorrespondenceAddressRequired") + ); } @Test - void shouldUpdateCorrespondence1_whenProvided1v2ss() { + void shouldUpdateCorrespondence1_whenProvided1v2ss_withSameResponse_withv2copyAndNoTempAdr() { // Given when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); when(mockedStateFlow.isFlagSet(any())).thenReturn(true); @@ -1299,8 +1705,7 @@ void shouldUpdateCorrespondence1_whenProvided1v2ss() { when(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).thenReturn(false); when(toggleService.isCaseFileViewEnabled()).thenReturn(true); var testDocument = ResponseDocument.builder() - .file(Document.builder().documentUrl("fake-url").documentFileName("file-name").documentBinaryUrl( - "binary-url").build()).build(); + .file(Document.builder().documentUrl("fake-url").documentFileName("file-name").documentBinaryUrl("binary-url").build()).build(); CaseData caseData = CaseData.builder() .respondent1(PartyBuilder.builder().individual().build()) @@ -1311,8 +1716,9 @@ void shouldUpdateCorrespondence1_whenProvided1v2ss() { .respondent1SpecDefenceResponseDocument(testDocument) .respondent2SpecDefenceResponseDocument(testDocument) .isRespondent1(YesOrNo.YES) - .specAoSRespondentCorrespondenceAddressRequired(YesOrNo.NO) - .specAoSRespondentCorrespondenceAddressdetails( + .respondentResponseIsSame(YES) + .respondentSolicitor1ServiceAddressRequired(YesOrNo.NO) + .respondentSolicitor1ServiceAddress( Address.builder() .postCode("new postcode") .build() @@ -1321,7 +1727,9 @@ void shouldUpdateCorrespondence1_whenProvided1v2ss() { .type(Party.Type.COMPANY) .companyName("Company 3") .build()) + .respondent2Copy(PartyBuilder.builder().individual().build()) .respondent2SameLegalRepresentative(YES) + .tempAddress2Required(NO) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); @@ -1334,7 +1742,7 @@ void shouldUpdateCorrespondence1_whenProvided1v2ss() { assertThat(response.getData().get("specRespondentCorrespondenceAddressdetails")) .extracting("PostCode") .isEqualTo("new postcode"); - assertThat(response.getData().get("specAoSRespondentCorrespondenceAddressdetails")) + assertThat(response.getData().get("respondentSolicitor1ServiceAddress")) .extracting("PostCode") .isNull(); assertEquals( @@ -1356,20 +1764,21 @@ void shouldUpdateCorrespondence2_whenProvided() { when(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).thenReturn(true); when(toggleService.isCaseFileViewEnabled()).thenReturn(true); var testDocument = ResponseDocument.builder() - .file(Document.builder().documentUrl("fake-url").documentFileName("file-name").documentBinaryUrl( - "binary-url").build()).build(); + .file(Document.builder().documentUrl("fake-url").documentFileName("file-name").documentBinaryUrl("binary-url").build()).build(); CaseData caseData = CaseData.builder() .respondent1(PartyBuilder.builder().individual().build()) .respondent1Copy(PartyBuilder.builder().individual().build()) .respondent1DQ(Respondent1DQ.builder().build()) + .respondent2(PartyBuilder.builder().individual().build()) + .respondent2Copy(PartyBuilder.builder().individual().build()) .respondent2DQ(Respondent2DQ.builder().build()) .ccdCaseReference(354L) .respondent1SpecDefenceResponseDocument(testDocument) .respondent2SpecDefenceResponseDocument(testDocument) .isRespondent2(YesOrNo.YES) - .specAoSRespondent2CorrespondenceAddressRequired(YesOrNo.NO) - .specAoSRespondent2CorrespondenceAddressdetails( + .respondentSolicitor2ServiceAddressRequired(YesOrNo.NO) + .respondentSolicitor2ServiceAddress( Address.builder() .postCode("new postcode") .build() @@ -1386,7 +1795,7 @@ void shouldUpdateCorrespondence2_whenProvided() { assertThat(response.getData().get("specRespondent2CorrespondenceAddressdetails")) .extracting("PostCode") .isEqualTo("new postcode"); - assertThat(response.getData().get("specAoSRespondent2CorrespondenceAddressdetails")) + assertThat(response.getData().get("respondentSolicitor2ServiceAddress")) .extracting("PostCode") .isNull(); } @@ -1416,6 +1825,58 @@ void shouldPopulateRespondent2Flag_WhenInvoked() { assertThat(response.getData().get("respondent2DocumentGeneration")).isEqualTo("userRespondent2"); } + @Test + void shouldPopulateRespondent2Flag_WhenInvokedWithSmallClaimExperts_1DQ() { + // Given + when(toggleService.isCaseFileViewEnabled()).thenReturn(true); + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + when(stateFlowEngine.evaluate(any(CaseData.class))).thenReturn(mockedStateFlow); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(true); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); + CaseData caseData = CaseDataBuilder.builder() + .atStateClaimDetailsNotified() + .respondent2(PartyBuilder.builder().individual().build()) + .addRespondent2(YES) + .respondent1(PartyBuilder.builder().individual().build()) + .respondent1Copy(PartyBuilder.builder().individual().build()) + .respondent1DQ(Respondent1DQ.builder() + .respondToClaimExperts(ExpertDetails.builder().build()).build()) + .respondent2DQ(Respondent2DQ.builder().build()) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + // When + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler + .handle(params); + // Given + assertThat(response.getData().get("respondent2DocumentGeneration")).isEqualTo("userRespondent2"); + } + + @Test + void shouldPopulateRespondent2Flag_WhenInvokedWithSmallClaimExperts_2DQ() { + // Given + when(toggleService.isCaseFileViewEnabled()).thenReturn(true); + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + when(stateFlowEngine.evaluate(any(CaseData.class))).thenReturn(mockedStateFlow); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(true); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); + CaseData caseData = CaseDataBuilder.builder() + .atStateClaimDetailsNotified() + .respondent2(PartyBuilder.builder().individual().build()) + .addRespondent2(YES) + .respondent1(PartyBuilder.builder().individual().build()) + .respondent1Copy(PartyBuilder.builder().individual().build()) + .respondent2DQ(Respondent2DQ.builder() + .respondToClaimExperts2(ExpertDetails.builder().build()).build()) + .respondent1DQ(Respondent1DQ.builder().build()) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + // When + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler + .handle(params); + // Given + assertThat(response.getData().get("respondent2DocumentGeneration")).isEqualTo("userRespondent2"); + } + @Test void shouldNotPopulateRespondent2Flag_WhenInvoked() { // Given @@ -1478,6 +1939,26 @@ void shouldSetMultiPartyResponseTypeFlags_Counter_Admit_OR_Admit_Part_combinatio .isEqualTo("COUNTER_ADMIT_OR_ADMIT_PART"); } + @Test + void shouldSetMultiPartyResponseTypeFlags_Counter_Admit_OR_Admit_Part_combination2_CanAddApplicant2() { + // Given + CaseData caseData = CaseDataBuilder.builder().atStateRespondent2v1BothNotFullDefence_CounterClaimX2() + .addApplicant2(YES) + .respondent1ClaimResponseTypeForSpec(FULL_ADMISSION) + .respondent1ClaimResponseTypeForSpec(FULL_ADMISSION) + .build(); + + CallbackParams params = callbackParamsOf(caseData, MID, PAGE_ID); + + // When + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + // Then + assertThat(response.getData()).extracting("multiPartyResponseTypeFlags") + .isEqualTo("COUNTER_ADMIT_OR_ADMIT_PART"); + } + + /** * if solicitor says that each defendant gets their response but then chooses the same * option from full defence/part admit/full admit/counterclaim, then it is not different response. @@ -1568,7 +2049,6 @@ void shouldReturnError_whenWitnessRequiredAndNullDetails() { void shouldReturnNoError_whenWitnessRequiredAndDetailsProvided() { // Given List> testWitness = wrapElements(Witness.builder().name("test witness").build()); - Witnesses witnesses = Witnesses.builder().witnessesToAppear(YES).details(testWitness).build(); CaseData caseData = CaseDataBuilder.builder() .respondent1DQ(Respondent1DQ.builder().build()) .respondent1DQWitnessesRequiredSpec(YES) @@ -1657,9 +2137,6 @@ void specificSummary_whenPartialAdmitNotPay() { // When SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); - LocalDateTime responseDeadline = caseData.getApplicant1ResponseDeadline(); - String claimNumber = caseData.getLegacyCaseReference(); - // Then assertThat(response.getConfirmationBody()) .contains(caseData.getApplicant1().getPartyName()) @@ -2067,12 +2544,12 @@ void whenProvided_thenValidateCorrespondence1() { CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build() .toBuilder() .isRespondent1(YES) - .specAoSRespondentCorrespondenceAddressRequired(YesOrNo.NO) - .specAoSRespondentCorrespondenceAddressdetails(Address.builder() + .respondentSolicitor1ServiceAddressRequired(YesOrNo.NO) + .respondentSolicitor1ServiceAddress(Address.builder() .postCode("postal code") .build()) .build(); - CallbackParams params = callbackParamsOf(caseData, MID, "confirm-details"); + CallbackParams params = callbackParamsOf(caseData, MID, "specCorrespondenceAddress"); when(postcodeValidator.validate("postal code")).thenReturn(Collections.emptyList()); // When @@ -2089,12 +2566,12 @@ void whenProvided_thenValidateCorrespondence2() { CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build() .toBuilder() .isRespondent2(YES) - .specAoSRespondent2CorrespondenceAddressRequired(YesOrNo.NO) - .specAoSRespondent2CorrespondenceAddressdetails(Address.builder() - .postCode("postal code") - .build()) + .respondentSolicitor2ServiceAddressRequired(YesOrNo.NO) + .respondentSolicitor2ServiceAddress(Address.builder() + .postCode("postal code") + .build()) .build(); - CallbackParams params = callbackParamsOf(caseData, MID, "confirm-details"); + CallbackParams params = callbackParamsOf(caseData, MID, "specCorrespondenceAddress"); when(postcodeValidator.validate("postal code")).thenReturn(Collections.emptyList()); // When @@ -2324,10 +2801,55 @@ public void shouldThrowError_whenValidateRespondentExpertsMultipartyWithNoUnavai // Then assertThat(response.getErrors()).isNotEmpty(); } + + @Test + public void shouldThrowError_whenValidateRespondentExpertsMultipartyWithNoUnavailableDates_DisputesTheClaim() { + // Given + CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified() + .responseClaimTrack(SpecJourneyConstantLRSpec.DISPUTES_THE_CLAIM) + .respondent1DQ(Respondent1DQ.builder() + .respondent1DQHearingSmallClaim(SmallClaimHearing.builder().unavailableDatesRequired( + YES).build()).build()) + .build(); + List errors = Collections.singletonList("error 1"); + Mockito.when(dateValidator.validateFastClaimHearing(any())).thenReturn(errors); + CallbackParams params = callbackParamsOf(caseData, MID, "validate-unavailable-dates"); + // When + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler + .handle(params); + + // Then + assertThat(response.getErrors()).isNotEmpty(); + } + + @Test + public void shouldThrowError_whenValidateRespondentExpertsMultipartyWithNoUnavailableDates_V2() { + // Given + CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified() + .responseClaimTrack(SpecJourneyConstantLRSpec.SMALL_CLAIM) + .respondent1DQ(Respondent1DQ.builder() + .respondent1DQHearingSmallClaim(SmallClaimHearing.builder().unavailableDatesRequired( + YES).build()).build()) + .respondent2DQ(Respondent2DQ.builder() + .respondent2DQHearingSmallClaim(SmallClaimHearing.builder().unavailableDatesRequired( + YES).build()).build()) + .isRespondent2(YES) + .build(); + List errors = Collections.singletonList("error 1"); + Mockito.when(dateValidator.validateSmallClaimsHearing(any())).thenReturn(errors); + CallbackParams params = callbackParamsOf(caseData, MID, "validate-unavailable-dates"); + // When + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler + .handle(params); + + // Then + assertThat(response.getErrors()).isNotEmpty(); + } } @Test void handleEventsReturnsTheExpectedCallbackEvents() { assertThat(handler.handledEvents()).containsOnly(DEFENDANT_RESPONSE_SPEC); } + } From ef0198c18dede00f5cc2950e0510ee462fea8b33 Mon Sep 17 00:00:00 2001 From: UshaPanneerselvam1 <122611188+UshaPanneerselvam1@users.noreply.github.com> Date: Tue, 14 Nov 2023 14:08:43 +0000 Subject: [PATCH 28/28] CIV-8923 Refactoring tempAddress to tempCorrespondence (#3568) CIV-8923 specAoSApplicantCorrespondenceAddressdetails is being updated when defendant updates address --- .../RespondToClaimSpecCallbackHandler.java | 8 +++---- .../reform/civil/model/CaseDataParent.java | 12 +++++----- ...RespondToClaimSpecCallbackHandlerTest.java | 22 +++++++++---------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandler.java index 701d9c1c912..df862ffbf82 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandler.java @@ -1363,9 +1363,9 @@ private CallbackResponse setApplicantResponseDeadline(CallbackParams callbackPar AllocatedTrack allocatedTrack = caseData.getAllocatedTrack(); Party updatedRespondent1; - if (NO.equals(caseData.getTempAddress1Required())) { + if (NO.equals(caseData.getTempCorrespondenceAddress1Required())) { updatedRespondent1 = caseData.getRespondent1().toBuilder() - .primaryAddress(caseData.getTempAddress1()).build(); + .primaryAddress(caseData.getTempCorrespondenceAddress1()).build(); } else { updatedRespondent1 = caseData.getRespondent1().toBuilder() .primaryAddress(caseData.getRespondent1Copy().getPrimaryAddress()) @@ -1578,9 +1578,9 @@ && isAwaitingAnotherDefendantResponse(caseData)) { private static Party applyRespondent2Address(CaseData caseData, CaseData.CaseDataBuilder updatedData) { Party updatedRespondent2; - if (NO.equals(caseData.getTempAddress2Required())) { + if (NO.equals(caseData.getTempCorrespondenceAddress2Required())) { updatedRespondent2 = caseData.getRespondent2().toBuilder() - .primaryAddress(caseData.getTempAddress2()).build(); + .primaryAddress(caseData.getTempCorrespondenceAddress2()).build(); } else { updatedRespondent2 = caseData.getRespondent2().toBuilder() .primaryAddress(caseData.getRespondent2Copy().getPrimaryAddress()).build(); diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseDataParent.java b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseDataParent.java index 08b9556caf8..5db7728550f 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseDataParent.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseDataParent.java @@ -726,19 +726,19 @@ public boolean isApplicantNotRepresented() { /** * used to temporary hold addresses. */ - private final Address tempAddress1; + private final Address tempCorrespondenceAddress1; /** - * used with tempAddress1. + * used with tempCorrespondenceAddress1. */ - private final YesOrNo tempAddress1Required; + private final YesOrNo tempCorrespondenceAddress1Required; /** * used to temporary hold addresses. */ - private final Address tempAddress2; + private final Address tempCorrespondenceAddress2; /** - * used with tempAddress1. + * used with tempCorrespondenceAddress2. */ - private final YesOrNo tempAddress2Required; + private final YesOrNo tempCorrespondenceAddress2Required; @JsonIgnore public boolean isResponseAcceptedByClaimant() { diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandlerTest.java index 1ae04095de2..73040deeb42 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandlerTest.java @@ -789,8 +789,8 @@ void updateRespondent1AddressWhenUpdated() { .respondent1(PartyBuilder.builder().individual().build()) .atStateApplicantRespondToDefenceAndProceed() .build().toBuilder() - .tempAddress1Required(NO) - .tempAddress1(AddressBuilder.maximal().build()) + .tempCorrespondenceAddress1Required(NO) + .tempCorrespondenceAddress1(AddressBuilder.maximal().build()) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); @@ -829,11 +829,11 @@ void updateRespondent2AddressWhenUpdated() { .respondent2(PartyBuilder.builder().individual().build()) .respondent2Copy(PartyBuilder.builder().individual().build()) .build().toBuilder() - .tempAddress1Required(YES) - .tempAddress1(Address.builder().build()) + .tempCorrespondenceAddress1Required(YES) + .tempCorrespondenceAddress1(Address.builder().build()) .build().toBuilder() - .tempAddress2Required(NO) - .tempAddress2(newAddress2) + .tempCorrespondenceAddress2Required(NO) + .tempCorrespondenceAddress2(newAddress2) .respondentSolicitor2ServiceAddressRequired(NO) .respondentSolicitor2ServiceAddress(newAddress2) .build(); @@ -906,12 +906,12 @@ void defendantResponsePopulatesWitnessesData() { .respondent1DQWitnessesSmallClaim(res1witnesses) .respondent2DQWitnessesSmallClaim(res2witnesses) .build().toBuilder() - .tempAddress1Required(YES) - .tempAddress1(Address.builder().build()) + .tempCorrespondenceAddress1Required(YES) + .tempCorrespondenceAddress1(Address.builder().build()) .respondent2ResponseDate(dateTime) .respondent1ResponseDate(dateTime).build().toBuilder() - .tempAddress2Required(NO) - .tempAddress2(AddressBuilder.maximal().build()) + .tempCorrespondenceAddress2Required(NO) + .tempCorrespondenceAddress2(AddressBuilder.maximal().build()) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); @@ -1729,7 +1729,7 @@ void shouldUpdateCorrespondence1_whenProvided1v2ss_withSameResponse_withv2copyAn .build()) .respondent2Copy(PartyBuilder.builder().individual().build()) .respondent2SameLegalRepresentative(YES) - .tempAddress2Required(NO) + .tempCorrespondenceAddress2Required(NO) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT);

`#w_^7VK-DPo8% z2gkodzxMtcM9mmA(6}uzE(XIWKztp82G#ixnPb&K_whvCSg}+8Nj1=K`up!~C1PT% zD(HI*~J%=Q!wM diff --git a/docker/docmosis/templates/CV-UNS-GAP-ENG-01078.docx b/docker/docmosis/templates/CV-UNS-GAP-ENG-01078.docx index 8b1a1541fc9fd89a7af6e1b0d85038667dca6bdd..6ebdfc6bb623ce45e682e48e0bafe0f6e916bbb6 100644 GIT binary patch delta 13785 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 JGp#?H{~wt&cn1Ig delta 14303 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 d*95Ms;bAJuLjI+KKJ^FPVf From 730304acc965eb67dab4c13c02c45b8f26a71507 Mon Sep 17 00:00:00 2001 From: pliao-hmcts <113367232+pliao-hmcts@users.noreply.github.com> Date: Thu, 9 Nov 2023 14:59:36 +0000 Subject: [PATCH 18/28] CIV-11438 further hearing dates range check (#3546) --- ...GenerateDirectionOrderCallbackHandler.java | 8 ++++++++ ...rateDirectionOrderCallbackHandlerTest.java | 19 ++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandler.java index 59d211a4604..57967679b5d 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandler.java @@ -368,6 +368,14 @@ private void checkFieldDate(CaseData caseData, List errors) { .map(DatesFinalOrders::getDatesToAvoidDates).orElse(null), "Further hearing", NOT_ALLOWED_DATE_PAST, errors, true); + if (nonNull(caseData.getFinalOrderFurtherHearingComplex())) { + if (nonNull(caseData.getFinalOrderFurtherHearingComplex().getDateToDate()) + && caseData.getFinalOrderFurtherHearingComplex().getDateToDate() + .isBefore(caseData.getFinalOrderFurtherHearingComplex().getListFromDate())) { + errors.add(String.format(NOT_ALLOWED_DATE_RANGE, "Further hearing")); + } + } + validateDate(Optional.ofNullable(caseData.getAssistedOrderMakeAnOrderForCosts()) .map(AssistedOrderCostDetails::getAssistedOrderCostsFirstDropdownDate).orElse(null), "Make an order for detailed/summary costs", NOT_ALLOWED_DATE_PAST, errors, true); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandlerTest.java index e8bb81dee02..ca123fb867f 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandlerTest.java @@ -421,6 +421,14 @@ static Stream validAssistedOrderDates() { .datesToAvoidDates(LocalDate.now().plusDays(2)) .build()).build()).build() ), + Arguments.of( + CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() + .finalOrderSelection(FinalOrderSelection.ASSISTED_ORDER) + .finalOrderFurtherHearingComplex(FinalOrderFurtherHearing.builder() + .dateToDate(LocalDate.now().minusDays(4)) + .listFromDate(LocalDate.now().minusDays(5)) + .build()).build() + ), Arguments.of( CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .finalOrderSelection(FinalOrderSelection.ASSISTED_ORDER) @@ -532,7 +540,16 @@ static Stream invalidAssistedOrderDates() { "The date in Further hearing may not be before the established date" ), Arguments.of( - CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() + CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() + .finalOrderSelection(FinalOrderSelection.ASSISTED_ORDER) + .finalOrderFurtherHearingComplex(FinalOrderFurtherHearing.builder() + .dateToDate(LocalDate.now().minusDays(5)) + .listFromDate(LocalDate.now().minusDays(4)) + .build()).build(), + "The date range in Further hearing may not have a 'from date', that is after the 'date to'" + ), + Arguments.of( + CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .finalOrderSelection(FinalOrderSelection.ASSISTED_ORDER) .assistedOrderMakeAnOrderForCosts(AssistedOrderCostDetails.builder() .assistedOrderCostsFirstDropdownDate(LocalDate.now().minusDays(2)) From 7d8c1123ba0e11126fc1e1eb1a6d833f23db0f6b Mon Sep 17 00:00:00 2001 From: vasudevganesanhmcts <100689363+vasudevganesanhmcts@users.noreply.github.com> Date: Fri, 10 Nov 2023 14:27:18 +0000 Subject: [PATCH 19/28] Revert "CIV-10918 - Performance upgrade for Case Progression classes (#3389)" (#3555) This reverts commit c8f01e6092ed6049c6905e990213e4538c8cbdd7. --- .../gov/hmcts/reform/civil/Application.java | 3 - .../user/EvidenceUploadApplicantHandler.java | 12 +- .../user/EvidenceUploadHandlerBase.java | 176 ++++++------------ .../user/EvidenceUploadRespondentHandler.java | 14 +- .../user/HearingScheduledHandler.java | 1 + .../user/TrialReadinessCallbackHandler.java | 43 +++-- .../InitiateGeneralApplicationService.java | 3 +- ...itiateGeneralApplicationServiceHelper.java | 3 +- .../reform/civil/utils/UserRoleCaching.java | 23 +-- .../EvidenceUploadApplicantHandlerTest.java | 53 ++++-- .../EvidenceUploadRespondentHandlerTest.java | 104 +++++++---- .../TrialReadinessCallbackHandlerTest.java | 106 ++++------- ...InitiateGeneralApplicationServiceTest.java | 12 +- .../civil/utils/UserRoleCachingTest.java | 42 ----- 14 files changed, 246 insertions(+), 349 deletions(-) delete mode 100644 src/test/java/uk/gov/hmcts/reform/civil/utils/UserRoleCachingTest.java diff --git a/src/main/java/uk/gov/hmcts/reform/civil/Application.java b/src/main/java/uk/gov/hmcts/reform/civil/Application.java index 7f27bb76741..4fed58056f7 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/Application.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/Application.java @@ -3,7 +3,6 @@ import org.camunda.bpm.extension.rest.EnableCamundaRestClient; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cache.annotation.EnableCaching; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication @@ -18,8 +17,6 @@ "uk.gov.hmcts.reform.civil.crd", "uk.gov.hmcts.reform.hmc" }) - -@EnableCaching @SuppressWarnings("HideUtilityClassConstructor") // Spring needs a constructor, its not a utility class public class Application { diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandler.java index 7f2ef1da220..2f1c783db93 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandler.java @@ -22,25 +22,27 @@ import uk.gov.hmcts.reform.civil.model.caseprogression.UploadEvidenceDocumentType; import uk.gov.hmcts.reform.civil.model.common.Element; import uk.gov.hmcts.reform.civil.service.CoreCaseDataService; +import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; import uk.gov.hmcts.reform.civil.service.Time; -import uk.gov.hmcts.reform.civil.utils.UserRoleCaching; +import uk.gov.hmcts.reform.civil.service.UserService; +import uk.gov.hmcts.reform.idam.client.models.UserInfo; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.EVIDENCE_UPLOAD_APPLICANT; @Service public class EvidenceUploadApplicantHandler extends EvidenceUploadHandlerBase { - public EvidenceUploadApplicantHandler(CaseDetailsConverter caseDetailsConverter, + public EvidenceUploadApplicantHandler(UserService userService, CoreCaseUserService coreCaseUserService, + CaseDetailsConverter caseDetailsConverter, CoreCaseDataService coreCaseDataService, - UserRoleCaching userRoleCaching, ObjectMapper objectMapper, Time time) { - super(caseDetailsConverter, coreCaseDataService, userRoleCaching, + super(userService, coreCaseUserService, caseDetailsConverter, coreCaseDataService, objectMapper, time, Collections.singletonList(EVIDENCE_UPLOAD_APPLICANT), "validateValuesApplicant", "createShowCondition"); } @Override - CallbackResponse createShowCondition(CaseData caseData, List userRoles) { + CallbackResponse createShowCondition(CaseData caseData, UserInfo userInfo) { CaseData.CaseDataBuilder caseDataBuilder = caseData.toBuilder(); //For case which are 1v1, 2v1 we show respondent fields for documents to be uploaded, //if a case is 1v2 and different solicitors we want to show separate fields for each respondent solicitor i.e. diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadHandlerBase.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadHandlerBase.java index c850f6b8bd4..e69ffd03ba7 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadHandlerBase.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadHandlerBase.java @@ -39,9 +39,11 @@ import uk.gov.hmcts.reform.civil.model.common.Element; import uk.gov.hmcts.reform.civil.documentmanagement.model.Document; import uk.gov.hmcts.reform.civil.service.CoreCaseDataService; +import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; import uk.gov.hmcts.reform.civil.service.Time; +import uk.gov.hmcts.reform.civil.service.UserService; import uk.gov.hmcts.reform.civil.utils.ElementUtils; -import uk.gov.hmcts.reform.civil.utils.UserRoleCaching; +import uk.gov.hmcts.reform.idam.client.models.UserInfo; import static java.lang.String.format; import static java.util.Objects.nonNull; @@ -55,7 +57,6 @@ import static uk.gov.hmcts.reform.civil.enums.AllocatedTrack.getAllocatedTrack; import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORONE; import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORTWO; -import static uk.gov.hmcts.reform.civil.utils.UserRoleUtils.isRespondentSolicitorTwo; abstract class EvidenceUploadHandlerBase extends CallbackHandler { @@ -64,11 +65,11 @@ abstract class EvidenceUploadHandlerBase extends CallbackHandler { private final String createShowCondition; protected final ObjectMapper objectMapper; private final Time time; + private final CoreCaseUserService coreCaseUserService; + private final UserService userService; private final CaseDetailsConverter caseDetailsConverter; private final CoreCaseDataService coreCaseDataService; - private final UserRoleCaching userRoleCaching; - private static final String SPACE = " "; private static final String END = "."; private static final String DATE_FORMAT = "dd-MM-yyyy"; @@ -163,8 +164,9 @@ abstract class EvidenceUploadHandlerBase extends CallbackHandler { private static final String SELECTED_VALUE_DEF_BOTH = "RESPONDENTBOTH"; private static final String SELECTED_VALUE_APP_BOTH = "APPLICANTBOTH"; - protected EvidenceUploadHandlerBase(CaseDetailsConverter caseDetailsConverter, - CoreCaseDataService coreCaseDataService, UserRoleCaching userRoleCaching, + protected EvidenceUploadHandlerBase(UserService userService, CoreCaseUserService coreCaseUserService, + CaseDetailsConverter caseDetailsConverter, + CoreCaseDataService coreCaseDataService, ObjectMapper objectMapper, Time time, List events, String pageId, String createShowCondition) { this.objectMapper = objectMapper; @@ -172,14 +174,15 @@ protected EvidenceUploadHandlerBase(CaseDetailsConverter caseDetailsConverter, this.createShowCondition = createShowCondition; this.events = events; this.pageId = pageId; - this.userRoleCaching = userRoleCaching; + this.coreCaseUserService = coreCaseUserService; + this.userService = userService; this.caseDetailsConverter = caseDetailsConverter; this.coreCaseDataService = coreCaseDataService; } abstract CallbackResponse validateValues(CallbackParams callbackParams, CaseData caseData); - abstract CallbackResponse createShowCondition(CaseData caseData, List userRoles); + abstract CallbackResponse createShowCondition(CaseData caseData, UserInfo userInfo); abstract void applyDocumentUploadDate(CaseData.CaseDataBuilder caseDataBuilder, LocalDateTime now); @@ -234,20 +237,16 @@ CallbackResponse setOptions(CallbackParams callbackParams) { } CallbackResponse createShow(CallbackParams callbackParams) { - CaseData caseData = callbackParams.getCaseData(); - String bearerToken = callbackParams.getParams().get(BEARER_TOKEN).toString(); - String ccdCaseRef = callbackParams.getCaseData().getCcdCaseReference().toString(); - String keyToken = userRoleCaching.getCacheKeyToken(bearerToken); - List userRoles = userRoleCaching.getUserRoles(bearerToken, ccdCaseRef, keyToken); + UserInfo userInfo = userService.getUserInfo(callbackParams.getParams().get(BEARER_TOKEN).toString()); - return createShowCondition(callbackParams.getCaseData(), userRoles); + return createShowCondition(callbackParams.getCaseData(), userInfo); } // CCD has limited show hide functionality, we want to show a field based on a fixed listed containing an element, // or a second list containing an element, AND with the addition of the user being respondent2 solicitor, the below // combines the list condition into one single condition, which can then be used in CCD along with the // caseTypeFlag condition - CallbackResponse showCondition(CaseData caseData, List userRoles, + CallbackResponse showCondition(CaseData caseData, UserInfo userInfo, List witnessStatementFastTrack, List witnessStatementSmallTrack, List witnessSummaryFastTrack, @@ -276,11 +275,24 @@ CallbackResponse showCondition(CaseData caseData, List userRoles, boolean multiParts = Objects.nonNull(caseData.getEvidenceUploadOptions()) && !caseData.getEvidenceUploadOptions().getListItems().isEmpty(); - if (isApplicantTwoFields(multiParts, caseData)) { - caseDataBuilder.caseTypeFlag("ApplicantTwoFields"); - } else if (isRespondentTwoFields(multiParts, caseData, userRoles)) { + if (events.get(0).equals(EVIDENCE_UPLOAD_APPLICANT)) { + //2v1, app2 selected + if (multiParts + && caseData.getEvidenceUploadOptions() + .getValue().getLabel().startsWith(OPTION_APP2)) { + caseDataBuilder.caseTypeFlag("ApplicantTwoFields"); + } + } else if (events.get(0).equals(EVIDENCE_UPLOAD_RESPONDENT)) { //1v2 same sol, def2 selected - caseDataBuilder.caseTypeFlag("RespondentTwoFields"); + if ((multiParts + && caseData.getEvidenceUploadOptions() + .getValue().getLabel().startsWith(OPTION_DEF2)) + //1v2 dif sol, log in as def2 + || (!multiParts && Objects.nonNull(caseData.getCcdCaseReference()) + && coreCaseUserService.userHasCaseRole(caseData.getCcdCaseReference() + .toString(), userInfo.getUid(), RESPONDENTSOLICITORTWO))) { + caseDataBuilder.caseTypeFlag("RespondentTwoFields"); + } } // clears the flag, as otherwise if the user returns to previous screen and unselects an option, @@ -297,28 +309,36 @@ CallbackResponse showCondition(CaseData caseData, List userRoles, // Based on claim type being fast track or small claims, there will be two different lists to select from // for either list we then want to display a (same) document upload field corresponding, // below combines what would have been two separate show conditions in CCD, into a single flag - if (isWitnessStatementFlag(witnessStatementFastTrack, witnessStatementSmallTrack)) { + if (nonNull(witnessStatementFastTrack) && witnessStatementFastTrack.contains(EvidenceUploadWitness.WITNESS_STATEMENT) + || nonNull(witnessStatementSmallTrack) && witnessStatementSmallTrack.contains(EvidenceUploadWitness.WITNESS_STATEMENT)) { caseDataBuilder.witnessStatementFlag("show_witness_statement"); } - if (showWitnessSummary(witnessSummaryFastTrack, witnessSummarySmallTrack)) { + if (nonNull(witnessSummaryFastTrack) && witnessSummaryFastTrack.contains(EvidenceUploadWitness.WITNESS_SUMMARY) + || nonNull(witnessSummarySmallTrack) && witnessSummarySmallTrack.contains(EvidenceUploadWitness.WITNESS_SUMMARY)) { caseDataBuilder.witnessSummaryFlag("show_witness_summary"); } - if (showWitnessReferred(witnessReferredFastTrack, witnessReferredSmallTrack)) { + if (nonNull(witnessReferredFastTrack) && witnessReferredFastTrack.contains(EvidenceUploadWitness.DOCUMENTS_REFERRED) + || nonNull(witnessReferredSmallTrack) && witnessReferredSmallTrack.contains(EvidenceUploadWitness.DOCUMENTS_REFERRED)) { caseDataBuilder.witnessReferredStatementFlag("show_witness_referred"); } - if (showExpertReport(expertReportFastTrack, expertReportSmallTrack)) { + if (nonNull(expertReportFastTrack) && expertReportFastTrack.contains(EvidenceUploadExpert.EXPERT_REPORT) + || nonNull(expertReportSmallTrack) && expertReportSmallTrack.contains(EvidenceUploadExpert.EXPERT_REPORT)) { caseDataBuilder.expertReportFlag("show_expert_report"); } - if (showJointExpert(expertJointFastTrack, expertJointSmallTrack)) { + if (nonNull(expertJointFastTrack) && expertJointFastTrack.contains(EvidenceUploadExpert.JOINT_STATEMENT) + || nonNull(expertJointSmallTrack) && expertJointSmallTrack.contains(EvidenceUploadExpert.JOINT_STATEMENT)) { caseDataBuilder.expertJointFlag("show_joint_expert"); } - if (showTrialAuthority(trialAuthorityFastTrack, trialAuthoritySmallTrack)) { + if (nonNull(trialAuthorityFastTrack) && trialAuthorityFastTrack.contains(EvidenceUploadTrial.AUTHORITIES) + || nonNull(trialAuthoritySmallTrack) && trialAuthoritySmallTrack.contains(EvidenceUploadTrial.AUTHORITIES)) { caseDataBuilder.trialAuthorityFlag("show_trial_authority"); } - if (showTrialCosts(trialCostsFastTrack, trialCostsSmallTrack)) { + if (nonNull(trialCostsFastTrack) && trialCostsFastTrack.contains(EvidenceUploadTrial.COSTS) + || nonNull(trialCostsSmallTrack) && trialCostsSmallTrack.contains(EvidenceUploadTrial.COSTS)) { caseDataBuilder.trialCostsFlag("show_trial_costs"); } - if (showTrialDocumentary(trialDocumentaryFastTrack, trialDocumentarySmallTrack)) { + if (nonNull(trialDocumentaryFastTrack) && trialDocumentaryFastTrack.contains(EvidenceUploadTrial.DOCUMENTARY) + || nonNull(trialDocumentarySmallTrack) && trialDocumentarySmallTrack.contains(EvidenceUploadTrial.DOCUMENTARY)) { caseDataBuilder.trialDocumentaryFlag("show_trial_documentary"); } @@ -327,89 +347,6 @@ CallbackResponse showCondition(CaseData caseData, List userRoles, .build(); } - private boolean isApplicantTwoFields(boolean multiParts, - CaseData caseData) { - //2v1, app2 selected - return events.get(0).equals(EVIDENCE_UPLOAD_APPLICANT) && (multiParts - && caseData.getEvidenceUploadOptions() - .getValue().getLabel().startsWith(OPTION_APP2)); - } - - private boolean isRespondentTwoFields(boolean multiParts, - CaseData caseData, - List userRoles) { - //1v2 dif sol, log in as def2 - return events.get(0).equals(EVIDENCE_UPLOAD_RESPONDENT) && ((multiParts - && caseData.getEvidenceUploadOptions() - .getValue().getLabel().startsWith(OPTION_DEF2)) - || (!multiParts && Objects.nonNull(caseData.getCcdCaseReference()) - && isRespondentSolicitorTwo(userRoles))); - } - - private boolean isWitnessStatementFlag(List witnessStatementFastTrack, - List witnessStatementSmallTrack) { - return nonNull(witnessStatementFastTrack) - && witnessStatementFastTrack.contains(EvidenceUploadWitness.WITNESS_STATEMENT) - || nonNull(witnessStatementSmallTrack) - && witnessStatementSmallTrack.contains(EvidenceUploadWitness.WITNESS_STATEMENT); - } - - private boolean showWitnessSummary(List witnessSummaryFastTrack, - List witnessSummarySmallTrack) { - return nonNull(witnessSummaryFastTrack) - && witnessSummaryFastTrack.contains(EvidenceUploadWitness.WITNESS_SUMMARY) - || nonNull(witnessSummarySmallTrack) - && witnessSummarySmallTrack.contains(EvidenceUploadWitness.WITNESS_SUMMARY); - } - - private boolean showWitnessReferred(List witnessReferredFastTrack, - List witnessReferredSmallTrack) { - return nonNull(witnessReferredFastTrack) - && witnessReferredFastTrack.contains(EvidenceUploadWitness.DOCUMENTS_REFERRED) - || nonNull(witnessReferredSmallTrack) - && witnessReferredSmallTrack.contains(EvidenceUploadWitness.DOCUMENTS_REFERRED); - } - - private boolean showExpertReport(List expertReportFastTrack, - List expertReportSmallTrack) { - return nonNull(expertReportFastTrack) - && expertReportFastTrack.contains(EvidenceUploadExpert.EXPERT_REPORT) - || nonNull(expertReportSmallTrack) - && expertReportSmallTrack.contains(EvidenceUploadExpert.EXPERT_REPORT); - } - - private boolean showJointExpert(List expertJointFastTrack, - List expertJointSmallTrack) { - return nonNull(expertJointFastTrack) - && expertJointFastTrack.contains(EvidenceUploadExpert.JOINT_STATEMENT) - || nonNull(expertJointSmallTrack) - && expertJointSmallTrack.contains(EvidenceUploadExpert.JOINT_STATEMENT); - } - - private boolean showTrialAuthority(List trialAuthorityFastTrack, - List trialAuthoritySmallTrack) { - return nonNull(trialAuthorityFastTrack) - && trialAuthorityFastTrack.contains(EvidenceUploadTrial.AUTHORITIES) - || nonNull(trialAuthoritySmallTrack) - && trialAuthoritySmallTrack.contains(EvidenceUploadTrial.AUTHORITIES); - } - - private boolean showTrialCosts(List trialCostsFastTrack, - List trialCostsSmallTrack) { - return nonNull(trialCostsFastTrack) - && trialCostsFastTrack.contains(EvidenceUploadTrial.COSTS) - || nonNull(trialCostsSmallTrack) - && trialCostsSmallTrack.contains(EvidenceUploadTrial.COSTS); - } - - private boolean showTrialDocumentary(List trialDocumentaryFastTrack, - List trialDocumentarySmallTrack) { - return nonNull(trialDocumentaryFastTrack) - && trialDocumentaryFastTrack.contains(EvidenceUploadTrial.DOCUMENTARY) - || nonNull(trialDocumentarySmallTrack) - && trialDocumentarySmallTrack.contains(EvidenceUploadTrial.DOCUMENTARY); - } - CallbackResponse validate(CallbackParams callbackParams) { return validateValues(callbackParams, callbackParams.getCaseData()); } @@ -1166,7 +1103,7 @@ private String getSelectedRole(CallbackParams callbackParams) { CaseData caseData = callbackParams.getCaseData(); boolean multiParts = Objects.nonNull(caseData.getEvidenceUploadOptions()) && !caseData.getEvidenceUploadOptions().getListItems().isEmpty(); - + UserInfo userInfo = userService.getUserInfo(callbackParams.getParams().get(BEARER_TOKEN).toString()); if (events.get(0).equals(EVIDENCE_UPLOAD_APPLICANT)) { if (multiParts && caseData.getEvidenceUploadOptions() .getValue().getLabel().startsWith(OPTION_APP2)) { @@ -1178,11 +1115,11 @@ private String getSelectedRole(CallbackParams callbackParams) { } return CaseRole.APPLICANTSOLICITORONE.name(); } else { - String bearerToken = callbackParams.getParams().get(BEARER_TOKEN).toString(); - String ccdCaseRef = callbackParams.getCaseData().getCcdCaseReference().toString(); - String keyToken = userRoleCaching.getCacheKeyToken(bearerToken); - List userRoles = userRoleCaching.getUserRoles(bearerToken, ccdCaseRef, keyToken); - if (isResp2(multiParts, caseData, userRoles)) { + if ((multiParts && caseData.getEvidenceUploadOptions() + .getValue().getLabel().startsWith(OPTION_DEF2)) + || (!multiParts + && coreCaseUserService.userHasCaseRole(caseData.getCcdCaseReference().toString(), + userInfo.getUid(), RESPONDENTSOLICITORTWO))) { return CaseRole.RESPONDENTSOLICITORTWO.name(); } if (multiParts && caseData.getEvidenceUploadOptions() @@ -1193,13 +1130,6 @@ private String getSelectedRole(CallbackParams callbackParams) { } } - private boolean isResp2(boolean multiParts, CaseData caseData, List userRoles) { - return (multiParts && caseData.getEvidenceUploadOptions() - .getValue().getLabel().startsWith(OPTION_DEF2)) - || (!multiParts - && isRespondentSolicitorTwo(userRoles)); - } - SubmittedCallbackResponse buildConfirmation(CallbackParams callbackParams) { return SubmittedCallbackResponse.builder() .confirmationHeader("# Documents uploaded") diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandler.java index e4b87694ca5..91c7ee7e416 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandler.java @@ -20,19 +20,21 @@ import uk.gov.hmcts.reform.civil.model.caseprogression.UploadEvidenceDocumentType; import uk.gov.hmcts.reform.civil.model.common.Element; import uk.gov.hmcts.reform.civil.service.CoreCaseDataService; +import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; import uk.gov.hmcts.reform.civil.service.Time; -import uk.gov.hmcts.reform.civil.utils.UserRoleCaching; +import uk.gov.hmcts.reform.civil.service.UserService; +import uk.gov.hmcts.reform.idam.client.models.UserInfo; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.EVIDENCE_UPLOAD_RESPONDENT; @Service public class EvidenceUploadRespondentHandler extends EvidenceUploadHandlerBase { - public EvidenceUploadRespondentHandler(CaseDetailsConverter caseDetailsConverter, + public EvidenceUploadRespondentHandler(UserService userService, CoreCaseUserService coreCaseUserService, + CaseDetailsConverter caseDetailsConverter, CoreCaseDataService coreCaseDataService, - UserRoleCaching userRoleCaching, ObjectMapper objectMapper, Time time) { - super(caseDetailsConverter, coreCaseDataService, userRoleCaching, + super(userService, coreCaseUserService, caseDetailsConverter, coreCaseDataService, objectMapper, time, Collections.singletonList(EVIDENCE_UPLOAD_RESPONDENT), "validateValuesRespondent", "createShowCondition"); } @@ -64,9 +66,9 @@ CallbackResponse validateValues(CallbackParams callbackParams, CaseData caseData } @Override - CallbackResponse createShowCondition(CaseData caseData, List userRoles) { + CallbackResponse createShowCondition(CaseData caseData, UserInfo userInfo) { - return showCondition(caseData, userRoles, caseData.getWitnessSelectionEvidenceRes(), + return showCondition(caseData, userInfo, caseData.getWitnessSelectionEvidenceRes(), caseData.getWitnessSelectionEvidenceSmallClaimRes(), caseData.getWitnessSelectionEvidenceRes(), caseData.getWitnessSelectionEvidenceSmallClaimRes(), diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/HearingScheduledHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/HearingScheduledHandler.java index 4c962b98090..f378b489e01 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/HearingScheduledHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/HearingScheduledHandler.java @@ -145,6 +145,7 @@ private CallbackResponse checkPastDate(CallbackParams callbackParams) { "The Date must be in the past"); CaseData.CaseDataBuilder caseDataBuilder = caseData.toBuilder(); + return AboutToStartOrSubmitCallbackResponse.builder() .data(caseDataBuilder.build().toMap(objectMapper)) .errors(errors) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/TrialReadinessCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/TrialReadinessCallbackHandler.java index b9258e3f637..fcf84a5bc97 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/TrialReadinessCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/TrialReadinessCallbackHandler.java @@ -13,7 +13,9 @@ import uk.gov.hmcts.reform.civil.enums.YesOrNo; import uk.gov.hmcts.reform.civil.model.BusinessProcess; import uk.gov.hmcts.reform.civil.model.CaseData; -import uk.gov.hmcts.reform.civil.utils.UserRoleCaching; +import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; +import uk.gov.hmcts.reform.civil.service.UserService; +import uk.gov.hmcts.reform.idam.client.models.UserInfo; import java.time.LocalDate; import java.util.ArrayList; @@ -64,7 +66,8 @@ public class TrialReadinessCallbackHandler extends CallbackHandler { + "you will need to make an application to the court and pay the appropriate fee."; private final ObjectMapper objectMapper; - private final UserRoleCaching userRoleCaching; + private final UserService userService; + private final CoreCaseUserService coreCaseUserService; @Override protected Map callbacks() { @@ -78,11 +81,7 @@ protected Map callbacks() { private CallbackResponse populateValues(CallbackParams callbackParams) { var caseData = callbackParams.getCaseData(); CaseData.CaseDataBuilder updatedData = caseData.toBuilder(); - - String bearerToken = callbackParams.getParams().get(BEARER_TOKEN).toString(); - String ccdCaseRef = callbackParams.getCaseData().getCcdCaseReference().toString(); - String keyToken = userRoleCaching.getCacheKeyToken(bearerToken); - List userRoles = userRoleCaching.getUserRoles(bearerToken, ccdCaseRef, keyToken); + List userRoles = getUserRoles(callbackParams); var isApplicant = YesOrNo.NO; var isRespondent1 = YesOrNo.NO; @@ -121,19 +120,15 @@ private CallbackResponse populateValues(CallbackParams callbackParams) { private CallbackResponse setBusinessProcess(CallbackParams callbackParams) { var caseData = callbackParams.getCaseData(); CaseData.CaseDataBuilder updatedData = caseData.toBuilder(); + List userRoles = getUserRoles(callbackParams); - String bearerToken = callbackParams.getParams().get(BEARER_TOKEN).toString(); - String ccdCaseRef = callbackParams.getCaseData().getCcdCaseReference().toString(); - String keyToken = userRoleCaching.getCacheKeyToken(bearerToken); - List roles = userRoleCaching.getUserRoles(bearerToken, ccdCaseRef, keyToken); - - if (isApplicantSolicitor(roles) || isLIPClaimant(roles)) { + if (isApplicantSolicitor(userRoles) || isLIPClaimant(userRoles)) { if (caseData.getTrialReadyApplicant() == YesOrNo.YES) { updatedData.businessProcess(BusinessProcess.ready(APPLICANT_TRIAL_READY_NOTIFY_OTHERS)); } else { updatedData.businessProcess(BusinessProcess.ready(GENERATE_TRIAL_READY_DOCUMENT_APPLICANT)); } - } else if (isRespondentSolicitorOne(roles) || isLIPDefendant(roles)) { + } else if (isRespondentSolicitorOne(userRoles) || isLIPDefendant(userRoles)) { if (caseData.getTrialReadyRespondent1() == YesOrNo.YES) { updatedData.businessProcess(BusinessProcess.ready(RESPONDENT1_TRIAL_READY_NOTIFY_OTHERS)); } else { @@ -146,27 +141,24 @@ private CallbackResponse setBusinessProcess(CallbackParams callbackParams) { updatedData.businessProcess(BusinessProcess.ready(GENERATE_TRIAL_READY_DOCUMENT_RESPONDENT2)); } } + return AboutToStartOrSubmitCallbackResponse.builder() .data(updatedData.build().toMap(objectMapper)) .build(); } private SubmittedCallbackResponse buildConfirmation(CallbackParams callbackParams) { + List userRoles = getUserRoles(callbackParams); return SubmittedCallbackResponse.builder() - .confirmationHeader(checkUserReady(callbackParams).equals(YesOrNo.YES) ? READY_HEADER : NOT_READY_HEADER) - .confirmationBody(checkUserReady(callbackParams).equals(YesOrNo.YES) ? READY_BODY : NOT_READY_BODY) + .confirmationHeader(checkUserReady(callbackParams, userRoles).equals(YesOrNo.YES) ? READY_HEADER : NOT_READY_HEADER) + .confirmationBody(checkUserReady(callbackParams, userRoles).equals(YesOrNo.YES) ? READY_BODY : NOT_READY_BODY) .build(); } - private YesOrNo checkUserReady(CallbackParams callbackParams) { + private YesOrNo checkUserReady(CallbackParams callbackParams, List userRoles) { var caseData = callbackParams.getCaseData(); - String bearerToken = callbackParams.getParams().get(BEARER_TOKEN).toString(); - String ccdCaseRef = callbackParams.getCaseData().getCcdCaseReference().toString(); - String keyToken = userRoleCaching.getCacheKeyToken(bearerToken); - List userRoles = userRoleCaching.getUserRoles(bearerToken, ccdCaseRef, keyToken); - if (isApplicantSolicitor(userRoles) || isLIPClaimant(userRoles)) { return caseData.getTrialReadyApplicant(); } else if (isRespondentSolicitorOne(userRoles) || isLIPDefendant(userRoles)) { @@ -176,6 +168,13 @@ private YesOrNo checkUserReady(CallbackParams callbackParams) { } } + private List getUserRoles(CallbackParams callbackParams) { + String bearerToken = callbackParams.getParams().get(BEARER_TOKEN).toString(); + String ccdCaseRef = callbackParams.getCaseData().getCcdCaseReference().toString(); + UserInfo userInfo = userService.getUserInfo(bearerToken); + return coreCaseUserService.getUserCaseRoles(ccdCaseRef, userInfo.getUid()); + } + @Override public List handledEvents() { return EVENTS; diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationService.java b/src/main/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationService.java index ded72ad6e41..a6191151527 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationService.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationService.java @@ -297,8 +297,7 @@ private void validateUnavailableDates(List errors, public boolean respondentAssigned(CaseData caseData, String authToken) { String caseId = caseData.getCcdCaseReference().toString(); - String keyToken = userRoleCaching.getCacheKeyToken(authToken); - List userRoles = userRoleCaching.getUserRoles(authToken, caseId, keyToken); + List userRoles = userRoleCaching.getUserRoles(authToken, caseId); List respondentCaseRoles = getRespondentCaseRoles(caseData); return !(userRoles.isEmpty() || !isRespondentSolicitorOne(respondentCaseRoles) || (respondentCaseRoles.size() > 1 && !isRespondentSolicitorTwo(respondentCaseRoles))); diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationServiceHelper.java b/src/main/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationServiceHelper.java index 2199f76c58a..d6d35fe839d 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationServiceHelper.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationServiceHelper.java @@ -233,8 +233,7 @@ public String getApplicantPartyName(CaseAssignedUserRolesResource userRoles, Use public boolean isGAApplicantSameAsParentCaseClaimant(CaseData caseData, String authToken) { String parentCaseId = caseData.getCcdCaseReference().toString(); - String keyToken = userRoleCaching.getCacheKeyToken(authToken); - List userRolesCaching = userRoleCaching.getUserRoles(authToken, parentCaseId, keyToken); + List userRolesCaching = userRoleCaching.getUserRoles(authToken, parentCaseId); boolean isApplicantSolicitor = UserRoleUtils.isApplicantSolicitor(userRolesCaching); diff --git a/src/main/java/uk/gov/hmcts/reform/civil/utils/UserRoleCaching.java b/src/main/java/uk/gov/hmcts/reform/civil/utils/UserRoleCaching.java index dfdb019f954..3f5a4898b5c 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/utils/UserRoleCaching.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/utils/UserRoleCaching.java @@ -2,12 +2,6 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.cache.CacheManager; -import org.springframework.cache.annotation.CacheEvict; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.cache.concurrent.ConcurrentMapCacheManager; -import org.springframework.context.annotation.Bean; -import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; import uk.gov.hmcts.reform.civil.service.UserService; @@ -23,24 +17,9 @@ public class UserRoleCaching { private final UserService userService; private final CoreCaseUserService coreCaseUserService; - @Cacheable(cacheNames = "UserCache", cacheManager = "userCacheManager", key = "#keyToken") - public List getUserRoles(String bearerToken, String ccdCaseRef, String keyToken) { + public List getUserRoles(String bearerToken, String ccdCaseRef) { UserInfo userInfo = userService.getUserInfo(bearerToken); return coreCaseUserService.getUserCaseRoles(ccdCaseRef, userInfo.getUid()); } - public String getCacheKeyToken(String bearerToken) { - return bearerToken.substring(bearerToken.length() - 16); - } - - @Bean(name = "userCacheManager") - public CacheManager getCacheManager() { - return new ConcurrentMapCacheManager(); - } - - @CacheEvict(value = "UserCache", allEntries = true) - @Scheduled(fixedRateString = "1800000") - public void emptyUserCache() { - log.debug("Cache removed"); - } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandlerTest.java index ec3b2d9d8e2..cda6fc74fc7 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandlerTest.java @@ -27,7 +27,6 @@ import uk.gov.hmcts.reform.ccd.client.model.SubmittedCallbackResponse; import uk.gov.hmcts.reform.civil.callback.CallbackHandler; import uk.gov.hmcts.reform.civil.callback.CallbackParams; -import uk.gov.hmcts.reform.civil.enums.CaseRole; import uk.gov.hmcts.reform.civil.enums.ClaimType; import uk.gov.hmcts.reform.civil.handler.callback.BaseCallbackHandlerTest; import uk.gov.hmcts.reform.civil.helpers.CaseDetailsConverter; @@ -47,7 +46,7 @@ import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; import uk.gov.hmcts.reform.civil.service.Time; import uk.gov.hmcts.reform.civil.utils.ElementUtils; -import uk.gov.hmcts.reform.civil.utils.UserRoleCaching; +import uk.gov.hmcts.reform.idam.client.models.UserInfo; import static java.util.Map.entry; import static org.assertj.core.api.Assertions.assertThat; @@ -55,12 +54,15 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_START; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; import static uk.gov.hmcts.reform.civil.callback.CallbackType.MID; import static uk.gov.hmcts.reform.civil.callback.CallbackType.SUBMITTED; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.EVIDENCE_UPLOAD_APPLICANT; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORONE; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORTWO; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; import static uk.gov.hmcts.reform.civil.utils.ElementUtils.element; @@ -88,9 +90,6 @@ class EvidenceUploadApplicantHandlerTest extends BaseCallbackHandlerTest { private CoreCaseDataService coreCaseDataService; @MockBean CaseData.CaseDataBuilder caseDataBuilder; - - @MockBean - private UserRoleCaching userRoleCaching; @Autowired private final ObjectMapper mapper = new ObjectMapper(); @@ -128,8 +127,6 @@ class EvidenceUploadApplicantHandlerTest extends BaseCallbackHandlerTest { @BeforeEach void setup() { given(time.now()).willReturn(LocalDateTime.now()); - given(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) - .willReturn(List.of(CaseRole.APPLICANTSOLICITORONE.getFormattedName())); } @Test @@ -142,7 +139,8 @@ void givenAboutToStart_assignCaseProgAllocatedTrackUnSpec() { .statementOfValueInPennies(BigDecimal.valueOf(5000)) .build()) .build(); - + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), any())).willReturn(false); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_START); // When AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler @@ -160,7 +158,8 @@ void givenAboutToStart_assignCaseProgAllocatedTrackSpec() { .claimType(null) .totalClaimAmount(BigDecimal.valueOf(12500)) .build(); - + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), any())).willReturn(false); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_START); // When AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler @@ -506,6 +505,9 @@ void shouldCallExternalTask_whenAboutToSubmit() { CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -531,7 +533,9 @@ void shouldAssignCategoryID_whenDocumentExists() { CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .documentHearsayNotice(documentList) .build(); - + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // When @@ -547,7 +551,9 @@ void shouldNotAssignCategoryID_whenDocumentNotExists() { CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .addRespondent2(YES) .build(); - + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // When @@ -604,6 +610,9 @@ void shouldAddApplicantEvidenceDocWhenBundleCreatedDateIsBeforeEvidenceUploaded( .caseBundles(prepareCaseBundles(LocalDateTime.of(2022, 05, 10, 12, 12, 12))).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); // When handle is called var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -622,6 +631,9 @@ void shouldNotAddApplicantEvidenceDocWhenBundleCreatedDateIsAfterEvidenceUploade .caseBundles(prepareCaseBundles(LocalDateTime.of(2022, 05, 15, 12, 12, 12))).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); // When handle is called var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -650,6 +662,9 @@ void shouldBreakWhenThereIsAnyCaseBundlesWithoutCreatedDate() { .caseBundles(caseBundles) .build(); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); // When: handler is called @@ -675,6 +690,9 @@ void shouldBreakWhenThereIsAnyCaseBundlesWithNullCreatedDate() { .caseBundles(caseBundles) .build(); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); // When: handler is called @@ -722,6 +740,9 @@ void should_do_naming_convention(String selected) { .applicant2(PartyBuilder.builder().individual().build()) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); given(coreCaseDataService.getCase(anyLong())).willReturn(CaseDetails.builder().build()); given(caseDetailsConverter.toCaseData(any(CaseDetails.class))).willReturn(caseDataBefore); @@ -858,6 +879,10 @@ void should_do_naming_convention_app2() { .documentCostsApp2(createEvidenceDocs(null, null)) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); // When handle is called var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -911,6 +936,9 @@ void shouldNotAddSameNotificationIfAlreadyAdded_notificationText() { .documentJointStatement(createExpertDocs("expertsName", witnessDate, null, "expertises", null, null, null)) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); given(coreCaseDataService.getCase(anyLong())).willReturn(CaseDetails.builder().build()); // When handle is called var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -935,6 +963,9 @@ void shouldNotPopulateNotificationWithOldDocument_whenNewDocumentUploadAdded() { .documentWitnessSummary(createWitnessDocs(witnessName, LocalDateTime.now(), witnessDate)) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); given(coreCaseDataService.getCase(anyLong())).willReturn(CaseDetails.builder().build()); // When handle is called var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandlerTest.java index 9aef6e555de..455cd043a2e 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandlerTest.java @@ -30,7 +30,6 @@ import uk.gov.hmcts.reform.ccd.client.model.SubmittedCallbackResponse; import uk.gov.hmcts.reform.civil.callback.CallbackHandler; import uk.gov.hmcts.reform.civil.callback.CallbackParams; -import uk.gov.hmcts.reform.civil.enums.CaseRole; import uk.gov.hmcts.reform.civil.enums.ClaimType; import uk.gov.hmcts.reform.civil.enums.caseprogression.EvidenceUploadExpert; import uk.gov.hmcts.reform.civil.enums.caseprogression.EvidenceUploadTrial; @@ -53,7 +52,7 @@ import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; import uk.gov.hmcts.reform.civil.service.Time; import uk.gov.hmcts.reform.civil.utils.ElementUtils; -import uk.gov.hmcts.reform.civil.utils.UserRoleCaching; +import uk.gov.hmcts.reform.idam.client.models.UserInfo; import static java.util.Map.entry; import static org.assertj.core.api.Assertions.assertThat; @@ -62,6 +61,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_START; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; @@ -105,9 +105,6 @@ class EvidenceUploadRespondentHandlerTest extends BaseCallbackHandlerTest { @MockBean private CaseDetailsConverter caseDetailsConverter; - @MockBean - private UserRoleCaching userRoleCaching; - @Autowired private final ObjectMapper mapper = new ObjectMapper(); @@ -145,9 +142,6 @@ class EvidenceUploadRespondentHandlerTest extends BaseCallbackHandlerTest { @BeforeEach void setup() { given(time.now()).willReturn(LocalDateTime.now()); - given(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) - .willReturn(List.of(RESPONDENTSOLICITORONE.getFormattedName())); - given(userRoleCaching.getCacheKeyToken(anyString())).willReturn("1234"); } @Test @@ -160,7 +154,8 @@ void givenAboutToStart_assignCaseProgAllocatedTrackUnSpec() { .statementOfValueInPennies(BigDecimal.valueOf(5000)) .build()) .build(); - + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), any())).willReturn(false); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_START); // When AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler @@ -178,7 +173,8 @@ void givenAboutToStart_assignCaseProgAllocatedTrackSpec() { .claimType(null) .totalClaimAmount(BigDecimal.valueOf(12500)) .build(); - + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), any())).willReturn(false); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_START); // When AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler @@ -242,8 +238,8 @@ void givenCreateShow_1v2DifferentSolicitorsWillChangeToRespondentTwoFlag() { .respondent2(PartyBuilder.builder().individual().build()) .respondent2SameLegalRepresentative(NO) .build(); - given(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) - .willReturn(List.of(RESPONDENTSOLICITORTWO.getFormattedName())); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(true); CallbackParams params = callbackParamsOf(caseData, MID, "createShowCondition"); // When AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler @@ -261,8 +257,8 @@ void givenCreateShow_1v2DifferentSolicitorsWillChangeToRespondentTwoFlagSpec() { .respondent2(PartyBuilder.builder().individual().build()) .respondent2SameLegalRepresentative(NO) .build(); - given(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) - .willReturn(List.of(RESPONDENTSOLICITORTWO.getFormattedName())); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(true); CallbackParams params = callbackParamsOf(caseData, MID, "createShowCondition"); // When AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler @@ -276,7 +272,8 @@ void givenCreateShow_1v1WillNotChangeToRespondentTwoFlag() { // Given CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build().toBuilder() .build(); - + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); CallbackParams params = callbackParamsOf(caseData, MID, "createShowCondition"); // When AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler @@ -336,7 +333,8 @@ static Stream optionsNotSelected() { void shouldSetWitnessFlag_whenWitnessOptionsAreSelected(CaseData caseData) { // Given CallbackParams params = callbackParamsOf(caseData, MID, "createShowCondition"); - + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); // When var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // Then @@ -350,7 +348,8 @@ void shouldSetWitnessFlag_whenWitnessOptionsAreSelected(CaseData caseData) { void shouldNotSetWitnessFlag_whenWitnessOptionsAreNotSelected(CaseData caseData) { // Given CallbackParams params = callbackParamsOf(caseData, MID, "createShowCondition"); - + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); // When var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // Then @@ -364,7 +363,8 @@ void shouldNotSetWitnessFlag_whenWitnessOptionsAreNotSelected(CaseData caseData) void shouldSetExpertFlag_whenExpertOptionsAreSelected(CaseData caseData) { // Given CallbackParams params = callbackParamsOf(caseData, MID, "createShowCondition"); - + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); // When var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // Then @@ -377,7 +377,8 @@ void shouldSetExpertFlag_whenExpertOptionsAreSelected(CaseData caseData) { void shouldNotSetExpertFlag_whenExpertOptionsAreNotSelected(CaseData caseData) { // Given CallbackParams params = callbackParamsOf(caseData, MID, "createShowCondition"); - + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); // When var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // Then @@ -390,7 +391,8 @@ void shouldNotSetExpertFlag_whenExpertOptionsAreNotSelected(CaseData caseData) { void shouldSetTrialFlag_whenTrialOptionsAreSelected(CaseData caseData) { // Given CallbackParams params = callbackParamsOf(caseData, MID, "createShowCondition"); - + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); // When var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // Then @@ -404,7 +406,8 @@ void shouldSetTrialFlag_whenTrialOptionsAreSelected(CaseData caseData) { void shouldNotSetTrialFlag_whenTrialOptionsAreNotSelected(CaseData caseData) { // Given CallbackParams params = callbackParamsOf(caseData, MID, "createShowCondition"); - + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); // When var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // Then @@ -1006,6 +1009,9 @@ void shouldCallExternalTask_whenAboutToSubmit() { CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(true); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -1032,8 +1038,8 @@ void shouldAssignCategoryID_whenDocumentExistsTwoRespondentSpec() { .addRespondent2(YES) .documentForDisclosureRes2(documentList) .build(); - given(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) - .willReturn(List.of(RESPONDENTSOLICITORTWO.getFormattedName())); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(true); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // When @@ -1059,8 +1065,8 @@ void shouldAssignCategoryID_whenDocumentExistsTwoRespondentUnSpec() { .addRespondent2(YES) .documentForDisclosureRes2(documentList) .build(); - given(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) - .willReturn(List.of(RESPONDENTSOLICITORTWO.getFormattedName())); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(true); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // When @@ -1086,7 +1092,9 @@ void shouldAssignCategoryID_whenDocumentExistsOneRespondentSpec() { .addRespondent2(NO) .documentAnswersRes(documentList) .build(); - + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(true); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // When @@ -1112,7 +1120,9 @@ void shouldAssignCategoryID_whenDocumentExistsOneRespondentUnSpec() { .addRespondent2(NO) .documentQuestionsRes(documentList) .build(); - + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(true); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // When @@ -1128,8 +1138,8 @@ void shouldNotAssignCategoryID_whenDocumentNotExistsTwoRespondent() { CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .addRespondent2(YES) .build(); - given(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) - .willReturn(List.of(CaseRole.APPLICANTSOLICITORONE.getFormattedName())); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(true); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // When @@ -1144,7 +1154,9 @@ void shouldNotAssignCategoryID_whenDocumentNotExistsOneRespondent() { CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .addRespondent2(NO) .build(); - + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(true); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // When @@ -1204,6 +1216,9 @@ void shouldAddRespondentEvidenceDocWhenBundleCreatedDateIsBeforeEvidenceUploaded .caseBundles(prepareCaseBundles(LocalDateTime.of(2022, 05, 10, 12, 12, 12))).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); // When handle is called var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -1222,6 +1237,9 @@ void shouldNotAddRespondentEvidenceDocWhenBundleCreatedDateIsAfterEvidenceUpload .caseBundles(prepareCaseBundles(LocalDateTime.of(2022, 05, 15, 12, 12, 12))).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); // When handle is called var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -1250,6 +1268,9 @@ void shouldBreakWhenThereIsAnyCaseBundlesWithoutCreatedDate() { .caseBundles(caseBundles) .build(); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(true); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); // When: handler is called @@ -1275,6 +1296,9 @@ void shouldBreakWhenThereIsAnyCaseBundlesWithNullCreatedDate() { .caseBundles(caseBundles) .build(); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(true); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); // When: handler is called @@ -1323,6 +1347,10 @@ void should_do_naming_convention_resp1(String selected) { .respondent2(PartyBuilder.builder().individual().build()) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(true); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); given(coreCaseDataService.getCase(anyLong())).willReturn(CaseDetails.builder().build()); given(caseDetailsConverter.toCaseData(any(CaseDetails.class))).willReturn(caseDataBefore); @@ -1455,8 +1483,10 @@ void should_do_naming_convention_resp2() { .documentCostsRes2(createEvidenceDocs(null, null)) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - given(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) - .willReturn(List.of(RESPONDENTSOLICITORTWO.getFormattedName())); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(false); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(true); // When handle is called var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -1510,8 +1540,9 @@ void shouldNotAddSameNotificationIfAlreadyAdded_notificationText() { .documentJointStatementRes(createExpertDocs("expertsName", witnessDate, null, "expertises", null, null, null)) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - given(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) - .willReturn(List.of(RESPONDENTSOLICITORONE.getFormattedName())); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(true); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); given(coreCaseDataService.getCase(anyLong())).willReturn(CaseDetails.builder().build()); // When handle is called var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -1536,8 +1567,9 @@ void shouldNotPopulateNotificationWithOldDocument_whenNewDocumentUploadAdded() { .documentWitnessSummaryRes(createWitnessDocs(witnessName, LocalDateTime.now(), witnessDate)) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - given(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) - .willReturn(List.of(RESPONDENTSOLICITORONE.getFormattedName())); + given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORONE))).willReturn(true); + given(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).willReturn(false); given(coreCaseDataService.getCase(anyLong())).willReturn(CaseDetails.builder().build()); // When handle is called var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/TrialReadinessCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/TrialReadinessCallbackHandlerTest.java index 1385919b3a5..66dbe5568ee 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/TrialReadinessCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/TrialReadinessCallbackHandlerTest.java @@ -19,7 +19,7 @@ import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.sampledata.CallbackParamsBuilder; import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; -import uk.gov.hmcts.reform.civil.utils.UserRoleCaching; +import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; import uk.gov.hmcts.reform.idam.client.models.UserInfo; import java.time.LocalDate; @@ -44,7 +44,7 @@ public class TrialReadinessCallbackHandlerTest extends BaseCallbackHandlerTest { private TrialReadinessCallbackHandler handler; @MockBean - private UserRoleCaching userRoleCaching; + private CoreCaseUserService coreCaseUserService; public static final String READY_HEADER = "## You have said this case is ready for trial or hearing"; public static final String READY_BODY = "### What happens next \n\n" @@ -61,22 +61,20 @@ public class TrialReadinessCallbackHandlerTest extends BaseCallbackHandlerTest { + "If you want the date of the hearing to be changed (or any other order to make the case ready for trial)" + "you will need to make an application to the court and pay the appropriate fee."; - @BeforeEach - public void setup() { - when(userRoleCaching.getCacheKeyToken(anyString())).thenReturn("1234"); - when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); - } - @Nested class AboutToStartCallback { + @BeforeEach + public void setup() { + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + } + @Test void shouldNotReturnError_WhenAboutToStartIsInvoked_ApplicantSolicitor() { //given: applicant solicitor logs in more than 3 weeks before hearing CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_START, caseData).build(); - - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.APPLICANTSOLICITORONE.getFormattedName())); //when: Event is started @@ -91,7 +89,7 @@ void shouldNotReturnError_WhenAboutToStartIsInvoked_Claimant() { //given: claimant logs in more than 3 weeks before hearing CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_START, caseData).build(); - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.CLAIMANT.getFormattedName())); //when: Event is started @@ -106,8 +104,7 @@ void shouldNotReturnError_WhenAboutToStartIsInvoked_RespondentSolicitor1() { //given: respondent 1 solicitor logs in more than 3 weeks before hearing CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_START, caseData).build(); - - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.RESPONDENTSOLICITORONE.getFormattedName())); //when: Event is started @@ -122,7 +119,7 @@ void shouldNotReturnError_WhenAboutToStartIsInvoked_Defendant() { //given: defendant logs in more than 3 weeks before hearing CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_START, caseData).build(); - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.DEFENDANT.getFormattedName())); //when: Event is started @@ -137,8 +134,7 @@ void shouldNotReturnError_WhenAboutToStartIsInvoked_RespondentSolicitor2() { //given: respondent 2 solicitor logs in more than 3 weeks before hearing CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_START, caseData).build(); - - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.RESPONDENTSOLICITORTWO.getFormattedName())); //when: Event is started @@ -154,8 +150,7 @@ void shouldReturnError_WhenAboutToStartIsInvokedWithinThreeWeeksOfHearingDate_Ap CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck() .hearingDate(LocalDate.now().plusWeeks(2).plusDays(6)).build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_START, caseData).build(); - - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.APPLICANTSOLICITORONE.getFormattedName())); //when: Event is started @@ -171,7 +166,7 @@ void shouldReturnError_WhenAboutToStartIsInvokedWithinThreeWeeksOfHearingDate_Cl CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck() .hearingDate(LocalDate.now().plusWeeks(2).plusDays(6)).build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_START, caseData).build(); - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.CLAIMANT.getFormattedName())); //when: Event is started @@ -187,8 +182,7 @@ void shouldReturnError_WhenAboutToStartIsInvokedWithinThreeWeeksOfHearingDate_Re CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck() .hearingDate(LocalDate.now().plusWeeks(2).plusDays(6)).build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_START, caseData).build(); - - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.RESPONDENTSOLICITORONE.getFormattedName())); //when: Event is started @@ -204,7 +198,7 @@ void shouldReturnError_WhenAboutToStartIsInvokedWithinThreeWeeksOfHearingDate_De CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck() .hearingDate(LocalDate.now().plusWeeks(2).plusDays(6)).build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_START, caseData).build(); - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.DEFENDANT.getFormattedName())); //when: Event is started @@ -220,8 +214,7 @@ void shouldReturnError_WhenAboutToStartIsInvokedWithinThreeWeeksOfHearingDate_Re CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck() .hearingDate(LocalDate.now().plusWeeks(2).plusDays(6)).build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_START, caseData).build(); - - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.RESPONDENTSOLICITORTWO.getFormattedName())); //when: Event is started @@ -245,8 +238,7 @@ void shouldTriggerApplicantNotifyOthers_WhenAboutToSubmitIsInvoked_ApplicantSoli CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build().toBuilder() .trialReadyApplicant(YesOrNo.YES).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.APPLICANTSOLICITORONE.getFormattedName())); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -262,8 +254,7 @@ void shouldTriggerApplicantNotifyOthers_WhenAboutToSubmitIsInvoked_Claimant() { CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build().toBuilder() .trialReadyApplicant(YesOrNo.YES).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.CLAIMANT.getFormattedName())); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -272,17 +263,14 @@ void shouldTriggerApplicantNotifyOthers_WhenAboutToSubmitIsInvoked_Claimant() { assertThat(response.getData()).extracting("businessProcess") .extracting("camundaEvent", "status") .containsOnly(CaseEvent.APPLICANT_TRIAL_READY_NOTIFY_OTHERS.name(), "READY"); - } @Test - void shouldTriggerRespondent1NotifyOthers_WhenAboutToSubmitIsInvoked_Respondent1Solicitor() { CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build().toBuilder() .trialReadyRespondent1(YesOrNo.YES).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.RESPONDENTSOLICITORONE.getFormattedName())); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -298,8 +286,7 @@ void shouldTriggerRespondent1NotifyOthers_WhenAboutToSubmitIsInvoked_Defendant() CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build().toBuilder() .trialReadyRespondent1(YesOrNo.YES).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.DEFENDANT.getFormattedName())); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -315,8 +302,7 @@ void shouldTriggerRespondent2NotifyOthers_WhenAboutToSubmitIsInvoked_Respondent2 CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build().toBuilder() .trialReadyRespondent2(YesOrNo.YES).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.RESPONDENTSOLICITORTWO.getFormattedName())); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -332,8 +318,7 @@ void shouldTriggerApplicantDocument_WhenAboutToSubmitIsInvoked_ApplicantSolicito CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build().toBuilder() .trialReadyApplicant(YesOrNo.NO).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.APPLICANTSOLICITORONE.getFormattedName())); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -349,8 +334,7 @@ void shouldTriggerApplicantDocument_WhenAboutToSubmitIsInvoked_Claimant() { CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build().toBuilder() .trialReadyApplicant(YesOrNo.NO).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.CLAIMANT.getFormattedName())); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -366,8 +350,7 @@ void shouldTriggerRespondent1Document_WhenAboutToSubmitIsInvoked_Respondent1Soli CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build().toBuilder() .trialReadyRespondent1(YesOrNo.NO).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.RESPONDENTSOLICITORONE.getFormattedName())); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -383,8 +366,7 @@ void shouldTriggerRespondent1Document_WhenAboutToSubmitIsInvoked_Defendant() { CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build().toBuilder() .trialReadyRespondent1(YesOrNo.NO).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.DEFENDANT.getFormattedName())); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -400,8 +382,7 @@ void shouldTriggerRespondent2Document_WhenAboutToSubmitIsInvoked_Respondent2Soli CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyCheck().build().toBuilder() .trialReadyRespondent2(YesOrNo.NO).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.RESPONDENTSOLICITORTWO.getFormattedName())); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -426,8 +407,7 @@ void shouldReturnConfirmationScreen_when1v1ReadySubmitted_ApplicantSolicitor() { //given: applicant solicitor selects Ready CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyApplicant().build(); CallbackParams params = CallbackParamsBuilder.builder().of(SUBMITTED, caseData).build(); - - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.APPLICANTSOLICITORONE.getFormattedName())); //when: Event is submitted @@ -446,12 +426,11 @@ void shouldReturnConfirmationScreen_when1v1ReadySubmitted_Claimant() { //given: claimant selects Ready CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyApplicant().build(); CallbackParams params = CallbackParamsBuilder.builder().of(SUBMITTED, caseData).build(); - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.CLAIMANT.getFormattedName())); //when: Event is submitted SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); - //then: header + body for the ready status get used in the confirmation assertThat(response).usingRecursiveComparison().isEqualTo( SubmittedCallbackResponse.builder() @@ -466,13 +445,11 @@ void shouldReturnConfirmationScreen_when1v1NotReadySubmitted_ApplicantSolicitor( //given: applicant solicitor selects Not Ready CaseData caseData = CaseDataBuilder.builder().atStateTrialNotReadyApplicant().build(); CallbackParams params = CallbackParamsBuilder.builder().of(SUBMITTED, caseData).build(); - - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.APPLICANTSOLICITORONE.getFormattedName())); //when: Event is submitted SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); - //then: header + body for the not ready status get used in the confirmation assertThat(response).usingRecursiveComparison().isEqualTo( SubmittedCallbackResponse.builder() @@ -487,12 +464,11 @@ void shouldReturnConfirmationScreen_when1v1NotReadySubmitted_Claimant() { //given: claimant selects Not Ready CaseData caseData = CaseDataBuilder.builder().atStateTrialNotReadyApplicant().build(); CallbackParams params = CallbackParamsBuilder.builder().of(SUBMITTED, caseData).build(); - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.CLAIMANT.getFormattedName())); //when: Event is submitted SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); - //then: header + body for the not ready status get used in the confirmation assertThat(response).usingRecursiveComparison().isEqualTo( SubmittedCallbackResponse.builder() @@ -507,13 +483,11 @@ void shouldReturnConfirmationScreen_when1v1ReadySubmitted_Respondent1Solicitor() //given: respondent 1 solicitor selects Ready CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyRespondent1().build(); CallbackParams params = CallbackParamsBuilder.builder().of(SUBMITTED, caseData).build(); - - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.RESPONDENTSOLICITORONE.getFormattedName())); //when: Event is submitted SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); - //then: header + body for the ready status get used in the confirmation assertThat(response).usingRecursiveComparison().isEqualTo( SubmittedCallbackResponse.builder() @@ -528,12 +502,11 @@ void shouldReturnConfirmationScreen_when1v1ReadySubmitted_Defendant() { //given: defendant selects Ready CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyRespondent1().build(); CallbackParams params = CallbackParamsBuilder.builder().of(SUBMITTED, caseData).build(); - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.DEFENDANT.getFormattedName())); //when: Event is submitted SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); - //then: header + body for the ready status get used in the confirmation assertThat(response).usingRecursiveComparison().isEqualTo( SubmittedCallbackResponse.builder() @@ -548,13 +521,11 @@ void shouldReturnConfirmationScreen_when1v1NotReadySubmitted_Respondent1Solicito //given: respondent 1 solicitor selects Not Ready CaseData caseData = CaseDataBuilder.builder().atStateTrialNotReadyRespondent1().build(); CallbackParams params = CallbackParamsBuilder.builder().of(SUBMITTED, caseData).build(); - - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.RESPONDENTSOLICITORONE.getFormattedName())); //when: Event is submitted SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); - //then: header + body for the not ready status get used in the confirmation assertThat(response).usingRecursiveComparison().isEqualTo( SubmittedCallbackResponse.builder() @@ -569,12 +540,11 @@ void shouldReturnConfirmationScreen_when1v1NotReadySubmitted_Defendant() { //given: defendant selects Not Ready CaseData caseData = CaseDataBuilder.builder().atStateTrialNotReadyRespondent1().build(); CallbackParams params = CallbackParamsBuilder.builder().of(SUBMITTED, caseData).build(); - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.DEFENDANT.getFormattedName())); //when: Event is submitted SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); - //then: header + body for the not ready status get used in the confirmation assertThat(response).usingRecursiveComparison().isEqualTo( SubmittedCallbackResponse.builder() @@ -589,8 +559,7 @@ void shouldReturnConfirmationScreen_when1v1ReadySubmitted_Respondent2Solicitor() //given: Respondent 2 selects Ready CaseData caseData = CaseDataBuilder.builder().atStateTrialReadyRespondent2().build(); CallbackParams params = CallbackParamsBuilder.builder().of(SUBMITTED, caseData).build(); - - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.RESPONDENTSOLICITORTWO.getFormattedName())); //when: Event is submitted @@ -609,8 +578,7 @@ void shouldReturnConfirmationScreen_when1v1NotReadySubmitted_Respondent2Solicito //given: Respondent 2 solicitor selects Not Ready CaseData caseData = CaseDataBuilder.builder().atStateTrialNotReadyRespondent2().build(); CallbackParams params = CallbackParamsBuilder.builder().of(SUBMITTED, caseData).build(); - - when(userRoleCaching.getUserRoles(anyString(), anyString(), anyString())) + when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())) .thenReturn(List.of(CaseRole.RESPONDENTSOLICITORTWO.getFormattedName())); //when: Event is submitted diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationServiceTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationServiceTest.java index 269c35c7add..3eabd89f790 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationServiceTest.java @@ -196,7 +196,7 @@ void shouldReturnTrue_whenRespondent1SolIsAssigned_1V1() { .respondent1OrganisationPolicy(respondent1Organization) .build(); List userRoles = new ArrayList<>(Arrays.asList("[APPLICANTSOLICITORONE]", "[RESPONDENTSOLICITORONE]")); - when(userRoleCaching.getUserRoles(any(), any(), any())).thenReturn(userRoles); + when(userRoleCaching.getUserRoles(any(), any())).thenReturn(userRoles); when(caseAccessDataStoreApi.getUserRoles(any(), any(), any())) .thenReturn(CaseAssignedUserRolesResource.builder() .caseAssignedUserRoles(applicant1Respondent1SolAssigned()).build()); @@ -227,7 +227,7 @@ void shouldReturnTrue_whenR1SolicitorsIsAssigned_1V2_SAME() { .respondent2OrganisationPolicy(respondent2Organization) .build(); List userRoles = new ArrayList<>(Arrays.asList("[APPLICANTSOLICITORONE]", "[RESPONDENTSOLICITORONE]")); - when(userRoleCaching.getUserRoles(any(), any(), any())).thenReturn(userRoles); + when(userRoleCaching.getUserRoles(any(), any())).thenReturn(userRoles); when(caseAccessDataStoreApi.getUserRoles(any(), any(), any())) .thenReturn(CaseAssignedUserRolesResource.builder() .caseAssignedUserRoles(applicant1Respondent1SolAssigned()).build()); @@ -244,7 +244,7 @@ void shouldReturnTrue_whenR1AndR2AreAssigned_1V2_SAME() { .respondent2OrganisationPolicy(respondent2Organization) .build(); List userRoles = new ArrayList<>(Arrays.asList("[APPLICANTSOLICITORONE]", "[RESPONDENTSOLICITORONE]", "[RESPONDENTSOLICITORTWO]")); - when(userRoleCaching.getUserRoles(any(), any(), any())).thenReturn(userRoles); + when(userRoleCaching.getUserRoles(any(), any())).thenReturn(userRoles); when(caseAccessDataStoreApi.getUserRoles(any(), any(), any())) .thenReturn(CaseAssignedUserRolesResource.builder() .caseAssignedUserRoles(applicant1Respondent1Respondent2SolAssigned()).build()); @@ -293,7 +293,7 @@ void shouldReturnTrue_whenR1R2SolsAreAssigned_1V2_DIFF() { .respondent2OrganisationPolicy(respondent2Organization) .build(); List userRoles = new ArrayList<>(Arrays.asList("[APPLICANTSOLICITORONE]", "[RESPONDENTSOLICITORONE]", "[RESPONDENTSOLICITORTWO]")); - when(userRoleCaching.getUserRoles(any(), any(), any())).thenReturn(userRoles); + when(userRoleCaching.getUserRoles(any(), any())).thenReturn(userRoles); when(caseAccessDataStoreApi.getUserRoles(any(), any(), any())) .thenReturn(CaseAssignedUserRolesResource.builder() .caseAssignedUserRoles(applicant1Respondent1Respondent2SolAssigned()).build()); @@ -868,7 +868,7 @@ void shouldReturnTrue_whenApplicantIsClaimantAtMainCase() { CaseData.CaseDataBuilder builder = caseData.toBuilder(); builder.applicant1OrganisationPolicy(OrganisationPolicy .builder().orgPolicyCaseAssignedRole("[APPLICANTSOLICITORONE]").build()); - when(userRoleCaching.getUserRoles(any(), any(), any())).thenReturn(userRoles); + when(userRoleCaching.getUserRoles(any(), any())).thenReturn(userRoles); when(caseAccessDataStoreApi.getUserRoles(any(), any(), any())) .thenReturn(CaseAssignedUserRolesResource.builder() .caseAssignedUserRoles(onlyApplicantSolicitorAssigned()).build()); @@ -886,7 +886,7 @@ void shouldReturnFalse_whenApplicantIsClaimantAtMainCase() { CaseData.CaseDataBuilder builder = caseData.toBuilder(); builder.applicant1OrganisationPolicy(OrganisationPolicy .builder().orgPolicyCaseAssignedRole("[APPLICANTSOLICITORONE]").build()); - when(userRoleCaching.getUserRoles(any(), any(), any())).thenReturn(userRoles); + when(userRoleCaching.getUserRoles(any(), any())).thenReturn(userRoles); when(caseAccessDataStoreApi.getUserRoles(any(), any(), any())) .thenReturn(CaseAssignedUserRolesResource.builder() .caseAssignedUserRoles(applicant1Respondent2SolAssigned()).build()); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/utils/UserRoleCachingTest.java b/src/test/java/uk/gov/hmcts/reform/civil/utils/UserRoleCachingTest.java deleted file mode 100644 index dcdcf254035..00000000000 --- a/src/test/java/uk/gov/hmcts/reform/civil/utils/UserRoleCachingTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package uk.gov.hmcts.reform.civil.utils; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; -import uk.gov.hmcts.reform.civil.service.UserService; -import uk.gov.hmcts.reform.idam.client.models.UserInfo; - -import java.util.ArrayList; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.when; - -@SpringBootTest(classes = { - UserRoleCaching.class, - CoreCaseUserService.class, - UserService.class -}) -public class UserRoleCachingTest { - - @MockBean - private CoreCaseUserService coreCaseUserService; - @MockBean - private UserService userService; - @Autowired - private UserRoleCaching userRoleCaching; - - @Test - void getUserRolesTest() { - List caseRoles = new ArrayList<>(); - caseRoles.add("[APPLICANTSOLICITORONE]"); - when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); - when(coreCaseUserService.getUserCaseRoles(anyString(), anyString())).thenReturn(caseRoles); - assertThat(userRoleCaching.getUserRoles("bearerToken", "ccdcase", "keyToken")) - .contains("[APPLICANTSOLICITORONE]"); - } - -} From 63d47db91157c3ea396062b13f60cad031989b92 Mon Sep 17 00:00:00 2001 From: dharmendra kumar Date: Fri, 10 Nov 2023 15:31:53 +0000 Subject: [PATCH 20/28] CIV-11367 Correct court location for LIPVLIP (#3510) * Correct court location for LIPVLIP * fixed unit test * fixed test error and updated unit test. * fixed review comment --------- Co-authored-by: neeta-hmcts Co-authored-by: neeta-hmcts <115545612+neeta-hmcts@users.noreply.github.com> Co-authored-by: jarekPierchala <118526007+jarekPierchala@users.noreply.github.com> Co-authored-by: Raja Mani --- .../ClaimantResponseCuiCallbackHandler.java | 16 ++- .../UpdateCaseManagementDetailsService.java | 118 ++++++++++++++++++ .../civil/utils/CourtLocationUtils.java | 2 +- ...laimantResponseCuiCallbackHandlerTest.java | 84 ++++++++++++- 4 files changed, 212 insertions(+), 8 deletions(-) create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/service/citizen/UpdateCaseManagementDetailsService.java diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandler.java index e00acfdeb49..b42f274c8df 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandler.java @@ -14,6 +14,7 @@ import uk.gov.hmcts.reform.civil.model.BusinessProcess; import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.service.citizenui.ResponseOneVOneShowTagService; +import uk.gov.hmcts.reform.civil.service.citizen.UpdateCaseManagementDetailsService; import java.time.LocalDateTime; import java.util.Collections; @@ -35,6 +36,7 @@ public class ClaimantResponseCuiCallbackHandler extends CallbackHandler { private final ResponseOneVOneShowTagService responseOneVOneService; private final ObjectMapper objectMapper; + private final UpdateCaseManagementDetailsService updateCaseManagementLocationDetailsService; @Override protected Map callbacks() { @@ -62,14 +64,16 @@ private CallbackResponse populateCaseData(CallbackParams callbackParams) { private CallbackResponse aboutToSubmit(CallbackParams callbackParams) { CaseData caseData = callbackParams.getCaseData(); - CaseData updatedData = caseData.toBuilder() - .applicant1ResponseDate(LocalDateTime.now()) - .businessProcess(BusinessProcess.ready(CLAIMANT_RESPONSE_CUI)) - .build(); + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .applicant1ResponseDate(LocalDateTime.now()) + .businessProcess(BusinessProcess.ready(CLAIMANT_RESPONSE_CUI)); + + updateCaseManagementLocationDetailsService.updateCaseManagementDetails(builder, callbackParams); + CaseData updatedData = builder.build(); AboutToStartOrSubmitCallbackResponse.AboutToStartOrSubmitCallbackResponseBuilder response = - AboutToStartOrSubmitCallbackResponse.builder() - .data(updatedData.toMap(objectMapper)); + AboutToStartOrSubmitCallbackResponse.builder() + .data(updatedData.toMap(objectMapper)); updateClaimEndState(response, updatedData); diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/citizen/UpdateCaseManagementDetailsService.java b/src/main/java/uk/gov/hmcts/reform/civil/service/citizen/UpdateCaseManagementDetailsService.java new file mode 100644 index 00000000000..b37adcba484 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/citizen/UpdateCaseManagementDetailsService.java @@ -0,0 +1,118 @@ +package uk.gov.hmcts.reform.civil.service.citizen; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.enums.MultiPartyScenario; +import uk.gov.hmcts.reform.civil.helpers.LocationHelper; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.CaseManagementCategory; +import uk.gov.hmcts.reform.civil.model.CaseManagementCategoryElement; +import uk.gov.hmcts.reform.civil.model.common.Element; +import uk.gov.hmcts.reform.civil.model.dq.RequestedCourt; +import uk.gov.hmcts.reform.civil.referencedata.LocationRefDataService; +import uk.gov.hmcts.reform.civil.referencedata.model.LocationRefData; +import uk.gov.hmcts.reform.civil.utils.CourtLocationUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import static uk.gov.hmcts.reform.civil.callback.CallbackParams.Params.BEARER_TOKEN; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.getMultiPartyScenario; +import static uk.gov.hmcts.reform.civil.utils.ElementUtils.element; + +@Slf4j +@Service +@RequiredArgsConstructor +public class UpdateCaseManagementDetailsService { + + private final LocationHelper locationHelper; + private final LocationRefDataService locationRefDataService; + private final CourtLocationUtils courtLocationUtils; + + public void updateCaseManagementDetails(CaseData.CaseDataBuilder builder, CallbackParams callbackParams) { + CaseData caseData = callbackParams.getCaseData(); + final List availableLocations = fetchLocationData(callbackParams); + + updateApplicant1RequestedCourtDetails(caseData, builder, availableLocations); + updateRespondent1RequestedCourtDetails(caseData, builder, availableLocations); + + caseData = builder.build(); + locationHelper.getCaseManagementLocation(caseData) + .ifPresent(requestedCourt -> locationHelper.updateCaseManagementLocation( + builder, + requestedCourt, + () -> locationRefDataService.getCourtLocationsForDefaultJudgments(callbackParams.getParams().get( + CallbackParams.Params.BEARER_TOKEN).toString()) + )); + + builder.caseNameHmctsInternal(caseParticipants(caseData).toString()); + + CaseManagementCategoryElement civil = + CaseManagementCategoryElement.builder().code("Civil").label("Civil").build(); + List> itemList = new ArrayList<>(); + itemList.add(element(civil)); + builder.caseManagementCategory( + CaseManagementCategory.builder().value(civil).list_items(itemList).build()); + + } + + private void updateApplicant1RequestedCourtDetails(CaseData caseData, CaseData.CaseDataBuilder builder, List availableLocations) { + Optional.ofNullable(caseData.getApplicant1DQ()) + .ifPresent(dq -> Optional.ofNullable(dq.getApplicant1DQRequestedCourt()) + .ifPresent(requestedCourt -> builder.applicant1DQ( + dq.toBuilder().applicant1DQRequestedCourt(correctCaseLocation(requestedCourt, availableLocations)) + .build()))); + } + + private void updateRespondent1RequestedCourtDetails(CaseData caseData, CaseData.CaseDataBuilder builder, List availableLocations) { + Optional.ofNullable(caseData.getRespondent1DQ()) + .ifPresent(dq -> Optional.ofNullable(dq.getRespondent1DQRequestedCourt()) + .ifPresent(requestedCourt -> builder.respondent1DQ( + dq.toBuilder().respondent1DQRequestedCourt(correctCaseLocation(requestedCourt, availableLocations)) + .build()))); + } + + private RequestedCourt correctCaseLocation(RequestedCourt requestedCourt, List locations) { + String locationLabel = requestedCourt.getCaseLocation().getBaseLocation(); + LocationRefData preferredLocation = locations.stream() + .filter(locationRefData -> courtLocationUtils.checkLocation(locationRefData, locationLabel)) + .findFirst().orElseThrow(RuntimeException::new); + return requestedCourt.toBuilder() + .responseCourtCode(preferredLocation.getCourtLocationCode()) + .caseLocation(LocationHelper.buildCaseLocation(preferredLocation)) + .build(); + } + + private List fetchLocationData(CallbackParams callbackParams) { + String authToken = callbackParams.getParams().get(BEARER_TOKEN).toString(); + return locationRefDataService.getCourtLocationsForDefaultJudgments(authToken); + } + + private StringBuilder caseParticipants(CaseData caseData) { + StringBuilder participantString = new StringBuilder(); + MultiPartyScenario multiPartyScenario = getMultiPartyScenario(caseData); + if (multiPartyScenario.equals(MultiPartyScenario.ONE_V_TWO_ONE_LEGAL_REP) + || multiPartyScenario.equals(MultiPartyScenario.ONE_V_TWO_TWO_LEGAL_REP)) { + participantString.append(caseData.getApplicant1().getPartyName()) + .append(" v ").append(caseData.getRespondent1().getPartyName()) + .append(" and ").append(caseData.getRespondent2().getPartyName()); + + } else if (multiPartyScenario.equals(MultiPartyScenario.TWO_V_ONE)) { + participantString.append(caseData.getApplicant1().getPartyName()) + .append(" and ").append(caseData.getApplicant2().getPartyName()) + .append(" v ") + .append(caseData.getRespondent1().getPartyName()); + + } else { + participantString.append(caseData.getApplicant1().getPartyName()) + .append(" v ") + .append(caseData.getRespondent1().getPartyName()); + } + return participantString; + + } + +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/utils/CourtLocationUtils.java b/src/main/java/uk/gov/hmcts/reform/civil/utils/CourtLocationUtils.java index ac70c9b2442..d1fae17737c 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/utils/CourtLocationUtils.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/utils/CourtLocationUtils.java @@ -35,7 +35,7 @@ public LocationRefData findPreferredLocationData(final List loc return preferredLocation.orElse(null); } - private Boolean checkLocation(final LocationRefData location, String locationTempLabel) { + public Boolean checkLocation(final LocationRefData location, String locationTempLabel) { String locationLabel = location.getSiteName() + " - " + location.getCourtAddress() + " - " + location.getPostcode(); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandlerTest.java index d2dfccfe6ee..8c889304389 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandlerTest.java @@ -1,6 +1,7 @@ package uk.gov.hmcts.reform.civil.handler.callback.user; import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -14,14 +15,29 @@ import uk.gov.hmcts.reform.civil.enums.CaseState; import uk.gov.hmcts.reform.civil.enums.MediationDecision; import uk.gov.hmcts.reform.civil.handler.callback.BaseCallbackHandlerTest; +import uk.gov.hmcts.reform.civil.helpers.LocationHelper; import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.model.Party; import uk.gov.hmcts.reform.civil.model.citizenui.CaseDataLiP; import uk.gov.hmcts.reform.civil.model.citizenui.ClaimantMediationLip; +import uk.gov.hmcts.reform.civil.model.defaultjudgment.CaseLocationCivil; +import uk.gov.hmcts.reform.civil.model.dq.Applicant1DQ; +import uk.gov.hmcts.reform.civil.model.dq.RequestedCourt; +import uk.gov.hmcts.reform.civil.model.dq.Respondent1DQ; +import uk.gov.hmcts.reform.civil.referencedata.LocationRefDataService; +import uk.gov.hmcts.reform.civil.referencedata.model.LocationRefData; import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; +import uk.gov.hmcts.reform.civil.service.citizen.UpdateCaseManagementDetailsService; import uk.gov.hmcts.reform.civil.service.citizenui.ResponseOneVOneShowTagService; +import uk.gov.hmcts.reform.civil.utils.CourtLocationUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_START; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.CLAIMANT_RESPONSE_CUI; @@ -33,12 +49,24 @@ @SpringBootTest(classes = { ClaimantResponseCuiCallbackHandler.class, JacksonAutoConfiguration.class, - ResponseOneVOneShowTagService.class + ResponseOneVOneShowTagService.class, + JacksonAutoConfiguration.class, + CourtLocationUtils.class, + LocationRefDataService.class, + LocationHelper.class, + UpdateCaseManagementDetailsService.class }) class ClaimantResponseCuiCallbackHandlerTest extends BaseCallbackHandlerTest { + @Autowired + private CourtLocationUtils courtLocationUtility; + @MockBean + private LocationHelper locationHelper; + @MockBean + private LocationRefDataService locationRefDataService; @Autowired private ClaimantResponseCuiCallbackHandler handler; + private static final String courtLocation = "Site 1 - Adr 1 - AAA 111"; @Autowired private final ObjectMapper mapper = new ObjectMapper(); @@ -63,9 +91,21 @@ void shouldReturnNoError_WhenAboutToStartIsInvoked() { @Nested class AboutToSubmitCallback { + @BeforeEach + void before() { + LocationRefData locationRefData = LocationRefData.builder().siteName("Site 1").courtAddress("Adr 1").postcode("AAA 111") + .courtName("Court Name").region("Region").regionId("1").courtVenueId("1") + .courtTypeId("10").courtLocationCode("court1") + .epimmsId("111").build(); + given(locationRefDataService.getCourtLocationsForDefaultJudgments(any())) + .willReturn(getSampleCourLocationsRefObject()); + given(locationHelper.updateCaseManagementLocation(any(), any(), any())).willReturn(Optional.ofNullable(locationRefData)); + } + @Test void shouldUpdateBusinessProcess() { CaseData caseData = CaseDataBuilder.builder() + .atStateClaimIssued1v1LiP() .caseDataLip( CaseDataLiP.builder() .applicant1ClaimMediationSpecRequiredLip( @@ -90,10 +130,28 @@ void shouldUpdateBusinessProcess() { @Test void shouldOnlyUpdateClaimStatus_whenPartAdmitNotSettled_NoMediation() { + Applicant1DQ applicant1DQ = + Applicant1DQ.builder().applicant1DQRequestedCourt(RequestedCourt.builder() + .responseCourtCode("court1") + .caseLocation(CaseLocationCivil.builder() + .region(courtLocation) + .baseLocation(courtLocation) + .build()) + .build()).build(); + Respondent1DQ respondent1DQ = + Respondent1DQ.builder().respondent1DQRequestedCourt(RequestedCourt.builder() + .responseCourtCode("court2") + .caseLocation(CaseLocationCivil.builder() + .region(courtLocation) + .baseLocation(courtLocation) + .build()) + .build()).build(); CaseData caseData = CaseDataBuilder.builder() .atStateClaimIssued() .applicant1PartAdmitConfirmAmountPaidSpec(NO) .applicant1PartAdmitIntentionToSettleClaimSpec(NO) + .applicant1DQ(applicant1DQ) + .respondent1DQ(respondent1DQ) .applicant1AcceptAdmitAmountPaidSpec(NO) .caseDataLip(CaseDataLiP.builder().applicant1ClaimMediationSpecRequiredLip(ClaimantMediationLip.builder().hasAgreedFreeMediation( MediationDecision.No).build()) @@ -112,6 +170,10 @@ void shouldOnlyUpdateClaimStatus_whenPartAdmitNotSettled_NoMediation() { .extracting("status") .isEqualTo("READY"); + assertThat(response.getState()).isEqualTo(CaseState.JUDICIAL_REFERRAL.name()); + CaseData data = mapper.convertValue(response.getData(), CaseData.class); + assertThat(data.getApplicant1DQ().getApplicant1DQRequestedCourt().getResponseCourtCode()).isEqualTo("court1"); + assertThat(data.getCaseNameHmctsInternal()).isEqualTo(data.getApplicant1().getPartyName() + " v " + data.getRespondent1().getPartyName()); } @Test @@ -130,6 +192,20 @@ void shouldChangeCaseState_whenApplicantRejectClaimSettlementAndAgreeToMediation assertThat(response.getState()).isEqualTo(CaseState.IN_MEDIATION.name()); } + protected List getSampleCourLocationsRefObject() { + return new ArrayList<>(List.of( + LocationRefData.builder() + .epimmsId("111").siteName("Site 1").courtAddress("Adr 1").postcode("AAA 111") + .courtLocationCode("court1").build(), + LocationRefData.builder() + .epimmsId("222").siteName("Site 2").courtAddress("Adr 2").postcode("BBB 222") + .courtLocationCode("court2").build(), + LocationRefData.builder() + .epimmsId("333").siteName("Site 3").courtAddress("Adr 3").postcode("CCC 333") + .courtLocationCode("court3").build() + )); + } + @Test void shouldChangeCaseState_whenApplicantRejectRepaymentPlanAndIsCompany_toAllFinalOrdersIssued() { CaseData caseData = CaseDataBuilder.builder() @@ -164,4 +240,10 @@ void shouldChangeCaseState_whenApplicantRejectRepaymentPlanAndIsOrganisation_toA assertThat(response.getState()).isEqualTo(CaseState.PROCEEDS_IN_HERITAGE_SYSTEM.name()); } } + + @Test + void handleEventsReturnsTheExpectedCallbackEvents() { + assertThat(handler.handledEvents()).containsOnly(CLAIMANT_RESPONSE_CUI); + } + } From 6a276fc21170f76343d4e538f578318b45558373 Mon Sep 17 00:00:00 2001 From: sherlynkhaw Date: Fri, 10 Nov 2023 16:27:37 +0000 Subject: [PATCH 21/28] CIV-9993 Hearing party MCI (#3285) * Added new ManageContactInformation callback handler and event and whitelisted it within the AllowedFlowState service. * Added new ManageContactInformation callback handler and event and whitelisted it within the AllowedFlowState service. * CIV-9992 add options for manage contact information * revert accidental commit * add utils test * update utils test * add test scenarios for handler * update handler tests * add IDs to party options * changed name of some variables * added chosenpartytype and chosenpartyid to determine what to show on page 2, wip on applicant/defendant pages * adding tests ManageContactInformationUtilsTest * changed some keys, updated tests * experts and witnesses form wip * show experts on ui * make id fields public * Cherry picked the 3 main commits from CIV-3216 Added partyID to dq witness and expert objects. Enabled the initialisation on party Ids in DQ witnesses and experts and copied partyIDs into their relative case level counterparts Moved changes behind hmc toggle Fixed duplicate append call * Updated experts and witnesses to have mappings * changed utils class back to static and removed mocks * Fixed witnesses * fixed litigation friend * fixed capability to delete all experts/witnesses and add new expert/witnesses when never existed before * postcode * removed unnecessary lines and imports * fixed data going missing for applicant 1 for party id * fixed claim details tab * added ccd data store image in charts * fixed test * Update values.preview.template.yaml --------- Co-authored-by: GarethLancaster <31533575+Gareth40342@users.noreply.github.com> Co-authored-by: sankaviv1 Co-authored-by: Gareth Lancaster <90632240+Gareth40343@users.noreply.github.com> Co-authored-by: TurkingtonL Co-authored-by: sankaviv1 <95748224+sankaviv1@users.noreply.github.com> Co-authored-by: AhsanZX97 --- ...nageContactInformationCallbackHandler.java | 325 +++++++++- .../reform/civil/model/CaseDataParent.java | 10 +- .../reform/civil/model/UpdateDetailsForm.java | 16 +- .../civil/model/UpdatePartyDetailsForm.java | 16 + .../utils/ManageContactInformationUtils.java | 230 ++++++- ...ContactInformationCallbackHandlerTest.java | 577 +++++++++++++++++- .../civil/sampledata/CaseDataBuilder.java | 4 +- .../ManageContactInformationUtilsTest.java | 256 +++++++- 8 files changed, 1362 insertions(+), 72 deletions(-) create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/model/UpdatePartyDetailsForm.java diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandler.java index 9183d1089c3..f7570b2557a 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandler.java @@ -6,37 +6,74 @@ 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.ccd.client.model.SubmittedCallbackResponse; 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.enums.MultiPartyScenario; +import uk.gov.hmcts.reform.civil.enums.YesOrNo; +import uk.gov.hmcts.reform.civil.helpers.CaseDetailsConverter; import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.LitigationFriend; +import uk.gov.hmcts.reform.civil.model.Party; import uk.gov.hmcts.reform.civil.model.UpdateDetailsForm; +import uk.gov.hmcts.reform.civil.model.UpdatePartyDetailsForm; import uk.gov.hmcts.reform.civil.model.common.DynamicList; import uk.gov.hmcts.reform.civil.model.common.DynamicListElement; +import uk.gov.hmcts.reform.civil.model.common.Element; +import uk.gov.hmcts.reform.civil.model.dq.Expert; +import uk.gov.hmcts.reform.civil.model.dq.Witness; import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; import uk.gov.hmcts.reform.civil.service.UserService; +import uk.gov.hmcts.reform.civil.validation.PostcodeValidator; import uk.gov.hmcts.reform.idam.client.models.UserInfo; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; - +import static java.lang.String.format; +import static java.util.Optional.ofNullable; import static uk.gov.hmcts.reform.civil.callback.CallbackParams.Params.BEARER_TOKEN; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_START; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; +import static uk.gov.hmcts.reform.civil.callback.CallbackType.MID; import static uk.gov.hmcts.reform.civil.callback.CallbackType.SUBMITTED; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.MANAGE_CONTACT_INFORMATION; +import static uk.gov.hmcts.reform.civil.enums.CaseCategory.SPEC_CLAIM; import static uk.gov.hmcts.reform.civil.enums.CaseState.AWAITING_APPLICANT_INTENTION; import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_TWO_LEGAL_REP; import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.getMultiPartyScenario; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; +import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.addApplicantExpertAndWitnessFlagsStructure; +import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.addRespondentDQPartiesFlagStructure; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_EXPERTS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_LITIGATION_FRIEND_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_WITNESSES_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_TWO_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_TWO_LITIGATION_FRIEND_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_EXPERTS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_LITIGATION_FRIEND_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_WITNESSES_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_EXPERTS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_LITIGATION_FRIEND_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_WITNESSES_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.addApplicant1Options; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.addApplicantOptions2v1; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.addDefendant1Options; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.addDefendant2Options; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.addDefendantOptions1v2SameSolicitor; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.appendUserAndType; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.mapExpertsToUpdatePartyDetailsForm; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.mapUpdatePartyDetailsFormToDQExperts; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.mapUpdatePartyDetailsFormToDQWitnesses; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.mapWitnessesToUpdatePartyDetailsForm; import static uk.gov.hmcts.reform.civil.utils.UserRoleUtils.isApplicantSolicitor; import static uk.gov.hmcts.reform.civil.utils.UserRoleUtils.isRespondentSolicitorOne; import static uk.gov.hmcts.reform.civil.utils.UserRoleUtils.isRespondentSolicitorTwo; @@ -47,6 +84,9 @@ public class ManageContactInformationCallbackHandler extends CallbackHandler { private static final String INVALID_CASE_STATE_ERROR = "You will be able run the manage contact information " + "event once the claimant has responded."; + private static final String CHECK_LITIGATION_FRIEND_ERROR_TITLE = "Check the litigation friend's details"; + private static final String CHECK_LITIGATION_FRIEND_ERROR = "After making these changes, please ensure that the " + + "litigation friend's contact information is also up to date."; private static final List ADMIN_ROLES = List.of( "caseworker-civil-admin"); private static final List EVENTS = List.of( @@ -56,13 +96,17 @@ public class ManageContactInformationCallbackHandler extends CallbackHandler { private final CoreCaseUserService coreCaseUserService; private final UserService userService; private final ObjectMapper objectMapper; + private final CaseDetailsConverter caseDetailsConverter; + private final PostcodeValidator postcodeValidator; @Override protected Map callbacks() { return new ImmutableMap.Builder() - .put(callbackKey(ABOUT_TO_START), this::validateUserCanTriggerEvent) - .put(callbackKey(ABOUT_TO_SUBMIT), this::emptyCallbackResponse) - .put(callbackKey(SUBMITTED), this::emptyCallbackResponse) + .put(callbackKey(ABOUT_TO_START), this::prepareEvent) + .put(callbackKey(MID, "show-party-field"), this::showPartyField) + .put(callbackKey(MID, "show-warning"), this::showWarning) + .put(callbackKey(ABOUT_TO_SUBMIT), this::submitChanges) + .put(callbackKey(SUBMITTED), this::buildConfirmation) .build(); } @@ -71,7 +115,8 @@ public List handledEvents() { return EVENTS; } - private CallbackResponse validateUserCanTriggerEvent(CallbackParams callbackParams) { + private CallbackResponse prepareEvent(CallbackParams callbackParams) { + //TODO: 1v2DS/SS -> LR to show LR org 1/2 dependning on MP CaseData caseData = callbackParams.getCaseData(); String authToken = callbackParams.getParams().get(BEARER_TOKEN).toString(); @@ -146,6 +191,276 @@ private CallbackResponse validateUserCanTriggerEvent(CallbackParams callbackPara .build(); } + private List> prepareExperts(String partyId, CaseData caseData) { + if (partyId.equals(CLAIMANT_ONE_EXPERTS_ID)) { + return mapExpertsToUpdatePartyDetailsForm(caseData.getApplicant1DQ().getExperts().getDetails()); + } else if (partyId.equals(DEFENDANT_ONE_EXPERTS_ID)) { + return mapExpertsToUpdatePartyDetailsForm(caseData.getRespondent1DQ().getExperts().getDetails()); + } else if (partyId.equals(DEFENDANT_TWO_EXPERTS_ID)) { + return mapExpertsToUpdatePartyDetailsForm(caseData.getRespondent2DQ().getExperts().getDetails()); + } + return Collections.emptyList(); + } + + private List> prepareWitnesses(String partyId, CaseData caseData) { + if (partyId.equals(CLAIMANT_ONE_WITNESSES_ID)) { + return mapWitnessesToUpdatePartyDetailsForm(caseData.getApplicant1DQ().getWitnesses().getDetails()); + } else if (partyId.equals(DEFENDANT_ONE_WITNESSES_ID)) { + return mapWitnessesToUpdatePartyDetailsForm(caseData.getRespondent1DQ().getWitnesses().getDetails()); + } else if (partyId.equals(DEFENDANT_TWO_WITNESSES_ID)) { + return mapWitnessesToUpdatePartyDetailsForm(caseData.getRespondent2DQ().getWitnesses().getDetails()); + } + return Collections.emptyList(); + } + + private String getPostCode(String partyChosen, CaseData caseData) { + switch (partyChosen) { + case CLAIMANT_ONE_ID: { + return getPartyPostCode(caseData.getApplicant1()); + } + case CLAIMANT_TWO_ID: { + return getPartyPostCode(caseData.getApplicant2()); + } + case DEFENDANT_ONE_ID: { + return getPartyPostCode(caseData.getRespondent1()); + } + case DEFENDANT_TWO_ID: { + return getPartyPostCode(caseData.getRespondent2()); + } + case CLAIMANT_ONE_LITIGATION_FRIEND_ID: { + return getPartyPostCode(caseData.getApplicant1LitigationFriend()); + } + case CLAIMANT_TWO_LITIGATION_FRIEND_ID: { + return getPartyPostCode(caseData.getApplicant2LitigationFriend()); + } + case DEFENDANT_ONE_LITIGATION_FRIEND_ID: { + return getPartyPostCode(caseData.getRespondent1LitigationFriend()); + } + case DEFENDANT_TWO_LITIGATION_FRIEND_ID: { + return getPartyPostCode(caseData.getRespondent2LitigationFriend()); + } + default: { + return null; + } + } + } + + private String getPartyPostCode(Party party) { + return party.getPrimaryAddress().getPostCode(); + } + + private String getPartyPostCode(LitigationFriend party) { + return party.getPrimaryAddress().getPostCode(); + } + + private CallbackResponse showWarning(CallbackParams callbackParams) { + CaseData caseData = callbackParams.getCaseData(); + CaseData.CaseDataBuilder caseDataBuilder = caseData.toBuilder(); + String partyChosen = caseData.getUpdateDetailsForm().getPartyChosen().getValue().getCode(); + ArrayList warnings = new ArrayList<>(); + List errors = new ArrayList<>(); + + if (partyHasLitigationFriend(partyChosen, caseData)) { + warnings.add(CHECK_LITIGATION_FRIEND_ERROR_TITLE); + warnings.add(CHECK_LITIGATION_FRIEND_ERROR); + } + + if (SPEC_CLAIM.equals(caseData.getCaseAccessCategory())) { + errors = postcodeValidator.validate(getPostCode(partyChosen, caseData)); + } + + return AboutToStartOrSubmitCallbackResponse.builder() + .data(caseDataBuilder.build().toMap(objectMapper)) + .warnings(warnings) + .errors(errors) + .build(); + } + + private Boolean partyHasLitigationFriend(String partyChosen, CaseData caseData) { + if (hasLitigationFriend(CLAIMANT_ONE_ID, partyChosen, caseData.getApplicant1LitigationFriendRequired()) + || hasLitigationFriend(CLAIMANT_TWO_ID, partyChosen, caseData.getApplicant2LitigationFriendRequired()) + || hasLitigationFriend(DEFENDANT_ONE_ID, partyChosen, caseData.getRespondent1LitigationFriend()) + || hasLitigationFriend(DEFENDANT_TWO_ID, partyChosen, caseData.getRespondent2LitigationFriend()) + ) { + return true; + } + return false; + } + + private Boolean hasLitigationFriend(String id, String partyChosen, YesOrNo litigationFriend) { + return id.equals(partyChosen) && YES.equals(litigationFriend); + } + + private Boolean hasLitigationFriend(String id, String partyChosen, LitigationFriend litigationFriend) { + return id.equals(partyChosen) && litigationFriend != null; + } + + private CallbackResponse showPartyField(CallbackParams callbackParams) { + CaseData caseData = callbackParams.getCaseData(); + CaseData.CaseDataBuilder builder = caseData.toBuilder(); + + String partyChosen = caseData.getUpdateDetailsForm().getPartyChosen().getValue().getCode(); + String partyChosenType = null; + + if (isParty(partyChosen) || isLitigationFriend(partyChosen)) { + // Party fields are empty in this mid event, this is a workaround + CaseData oldCaseData = caseDetailsConverter.toCaseData(callbackParams.getRequest().getCaseDetailsBefore()); + String authToken = callbackParams.getParams().get(BEARER_TOKEN).toString(); + boolean isAdmin = isAdmin(authToken); + partyChosenType = appendUserAndType(partyChosen, oldCaseData, isAdmin); + } + + UpdateDetailsForm.UpdateDetailsFormBuilder formBuilder = caseData.getUpdateDetailsForm().toBuilder() + .partyChosenId(partyChosen) + .partyChosenType(partyChosenType) + .updateExpertsDetailsForm(prepareExperts(partyChosen, caseData)) + .updateWitnessesDetailsForm(prepareWitnesses(partyChosen, caseData)) + .build().toBuilder(); + + builder.updateDetailsForm(formBuilder.build()); + + return AboutToStartOrSubmitCallbackResponse.builder() + .data(builder.build().toMap(objectMapper)) + .build(); + } + + private Boolean isParty(String partyChosen) { + return CLAIMANT_ONE_ID.equals(partyChosen) + || CLAIMANT_TWO_ID.equals(partyChosen) + || DEFENDANT_ONE_ID.equals(partyChosen) + || DEFENDANT_TWO_ID.equals(partyChosen); + } + + private Boolean isLitigationFriend(String partyChosen) { + return CLAIMANT_ONE_LITIGATION_FRIEND_ID.equals(partyChosen) + || CLAIMANT_TWO_LITIGATION_FRIEND_ID.equals(partyChosen) + || DEFENDANT_ONE_LITIGATION_FRIEND_ID.equals(partyChosen) + || DEFENDANT_TWO_LITIGATION_FRIEND_ID.equals(partyChosen); + } + + private CallbackResponse submitChanges(CallbackParams callbackParams) { + CaseData caseData = callbackParams.getCaseData(); + CaseData.CaseDataBuilder builder = caseData.toBuilder(); + + updateExperts(caseData.getUpdateDetailsForm().getPartyChosenId(), caseData, builder); + updateWitnesses(caseData.getUpdateDetailsForm().getPartyChosenId(), caseData, builder); + + // clear updateDetailsForm + builder.updateDetailsForm(UpdateDetailsForm.builder().manageContactDetailsEventUsed(YES).build()); + + // update claim details tab + updateClaimDetailsTab(caseData, builder); + + return AboutToStartOrSubmitCallbackResponse.builder() + .data(builder.build().toMap(objectMapper)) + .build(); + } + + private void updateClaimDetailsTab(CaseData caseData, CaseData.CaseDataBuilder builder) { + builder.respondent1DetailsForClaimDetailsTab(caseData.getRespondent1().toBuilder().flags(null).build()); + + if (ofNullable(caseData.getRespondent2()).isPresent()) { + builder.respondent2DetailsForClaimDetailsTab(caseData.getRespondent2().toBuilder().flags(null).build()); + } + } + + // wip can't be tested yet because need to get ids from new ticket: CIV-10382 + // have to delete experts (yes/no etc) if the experts are removed, same as witnesses + + private void updateExperts(String partyId, CaseData caseData, CaseData.CaseDataBuilder builder) { + List> formData = caseData.getUpdateDetailsForm().getUpdateExpertsDetailsForm(); + List> mappedExperts; + + if (partyId.equals(CLAIMANT_ONE_EXPERTS_ID)) { + mappedExperts = mapUpdatePartyDetailsFormToDQExperts( + caseData.getApplicant1DQ().getApplicant1DQExperts().getDetails(), formData); + builder.applicant1DQ(caseData.getApplicant1DQ().toBuilder() + .applicant1DQExperts( + caseData.getApplicant1DQ().getApplicant1DQExperts().toBuilder() + .expertRequired(mappedExperts.size() >= 1 ? YES : NO) + .details(mappedExperts) + .build()) + .build()); + addApplicantExpertAndWitnessFlagsStructure(builder, caseData); + //TODO: need to add it to top level party object + } else if (partyId.equals(DEFENDANT_ONE_EXPERTS_ID)) { + mappedExperts = mapUpdatePartyDetailsFormToDQExperts( + caseData.getRespondent1DQ().getRespondent1DQExperts().getDetails(), formData); + builder.respondent1DQ(caseData.getRespondent1DQ().toBuilder() + .respondent1DQExperts( + caseData.getRespondent1DQ().getRespondent1DQExperts().toBuilder() + .expertRequired(mappedExperts.size() >= 1 ? YES : NO) + .details(mappedExperts) + .build()) + .build()); + addRespondentDQPartiesFlagStructure(builder, caseData); + //TODO: need to add it to top level party object + } else if (partyId.equals(DEFENDANT_TWO_EXPERTS_ID)) { + mappedExperts = mapUpdatePartyDetailsFormToDQExperts( + caseData.getRespondent2DQ().getRespondent2DQExperts().getDetails(), formData); + builder.respondent2DQ(caseData.getRespondent2DQ().toBuilder() + .respondent2DQExperts( + caseData.getRespondent2DQ().getRespondent2DQExperts().toBuilder() + .expertRequired(mappedExperts.size() >= 1 ? YES : NO) + .details(mappedExperts) + .build()) + .build()); + addRespondentDQPartiesFlagStructure(builder, caseData); + //TODO: need to add it to top level party object + } + + } + + private void updateWitnesses(String partyId, CaseData caseData, CaseData.CaseDataBuilder builder) { + List> formData = caseData.getUpdateDetailsForm().getUpdateWitnessesDetailsForm(); + List> mappedWitnesses; + + if (partyId.equals(CLAIMANT_ONE_WITNESSES_ID)) { + mappedWitnesses = mapUpdatePartyDetailsFormToDQWitnesses( + caseData.getApplicant1DQ().getApplicant1DQWitnesses().getDetails(), formData); + builder.applicant1DQ(caseData.getApplicant1DQ().toBuilder() + .applicant1DQWitnesses( + caseData.getApplicant1DQ().getApplicant1DQWitnesses().toBuilder() + .witnessesToAppear(mappedWitnesses.size() >= 1 ? YES : NO) + .details(mappedWitnesses) + .build()) + .build()); + addApplicantExpertAndWitnessFlagsStructure(builder, caseData); + //TODO: need to add it to top level party object + } else if (partyId.equals(DEFENDANT_ONE_WITNESSES_ID)) { + mappedWitnesses = mapUpdatePartyDetailsFormToDQWitnesses( + caseData.getRespondent1DQ().getRespondent1DQWitnesses().getDetails(), formData); + builder.respondent1DQ(caseData.getRespondent1DQ().toBuilder() + .respondent1DQWitnesses( + caseData.getRespondent1DQ().getRespondent1DQWitnesses().toBuilder() + .witnessesToAppear(mappedWitnesses.size() >= 1 ? YES : NO) + .details(mappedWitnesses) + .build()) + .build()); + addRespondentDQPartiesFlagStructure(builder, caseData); + //TODO: need to add it to top level party object + } else if (partyId.equals(DEFENDANT_TWO_WITNESSES_ID)) { + mappedWitnesses = mapUpdatePartyDetailsFormToDQWitnesses( + caseData.getRespondent2DQ().getRespondent2DQWitnesses().getDetails(), formData); + builder.respondent2DQ(caseData.getRespondent2DQ().toBuilder() + .respondent2DQWitnesses( + caseData.getRespondent2DQ().getRespondent2DQWitnesses().toBuilder() + .witnessesToAppear(mappedWitnesses.size() >= 1 ? YES : NO) + .details(mappedWitnesses) + .build()) + .build()); + addRespondentDQPartiesFlagStructure(builder, caseData); + //TODO: need to add it to top level party object + } + } + + private SubmittedCallbackResponse buildConfirmation(CallbackParams callbackParams) { + return SubmittedCallbackResponse.builder() + .confirmationHeader(format("# Contact information changed")) + .confirmationBody(format("### What happens next\nAny changes made to contact details have been updated in the Claim Details tab.")) + .build(); + } + private boolean isAwaitingClaimantIntention(CaseData caseData) { return caseData.getCcdState().equals(AWAITING_APPLICANT_INTENTION); } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseDataParent.java b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseDataParent.java index e5b1329495e..7d2a5546ce9 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseDataParent.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseDataParent.java @@ -534,9 +534,13 @@ public boolean isApplicantNotRepresented() { private final List> applicantWitnesses; private final List> respondent1Witnesses; private final List> respondent2Witnesses; - private final List> applicantSolOrgIndividuals; - private final List> respondent1SolOrgIndividuals; - private final List> applicant1SolOrgIndividuals; + private final List> applicant1LRIndividuals; + private final List> respondent1LRIndividuals; + private final List> respondent2LRIndividuals; + private final List> applicant1OrgIndividuals; + private final List> applicant2OrgIndividuals; + private final List> respondent1OrgIndividuals; + private final List> respondent2OrgIndividuals; private List disposalHearingDisclosureOfDocumentsDJToggle; private List disposalHearingWitnessOfFactDJToggle; diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/UpdateDetailsForm.java b/src/main/java/uk/gov/hmcts/reform/civil/model/UpdateDetailsForm.java index 82f48651bb7..33b489f1fec 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/UpdateDetailsForm.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/UpdateDetailsForm.java @@ -1,6 +1,5 @@ package uk.gov.hmcts.reform.civil.model; -import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -11,17 +10,18 @@ import java.util.List; @Data -@Builder +@Builder(toBuilder = true) @NoArgsConstructor @AllArgsConstructor public class UpdateDetailsForm { - @JsonProperty("partyChosen") private DynamicList partyChosen; - - @JsonProperty("additionalUnavailableDates") - private List> additionalUnavailableDates; - - @JsonProperty("hidePartyChoice") + private String partyChosenId; + private String partyChosenType; private YesOrNo hidePartyChoice; + private List> additionalUnavailableDates; + private List> updateExpertsDetailsForm; + private List> updateWitnessesDetailsForm; + private YesOrNo manageContactDetailsEventUsed; } + diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/UpdatePartyDetailsForm.java b/src/main/java/uk/gov/hmcts/reform/civil/model/UpdatePartyDetailsForm.java new file mode 100644 index 00000000000..5955d276a92 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/UpdatePartyDetailsForm.java @@ -0,0 +1,16 @@ +package uk.gov.hmcts.reform.civil.model; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder(toBuilder = true) +public class UpdatePartyDetailsForm { + + private String firstName; + private String lastName; + private String phoneNumber; + private String emailAddress; + private String partyId; + private String fieldOfExpertise; +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/utils/ManageContactInformationUtils.java b/src/main/java/uk/gov/hmcts/reform/civil/utils/ManageContactInformationUtils.java index 5967810fb19..83ff6136dd6 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/utils/ManageContactInformationUtils.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/utils/ManageContactInformationUtils.java @@ -2,16 +2,22 @@ import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.model.Party; +import uk.gov.hmcts.reform.civil.model.UpdatePartyDetailsForm; import uk.gov.hmcts.reform.civil.model.common.DynamicListElement; +import uk.gov.hmcts.reform.civil.model.common.Element; +import uk.gov.hmcts.reform.civil.model.dq.Expert; import uk.gov.hmcts.reform.civil.model.dq.Experts; +import uk.gov.hmcts.reform.civil.model.dq.Witness; import uk.gov.hmcts.reform.civil.model.dq.Witnesses; - +import java.time.LocalDate; +import java.util.ArrayList; import java.util.List; - import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; import static uk.gov.hmcts.reform.civil.model.Party.Type.COMPANY; import static uk.gov.hmcts.reform.civil.model.Party.Type.ORGANISATION; import static uk.gov.hmcts.reform.civil.model.common.DynamicListElement.dynamicElementFromCode; +import static uk.gov.hmcts.reform.civil.utils.ElementUtils.unwrapElements; +import static uk.gov.hmcts.reform.civil.utils.ElementUtils.wrapElements; public class ManageContactInformationUtils { @@ -34,30 +40,30 @@ private ManageContactInformationUtils() { private static final String ORG_INDIVIDUALS = "Individuals attending for the organisation"; private static final String LEGAL_REP_INDIVIDUALS = "Individuals attending for the legal representative"; - private static final String CLAIMANT_ONE_ID = "CLAIMANT_1"; - private static final String CLAIMANT_ONE_LITIGATION_FRIEND_ID = "CLAIMANT_1_LITIGATIONFRIEND"; - private static final String CLAIMANT_ONE_LEGAL_REP_INDIVIDUALS_ID = "CLAIMANT_1_INDIVIDUALSSOLICITORORG"; - private static final String CLAIMANT_ONE_ORG_INDIVIDUALS_ID = "CLAIMANT_1_INDIVIDUALSORG"; - private static final String CLAIMANT_ONE_WITNESSES_ID = "CLAIMANT_1_WITNESSES"; - private static final String CLAIMANT_ONE_EXPERTS_ID = "CLAIMANT_1_EXPERTS"; - - private static final String CLAIMANT_TWO_ID = "CLAIMANT_2"; - private static final String CLAIMANT_TWO_LITIGATION_FRIEND_ID = "CLAIMANT_2_LITIGATIONFRIEND"; - private static final String CLAIMANT_TWO_ORG_INDIVIDUALS_ID = "CLAIMANT_1_INDIVIDUALSORG"; - - private static final String DEFENDANT_ONE_ID = "DEFENDANT_1"; - private static final String DEFENDANT_ONE_LITIGATION_FRIEND_ID = "DEFENDANT_1_LITIGATIONFRIEND"; - private static final String DEFENDANT_ONE_LEGAL_REP_INDIVIDUALS_ID = "DEFENDANT_1_INDIVIDUALSSOLICITORORG"; - private static final String DEFENDANT_ONE_ORG_INDIVIDUALS_ID = "DEFENDANT_1_INDIVIDUALSORG"; - private static final String DEFENDANT_ONE_WITNESSES_ID = "DEFENDANT_1_WITNESSES"; - private static final String DEFENDANT_ONE_EXPERTS_ID = "DEFENDANT_1_EXPERTS"; - - private static final String DEFENDANT_TWO_ID = "DEFENDANT_2"; - private static final String DEFENDANT_TWO_LITIGATION_FRIEND_ID = "DEFENDANT_2_LITIGATIONFRIEND"; - private static final String DEFENDANT_TWO_LEGAL_REP_INDIVIDUALS_ID = "DEFENDANT_2_INDIVIDUALSSOLICITORORG"; - private static final String DEFENDANT_TWO_ORG_INDIVIDUALS_ID = "DEFENDANT_2_INDIVIDUALSORG"; - private static final String DEFENDANT_TWO_WITNESSES_ID = "DEFENDANT_2_WITNESSES"; - private static final String DEFENDANT_TWO_EXPERTS_ID = "DEFENDANT_2_EXPERTS"; + public static final String CLAIMANT_ONE_ID = "CLAIMANT_1"; + public static final String CLAIMANT_ONE_LITIGATION_FRIEND_ID = "CLAIMANT_1_LITIGATION_FRIEND"; + public static final String CLAIMANT_ONE_LEGAL_REP_INDIVIDUALS_ID = "CLAIMANT_1_LR_INDIVIDUALS"; + public static final String CLAIMANT_ONE_ORG_INDIVIDUALS_ID = "CLAIMANT_1_ORGANISATION_INDIVIDUALS"; + public static final String CLAIMANT_ONE_WITNESSES_ID = "CLAIMANT_1_WITNESSES"; + public static final String CLAIMANT_ONE_EXPERTS_ID = "CLAIMANT_1_EXPERTS"; + + public static final String CLAIMANT_TWO_ID = "CLAIMANT_2"; + public static final String CLAIMANT_TWO_LITIGATION_FRIEND_ID = "CLAIMANT_2_LITIGATION_FRIEND"; + public static final String CLAIMANT_TWO_ORG_INDIVIDUALS_ID = "CLAIMANT_2_ORGANISATION_INDIVIDUALS"; + + public static final String DEFENDANT_ONE_ID = "DEFENDANT_1"; + public static final String DEFENDANT_ONE_LITIGATION_FRIEND_ID = "DEFENDANT_1_LITIGATION_FRIEND"; + public static final String DEFENDANT_ONE_LEGAL_REP_INDIVIDUALS_ID = "DEFENDANT_1_LR_INDIVIDUALS"; + public static final String DEFENDANT_ONE_ORG_INDIVIDUALS_ID = "DEFENDANT_1_ORGANISATION_INDIVIDUALS"; + public static final String DEFENDANT_ONE_WITNESSES_ID = "DEFENDANT_1_WITNESSES"; + public static final String DEFENDANT_ONE_EXPERTS_ID = "DEFENDANT_1_EXPERTS"; + + public static final String DEFENDANT_TWO_ID = "DEFENDANT_2"; + public static final String DEFENDANT_TWO_LITIGATION_FRIEND_ID = "DEFENDANT_2_LITIGATION_FRIEND"; + public static final String DEFENDANT_TWO_LEGAL_REP_INDIVIDUALS_ID = "DEFENDANT_2_LR_INDIVIDUALS"; + public static final String DEFENDANT_TWO_ORG_INDIVIDUALS_ID = "DEFENDANT_2_ORGANISATION_INDIVIDUALS"; + public static final String DEFENDANT_TWO_WITNESSES_ID = "DEFENDANT_2_WITNESSES"; + public static final String DEFENDANT_TWO_EXPERTS_ID = "DEFENDANT_2_EXPERTS"; public static void addApplicant1Options(List list, CaseData caseData, boolean isAdmin) { addApplicant1PartyOptions(list, caseData); @@ -95,6 +101,178 @@ public static void addDefendant2Options(List list, CaseData addDefendant2ExpertsAndWitnesses(list, caseData, isAdmin); } + public static String appendUserAndType(String partyChosen, CaseData caseData, boolean isAdmin) { + String user = isAdmin ? "ADMIN" : "LR"; + + switch (partyChosen) { + case (CLAIMANT_ONE_ID): { + return formatId(partyChosen, user, caseData.getApplicant1()); + } + case(CLAIMANT_TWO_ID): { + return formatId(partyChosen, user, caseData.getApplicant2()); + } + case (DEFENDANT_ONE_ID): { + return formatId(partyChosen, user, caseData.getRespondent1()); + } + case(DEFENDANT_TWO_ID): { + return formatId(partyChosen, user, caseData.getRespondent2()); + } + case(CLAIMANT_ONE_LITIGATION_FRIEND_ID): + case(CLAIMANT_TWO_LITIGATION_FRIEND_ID): + case(DEFENDANT_ONE_LITIGATION_FRIEND_ID): + case(DEFENDANT_TWO_LITIGATION_FRIEND_ID): { + return formatId(partyChosen, user); + } + default: { + throw new IllegalArgumentException("Manage Contact Information party chosen ID does not exist"); + } + } + } + + public static List> mapExpertsToUpdatePartyDetailsForm(List> experts) { + List> newExperts = new ArrayList<>(); + + if (experts != null) { + for (Element party : experts) { + Expert expert = party.getValue(); + newExperts.addAll(wrapElements(UpdatePartyDetailsForm.builder() + .firstName(expert.getFirstName()) + .lastName(expert.getLastName()) + .emailAddress(expert.getEmailAddress()) + .phoneNumber(expert.getPhoneNumber()) + .fieldOfExpertise(expert.getFieldOfExpertise()) + .partyId(expert.getPartyID()) //this will need to be added in new ticket + .build())); + } + } + return newExperts; + } + + public static List> mapUpdatePartyDetailsFormToDQExperts(List> existingDQExperts, List> formExperts) { + List> newExperts = new ArrayList<>(); + List experts = unwrapElements(existingDQExperts); + + if (formExperts != null) { + for (Element form : formExperts) { + UpdatePartyDetailsForm formExpert = form.getValue(); + + Expert dqExpert = experts.stream() + .filter(e -> e.getPartyID().equals(formExpert.getPartyId())) + .findFirst() + .orElse(null); + + if (dqExpert != null && dqExpert.getPartyID() != null) { + // if id already exists in dq + newExperts.addAll(wrapElements(dqExpert.toBuilder() + .firstName(formExpert.getFirstName()) + .lastName(formExpert.getLastName()) + .emailAddress(formExpert.getEmailAddress()) + .phoneNumber(formExpert.getPhoneNumber()) + .fieldOfExpertise(formExpert.getFieldOfExpertise()) + .build())); + } else { + // if id doesn't exist in dq means it is a newly added expert + newExperts.addAll(wrapElements(Expert.builder() + .firstName(formExpert.getFirstName()) + .lastName(formExpert.getLastName()) + .emailAddress(formExpert.getEmailAddress()) + .phoneNumber(formExpert.getPhoneNumber()) + .fieldOfExpertise(formExpert.getFieldOfExpertise()) + .dateAdded(LocalDate.now()) + .eventAdded("Manage Contact Information Event") + .partyID(null) //CIV-10382 + .build())); + // Replace above to this in CIV-10382 + // newExperts.addAll(wrapElements(appendWithNewPartyIds(Expert.builder() + // .firstName(formExpert.getFirstName()) + // .lastName(formExpert.getLastName()) + // .emailAddress(formExpert.getEmailAddress()) + // .phoneNumber(formExpert.getPhoneNumber()) + // .fieldOfExpertise(formExpert.getFieldOfExpertise()) + // .dateAdded(LocalDate.now()) + // .eventAdded("Manage Contact Information Event") + // .build()))); + } + } + } + + return newExperts; + } + + public static List> mapWitnessesToUpdatePartyDetailsForm(List> witnesses) { + List> newWitnesses = new ArrayList<>(); + + if (witnesses != null) { + for (Element party : witnesses) { + Witness witness = party.getValue(); + newWitnesses.addAll(wrapElements(UpdatePartyDetailsForm.builder() + .firstName(witness.getFirstName()) + .lastName(witness.getLastName()) + .emailAddress(witness.getEmailAddress()) + .phoneNumber(witness.getPhoneNumber()) + .partyId(witness.getPartyID()) + .build())); + } + } + return newWitnesses; + } + + public static List> mapUpdatePartyDetailsFormToDQWitnesses(List> existingDQWitnesses, List> formWitnesses) { + List> newWitnesses = new ArrayList<>(); + List witnesses = unwrapElements(existingDQWitnesses); + + if (formWitnesses != null) { + for (Element form : formWitnesses) { + UpdatePartyDetailsForm formWitness = form.getValue(); + + Witness dqWitness = witnesses.stream() + .filter(w -> w.getPartyID().equals(formWitness.getPartyId())) + .findFirst() + .orElse(null); + + // if id already exists in dq + if (dqWitness != null && dqWitness.getPartyID() != null) { + newWitnesses.addAll(wrapElements(dqWitness.toBuilder() + .firstName(formWitness.getFirstName()) + .lastName(formWitness.getLastName()) + .emailAddress(formWitness.getEmailAddress()) + .phoneNumber(formWitness.getPhoneNumber()) + .build())); + } else { + // if id doesn't exist in dq means it is a newly added witness + newWitnesses.addAll(wrapElements(Witness.builder() + .firstName(formWitness.getFirstName()) + .lastName(formWitness.getLastName()) + .emailAddress(formWitness.getEmailAddress()) + .phoneNumber(formWitness.getPhoneNumber()) + .dateAdded(LocalDate.now()) + .eventAdded("Manage Contact Information Event") + .partyID(null) //CIV-10382 + .build())); + // Replace above to this in CIV-10382 + // newWitnesses.addAll(wrapElements(appendWithNewPartyIds(Witness.builder() + // .firstName(formWitness.getFirstName()) + // .lastName(formWitness.getLastName()) + // .emailAddress(formWitness.getEmailAddress()) + // .phoneNumber(formWitness.getPhoneNumber()) + // .dateAdded(LocalDate.now()) + // .eventAdded("Manage Contact Information Event") + // .build()))); + } + } + } + + return newWitnesses; + } + + private static String formatId(String partyChosen, String isAdmin, Party party) { + return String.format("%s_%s_%s", partyChosen, isAdmin, party.getType().toString()); + } + + private static String formatId(String partyChosen, String isAdmin) { + return String.format("%s_%s", partyChosen, isAdmin); + } + private static void addApplicant1PartyOptions(List list, CaseData caseData) { // applicant 1 party name list.add(dynamicElementFromCode(CLAIMANT_ONE_ID, diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandlerTest.java index 832084cce8f..de083369ffa 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandlerTest.java @@ -4,40 +4,79 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; 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.AboutToStartOrSubmitCallbackResponse; +import uk.gov.hmcts.reform.ccd.client.model.CaseDetails; import uk.gov.hmcts.reform.civil.callback.CallbackParams; import uk.gov.hmcts.reform.civil.callback.CallbackType; +import uk.gov.hmcts.reform.civil.enums.CaseCategory; import uk.gov.hmcts.reform.civil.enums.CaseState; import uk.gov.hmcts.reform.civil.enums.RespondentResponseType; import uk.gov.hmcts.reform.civil.handler.callback.BaseCallbackHandlerTest; import uk.gov.hmcts.reform.civil.helpers.CaseDetailsConverter; +import uk.gov.hmcts.reform.civil.model.Address; import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.model.Party; +import uk.gov.hmcts.reform.civil.model.UpdateDetailsForm; +import uk.gov.hmcts.reform.civil.model.UpdatePartyDetailsForm; +import uk.gov.hmcts.reform.civil.model.common.DynamicList; +import uk.gov.hmcts.reform.civil.model.common.DynamicListElement; +import uk.gov.hmcts.reform.civil.model.common.Element; +import uk.gov.hmcts.reform.civil.model.dq.Applicant1DQ; +import uk.gov.hmcts.reform.civil.model.dq.Expert; +import uk.gov.hmcts.reform.civil.model.dq.Experts; +import uk.gov.hmcts.reform.civil.model.dq.Respondent1DQ; +import uk.gov.hmcts.reform.civil.model.dq.Respondent2DQ; +import uk.gov.hmcts.reform.civil.model.dq.Witness; +import uk.gov.hmcts.reform.civil.model.dq.Witnesses; import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; +import uk.gov.hmcts.reform.civil.validation.PostcodeValidator; import uk.gov.hmcts.reform.idam.client.models.UserInfo; - +import java.time.LocalDate; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.BDDMockito.given; 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.callback.CallbackType.SUBMITTED; +import static uk.gov.hmcts.reform.civil.callback.CallbackType.MID; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; import static uk.gov.hmcts.reform.civil.model.Party.Type.COMPANY; +import static uk.gov.hmcts.reform.civil.model.Party.Type.INDIVIDUAL; import static uk.gov.hmcts.reform.civil.utils.DynamicListUtils.listFromDynamicList; +import static uk.gov.hmcts.reform.civil.utils.ElementUtils.unwrapElements; +import static uk.gov.hmcts.reform.civil.utils.ElementUtils.wrapElements; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_EXPERTS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_LITIGATION_FRIEND_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_WITNESSES_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_TWO_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_TWO_LITIGATION_FRIEND_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_EXPERTS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_LITIGATION_FRIEND_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_WITNESSES_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_EXPERTS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_LITIGATION_FRIEND_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_WITNESSES_ID; @SpringBootTest(classes = { ManageContactInformationCallbackHandler.class, JacksonAutoConfiguration.class, - CaseDetailsConverter.class + CaseDetailsConverter.class, + PostcodeValidator.class }) class ManageContactInformationCallbackHandlerTest extends BaseCallbackHandlerTest { @@ -50,6 +89,12 @@ class ManageContactInformationCallbackHandlerTest extends BaseCallbackHandlerTes @MockBean private CoreCaseUserService coreCaseUserService; + @MockBean + private CaseDetailsConverter caseDetailsConverter; + + @MockBean + private PostcodeValidator postcodeValidator; + private static final UserInfo ADMIN_USER = UserInfo.builder() .roles(List.of("caseworker-civil-admin")) .uid("uid") @@ -664,31 +709,537 @@ void shouldReturnExpectedList_WhenInvokedFor1v2DifferentSolicitorAsRespondentSol @Nested class AboutToSubmit { + UpdatePartyDetailsForm party; + Expert dqExpert; + Expert expectedExpert1; + Witness dqWitness; + Witness expectedWitness1; + + @BeforeEach + void setup() { + party = UpdatePartyDetailsForm.builder().firstName("First").lastName("Name").build(); + dqExpert = Expert.builder().partyID("id").firstName("dq").lastName("dq").build(); + expectedExpert1 = dqExpert.builder().firstName("First").lastName("Name") + .eventAdded("Manage Contact Information Event").dateAdded(LocalDate.now()) + .partyID(null) //change this for CIV-10382 + .build(); + dqWitness = Witness.builder().firstName("dq").lastName("dq").partyID("id").build(); + expectedWitness1 = Witness.builder().firstName("First").lastName("Name") + .eventAdded("Manage Contact Information Event").dateAdded(LocalDate.now()) + .partyID(null).build(); // CIV-10382 + } @Test - void shouldReturnExpectedResponse_WhenAboutToSubmitIsInvoked() { - CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build(); + void shouldUpdateApplicantOneExperts() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .updateDetailsForm(UpdateDetailsForm.builder() + .partyChosen(DynamicList.builder() + .value(DynamicListElement.builder() + .code(CLAIMANT_ONE_EXPERTS_ID) + .build()) + .build()) + .partyChosenId(CLAIMANT_ONE_EXPERTS_ID) + .updateExpertsDetailsForm(wrapElements(party)) + .build()) + .applicant1DQ(Applicant1DQ.builder() + .applicant1DQExperts(Experts.builder().details(wrapElements(dqExpert)).build()) + .build()) + .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler .handle(params); - assertEquals(AboutToStartOrSubmitCallbackResponse.builder().build(), response); + CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); + assertThat(unwrapElements(updatedData.getApplicant1DQ().getApplicant1DQExperts().getDetails()).get(0)).isEqualTo(expectedExpert1); } - } - @Nested - class Submitted { + @Test + void shouldUpdateDefendantOneExperts() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .updateDetailsForm(UpdateDetailsForm.builder() + .partyChosen(DynamicList.builder() + .value(DynamicListElement.builder() + .code(DEFENDANT_ONE_EXPERTS_ID) + .build()) + .build()) + .partyChosenId(DEFENDANT_ONE_EXPERTS_ID) + .updateExpertsDetailsForm(wrapElements(party)) + .build()) + .respondent1DQ(Respondent1DQ.builder() + .respondent1DQExperts(Experts.builder().details(wrapElements(dqExpert)).build()) + .build()) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler + .handle(params); + + CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); + assertThat(unwrapElements(updatedData.getRespondent1DQ().getRespondent1DQExperts().getDetails()).get(0)).isEqualTo(expectedExpert1); + } @Test - void shouldReturnExpectedResponse_WhenSubmittedIsInvoked() { - CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build(); - CallbackParams params = callbackParamsOf(caseData, SUBMITTED); + void shouldUpdateDefendantTwoExperts() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .updateDetailsForm(UpdateDetailsForm.builder() + .partyChosen(DynamicList.builder() + .value(DynamicListElement.builder() + .code(DEFENDANT_TWO_EXPERTS_ID) + .build()) + .build()) + .partyChosenId(DEFENDANT_TWO_EXPERTS_ID) + .updateExpertsDetailsForm(wrapElements(party)) + .build()) + .respondent2DQ(Respondent2DQ.builder() + .respondent2DQExperts(Experts.builder().details(wrapElements(dqExpert)).build()) + .build()) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler .handle(params); - assertEquals(AboutToStartOrSubmitCallbackResponse.builder().build(), response); + CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); + assertThat(unwrapElements(updatedData.getRespondent2DQ().getRespondent2DQExperts().getDetails()).get(0)).isEqualTo(expectedExpert1); + } + + @Test + void shouldUpdateApplicantOneWitnesses() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .updateDetailsForm(UpdateDetailsForm.builder() + .partyChosen(DynamicList.builder() + .value(DynamicListElement.builder() + .code(CLAIMANT_ONE_WITNESSES_ID) + .build()) + .build()) + .partyChosenId(CLAIMANT_ONE_WITNESSES_ID) + .updateWitnessesDetailsForm(wrapElements(party)) + .build()) + .applicant1DQ(Applicant1DQ.builder() + .applicant1DQWitnesses(Witnesses.builder().details(wrapElements(dqWitness)).build()) + .build()) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler + .handle(params); + + CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); + assertThat(unwrapElements(updatedData.getApplicant1DQ().getApplicant1DQWitnesses().getDetails()).get(0)).isEqualTo(expectedWitness1); + } + + @Test + void shouldUpdateDefendantOneWitnesses() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .updateDetailsForm(UpdateDetailsForm.builder() + .partyChosen(DynamicList.builder() + .value(DynamicListElement.builder() + .code(DEFENDANT_ONE_WITNESSES_ID) + .build()) + .build()) + .partyChosenId(DEFENDANT_ONE_WITNESSES_ID) + .updateWitnessesDetailsForm(wrapElements(party)) + .build()) + .respondent1DQ(Respondent1DQ.builder() + .respondent1DQWitnesses(Witnesses.builder().details(wrapElements(dqWitness)).build()) + .build()) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler + .handle(params); + + CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); + assertThat(unwrapElements(updatedData.getRespondent1DQ().getRespondent1DQWitnesses().getDetails()).get(0)).isEqualTo(expectedWitness1); + } + + @Test + void shouldUpdateDefendantTwoWitnesses() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .updateDetailsForm(UpdateDetailsForm.builder() + .partyChosen(DynamicList.builder() + .value(DynamicListElement.builder() + .code(DEFENDANT_TWO_WITNESSES_ID) + .build()) + .build()) + .partyChosenId(DEFENDANT_TWO_WITNESSES_ID) + .updateWitnessesDetailsForm(wrapElements(party)) + .build()) + .respondent2DQ(Respondent2DQ.builder() + .respondent2DQWitnesses(Witnesses.builder().details(wrapElements(dqWitness)).build()) + .build()) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler + .handle(params); + + CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); + assertThat(unwrapElements(updatedData.getRespondent2DQ().getRespondent2DQWitnesses().getDetails()).get(0)).isEqualTo(expectedWitness1); + } + + @Test + void addingExpertWhenNoneExisted() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .updateDetailsForm(UpdateDetailsForm.builder() + .partyChosen(DynamicList.builder() + .value(DynamicListElement.builder() + .code(CLAIMANT_ONE_EXPERTS_ID) + .build()) + .build()) + .partyChosenId(CLAIMANT_ONE_EXPERTS_ID) + .updateExpertsDetailsForm(wrapElements(party)) + .build()) + .applicant1DQ(Applicant1DQ.builder() + .applicant1DQExperts(Experts.builder() + .expertRequired(NO) + .build()) + .build()) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler + .handle(params); + + CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); + assertThat(unwrapElements(updatedData.getApplicant1DQ().getApplicant1DQExperts().getDetails()).get(0)).isEqualTo(expectedExpert1); + assertThat(updatedData.getApplicant1DQ().getApplicant1DQExperts().getExpertRequired()).isEqualTo(YES); + } + + @Test + void removingAllExperts() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .updateDetailsForm(UpdateDetailsForm.builder() + .partyChosen(DynamicList.builder() + .value(DynamicListElement.builder() + .code(CLAIMANT_ONE_EXPERTS_ID) + .build()) + .build()) + .partyChosenId(CLAIMANT_ONE_EXPERTS_ID) + .updateExpertsDetailsForm(null) + .build()) + .applicant1DQ(Applicant1DQ.builder() + .applicant1DQExperts(Experts.builder() + .expertRequired(YES) + .details(wrapElements(dqExpert)).build()) + .build()) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler + .handle(params); + + CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); + assertThat(unwrapElements(updatedData.getApplicant1DQ().getApplicant1DQExperts().getDetails())).isEmpty(); + assertThat(updatedData.getApplicant1DQ().getApplicant1DQExperts().getExpertRequired()).isEqualTo(NO); + } + + @Test + void addingWitnessWhenNoneExisted() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .updateDetailsForm(UpdateDetailsForm.builder() + .partyChosen(DynamicList.builder() + .value(DynamicListElement.builder() + .code(DEFENDANT_ONE_WITNESSES_ID) + .build()) + .build()) + .partyChosenId(DEFENDANT_ONE_WITNESSES_ID) + .updateWitnessesDetailsForm(wrapElements(party)) + .build()) + .respondent1DQ(Respondent1DQ.builder() + .respondent1DQWitnesses(Witnesses.builder().witnessesToAppear(NO).build()) + .build()) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler + .handle(params); + + CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); + assertThat(unwrapElements(updatedData.getRespondent1DQ().getRespondent1DQWitnesses().getDetails()).get(0)).isEqualTo(expectedWitness1); + assertThat(updatedData.getRespondent1DQ().getRespondent1DQWitnesses().getWitnessesToAppear()).isEqualTo(YES); + } + + @Test + void removingAllWitnesses() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .updateDetailsForm(UpdateDetailsForm.builder() + .partyChosen(DynamicList.builder() + .value(DynamicListElement.builder() + .code(DEFENDANT_ONE_WITNESSES_ID) + .build()) + .build()) + .partyChosenId(DEFENDANT_ONE_WITNESSES_ID) + .updateWitnessesDetailsForm(null) + .build()) + .respondent1DQ(Respondent1DQ.builder() + .respondent1DQWitnesses(Witnesses.builder() + .details(wrapElements(dqWitness)) + .witnessesToAppear(YES).build()) + .build()) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler + .handle(params); + + CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); + assertThat(unwrapElements(updatedData.getRespondent1DQ().getRespondent1DQWitnesses().getDetails())).isEmpty(); + assertThat(updatedData.getRespondent1DQ().getRespondent1DQWitnesses().getWitnessesToAppear()).isEqualTo(NO); + } + } + + @Nested + class MidShowWarning { + private static final String PAGE_ID = "show-warning"; + + @ParameterizedTest + @ValueSource(strings = {CLAIMANT_ONE_ID, CLAIMANT_TWO_ID, DEFENDANT_ONE_ID, DEFENDANT_TWO_ID}) + void shouldReturnWarning(String partyChosenId) { + String errorTitle = "Check the litigation friend's details"; + String errorMessage = "After making these changes, please ensure that the " + + "litigation friend's contact information is also up to date."; + + CaseData caseData = CaseDataBuilder.builder() + .updateDetailsForm(UpdateDetailsForm.builder() + .partyChosen(DynamicList.builder() + .value(DynamicListElement.builder() + .code(partyChosenId) + .build()) + .build()) + .build()) + .addApplicant1LitigationFriend() + .addApplicant2LitigationFriend() + .addRespondent1LitigationFriend() + .addRespondent2LitigationFriend() + .build(); + CallbackParams params = callbackParamsOf(caseData, MID, PAGE_ID); + + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + assertThat(response.getWarnings()).contains(errorTitle); + assertThat(response.getWarnings()).contains(errorMessage); + } + + @ParameterizedTest + @ValueSource(strings = {CLAIMANT_ONE_ID, CLAIMANT_TWO_ID, DEFENDANT_ONE_ID, DEFENDANT_TWO_ID, DEFENDANT_ONE_LITIGATION_FRIEND_ID}) + void shouldNotReturnWarning(String partyChosenId) { + CaseData caseData = CaseDataBuilder.builder() + .updateDetailsForm(UpdateDetailsForm.builder() + .partyChosen(DynamicList.builder() + .value(DynamicListElement.builder() + .code(partyChosenId) + .build()) + .build()) + .build()) + .build(); + + CallbackParams params = callbackParamsOf(caseData, MID, PAGE_ID); + + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + assertThat(response.getWarnings()).isEmpty(); + } + + @Test + void shouldReturnPostcodeError() { + given(postcodeValidator.validate(any())).willReturn(List.of("Please enter Postcode")); + + CaseData caseData = CaseDataBuilder.builder() + .caseAccessCategory(CaseCategory.SPEC_CLAIM) + .updateDetailsForm(UpdateDetailsForm.builder() + .partyChosen(DynamicList.builder() + .value(DynamicListElement.builder() + .code(CLAIMANT_ONE_ID) + .build()) + .build()) + .build()) + .applicant1(Party.builder() + .type(INDIVIDUAL) + .primaryAddress(Address.builder() + .postCode(null) + .build()) + .build()) + .build(); + CallbackParams params = callbackParamsOf(caseData, MID, PAGE_ID); + + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + assertThat(response.getErrors()).isNotNull(); + assertEquals(1, response.getErrors().size()); + assertEquals("Please enter Postcode", response.getErrors().get(0)); + } + } + + @Nested + class MidShowPartyField { + private static final String PAGE_ID = "show-party-field"; + + @Test + void shouldPopulatePartyChosenId() { + CaseData caseData = CaseDataBuilder.builder() + .updateDetailsForm(UpdateDetailsForm.builder() + .partyChosen(DynamicList.builder() + .value(DynamicListElement.builder() + .code("CODE") + .build()) + .build()) + .build()) + .build(); + CallbackParams params = callbackParamsOf(caseData, MID, PAGE_ID); + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); + assertThat(updatedData.getUpdateDetailsForm().getPartyChosenId()).isEqualTo("CODE"); + assertThat(updatedData.getUpdateDetailsForm().getPartyChosenType()).isEqualTo(null); + assertThat(updatedData.getUpdateDetailsForm().getUpdateExpertsDetailsForm()).isEmpty(); + assertThat(updatedData.getUpdateDetailsForm().getUpdateWitnessesDetailsForm()).isEmpty(); + } + + @ParameterizedTest + @ValueSource(strings = {CLAIMANT_ONE_ID, CLAIMANT_TWO_ID, DEFENDANT_ONE_ID, DEFENDANT_TWO_ID}) + void shouldPopulatePartyType(String partyChosenId) { + when(userService.getUserInfo(anyString())).thenReturn(ADMIN_USER); + CaseData caseDataBefore = CaseDataBuilder.builder() + .applicant1(Party.builder().type(INDIVIDUAL).build()) + .applicant2(Party.builder().type(INDIVIDUAL).build()) + .respondent1(Party.builder().type(INDIVIDUAL).build()) + .respondent2(Party.builder().type(INDIVIDUAL).build()) + .buildClaimIssuedPaymentCaseData(); + given(caseDetailsConverter.toCaseData(any(CaseDetails.class))).willReturn(caseDataBefore); + + CaseData caseData = CaseDataBuilder.builder() + .updateDetailsForm(UpdateDetailsForm.builder() + .partyChosen(DynamicList.builder() + .value(DynamicListElement.builder() + .code(partyChosenId) + .build()) + .build()) + .build()) + .build(); + CallbackParams params = callbackParamsOf(caseData, MID, PAGE_ID); + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); + assertThat(updatedData.getUpdateDetailsForm().getPartyChosenId()).isEqualTo(partyChosenId); + assertThat(updatedData.getUpdateDetailsForm().getPartyChosenType()).isEqualTo(partyChosenId + "_ADMIN_INDIVIDUAL"); + assertThat(updatedData.getUpdateDetailsForm().getUpdateExpertsDetailsForm()).isEmpty(); + assertThat(updatedData.getUpdateDetailsForm().getUpdateWitnessesDetailsForm()).isEmpty(); + } + + @ParameterizedTest + @ValueSource(strings = {CLAIMANT_ONE_LITIGATION_FRIEND_ID, CLAIMANT_TWO_LITIGATION_FRIEND_ID, DEFENDANT_ONE_LITIGATION_FRIEND_ID, DEFENDANT_TWO_LITIGATION_FRIEND_ID}) + void shouldPopulatePartyTypeForLitigationFriend(String partyChosenId) { + when(userService.getUserInfo(anyString())).thenReturn(LEGAL_REP_USER); + CaseData caseDataBefore = CaseDataBuilder.builder() + .applicant1(Party.builder().type(INDIVIDUAL).build()) + .applicant2(Party.builder().type(INDIVIDUAL).build()) + .respondent1(Party.builder().type(INDIVIDUAL).build()) + .respondent2(Party.builder().type(INDIVIDUAL).build()) + .buildClaimIssuedPaymentCaseData(); + given(caseDetailsConverter.toCaseData(any(CaseDetails.class))).willReturn(caseDataBefore); + + CaseData caseData = CaseDataBuilder.builder() + .updateDetailsForm(UpdateDetailsForm.builder() + .partyChosen(DynamicList.builder() + .value(DynamicListElement.builder() + .code(partyChosenId) + .build()) + .build()) + .build()) + .build(); + CallbackParams params = callbackParamsOf(caseData, MID, PAGE_ID); + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); + assertThat(updatedData.getUpdateDetailsForm().getPartyChosenId()).isEqualTo(partyChosenId); + assertThat(updatedData.getUpdateDetailsForm().getPartyChosenType()).isEqualTo(partyChosenId + "_LR"); + assertThat(updatedData.getUpdateDetailsForm().getUpdateExpertsDetailsForm()).isEmpty(); + assertThat(updatedData.getUpdateDetailsForm().getUpdateWitnessesDetailsForm()).isEmpty(); + } + + @ParameterizedTest + @ValueSource(strings = {CLAIMANT_ONE_EXPERTS_ID, DEFENDANT_ONE_EXPERTS_ID, DEFENDANT_TWO_EXPERTS_ID}) + void shouldPopulateExperts(String partyChosenId) { + when(userService.getUserInfo(anyString())).thenReturn(ADMIN_USER); + Expert expert = Expert.builder().firstName("First").lastName("Name").partyID("id").build(); + UpdatePartyDetailsForm party = UpdatePartyDetailsForm.builder().firstName("First").lastName("Name") + .partyId("id").build(); + List> form = wrapElements(party); + + CaseData caseData = CaseDataBuilder.builder() + .applicant1DQ(Applicant1DQ.builder() + .applicant1DQExperts(Experts.builder().details(wrapElements(expert)).build()) + .build()) + .respondent1DQ(Respondent1DQ.builder() + .respondent1DQExperts(Experts.builder().details(wrapElements(expert)).build()) + .build()) + .respondent2DQ(Respondent2DQ.builder() + .respondent2DQExperts(Experts.builder().details(wrapElements(expert)).build()) + .build()) + .updateDetailsForm(UpdateDetailsForm.builder() + .partyChosen(DynamicList.builder() + .value(DynamicListElement.builder() + .code(partyChosenId) + .build()) + .build()) + .build()) + .build(); + CallbackParams params = callbackParamsOf(caseData, MID, PAGE_ID); + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); + assertThat(updatedData.getUpdateDetailsForm().getPartyChosenId()).isEqualTo(partyChosenId); + assertThat(updatedData.getUpdateDetailsForm().getPartyChosenType()).isEqualTo(null); + assertThat(updatedData.getUpdateDetailsForm().getUpdateExpertsDetailsForm()).isEqualTo(form); + assertThat(updatedData.getUpdateDetailsForm().getUpdateWitnessesDetailsForm()).isEmpty(); + + } + + @ParameterizedTest + @ValueSource(strings = {CLAIMANT_ONE_WITNESSES_ID, DEFENDANT_ONE_WITNESSES_ID, DEFENDANT_TWO_WITNESSES_ID}) + void shouldPopulateWitnesses(String partyChosenId) { + Witness witness = Witness.builder().firstName("First").lastName("Name").partyID("id").build(); + UpdatePartyDetailsForm party = UpdatePartyDetailsForm.builder().firstName("First").lastName("Name") + .partyId("id").build(); + List> form = wrapElements(party); + + CaseData caseData = CaseDataBuilder.builder() + .applicant1DQ(Applicant1DQ.builder() + .applicant1DQWitnesses(Witnesses.builder().details(wrapElements(witness)).build()) + .build()) + .respondent1DQ(Respondent1DQ.builder() + .respondent1DQWitnesses(Witnesses.builder().details(wrapElements(witness)).build()) + .build()) + .respondent2DQ(Respondent2DQ.builder() + .respondent2DQWitnesses(Witnesses.builder().details(wrapElements(witness)).build()) + .build()) + .updateDetailsForm(UpdateDetailsForm.builder() + .partyChosen(DynamicList.builder() + .value(DynamicListElement.builder() + .code(partyChosenId) + .build()) + .build()) + .build()) + .build(); + CallbackParams params = callbackParamsOf(caseData, MID, PAGE_ID); + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); + assertThat(updatedData.getUpdateDetailsForm().getPartyChosenId()).isEqualTo(partyChosenId); + assertThat(updatedData.getUpdateDetailsForm().getPartyChosenType()).isEqualTo(null); + assertThat(updatedData.getUpdateDetailsForm().getUpdateExpertsDetailsForm()).isEmpty(); + assertThat(updatedData.getUpdateDetailsForm().getUpdateWitnessesDetailsForm()).isEqualTo(form); + } } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilder.java b/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilder.java index f6b96b180f4..4b2a4a05581 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilder.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilder.java @@ -6076,8 +6076,8 @@ public CaseDataBuilder claimantUserDetails(IdamUserDetails claimantUserDetails) return this; } - public CaseDataBuilder updateDetailsForm(UpdateDetailsForm additionalDates) { - this.updateDetailsForm = additionalDates; + public CaseDataBuilder updateDetailsForm(UpdateDetailsForm form) { + this.updateDetailsForm = form; return this; } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/utils/ManageContactInformationUtilsTest.java b/src/test/java/uk/gov/hmcts/reform/civil/utils/ManageContactInformationUtilsTest.java index f8fc3f207cb..ac5effba420 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/utils/ManageContactInformationUtilsTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/utils/ManageContactInformationUtilsTest.java @@ -1,11 +1,16 @@ package uk.gov.hmcts.reform.civil.utils; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.model.Party; +import uk.gov.hmcts.reform.civil.model.UpdatePartyDetailsForm; import uk.gov.hmcts.reform.civil.model.common.DynamicListElement; +import uk.gov.hmcts.reform.civil.model.dq.Expert; +import uk.gov.hmcts.reform.civil.model.dq.Witness; import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; - +import java.math.BigDecimal; +import java.time.LocalDate; import java.util.ArrayList; import java.util.List; @@ -14,13 +19,26 @@ import static uk.gov.hmcts.reform.civil.enums.RespondentResponseType.FULL_DEFENCE; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; import static uk.gov.hmcts.reform.civil.model.Party.Type.COMPANY; +import static uk.gov.hmcts.reform.civil.model.Party.Type.INDIVIDUAL; import static uk.gov.hmcts.reform.civil.model.Party.Type.ORGANISATION; +import static uk.gov.hmcts.reform.civil.model.Party.Type.SOLE_TRADER; import static uk.gov.hmcts.reform.civil.model.common.DynamicListElement.dynamicElementFromCode; +import static uk.gov.hmcts.reform.civil.utils.ElementUtils.wrapElements; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_LITIGATION_FRIEND_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_TWO_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_LITIGATION_FRIEND_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.addApplicant1Options; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.addApplicantOptions2v1; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.addDefendant1Options; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.addDefendant2Options; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.addDefendantOptions1v2SameSolicitor; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.appendUserAndType; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.mapExpertsToUpdatePartyDetailsForm; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.mapUpdatePartyDetailsFormToDQExperts; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.mapUpdatePartyDetailsFormToDQWitnesses; class ManageContactInformationUtilsTest { @@ -246,11 +264,219 @@ void shouldAddCorrectOptions_forDefendant1v2SameSolicitorAsAdmin() { assertThat(options).isEqualTo(expectedDefendants1v2SameSolicitorOptions(true, true)); } + @Test + void shouldMapExpertsToUpdatePartyDetailsForm() { + Expert expert1 = Expert.builder().firstName("First").lastName("Name").partyID("id").eventAdded("event").build(); + Expert expert2 = Expert.builder().firstName("Second").lastName("expert").fieldOfExpertise("field") + .phoneNumber("1").emailAddress("email").partyID("id2").build(); + UpdatePartyDetailsForm party = UpdatePartyDetailsForm.builder().firstName("First").lastName("Name") + .partyId("id").build(); + UpdatePartyDetailsForm party2 = UpdatePartyDetailsForm.builder().firstName("Second").lastName("expert") + .fieldOfExpertise("field").phoneNumber("1").emailAddress("email").partyId("id2").build(); + + assertThat(mapExpertsToUpdatePartyDetailsForm(wrapElements(expert1, expert2))) + .isEqualTo(wrapElements(party, party2)); + } + + @Test + void shouldMapExpertsToUpdatePartyDetailsForm_ifEmpty() { + assertThat(mapExpertsToUpdatePartyDetailsForm(null)).isEqualTo(new ArrayList<>()); + } + + @Nested + class MapToDQExperts { + UpdatePartyDetailsForm party = UpdatePartyDetailsForm.builder().firstName("Lewis").lastName("John") + .partyId("id").build(); + UpdatePartyDetailsForm party2 = UpdatePartyDetailsForm.builder().firstName("Second").lastName("expert") + .fieldOfExpertise("field").phoneNumber("1").emailAddress("expertemail").partyId("id2").build(); + + LocalDate date = LocalDate.of(2020, 3, 20); + + Expert expert1 = Expert.builder().firstName("First").lastName("Name").partyID("id").eventAdded("event") + .dateAdded(date).estimatedCost(BigDecimal.valueOf(10000)).build(); + Expert expert2 = Expert.builder().firstName("Second").lastName("expert").fieldOfExpertise("field") + .eventAdded("event").dateAdded(date).phoneNumber("1").emailAddress("email").partyID("id2").build(); + + @Test + void shouldEditExperts() { + Expert expectedExpert1 = Expert.builder().firstName("Lewis").lastName("John").partyID("id") + .eventAdded("event").dateAdded(date).estimatedCost(BigDecimal.valueOf(10000)).build(); + Expert expectedExpert2 = Expert.builder().firstName("Second").lastName("expert").fieldOfExpertise("field") + .eventAdded("event").dateAdded(date).phoneNumber("1").emailAddress("expertemail").partyID("id2").build(); + + assertThat(mapUpdatePartyDetailsFormToDQExperts(wrapElements(expert1, expert2), wrapElements(party, party2))) + .isEqualTo(wrapElements(expectedExpert1, expectedExpert2)); + } + + @Test + void shouldAddExperts() { + Expert expectedExpert1 = Expert.builder().firstName("Lewis").lastName("John") + .eventAdded("Manage Contact Information Event").dateAdded(LocalDate.now()) + .partyID(null) //change this for CIV-10382 + .build(); + Expert expectedExpert2 = Expert.builder().firstName("Second").lastName("expert").fieldOfExpertise("field") + .eventAdded("Manage Contact Information Event").dateAdded(LocalDate.now()).phoneNumber("1") + .emailAddress("expertemail") + .partyID(null) //change this for CIV-10382 + .build(); + + assertThat(mapUpdatePartyDetailsFormToDQExperts(null, wrapElements(party, party2))) + .isEqualTo(wrapElements(expectedExpert1, expectedExpert2)); + } + + @Test + void shouldAddExpertsWithExistingExperts() { + Expert expectedExpert1 = Expert.builder().firstName("Lewis").lastName("John").partyID("id") + .eventAdded("event").dateAdded(date).estimatedCost(BigDecimal.valueOf(10000)).build(); + Expert expectedExpert2 = Expert.builder().firstName("Second").lastName("expert").fieldOfExpertise("field") + .eventAdded("Manage Contact Information Event").dateAdded(LocalDate.now()).phoneNumber("1") + .emailAddress("expertemail") + .partyID(null) //change this for CIV-10382 + .build(); + + assertThat(mapUpdatePartyDetailsFormToDQExperts(wrapElements(expert1), wrapElements(party, party2))) + .isEqualTo(wrapElements(expectedExpert1, expectedExpert2)); + } + } + + @Nested + class MapToDQWitnesses { + UpdatePartyDetailsForm party = UpdatePartyDetailsForm.builder().firstName("Lewis").lastName("John") + .partyId("id").build(); + UpdatePartyDetailsForm party2 = UpdatePartyDetailsForm.builder().firstName("Second").lastName("witness") + .phoneNumber("1").emailAddress("witnessemail").partyId("id2").build(); + + LocalDate date = LocalDate.of(2020, 3, 20); + + Witness witness1 = Witness.builder().firstName("First").lastName("Name").partyID("id").eventAdded("event") + .dateAdded(date).reasonForWitness("reason").build(); + Witness witness2 = Witness.builder().firstName("Second").lastName("expert").eventAdded("event") + .dateAdded(date).phoneNumber("1").emailAddress("email").partyID("id2").build(); + + @Test + void shouldEditWitnesses() { + Witness expectedWitness1 = Witness.builder().firstName("Lewis").lastName("John") + .eventAdded("event").dateAdded(date).reasonForWitness("reason").partyID("id").build(); + + Witness expectedWitness2 = Witness.builder().firstName("Second").lastName("witness") + .eventAdded("event").dateAdded(date).phoneNumber("1").emailAddress("witnessemail") + .partyID("id2").build(); + + assertThat(mapUpdatePartyDetailsFormToDQWitnesses(wrapElements(witness1, witness2), wrapElements(party, party2))) + .isEqualTo(wrapElements(expectedWitness1, expectedWitness2)); + } + + @Test + void shouldAddWitnesses() { + Witness expectedWitness1 = Witness.builder().firstName("Lewis").lastName("John") + .eventAdded("Manage Contact Information Event").dateAdded(LocalDate.now()) + .partyID(null).build(); // CIV-10382 + Witness expectedWitness2 = Witness.builder().firstName("Second").lastName("witness") + .eventAdded("Manage Contact Information Event").dateAdded(LocalDate.now()).phoneNumber("1") + .emailAddress("witnessemail") + .partyID(null).build(); // CIV-10382 + + assertThat(mapUpdatePartyDetailsFormToDQWitnesses(null, wrapElements(party, party2))) + .isEqualTo(wrapElements(expectedWitness1, expectedWitness2)); + } + + @Test + void shouldRemoveWitnesses() { + assertThat(mapUpdatePartyDetailsFormToDQWitnesses(wrapElements(witness1, witness2), null)) + .isEmpty(); + } + + @Test + void shouldAddWitnessesWithExistingWitnesses() { + Witness expectedWitness1 = Witness.builder().firstName("Lewis").lastName("John").partyID("id") + .reasonForWitness("reason").eventAdded("event").dateAdded(date).build(); + Witness expectedWitness2 = Witness.builder().firstName("Second").lastName("witness") + .eventAdded("Manage Contact Information Event").dateAdded(LocalDate.now()).phoneNumber("1") + .emailAddress("witnessemail") + .partyID(null) //change this for CIV-10382 + .build(); + + assertThat(mapUpdatePartyDetailsFormToDQWitnesses(wrapElements(witness1), wrapElements(party, party2))) + .isEqualTo(wrapElements(expectedWitness1, expectedWitness2)); + } + } + + @Nested + class AppendCorrectUserAndType { + @Test + void shouldHaveCorrectID_ClaimantOneAdminIndividual() { + CaseData caseData = CaseDataBuilder.builder() + .applicant1(Party.builder().type(INDIVIDUAL).build()).build(); + + String result = appendUserAndType(CLAIMANT_ONE_ID, caseData, true); + + assertThat(result).isEqualTo("CLAIMANT_1_ADMIN_INDIVIDUAL"); + } + + @Test + void shouldHaveCorrectID_ClaimantTwoAdminSoleTrader() { + CaseData caseData = CaseDataBuilder.builder() + .applicant2(Party.builder().type(SOLE_TRADER).build()).build(); + + String result = appendUserAndType(CLAIMANT_TWO_ID, caseData, true); + + assertThat(result).isEqualTo("CLAIMANT_2_ADMIN_SOLE_TRADER"); + } + + @Test + void shouldHaveCorrectID_DefendantOneAdminOrganisation() { + CaseData caseData = CaseDataBuilder.builder() + .respondent1(Party.builder().type(ORGANISATION).build()).build(); + + String result = appendUserAndType(DEFENDANT_ONE_ID, caseData, true); + + assertThat(result).isEqualTo("DEFENDANT_1_ADMIN_ORGANISATION"); + } + + @Test + void shouldHaveCorrectID_DefendantTwoAdminCompany() { + CaseData caseData = CaseDataBuilder.builder() + .respondent2(Party.builder().type(COMPANY).build()).build(); + + String result = appendUserAndType(DEFENDANT_TWO_ID, caseData, true); + + assertThat(result).isEqualTo("DEFENDANT_2_ADMIN_COMPANY"); + } + + @Test + void shouldHaveCorrectID_DefendantTwoLegalRepIndividual() { + CaseData caseData = CaseDataBuilder.builder() + .respondent2(Party.builder().type(INDIVIDUAL).build()).build(); + + String result = appendUserAndType(DEFENDANT_TWO_ID, caseData, false); + + assertThat(result).isEqualTo("DEFENDANT_2_LR_INDIVIDUAL"); + } + + @Test + void shouldHaveCorrectID_Applicant1LitigationFriendAdmin() { + CaseData caseData = CaseDataBuilder.builder().build(); + + String result = appendUserAndType(CLAIMANT_ONE_LITIGATION_FRIEND_ID, caseData, false); + + assertThat(result).isEqualTo("CLAIMANT_1_LITIGATION_FRIEND_LR"); + } + + @Test + void shouldHaveCorrectID_Defendant2LitigationFriendAdmin() { + CaseData caseData = CaseDataBuilder.builder().build(); + + String result = appendUserAndType(DEFENDANT_TWO_LITIGATION_FRIEND_ID, caseData, true); + + assertThat(result).isEqualTo("DEFENDANT_2_LITIGATION_FRIEND_ADMIN"); + } + } + private List expectedApplicant1Options(boolean withExpertsAndWitnesses, boolean isAdmin) { List list = new ArrayList<>(); list.add(dynamicElementFromCode("CLAIMANT_1", "CLAIMANT 1: Mr. John Rambo")); - list.add(dynamicElementFromCode("CLAIMANT_1_LITIGATIONFRIEND", "CLAIMANT 1: Litigation Friend: Applicant Litigation Friend")); - list.add(dynamicElementFromCode("CLAIMANT_1_INDIVIDUALSSOLICITORORG", "CLAIMANT 1: Individuals attending for the legal representative")); + list.add(dynamicElementFromCode("CLAIMANT_1_LITIGATION_FRIEND", "CLAIMANT 1: Litigation Friend: Applicant Litigation Friend")); + list.add(dynamicElementFromCode("CLAIMANT_1_LR_INDIVIDUALS", "CLAIMANT 1: Individuals attending for the legal representative")); if (withExpertsAndWitnesses || isAdmin) { list.add(dynamicElementFromCode("CLAIMANT_1_WITNESSES", "CLAIMANT 1: Witnesses")); list.add(dynamicElementFromCode("CLAIMANT_1_EXPERTS", "CLAIMANT 1: Experts")); @@ -261,8 +487,8 @@ private List expectedApplicant1Options(boolean withExpertsAn private List expectedApplicant1OrgOptions(boolean withExpertsAndWitnesses, boolean isAdmin) { List list = new ArrayList<>(); list.add(dynamicElementFromCode("CLAIMANT_1", "CLAIMANT 1: Test Inc")); - list.add(dynamicElementFromCode("CLAIMANT_1_INDIVIDUALSORG", "CLAIMANT 1: Individuals attending for the organisation")); - list.add(dynamicElementFromCode("CLAIMANT_1_INDIVIDUALSSOLICITORORG", "CLAIMANT 1: Individuals attending for the legal representative")); + list.add(dynamicElementFromCode("CLAIMANT_1_ORGANISATION_INDIVIDUALS", "CLAIMANT 1: Individuals attending for the organisation")); + list.add(dynamicElementFromCode("CLAIMANT_1_LR_INDIVIDUALS", "CLAIMANT 1: Individuals attending for the legal representative")); if (withExpertsAndWitnesses || isAdmin) { list.add(dynamicElementFromCode("CLAIMANT_1_WITNESSES", "CLAIMANT 1: Witnesses")); list.add(dynamicElementFromCode("CLAIMANT_1_EXPERTS", "CLAIMANT 1: Experts")); @@ -273,10 +499,10 @@ private List expectedApplicant1OrgOptions(boolean withExpert private List expectedApplicants2v1Options(boolean withExpertsAndWitnesses, boolean isAdmin) { List list = new ArrayList<>(); list.add(dynamicElementFromCode("CLAIMANT_1", "CLAIMANT 1: Mr. John Rambo")); - list.add(dynamicElementFromCode("CLAIMANT_1_LITIGATIONFRIEND", "CLAIMANT 1: Litigation Friend: Applicant Litigation Friend")); + list.add(dynamicElementFromCode("CLAIMANT_1_LITIGATION_FRIEND", "CLAIMANT 1: Litigation Friend: Applicant Litigation Friend")); list.add(dynamicElementFromCode("CLAIMANT_2", "CLAIMANT 2: Mr. Jason Rambo")); - list.add(dynamicElementFromCode("CLAIMANT_2_LITIGATIONFRIEND", "CLAIMANT 2: Litigation Friend: Applicant Two Litigation Friend")); - list.add(dynamicElementFromCode("CLAIMANT_1_INDIVIDUALSSOLICITORORG", "CLAIMANTS: Individuals attending for the legal representative")); + list.add(dynamicElementFromCode("CLAIMANT_2_LITIGATION_FRIEND", "CLAIMANT 2: Litigation Friend: Applicant Two Litigation Friend")); + list.add(dynamicElementFromCode("CLAIMANT_1_LR_INDIVIDUALS", "CLAIMANTS: Individuals attending for the legal representative")); if (withExpertsAndWitnesses || isAdmin) { list.add(dynamicElementFromCode("CLAIMANT_1_WITNESSES", "CLAIMANTS: Witnesses")); list.add(dynamicElementFromCode("CLAIMANT_1_EXPERTS", "CLAIMANTS: Experts")); @@ -287,8 +513,8 @@ private List expectedApplicants2v1Options(boolean withExpert private List expectedDefendant1Options(boolean withExpertsAndWitnesses, boolean isAdmin) { List list = new ArrayList<>(); list.add(dynamicElementFromCode("DEFENDANT_1", "DEFENDANT 1: Mr. Sole Trader")); - list.add(dynamicElementFromCode("DEFENDANT_1_LITIGATIONFRIEND", "DEFENDANT 1: Litigation Friend: Litigation Friend")); - list.add(dynamicElementFromCode("DEFENDANT_1_INDIVIDUALSSOLICITORORG", "DEFENDANT 1: Individuals attending for the legal representative")); + list.add(dynamicElementFromCode("DEFENDANT_1_LITIGATION_FRIEND", "DEFENDANT 1: Litigation Friend: Litigation Friend")); + list.add(dynamicElementFromCode("DEFENDANT_1_LR_INDIVIDUALS", "DEFENDANT 1: Individuals attending for the legal representative")); if (withExpertsAndWitnesses || isAdmin) { list.add(dynamicElementFromCode("DEFENDANT_1_WITNESSES", "DEFENDANT 1: Witnesses")); list.add(dynamicElementFromCode("DEFENDANT_1_EXPERTS", "DEFENDANT 1: Experts")); @@ -299,8 +525,8 @@ private List expectedDefendant1Options(boolean withExpertsAn private List expectedDefendant2Options(boolean withExpertsAndWitnesses, boolean isAdmin) { List list = new ArrayList<>(); list.add(dynamicElementFromCode("DEFENDANT_2", "DEFENDANT 2: Mr. John Rambo")); - list.add(dynamicElementFromCode("DEFENDANT_2_LITIGATIONFRIEND", "DEFENDANT 2: Litigation Friend: Litigation Friend")); - list.add(dynamicElementFromCode("DEFENDANT_2_INDIVIDUALSSOLICITORORG", "DEFENDANT 2: Individuals attending for the legal representative")); + list.add(dynamicElementFromCode("DEFENDANT_2_LITIGATION_FRIEND", "DEFENDANT 2: Litigation Friend: Litigation Friend")); + list.add(dynamicElementFromCode("DEFENDANT_2_LR_INDIVIDUALS", "DEFENDANT 2: Individuals attending for the legal representative")); if (withExpertsAndWitnesses || isAdmin) { list.add(dynamicElementFromCode("DEFENDANT_2_WITNESSES", "DEFENDANT 2: Witnesses")); list.add(dynamicElementFromCode("DEFENDANT_2_EXPERTS", "DEFENDANT 2: Experts")); @@ -311,10 +537,10 @@ private List expectedDefendant2Options(boolean withExpertsAn private List expectedDefendants1v2SameSolicitorOptions(boolean withExpertsAndWitnesses, boolean isAdmin) { List list = new ArrayList<>(); list.add(dynamicElementFromCode("DEFENDANT_1", "DEFENDANT 1: Mr. Sole Trader")); - list.add(dynamicElementFromCode("DEFENDANT_1_LITIGATIONFRIEND", "DEFENDANT 1: Litigation Friend: Litigation Friend")); + list.add(dynamicElementFromCode("DEFENDANT_1_LITIGATION_FRIEND", "DEFENDANT 1: Litigation Friend: Litigation Friend")); list.add(dynamicElementFromCode("DEFENDANT_2", "DEFENDANT 2: Mr. John Rambo")); - list.add(dynamicElementFromCode("DEFENDANT_2_LITIGATIONFRIEND", "DEFENDANT 2: Litigation Friend: Litigation Friend")); - list.add(dynamicElementFromCode("DEFENDANT_1_INDIVIDUALSSOLICITORORG", "DEFENDANTS: Individuals attending for the legal representative")); + list.add(dynamicElementFromCode("DEFENDANT_2_LITIGATION_FRIEND", "DEFENDANT 2: Litigation Friend: Litigation Friend")); + list.add(dynamicElementFromCode("DEFENDANT_1_LR_INDIVIDUALS", "DEFENDANTS: Individuals attending for the legal representative")); if (withExpertsAndWitnesses || isAdmin) { list.add(dynamicElementFromCode("DEFENDANT_1_WITNESSES", "DEFENDANTS: Witnesses")); list.add(dynamicElementFromCode("DEFENDANT_1_EXPERTS", "DEFENDANTS: Experts")); From ac9f24b3427d20e198ef0bc1266be6cb5895aaea Mon Sep 17 00:00:00 2001 From: neeta-hmcts <115545612+neeta-hmcts@users.noreply.github.com> Date: Mon, 13 Nov 2023 09:31:01 +0000 Subject: [PATCH 22/28] CIV-11514 - Full admit pay immediately 5 working days calculation(EXUI) (#3554) * updated logic to calculate workingDays. * fxied review comment. * added dto * fixed unit test. * CIV-11514: Deadline Calculator * CIV-11514: Service Class problem * fixed payment by date in sealed form. * fixed payment by date in sealed form. * fixed checkstyle. * fixed unit tests. * fixed judgment by admission logic * fixed code smell and coverage. --------- Co-authored-by: kenneth-hmcts Co-authored-by: jarekPierchala <118526007+jarekPierchala@users.noreply.github.com> --- .../cases/CasesControllerTest.java | 8 ++-- .../controllers/cases/CasesController.java | 6 ++- ...tByAdmissionForSpecCuiCallbackHandler.java | 7 +--- .../RespondToClaimSpecCallbackHandler.java | 7 +++- .../RespondToDefenceSpecCallbackHandler.java | 10 ++--- .../hmcts/reform/civil/model/CaseData.java | 6 +-- .../citizenui/dto/ExtendedDeadlineDto.java | 18 ++++++++ .../ResponseRepaymentDetailsForm.java | 12 +++--- .../DeadlineExtensionCalculatorService.java | 20 +++++++-- .../SealedClaimLipResponseFormGenerator.java | 40 +----------------- ...dmissionForSpecCuiCallbackHandlerTest.java | 20 ++++----- ...RespondToClaimSpecCallbackHandlerTest.java | 14 ++++--- ...spondToDefenceSpecCallbackHandlerTest.java | 12 +++--- ...eadlineExtensionCalculatorServiceTest.java | 42 +++++++++++++++---- ...aledClaimLipResponseFormGeneratorTest.java | 32 +++++++++++--- 15 files changed, 145 insertions(+), 109 deletions(-) create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/dto/ExtendedDeadlineDto.java diff --git a/src/integrationTest/java/uk/gov/hmcts/reform/civil/controllers/cases/CasesControllerTest.java b/src/integrationTest/java/uk/gov/hmcts/reform/civil/controllers/cases/CasesControllerTest.java index 4f9174d907a..627fda38600 100644 --- a/src/integrationTest/java/uk/gov/hmcts/reform/civil/controllers/cases/CasesControllerTest.java +++ b/src/integrationTest/java/uk/gov/hmcts/reform/civil/controllers/cases/CasesControllerTest.java @@ -12,13 +12,12 @@ import uk.gov.hmcts.reform.civil.exceptions.CaseDataInvalidException; import uk.gov.hmcts.reform.civil.exceptions.CaseNotFoundException; import uk.gov.hmcts.reform.civil.exceptions.UserNotFoundOnCaseException; -import uk.gov.hmcts.reform.civil.exceptions.CaseNotFoundException; -import uk.gov.hmcts.reform.civil.exceptions.UserNotFoundOnCaseException; import uk.gov.hmcts.reform.civil.helpers.CaseDetailsConverter; import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.model.bulkclaims.CaseworkerSubmitEventDTo; import uk.gov.hmcts.reform.civil.model.citizenui.DashboardClaimInfo; import uk.gov.hmcts.reform.civil.model.citizenui.DashboardResponse; +import uk.gov.hmcts.reform.civil.model.citizenui.dto.ExtendedDeadlineDto; import uk.gov.hmcts.reform.civil.model.citizenui.dto.EventDto; import uk.gov.hmcts.reform.civil.model.repaymentplan.ClaimantProposedPlan; import uk.gov.hmcts.reform.civil.service.CoreCaseDataService; @@ -42,6 +41,7 @@ import java.util.Map; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; @@ -228,10 +228,10 @@ void shouldSubmitEventSuccessfully() { @SneakyThrows void shouldCalculateDeadlineSuccessfully() { LocalDate extensionDate = LocalDate.of(2022, 6, 6); - when(deadlineExtensionCalculatorService.calculateExtendedDeadline(any())).thenReturn(extensionDate); + when(deadlineExtensionCalculatorService.calculateExtendedDeadline(any(), anyInt())).thenReturn(extensionDate); doPost( BEARER_TOKEN, - extensionDate, + ExtendedDeadlineDto.builder().responseDate(extensionDate).plusDays(5).build(), CALCULATE_DEADLINE_URL ) .andExpect(content().json(toJson(extensionDate))) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/controllers/cases/CasesController.java b/src/main/java/uk/gov/hmcts/reform/civil/controllers/cases/CasesController.java index 47814b87877..b83ea9be12c 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/controllers/cases/CasesController.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/controllers/cases/CasesController.java @@ -24,6 +24,7 @@ import uk.gov.hmcts.reform.civil.exceptions.CaseDataInvalidException; import uk.gov.hmcts.reform.civil.model.bulkclaims.CaseworkerSubmitEventDTo; import uk.gov.hmcts.reform.civil.model.citizenui.DashboardResponse; +import uk.gov.hmcts.reform.civil.model.citizenui.dto.ExtendedDeadlineDto; import uk.gov.hmcts.reform.civil.model.citizenui.dto.EventDto; import uk.gov.hmcts.reform.civil.model.citizenui.dto.RepaymentDecisionType; import uk.gov.hmcts.reform.civil.model.repaymentplan.ClaimantProposedPlan; @@ -174,8 +175,9 @@ public ResponseEntity submitEvent( @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "401", description = "Not Authorized")}) - public ResponseEntity calculateNewResponseDeadline(@RequestBody LocalDate extendedDeadline) { - LocalDate calculatedDeadline = deadlineExtensionCalculatorService.calculateExtendedDeadline(extendedDeadline); + public ResponseEntity calculateNewResponseDeadline(@RequestBody ExtendedDeadlineDto deadlineDateDetails) { + LocalDate calculatedDeadline = deadlineExtensionCalculatorService.calculateExtendedDeadline( + deadlineDateDetails.getResponseDate(), deadlineDateDetails.getPlusDays()); return new ResponseEntity<>(calculatedDeadline, HttpStatus.OK); } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RequestJudgementByAdmissionForSpecCuiCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RequestJudgementByAdmissionForSpecCuiCallbackHandler.java index 9ebf5ff394e..aebd58fee07 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RequestJudgementByAdmissionForSpecCuiCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RequestJudgementByAdmissionForSpecCuiCallbackHandler.java @@ -18,9 +18,7 @@ import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.service.FeatureToggleService; import uk.gov.hmcts.reform.civil.service.JudgementService; -import uk.gov.hmcts.reform.civil.service.citizenui.responsedeadline.DeadlineExtensionCalculatorService; -import java.time.LocalDate; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -43,7 +41,6 @@ public class RequestJudgementByAdmissionForSpecCuiCallbackHandler extends Callba private final JudgementService judgementService; private final CaseDetailsConverter caseDetailsConverter; private final FeatureToggleService featureToggleService; - private final DeadlineExtensionCalculatorService deadlineCalculatorService; @Override protected Map callbacks() { @@ -67,9 +64,7 @@ private CallbackResponse validateDefaultJudgementEligibility(CallbackParams call CaseData.CaseDataBuilder caseDataBuilder = caseData.toBuilder(); ArrayList errors = new ArrayList<>(); if (caseData.isJudgementDateNotPermitted()) { - LocalDate extendedResponseDate = caseData.getRespondent1ResponseDate().toLocalDate().plusDays(5); - LocalDate extendedRespondent1ResponseDate = deadlineCalculatorService.calculateExtendedDeadline(extendedResponseDate); - errors.add(format(NOT_VALID_DJ_BY_ADMISSION, caseData.setUpJudgementFormattedPermittedDate(extendedRespondent1ResponseDate))); + errors.add(format(NOT_VALID_DJ_BY_ADMISSION, caseData.setUpJudgementFormattedPermittedDate(caseData.getRespondToClaimAdmitPartLRspec().getWhenWillThisAmountBePaid()))); } return AboutToStartOrSubmitCallbackResponse.builder() diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandler.java index 691bf0b241a..5640b94350a 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandler.java @@ -20,6 +20,7 @@ import uk.gov.hmcts.reform.civil.enums.DocCategory; import uk.gov.hmcts.reform.civil.enums.MultiPartyResponseTypeFlags; import uk.gov.hmcts.reform.civil.enums.MultiPartyScenario; +import uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec; import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec; import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpecPaidStatus; import uk.gov.hmcts.reform.civil.enums.TimelineUploadTypeSpec; @@ -55,6 +56,7 @@ import uk.gov.hmcts.reform.civil.service.FeatureToggleService; import uk.gov.hmcts.reform.civil.service.Time; import uk.gov.hmcts.reform.civil.service.UserService; +import uk.gov.hmcts.reform.civil.service.citizenui.responsedeadline.DeadlineExtensionCalculatorService; import uk.gov.hmcts.reform.civil.service.flowstate.StateFlowEngine; import uk.gov.hmcts.reform.civil.utils.AssignCategoryId; import uk.gov.hmcts.reform.civil.utils.CaseFlagsInitialiser; @@ -164,6 +166,7 @@ public class RespondToClaimSpecCallbackHandler extends CallbackHandler private final CourtLocationUtils courtLocationUtils; private final CaseFlagsInitialiser caseFlagsInitialiser; private final AssignCategoryId assignCategoryId; + private final DeadlineExtensionCalculatorService deadlineCalculatorService; @Override public List handledEvents() { @@ -1383,7 +1386,9 @@ && ofNullable(caseData.getRespondent2Copy()).isPresent()) { if (caseData.getDefenceAdmitPartPaymentTimeRouteRequired() != null && caseData.getDefenceAdmitPartPaymentTimeRouteRequired() == IMMEDIATELY && ifResponseTypeIsPartOrFullAdmission(caseData)) { - LocalDate whenBePaid = deadlinesCalculator.calculateWhenToBePaid(responseDate); + LocalDate whenBePaid = deadlineCalculatorService.calculateExtendedDeadline( + LocalDate.now(), + RespondentResponsePartAdmissionPaymentTimeLRspec.DAYS_TO_PAY_IMMEDIATELY); updatedData.respondToClaimAdmitPartLRspec(RespondToClaimAdmitPartLRspec.builder() .whenWillThisAmountBePaid(whenBePaid).build()); } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandler.java index 49a3a85d317..ecbac578256 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandler.java @@ -16,6 +16,7 @@ import uk.gov.hmcts.reform.civil.enums.AllocatedTrack; import uk.gov.hmcts.reform.civil.enums.CaseCategory; import uk.gov.hmcts.reform.civil.enums.CaseState; +import uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec; import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec; import uk.gov.hmcts.reform.civil.enums.YesOrNo; import uk.gov.hmcts.reform.civil.handler.callback.user.spec.CaseDataToTextGenerator; @@ -568,11 +569,10 @@ private String setUpPayDateToString(CaseData caseData) { .format(DateTimeFormatter.ofPattern(datePattern, Locale.ENGLISH)); } if (caseData.getRespondent1ResponseDate() != null) { - LocalDate extendedResponseDate = caseData.getRespondent1ResponseDate().toLocalDate().plusDays(5); - return deadlineCalculatorService.calculateExtendedDeadline(extendedResponseDate).format(DateTimeFormatter.ofPattern( - datePattern, - Locale.ENGLISH - )); + return deadlineCalculatorService.calculateExtendedDeadline( + caseData.getRespondent1ResponseDate().toLocalDate(), + RespondentResponsePartAdmissionPaymentTimeLRspec.DAYS_TO_PAY_IMMEDIATELY) + .format(DateTimeFormatter.ofPattern(datePattern, Locale.ENGLISH)); } return null; } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java index 63d6365fd37..953b02321d3 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java @@ -874,9 +874,9 @@ && isApplicant1NotRepresented() @JsonIgnore public boolean isJudgementDateNotPermitted() { - return nonNull(getRespondent1ResponseDate()) - && getRespondent1ResponseDate() - .toLocalDate().plusDays(5).atTime(DeadlinesCalculator.END_OF_BUSINESS_DAY).isAfter(LocalDateTime.now()); + return nonNull(getRespondToClaimAdmitPartLRspec().getWhenWillThisAmountBePaid()) + && getRespondToClaimAdmitPartLRspec().getWhenWillThisAmountBePaid() + .atTime(DeadlinesCalculator.END_OF_BUSINESS_DAY).isAfter(LocalDateTime.now()); } @JsonIgnore diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/dto/ExtendedDeadlineDto.java b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/dto/ExtendedDeadlineDto.java new file mode 100644 index 00000000000..58c4a1182de --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/dto/ExtendedDeadlineDto.java @@ -0,0 +1,18 @@ +package uk.gov.hmcts.reform.civil.model.citizenui.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ExtendedDeadlineDto { + + private LocalDate responseDate; + private Integer plusDays; +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/sealedclaim/ResponseRepaymentDetailsForm.java b/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/sealedclaim/ResponseRepaymentDetailsForm.java index ecacb8ca9f9..ae474fb8326 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/sealedclaim/ResponseRepaymentDetailsForm.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/sealedclaim/ResponseRepaymentDetailsForm.java @@ -78,9 +78,9 @@ public static ResponseRepaymentDetailsForm toSealedClaimResponseCommonContent(Ca .build(); } - private static void addRepaymentMethod(CaseData caseData, ResponseRepaymentDetailsForm.ResponseRepaymentDetailsFormBuilder builder, BigDecimal totalAmount) { + private static void addRepaymentMethod(CaseData caseData, ResponseRepaymentDetailsFormBuilder builder, BigDecimal totalAmount) { if (caseData.isPayImmediately()) { - addPayByDatePayImmediately(builder, totalAmount); + addPayByDatePayImmediately(builder, totalAmount, caseData.getRespondToClaimAdmitPartLRspec().getWhenWillThisAmountBePaid()); } else if (caseData.isPayByInstallment()) { addRepaymentPlan(caseData, builder, totalAmount); } else if (caseData.isPayBySetDate()) { @@ -94,10 +94,8 @@ private static void addPayBySetDate(CaseData caseData, ResponseRepaymentDetailsF .whyNotPayImmediately(caseData.getResponseToClaimAdmitPartWhyNotPayLRspec()); } - private static void addPayByDatePayImmediately(ResponseRepaymentDetailsForm.ResponseRepaymentDetailsFormBuilder builder, BigDecimal totalClaimAmount) { - builder.payBy(LocalDate.now() - .plusDays(RespondentResponsePartAdmissionPaymentTimeLRspec.DAYS_TO_PAY_IMMEDIATELY)) - .amountToPay(totalClaimAmount + ""); + private static void addPayByDatePayImmediately(ResponseRepaymentDetailsFormBuilder builder, BigDecimal totalClaimAmount, LocalDate responseDate) { + builder.payBy(responseDate).amountToPay(totalClaimAmount + ""); } private static void addRepaymentPlan(CaseData caseData, ResponseRepaymentDetailsForm.ResponseRepaymentDetailsFormBuilder builder, BigDecimal totalClaimAmount) { @@ -142,7 +140,7 @@ private static void fullDefenceData(CaseData caseData, ResponseRepaymentDetailsF } } - private static void partAdmissionData(CaseData caseData, ResponseRepaymentDetailsForm.ResponseRepaymentDetailsFormBuilder builder) { + private static void partAdmissionData(CaseData caseData, ResponseRepaymentDetailsFormBuilder builder) { addDetailsOnWhyClaimIsRejected(caseData, builder); if (caseData.getSpecDefenceAdmittedRequired() == YesOrNo.YES) { alreadyPaid(caseData, builder); diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/citizenui/responsedeadline/DeadlineExtensionCalculatorService.java b/src/main/java/uk/gov/hmcts/reform/civil/service/citizenui/responsedeadline/DeadlineExtensionCalculatorService.java index 0e6e5479803..71bf64f61c1 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/citizenui/responsedeadline/DeadlineExtensionCalculatorService.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/citizenui/responsedeadline/DeadlineExtensionCalculatorService.java @@ -6,16 +6,28 @@ import java.time.LocalDate; +import static java.util.Objects.requireNonNull; + @Service @RequiredArgsConstructor public class DeadlineExtensionCalculatorService { private final WorkingDayIndicator workingDayIndicator; + int workingDaysCounter; - public LocalDate calculateExtendedDeadline(LocalDate dateProposed) { - return workingDayIndicator.isWorkingDay(dateProposed) - ? dateProposed - : workingDayIndicator.getNextWorkingDay(dateProposed); + public LocalDate calculateExtendedDeadline(LocalDate responseDate, int plusDays) { + workingDaysCounter = 0; + requireNonNull(responseDate); + if (plusDays == 0) { + return workingDayIndicator.getNextWorkingDay(responseDate); + } + return calculateWorkingDays(responseDate.plusDays(1), plusDays); } + public LocalDate calculateWorkingDays(LocalDate responseDate, int plusDays) { + if (workingDayIndicator.isWorkingDay(responseDate)) { + workingDaysCounter++; + } + return workingDaysCounter == plusDays ? responseDate : calculateWorkingDays(responseDate.plusDays(1), plusDays); + } } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/sealedclaim/SealedClaimLipResponseFormGenerator.java b/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/sealedclaim/SealedClaimLipResponseFormGenerator.java index 42a5ae911ac..bc971235285 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/sealedclaim/SealedClaimLipResponseFormGenerator.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/sealedclaim/SealedClaimLipResponseFormGenerator.java @@ -1,27 +1,17 @@ package uk.gov.hmcts.reform.civil.service.docmosis.sealedclaim; import lombok.RequiredArgsConstructor; - import org.springframework.stereotype.Service; import uk.gov.hmcts.reform.civil.documentmanagement.DocumentManagementService; import uk.gov.hmcts.reform.civil.documentmanagement.model.CaseDocument; import uk.gov.hmcts.reform.civil.documentmanagement.model.DocumentType; import uk.gov.hmcts.reform.civil.documentmanagement.model.PDF; -import uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec; -import uk.gov.hmcts.reform.civil.enums.YesOrNo; import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.model.docmosis.DocmosisDocument; -import uk.gov.hmcts.reform.civil.model.docmosis.sealedclaim.ResponseRepaymentDetailsForm; import uk.gov.hmcts.reform.civil.model.docmosis.sealedclaim.SealedClaimLipResponseForm; import uk.gov.hmcts.reform.civil.service.docmosis.DocumentGeneratorService; -import uk.gov.hmcts.reform.civil.service.citizenui.responsedeadline.DeadlineExtensionCalculatorService; import uk.gov.hmcts.reform.civil.service.docmosis.TemplateDataGenerator; -import java.time.LocalDate; -import java.util.Objects; - -import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.FULL_ADMISSION; -import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.PART_ADMISSION; import static uk.gov.hmcts.reform.civil.service.docmosis.DocmosisTemplates.DEFENDANT_RESPONSE_LIP_SPEC; @Service @@ -30,12 +20,10 @@ public class SealedClaimLipResponseFormGenerator implements TemplateDataGenerato private final DocumentGeneratorService documentGeneratorService; private final DocumentManagementService documentManagementService; - private final DeadlineExtensionCalculatorService deadlineCalculatorService; @Override public SealedClaimLipResponseForm getTemplateData(CaseData caseData) { - SealedClaimLipResponseForm templateData = SealedClaimLipResponseForm.toTemplate(caseData); - return getRespondent1RepaymentDate(caseData, templateData); + return SealedClaimLipResponseForm.toTemplate(caseData); } public CaseDocument generate(final CaseData caseData, final String authorization) { @@ -54,30 +42,4 @@ public CaseDocument generate(final CaseData caseData, final String authorization new PDF(fileName, docmosisDocument.getBytes(), DocumentType.DEFENDANT_DEFENCE) ); } - - private SealedClaimLipResponseForm getRespondent1RepaymentDate(final CaseData caseData, SealedClaimLipResponseForm templateData) { - if (!Objects.isNull(caseData.getRespondent1ClaimResponseTypeForSpec())) { - if (hasPayByDatePayImmediately(caseData)) { - return addPayByDatePayImmediately(caseData, templateData); - } - } - return templateData; - } - - private SealedClaimLipResponseForm addPayByDatePayImmediately(CaseData caseData, SealedClaimLipResponseForm templateData) { - if (caseData.isPayImmediately()) { - LocalDate extendedDate = LocalDate.now().plusDays(RespondentResponsePartAdmissionPaymentTimeLRspec.DAYS_TO_PAY_IMMEDIATELY); - LocalDate payDeadlineDate = deadlineCalculatorService.calculateExtendedDeadline(extendedDate); - ResponseRepaymentDetailsForm responseRepaymentDetailsForm = templateData.getCommonDetails().toBuilder().payBy( - payDeadlineDate).build(); - SealedClaimLipResponseForm.SealedClaimLipResponseFormBuilder templateFormData = templateData.toBuilder(); - return templateFormData.commonDetails(responseRepaymentDetailsForm).build(); - } - return templateData; - } - - private boolean hasPayByDatePayImmediately(CaseData caseData) { - return (FULL_ADMISSION.equals(caseData.getRespondent1ClaimResponseTypeForSpec()) || (PART_ADMISSION.equals( - caseData.getRespondent1ClaimResponseTypeForSpec()) && caseData.getSpecDefenceAdmittedRequired() == YesOrNo.NO)); - } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RequestJudgementByAdmissionForSpecCuiCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RequestJudgementByAdmissionForSpecCuiCallbackHandlerTest.java index 3f906a4b330..4587d7afc7a 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RequestJudgementByAdmissionForSpecCuiCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RequestJudgementByAdmissionForSpecCuiCallbackHandlerTest.java @@ -11,7 +11,6 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import uk.gov.hmcts.reform.ccd.client.model.AboutToStartOrSubmitCallbackResponse; import uk.gov.hmcts.reform.ccd.client.model.SubmittedCallbackResponse; -import uk.gov.hmcts.reform.civil.bankholidays.WorkingDayIndicator; import uk.gov.hmcts.reform.civil.callback.CallbackParams; import uk.gov.hmcts.reform.civil.enums.CaseState; import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec; @@ -21,26 +20,24 @@ import uk.gov.hmcts.reform.civil.model.CCJPaymentDetails; import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.model.Fee; +import uk.gov.hmcts.reform.civil.model.RespondToClaimAdmitPartLRspec; import uk.gov.hmcts.reform.civil.sampledata.CallbackParamsBuilder; import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; import uk.gov.hmcts.reform.civil.service.FeatureToggleService; import uk.gov.hmcts.reform.civil.service.JudgementService; -import uk.gov.hmcts.reform.civil.service.citizenui.responsedeadline.DeadlineExtensionCalculatorService; import uk.gov.hmcts.reform.civil.utils.MonetaryConversions; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; import static java.lang.String.format; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.when; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_START; -import static uk.gov.hmcts.reform.civil.callback.CallbackType.MID; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; +import static uk.gov.hmcts.reform.civil.callback.CallbackType.MID; import static uk.gov.hmcts.reform.civil.callback.CallbackType.SUBMITTED; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.REQUEST_JUDGEMENT_ADMISSION_SPEC; import static uk.gov.hmcts.reform.civil.enums.CaseState.AWAITING_APPLICANT_INTENTION; @@ -70,23 +67,18 @@ public class RequestJudgementByAdmissionForSpecCuiCallbackHandlerTest extends Ba @MockBean private CaseDetailsConverter caseDetailsConverter; - @MockBean - private DeadlineExtensionCalculatorService deadlineCalculatorService; - @MockBean - private WorkingDayIndicator workingDayIndicator; @Nested class AboutToStartCallback { @Test void shouldReturnError_WhenAboutToStartIsInvoked() { + LocalDate whenWillPay = LocalDate.now().plusDays(5); CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build().toBuilder() .respondent1ResponseDate(LocalDateTime.now()) .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) .ccdState(AWAITING_APPLICANT_INTENTION) + .respondToClaimAdmitPartLRspec(RespondToClaimAdmitPartLRspec.builder().whenWillThisAmountBePaid(whenWillPay).build()) .build(); - given(workingDayIndicator.isWorkingDay(any())).willReturn(true); - LocalDate proposedExtensionDeadline = LocalDate.now(); - given(deadlineCalculatorService.calculateExtendedDeadline(any())).willReturn(proposedExtensionDeadline); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_START, caseData).build(); AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler .handle(params); @@ -95,10 +87,12 @@ void shouldReturnError_WhenAboutToStartIsInvoked() { @Test void shouldNotReturnError_WhenAboutToStartIsInvokedOneDefendant() { + LocalDate whenWillPay = LocalDate.of(2023, 10, 11); CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build().toBuilder() .respondent1ResponseDate(LocalDateTime.now().minusDays(15)) .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) .ccdState(AWAITING_APPLICANT_INTENTION) + .respondToClaimAdmitPartLRspec(RespondToClaimAdmitPartLRspec.builder().whenWillThisAmountBePaid(whenWillPay).build()) .build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_START, caseData).build(); AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandlerTest.java index ac9d11481ef..6fbfc1fb527 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandlerTest.java @@ -72,6 +72,7 @@ import uk.gov.hmcts.reform.civil.service.FeatureToggleService; import uk.gov.hmcts.reform.civil.service.Time; import uk.gov.hmcts.reform.civil.service.UserService; +import uk.gov.hmcts.reform.civil.service.citizenui.responsedeadline.DeadlineExtensionCalculatorService; import uk.gov.hmcts.reform.civil.service.flowstate.FlowFlag; import uk.gov.hmcts.reform.civil.service.flowstate.StateFlowEngine; import uk.gov.hmcts.reform.civil.stateflow.StateFlow; @@ -100,6 +101,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; @@ -162,6 +164,8 @@ class RespondToClaimSpecCallbackHandlerTest extends BaseCallbackHandlerTest { private CourtLocationUtils courtLocationUtils; @Mock private CaseFlagsInitialiser caseFlagsInitialiser; + @Mock + private DeadlineExtensionCalculatorService deadlineExtensionCalculatorService; @Spy private List confirmationTextGenerators = List.of( @@ -751,8 +755,6 @@ void updateRespondent2AddressWhenUpdated() { when(stateFlowEngine.evaluate(any(CaseData.class))).thenReturn(mockedStateFlow); when(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).thenReturn(true); - Address changedAddress = AddressBuilder.maximal().build(); - CaseData caseData = CaseDataBuilder.builder().atStateApplicantRespondToDefenceAndProceed() .respondent2DQ() .respondent1Copy(PartyBuilder.builder().individual().build()) @@ -1084,7 +1086,6 @@ void oneVTwo_SecondDefendantRepliesSameLegalRep() { DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_2 )) .build(); - CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); List locations = List.of(LocationRefData.builder().build()); when(locationRefDataService.getCourtLocationsForDefaultJudgments(any())) @@ -1104,10 +1105,13 @@ void oneVTwo_SecondDefendantRepliesSameLegalRep() { .thenReturn(true); UserInfo userInfo = UserInfo.builder().uid("798").build(); when(userService.getUserInfo(anyString())).thenReturn(userInfo); + LocalDate whenWillPay = LocalDate.now().plusDays(5); + given(deadlineExtensionCalculatorService.calculateExtendedDeadline(any(), anyInt())).willReturn(whenWillPay); + + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); // When - AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler - .handle(params); + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); // Then AbstractObjectAssert sent2 = assertThat(response.getData()) diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandlerTest.java index 9eae8beac2d..9b5371b1f9f 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToDefenceSpecCallbackHandlerTest.java @@ -94,6 +94,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.when; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_START; @@ -1369,8 +1370,8 @@ void shouldSetUpPaymentDateToString() { when(featureToggleService.isPinInPostEnabled()).thenReturn(true); given(workingDayIndicator.isWorkingDay(any())).willReturn(true); - LocalDate whenWillPay = LocalDate.now().plusDays(5); - given(deadlineCalculatorService.calculateExtendedDeadline(any())).willReturn(whenWillPay); + LocalDate whenWillPay = LocalDate.now(); + given(deadlineCalculatorService.calculateExtendedDeadline(any(), anyInt())).willReturn(whenWillPay); RespondToClaimAdmitPartLRspec respondToClaimAdmitPartLRspec = RespondToClaimAdmitPartLRspec.builder() @@ -1397,9 +1398,8 @@ void shouldSetUpPaymentDateToString() { void shouldSetUpPaymentDateToStringForPartAdmitPaid() { when(featureToggleService.isPinInPostEnabled()).thenReturn(true); - given(workingDayIndicator.isWorkingDay(any())).willReturn(true); LocalDate whenWillPay = LocalDate.now().plusDays(5); - given(deadlineCalculatorService.calculateExtendedDeadline(any())).willReturn(whenWillPay); + given(deadlineCalculatorService.calculateExtendedDeadline(any(), anyInt())).willReturn(whenWillPay); RespondToClaim respondToAdmittedClaim = RespondToClaim.builder() @@ -1428,8 +1428,8 @@ void shouldSetUpPaymentDateForResponseDateToString() { when(featureToggleService.isPinInPostEnabled()).thenReturn(true); given(workingDayIndicator.isWorkingDay(any())).willReturn(true); - LocalDate whenWillPay = LocalDate.now().plusDays(5); - given(deadlineCalculatorService.calculateExtendedDeadline(any())).willReturn(whenWillPay); + LocalDate whenWillPay = LocalDate.now(); + given(deadlineCalculatorService.calculateExtendedDeadline(any(), anyInt())).willReturn(whenWillPay); CaseData caseData = CaseData.builder() .respondent1ResponseDate(LocalDateTime.now()) diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/citizenui/responsedeadline/DeadlineExtensionCalculatorServiceTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/citizenui/responsedeadline/DeadlineExtensionCalculatorServiceTest.java index 736974f4cce..dcc0e6f718c 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/citizenui/responsedeadline/DeadlineExtensionCalculatorServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/citizenui/responsedeadline/DeadlineExtensionCalculatorServiceTest.java @@ -26,30 +26,54 @@ public class DeadlineExtensionCalculatorServiceTest { @Test void shouldReturnTheSameGivenDateWhenDateIsWorkday() { - given(workingDayIndicator.isWorkingDay(any())).willReturn(true); + given(workingDayIndicator.getNextWorkingDay(any())).willReturn(LocalDate.now()); LocalDate proposedExtensionDeadline = LocalDate.now(); LocalDate calculatedDeadline = deadlineExtensionCalculatorService.calculateExtendedDeadline( - proposedExtensionDeadline); + proposedExtensionDeadline, 0); assertThat(calculatedDeadline).isEqualTo(proposedExtensionDeadline); - verify(workingDayIndicator).isWorkingDay(proposedExtensionDeadline); - verify(workingDayIndicator, never()).getNextWorkingDay(proposedExtensionDeadline); + verify(workingDayIndicator).getNextWorkingDay(proposedExtensionDeadline); + verify(workingDayIndicator, never()).isWorkingDay(proposedExtensionDeadline); } @Test void shouldReturnNextWorkingDayWhenDateIsHoliday() { - given(workingDayIndicator.isWorkingDay(any())).willReturn(false); + LocalDate proposedExtensionDeadline = LocalDate.of(2022, 6, 3); LocalDate calculatedNextWorkingDay = LocalDate.of(2022, 6, 4); + given(workingDayIndicator.getNextWorkingDay(any())).willReturn(calculatedNextWorkingDay); - LocalDate proposedExtensionDeadline = LocalDate.of(2022, 6, 3); LocalDate calculatedDeadline = deadlineExtensionCalculatorService.calculateExtendedDeadline( - proposedExtensionDeadline); + proposedExtensionDeadline, 0); assertThat(calculatedDeadline).isEqualTo(calculatedNextWorkingDay); - verify(workingDayIndicator).isWorkingDay(proposedExtensionDeadline); - verify(workingDayIndicator).getNextWorkingDay(proposedExtensionDeadline); + verify(workingDayIndicator, never()).isWorkingDay(calculatedNextWorkingDay); + } + + @Test + void shouldReturnFifthWorkingDayFromTheGivenDateWhen_NoHoliday_NoWeekend_InBetween() { + given(workingDayIndicator.isWorkingDay(any())).willReturn(true); + LocalDate proposedExtensionDeadline = LocalDate.of(2023, 11, 17); + LocalDate expectedExtensionDeadline = LocalDate.of(2023, 11, 22); + + LocalDate calculatedDeadline = deadlineExtensionCalculatorService.calculateExtendedDeadline( + proposedExtensionDeadline, 5); + + assertThat(calculatedDeadline).isEqualTo(expectedExtensionDeadline); + } + + @Test + void shouldReturnFifthWorkingDayFromTheGivenDateWhen_Holiday_InBetween() { + given(workingDayIndicator.isWorkingDay(any())).willReturn(true); + given(workingDayIndicator.isWorkingDay(LocalDate.of(2023, 11, 19))).willReturn(false); + LocalDate proposedExtensionDeadline = LocalDate.of(2023, 11, 17); + LocalDate expectedExtensionDeadline = LocalDate.of(2023, 11, 23); + + LocalDate calculatedDeadline = deadlineExtensionCalculatorService.calculateExtendedDeadline( + proposedExtensionDeadline, 5); + + assertThat(calculatedDeadline).isEqualTo(expectedExtensionDeadline); } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/sealedclaim/SealedClaimLipResponseFormGeneratorTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/sealedclaim/SealedClaimLipResponseFormGeneratorTest.java index 299d334a0e7..ab25f0fbe0e 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/sealedclaim/SealedClaimLipResponseFormGeneratorTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/sealedclaim/SealedClaimLipResponseFormGeneratorTest.java @@ -118,15 +118,20 @@ void shouldGenerateDocumentSuccessfully() { @Test void admitPayImmediate() { - CaseData caseData = commonData() + LocalDate whenWillPay = LocalDate.now().plusDays(5); + CaseData.CaseDataBuilder builder = commonData() .respondent1(company("B")) .respondent2(individual("C")) .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) .defenceAdmitPartPaymentTimeRouteRequired(RespondentResponsePartAdmissionPaymentTimeLRspec.IMMEDIATELY) - .build(); + .respondToClaimAdmitPartLRspec( + RespondToClaimAdmitPartLRspec.builder() + .whenWillThisAmountBePaid(whenWillPay) + .build() + ); SealedClaimLipResponseForm templateData = generator - .getTemplateData(caseData); + .getTemplateData(builder.build()); Assertions.assertEquals(LocalDate.now(), templateData.getGenerationDate()); } @@ -174,6 +179,7 @@ void admitPayByDate() { @Test void partAdmitPayImmediate() { + LocalDate whenWillPay = LocalDate.now().plusDays(5); CaseData.CaseDataBuilder builder = commonData() .respondent1(company("B")) .respondent2(individual("C")) @@ -181,7 +187,12 @@ void partAdmitPayImmediate() { .specDefenceAdmittedRequired(YesOrNo.NO) .respondToAdmittedClaimOwingAmount(BigDecimal.valueOf(2000)) .detailsOfWhyDoesYouDisputeTheClaim("Reason to dispute the claim") - .defenceAdmitPartPaymentTimeRouteRequired(RespondentResponsePartAdmissionPaymentTimeLRspec.IMMEDIATELY); + .defenceAdmitPartPaymentTimeRouteRequired(RespondentResponsePartAdmissionPaymentTimeLRspec.IMMEDIATELY) + .respondToClaimAdmitPartLRspec( + RespondToClaimAdmitPartLRspec.builder() + .whenWillThisAmountBePaid(whenWillPay) + .build() + ); CaseData caseData = timeline(financialDetails(builder)) .build(); @@ -340,11 +351,17 @@ void counterClaim() { @Test void shouldGenerateDocumentSuccessfullyForFullAdmit() { //Given + LocalDate whenWillPay = LocalDate.now().plusDays(5); CaseData caseData = commonData() .respondent1(company("B")) .respondent2(individual("C")) .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) .defenceAdmitPartPaymentTimeRouteRequired(RespondentResponsePartAdmissionPaymentTimeLRspec.IMMEDIATELY) + .respondToClaimAdmitPartLRspec( + RespondToClaimAdmitPartLRspec.builder() + .whenWillThisAmountBePaid(whenWillPay) + .build() + ) .build(); String fileName = "someName"; DocmosisDocument docmosisDocument = mock(DocmosisDocument.class); @@ -365,6 +382,7 @@ void shouldGenerateDocumentSuccessfullyForFullAdmit() { @Test void shouldGenerateDocumentSuccessfullyForPartAdmit() { //Given + LocalDate whenWillPay = LocalDate.now().plusDays(5); CaseData caseData = commonData() .respondent1(company("B")) .respondent2(individual("C")) @@ -373,7 +391,11 @@ void shouldGenerateDocumentSuccessfullyForPartAdmit() { .respondToAdmittedClaimOwingAmount(BigDecimal.valueOf(2000)) .detailsOfWhyDoesYouDisputeTheClaim("Reason to dispute the claim") .defenceAdmitPartPaymentTimeRouteRequired(RespondentResponsePartAdmissionPaymentTimeLRspec.IMMEDIATELY) - .build(); + .respondToClaimAdmitPartLRspec( + RespondToClaimAdmitPartLRspec.builder() + .whenWillThisAmountBePaid(whenWillPay) + .build() + ).build(); String fileName = "someName"; DocmosisDocument docmosisDocument = mock(DocmosisDocument.class); byte[] bytes = {}; From d17824f6442dbb56ae87e64b24c83fe8da938c33 Mon Sep 17 00:00:00 2001 From: drummondjm <93932689+drummondjm@users.noreply.github.com> Date: Mon, 13 Nov 2023 11:07:36 +0000 Subject: [PATCH 23/28] CIV-11342 categories for DocumentCosts (#3537) * updated categories for DocumentCosts * checkstyle * removed unused categories * reapply 11342 changes --------- Co-authored-by: vasudevganesanhmcts <100689363+vasudevganesanhmcts@users.noreply.github.com> --- .../user/EvidenceUploadHandlerBase.java | 21 +++++++++---------- .../EvidenceUploadApplicantHandlerTest.java | 2 +- .../EvidenceUploadRespondentHandlerTest.java | 2 +- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadHandlerBase.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadHandlerBase.java index e69ffd03ba7..5277c8351c6 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadHandlerBase.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadHandlerBase.java @@ -118,23 +118,22 @@ abstract class EvidenceUploadHandlerBase extends CallbackHandler { protected static final String RESPONDENT_ONE_PRE_TRIAL_SUMMARY = "RespondentOnePreTrialSummary"; protected static final String RESPONDENT_ONE_TRIAL_SKELETON = "RespondentOneTrialSkeleton"; protected static final String RESPONDENT_ONE_PRECEDENT_H = "RespondentOneUploadedPrecedentH"; - protected static final String RESPONDENT_ONE_ANY_PRECEDENT_H = "respondentOneAnyPrecedentH"; protected static final String RESPONDENT_TWO_DISCLOSURE_LIST = "RespondentTwoDisclosureList"; protected static final String RESPONDENT_TWO_PRE_TRIAL_SUMMARY = "RespondentTwoPreTrialSummary"; protected static final String RESPONDENT_TWO_TRIAL_SKELETON = "RespondentTwoTrialSkeleton"; protected static final String RESPONDENT_TWO_PRECEDENT_H = "RespondentTwoUploadedPrecedentH"; - protected static final String RESPONDENT_TWO_ANY_PRECEDENT_H = "respondentTwoAnyPrecedentH"; + protected static final String RESPONDENT_ONE_SCHEDULE_OF_COSTS = "RespondentSchedulesOfCost"; + protected static final String RESPONDENT_TWO_SCHEDULE_OF_COSTS = "RespondentTwoSchedulesOfCost"; protected static final String APPLICANT_DISCLOSURE_LIST = "ApplicantDisclosureList"; protected static final String APPLICANT_PRE_TRIAL_SUMMARY = "ApplicantPreTrialSummary"; protected static final String APPLICANT_TRIAL_SKELETON = "ApplicantTrialSkeleton"; protected static final String APPLICANT_PRECEDENT_H = "ApplicantUploadedPrecedentH"; - protected static final String APPLICANT_ANY_PRECEDENT_H = "ApplicantAnyPrecedentH"; protected static final String APPLICANT_TWO_DISCLOSURE_LIST = "ApplicantTwoDisclosureList"; protected static final String APPLICANT_TWO_PRE_TRIAL_SUMMARY = "ApplicantTwoPreTrialSummary"; protected static final String APPLICANT_TWO_TRIAL_SKELETON = "ApplicantTwoTrialSkeleton"; protected static final String APPLICANT_TWO_PRECEDENT_H = "ApplicantTwoUploadedPrecedentH"; - protected static final String APPLICANT_TWO_ANY_PRECEDENT_H = "ApplicantTwoAnyPrecedentH"; - + protected static final String APPLICANT_SCHEDULE_OF_COSTS = "ApplicantSchedulesOfCost"; + protected static final String APPLICANT_TWO_SCHEDULE_OF_COSTS = "ApplicantTwoSchedulesOfCost"; // Notification Strings used for email protected static StringBuilder notificationString = new StringBuilder(); protected static final String DISCLOSURE_LIST_TEXT = "%s - Disclosure list"; @@ -635,7 +634,7 @@ CallbackResponse documentUploadTime(CallbackParams callbackParams) { TRIAL_SKELETON_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); setCategoryIdAndRenameDoc(caseData.getDocumentAuthoritiesRes(), document -> document.getValue().getDocumentUpload(), RESPONDENT_ONE_PRECEDENT_H, TRIAL_AUTHORITIES_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); - setCategoryIdAndRenameDoc(caseData.getDocumentCostsRes(), document -> document.getValue().getDocumentUpload(), RESPONDENT_ONE_ANY_PRECEDENT_H, + setCategoryIdAndRenameDoc(caseData.getDocumentCostsRes(), document -> document.getValue().getDocumentUpload(), RESPONDENT_ONE_SCHEDULE_OF_COSTS, TRIAL_COSTS_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); setCategoryIdAndRenameDoc(caseData.getDocumentEvidenceForTrialRes(), document -> document.getValue().getDocumentUpload(), RESPONDENT_ONE_TRIAL_DOC_CORRESPONDENCE, TRIAL_DOC_CORRESPONDENCE_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); @@ -671,7 +670,7 @@ CallbackResponse documentUploadTime(CallbackParams callbackParams) { TRIAL_SKELETON_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); setCategoryIdAndRenameDoc(caseData.getDocumentAuthoritiesRes2(), document -> document.getValue().getDocumentUpload(), RESPONDENT_TWO_PRECEDENT_H, TRIAL_AUTHORITIES_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); - setCategoryIdAndRenameDoc(caseData.getDocumentCostsRes2(), document -> document.getValue().getDocumentUpload(), RESPONDENT_TWO_ANY_PRECEDENT_H, + setCategoryIdAndRenameDoc(caseData.getDocumentCostsRes2(), document -> document.getValue().getDocumentUpload(), RESPONDENT_TWO_SCHEDULE_OF_COSTS, TRIAL_COSTS_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); setCategoryIdAndRenameDoc(caseData.getDocumentEvidenceForTrialRes2(), document -> document.getValue().getDocumentUpload(), RESPONDENT_TWO_TRIAL_DOC_CORRESPONDENCE, TRIAL_DOC_CORRESPONDENCE_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), defendantString); @@ -708,7 +707,7 @@ CallbackResponse documentUploadTime(CallbackParams callbackParams) { TRIAL_SKELETON_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); setCategoryIdAndRenameDoc(caseData.getDocumentAuthorities(), document -> document.getValue().getDocumentUpload(), APPLICANT_PRECEDENT_H, TRIAL_AUTHORITIES_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); - setCategoryIdAndRenameDoc(caseData.getDocumentCosts(), document -> document.getValue().getDocumentUpload(), APPLICANT_ANY_PRECEDENT_H, + setCategoryIdAndRenameDoc(caseData.getDocumentCosts(), document -> document.getValue().getDocumentUpload(), APPLICANT_SCHEDULE_OF_COSTS, TRIAL_COSTS_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); setCategoryIdAndRenameDoc(caseData.getDocumentEvidenceForTrial(), document -> document.getValue().getDocumentUpload(), APPLICANT_TRIAL_DOC_CORRESPONDENCE, TRIAL_DOC_CORRESPONDENCE_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); @@ -745,7 +744,7 @@ CallbackResponse documentUploadTime(CallbackParams callbackParams) { TRIAL_SKELETON_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); setCategoryIdAndRenameDoc(caseData.getDocumentAuthoritiesApp2(), document -> document.getValue().getDocumentUpload(), APPLICANT_TWO_PRECEDENT_H, TRIAL_AUTHORITIES_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); - setCategoryIdAndRenameDoc(caseData.getDocumentCostsApp2(), document -> document.getValue().getDocumentUpload(), APPLICANT_TWO_ANY_PRECEDENT_H, + setCategoryIdAndRenameDoc(caseData.getDocumentCostsApp2(), document -> document.getValue().getDocumentUpload(), APPLICANT_TWO_SCHEDULE_OF_COSTS, TRIAL_COSTS_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); setCategoryIdAndRenameDoc(caseData.getDocumentEvidenceForTrialApp2(), document -> document.getValue().getDocumentUpload(), APPLICANT_TWO_TRIAL_DOC_CORRESPONDENCE, TRIAL_DOC_CORRESPONDENCE_TEXT, documentDateTime -> documentDateTime.getValue().getCreatedDatetime(), claimantString); @@ -872,7 +871,7 @@ private CaseData copyResp1ChangesToResp2(CaseData caseData, CaseData.CaseDataBui evidenceDocToCopy = compareAndCopy(caseDataBefore.getDocumentCostsRes(), caseData.getDocumentCostsRes(), caseData.getDocumentCostsRes2()); - evidenceDocToAdd = deepCopyUploadEvidenceDocumentType(evidenceDocToCopy, RESPONDENT_TWO_ANY_PRECEDENT_H); + evidenceDocToAdd = deepCopyUploadEvidenceDocumentType(evidenceDocToCopy, RESPONDENT_TWO_SCHEDULE_OF_COSTS); builder.documentCostsRes2(evidenceDocToAdd); evidenceDocToCopy = compareAndCopy(caseDataBefore.getDocumentEvidenceForTrialRes(), @@ -984,7 +983,7 @@ private CaseData copyApp1ChangesToApp2(CaseData caseData, CaseData.CaseDataBuild evidenceDocToCopy = compareAndCopy(caseDataBefore.getDocumentCosts(), caseData.getDocumentCosts(), caseData.getDocumentCostsApp2()); - evidenceDocToAdd = deepCopyUploadEvidenceDocumentType(evidenceDocToCopy, APPLICANT_TWO_ANY_PRECEDENT_H); + evidenceDocToAdd = deepCopyUploadEvidenceDocumentType(evidenceDocToCopy, APPLICANT_TWO_SCHEDULE_OF_COSTS); builder.documentCostsApp2(evidenceDocToAdd); evidenceDocToCopy = compareAndCopy(caseDataBefore.getDocumentEvidenceForTrial(), diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandlerTest.java index cda6fc74fc7..3704297d425 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandlerTest.java @@ -843,7 +843,7 @@ void should_do_naming_convention(String selected) { assertThat(updatedData.getDocumentCostsApp2().get(0).getValue() .getDocumentUpload().getDocumentFileName()).isEqualTo(TEST_FILE_NAME); assertThat(updatedData.getDocumentCostsApp2().get(0).getValue() - .getDocumentUpload().getCategoryID()).isEqualTo(EvidenceUploadHandlerBase.APPLICANT_TWO_ANY_PRECEDENT_H); + .getDocumentUpload().getCategoryID()).isEqualTo(EvidenceUploadHandlerBase.APPLICANT_TWO_SCHEDULE_OF_COSTS); assertThat(updatedData.getNotificationText()).isEqualTo(NotificationWhenBothClaimant); } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandlerTest.java index 455cd043a2e..d5c32eeac09 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandlerTest.java @@ -1451,7 +1451,7 @@ void should_do_naming_convention_resp1(String selected) { assertThat(updatedData.getDocumentCostsRes2().get(0).getValue() .getDocumentUpload().getDocumentFileName()).isEqualTo(TEST_FILE_NAME); assertThat(updatedData.getDocumentCostsRes2().get(0).getValue() - .getDocumentUpload().getCategoryID()).isEqualTo(EvidenceUploadHandlerBase.RESPONDENT_TWO_ANY_PRECEDENT_H); + .getDocumentUpload().getCategoryID()).isEqualTo(EvidenceUploadHandlerBase.RESPONDENT_TWO_SCHEDULE_OF_COSTS); assertThat(updatedData.getNotificationText()).contains(NotificationWhenBothDefendant); } } From e3851f09da9a8575ee449275c0779debd3b0c902 Mon Sep 17 00:00:00 2001 From: sankaviv1 <95748224+sankaviv1@users.noreply.github.com> Date: Mon, 13 Nov 2023 13:40:41 +0000 Subject: [PATCH 24/28] CIV-10094 Case flags updates for new parties (#3229) * Added new ManageContactInformation callback handler and event and whitelisted it within the AllowedFlowState service. * Added new ManageContactInformation callback handler and event and whitelisted it within the AllowedFlowState service. * CIV-9992 add options for manage contact information * revert accidental commit * add utils test * update utils test * add test scenarios for handler * update handler tests * add IDs to party options * changed name of some variables * added chosenpartytype and chosenpartyid to determine what to show on page 2, wip on applicant/defendant pages * adding tests ManageContactInformationUtilsTest * changed some keys, updated tests * experts and witnesses form wip * show experts on ui * make id fields public * CIV-10094 create/update case flags names for new/edited individuals * add unit tests * Cherry picked the 3 main commits from CIV-3216 Added partyID to dq witness and expert objects. Enabled the initialisation on party Ids in DQ witnesses and experts and copied partyIDs into their relative case level counterparts Moved changes behind hmc toggle Fixed duplicate append call * Updated experts and witnesses to have mappings * changed utils class back to static and removed mocks * Fixed witnesses * fixed litigation friend * append with party ID * remove unnecessary changes * remove unnecessary tests * update tests for party ids * fixed capability to delete all experts/witnesses and add new expert/witnesses when never existed before * postcode * removed unnecessary lines and imports * fix conflicts * fixed data going missing for applicant 1 for party id * fixed claim details tab * added ccd data store image in charts * fixed test * sonar fix --------- Co-authored-by: GarethLancaster <31533575+Gareth40342@users.noreply.github.com> Co-authored-by: sherlynkhaw Co-authored-by: Gareth Lancaster <90632240+Gareth40343@users.noreply.github.com> Co-authored-by: TurkingtonL Co-authored-by: AhsanZX97 --- ...nageContactInformationCallbackHandler.java | 5 + .../reform/civil/utils/CaseFlagUtils.java | 180 ++++- .../civil/utils/CaseFlagsInitialiser.java | 31 +- ...ContactInformationCallbackHandlerTest.java | 4 + .../civil/sampledata/CaseDataBuilder.java | 135 ++++ .../reform/civil/utils/CaseFlagUtilsTest.java | 692 ++++++++++++++++++ .../civil/utils/CaseFlagsInitialiserTest.java | 35 +- 7 files changed, 1064 insertions(+), 18 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandler.java index f7570b2557a..1ce5e75b370 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandler.java @@ -27,6 +27,7 @@ import uk.gov.hmcts.reform.civil.model.dq.Witness; import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; import uk.gov.hmcts.reform.civil.service.UserService; +import uk.gov.hmcts.reform.civil.utils.CaseFlagsInitialiser; import uk.gov.hmcts.reform.civil.validation.PostcodeValidator; import uk.gov.hmcts.reform.idam.client.models.UserInfo; @@ -97,6 +98,7 @@ public class ManageContactInformationCallbackHandler extends CallbackHandler { private final UserService userService; private final ObjectMapper objectMapper; private final CaseDetailsConverter caseDetailsConverter; + private final CaseFlagsInitialiser caseFlagsInitialiser; private final PostcodeValidator postcodeValidator; @Override @@ -345,6 +347,9 @@ private CallbackResponse submitChanges(CallbackParams callbackParams) { updateExperts(caseData.getUpdateDetailsForm().getPartyChosenId(), caseData, builder); updateWitnesses(caseData.getUpdateDetailsForm().getPartyChosenId(), caseData, builder); + // last step before clearing update details form + caseFlagsInitialiser.initialiseCaseFlags(MANAGE_CONTACT_INFORMATION, builder); + // clear updateDetailsForm builder.updateDetailsForm(UpdateDetailsForm.builder().manageContactDetailsEventUsed(YES).build()); diff --git a/src/main/java/uk/gov/hmcts/reform/civil/utils/CaseFlagUtils.java b/src/main/java/uk/gov/hmcts/reform/civil/utils/CaseFlagUtils.java index 62a60317e95..cfc0249f777 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/utils/CaseFlagUtils.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/utils/CaseFlagUtils.java @@ -1,5 +1,6 @@ package uk.gov.hmcts.reform.civil.utils; +import uk.gov.hmcts.reform.ccd.model.OrganisationPolicy; import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.model.PartyFlagStructure; import uk.gov.hmcts.reform.civil.model.caseflags.FlagDetail; @@ -22,18 +23,45 @@ import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; import static uk.gov.hmcts.reform.civil.utils.ElementUtils.element; import static uk.gov.hmcts.reform.civil.utils.ElementUtils.unwrapElements; +import static uk.gov.hmcts.reform.civil.utils.ElementUtils.wrapElements; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_LEGAL_REP_INDIVIDUALS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_LITIGATION_FRIEND_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_ORG_INDIVIDUALS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_TWO_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_TWO_LITIGATION_FRIEND_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_TWO_ORG_INDIVIDUALS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_LEGAL_REP_INDIVIDUALS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_LITIGATION_FRIEND_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_ORG_INDIVIDUALS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_LEGAL_REP_INDIVIDUALS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_LITIGATION_FRIEND_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_ORG_INDIVIDUALS_ID; +import static uk.gov.hmcts.reform.civil.utils.PartyUtils.appendWithNewPartyId; import uk.gov.hmcts.reform.civil.model.LitigationFriend; import uk.gov.hmcts.reform.civil.model.Party; +import uk.gov.hmcts.reform.civil.prd.model.Organisation; +import uk.gov.hmcts.reform.civil.service.OrganisationService; public class CaseFlagUtils { - public static String RESPONDENT_SOLICITOR_ONE_WITNESS = "Respondent solicitor 1 witness"; - public static String RESPONDENT_SOLICITOR_ONE_EXPERT = "Respondent solicitor 1 expert"; - public static String RESPONDENT_SOLICITOR_TWO_WITNESS = "Respondent solicitor 2 witness"; - public static String RESPONDENT_SOLICITOR_TWO_EXPERT = "Respondent solicitor 2 expert"; - public static String APPLICANT_SOLICITOR_WITNESS = "Applicant solicitor witness"; - public static String APPLICANT_SOLICITOR_EXPERT = "Applicant solicitor expert"; + public static final String RESPONDENT_SOLICITOR_ONE_WITNESS = "Respondent solicitor 1 witness"; + public static final String RESPONDENT_SOLICITOR_ONE_EXPERT = "Respondent solicitor 1 expert"; + public static final String RESPONDENT_SOLICITOR_TWO_WITNESS = "Respondent solicitor 2 witness"; + public static final String RESPONDENT_SOLICITOR_TWO_EXPERT = "Respondent solicitor 2 expert"; + public static final String APPLICANT_SOLICITOR_WITNESS = "Applicant solicitor witness"; + public static final String APPLICANT_SOLICITOR_EXPERT = "Applicant solicitor expert"; + public static final String APPLICANT_ONE = "Applicant 1"; + public static final String APPLICANT_TWO = "Applicant 2"; + public static final String APPLICANT_ONE_LITIGATION_FRIEND = "Applicant 1 Litigation Friend"; + public static final String APPLICANT_TWO_LITIGATION_FRIEND = "Applicant 2 Litigation Friend"; + public static final String RESPONDENT_ONE = "Respondent 1"; + public static final String RESPONDENT_TWO = "Respondent 2"; + public static final String RESPONDENT_ONE_LITIGATION_FRIEND = "Respondent 1 Litigation Friend"; + public static final String RESPONDENT_TWO_LITIGATION_FRIEND = "Respondent 2 Litigation Friend"; private CaseFlagUtils() { //NO-OP @@ -49,7 +77,7 @@ public static Flags createFlags(String flagsPartyName, String roleOnCase) { private static PartyFlagStructure createPartiesCaseFlagsField(String partyId, String firstName, String lastName, String email, String phone, String roleOnCase) { - String partyName = String.format("%s %s", firstName, lastName); + String partyName = formattedPartyNameForFlags(firstName, lastName); return PartyFlagStructure.builder() .partyID(partyId) .firstName(firstName) @@ -72,7 +100,7 @@ public static LitigationFriend updateLitFriend(String roleOnCase, LitigationFrie // ToDo: Remove the use of fullName after H&L changes are default ===================================== litFriendToUpdate.getFullName() != null ? litFriendToUpdate.getFullName() // ==================================================================================================== - : String.format("%s %s", litFriendToUpdate.getFirstName(), litFriendToUpdate.getLastName()), + : formattedPartyNameForFlags(litFriendToUpdate.getFirstName(), litFriendToUpdate.getLastName()), roleOnCase)).build() : null; } @@ -171,6 +199,129 @@ public static void addApplicantExpertAndWitnessFlagsStructure(CaseData.CaseDataB } } + public static void createOrUpdateFlags(CaseData.CaseDataBuilder builder, CaseData caseData, OrganisationService organisationService) { + String partyChosen = caseData.getUpdateDetailsForm().getPartyChosenId(); + // claimant/defendant + updatePartyFlags(builder, caseData, partyChosen); + // litigation friend + updateLitigationFriendFlags(builder, caseData, partyChosen); + // attending for org/company + updateOrgIndividualsFlags(builder, caseData, partyChosen); + // attending for legal rep + updateLRIndividualsFlags(builder, caseData, partyChosen, organisationService); + } + + private static void updateLRIndividualsFlags(CaseData.CaseDataBuilder builder, CaseData caseData, String partyChosen, OrganisationService organisationService) { + if ((CLAIMANT_ONE_LEGAL_REP_INDIVIDUALS_ID).equals(partyChosen)) { + String legalRepFirmName = getLegalRepFirmName( + caseData.getApplicant1OrganisationPolicy(), + organisationService, + APPLICANT_ONE); + builder.applicant1LRIndividuals(updatePartyNameForPartyFlagStructures(caseData.getApplicant1LRIndividuals(), legalRepFirmName)); + } + if ((DEFENDANT_ONE_LEGAL_REP_INDIVIDUALS_ID).equals(partyChosen)) { + String legalRepFirmName = getLegalRepFirmName( + caseData.getRespondent1OrganisationPolicy(), + organisationService, + RESPONDENT_ONE); + builder.respondent1LRIndividuals(updatePartyNameForPartyFlagStructures(caseData.getRespondent1LRIndividuals(), legalRepFirmName)); + } + if ((DEFENDANT_TWO_LEGAL_REP_INDIVIDUALS_ID).equals(partyChosen)) { + String legalRepFirmName = getLegalRepFirmName( + caseData.getRespondent2OrganisationPolicy(), + organisationService, + RESPONDENT_TWO); + builder.respondent2LRIndividuals(updatePartyNameForPartyFlagStructures(caseData.getRespondent2LRIndividuals(), legalRepFirmName)); + } + } + + private static void updateOrgIndividualsFlags(CaseData.CaseDataBuilder builder, CaseData caseData, String partyChosen) { + if ((CLAIMANT_ONE_ORG_INDIVIDUALS_ID).equals(partyChosen)) { + builder.applicant1OrgIndividuals(updatePartyNameForPartyFlagStructures(caseData.getApplicant1OrgIndividuals(), caseData.getApplicant1().getPartyName())); + } + if ((CLAIMANT_TWO_ORG_INDIVIDUALS_ID).equals(partyChosen)) { + builder.applicant2OrgIndividuals(updatePartyNameForPartyFlagStructures(caseData.getApplicant2OrgIndividuals(), caseData.getApplicant2().getPartyName())); + } + if ((DEFENDANT_ONE_ORG_INDIVIDUALS_ID).equals(partyChosen)) { + builder.respondent1OrgIndividuals(updatePartyNameForPartyFlagStructures(caseData.getRespondent1OrgIndividuals(), caseData.getRespondent1().getPartyName())); + } + if ((DEFENDANT_TWO_ORG_INDIVIDUALS_ID).equals(partyChosen)) { + builder.respondent2OrgIndividuals(updatePartyNameForPartyFlagStructures(caseData.getRespondent2OrgIndividuals(), caseData.getRespondent2().getPartyName())); + } + } + + private static void updateLitigationFriendFlags(CaseData.CaseDataBuilder builder, CaseData caseData, String partyChosen) { + if ((CLAIMANT_ONE_LITIGATION_FRIEND_ID).equals(partyChosen)) { + builder.applicant1LitigationFriend(updatePartyNameForLitigationFriendFlags(caseData.getApplicant1LitigationFriend())); + } + if ((CLAIMANT_TWO_LITIGATION_FRIEND_ID).equals(partyChosen)) { + builder.applicant2LitigationFriend(updatePartyNameForLitigationFriendFlags(caseData.getApplicant2LitigationFriend())); + } + if ((DEFENDANT_ONE_LITIGATION_FRIEND_ID).equals(partyChosen)) { + builder.respondent1LitigationFriend(updatePartyNameForLitigationFriendFlags(caseData.getRespondent1LitigationFriend())); + } + if ((DEFENDANT_TWO_LITIGATION_FRIEND_ID).equals(partyChosen)) { + builder.respondent2LitigationFriend(updatePartyNameForLitigationFriendFlags(caseData.getRespondent2LitigationFriend())); + } + } + + private static void updatePartyFlags(CaseData.CaseDataBuilder builder, CaseData caseData, String partyChosen) { + if ((CLAIMANT_ONE_ID).equals(partyChosen)) { + builder.applicant1(updatePartyNameForFlags(caseData.getApplicant1())); + } + if ((CLAIMANT_TWO_ID).equals(partyChosen)) { + builder.applicant2(updatePartyNameForFlags(caseData.getApplicant2())); + } + if ((DEFENDANT_ONE_ID).equals(partyChosen)) { + builder.respondent1(updatePartyNameForFlags(caseData.getRespondent1())); + } + if ((DEFENDANT_TWO_ID).equals(partyChosen)) { + builder.respondent2(updatePartyNameForFlags(caseData.getRespondent2())); + } + } + + private static List> updatePartyNameForPartyFlagStructures(List> individuals, + String roleOnCase) { + if (individuals != null && !individuals.isEmpty()) { + List partyFlagStructures = unwrapElements(individuals); + List updatedList = new ArrayList<>(); + for (PartyFlagStructure partyFlagStructure : partyFlagStructures) { + String formattedPartyNameForFlags = formattedPartyNameForFlags(partyFlagStructure.getFirstName(), partyFlagStructure.getLastName()); + if (partyFlagStructure.getFlags() == null) { + // new party so initialise flags and party ID + updatedList.add( + appendWithNewPartyId(partyFlagStructure + .toBuilder() + .flags(createFlags(formattedPartyNameForFlags, roleOnCase)).build())); + } else { + // existing party with flags so just update the name + updatedList.add( + partyFlagStructure + .toBuilder() + .flags(partyFlagStructure.getFlags().toBuilder() + .partyName(formattedPartyNameForFlags) + .build()).build()); + } + } + return wrapElements(updatedList); + } + return null; + } + + private static Party updatePartyNameForFlags(Party party) { + return party.toBuilder().flags(party.getFlags().toBuilder() + .partyName(party.getPartyName()) + .build()).build(); + } + + private static LitigationFriend updatePartyNameForLitigationFriendFlags(LitigationFriend litigationFriend) { + return litigationFriend.toBuilder() + .flags(litigationFriend.getFlags().toBuilder() + .partyName(litigationFriend.getFullName() != null ? litigationFriend.getFullName() + : formattedPartyNameForFlags(litigationFriend.getFirstName(), litigationFriend.getLastName())) + .build()).build(); + } + public static List getAllCaseFlags(CaseData caseData) { var flagCollection = new ArrayList(); flagCollection.addAll(getFlagDetails(caseData.getCaseFlags())); @@ -222,4 +373,17 @@ public static List filter(List flagDetails, Predicate true)) .collect(Collectors.toList()); } + + private static String formattedPartyNameForFlags(String firstName, String lastName) { + return String.format("%s %s", firstName, lastName); + } + + private static String getLegalRepFirmName(OrganisationPolicy organisationPolicy, + OrganisationService organisationService, + String party) { + String organisationID = organisationPolicy.getOrganisation().getOrganisationID(); + return organisationService.findOrganisationById(organisationID) + .map(Organisation::getName) + .orElse(String.format("legal representative for %s", party.toLowerCase())); + } } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/utils/CaseFlagsInitialiser.java b/src/main/java/uk/gov/hmcts/reform/civil/utils/CaseFlagsInitialiser.java index 8955dff6ea4..708b197e462 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/utils/CaseFlagsInitialiser.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/utils/CaseFlagsInitialiser.java @@ -5,16 +5,27 @@ import uk.gov.hmcts.reform.civil.callback.CaseEvent; import uk.gov.hmcts.reform.civil.service.FeatureToggleService; import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.service.OrganisationService; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; +import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.APPLICANT_ONE; +import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.APPLICANT_ONE_LITIGATION_FRIEND; +import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.APPLICANT_TWO; +import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.APPLICANT_TWO_LITIGATION_FRIEND; +import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.RESPONDENT_ONE; +import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.RESPONDENT_ONE_LITIGATION_FRIEND; +import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.RESPONDENT_TWO; +import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.RESPONDENT_TWO_LITIGATION_FRIEND; import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.addApplicantExpertAndWitnessFlagsStructure; import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.addRespondentDQPartiesFlagStructure; +import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.createOrUpdateFlags; @Component @AllArgsConstructor public class CaseFlagsInitialiser { private final FeatureToggleService featureToggleService; + private final OrganisationService organisationService; public void initialiseCaseFlags(CaseEvent caseEvent, CaseData.CaseDataBuilder dataBuilder) { if (!featureToggleService.isCaseFlagsEnabled()) { @@ -42,6 +53,10 @@ public void initialiseCaseFlags(CaseEvent caseEvent, CaseData.CaseDataBuilder da addApplicantExpertAndWitnessFlagsStructure(dataBuilder, caseData); break; } + case MANAGE_CONTACT_INFORMATION: { + createOrUpdateFlags(dataBuilder, caseData, organisationService); + break; + } default: } } @@ -62,26 +77,26 @@ private void initialiseRespondentLitigationFriendFlags(CaseData.CaseDataBuilder dataBuilder .respondent1LitigationFriend( CaseFlagUtils.updateLitFriend( - "Respondent 1 Litigation Friend", + RESPONDENT_ONE_LITIGATION_FRIEND, caseData.getRespondent1LitigationFriend() )) .respondent2LitigationFriend( CaseFlagUtils.updateLitFriend( - "Respondent 2 Litigation Friend", + RESPONDENT_TWO_LITIGATION_FRIEND, caseData.getRespondent2LitigationFriend() )); } private void initialiseApplicantAndRespondentFlags(CaseData.CaseDataBuilder dataBuilder, CaseData caseData) { dataBuilder - .applicant1(CaseFlagUtils.updateParty("Applicant 1", caseData.getApplicant1())) - .applicant2(CaseFlagUtils.updateParty("Applicant 2", caseData.getApplicant2())) - .respondent1(CaseFlagUtils.updateParty("Respondent 1", caseData.getRespondent1())) - .respondent2(CaseFlagUtils.updateParty("Respondent 2", caseData.getRespondent2())) + .applicant1(CaseFlagUtils.updateParty(APPLICANT_ONE, caseData.getApplicant1())) + .applicant2(CaseFlagUtils.updateParty(APPLICANT_TWO, caseData.getApplicant2())) + .respondent1(CaseFlagUtils.updateParty(RESPONDENT_ONE, caseData.getRespondent1())) + .respondent2(CaseFlagUtils.updateParty(RESPONDENT_TWO, caseData.getRespondent2())) .applicant1LitigationFriend(CaseFlagUtils.updateLitFriend( - "Applicant 1 Litigation Friend", caseData.getApplicant1LitigationFriend())) + APPLICANT_ONE_LITIGATION_FRIEND, caseData.getApplicant1LitigationFriend())) .applicant2LitigationFriend(CaseFlagUtils.updateLitFriend( - "Applicant 2 Litigation Friend", caseData.getApplicant2LitigationFriend())); + APPLICANT_TWO_LITIGATION_FRIEND, caseData.getApplicant2LitigationFriend())); } private boolean shouldReinitialiseRespondentDQFlags(CaseData caseData) { diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandlerTest.java index de083369ffa..8ff9b667be7 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandlerTest.java @@ -36,6 +36,7 @@ import uk.gov.hmcts.reform.civil.model.dq.Witnesses; import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; +import uk.gov.hmcts.reform.civil.utils.CaseFlagsInitialiser; import uk.gov.hmcts.reform.civil.validation.PostcodeValidator; import uk.gov.hmcts.reform.idam.client.models.UserInfo; import java.time.LocalDate; @@ -86,6 +87,9 @@ class ManageContactInformationCallbackHandlerTest extends BaseCallbackHandlerTes @Autowired private ObjectMapper mapper; + @MockBean + private CaseFlagsInitialiser caseFlagInitialiser; + @MockBean private CoreCaseUserService coreCaseUserService; diff --git a/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilder.java b/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilder.java index 4b2a4a05581..df35ed83ab4 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilder.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilder.java @@ -488,6 +488,15 @@ public class CaseDataBuilder { private NotSuitableSdoOptions notSuitableSdoOptions; + private List> applicant1LRIndividuals; + private List> respondent1LRIndividuals; + private List> respondent2LRIndividuals; + + private List> applicant1OrgIndividuals; + private List> applicant2OrgIndividuals; + private List> respondent1OrgIndividuals; + private List> respondent2OrgIndividuals; + protected String hearingReference; protected ListingOrRelisting listingOrRelisting; @@ -6131,6 +6140,125 @@ public CaseDataBuilder atTrialHearingWitnessOfFactWithNegativeInputs() { return this; } + public CaseDataBuilder addApplicantLRIndividual(String firstName, String lastName) { + List> individual = + wrapElements(PartyFlagStructure.builder() + .partyID("app-lr-ind-party-id") + .firstName(firstName) + .lastName(lastName) + .email("abc@def.ghi") + .phone("07777777777") + .build()); + if (this.applicant1LRIndividuals != null && !this.applicant1LRIndividuals.isEmpty()) { + this.applicant1LRIndividuals.addAll(individual); + } else { + this.applicant1LRIndividuals = individual; + } + return this; + } + + public CaseDataBuilder addRespondent1LRIndividual(String firstName, String lastName) { + List> individual = + wrapElements(PartyFlagStructure.builder() + .partyID("res-1-lr-ind-party-id") + .firstName(firstName) + .lastName(lastName) + .email("abc@def.ghi") + .phone("07777777777") + .build()); + if (this.respondent1LRIndividuals != null && !this.respondent1LRIndividuals.isEmpty()) { + this.respondent1LRIndividuals.addAll(individual); + } else { + this.respondent1LRIndividuals = individual; + } + return this; + } + + public CaseDataBuilder addRespondent2LRIndividual(String firstName, String lastName) { + List> individual = + wrapElements(PartyFlagStructure.builder() + .partyID("res-2-lr-ind-party-id") + .firstName(firstName) + .lastName(lastName) + .email("abc@def.ghi") + .phone("07777777777") + .build()); + if (this.respondent2LRIndividuals != null && !this.respondent2LRIndividuals.isEmpty()) { + this.respondent2LRIndividuals.addAll(individual); + } else { + this.respondent2LRIndividuals = individual; + } + return this; + } + + public CaseDataBuilder addApplicant1OrgIndividual(String firstName, String lastName) { + List> individual = + wrapElements(PartyFlagStructure.builder() + .partyID("app-1-org-ind-party-id") + .firstName(firstName) + .lastName(lastName) + .email("abc@def.ghi") + .phone("07777777777") + .build()); + if (this.applicant1OrgIndividuals != null && !this.applicant1OrgIndividuals.isEmpty()) { + this.applicant1OrgIndividuals.addAll(individual); + } else { + this.applicant1OrgIndividuals = individual; + } + return this; + } + + public CaseDataBuilder addApplicant2OrgIndividual(String firstName, String lastName) { + List> individual = + wrapElements(PartyFlagStructure.builder() + .partyID("app-2-org-ind-party-id") + .firstName(firstName) + .lastName(lastName) + .email("abc@def.ghi") + .phone("07777777777") + .build()); + if (this.applicant2OrgIndividuals != null && !this.applicant2OrgIndividuals.isEmpty()) { + this.applicant2OrgIndividuals.addAll(individual); + } else { + this.applicant2OrgIndividuals = individual; + } + return this; + } + + public CaseDataBuilder addRespondent1OrgIndividual(String firstName, String lastName) { + List> individual = + wrapElements(PartyFlagStructure.builder() + .partyID("res-1-org-ind-party-id") + .firstName(firstName) + .lastName(lastName) + .email("abc@def.ghi") + .phone("07777777777") + .build()); + if (this.respondent1OrgIndividuals != null && !this.respondent1OrgIndividuals.isEmpty()) { + this.respondent1OrgIndividuals.addAll(individual); + } else { + this.respondent1OrgIndividuals = individual; + } + return this; + } + + public CaseDataBuilder addRespondent2OrgIndividual(String firstName, String lastName) { + List> individual = + wrapElements(PartyFlagStructure.builder() + .partyID("res-2-org-ind-party-id") + .firstName(firstName) + .lastName(lastName) + .email("abc@def.ghi") + .phone("07777777777") + .build()); + if (this.respondent2OrgIndividuals != null && !this.respondent2OrgIndividuals.isEmpty()) { + this.respondent2OrgIndividuals.addAll(individual); + } else { + this.respondent2OrgIndividuals = individual; + } + return this; + } + public static CaseDataBuilder builder() { return new CaseDataBuilder(); } @@ -6416,6 +6544,13 @@ public CaseData build() { .drawDirectionsOrderRequired(drawDirectionsOrderRequired) .transferCourtLocationList(transferCourtLocationList) .reasonForTransfer(reasonForTransfer) + .applicant1LRIndividuals(applicant1LRIndividuals) + .respondent1LRIndividuals(respondent1LRIndividuals) + .respondent2LRIndividuals(respondent2LRIndividuals) + .applicant1OrgIndividuals(applicant1OrgIndividuals) + .applicant2OrgIndividuals(applicant2OrgIndividuals) + .respondent1OrgIndividuals(respondent1OrgIndividuals) + .respondent2OrgIndividuals(respondent2OrgIndividuals) .build(); } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/utils/CaseFlagUtilsTest.java b/src/test/java/uk/gov/hmcts/reform/civil/utils/CaseFlagUtilsTest.java index cca5bf3657e..aae666611d3 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/utils/CaseFlagUtilsTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/utils/CaseFlagUtilsTest.java @@ -1,5 +1,6 @@ package uk.gov.hmcts.reform.civil.utils; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -7,6 +8,7 @@ import uk.gov.hmcts.reform.civil.model.PartyFlagStructure; import uk.gov.hmcts.reform.civil.model.LitigationFriend; import uk.gov.hmcts.reform.civil.model.Party; +import uk.gov.hmcts.reform.civil.model.UpdateDetailsForm; import uk.gov.hmcts.reform.civil.model.caseflags.FlagDetail; import uk.gov.hmcts.reform.civil.model.caseflags.Flags; import uk.gov.hmcts.reform.civil.model.common.Element; @@ -18,15 +20,21 @@ import uk.gov.hmcts.reform.civil.model.dq.Respondent2DQ; import uk.gov.hmcts.reform.civil.model.dq.Witness; import uk.gov.hmcts.reform.civil.model.dq.Witnesses; +import uk.gov.hmcts.reform.civil.prd.model.Organisation; import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; import uk.gov.hmcts.reform.civil.sampledata.PartyBuilder; +import uk.gov.hmcts.reform.civil.service.OrganisationService; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.APPLICANT_SOLICITOR_EXPERT; @@ -39,10 +47,35 @@ import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.addRespondentDQPartiesFlagStructure; import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.filter; import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.getAllCaseFlags; +import static uk.gov.hmcts.reform.civil.utils.ElementUtils.unwrapElements; import static uk.gov.hmcts.reform.civil.utils.ElementUtils.wrapElements; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_LEGAL_REP_INDIVIDUALS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_LITIGATION_FRIEND_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_ORG_INDIVIDUALS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_TWO_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_TWO_LITIGATION_FRIEND_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_TWO_ORG_INDIVIDUALS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_LEGAL_REP_INDIVIDUALS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_LITIGATION_FRIEND_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_ORG_INDIVIDUALS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_LEGAL_REP_INDIVIDUALS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_LITIGATION_FRIEND_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_ORG_INDIVIDUALS_ID; class CaseFlagUtilsTest { + private OrganisationService organisationService; + + @BeforeEach + void setUp() { + organisationService = mock(OrganisationService.class); + when(organisationService.findOrganisationById(anyString())) + .thenReturn(Optional.of(Organisation.builder().name("Civil - Organisation").build())); + } + @Nested class CreateFlags { @@ -648,4 +681,663 @@ private List hearingRelevantFlagDetails() { return List.of(details1, details2, details3); } } + + @Nested + class CreateAndUpdateFlagNamesAfterManageContactInformationEvent { + + @Nested + class Parties { + + @Test + void shouldUpdateFlagName_whenClaimant1NameUpdated() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(CLAIMANT_ONE_ID).build()) + .build(); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .applicant1(caseData.getApplicant1().toBuilder() + .flags(Flags.builder() + .partyName("Mr. John Rambo") + .roleOnCase("applicant") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))).build()) + .individualFirstName("Johnny") + .individualLastName("Rambo new").build()); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + Flags actual = builder.build().getApplicant1().getFlags(); + Flags expected = Flags.builder().partyName("Mr. Johnny Rambo new") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))) + .roleOnCase("applicant").build(); + + assertThat(actual).isEqualTo(expected); + } + + @Test + void shouldUpdateFlagName_whenClaimant2NameUpdated() { + CaseData caseData = CaseDataBuilder.builder() + .multiPartyClaimTwoApplicants() + .atStateClaimIssued() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(CLAIMANT_TWO_ID).build()) + .build(); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .applicant2(caseData.getApplicant2().toBuilder() + .flags(Flags.builder() + .partyName("Mr. Jason Rambo") + .roleOnCase("applicant") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))).build()) + .individualFirstName("JJ") + .individualLastName("Rambo edited").build()); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + Flags actual = builder.build().getApplicant2().getFlags(); + Flags expected = Flags.builder().partyName("Mr. JJ Rambo edited") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))) + .roleOnCase("applicant").build(); + + assertThat(actual).isEqualTo(expected); + } + + @Test + void shouldUpdateFlagName_whenRespondent1NameUpdated() { + CaseData caseData = CaseDataBuilder.builder() + .atStateClaimIssued() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(DEFENDANT_ONE_ID).build()) + .build(); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .respondent1(caseData.getRespondent1().toBuilder() + .flags(Flags.builder() + .partyName("Mr. Sole Trader") + .roleOnCase("respondent") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))).build()) + .soleTraderFirstName("Solo") + .soleTraderLastName("New trader").build()); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + Flags actual = builder.build().getRespondent1().getFlags(); + Flags expected = Flags.builder().partyName("Mr. Solo New trader") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))) + .roleOnCase("respondent").build(); + + assertThat(actual).isEqualTo(expected); + } + + @Test + void shouldUpdateFlagName_whenRespondent2NameUpdated() { + CaseData caseData = CaseDataBuilder.builder() + .atStateClaimIssued() + .multiPartyClaimTwoDefendantSolicitors() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(DEFENDANT_TWO_ID).build()) + .build(); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .respondent2(caseData.getRespondent2().toBuilder() + .flags(Flags.builder() + .partyName("Mr. John Rambo") + .roleOnCase("respondent") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))).build()) + .individualTitle("Miss") + .individualFirstName("Jenny") + .individualLastName("Rombo").build()); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + Flags actual = builder.build().getRespondent2().getFlags(); + Flags expected = Flags.builder().partyName("Miss Jenny Rombo") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))) + .roleOnCase("respondent").build(); + + assertThat(actual).isEqualTo(expected); + } + } + + @Nested + class LitigationFriend { + + @Test + void shouldUpdateFlagName_whenClaimant1LitigationFriendNameUpdated() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .addApplicant1LitigationFriend() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(CLAIMANT_ONE_LITIGATION_FRIEND_ID).build()) + .build(); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .applicant1LitigationFriend(caseData.getApplicant1LitigationFriend().toBuilder() + .flags(Flags.builder() + .partyName("Mr. Applicant Litigation Friend") + .roleOnCase("litigation friend") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))).build()) + .fullName(null) + .firstName("Johnny").lastName("Rambo new") + .build()); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + Flags actual = builder.build().getApplicant1LitigationFriend().getFlags(); + Flags expected = Flags.builder().partyName("Johnny Rambo new") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))) + .roleOnCase("litigation friend").build(); + + assertThat(actual).isEqualTo(expected); + } + + @Test + void shouldUpdateFlagName_whenClaimant2LitigationFriendNameUpdated() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .addApplicant2LitigationFriend() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(CLAIMANT_TWO_LITIGATION_FRIEND_ID).build()) + .build(); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .applicant2LitigationFriend(caseData.getApplicant2LitigationFriend().toBuilder() + .flags(Flags.builder() + .partyName("Applicant Two Litigation Friend") + .roleOnCase("litigation friend") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))).build()) + .fullName(null) + .firstName("Johnny").lastName("Rambo new") + .build()); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + Flags actual = builder.build().getApplicant2LitigationFriend().getFlags(); + Flags expected = Flags.builder().partyName("Johnny Rambo new") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))) + .roleOnCase("litigation friend").build(); + + assertThat(actual).isEqualTo(expected); + } + + @Test + void shouldUpdateFlagName_whenRespondent1LitigationFriendNameUpdated() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .addRespondent1LitigationFriend() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(DEFENDANT_ONE_LITIGATION_FRIEND_ID).build()) + .build(); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .respondent1LitigationFriend(caseData.getRespondent1LitigationFriend().toBuilder() + .flags(Flags.builder() + .partyName("Litigation Friend") + .roleOnCase("litigation friend") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))).build()) + .fullName(null) + .firstName("Johnny").lastName("Rambo new") + .build()); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + Flags actual = builder.build().getRespondent1LitigationFriend().getFlags(); + Flags expected = Flags.builder().partyName("Johnny Rambo new") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))) + .roleOnCase("litigation friend").build(); + + assertThat(actual).isEqualTo(expected); + } + + @Test + void shouldUpdateFlagName_whenRespondent2LitigationFriendNameUpdated() { + CaseData caseData = CaseDataBuilder.builder() + .multiPartyClaimTwoDefendantSolicitors() + .atStateApplicantRespondToDefenceAndProceed() + .addRespondent2LitigationFriend() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(DEFENDANT_TWO_LITIGATION_FRIEND_ID).build()) + .build(); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .respondent2LitigationFriend(caseData.getRespondent2LitigationFriend().toBuilder() + .flags(Flags.builder() + .partyName("Litigation Friend") + .roleOnCase("litigation friend") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))).build()) + .fullName(null) + .firstName("Johnny").lastName("Rambo new") + .build()); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + Flags actual = builder.build().getRespondent2LitigationFriend().getFlags(); + Flags expected = Flags.builder().partyName("Johnny Rambo new") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))) + .roleOnCase("litigation friend").build(); + + assertThat(actual).isEqualTo(expected); + } + } + + @Nested + class LegalRepIndividuals { + + @Test + void shouldCreateFlag_whenClaimantLRIndividualAdded() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(CLAIMANT_ONE_LEGAL_REP_INDIVIDUALS_ID).build()) + .build(); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .applicant1LRIndividuals(wrapElements(PartyFlagStructure.builder() + .firstName("Legally").lastName("Rep") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getApplicant1LRIndividuals()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Legally Rep") + .details(List.of()) + .roleOnCase("Civil - Organisation").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isNotNull(); + } + + @Test + void shouldUpdateFlagName_whenClaimantLRIndividualNameUpdated() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .addApplicantLRIndividual("Legal", "Rep") + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(CLAIMANT_ONE_LEGAL_REP_INDIVIDUALS_ID).build()) + .build(); + + PartyFlagStructure lrIndividual = unwrapElements(caseData.getApplicant1LRIndividuals()).get(0); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .applicant1LRIndividuals(wrapElements(lrIndividual.toBuilder() + .flags(Flags.builder() + .partyName("Legal Rep") + .roleOnCase("Civil - Organisation") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))).build()) + .firstName("Legally").lastName("Rep") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getApplicant1LRIndividuals()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Legally Rep") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))) + .roleOnCase("Civil - Organisation").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isEqualTo("app-lr-ind-party-id"); + } + + @Test + void shouldCreateFlag_whenRespondent1LRIndividualAdded() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(DEFENDANT_ONE_LEGAL_REP_INDIVIDUALS_ID).build()) + .build(); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .respondent1LRIndividuals(wrapElements(PartyFlagStructure.builder() + .firstName("Legally").lastName("Rep") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getRespondent1LRIndividuals()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Legally Rep") + .details(List.of()) + .roleOnCase("Civil - Organisation").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isNotNull(); + } + + @Test + void shouldUpdateFlagName_whenRespondent1LRIndividualNameUpdated() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .addRespondent1LRIndividual("Legal", "Rep") + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(DEFENDANT_ONE_LEGAL_REP_INDIVIDUALS_ID).build()) + .build(); + + PartyFlagStructure lrIndividual = unwrapElements(caseData.getRespondent1LRIndividuals()).get(0); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .respondent1LRIndividuals(wrapElements(lrIndividual.toBuilder() + .flags(Flags.builder() + .partyName("Legal Rep") + .roleOnCase("Civil - Organisation") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))).build()) + .firstName("Legally").lastName("Rep") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getRespondent1LRIndividuals()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Legally Rep") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))) + .roleOnCase("Civil - Organisation").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isEqualTo("res-1-lr-ind-party-id"); + } + + @Test + void shouldCreateFlag_whenRespondent2LRIndividualAdded() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(DEFENDANT_TWO_LEGAL_REP_INDIVIDUALS_ID).build()) + .build(); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .respondent2LRIndividuals(wrapElements(PartyFlagStructure.builder() + .firstName("Legally").lastName("Rep") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getRespondent2LRIndividuals()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Legally Rep") + .details(List.of()) + .roleOnCase("Civil - Organisation").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isNotNull(); + } + + @Test + void shouldUpdateFlagName_whenRespondent2LRIndividualNameUpdated() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .addRespondent2LRIndividual("Legal", "Rep") + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(DEFENDANT_TWO_LEGAL_REP_INDIVIDUALS_ID).build()) + .build(); + + PartyFlagStructure lrIndividual = unwrapElements(caseData.getRespondent2LRIndividuals()).get(0); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .respondent2LRIndividuals(wrapElements(lrIndividual.toBuilder() + .flags(Flags.builder() + .partyName("Legal Rep") + .roleOnCase("Civil - Organisation") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))).build()) + .firstName("Legally").lastName("Rep") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getRespondent2LRIndividuals()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Legally Rep") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))) + .roleOnCase("Civil - Organisation").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isEqualTo("res-2-lr-ind-party-id"); + } + } + + @Nested + class OrgIndividuals { + + @Test + void shouldCreateFlag_whenClaimant1OrgIndividualAdded() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(CLAIMANT_ONE_ORG_INDIVIDUALS_ID).build()) + .build(); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .applicant1OrgIndividuals(wrapElements(PartyFlagStructure.builder() + .firstName("Org").lastName("Ind") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getApplicant1OrgIndividuals()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Org Ind") + .details(List.of()) + .roleOnCase("Mr. John Rambo").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isNotNull(); + } + + @Test + void shouldUpdateFlagName_whenClaimant1OrgIndividualNameUpdated() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .addApplicant1OrgIndividual("Org", "Person") + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(CLAIMANT_ONE_ORG_INDIVIDUALS_ID).build()) + .build(); + + PartyFlagStructure orgIndividual = unwrapElements(caseData.getApplicant1OrgIndividuals()).get(0); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .applicant1OrgIndividuals(wrapElements(orgIndividual.toBuilder() + .flags(Flags.builder() + .partyName("Org Person") + .roleOnCase("Mr. John Rambo") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))).build()) + .firstName("Org").lastName("Ind") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getApplicant1OrgIndividuals()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Org Ind") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))) + .roleOnCase("Mr. John Rambo").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isEqualTo("app-1-org-ind-party-id"); + } + + @Test + void shouldCreateFlag_whenClaimant2OrgIndividualAdded() { + CaseData caseData = CaseDataBuilder.builder() + .atStateClaimIssued() + .multiPartyClaimTwoApplicants() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(CLAIMANT_TWO_ORG_INDIVIDUALS_ID).build()) + .build(); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .applicant2OrgIndividuals(wrapElements(PartyFlagStructure.builder() + .firstName("Org").lastName("Ind") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getApplicant2OrgIndividuals()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Org Ind") + .details(List.of()) + .roleOnCase("Mr. Jason Rambo").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isNotNull(); + } + + @Test + void shouldUpdateFlagName_whenClaimant2OrgIndividualNameUpdated() { + CaseData caseData = CaseDataBuilder.builder() + .atStateClaimIssued() + .multiPartyClaimTwoApplicants() + .addApplicant2OrgIndividual("Org", "Person") + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(CLAIMANT_TWO_ORG_INDIVIDUALS_ID).build()) + .build(); + + PartyFlagStructure orgIndividual = unwrapElements(caseData.getApplicant2OrgIndividuals()).get(0); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .applicant2OrgIndividuals(wrapElements(orgIndividual.toBuilder() + .flags(Flags.builder() + .partyName("Org Person") + .roleOnCase("Mr. Jason Rambo") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))).build()) + .firstName("Org").lastName("Ind") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getApplicant2OrgIndividuals()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Org Ind") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))) + .roleOnCase("Mr. Jason Rambo").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isEqualTo("app-2-org-ind-party-id"); + } + + @Test + void shouldCreateFlag_whenRespondent1OrgIndividualAdded() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(DEFENDANT_ONE_ORG_INDIVIDUALS_ID).build()) + .build(); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .respondent1OrgIndividuals(wrapElements(PartyFlagStructure.builder() + .firstName("Org").lastName("Ind") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getRespondent1OrgIndividuals()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Org Ind") + .details(List.of()) + .roleOnCase("Mr. Sole Trader").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isNotNull(); + } + + @Test + void shouldUpdateFlagName_whenRespondent1OrgIndividualNameUpdated() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .addRespondent1OrgIndividual("Org", "Person") + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(DEFENDANT_ONE_ORG_INDIVIDUALS_ID).build()) + .build(); + + PartyFlagStructure orgIndividual = unwrapElements(caseData.getRespondent1OrgIndividuals()).get(0); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .respondent1OrgIndividuals(wrapElements(orgIndividual.toBuilder() + .flags(Flags.builder() + .partyName("Org Person") + .roleOnCase("Mr. Sole Trader") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))).build()) + .firstName("Org").lastName("Ind") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getRespondent1OrgIndividuals()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Org Ind") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))) + .roleOnCase("Mr. Sole Trader").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isEqualTo("res-1-org-ind-party-id"); + } + + @Test + void shouldCreateFlag_whenRespondent2OrgIndividualAdded() { + CaseData caseData = CaseDataBuilder.builder() + .atStateClaimIssued() + .multiPartyClaimTwoDefendantSolicitors() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(DEFENDANT_TWO_ORG_INDIVIDUALS_ID).build()) + .build(); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .respondent2OrgIndividuals(wrapElements(PartyFlagStructure.builder() + .firstName("Org").lastName("Ind") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getRespondent2OrgIndividuals()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Org Ind") + .details(List.of()) + .roleOnCase("Mr. John Rambo").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isNotNull(); + } + + @Test + void shouldUpdateFlagName_whenRespondent2OrgIndividualNameUpdated() { + CaseData caseData = CaseDataBuilder.builder() + .atStateClaimIssued() + .multiPartyClaimTwoDefendantSolicitors() + .addRespondent2OrgIndividual("Org", "Person") + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(DEFENDANT_TWO_ORG_INDIVIDUALS_ID).build()) + .build(); + + PartyFlagStructure lrIndividual = unwrapElements(caseData.getRespondent2OrgIndividuals()).get(0); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .respondent2OrgIndividuals(wrapElements(lrIndividual.toBuilder() + .flags(Flags.builder() + .partyName("Org Person") + .roleOnCase("Mr. John Rambo") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))).build()) + .firstName("Org").lastName("Ind") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getRespondent2OrgIndividuals()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Org Ind") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))) + .roleOnCase("Mr. John Rambo").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isEqualTo("res-2-org-ind-party-id"); + } + } + } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/utils/CaseFlagsInitialiserTest.java b/src/test/java/uk/gov/hmcts/reform/civil/utils/CaseFlagsInitialiserTest.java index bb546a4f699..334bb719764 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/utils/CaseFlagsInitialiserTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/utils/CaseFlagsInitialiserTest.java @@ -2,6 +2,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import uk.gov.hmcts.reform.ccd.model.OrganisationPolicy; import uk.gov.hmcts.reform.civil.callback.CaseEvent; import uk.gov.hmcts.reform.civil.model.Party; import uk.gov.hmcts.reform.civil.model.PartyFlagStructure; @@ -14,17 +15,23 @@ import uk.gov.hmcts.reform.civil.model.dq.Respondent2DQ; import uk.gov.hmcts.reform.civil.model.dq.Witness; import uk.gov.hmcts.reform.civil.model.dq.Witnesses; -import uk.gov.hmcts.reform.civil.service.FeatureToggleService; +import uk.gov.hmcts.reform.civil.model.UpdateDetailsForm; import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.model.LitigationFriend; import uk.gov.hmcts.reform.civil.model.caseflags.Flags; +import uk.gov.hmcts.reform.civil.prd.model.Organisation; import uk.gov.hmcts.reform.civil.sampledata.PartyBuilder; +import uk.gov.hmcts.reform.civil.service.FeatureToggleService; +import uk.gov.hmcts.reform.civil.service.OrganisationService; import java.util.List; +import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.APPLICANT_SOLICITOR_EXPERT; @@ -35,6 +42,7 @@ import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.RESPONDENT_SOLICITOR_TWO_WITNESS; import static uk.gov.hmcts.reform.civil.utils.ElementUtils.unwrapElements; import static uk.gov.hmcts.reform.civil.utils.ElementUtils.wrapElements; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_LEGAL_REP_INDIVIDUALS_ID; class CaseFlagsInitialiserTest { @@ -42,11 +50,16 @@ class CaseFlagsInitialiserTest { private FeatureToggleService featureToggleService; + private OrganisationService organisationService; + @BeforeEach void setup() { featureToggleService = mock(FeatureToggleService.class); - caseFlagsInitialiser = new CaseFlagsInitialiser(featureToggleService); + organisationService = mock(OrganisationService.class); + caseFlagsInitialiser = new CaseFlagsInitialiser(featureToggleService, organisationService); when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); + when(organisationService.findOrganisationById(anyString())) + .thenReturn(Optional.of(Organisation.builder().name("Civil - Organisation 1").build())); } @Test @@ -178,6 +191,24 @@ void shouldNotInitialiseCaseFlagsWhenCaseFlagsToggleIsOff() { assertEquals(expected, actual.build()); } + @Test + void shouldInitialiseCaseFlagsForManageContactInformationEvent() { + CaseData caseData = CaseData.builder() + .applicant1OrganisationPolicy(OrganisationPolicy.builder() + .organisation(uk.gov.hmcts.reform.ccd.model.Organisation.builder() + .organisationID("id") + .build()) + .build()) + .updateDetailsForm(UpdateDetailsForm.builder() + .partyChosenId(CLAIMANT_ONE_LEGAL_REP_INDIVIDUALS_ID) + .build()) + .build(); + + caseFlagsInitialiser.initialiseCaseFlags(CaseEvent.MANAGE_CONTACT_INFORMATION, caseData.toBuilder()); + + verify(organisationService).findOrganisationById("id"); + } + @Test void shouldReinitialiseMissingCaseFlags() { Party applicant1 = PartyBuilder.builder().individual().build(); From 31f15428b359337b03b3ac2d6c0aff747039ead8 Mon Sep 17 00:00:00 2001 From: pliao-hmcts <113367232+pliao-hmcts@users.noreply.github.com> Date: Mon, 13 Nov 2023 14:44:40 +0000 Subject: [PATCH 25/28] CIV-11440 Assisted Order - Costs default value (#3548) * CIV-11440 set default value for costs * CIV-11440 Interim payment required set to No * CIV-11440 unit test --------- Co-authored-by: Madhan Mahadevan Co-authored-by: vasudevganesanhmcts <100689363+vasudevganesanhmcts@users.noreply.github.com> --- .../user/GenerateDirectionOrderCallbackHandler.java | 8 ++++++++ .../GenerateDirectionOrderCallbackHandlerTest.java | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandler.java index 57967679b5d..91e5960c66b 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandler.java @@ -14,6 +14,7 @@ import uk.gov.hmcts.reform.civil.enums.CaseState; import uk.gov.hmcts.reform.civil.enums.MultiPartyScenario; import uk.gov.hmcts.reform.civil.enums.YesOrNo; +import uk.gov.hmcts.reform.civil.enums.finalorders.CostEnums; import uk.gov.hmcts.reform.civil.enums.finalorders.FinalOrderToggle; import uk.gov.hmcts.reform.civil.enums.finalorders.HearingLengthFinalOrderList; import uk.gov.hmcts.reform.civil.model.BusinessProcess; @@ -66,6 +67,9 @@ import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.TWO_V_ONE; import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.getMultiPartyScenario; import static uk.gov.hmcts.reform.civil.enums.caseprogression.FinalOrderSelection.ASSISTED_ORDER; +import static uk.gov.hmcts.reform.civil.enums.finalorders.CostEnums.CLAIMANT; +import static uk.gov.hmcts.reform.civil.enums.finalorders.CostEnums.STANDARD_BASIS; +import static uk.gov.hmcts.reform.civil.enums.finalorders.CostEnums.SUBJECT_DETAILED_ASSESSMENT; import static uk.gov.hmcts.reform.civil.enums.finalorders.FinalOrderRepresentationList.CLAIMANT_AND_DEFENDANT; import static uk.gov.hmcts.reform.civil.model.common.DynamicList.fromList; import static uk.gov.hmcts.reform.civil.utils.ElementUtils.element; @@ -289,6 +293,10 @@ private DynamicList populateCurrentHearingLocation(CaseData caseData, String aut .assistedOrderCostsFirstDropdownDate(advancedDate) .assistedOrderAssessmentThirdDropdownDate(advancedDate) .makeAnOrderForCostsYesOrNo(YesOrNo.NO) + .makeAnOrderForCostsList(CLAIMANT) + .assistedOrderClaimantDefendantFirstDropdown(SUBJECT_DETAILED_ASSESSMENT) + .assistedOrderAssessmentSecondDropdownList1(STANDARD_BASIS) + .assistedOrderAssessmentSecondDropdownList2(CostEnums.NO) .build()) .publicFundingCostsProtection(YesOrNo.NO) .finalOrderAppealComplex(FinalOrderAppeal.builder() diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandlerTest.java index ca123fb867f..9891b5f8586 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/GenerateDirectionOrderCallbackHandlerTest.java @@ -275,6 +275,18 @@ void shouldPopulateFields_whenIsCalledAfterSdo() { assertThat(response.getData()).extracting("assistedOrderMakeAnOrderForCosts") .extracting("makeAnOrderForCostsQOCSYesOrNo") .isEqualTo("No"); + assertThat(response.getData()).extracting("assistedOrderMakeAnOrderForCosts") + .extracting("makeAnOrderForCostsList") + .isEqualTo("CLAIMANT"); + assertThat(response.getData()).extracting("assistedOrderMakeAnOrderForCosts") + .extracting("assistedOrderClaimantDefendantFirstDropdown") + .isEqualTo("SUBJECT_DETAILED_ASSESSMENT"); + assertThat(response.getData()).extracting("assistedOrderMakeAnOrderForCosts") + .extracting("assistedOrderAssessmentSecondDropdownList1") + .isEqualTo("STANDARD_BASIS"); + assertThat(response.getData()).extracting("assistedOrderMakeAnOrderForCosts") + .extracting("assistedOrderAssessmentSecondDropdownList2") + .isEqualTo("NO"); assertThat(response.getData()).extracting("publicFundingCostsProtection") .isEqualTo("No"); assertThat(response.getData()).extracting("finalOrderAppealComplex") From c3af6666841de65a3310d3937abbdc039465d3af Mon Sep 17 00:00:00 2001 From: Deepthi Doppalapudi <107422736+deepthidoppalapudihmcts@users.noreply.github.com> Date: Tue, 14 Nov 2023 08:30:55 +0000 Subject: [PATCH 26/28] CIV-11205 Add new fields in GA to store court address and postcode (#3557) * CIV-11205 populated full address for after sdo scenarios * CIV-11205 update TriggerGenApp to update address * CIV-11205 Updated address during TriggerLocationUpdate Event * CIV-11205 Unit tests covered for location update * CIV-11205 updated templates with court full address * CIV-11205 Code smell corrected --- .../templates/CV-UNS-GAP-ENG-01067.docx | Bin 23905 -> 24221 bytes .../templates/CV-UNS-GAP-ENG-01068.docx | Bin 23663 -> 23801 bytes .../templates/CV-UNS-GAP-ENG-01069.docx | Bin 23669 -> 23492 bytes .../templates/CV-UNS-GAP-ENG-01073.docx | Bin 24133 -> 24314 bytes .../templates/CV-UNS-GAP-ENG-01075.docx | Bin 23180 -> 23120 bytes .../templates/CV-UNS-GAP-ENG-01076.docx | Bin 33657 -> 34163 bytes .../templates/CV-UNS-GAP-ENG-01078.docx | Bin 23432 -> 23270 bytes ...erGenAppLocationUpdateCallbackHandler.java | 4 +- .../genapplication/CaseLocationCivil.java | 2 + .../service/GenAppStateHelperService.java | 9 +- .../InitiateGeneralApplicationService.java | 18 ++++ ...nAppLocationUpdateCallbackHandlerTest.java | 8 +- .../service/GenAppStateHelperServiceTest.java | 39 +++++++- ...InitiateGeneralApplicationServiceTest.java | 90 +++++++++++++++++- 14 files changed, 160 insertions(+), 10 deletions(-) diff --git a/docker/docmosis/templates/CV-UNS-GAP-ENG-01067.docx b/docker/docmosis/templates/CV-UNS-GAP-ENG-01067.docx index 1016e0a18c4e8b1898fa37ba0f047f0dfe7187e2..bf518dcc5e41c904dac10e9e72ad59c63f7341b4 100644 GIT binary patch delta 8606 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 D^J{U0 delta 8306 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 L3(~0mzk>e-as$B+ diff --git a/docker/docmosis/templates/CV-UNS-GAP-ENG-01068.docx b/docker/docmosis/templates/CV-UNS-GAP-ENG-01068.docx index ca7751745025d2e5c61198098820dee8066e2b45..07e3a3b1e8c7687cfd69cbb16303146dd1f74521 100644 GIT binary patch delta 8385 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 delta 8238 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 diff --git a/docker/docmosis/templates/CV-UNS-GAP-ENG-01069.docx b/docker/docmosis/templates/CV-UNS-GAP-ENG-01069.docx index fe1a842c34ee4f3c4cc40586e506bec4acdb2fad..8a359232e14bb1a8b76346fc3e11be39adae6e12 100644 GIT binary patch delta 8971 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 LIvk_!e~SMHsuB?u delta 9100 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 MFyPnp{$ud}0DhTOLI3~& diff --git a/docker/docmosis/templates/CV-UNS-GAP-ENG-01073.docx b/docker/docmosis/templates/CV-UNS-GAP-ENG-01073.docx index e44df45adc1521e91b91cc02e27fbbe90742800e..75da4c61c2c89f9ea2091980a527a354e4feb9d3 100644 GIT binary patch delta 8401 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 diff --git a/docker/docmosis/templates/CV-UNS-GAP-ENG-01076.docx b/docker/docmosis/templates/CV-UNS-GAP-ENG-01076.docx index 9d6e2d9cb1d7caa3da3926d6b2ef70c0f6decb01..8c4163027d4dabdd48d09146d1d90c583bc2b0b7 100644 GIT binary patch delta 17188 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 XbX3)3mR1|4qT0z$t=eq!>p+440_KGH diff --git a/docker/docmosis/templates/CV-UNS-GAP-ENG-01078.docx b/docker/docmosis/templates/CV-UNS-GAP-ENG-01078.docx index 6ebdfc6bb623ce45e682e48e0bafe0f6e916bbb6..40d0ed386278f7fdc7de187b3c92eb0e0a9c1ee9 100644 GIT binary patch delta 7890 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