diff --git a/build.gradle b/build.gradle index a886bf6291d..515e6154e4d 100644 --- a/build.gradle +++ b/build.gradle @@ -361,8 +361,7 @@ configurations.all { } dependencies { - implementation 'com.github.hmcts:civil-commons:1.0.44' - + implementation 'com.github.hmcts:civil-commons:v1.0.46' 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/docker/docmosis/templates/CV-SPC-CLM-ENG-INTERLOCUTORY-JUDGEMENT.docx b/docker/docmosis/templates/CV-SPC-CLM-ENG-INTERLOCUTORY-JUDGEMENT.docx new file mode 100644 index 00000000000..8a51ad37511 Binary files /dev/null and b/docker/docmosis/templates/CV-SPC-CLM-ENG-INTERLOCUTORY-JUDGEMENT.docx differ diff --git a/src/main/java/uk/gov/hmcts/reform/civil/callback/CaseEvent.java b/src/main/java/uk/gov/hmcts/reform/civil/callback/CaseEvent.java index e54640574a4..132d26fb6d6 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/callback/CaseEvent.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/callback/CaseEvent.java @@ -306,6 +306,8 @@ public enum CaseEvent { UPDATE_CASE_PROGRESS_HMC(CAMUNDA), NOTIFY_APPLICANT1_CLAIM_SUBMITTED(CAMUNDA), NOTIFY_DEFENDANT_CLAIMANT_SETTLE_THE_CLAIM(CAMUNDA), + NOTIFY_DEFENDANT_LIP_CLAIMANT_REPRESENTED(CAMUNDA), + NOTIFY_CLAIMANT_LIP_AFTER_NOC_APPROVAL(CAMUNDA), SEND_CVP_JOIN_LINK(USER), SET_LIP_RESPONDENT_RESPONSE_DEADLINE(CAMUNDA), NOTIFY_LIP_RESPONDENT_CLAIMANT_CONFIRM_TO_PROCEED(CAMUNDA), @@ -322,7 +324,8 @@ public enum CaseEvent { RETRIGGER_CASES(CAMUNDA), GENERATE_LIP_CLAIMANT_MANUAL_DETERMINATION(CAMUNDA), GENERATE_LIP_SIGN_SETTLEMENT_AGREEMENT_FORM(CAMUNDA), - NOTIFY_CLAIMANT_LIP_HELP_WITH_FEES(CAMUNDA); + NOTIFY_CLAIMANT_LIP_HELP_WITH_FEES(CAMUNDA), + GENERATE_INTERLOCUTORY_JUDGEMENT_DOCUMENT(CAMUNDA); private final UserType userType; diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateInterlocutoryJudgementHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateInterlocutoryJudgementHandler.java new file mode 100644 index 00000000000..8ad2bf35e0d --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateInterlocutoryJudgementHandler.java @@ -0,0 +1,98 @@ +package uk.gov.hmcts.reform.civil.handler.callback.camunda.docmosis; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +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.CallbackHandler; +import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.callback.CaseEvent; +import uk.gov.hmcts.reform.civil.documentmanagement.model.CaseDocument; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.CaseDataParent; +import uk.gov.hmcts.reform.civil.model.citizenui.CaseDataLiP; +import uk.gov.hmcts.reform.civil.model.citizenui.ChooseHowToProceed; +import uk.gov.hmcts.reform.civil.model.citizenui.ClaimantLiPResponse; +import uk.gov.hmcts.reform.civil.model.citizenui.dto.RepaymentDecisionType; +import uk.gov.hmcts.reform.civil.service.SystemGeneratedDocumentService; +import uk.gov.hmcts.reform.civil.service.docmosis.claimantresponse.InterlocutoryJudgementDocGenerator; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import static uk.gov.hmcts.reform.civil.callback.CallbackParams.Params.BEARER_TOKEN; +import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; + +@Service +@RequiredArgsConstructor +public class GenerateInterlocutoryJudgementHandler extends CallbackHandler { + + private static final List EVENTS = List.of(CaseEvent.GENERATE_INTERLOCUTORY_JUDGEMENT_DOCUMENT); + private final ObjectMapper objectMapper; + private final InterlocutoryJudgementDocGenerator interlocutoryJudgementDocGenerator; + private final SystemGeneratedDocumentService systemGeneratedDocumentService; + private final Map callbackMap = Map.of( + callbackKey(ABOUT_TO_SUBMIT), + this::generateInterlocutoryJudgementDoc + ); + + @Override + protected Map callbacks() { + return callbackMap; + } + + @Override + public List handledEvents() { + return EVENTS; + } + + private CallbackResponse generateInterlocutoryJudgementDoc(CallbackParams callbackParams) { + CaseData caseData = callbackParams.getCaseData(); + if (isGenerateInterlocDocNotPermitted(callbackParams)) { + return SubmittedCallbackResponse.builder().build(); + } + + CaseDocument interlocutoryJudgementDoc = interlocutoryJudgementDocGenerator.generateInterlocutoryJudgementDoc( + caseData, + callbackParams.getParams().get(BEARER_TOKEN).toString() + ); + CaseData updatedCaseData = caseData.toBuilder() + .systemGeneratedCaseDocuments(systemGeneratedDocumentService.getSystemGeneratedDocumentsWithAddedDocument( + interlocutoryJudgementDoc, + caseData + )) + .build(); + + return AboutToStartOrSubmitCallbackResponse.builder() + .data(updatedCaseData.toMap(objectMapper)) + .build(); + } + + private ChooseHowToProceed getChooseHowToProceed(CaseData caseData) { + return Optional.ofNullable(caseData) + .map(CaseData::getCaseDataLiP) + .map(CaseDataLiP::getApplicant1LiPResponse) + .map(ClaimantLiPResponse::getApplicant1ChoosesHowToProceed) + .orElse(null); + } + + private RepaymentDecisionType getRepaymentDecisionType(CaseData caseData) { + return Optional.ofNullable(caseData).map(CaseDataParent::getCaseDataLiP) + .map(CaseDataLiP::getApplicant1LiPResponse) + .map(ClaimantLiPResponse::getClaimantCourtDecision) + .orElse(null); + } + + private boolean isGenerateInterlocDocNotPermitted(CallbackParams callbackParams) { + CaseData caseData = callbackParams.getCaseData(); + ChooseHowToProceed chooseHowToProceed = getChooseHowToProceed(caseData); + RepaymentDecisionType repaymentDecisionType = getRepaymentDecisionType(caseData); + boolean isCompanyOROrganisation = caseData.getApplicant1().isCompanyOROrganisation(); + return isCompanyOROrganisation || chooseHowToProceed != ChooseHowToProceed.REQUEST_A_CCJ || repaymentDecisionType != RepaymentDecisionType.IN_FAVOUR_OF_DEFENDANT; + } +} + diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotificationForClaimantRepresented.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotificationForClaimantRepresented.java new file mode 100644 index 00000000000..243fa31cc88 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotificationForClaimantRepresented.java @@ -0,0 +1,101 @@ +package uk.gov.hmcts.reform.civil.handler.callback.camunda.notification; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import uk.gov.hmcts.reform.ccd.client.model.AboutToStartOrSubmitCallbackResponse; +import uk.gov.hmcts.reform.ccd.client.model.CallbackResponse; +import uk.gov.hmcts.reform.civil.callback.Callback; +import uk.gov.hmcts.reform.civil.callback.CallbackHandler; +import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.callback.CaseEvent; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.Party; +import uk.gov.hmcts.reform.civil.notify.NotificationService; +import uk.gov.hmcts.reform.civil.notify.NotificationsProperties; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import static org.apache.commons.lang3.StringUtils.isNotEmpty; +import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.NOTIFY_CLAIMANT_LIP_AFTER_NOC_APPROVAL; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.NOTIFY_DEFENDANT_LIP_CLAIMANT_REPRESENTED; + +@Service +@RequiredArgsConstructor +public class NotificationForClaimantRepresented extends CallbackHandler implements NotificationData { + + private final NotificationService notificationService; + private final NotificationsProperties notificationsProperties; + private static final String REFERENCE_TEMPLATE_DEFENDANT = + "notify-lip-after-noc-approval-%s"; + public static final String TASK_ID_APPLICANT = "NotifyClaimantLipAfterNocApproval"; + public static final String TASK_ID_RESPONDENT = "NotifyDefendantLipClaimantRepresented"; + private final Map callbackMap = Map.of( + callbackKey(ABOUT_TO_SUBMIT), this::notifyLipAfterNocApproval + ); + + @Override + protected Map callbacks() { + return callbackMap; + } + + @Override + public String camundaActivityId(CallbackParams callbackParams) { + return isRespondentNotification(callbackParams) ? TASK_ID_RESPONDENT : TASK_ID_APPLICANT; + } + + private CallbackResponse notifyLipAfterNocApproval(CallbackParams callbackParams) { + CaseData caseData = callbackParams.getCaseData(); + String recipientEmail = isRespondentNotification(callbackParams) ? getRecipientEmailForRespondent(caseData) : + caseData.getApplicant1Email(); + String templateId = getTemplateID( + isRespondentNotification(callbackParams) + ); + if (isNotEmpty(recipientEmail) && templateId != null) { + notificationService.sendMail( + recipientEmail, + templateId, + addProperties(caseData), + String.format(REFERENCE_TEMPLATE_DEFENDANT, caseData.getLegacyCaseReference()) + ); + } + return AboutToStartOrSubmitCallbackResponse.builder().build(); + } + + @Override + public List handledEvents() { + return List.of( + NOTIFY_DEFENDANT_LIP_CLAIMANT_REPRESENTED, + NOTIFY_CLAIMANT_LIP_AFTER_NOC_APPROVAL + ); + } + + @Override + public Map addProperties(CaseData caseData) { + return Map.of( + RESPONDENT_NAME, caseData.getRespondent1().getPartyName(), + CLAIM_REFERENCE_NUMBER, caseData.getLegacyCaseReference(), + CLAIMANT_NAME, caseData.getApplicant1().getPartyName() + ); + } + + private boolean isRespondentNotification(CallbackParams callbackParams) { + return callbackParams.getRequest().getEventId() + .equals(NOTIFY_DEFENDANT_LIP_CLAIMANT_REPRESENTED.name()); + } + + private String getRecipientEmailForRespondent(CaseData caseData) { + return Optional.ofNullable(caseData.getRespondent1()) + .map(Party::getPartyEmail) + .orElse(""); + } + + private String getTemplateID(boolean isDefendantEvent) { + if (isDefendantEvent) { + return notificationsProperties.getNotifyRespondentLipForClaimantRepresentedTemplate(); + } + return notificationsProperties.getNotifyClaimantLipForNoLongerAccessTemplate(); + } +} 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 d96c85b3081..1c30ff235dd 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,15 +13,15 @@ import uk.gov.hmcts.reform.civil.enums.CaseState; import uk.gov.hmcts.reform.civil.model.BusinessProcess; import uk.gov.hmcts.reform.civil.model.CCJPaymentDetails; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.citizenui.CaseDataLiP; import uk.gov.hmcts.reform.civil.model.citizenui.ClaimantLiPResponse; import uk.gov.hmcts.reform.civil.service.DeadlinesCalculator; import uk.gov.hmcts.reform.civil.service.FeatureToggleService; import uk.gov.hmcts.reform.civil.service.JudgementService; -import uk.gov.hmcts.reform.civil.model.CaseData; -import uk.gov.hmcts.reform.civil.model.citizenui.CaseDataLiP; -import uk.gov.hmcts.reform.civil.service.citizenui.ResponseOneVOneShowTagService; -import uk.gov.hmcts.reform.civil.service.citizen.UpdateCaseManagementDetailsService; import uk.gov.hmcts.reform.civil.service.Time; +import uk.gov.hmcts.reform.civil.service.citizen.UpdateCaseManagementDetailsService; +import uk.gov.hmcts.reform.civil.service.citizenui.ResponseOneVOneShowTagService; import java.time.LocalDate; import java.time.LocalDateTime; @@ -83,7 +83,10 @@ private CallbackResponse aboutToSubmit(CallbackParams callbackParams) { CaseData.CaseDataBuilder builder = caseData.toBuilder() .applicant1ResponseDate(applicant1ResponseDate) .businessProcess(BusinessProcess.ready(CLAIMANT_RESPONSE_CUI)) - .respondent1RespondToSettlementAgreementDeadline(getRespondToSettlementAgreementDeadline(caseData, applicant1ResponseDate)); + .respondent1RespondToSettlementAgreementDeadline(getRespondToSettlementAgreementDeadline( + caseData, + applicant1ResponseDate + )); updateCaseManagementLocationDetailsService.updateCaseManagementDetails(builder, callbackParams); @@ -134,7 +137,7 @@ private String setUpCaseState(AboutToStartOrSubmitCallbackResponse.AboutToStartO return CaseState.JUDICIAL_REFERRAL.name(); } else if (updatedData.hasDefendantAgreedToFreeMediation() && updatedData.hasClaimantAgreedToFreeMediation()) { return CaseState.IN_MEDIATION.name(); - } else if (updatedData.hasApplicant1SignedSettlementAgreement() && updatedData.hasApplicantAcceptedRepaymentPlan()) { + } else if (isAllFinalOrderIssued(updatedData)) { return CaseState.All_FINAL_ORDERS_ISSUED.name(); } else if (isCaseSettledAllowed(updatedData)) { return CaseState.CASE_SETTLED.name(); @@ -149,10 +152,10 @@ private String setUpCaseState(AboutToStartOrSubmitCallbackResponse.AboutToStartO private boolean isCaseSettledAllowed(CaseData caseData) { return ((Objects.nonNull(caseData.getApplicant1PartAdmitIntentionToSettleClaimSpec()) - && caseData.isClaimantIntentionSettlePartAdmit()) - || (caseData.isPartAdmitImmediatePaymentClaimSettled())); + && caseData.isClaimantIntentionSettlePartAdmit()) + || (caseData.isPartAdmitImmediatePaymentClaimSettled())); } - + private void updateCcjRequestPaymentDetails(CaseData.CaseDataBuilder builder, CaseData caseData) { if (hasCcjRequest(caseData)) { CCJPaymentDetails ccjPaymentDetails = judgementService.buildJudgmentAmountSummaryDetails(caseData); @@ -162,7 +165,7 @@ private void updateCcjRequestPaymentDetails(CaseData.CaseDataBuilder build private boolean hasCcjRequest(CaseData caseData) { return (caseData.isLipvLipOneVOne() && featureToggleService.isLipVLipEnabled() - && caseData.hasApplicant1AcceptedCcj() && caseData.isCcjRequestJudgmentByAdmission()); + && caseData.hasApplicant1AcceptedCcj() && caseData.isCcjRequestJudgmentByAdmission()); } private boolean isJudicialReferralAllowed(CaseData caseData) { @@ -183,4 +186,19 @@ private boolean isClaimantOrDefendantRejectMediation(CaseData caseData) { private void updateClaimEndState(AboutToStartOrSubmitCallbackResponse.AboutToStartOrSubmitCallbackResponseBuilder response, CaseData updatedData) { response.state(setUpCaseState(response, updatedData)); } + + private boolean isAllFinalOrderIssued(CaseData caseData) { + ClaimantLiPResponse applicant1Response = Optional.ofNullable(caseData.getCaseDataLiP()) + .map(CaseDataLiP::getApplicant1LiPResponse) + .orElse(null); + boolean isCourtDecisionAccepted = applicant1Response != null + && applicant1Response.hasClaimantAcceptedCourtDecision(); + boolean isInFavourOfClaimant = applicant1Response != null + && applicant1Response.hasCourtDecisionInFavourOfClaimant(); + + return (caseData.hasApplicantRejectedRepaymentPlan() + && (isCourtDecisionAccepted || isInFavourOfClaimant)) + || caseData.hasApplicantAcceptedRepaymentPlan() + && caseData.hasApplicant1SignedSettlementAgreement(); + } } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimLipCallBackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimLipCallBackHandler.java index 08b193f9bca..5f6b2f11337 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimLipCallBackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimLipCallBackHandler.java @@ -18,6 +18,7 @@ import uk.gov.hmcts.reform.civil.repositories.SpecReferenceNumberRepository; import uk.gov.hmcts.reform.civil.service.Time; import uk.gov.hmcts.reform.civil.service.pininpost.DefendantPinToPostLRspecService; +import uk.gov.hmcts.reform.civil.utils.CaseFlagsInitialiser; import uk.gov.hmcts.reform.civil.utils.OrgPolicyUtils; import java.util.Collections; @@ -42,6 +43,7 @@ public class CreateClaimLipCallBackHandler extends CallbackHandler { private final Time time; private final ObjectMapper objectMapper; private final DefendantPinToPostLRspecService defendantPinToPostLRspecService; + private final CaseFlagsInitialiser caseFlagsInitialiser; @Override protected Map callbacks() { @@ -63,7 +65,7 @@ public List handledEvents() { private CallbackResponse lipClaimInitialState(CallbackParams callbackParams) { CaseData caseData = callbackParams.getCaseData(); - CaseData.CaseDataBuilder caseDataBuilder = caseData.toBuilder(); + CaseData.CaseDataBuilder caseDataBuilder = caseData.toBuilder(); caseDataBuilder.caseAccessCategory(SPEC_CLAIM); return AboutToStartOrSubmitCallbackResponse.builder() .data(caseDataBuilder.build().toMap(objectMapper)) @@ -71,15 +73,16 @@ private CallbackResponse lipClaimInitialState(CallbackParams callbackParams) { } private CallbackResponse submitClaim(CallbackParams callbackParams) { - CaseData.CaseDataBuilder caseDataBuilder = callbackParams.getCaseData().toBuilder(); + CaseData.CaseDataBuilder caseDataBuilder = callbackParams.getCaseData().toBuilder(); caseDataBuilder.submittedDate(time.now()); // Add back Pip in post to temporary pass the email event caseDataBuilder.respondent1PinToPostLRspec(defendantPinToPostLRspecService.buildDefendantPinToPost()); if (Optional.ofNullable(callbackParams.getRequest()).map(CallbackRequest::getEventId).isPresent()) { caseDataBuilder.legacyCaseReference(specReferenceNumberRepository.getSpecReferenceNumber()); caseDataBuilder.businessProcess(BusinessProcess.ready(CREATE_LIP_CLAIM)); + caseDataBuilder.respondent1DetailsForClaimDetailsTab(caseDataBuilder.build().getRespondent1().toBuilder().flags(null).build()); + caseFlagsInitialiser.initialiseCaseFlags(CREATE_LIP_CLAIM, caseDataBuilder); } - addOrginsationPoliciesforClaimantLip(caseDataBuilder); return AboutToStartOrSubmitCallbackResponse.builder() .data(caseDataBuilder.build().toMap(objectMapper)) 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 d5eb6fd14e4..7f8623ecb13 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 @@ -810,6 +810,11 @@ public boolean isSettlementDeclinedByClaimant() { return NO.equals(getApplicant1PartAdmitIntentionToSettleClaimSpec()); } + @JsonIgnore + public boolean isClaimantAcceptedClaimAmount() { + return YES.equals(getApplicant1AcceptAdmitAmountPaidSpec()); + } + @JsonIgnore public boolean isClaimantRejectsClaimAmount() { return NO.equals(getApplicant1AcceptAdmitAmountPaidSpec()); 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 e14c59b57bc..f4b74de37ed 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 @@ -444,7 +444,7 @@ public boolean isApplicantNotRepresented() { public boolean isApplicantRepresented() { return this.applicant1Represented == YES; } - + /** * Adding for Certificate of Service. */ diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/ClaimantLiPResponse.java b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/ClaimantLiPResponse.java index 2a821ea2b45..933499a6e14 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/ClaimantLiPResponse.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/ClaimantLiPResponse.java @@ -21,6 +21,7 @@ public class ClaimantLiPResponse { private ChooseHowToProceed applicant1ChoosesHowToProceed; private RepaymentDecisionType claimantCourtDecision; private ClaimantResponseOnCourtDecisionType claimantResponseOnCourtDecision; + private String applicant1RejectedRepaymentReason; @JsonIgnore public boolean hasApplicant1SignedSettlementAgreement() { diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/InterlocutoryJudgementDoc.java b/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/InterlocutoryJudgementDoc.java new file mode 100644 index 00000000000..cd5304bcc33 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/InterlocutoryJudgementDoc.java @@ -0,0 +1,38 @@ +package uk.gov.hmcts.reform.civil.model.docmosis; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import uk.gov.hmcts.reform.civil.model.common.MappableObject; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +@Builder(toBuilder = true) +@Getter +@EqualsAndHashCode +public class InterlocutoryJudgementDoc implements MappableObject { + + private final String claimNumber; + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd MMMM yyyy") + private final LocalDate claimIssueDate; + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd MMMM yyyy 'at' HH:mm a") + private final LocalDateTime claimantResponseSubmitDateTime; + + private final String claimantResponseToDefendantAdmission; + private final String claimantRequestRepaymentBy; + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd MMMM yyyy") + private final LocalDate claimantRequestRepaymentLastDateBy; + + private final String formattedDisposableIncome; + private final String courtDecisionRepaymentBy; + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd MMMM yyyy") + private final LocalDate courtDecisionRepaymentLastDateBy; + private final String formalisePaymentBy; + private final String rejectionReason; +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/InterlocutoryJudgementDocMapper.java b/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/InterlocutoryJudgementDocMapper.java new file mode 100644 index 00000000000..8bf831c4242 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/InterlocutoryJudgementDocMapper.java @@ -0,0 +1,109 @@ +package uk.gov.hmcts.reform.civil.model.docmosis; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import uk.gov.hmcts.reform.civil.enums.PaymentType; +import uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec; +import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.RespondToClaimAdmitPartLRspec; +import uk.gov.hmcts.reform.civil.model.citizenui.CaseDataLiP; +import uk.gov.hmcts.reform.civil.model.citizenui.ClaimantLiPResponse; +import uk.gov.hmcts.reform.civil.model.common.MappableObject; +import uk.gov.hmcts.reform.civil.service.citizen.repaymentplan.RepaymentPlanDecisionCalculator; +import uk.gov.hmcts.reform.civil.service.citizenui.responsedeadline.DeadlineExtensionCalculatorService; +import uk.gov.hmcts.reform.civil.service.docmosis.utils.ClaimantResponseUtils; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDate; +import java.util.Optional; + +import static uk.gov.hmcts.reform.civil.service.docmosis.utils.ClaimantResponseUtils.getClaimantRepaymentType; +import static uk.gov.hmcts.reform.civil.service.docmosis.utils.ClaimantResponseUtils.getDefendantRepaymentOption; + +@Component +@RequiredArgsConstructor +public class InterlocutoryJudgementDocMapper implements MappableObject { + + private static final String REFER_TO_JUDGE = "Refer to Judge"; + + private final DeadlineExtensionCalculatorService calculatorService; + private final RepaymentPlanDecisionCalculator repaymentPlanDecisionCalculator; + + private static String getClaimantResponseToDefendantAdmission(CaseData caseData) { + RespondentResponseTypeSpec respondentResponseTypeSpec = caseData.getRespondent1ClaimResponseTypeForSpec(); + + if (respondentResponseTypeSpec == null) { + return "No respondent response type"; + } + return switch (respondentResponseTypeSpec) { + case PART_ADMISSION -> "I accept part admission"; + case FULL_ADMISSION -> "I accept full admission"; + default -> ""; + }; + } + + public InterlocutoryJudgementDoc toInterlocutoryJudgementDoc(CaseData caseData) { + return InterlocutoryJudgementDoc.builder() + .claimIssueDate(caseData.getIssueDate()) + .claimNumber(caseData.getLegacyCaseReference()) + .claimantRequestRepaymentBy(getClaimantRepaymentType(caseData)) + .claimantRequestRepaymentLastDateBy(getClaimantRequestRepaymentLastDateBy(caseData)) + .claimantResponseSubmitDateTime(caseData.getApplicant1ResponseDate()) + .claimantResponseToDefendantAdmission(getClaimantResponseToDefendantAdmission(caseData)) + .courtDecisionRepaymentBy(getDefendantRepaymentOption(caseData)) + .courtDecisionRepaymentLastDateBy(getDefendantRepaymentLastDateBy(caseData)) + .formalisePaymentBy(REFER_TO_JUDGE) + .formattedDisposableIncome(getFormattedDisposableIncome(caseData)) + .rejectionReason(getApplicant1RejectedRepaymentReason(caseData)) + .build(); + } + + private LocalDate getClaimantRequestRepaymentLastDateBy(CaseData caseData) { + PaymentType claimantRepaymentOption = caseData.getApplicant1RepaymentOptionForDefendantSpec(); + if (claimantRepaymentOption == PaymentType.REPAYMENT_PLAN) { + return ClaimantResponseUtils.getClaimantFinalRepaymentDate(caseData); + } else if (claimantRepaymentOption == PaymentType.SET_DATE) { + var paymentDate = caseData.getApplicant1RequestedPaymentDateForDefendantSpec(); + return paymentDate != null ? paymentDate.getPaymentSetDate() : null; + } else if (claimantRepaymentOption == PaymentType.IMMEDIATELY) { + return calculatorService.calculateExtendedDeadline(LocalDate.now(), 5); + } + return null; + } + + private LocalDate getDefendantRepaymentLastDateBy(CaseData caseData) { + RespondentResponsePartAdmissionPaymentTimeLRspec defendantPaymentOption = caseData.getDefenceAdmitPartPaymentTimeRouteRequired(); + if (defendantPaymentOption == RespondentResponsePartAdmissionPaymentTimeLRspec.SUGGESTION_OF_REPAYMENT_PLAN) { + return ClaimantResponseUtils.getDefendantFinalRepaymentDate(caseData); + } else if (defendantPaymentOption == RespondentResponsePartAdmissionPaymentTimeLRspec.BY_SET_DATE) { + return Optional.ofNullable(caseData.getRespondToClaimAdmitPartLRspec()) + .map(RespondToClaimAdmitPartLRspec::getWhenWillThisAmountBePaid).orElse(null); + } else if (defendantPaymentOption == RespondentResponsePartAdmissionPaymentTimeLRspec.IMMEDIATELY) { + return calculatorService.calculateExtendedDeadline(LocalDate.now(), 5); + } + + return null; + } + + private String getFormattedDisposableIncome(CaseData caseData) { + StringBuilder defendantDisposableIncome = new StringBuilder(); + BigDecimal disposableIncome = BigDecimal.valueOf(repaymentPlanDecisionCalculator.calculateDisposableIncome( + caseData)).setScale(2, RoundingMode.CEILING); + if (disposableIncome.compareTo(BigDecimal.ZERO) < 0) { + defendantDisposableIncome.append("-"); + } + + defendantDisposableIncome.append("£"); + return defendantDisposableIncome.append(disposableIncome.abs()).toString(); + } + + private String getApplicant1RejectedRepaymentReason(CaseData caseData) { + return Optional.ofNullable(caseData.getCaseDataLiP()) + .map(CaseDataLiP::getApplicant1LiPResponse) + .map(ClaimantLiPResponse::getApplicant1RejectedRepaymentReason) + .orElse(null); + } + +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/citizen/repaymentplan/RepaymentPlanDecisionCalculator.java b/src/main/java/uk/gov/hmcts/reform/civil/service/citizen/repaymentplan/RepaymentPlanDecisionCalculator.java index d6bb205bbc9..fd53ce45bba 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/citizen/repaymentplan/RepaymentPlanDecisionCalculator.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/citizen/repaymentplan/RepaymentPlanDecisionCalculator.java @@ -78,7 +78,7 @@ private RepaymentDecisionType calculateDecisionBasedOnProposedDate(LocalDate def return RepaymentDecisionType.IN_FAVOUR_OF_DEFENDANT; } - private double calculateDisposableIncome(CaseData caseData) { + public double calculateDisposableIncome(CaseData caseData) { double calculatedIncome = incomeCalculator.calculateTotalMonthlyIncome( caseData.getRespondent1DQ().getRespondent1BankAccountList(), caseData.getRecurringIncomeForRespondent1(), diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/DocmosisTemplates.java b/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/DocmosisTemplates.java index 0adf4e7b9b2..6223142fc43 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/DocmosisTemplates.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/DocmosisTemplates.java @@ -63,7 +63,8 @@ public enum DocmosisTemplates { FREE_FORM_ORDER_PDF("CV-UNS-DEC-ENG-01099.docx", "Order_%s.pdf"), ASSISTED_ORDER_PDF("CV-UNS-DEC-ENG-01283.docx", "Order_%s.pdf"), SETTLEMENT_AGREEMENT_PDF("CV-SPC-CLM-ENG-00001-SETTLEMENT.docx", "%s-settlement-agreement.pdf"), - CLAIMANT_LIP_MANUAL_DETERMINATION_PDF("CV-SPC-CLM-ENG-00001-LIP-MD.docx", "%s_request-org-repayment-amount.pdf"); + CLAIMANT_LIP_MANUAL_DETERMINATION_PDF("CV-SPC-CLM-ENG-00001-LIP-MD.docx", "%s_request-org-repayment-amount.pdf"), + INTERLOCUTORY_JUDGEMENT_DOCUMENT("CV-SPC-CLM-ENG-INTERLOCUTORY-JUDGEMENT.docx", "%s-request-interloc-judgment.pdf"); private final String template; private final String documentTitle; diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/claimantresponse/InterlocutoryJudgementDocGenerator.java b/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/claimantresponse/InterlocutoryJudgementDocGenerator.java new file mode 100644 index 00000000000..29109f04889 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/claimantresponse/InterlocutoryJudgementDocGenerator.java @@ -0,0 +1,48 @@ +package uk.gov.hmcts.reform.civil.service.docmosis.claimantresponse; + +import lombok.Getter; +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.model.CaseData; +import uk.gov.hmcts.reform.civil.model.docmosis.DocmosisDocument; +import uk.gov.hmcts.reform.civil.model.docmosis.InterlocutoryJudgementDoc; +import uk.gov.hmcts.reform.civil.model.docmosis.InterlocutoryJudgementDocMapper; +import uk.gov.hmcts.reform.civil.service.docmosis.DocumentGeneratorService; +import uk.gov.hmcts.reform.civil.service.docmosis.TemplateDataGenerator; + +import static uk.gov.hmcts.reform.civil.service.docmosis.DocmosisTemplates.INTERLOCUTORY_JUDGEMENT_DOCUMENT; + +@Service +@Getter +@RequiredArgsConstructor +public class InterlocutoryJudgementDocGenerator implements TemplateDataGenerator { + + private final InterlocutoryJudgementDocMapper mapper; + private final DocumentManagementService documentManagementService; + private final DocumentGeneratorService documentGeneratorService; + + public CaseDocument generateInterlocutoryJudgementDoc(CaseData caseData, String authorisation) { + DocmosisDocument docmosisDocument = documentGeneratorService.generateDocmosisDocument( + getTemplateData(caseData), + INTERLOCUTORY_JUDGEMENT_DOCUMENT + ); + + return documentManagementService.uploadDocument( + authorisation, + new PDF( + String.format(INTERLOCUTORY_JUDGEMENT_DOCUMENT.getDocumentTitle(), caseData.getLegacyCaseReference()), + docmosisDocument.getBytes(), + DocumentType.INTERLOCUTORY_JUDGEMENT + ) + ); + } + + @Override + public InterlocutoryJudgementDoc getTemplateData(CaseData caseData) { + return mapper.toInterlocutoryJudgementDoc(caseData); + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/utils/ClaimantResponseUtils.java b/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/utils/ClaimantResponseUtils.java index 2ad44e53651..794b217240b 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/utils/ClaimantResponseUtils.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/utils/ClaimantResponseUtils.java @@ -1,8 +1,13 @@ package uk.gov.hmcts.reform.civil.service.docmosis.utils; import uk.gov.hmcts.reform.civil.enums.PaymentFrequencyClaimantResponseLRspec; +import uk.gov.hmcts.reform.civil.enums.PaymentFrequencyLRspec; import uk.gov.hmcts.reform.civil.enums.PaymentType; +import uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec; +import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec; import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.RepaymentPlanLRspec; +import uk.gov.hmcts.reform.civil.utils.MonetaryConversions; import java.math.BigDecimal; import java.math.RoundingMode; @@ -22,12 +27,25 @@ public static String getClaimantRepaymentType(CaseData caseData) { return "No payment type selected"; } if (claimantRepaymentOption == PaymentType.REPAYMENT_PLAN) { - return "By installments"; + return "By instalments"; } else { return claimantRepaymentOption.getDisplayedValue(); } } + public static String getDefendantRepaymentOption(CaseData caseData) { + RespondentResponsePartAdmissionPaymentTimeLRspec defendantRepaymentOption = caseData.getDefenceAdmitPartPaymentTimeRouteRequired(); + if (defendantRepaymentOption == null) { + return "No payment type selected"; + } + + if (defendantRepaymentOption == RespondentResponsePartAdmissionPaymentTimeLRspec.SUGGESTION_OF_REPAYMENT_PLAN) { + return "By instalments"; + } else { + return defendantRepaymentOption.getDisplayedValue(); + } + } + public static LocalDate getClaimantFinalRepaymentDate(CaseData caseData) { BigDecimal paymentAmount = caseData.getApplicant1SuggestInstalmentsPaymentAmountForDefendantSpec(); LocalDate firstRepaymentDate = caseData.getApplicant1SuggestInstalmentsFirstRepaymentDateForDefendantSpec(); @@ -46,7 +64,39 @@ public static LocalDate getClaimantFinalRepaymentDate(CaseData caseData) { }; } + public static LocalDate getDefendantFinalRepaymentDate(CaseData caseData) { + RepaymentPlanLRspec repaymentPlanLRspec = caseData.getRespondent1RepaymentPlan(); + if (isNull(repaymentPlanLRspec)) { + return null; + } + + BigDecimal paymentAmountInPence = repaymentPlanLRspec.getPaymentAmount(); + BigDecimal paymentAmount = MonetaryConversions.penniesToPounds(paymentAmountInPence); + LocalDate firstRepaymentDate = repaymentPlanLRspec.getFirstRepaymentDate(); + PaymentFrequencyLRspec repaymentFrequency = repaymentPlanLRspec.getRepaymentFrequency(); + + if (isNull(firstRepaymentDate) || isNull(paymentAmount) || isNull(repaymentFrequency)) { + return null; + } + + BigDecimal defendantAdmittedAmount = getDefendantAdmittedAmount(caseData); + long numberOfInstallmentsAfterFirst = getNumberOfInstallmentsAfterFirst(defendantAdmittedAmount, paymentAmount); + return switch (repaymentFrequency) { + case ONCE_ONE_WEEK -> firstRepaymentDate.plusWeeks(numberOfInstallmentsAfterFirst); + case ONCE_TWO_WEEKS -> firstRepaymentDate.plusWeeks(2 * numberOfInstallmentsAfterFirst); + default -> firstRepaymentDate.plusMonths(numberOfInstallmentsAfterFirst); + }; + } + private static long getNumberOfInstallmentsAfterFirst(BigDecimal totalAmount, BigDecimal paymentAmount) { return totalAmount.divide(paymentAmount, 0, RoundingMode.CEILING).longValue() - 1; } + + private static BigDecimal getDefendantAdmittedAmount(CaseData caseData) { + if (caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.FULL_ADMISSION) { + return caseData.getTotalClaimAmount(); + } else { + return caseData.getRespondToAdmittedClaimOwingAmountPounds(); + } + } } 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 708b197e462..a6da306fca2 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 @@ -35,7 +35,8 @@ public void initialiseCaseFlags(CaseEvent caseEvent, CaseData.CaseDataBuilder da CaseData caseData = dataBuilder.build(); switch (caseEvent) { case CREATE_CLAIM: - case CREATE_CLAIM_SPEC: { + case CREATE_CLAIM_SPEC: + case CREATE_LIP_CLAIM: { initialiseApplicantAndRespondentFlags(dataBuilder, caseData); break; } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index faddf679f1d..b8bada2fc99 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -333,7 +333,7 @@ notifications: notifyApplicantLipRequestJudgementByAdmissionNotificationTemplate: "d6625ee3-f794-4a87-b0a3-bef7dd0663b9" notifyRespondentLipRequestJudgementByAdmissionNotificationTemplate: "6ced7f9c-b0fd-4fad-a76c-745873b9a3a2" - + notifyClaimantLipHelpWithFees: "242171a6-98c8-4fe3-b6d2-1748b39d2c9b" notifyApplicantForSignedSettlementAgreement: "65459efd-a351-4a1b-814a-435aabe3beb5" @@ -342,6 +342,8 @@ notifications: notifyRespondentForSignedSettlementAgreement: "aeb3951e-4956-4542-a73b-e2e3abec8867" notifyRespondentForNotAgreedSignSettlement: "1742841b-d915-43a9-9d76-b6d17a189ba5" + notifyRespondentLipForClaimantRepresentedTemplate: "54dcfaca-41df-4588-bf3d-bf63f8d34570" + notifyClaimantLipForNoLongerAccessTemplate: "8bf1b6c6-2ee7-442d-8b72-550d2aca9bdf" sendgrid: api-key: ${SENDGRID_API_KEY:false} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateInterlocutoryJudgementHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateInterlocutoryJudgementHandlerTest.java new file mode 100644 index 00000000000..7ef990bdf27 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateInterlocutoryJudgementHandlerTest.java @@ -0,0 +1,122 @@ +package uk.gov.hmcts.reform.civil.handler.callback.camunda.docmosis; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import uk.gov.hmcts.reform.civil.documentmanagement.model.CaseDocument; +import uk.gov.hmcts.reform.civil.documentmanagement.model.Document; +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.ChooseHowToProceed; +import uk.gov.hmcts.reform.civil.model.citizenui.ClaimantLiPResponse; +import uk.gov.hmcts.reform.civil.model.citizenui.dto.RepaymentDecisionType; +import uk.gov.hmcts.reform.civil.service.SystemGeneratedDocumentService; +import uk.gov.hmcts.reform.civil.service.docmosis.claimantresponse.InterlocutoryJudgementDocGenerator; + +import java.time.LocalDateTime; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; +import static uk.gov.hmcts.reform.civil.documentmanagement.model.DocumentType.INTERLOCUTORY_JUDGEMENT; + +@ExtendWith(MockitoExtension.class) +class GenerateInterlocutoryJudgementHandlerTest extends BaseCallbackHandlerTest { + + private static final CaseDocument FORM = CaseDocument.builder() + .createdBy("John") + .documentName("document name") + .documentSize(0L) + .documentType(INTERLOCUTORY_JUDGEMENT) + .createdDatetime(LocalDateTime.now()) + .documentLink(Document.builder() + .documentUrl("fake-url") + .documentFileName("file-name") + .documentBinaryUrl("binary-url") + .build()) + + .build(); + private static final String BEARER_TOKEN = "BEARER_TOKEN"; + @Mock + private InterlocutoryJudgementDocGenerator interlocutoryJudgementDocGenerator; + @Mock + private SystemGeneratedDocumentService systemGeneratedDocumentService; + + private GenerateInterlocutoryJudgementHandler handler; + + @BeforeEach + public void setup() { + ObjectMapper mapper = new ObjectMapper(); + handler = new GenerateInterlocutoryJudgementHandler( + mapper, + interlocutoryJudgementDocGenerator, + systemGeneratedDocumentService + ); + + } + + @Test + void shouldGenerateInterlocutoryJudgementDoc() { + //Given + given(interlocutoryJudgementDocGenerator.generateInterlocutoryJudgementDoc( + any(CaseData.class), + anyString() + )).willReturn(FORM); + CaseData caseData = CaseData.builder() + .applicant1(Party.builder().type(Party.Type.INDIVIDUAL).build()) + .caseDataLiP(CaseDataLiP.builder() + + .applicant1LiPResponse(ClaimantLiPResponse.builder() + .applicant1ChoosesHowToProceed(ChooseHowToProceed.REQUEST_A_CCJ) + .claimantCourtDecision(RepaymentDecisionType.IN_FAVOUR_OF_DEFENDANT) + .build()) + .build()) + .build(); + + handler.handle(callbackParamsOf(caseData, ABOUT_TO_SUBMIT)); + verify(interlocutoryJudgementDocGenerator).generateInterlocutoryJudgementDoc(caseData, BEARER_TOKEN); + } + + @Test + void shouldNotGenerateDocWhenCourtDecisionInFavourClaimant() { + //Given + CaseData caseData = CaseData.builder() + .applicant1(Party.builder().type(Party.Type.INDIVIDUAL).build()) + .caseDataLiP(CaseDataLiP.builder() + .applicant1LiPResponse(ClaimantLiPResponse.builder() + .applicant1ChoosesHowToProceed(ChooseHowToProceed.REQUEST_A_CCJ) + .claimantCourtDecision(RepaymentDecisionType.IN_FAVOUR_OF_CLAIMANT) + .build()) + .build()) + .build(); + + handler.handle(callbackParamsOf(caseData, ABOUT_TO_SUBMIT)); + verify(interlocutoryJudgementDocGenerator, times(0)).generateInterlocutoryJudgementDoc(caseData, BEARER_TOKEN); + } + + @Test + void shouldNotGenerateDocWhenChoosesHowToProceedSignSettlementAgreement() { + //Given + CaseData caseData = CaseData.builder() + .applicant1(Party.builder().type(Party.Type.INDIVIDUAL).build()) + .caseDataLiP(CaseDataLiP.builder() + .applicant1LiPResponse(ClaimantLiPResponse.builder() + .applicant1ChoosesHowToProceed(ChooseHowToProceed.SIGN_A_SETTLEMENT_AGREEMENT) + .claimantCourtDecision(RepaymentDecisionType.IN_FAVOUR_OF_DEFENDANT) + .build()) + .build()) + .build(); + + handler.handle(callbackParamsOf(caseData, ABOUT_TO_SUBMIT)); + verify(interlocutoryJudgementDocGenerator, times(0)).generateInterlocutoryJudgementDoc(caseData, BEARER_TOKEN); + } +} + diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotificationForClaimantRepresentedTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotificationForClaimantRepresentedTest.java new file mode 100644 index 00000000000..ac8933222fe --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotificationForClaimantRepresentedTest.java @@ -0,0 +1,120 @@ +package uk.gov.hmcts.reform.civil.handler.callback.camunda.notification; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import uk.gov.hmcts.reform.ccd.client.model.CallbackRequest; +import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.enums.YesOrNo; +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.notify.NotificationService; +import uk.gov.hmcts.reform.civil.notify.NotificationsProperties; +import uk.gov.hmcts.reform.civil.sampledata.CallbackParamsBuilder; + +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.NOTIFY_CLAIMANT_LIP_AFTER_NOC_APPROVAL; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.NOTIFY_DEFENDANT_LIP_CLAIMANT_REPRESENTED; + +@SpringBootTest(classes = { + NotificationForClaimantRepresented.class, + JacksonAutoConfiguration.class, +}) +public class NotificationForClaimantRepresentedTest extends BaseCallbackHandlerTest { + + @Autowired + private NotificationForClaimantRepresented notificationHandler; + @MockBean + private NotificationService notificationService; + @MockBean + NotificationsProperties notificationsProperties; + @Captor + private ArgumentCaptor targetEmail; + @Captor + private ArgumentCaptor emailTemplate; + @Captor + private ArgumentCaptor> notificationDataMap; + @Captor + private ArgumentCaptor reference; + + @Nested + class AboutToSubmitCallback { + + private static final String DEFENDANT_EMAIL_ADDRESS = "defendantmail@hmcts.net"; + private static final String APPLICANT_EMAIL_ADDRESS = "applicantmail@hmcts.net"; + private static final String DEFENDANT_PARTY_NAME = "ABC ABC"; + private static final String REFERENCE_NUMBER = "8372942374"; + private static final String EMAIL_TEMPLATE = "test-notification-id"; + private static final String CLAIMANT_ORG_NAME = "Org Name"; + + @BeforeEach + void setUp() { + given(notificationsProperties.getNotifyRespondentLipForClaimantRepresentedTemplate()).willReturn(EMAIL_TEMPLATE); + given(notificationsProperties.getNotifyClaimantLipForNoLongerAccessTemplate()).willReturn(EMAIL_TEMPLATE); + } + + @Test + void shouldSendNotificationToDefendantLip_whenEventIsCalledAndDefendantHasEmail() { + //Given + CaseData caseData = CaseData.builder() + .respondent1(Party.builder().type(Party.Type.COMPANY).companyName(DEFENDANT_PARTY_NAME).partyEmail( + DEFENDANT_EMAIL_ADDRESS).build()) + .applicant1(Party.builder().type(Party.Type.COMPANY).companyName(CLAIMANT_ORG_NAME).build()) + .legacyCaseReference(REFERENCE_NUMBER) + .addApplicant2(YesOrNo.NO) + .addRespondent2(YesOrNo.NO) + .build(); + CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData) + .request(CallbackRequest.builder().eventId(NOTIFY_DEFENDANT_LIP_CLAIMANT_REPRESENTED.name()).build()).build(); + //When + notificationHandler.handle(params); + //Then + verify(notificationService, times(1)).sendMail(targetEmail.capture(), + emailTemplate.capture(), + notificationDataMap.capture(), reference.capture() + ); + assertThat(targetEmail.getAllValues().get(0)).isEqualTo(DEFENDANT_EMAIL_ADDRESS); + assertThat(emailTemplate.getAllValues().get(0)).isEqualTo(EMAIL_TEMPLATE); + } + + @Test + public void notifyApplicantAfterNocApproval() { + + //Given + CaseData caseData = CaseData.builder() + .respondent1(Party.builder().type(Party.Type.COMPANY).companyName(DEFENDANT_PARTY_NAME).partyEmail( + DEFENDANT_EMAIL_ADDRESS).build()) + .applicant1(Party.builder().type(Party.Type.COMPANY).companyName(CLAIMANT_ORG_NAME) + .partyEmail(APPLICANT_EMAIL_ADDRESS).build()) + .legacyCaseReference(REFERENCE_NUMBER) + .addApplicant2(YesOrNo.NO) + .addRespondent2(YesOrNo.NO) + .build(); + CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData) + .request(CallbackRequest.builder().eventId(NOTIFY_CLAIMANT_LIP_AFTER_NOC_APPROVAL.name()).build()) + .build(); + //When + notificationHandler.handle(params); + //Then + verify(notificationService, times(1)).sendMail(targetEmail.capture(), + emailTemplate.capture(), + notificationDataMap.capture(), reference.capture() + ); + assertThat(targetEmail.getAllValues().get(0)).isEqualTo(APPLICANT_EMAIL_ADDRESS); + assertThat(emailTemplate.getAllValues().get(0)).isEqualTo(EMAIL_TEMPLATE); + } + } +} 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 bfa0b30f4bb..f39d7dcc052 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,7 +1,6 @@ package uk.gov.hmcts.reform.civil.handler.callback.user; import com.fasterxml.jackson.databind.ObjectMapper; -import java.time.LocalDateTime; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -15,11 +14,12 @@ import uk.gov.hmcts.reform.civil.callback.CallbackParams; import uk.gov.hmcts.reform.civil.enums.CaseState; import uk.gov.hmcts.reform.civil.enums.MediationDecision; -import uk.gov.hmcts.reform.civil.enums.YesOrNo; -import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec; import uk.gov.hmcts.reform.civil.enums.PaymentType; +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.helpers.LocationHelper; +import uk.gov.hmcts.reform.civil.model.CCJPaymentDetails; 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; @@ -34,12 +34,10 @@ 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.model.CCJPaymentDetails; -import uk.gov.hmcts.reform.civil.model.citizenui.ChooseHowToProceed; -import uk.gov.hmcts.reform.civil.service.FeatureToggleService; -import uk.gov.hmcts.reform.civil.service.JudgementService; import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; import uk.gov.hmcts.reform.civil.service.DeadlinesCalculator; +import uk.gov.hmcts.reform.civil.service.FeatureToggleService; +import uk.gov.hmcts.reform.civil.service.JudgementService; import uk.gov.hmcts.reform.civil.service.Time; import uk.gov.hmcts.reform.civil.service.citizen.UpdateCaseManagementDetailsService; import uk.gov.hmcts.reform.civil.service.citizenui.ResponseOneVOneShowTagService; @@ -52,10 +50,10 @@ 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.any; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.when; -import static org.junit.jupiter.api.Assertions.assertEquals; 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; @@ -89,7 +87,7 @@ class ClaimantResponseCuiCallbackHandlerTest extends BaseCallbackHandlerTest { private DeadlinesCalculator deadlinesCalculator; @Autowired private ClaimantResponseCuiCallbackHandler handler; - private static final String courtLocation = "Site 1 - Adr 1 - AAA 111"; + private static final String courtLocation = "Site 1 - Adr 1 - AAA 111"; @Autowired private final ObjectMapper mapper = new ObjectMapper(); @@ -125,14 +123,16 @@ class AboutToSubmitCallback { @BeforeEach void before() { - LocationRefData locationRefData = LocationRefData.builder().siteName("Site 1").courtAddress("Adr 1").postcode("AAA 111") + 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(time.now()).willReturn(submittedDate); - given(locationHelper.updateCaseManagementLocation(any(), any(), any())).willReturn(Optional.ofNullable(locationRefData)); + given(locationHelper.updateCaseManagementLocation(any(), any(), any())).willReturn(Optional.ofNullable( + locationRefData)); given(deadlinesCalculator.getRespondToSettlementAgreementDeadline(any())).willReturn(LocalDateTime.MAX); } @@ -217,9 +217,9 @@ void shouldUpdateCaseStateToJudicialReferral_WhenPartAdmitNoSettle_NoMediation() .hasAgreedFreeMediation(MediationDecision.No).build()) .build(); CaseData caseData = CaseDataBuilder.builder() - .caseDataLip(caseDataLiP) - .applicant1AcceptAdmitAmountPaidSpec(NO) - .atStateClaimIssued().build(); + .caseDataLip(caseDataLiP) + .applicant1AcceptAdmitAmountPaidSpec(NO) + .atStateClaimIssued().build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -389,8 +389,8 @@ void shouldChangeCaseState_whenApplicantRejectClaimSettlementAndAgreeToMediation .atStateClaimIssued() .applicant1PartAdmitConfirmAmountPaidSpec(NO) .caseDataLip(CaseDataLiP.builder().applicant1ClaimMediationSpecRequiredLip(ClaimantMediationLip.builder().hasAgreedFreeMediation( - MediationDecision.Yes).build()) - .build()) + MediationDecision.Yes).build()) + .build()) .build().toBuilder() .responseClaimMediationSpecRequired(YES).build(); @@ -419,7 +419,7 @@ void shouldChangeCaseState_whenApplicantRejectRepaymentPlanAndIsCompany_toAllFin CaseData caseData = CaseDataBuilder.builder() .applicant1AcceptPartAdmitPaymentPlanSpec(NO) .caseDataLip(CaseDataLiP.builder().applicant1ClaimMediationSpecRequiredLip(ClaimantMediationLip.builder().hasAgreedFreeMediation( - MediationDecision.No).build()).build()) + MediationDecision.No).build()).build()) .applicant1(Party.builder().type(Party.Type.COMPANY).companyName("CLAIMANT_ORG_NAME").build()) .respondent1(Party.builder() .type(COMPANY) @@ -610,37 +610,37 @@ void shouldChangeCaseState_whenApplicantAcceptRepaymentPlanAndChooseSettlementAg void shouldUpdateCCJRequestPaymentDetails() { when(featureToggleService.isLipVLipEnabled()).thenReturn(true); CCJPaymentDetails ccjPaymentDetails = CCJPaymentDetails.builder() - .ccjPaymentPaidSomeOption(YES) - .ccjPaymentPaidSomeAmount(BigDecimal.valueOf(600.0)) - .ccjJudgmentLipInterest(BigDecimal.valueOf(300)) - .ccjJudgmentAmountClaimFee(BigDecimal.valueOf(0)) - .build(); + .ccjPaymentPaidSomeOption(YES) + .ccjPaymentPaidSomeAmount(BigDecimal.valueOf(600.0)) + .ccjJudgmentLipInterest(BigDecimal.valueOf(300)) + .ccjJudgmentAmountClaimFee(BigDecimal.valueOf(0)) + .build(); CaseData caseData = CaseDataBuilder.builder() - .applicant1(Party.builder().type(Party.Type.INDIVIDUAL).partyName("CLAIMANT_INDIVIDUAL").build()) - .respondent1(Party.builder().type(Party.Type.INDIVIDUAL).partyName("RESPONDENT_INDIVIDUAL").build()) - .caseDataLip( - CaseDataLiP.builder() - .applicant1LiPResponse(ClaimantLiPResponse.builder().applicant1ChoosesHowToProceed( - ChooseHowToProceed.REQUEST_A_CCJ).build()) - .build()) - .respondent1Represented(NO) - .specRespondent1Represented(NO) - .applicant1Represented(NO) - .totalClaimAmount(BigDecimal.valueOf(1000)) - .ccjPaymentDetails(ccjPaymentDetails) - .build(); + .applicant1(Party.builder().type(Party.Type.INDIVIDUAL).partyName("CLAIMANT_INDIVIDUAL").build()) + .respondent1(Party.builder().type(Party.Type.INDIVIDUAL).partyName("RESPONDENT_INDIVIDUAL").build()) + .caseDataLip( + CaseDataLiP.builder() + .applicant1LiPResponse(ClaimantLiPResponse.builder().applicant1ChoosesHowToProceed( + ChooseHowToProceed.REQUEST_A_CCJ).build()) + .build()) + .respondent1Represented(NO) + .specRespondent1Represented(NO) + .applicant1Represented(NO) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .ccjPaymentDetails(ccjPaymentDetails) + .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); CCJPaymentDetails ccjResponseForJudgement = - getCaseData(response).getCcjPaymentDetails(); + getCaseData(response).getCcjPaymentDetails(); assertThat(response.getData()) - .extracting("businessProcess") - .extracting("camundaEvent") - .isEqualTo(CLAIMANT_RESPONSE_CUI.name()); + .extracting("businessProcess") + .extracting("camundaEvent") + .isEqualTo(CLAIMANT_RESPONSE_CUI.name()); assertThat(response.getData()) - .extracting("businessProcess") - .extracting("status") - .isEqualTo("READY"); + .extracting("businessProcess") + .extracting("status") + .isEqualTo("READY"); assertThat(ccjPaymentDetails.getCcjPaymentPaidSomeOption()).isEqualTo(ccjResponseForJudgement.getCcjPaymentPaidSomeOption()); assertThat(caseData.getTotalClaimAmount()).isEqualTo(ccjResponseForJudgement.getCcjJudgmentAmountClaimAmount()); } @@ -667,15 +667,15 @@ void shouldChangeCaseState_whenApplicantAgreeClaimSettlement() { @Test void shouldChangeCaseState_whenApplicantAcceptedPartAdmitImmediatePayment() { CaseData caseData = CaseDataBuilder.builder() - .applicant1AcceptAdmitAmountPaidSpec(YES) - .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) - .applicant1RepaymentOptionForDefendantSpec(PaymentType.IMMEDIATELY) - .applicant1(Party.builder().type(Party.Type.COMPANY).companyName("CLAIMANT_ORG_NAME").build()) - .respondent1(Party.builder() - .type(COMPANY) - .companyName("Test Inc") - .build()) - .build(); + .applicant1AcceptAdmitAmountPaidSpec(YES) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .applicant1RepaymentOptionForDefendantSpec(PaymentType.IMMEDIATELY) + .applicant1(Party.builder().type(Party.Type.COMPANY).companyName("CLAIMANT_ORG_NAME").build()) + .respondent1(Party.builder() + .type(COMPANY) + .companyName("Test Inc") + .build()) + .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -683,6 +683,58 @@ void shouldChangeCaseState_whenApplicantAcceptedPartAdmitImmediatePayment() { assertThat(response.getState()).isEqualTo(CaseState.CASE_SETTLED.name()); } + @Test + void shouldChangeCaseStateWhenApplicantPlanAcceptedAndSignedSettlement() { + CaseData caseData = CaseDataBuilder.builder() + .applicant1AcceptAdmitAmountPaidSpec(YES) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .applicant1AcceptPartAdmitPaymentPlanSpec(NO) + .applicant1RepaymentOptionForDefendantSpec(PaymentType.SET_DATE) + .applicant1(Party.builder().type(Party.Type.INDIVIDUAL).partyName("CLAIMANT_ORG_NAME").build()) + .respondent1(Party.builder() + .type(Party.Type.INDIVIDUAL) + .partyName("Test Inc") + .build()) + .caseDataLip(CaseDataLiP.builder() + .applicant1LiPResponse(ClaimantLiPResponse.builder() + .claimantCourtDecision(RepaymentDecisionType.IN_FAVOUR_OF_CLAIMANT).applicant1SignedSettlementAgreement( + YesOrNo.YES).build()) + .build()) + .build(); + + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + assertThat(response.getState()).isEqualTo(CaseState.All_FINAL_ORDERS_ISSUED.name()); + } + + @Test + void shouldChangeCaseStateWhenApplicantAcceptCourtDecisionAndSignedSettlement() { + CaseData caseData = CaseDataBuilder.builder() + .applicant1AcceptAdmitAmountPaidSpec(YES) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .applicant1AcceptFullAdmitPaymentPlanSpec(NO) + .applicant1RepaymentOptionForDefendantSpec(PaymentType.REPAYMENT_PLAN) + .applicant1(Party.builder().type(Party.Type.INDIVIDUAL).partyName("CLAIMANT_ORG_NAME").build()) + .respondent1(Party.builder() + .type(Party.Type.INDIVIDUAL) + .partyName("Test Inc") + .build()) + .caseDataLip(CaseDataLiP.builder() + .applicant1LiPResponse(ClaimantLiPResponse.builder() + .claimantResponseOnCourtDecision( + ClaimantResponseOnCourtDecisionType.ACCEPT_REPAYMENT_DATE) + .applicant1SignedSettlementAgreement( + YesOrNo.YES).build()) + .build()) + .build(); + + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + assertThat(response.getState()).isEqualTo(CaseState.All_FINAL_ORDERS_ISSUED.name()); + } + } @Test diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimLipCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimLipCallbackHandlerTest.java index 13263a7584e..9894c493f7f 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimLipCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimLipCallbackHandlerTest.java @@ -1,5 +1,6 @@ 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; @@ -16,6 +17,7 @@ import uk.gov.hmcts.reform.civil.handler.callback.BaseCallbackHandlerTest; import uk.gov.hmcts.reform.civil.helpers.CaseDetailsConverter; import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.Party; import uk.gov.hmcts.reform.civil.repositories.SpecReferenceNumberRepository; import uk.gov.hmcts.reform.civil.sampledata.CallbackParamsBuilder; import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; @@ -24,6 +26,7 @@ import uk.gov.hmcts.reform.civil.service.Time; import uk.gov.hmcts.reform.civil.service.flowstate.StateFlowEngine; import uk.gov.hmcts.reform.civil.service.pininpost.DefendantPinToPostLRspecService; +import uk.gov.hmcts.reform.civil.utils.CaseFlagsInitialiser; import uk.gov.hmcts.reform.civil.utils.InterestCalculator; import java.time.LocalDateTime; @@ -59,6 +62,9 @@ class CreateClaimLipCallbackHandlerTest extends BaseCallbackHandlerTest { @MockBean private SpecReferenceNumberRepository specReferenceNumberRepository; + @MockBean + private CaseFlagsInitialiser caseFlagInitialiser; + @MockBean private Time time; @@ -70,6 +76,9 @@ class CreateClaimLipCallbackHandlerTest extends BaseCallbackHandlerTest { public static final String REFERENCE_NUMBER = "000MC001"; + @Autowired + private ObjectMapper mapper; + @Nested class AboutToStatCallback { @@ -91,6 +100,8 @@ class AboutToSubmitCallback { private CallbackParams params; private CaseData caseData; + private static final String DEFENDANT_EMAIL_ADDRESS = "defendantmail@hmcts.net"; + private static final String DEFENDANT_PARTY_NAME = "ABC ABC"; private final LocalDateTime submittedDate = LocalDateTime.now(); @@ -105,16 +116,25 @@ void setup() { @Test void shouldAddCaseReferenceSubmittedDateAndAllocatedTrack_whenInvoked() { + caseData = CaseDataBuilder.builder() + .respondent1(Party.builder() + .type(Party.Type.INDIVIDUAL) + .partyName(DEFENDANT_PARTY_NAME) + .partyEmail(DEFENDANT_EMAIL_ADDRESS).build()) + .build(); + CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData).request( CallbackRequest.builder().eventId(CREATE_LIP_CLAIM.name()).build()) .build(); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); - System.out.println(response.getData()); assertThat(response.getData()) .containsEntry("legacyCaseReference", REFERENCE_NUMBER) .containsEntry("submittedDate", submittedDate.format(DateTimeFormatter.ISO_DATE_TIME)); + CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); + assertThat(updatedData.getRespondent1DetailsForClaimDetailsTab().getPartyName().equals(DEFENDANT_PARTY_NAME)); + assertThat(updatedData.getRespondent1DetailsForClaimDetailsTab().getType().equals(Party.Type.INDIVIDUAL)); } @Test diff --git a/src/test/java/uk/gov/hmcts/reform/civil/model/docmosis/InterlocutoryJudgementDocMapperTest.java b/src/test/java/uk/gov/hmcts/reform/civil/model/docmosis/InterlocutoryJudgementDocMapperTest.java new file mode 100644 index 00000000000..2a767e2799b --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/model/docmosis/InterlocutoryJudgementDocMapperTest.java @@ -0,0 +1,226 @@ +package uk.gov.hmcts.reform.civil.model.docmosis; + +import org.hamcrest.MatcherAssert; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.junit.jupiter.MockitoExtension; +import uk.gov.hmcts.reform.civil.enums.PaymentType; +import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.PaymentBySetDate; +import uk.gov.hmcts.reform.civil.model.RespondToClaimAdmitPartLRspec; +import uk.gov.hmcts.reform.civil.model.citizenui.CaseDataLiP; +import uk.gov.hmcts.reform.civil.model.citizenui.ClaimantLiPResponse; +import uk.gov.hmcts.reform.civil.service.citizen.repaymentplan.RepaymentPlanDecisionCalculator; +import uk.gov.hmcts.reform.civil.service.citizenui.responsedeadline.DeadlineExtensionCalculatorService; +import uk.gov.hmcts.reform.civil.service.docmosis.utils.ClaimantResponseUtils; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +import static org.hamcrest.Matchers.samePropertyValuesAs; +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.mockStatic; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec.BY_SET_DATE; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec.SUGGESTION_OF_REPAYMENT_PLAN; + +@ExtendWith(MockitoExtension.class) +public class InterlocutoryJudgementDocMapperTest { + + private static final LocalDate ISSUE_DATE = LocalDate.of(2023, 11, 28); + private static final String CLAIM_NUMBER = "claim001"; + private static final String REFER_TO_JUDGE = "Refer to Judge"; + private static final LocalDateTime CLAIMANT_RESPONSE_DATE_TIME = LocalDateTime.of(2023, 11, 28, 6, 30, 40, 50000); + + @Mock + private DeadlineExtensionCalculatorService calculatorService; + @Mock + private RepaymentPlanDecisionCalculator repaymentPlanDecisionCalculator; + private InterlocutoryJudgementDocMapper mapper; + private CaseData caseData; + + @BeforeEach + public void setup() { + mapper = new InterlocutoryJudgementDocMapper(calculatorService, repaymentPlanDecisionCalculator); + } + + @Test + void shouldMapCaseDataToInterlocutoryJudgementDoc() { + + //Given + caseData = getCaseData(); + try (MockedStatic mocked = mockStatic(ClaimantResponseUtils.class)) { + given(repaymentPlanDecisionCalculator.calculateDisposableIncome( + caseData)).willReturn(-100.989999); + given(ClaimantResponseUtils.getClaimantRepaymentType(caseData)).willReturn("Immediately"); + given(ClaimantResponseUtils.getDefendantRepaymentOption(caseData)).willReturn("By a set date"); + given(ClaimantResponseUtils.getClaimantFinalRepaymentDate(caseData)).willReturn(null); + given(ClaimantResponseUtils.getDefendantFinalRepaymentDate(caseData)).willReturn(LocalDate.of( + 2024, + 10, + 10 + )); + InterlocutoryJudgementDoc interlocutoryJudgementDoc = getInterlocutoryJudgementDoc(); + // When + InterlocutoryJudgementDoc actual = mapper.toInterlocutoryJudgementDoc(caseData); + + // Then + MatcherAssert.assertThat(actual, samePropertyValuesAs(interlocutoryJudgementDoc)); + } + } + + @Test + void shouldMapClaimantResponseToDefendantAdmissionWhenResponseTypeSpecIsFull() { + + //Given + caseData = getCaseData(); + caseData = caseData.toBuilder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .build(); + + given(repaymentPlanDecisionCalculator.calculateDisposableIncome( + caseData)).willReturn(-100.989999); + + // When + InterlocutoryJudgementDoc actual = mapper.toInterlocutoryJudgementDoc(caseData); + + // Then + assertEquals(actual.getClaimantResponseToDefendantAdmission(), "I accept full admission"); + } + + @Test + void shouldMapFormattedDisposableIncomeWhenDisposableIncomeIsPositive() { + + //Given + caseData = getCaseData(); + caseData = caseData.toBuilder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .build(); + + given(repaymentPlanDecisionCalculator.calculateDisposableIncome( + caseData)).willReturn(100.989999); + + // When + InterlocutoryJudgementDoc actual = mapper.toInterlocutoryJudgementDoc(caseData); + + // Then + assertEquals(actual.getFormattedDisposableIncome(), "£100.99"); + } + + @Test + void shouldMapDefendantRepaymentLastDateByWhenBySetDate() { + + //Given + caseData = getCaseData(); + caseData = caseData.toBuilder() + .defenceAdmitPartPaymentTimeRouteRequired(BY_SET_DATE) + .respondToClaimAdmitPartLRspec(RespondToClaimAdmitPartLRspec.builder() + .whenWillThisAmountBePaid(LocalDate.of(2024, 10, 10)) + .build()) + .build(); + + // When + InterlocutoryJudgementDoc actual = mapper.toInterlocutoryJudgementDoc(caseData); + + // Then + assertEquals(LocalDate.of(2024, 10, 10), actual.getCourtDecisionRepaymentLastDateBy()); + } + + @Test + void shouldMapClaimantRequestRepaymentLastDateByWhenBySetDate() { + + //Given + caseData = getCaseData(); + caseData = caseData.toBuilder() + .applicant1RepaymentOptionForDefendantSpec(PaymentType.SET_DATE) + .applicant1RequestedPaymentDateForDefendantSpec(PaymentBySetDate.builder() + .paymentSetDate(LocalDate.of(2024, 1, 1)) + .build()) + .build(); + + // When + InterlocutoryJudgementDoc actual = mapper.toInterlocutoryJudgementDoc(caseData); + + // Then + assertEquals(LocalDate.of(2024, 1, 1), actual.getClaimantRequestRepaymentLastDateBy()); + } + + @Test + void shouldMapClaimantRequestRepaymentLastDateByWhenImmediately() { + + //Given + caseData = getCaseData(); + caseData = caseData.toBuilder() + .applicant1RepaymentOptionForDefendantSpec(PaymentType.IMMEDIATELY) + .build(); + given(calculatorService.calculateExtendedDeadline( + any(LocalDate.class), + anyInt() + )).willReturn(LocalDate.now().plusDays(5)); + + // When + InterlocutoryJudgementDoc actual = mapper.toInterlocutoryJudgementDoc(caseData); + + // Then + assertEquals(LocalDate.now().plusDays(5), actual.getClaimantRequestRepaymentLastDateBy()); + } + + @Test + void shouldMapRejectionReason() { + + //Given + caseData = getCaseData(); + caseData = caseData.toBuilder() + .caseDataLiP(CaseDataLiP.builder() + .applicant1LiPResponse(ClaimantLiPResponse.builder() + .applicant1RejectedRepaymentReason("Rejected in test") + .build()) + + .build()) + .build(); + + // When + InterlocutoryJudgementDoc actual = mapper.toInterlocutoryJudgementDoc(caseData); + + // Then + assertEquals("Rejected in test", actual.getRejectionReason()); + } + + private static InterlocutoryJudgementDoc getInterlocutoryJudgementDoc() { + return InterlocutoryJudgementDoc.builder() + .claimIssueDate(ISSUE_DATE) + .claimNumber(CLAIM_NUMBER) + .claimantRequestRepaymentBy("Immediately") + .claimantResponseSubmitDateTime(CLAIMANT_RESPONSE_DATE_TIME) + .claimantResponseToDefendantAdmission("I accept part admission") + .courtDecisionRepaymentBy("By a set date") + .courtDecisionRepaymentLastDateBy(LocalDate.of(2024, 10, 10)) + .formalisePaymentBy(REFER_TO_JUDGE) + .formattedDisposableIncome("-£100.98") + .rejectionReason("Rejected") + .build(); + } + + private static CaseData getCaseData() { + return CaseData.builder() + .issueDate(ISSUE_DATE) + .legacyCaseReference(CLAIM_NUMBER) + .applicant1RepaymentOptionForDefendantSpec(PaymentType.REPAYMENT_PLAN) + .applicant1ResponseDate(CLAIMANT_RESPONSE_DATE_TIME) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .defenceAdmitPartPaymentTimeRouteRequired(SUGGESTION_OF_REPAYMENT_PLAN) + .caseDataLiP(CaseDataLiP.builder() + .applicant1LiPResponse(ClaimantLiPResponse.builder() + .applicant1RejectedRepaymentReason("Rejected") + .build()) + .build()) + .build(); + } + +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/claimantresponse/InterlocutoryJudgementDocGeneratorTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/claimantresponse/InterlocutoryJudgementDocGeneratorTest.java new file mode 100644 index 00000000000..ff81e77b0db --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/claimantresponse/InterlocutoryJudgementDocGeneratorTest.java @@ -0,0 +1,77 @@ +package uk.gov.hmcts.reform.civil.service.docmosis.claimantresponse; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import uk.gov.hmcts.reform.civil.documentmanagement.DocumentManagementService; +import uk.gov.hmcts.reform.civil.documentmanagement.model.DocumentType; +import uk.gov.hmcts.reform.civil.documentmanagement.model.PDF; +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.InterlocutoryJudgementDoc; +import uk.gov.hmcts.reform.civil.model.docmosis.InterlocutoryJudgementDocMapper; +import uk.gov.hmcts.reform.civil.service.docmosis.DocmosisTemplates; +import uk.gov.hmcts.reform.civil.service.docmosis.DocumentGeneratorService; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.verify; + +@ExtendWith(MockitoExtension.class) +public class InterlocutoryJudgementDocGeneratorTest { + + private static final String AUTHORISATION = "authorisation"; + @Mock + private InterlocutoryJudgementDocMapper mapper; + @Mock + private DocumentManagementService documentManagementService; + @Mock + private DocumentGeneratorService documentGeneratorService; + + private InterlocutoryJudgementDocGenerator generator; + @Captor + ArgumentCaptor uploadDocumentArgumentCaptor; + + @BeforeEach + public void setup() { + generator = new InterlocutoryJudgementDocGenerator(mapper, documentManagementService, documentGeneratorService); + } + + @Test + void shouldGenerateInterlocutoryJudgementDoc() { + + //Given + CaseData caseData = CaseData.builder().build(); + InterlocutoryJudgementDoc interlocutoryJudgementDoc = InterlocutoryJudgementDoc.builder().build(); + given(mapper.toInterlocutoryJudgementDoc(any())).willReturn(interlocutoryJudgementDoc); + DocmosisDocument docmosisDocument = DocmosisDocument.builder().build(); + + given(documentGeneratorService.generateDocmosisDocument( + any(InterlocutoryJudgementDoc.class), + any() + )).willReturn( + docmosisDocument); + + //When + generator.generateInterlocutoryJudgementDoc(caseData, AUTHORISATION); + + //Then + verify(documentGeneratorService).generateDocmosisDocument( + interlocutoryJudgementDoc, + DocmosisTemplates.INTERLOCUTORY_JUDGEMENT_DOCUMENT + ); + verify(documentManagementService).uploadDocument( + eq(AUTHORISATION), + uploadDocumentArgumentCaptor.capture() + ); + + PDF document = uploadDocumentArgumentCaptor.getValue(); + assertThat(document.getDocumentType()).isEqualTo(DocumentType.INTERLOCUTORY_JUDGEMENT); + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/utils/ClaimantResponseUtilsTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/utils/ClaimantResponseUtilsTest.java index a5091c1f542..8aebcb551a6 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/utils/ClaimantResponseUtilsTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/utils/ClaimantResponseUtilsTest.java @@ -2,42 +2,50 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import uk.gov.hmcts.reform.civil.enums.PaymentFrequencyClaimantResponseLRspec; +import uk.gov.hmcts.reform.civil.enums.PaymentFrequencyLRspec; import uk.gov.hmcts.reform.civil.enums.PaymentType; +import uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec; +import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec; import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.RepaymentPlanLRspec; import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; import java.math.BigDecimal; import java.time.LocalDate; -import org.junit.jupiter.params.ParameterizedTest; + import static org.assertj.core.api.Assertions.assertThat; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec.SUGGESTION_OF_REPAYMENT_PLAN; import static uk.gov.hmcts.reform.civil.service.docmosis.utils.ClaimantResponseUtils.getClaimantFinalRepaymentDate; import static uk.gov.hmcts.reform.civil.service.docmosis.utils.ClaimantResponseUtils.getClaimantRepaymentType; +import static uk.gov.hmcts.reform.civil.service.docmosis.utils.ClaimantResponseUtils.getDefendantFinalRepaymentDate; +import static uk.gov.hmcts.reform.civil.service.docmosis.utils.ClaimantResponseUtils.getDefendantRepaymentOption; public class ClaimantResponseUtilsTest { @Test void shouldReturnFinalPaymentDateForDefendant() { CaseData caseData = CaseDataBuilder.builder() - .applicant1SuggestInstalmentsPaymentAmountForDefendantSpec(BigDecimal.valueOf(100)) - .issueDate(LocalDate.now()) - .applicant1RepaymentOptionForDefendantSpec(PaymentType.REPAYMENT_PLAN) - .applicant1SuggestInstalmentsFirstRepaymentDateForDefendantSpec(LocalDate.now()) - .applicant1SuggestInstalmentsRepaymentFrequencyForDefendantSpec(PaymentFrequencyClaimantResponseLRspec.ONCE_TWO_WEEKS) - .totalClaimAmount(BigDecimal.valueOf(1000)) - .build(); + .applicant1SuggestInstalmentsPaymentAmountForDefendantSpec(BigDecimal.valueOf(100)) + .issueDate(LocalDate.now()) + .applicant1RepaymentOptionForDefendantSpec(PaymentType.REPAYMENT_PLAN) + .applicant1SuggestInstalmentsFirstRepaymentDateForDefendantSpec(LocalDate.now()) + .applicant1SuggestInstalmentsRepaymentFrequencyForDefendantSpec(PaymentFrequencyClaimantResponseLRspec.ONCE_TWO_WEEKS) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); LocalDate finalDate = getClaimantFinalRepaymentDate(caseData); assertThat(finalDate).isNotNull(); } @ParameterizedTest - @CsvSource({"IMMEDIATELY,Immediately", "SET_DATE,By a set date", "REPAYMENT_PLAN,By installments"}) + @CsvSource({"IMMEDIATELY,Immediately", "SET_DATE,By a set date", "REPAYMENT_PLAN,By instalments"}) void shouldReturnClaimantRepaymentOption(PaymentType input, String expectedOutput) { CaseData caseData = CaseData.builder() - .applicant1RepaymentOptionForDefendantSpec(input) - .build(); + .applicant1RepaymentOptionForDefendantSpec(input) + .build(); String actualOutput = getClaimantRepaymentType(caseData); Assertions.assertEquals(expectedOutput, actualOutput); @@ -46,14 +54,58 @@ void shouldReturnClaimantRepaymentOption(PaymentType input, String expectedOutpu @Test void shouldNotReturnFinalPaymentDateForDefendant_WhenInstallmentIsNull() { CaseData caseData = CaseDataBuilder.builder() - .applicant1SuggestInstalmentsPaymentAmountForDefendantSpec(null) - .issueDate(LocalDate.now()) - .applicant1RepaymentOptionForDefendantSpec(PaymentType.SET_DATE) - .applicant1SuggestInstalmentsFirstRepaymentDateForDefendantSpec(LocalDate.now()) - .totalClaimAmount(BigDecimal.valueOf(1000)) - .build(); + .applicant1SuggestInstalmentsPaymentAmountForDefendantSpec(null) + .issueDate(LocalDate.now()) + .applicant1RepaymentOptionForDefendantSpec(PaymentType.SET_DATE) + .applicant1SuggestInstalmentsFirstRepaymentDateForDefendantSpec(LocalDate.now()) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); LocalDate finalDate = getClaimantFinalRepaymentDate(caseData); assertThat(finalDate).isNull(); } + + @Test + void shouldReturnDefendantFinalRepaymentDateWhenPartAdmission() { + CaseData caseData = CaseData.builder() + .respondent1RepaymentPlan(RepaymentPlanLRspec.builder().repaymentFrequency(PaymentFrequencyLRspec.ONCE_ONE_WEEK) + .firstRepaymentDate(LocalDate.of(2024, 1, 1)) + .paymentAmount(BigDecimal.valueOf(10000)).build()) + .issueDate(LocalDate.now()) + .defenceAdmitPartPaymentTimeRouteRequired(SUGGESTION_OF_REPAYMENT_PLAN) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .respondToAdmittedClaimOwingAmountPounds(BigDecimal.valueOf(800)) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + + LocalDate finalRepaymentDate = getDefendantFinalRepaymentDate(caseData); + assertThat(finalRepaymentDate).isNotNull(); + } + + @Test + void shouldReturnDefendantFinalRepaymentDateWhenFullAdmission() { + CaseData caseData = CaseData.builder() + .respondent1RepaymentPlan(RepaymentPlanLRspec.builder().repaymentFrequency(PaymentFrequencyLRspec.ONCE_ONE_WEEK) + .firstRepaymentDate(LocalDate.of(2024, 1, 1)) + .paymentAmount(new BigDecimal(10000)).build()) + .issueDate(LocalDate.now()) + .defenceAdmitPartPaymentTimeRouteRequired(SUGGESTION_OF_REPAYMENT_PLAN) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + + LocalDate finalRepaymentDate = getDefendantFinalRepaymentDate(caseData); + assertThat(finalRepaymentDate).isNotNull(); + } + + @ParameterizedTest + @CsvSource({"IMMEDIATELY,Immediately", "BY_SET_DATE,By a set date", "SUGGESTION_OF_REPAYMENT_PLAN,By instalments"}) + void shouldReturnDefendantRepaymentOption(RespondentResponsePartAdmissionPaymentTimeLRspec input, String expectedOutput) { + CaseData caseData = CaseData.builder() + .defenceAdmitPartPaymentTimeRouteRequired(input) + .build(); + + String actualOutput = getDefendantRepaymentOption(caseData); + Assertions.assertEquals(expectedOutput, actualOutput); + } }