diff --git a/build.gradle b/build.gradle index 8b2c8c92721..a886bf6291d 100644 --- a/build.gradle +++ b/build.gradle @@ -361,7 +361,8 @@ configurations.all { } dependencies { - implementation 'com.github.hmcts:civil-commons:1.0.43' + implementation 'com.github.hmcts:civil-commons:1.0.44' + 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-00001-LIP-MD.docx b/docker/docmosis/templates/CV-SPC-CLM-ENG-00001-LIP-MD.docx new file mode 100644 index 00000000000..b762584ccbb Binary files /dev/null and b/docker/docmosis/templates/CV-SPC-CLM-ENG-00001-LIP-MD.docx differ diff --git a/docker/docmosis/templates/CV-SPC-CLM-ENG-00001-SETTLEMENT.docx b/docker/docmosis/templates/CV-SPC-CLM-ENG-00001-SETTLEMENT.docx new file mode 100644 index 00000000000..dfb63890602 Binary files /dev/null and b/docker/docmosis/templates/CV-SPC-CLM-ENG-00001-SETTLEMENT.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 dc7bbceed2d..67772ee4bab 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 @@ -114,6 +114,7 @@ public enum CaseEvent { ASSIGN_CASE_TO_APPLICANT1(CAMUNDA), TRIGGER_APPLICATION_CLOSURE(CAMUNDA), APPLICATION_CLOSED_UPDATE_CLAIM(CAMUNDA), + APPLY_NOC_DECISION_LIP(CAMUNDA), TRIGGER_APPLICATION_PROCEEDS_IN_HERITAGE(CAMUNDA), APPLICATION_OFFLINE_UPDATE_CLAIM(CAMUNDA), NOTIFY_APPLICANT_SOLICITOR1_BREATHING_SPACE_ENTER(CAMUNDA), @@ -317,9 +318,11 @@ public enum CaseEvent { SEND_HEARING_TO_LIP_CLAIMANT(CAMUNDA), SEND_FINAL_ORDER_TO_LIP_DEFENDANT(CAMUNDA), SEND_FINAL_ORDER_TO_LIP_CLAIMANT(CAMUNDA), - NOTIFY_CLAIMANT_LIP_HELP_WITH_FEES(CAMUNDA), + RETRIGGER_CASES(CAMUNDA), + GENERATE_LIP_CLAIMANT_MANUAL_DETERMINATION(CAMUNDA), + GENERATE_LIP_SIGN_SETTLEMENT_AGREEMENT_FORM(CAMUNDA), + NOTIFY_CLAIMANT_LIP_HELP_WITH_FEES(CAMUNDA); - RETRIGGER_CASES(CAMUNDA); private final UserType userType; public boolean isCamundaEvent() { diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateClaimantLipManualDeterminationCallBackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateClaimantLipManualDeterminationCallBackHandler.java new file mode 100644 index 00000000000..f26dcc1d1f3 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateClaimantLipManualDeterminationCallBackHandler.java @@ -0,0 +1,67 @@ +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.civil.callback.CaseEvent; +import uk.gov.hmcts.reform.civil.callback.CallbackHandler; +import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.callback.Callback; +import uk.gov.hmcts.reform.civil.callback.CallbackType; +import uk.gov.hmcts.reform.civil.documentmanagement.model.CaseDocument; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.service.SystemGeneratedDocumentService; +import uk.gov.hmcts.reform.civil.service.docmosis.manualdetermination.ClaimantLipManualDeterminationFormGenerator; + +import java.util.Collections; +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.CaseEvent.GENERATE_LIP_CLAIMANT_MANUAL_DETERMINATION; + +@Service +@RequiredArgsConstructor +public class GenerateClaimantLipManualDeterminationCallBackHandler extends CallbackHandler { + + private static final List EVENTS = Collections.singletonList(GENERATE_LIP_CLAIMANT_MANUAL_DETERMINATION); + private static final String TASK_ID = "Generate_LIP_Claimant_MD"; + private final ObjectMapper objectMapper; + private final ClaimantLipManualDeterminationFormGenerator claimantLipManualDeterminationFormGenerator; + private final SystemGeneratedDocumentService systemGeneratedDocumentService; + private final Map callbackMap = Map.of(callbackKey(CallbackType.ABOUT_TO_SUBMIT), + this::prepareClaimantLipManualDetermination); + + @Override + public String camundaActivityId(CallbackParams callbackParams) { + return TASK_ID; + } + + @Override + protected Map callbacks() { + return callbackMap; + } + + @Override + public List handledEvents() { + return EVENTS; + } + + private CallbackResponse prepareClaimantLipManualDetermination(CallbackParams callbackParams) { + CaseData caseData = callbackParams.getCaseData(); + + if (!caseData.getRespondent1().isCompanyOROrganisation()) { + return AboutToStartOrSubmitCallbackResponse.builder().build(); + } + + CaseData.CaseDataBuilder caseDataBuilder = caseData.toBuilder(); + CaseDocument claimantResponseForm = claimantLipManualDeterminationFormGenerator.generate(callbackParams.getCaseData(), + callbackParams.getParams().get(BEARER_TOKEN).toString()); + caseDataBuilder.systemGeneratedCaseDocuments(systemGeneratedDocumentService + .getSystemGeneratedDocumentsWithAddedDocument(claimantResponseForm, caseData)); + return AboutToStartOrSubmitCallbackResponse.builder().data(caseDataBuilder.build().toMap(objectMapper)).build(); + } + +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateSettlementAgreementFormCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateSettlementAgreementFormCallbackHandler.java new file mode 100644 index 00000000000..97b0d74b5a4 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateSettlementAgreementFormCallbackHandler.java @@ -0,0 +1,72 @@ +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.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.service.SystemGeneratedDocumentService; +import uk.gov.hmcts.reform.civil.service.docmosis.settlementagreement.SettlementAgreementFormGenerator; + +import java.util.Collections; +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.GENERATE_LIP_SIGN_SETTLEMENT_AGREEMENT_FORM; + +@Service +@RequiredArgsConstructor +public class GenerateSettlementAgreementFormCallbackHandler extends CallbackHandler { + + private final SettlementAgreementFormGenerator settlementAgreementFormGenerator; + private final SystemGeneratedDocumentService systemGeneratedDocumentService; + private final ObjectMapper objectMapper; + private static final List EVENTS = Collections.singletonList(GENERATE_LIP_SIGN_SETTLEMENT_AGREEMENT_FORM); + private final Map callbackMap = Map.of(callbackKey(ABOUT_TO_SUBMIT), this::generateResponseDocument); + private static final String TASK_ID = "GenerateSignSettlementAgreement"; + + private CallbackResponse generateResponseDocument(CallbackParams callbackParams) { + CaseData caseData = callbackParams.getCaseData(); + CaseData.CaseDataBuilder updatedCaseDataBuilder = caseData.toBuilder(); + + if (caseData.isPayImmediately() || caseData.hasApplicantRejectedRepaymentPlan()) { + return AboutToStartOrSubmitCallbackResponse.builder().build(); + } + + CaseDocument claimantResponseForm = settlementAgreementFormGenerator.generate( + caseData, + callbackParams.getParams().get(BEARER_TOKEN).toString() + ); + updatedCaseDataBuilder.systemGeneratedCaseDocuments(systemGeneratedDocumentService.getSystemGeneratedDocumentsWithAddedDocument( + claimantResponseForm, + caseData + )); + + return AboutToStartOrSubmitCallbackResponse.builder() + .data(updatedCaseDataBuilder.build().toMap(objectMapper)) + .build(); + } + + @Override + protected Map callbacks() { + return callbackMap; + } + + @Override + public List handledEvents() { + return EVENTS; + } + + @Override + public String camundaActivityId(CallbackParams callbackParams) { + return TASK_ID; + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/noticeofchange/UpdateCaseDetailsAfterNoCHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/noticeofchange/UpdateCaseDetailsAfterNoCHandler.java index 43fafb9c004..18f4a4315a0 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/noticeofchange/UpdateCaseDetailsAfterNoCHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/noticeofchange/UpdateCaseDetailsAfterNoCHandler.java @@ -94,6 +94,7 @@ private CallbackResponse updateCaseDetails(CallbackParams callbackParams) { boolean isApplicantSolicitorRole = isApplicantOrRespondent(replacedSolicitorCaseRole); if (isApplicantSolicitorRole) { + unAssignCaseFromClaimantLip(caseDataBuilder); updateApplicantSolicitorDetails(caseDataBuilder, addedSolicitorDetails); } else { unassignCaseFromDefendantLip(caseData); @@ -133,6 +134,19 @@ private void unassignCaseFromDefendantLip(CaseData caseData) { } } + private void unAssignCaseFromClaimantLip(CaseData.CaseDataBuilder caseDataBuilder) { + CaseData caseData = caseDataBuilder.build(); + if (caseData.isApplicantLiP() && caseData.getClaimantUserDetails() != null) { + coreCaseUserService.unassignCase( + caseData.getCcdCaseReference().toString(), + caseData.getClaimantUserDetails().getId(), + null, + CaseRole.CLAIMANT + ); + caseDataBuilder.applicant1Represented(YES); + } + } + private void clearLRIndividuals(String replacedSolicitorCaseRole, CaseData caseData, CaseData.CaseDataBuilder caseDataBuilder, CaseData oldCaseData) { if (CaseRole.APPLICANTSOLICITORONE.getFormattedName().equals(replacedSolicitorCaseRole)) { diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ApplyNoticeOfChangeDecisionCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ApplyNoticeOfChangeDecisionCallbackHandler.java index 6d526dd48b5..30787c3b5ab 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ApplyNoticeOfChangeDecisionCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ApplyNoticeOfChangeDecisionCallbackHandler.java @@ -22,7 +22,6 @@ import uk.gov.hmcts.reform.civil.model.noc.ChangeOrganisationRequest; import uk.gov.hmcts.reform.civil.cas.model.DecisionRequest; -import java.util.Collections; import java.util.List; import java.util.Map; @@ -30,12 +29,14 @@ 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.CaseEvent.APPLY_NOC_DECISION; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.APPLY_NOC_DECISION_LIP; @Service @RequiredArgsConstructor public class ApplyNoticeOfChangeDecisionCallbackHandler extends CallbackHandler { - private static final List EVENTS = Collections.singletonList(APPLY_NOC_DECISION); + private static final List EVENTS = + List.of(APPLY_NOC_DECISION, APPLY_NOC_DECISION_LIP); private final AuthTokenGenerator authTokenGenerator; private final CaseAssignmentApi caseAssignmentApi; @@ -78,9 +79,9 @@ private CallbackResponse applyNoticeOfChangeDecision(CallbackParams callbackPara ); updatedCaseDataBuilder - .businessProcess(BusinessProcess.ready(APPLY_NOC_DECISION)) + .businessProcess(BusinessProcess.ready(getBussinessProcessEvent(postDecisionCaseData))) .changeOfRepresentation(getChangeOfRepresentation( - callbackParams.getCaseData().getChangeOrganisationRequestField(), postDecisionCaseData)); + callbackParams.getCaseData().getChangeOrganisationRequestField(), postDecisionCaseData)); return AboutToStartOrSubmitCallbackResponse.builder() .data(updatedCaseDataBuilder.build().toMap(objectMapper)).build(); @@ -203,7 +204,8 @@ private void setAddLegalRepDeadlinesToNull(CaseData.CaseDataBuilder update } private String getFormerEmail(String caseRole, CaseData caseData) { - if (caseRole.equals(CaseRole.APPLICANTSOLICITORONE.getFormattedName())) { + if (caseRole.equals(CaseRole.APPLICANTSOLICITORONE.getFormattedName()) + && caseData.getApplicantSolicitor1UserDetails() != null) { return caseData.getApplicantSolicitor1UserDetails().getEmail(); } else if (caseRole.equals(CaseRole.RESPONDENTSOLICITORONE.getFormattedName())) { return caseData.getRespondentSolicitor1EmailAddress(); @@ -217,6 +219,13 @@ private boolean isApplicant(String caseRole) { return caseRole.equals(CaseRole.APPLICANTSOLICITORONE.getFormattedName()); } + private CaseEvent getBussinessProcessEvent(CaseData postDecisionCaseData) { + if (postDecisionCaseData.isApplicantLiP()) { + return APPLY_NOC_DECISION_LIP; + } + return APPLY_NOC_DECISION; + } + @Override public List handledEvents() { return EVENTS; 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 c1039dbb757..d96c85b3081 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.CCJPaymentDetails; 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; @@ -49,6 +50,7 @@ public class ClaimantResponseCuiCallbackHandler extends CallbackHandler { private final ObjectMapper objectMapper; private final Time time; private final UpdateCaseManagementDetailsService updateCaseManagementLocationDetailsService; + private final DeadlinesCalculator deadlinesCalculator; @Override protected Map callbacks() { @@ -76,10 +78,12 @@ private CallbackResponse populateCaseData(CallbackParams callbackParams) { private CallbackResponse aboutToSubmit(CallbackParams callbackParams) { CaseData caseData = callbackParams.getCaseData(); + LocalDateTime applicant1ResponseDate = LocalDateTime.now(); CaseData.CaseDataBuilder builder = caseData.toBuilder() - .applicant1ResponseDate(LocalDateTime.now()) - .businessProcess(BusinessProcess.ready(CLAIMANT_RESPONSE_CUI)); + .applicant1ResponseDate(applicant1ResponseDate) + .businessProcess(BusinessProcess.ready(CLAIMANT_RESPONSE_CUI)) + .respondent1RespondToSettlementAgreementDeadline(getRespondToSettlementAgreementDeadline(caseData, applicant1ResponseDate)); updateCaseManagementLocationDetailsService.updateCaseManagementDetails(builder, callbackParams); @@ -93,23 +97,14 @@ private CallbackResponse aboutToSubmit(CallbackParams callbackParams) { AboutToStartOrSubmitCallbackResponse.builder() .data(updatedData.toMap(objectMapper)); - updateClaimStateJudicialReferral(response, updatedData); updateClaimEndState(response, updatedData); return response.build(); } - private void updateClaimStateJudicialReferral( - AboutToStartOrSubmitCallbackResponse.AboutToStartOrSubmitCallbackResponseBuilder response, - CaseData caseData) { - if (isJudicialReferralAllowed(caseData)) { - response.state(CaseState.JUDICIAL_REFERRAL.name()); - } - } - - private boolean isJudicialReferralAllowed(CaseData caseData) { - return (caseData.isClaimantNotSettlePartAdmitClaim() || caseData.isFullDefence()) - && (Objects.nonNull(caseData.getCaseDataLiP()) && caseData.getCaseDataLiP().hasClaimantNotAgreedToFreeMediation()); + private LocalDateTime getRespondToSettlementAgreementDeadline(CaseData caseData, LocalDateTime responseDate) { + return caseData.hasApplicant1SignedSettlementAgreement() + ? deadlinesCalculator.getRespondToSettlementAgreementDeadline(responseDate) : null; } private boolean isProceedsInHeritageSystemAllowed(CaseData caseData) { @@ -134,20 +129,30 @@ private boolean isProceedsInHeritageSystemAllowed(CaseData caseData) { || isCourtDecisionRejected; } - private void updateClaimEndState(AboutToStartOrSubmitCallbackResponse.AboutToStartOrSubmitCallbackResponseBuilder response, CaseData updatedData) { - if (updatedData.hasDefendantAgreedToFreeMediation() && updatedData.hasClaimantAgreedToFreeMediation()) { - response.state(CaseState.IN_MEDIATION.name()); + private String setUpCaseState(AboutToStartOrSubmitCallbackResponse.AboutToStartOrSubmitCallbackResponseBuilder response, CaseData updatedData) { + if (isJudicialReferralAllowed(updatedData)) { + return CaseState.JUDICIAL_REFERRAL.name(); + } else if (updatedData.hasDefendantAgreedToFreeMediation() && updatedData.hasClaimantAgreedToFreeMediation()) { + return CaseState.IN_MEDIATION.name(); } else if (updatedData.hasApplicant1SignedSettlementAgreement() && updatedData.hasApplicantAcceptedRepaymentPlan()) { - response.state(CaseState.All_FINAL_ORDERS_ISSUED.name()); - } else if (Objects.nonNull(updatedData.getApplicant1PartAdmitIntentionToSettleClaimSpec()) && updatedData.isClaimantIntentionSettlePartAdmit()) { - response.state(CaseState.CASE_SETTLED.name()); + return CaseState.All_FINAL_ORDERS_ISSUED.name(); + } else if (isCaseSettledAllowed(updatedData)) { + return CaseState.CASE_SETTLED.name(); } else if (updatedData.hasApplicantNotProceededWithClaim()) { - response.state(CaseState.CASE_DISMISSED.name()); + return CaseState.CASE_DISMISSED.name(); } else if (isProceedsInHeritageSystemAllowed(updatedData)) { - response.state(CaseState.PROCEEDS_IN_HERITAGE_SYSTEM.name()); + return CaseState.PROCEEDS_IN_HERITAGE_SYSTEM.name(); + } else { + return response.build().getState(); } } + private boolean isCaseSettledAllowed(CaseData caseData) { + return ((Objects.nonNull(caseData.getApplicant1PartAdmitIntentionToSettleClaimSpec()) + && caseData.isClaimantIntentionSettlePartAdmit()) + || (caseData.isPartAdmitImmediatePaymentClaimSettled())); + } + private void updateCcjRequestPaymentDetails(CaseData.CaseDataBuilder builder, CaseData caseData) { if (hasCcjRequest(caseData)) { CCJPaymentDetails ccjPaymentDetails = judgementService.buildJudgmentAmountSummaryDetails(caseData); @@ -159,4 +164,23 @@ private boolean hasCcjRequest(CaseData caseData) { return (caseData.isLipvLipOneVOne() && featureToggleService.isLipVLipEnabled() && caseData.hasApplicant1AcceptedCcj() && caseData.isCcjRequestJudgmentByAdmission()); } + + private boolean isJudicialReferralAllowed(CaseData caseData) { + return isProceedOrNotSettleClaim(caseData) + && (isClaimantOrDefendantRejectMediation(caseData) + || caseData.isFastTrackClaim()); + } + + private boolean isProceedOrNotSettleClaim(CaseData caseData) { + return caseData.isClaimantNotSettlePartAdmitClaim() || caseData.isFullDefence() || caseData.isFullDefenceNotPaid(); + } + + private boolean isClaimantOrDefendantRejectMediation(CaseData caseData) { + return (Objects.nonNull(caseData.getCaseDataLiP()) && caseData.getCaseDataLiP().hasClaimantNotAgreedToFreeMediation()) + || caseData.hasDefendantNotAgreedToFreeMediation(); + } + + private void updateClaimEndState(AboutToStartOrSubmitCallbackResponse.AboutToStartOrSubmitCallbackResponseBuilder response, CaseData updatedData) { + response.state(setUpCaseState(response, updatedData)); + } } 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 6ef4866acea..08b193f9bca 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 @@ -8,6 +8,7 @@ import uk.gov.hmcts.reform.ccd.client.model.AboutToStartOrSubmitCallbackResponse; import uk.gov.hmcts.reform.ccd.client.model.CallbackRequest; import uk.gov.hmcts.reform.ccd.client.model.CallbackResponse; +import uk.gov.hmcts.reform.ccd.model.OrganisationPolicy; import uk.gov.hmcts.reform.civil.callback.Callback; import uk.gov.hmcts.reform.civil.callback.CallbackHandler; import uk.gov.hmcts.reform.civil.callback.CallbackParams; @@ -17,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.OrgPolicyUtils; import java.util.Collections; import java.util.List; @@ -29,6 +31,7 @@ import static uk.gov.hmcts.reform.civil.callback.CallbackVersion.V_1; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.CREATE_LIP_CLAIM; import static uk.gov.hmcts.reform.civil.enums.CaseCategory.SPEC_CLAIM; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.APPLICANTSOLICITORONE; @Slf4j @Service @@ -76,9 +79,24 @@ private CallbackResponse submitClaim(CallbackParams callbackParams) { caseDataBuilder.legacyCaseReference(specReferenceNumberRepository.getSpecReferenceNumber()); caseDataBuilder.businessProcess(BusinessProcess.ready(CREATE_LIP_CLAIM)); } + + addOrginsationPoliciesforClaimantLip(caseDataBuilder); return AboutToStartOrSubmitCallbackResponse.builder() .data(caseDataBuilder.build().toMap(objectMapper)) .build(); } + private void addOrginsationPoliciesforClaimantLip(CaseData.CaseDataBuilder caseDataBuilder) { + CaseData caseData = caseDataBuilder.build(); + // LiP are not represented or registered + if (caseData.getApplicant1OrganisationPolicy() == null) { + caseDataBuilder + .applicant1OrganisationPolicy(OrganisationPolicy.builder() + .orgPolicyCaseAssignedRole(APPLICANTSOLICITORONE.getFormattedName()) + .build()); + } + + OrgPolicyUtils.addMissingOrgPolicies(caseDataBuilder); + } + } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimCuiCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimCuiCallbackHandler.java index b4ce2c6b1b2..79f6ad4bc1f 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimCuiCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimCuiCallbackHandler.java @@ -77,6 +77,7 @@ private CaseData getUpdatedCaseData(CallbackParams callbackParams) { .respondent1ResponseDate(responseDate) .respondent1GeneratedResponseDocument(dummyDocument) .respondent1ClaimResponseDocumentSpec(dummyDocument) + .responseClaimTrack(AllocatedTrack.getAllocatedTrack(caseData.getTotalClaimAmount(), null, null).name()) .applicant1ResponseDeadline(deadlinesCalculator.calculateApplicantResponseDeadline( responseDate, allocatedTrack 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 923220f605c..d967415044e 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 @@ -24,6 +24,7 @@ import uk.gov.hmcts.reform.civil.enums.MultiPartyResponseTypeFlags; import uk.gov.hmcts.reform.civil.enums.MultiPartyScenario; import uk.gov.hmcts.reform.civil.enums.PersonalInjuryType; +import uk.gov.hmcts.reform.civil.enums.PaymentType; import uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec; import uk.gov.hmcts.reform.civil.enums.RespondentResponseType; import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec; @@ -464,6 +465,7 @@ public boolean hasNoOngoingBusinessProcess() { private final String claimAmountBreakupSummaryObject; private final LocalDateTime respondent1LitigationFriendDate; private final LocalDateTime respondent2LitigationFriendDate; + private final LocalDateTime respondent1RespondToSettlementAgreementDeadline; private final String paymentTypePBA; private final String paymentTypePBASpec; private final String whenToBePaidText; @@ -926,6 +928,14 @@ public boolean isPartAdmitClaimSpec() { return PART_ADMISSION.equals(getRespondent1ClaimResponseTypeForSpec()); } + @JsonIgnore + public boolean isPartAdmitImmediatePaymentClaimSettled() { + return (isPartAdmitClaimSpec() + && (Objects.nonNull(getApplicant1AcceptAdmitAmountPaidSpec()) + && YesOrNo.YES.equals(getApplicant1AcceptAdmitAmountPaidSpec())) + && PaymentType.IMMEDIATELY.equals(getApplicant1RepaymentOptionForDefendantSpec())); + } + @JsonIgnore public boolean isFullAdmitClaimSpec() { return FULL_ADMISSION.equals(getRespondent1ClaimResponseTypeForSpec()); @@ -1138,6 +1148,16 @@ public String getRespondent1Email() { return null; } + @JsonIgnore + public boolean isRespondentRespondedToSettlementAgreement() { + return getCaseDataLiP() != null && getCaseDataLiP().getRespondentSignSettlementAgreement() != null; + } + + @JsonIgnore + public boolean isRespondentSignedSettlementAgreement() { + return getCaseDataLiP() != null && YesOrNo.YES.equals(getCaseDataLiP().getRespondentSignSettlementAgreement()); + } + @JsonIgnore public List getClaimAmountBreakupDetails() { return Optional.ofNullable(getClaimAmountBreakup()) @@ -1167,8 +1187,9 @@ public boolean hasApplicant1SignedSettlementAgreement() { } @JsonIgnore - public boolean isRespondentSignSettlementAgreement() { - return getCaseDataLiP() != null && getCaseDataLiP().getRespondentSignSettlementAgreement() != null; + public boolean isSettlementAgreementDeadlineExpired() { + return nonNull(respondent1RespondToSettlementAgreementDeadline) + && LocalDateTime.now().isAfter(respondent1RespondToSettlementAgreementDeadline); } @JsonIgnore 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 b8672919bc4..e14c59b57bc 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 @@ -160,6 +160,7 @@ import static java.math.BigDecimal.ZERO; import static java.util.Optional.ofNullable; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; @Jacksonized @@ -411,6 +412,7 @@ public class CaseDataParent implements MappableObject { */ private final ResponseOneVOneShowTag showResponseOneVOneFlag; private final YesOrNo applicant1AcceptAdmitAmountPaidSpec; + private final YesOrNo applicant1FullDefenceConfirmAmountPaidSpec; private final YesOrNo applicant1PartAdmitConfirmAmountPaidSpec; private final YesOrNo applicant1PartAdmitIntentionToSettleClaimSpec; private final YesOrNo applicant1AcceptFullAdmitPaymentPlanSpec; @@ -435,9 +437,14 @@ public class CaseDataParent implements MappableObject { @JsonIgnore public boolean isApplicantNotRepresented() { - return this.applicant1Represented == YesOrNo.NO; + return this.applicant1Represented == NO; } + @JsonIgnore + public boolean isApplicantRepresented() { + return this.applicant1Represented == YES; + } + /** * Adding for Certificate of Service. */ @@ -722,6 +729,7 @@ public boolean isApplicantNotRepresented() { private DynamicList transferCourtLocationList; private NotSuitableSdoOptions notSuitableSdoOptions; private TocTransferCaseReason tocTransferCaseReason; + private String claimantBilingualLanguagePreference; @JsonUnwrapped private final UpdateDetailsForm updateDetailsForm; @@ -810,4 +818,16 @@ public String getHearingLocationText() { .map(DynamicListElement::getLabel) .orElse(null); } + + @JsonIgnore + public boolean isBilingual() { + return null != claimantBilingualLanguagePreference + && !claimantBilingualLanguagePreference.equalsIgnoreCase(Language.ENGLISH.toString()); + } + + @JsonIgnore + public boolean isFullDefenceNotPaid() { + return NO.equals(getApplicant1FullDefenceConfirmAmountPaidSpec()); + } + } 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 32382122fad..769739d5802 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 @@ -108,6 +108,11 @@ public boolean isCompanyOROrganisation() { return this.isCompany() || this.isOrganisation(); } + @JsonIgnore + public boolean isIndividualORSoleTrader() { + return this.isIndividual() || this.isSoleTrader(); + } + @JsonIgnore public LocalDate getDateOfBirth() { return Optional.ofNullable(individualDateOfBirth).orElse(soleTraderDateOfBirth); diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdDashboardClaimMatcher.java b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdDashboardClaimMatcher.java new file mode 100644 index 00000000000..4de00c74f01 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdDashboardClaimMatcher.java @@ -0,0 +1,38 @@ +package uk.gov.hmcts.reform.civil.model.citizenui; + +import lombok.AllArgsConstructor; +import uk.gov.hmcts.reform.civil.model.CaseData; + +import java.util.Objects; + +@AllArgsConstructor +public class CcdDashboardClaimMatcher { + + protected CaseData caseData; + + public boolean hasClaimantAndDefendantSignedSettlementAgreement() { + return caseData.hasApplicant1SignedSettlementAgreement() && caseData.isRespondentSignedSettlementAgreement() && !isSettled(); + } + + public boolean hasDefendantRejectedSettlementAgreement() { + return caseData.hasApplicant1SignedSettlementAgreement() && caseData.isRespondentRespondedToSettlementAgreement() + && !caseData.isRespondentSignedSettlementAgreement() && !isSettled(); + } + + public boolean hasClaimantSignedSettlementAgreement() { + return caseData.hasApplicant1SignedSettlementAgreement() && !caseData.isSettlementAgreementDeadlineExpired() && !isSettled(); + } + + public boolean hasClaimantSignedSettlementAgreementAndDeadlineExpired() { + return caseData.hasApplicant1SignedSettlementAgreement() && caseData.isSettlementAgreementDeadlineExpired() && !isSettled(); + } + + public boolean isSettled() { + return !caseData.isRespondentResponseFullDefence() + && (caseData.respondent1PaidInFull() + || caseData.isResponseAcceptedByClaimant()) + && Objects.isNull(caseData.getCcjPaymentDetails()) + && !caseData.hasApplicantRejectedRepaymentPlan() + || caseData.isPartAdmitClaimSettled(); + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdDashboardClaimantClaimMatcher.java b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdDashboardClaimantClaimMatcher.java index bf89bd45a36..c4f7897c2cf 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdDashboardClaimantClaimMatcher.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdDashboardClaimantClaimMatcher.java @@ -1,6 +1,5 @@ package uk.gov.hmcts.reform.civil.model.citizenui; -import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import uk.gov.hmcts.reform.civil.enums.CaseState; import uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec; @@ -17,13 +16,16 @@ import java.util.Optional; @Slf4j -@AllArgsConstructor -public class CcdDashboardClaimantClaimMatcher implements Claim { +public class CcdDashboardClaimantClaimMatcher extends CcdDashboardClaimMatcher implements Claim { private static final LocalTime FOUR_PM = LocalTime.of(16, 1, 0); - private CaseData caseData; private FeatureToggleService featureToggleService; + public CcdDashboardClaimantClaimMatcher(CaseData caseData, FeatureToggleService featureToggleService) { + super(caseData); + this.featureToggleService = featureToggleService; + } + @Override public boolean hasResponsePending() { return caseData.getRespondent1ResponseDate() == null && !isPaperResponse(); @@ -86,16 +88,6 @@ public boolean claimantConfirmedDefendantPaid() { return caseData.getRespondent1CourtOrderPayment() != null && caseData.respondent1PaidInFull(); } - @Override - public boolean isSettled() { - return !caseData.isRespondentResponseFullDefence() - && (caseData.respondent1PaidInFull() - || caseData.isResponseAcceptedByClaimant()) - && Objects.isNull(caseData.getCcjPaymentDetails()) - && !caseData.hasApplicantRejectedRepaymentPlan() - || caseData.isPartAdmitClaimSettled(); - } - @Override public boolean isSentToCourt() { return false; diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdDashboardDefendantClaimMatcher.java b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdDashboardDefendantClaimMatcher.java index 594a2569625..ddfc375a873 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdDashboardDefendantClaimMatcher.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdDashboardDefendantClaimMatcher.java @@ -1,6 +1,7 @@ package uk.gov.hmcts.reform.civil.model.citizenui; -import lombok.AllArgsConstructor; +import java.time.LocalDate; +import java.time.LocalTime; import lombok.extern.slf4j.Slf4j; import uk.gov.hmcts.reform.civil.enums.CaseState; import uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec; @@ -11,17 +12,18 @@ import uk.gov.hmcts.reform.civil.model.sdo.SmallClaimsHearing; import uk.gov.hmcts.reform.civil.service.FeatureToggleService; -import java.time.LocalDate; -import java.time.LocalTime; import java.util.Objects; import java.util.Optional; @Slf4j -@AllArgsConstructor -public class CcdDashboardDefendantClaimMatcher implements Claim { +public class CcdDashboardDefendantClaimMatcher extends CcdDashboardClaimMatcher implements Claim { + + public CcdDashboardDefendantClaimMatcher(CaseData caseData, FeatureToggleService featureToggleService) { + super(caseData); + this.featureToggleService = featureToggleService; + } private static final LocalTime FOUR_PM = LocalTime.of(16, 1, 0); - private CaseData caseData; private FeatureToggleService featureToggleService; @Override @@ -86,16 +88,6 @@ public boolean claimantConfirmedDefendantPaid() { return caseData.getRespondent1CourtOrderPayment() != null && caseData.respondent1PaidInFull(); } - @Override - public boolean isSettled() { - return !caseData.isRespondentResponseFullDefence() - && (caseData.respondent1PaidInFull() - || caseData.isResponseAcceptedByClaimant()) - && Objects.isNull(caseData.getCcjPaymentDetails()) - && !caseData.hasApplicantRejectedRepaymentPlan() - || caseData.isPartAdmitClaimSettled(); - } - @Override public boolean isSentToCourt() { return false; diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/Claim.java b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/Claim.java index f8a6c0c3202..1f78c45c3d4 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/Claim.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/Claim.java @@ -42,6 +42,14 @@ public interface Claim { boolean hasClaimantAskedToSignSettlementAgreement(); + boolean hasClaimantAndDefendantSignedSettlementAgreement(); + + boolean hasDefendantRejectedSettlementAgreement(); + + boolean hasClaimantSignedSettlementAgreement(); + + boolean hasClaimantSignedSettlementAgreementAndDeadlineExpired(); + boolean hasClaimantAcceptedPartialAdmissionAmount(); boolean haveBothPartiesSignedSettlementAgreement(); diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/DashboardClaimStatus.java b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/DashboardClaimStatus.java index c297110458b..2d18920fb0b 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/DashboardClaimStatus.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/DashboardClaimStatus.java @@ -42,6 +42,18 @@ public enum DashboardClaimStatus { TRANSFERRED( Claim::isSentToCourt ), + CLAIMANT_AND_DEFENDANT_SIGNED_SETTLEMENT_AGREEMENT( + Claim::hasClaimantAndDefendantSignedSettlementAgreement + ), + DEFENDANT_REJECTED_SETTLEMENT_AGREEMENT( + Claim::hasDefendantRejectedSettlementAgreement + ), + CLAIMANT_SIGNED_SETTLEMENT_AGREEMENT_DEADLINE_EXPIRED( + Claim::hasClaimantSignedSettlementAgreementAndDeadlineExpired + ), + CLAIMANT_SIGNED_SETTLEMENT_AGREEMENT( + Claim::hasClaimantSignedSettlementAgreement + ), SETTLED( Claim::isSettled ), diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/manualdetermination/ClaimantLipManualDeterminationForm.java b/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/manualdetermination/ClaimantLipManualDeterminationForm.java new file mode 100644 index 00000000000..9ace28e0e92 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/manualdetermination/ClaimantLipManualDeterminationForm.java @@ -0,0 +1,49 @@ +package uk.gov.hmcts.reform.civil.model.docmosis.manualdetermination; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import uk.gov.hmcts.reform.civil.enums.PaymentType; +import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec; +import uk.gov.hmcts.reform.civil.model.common.MappableObject; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; + +@Getter +@Builder +@AllArgsConstructor +@EqualsAndHashCode +public class ClaimantLipManualDeterminationForm implements MappableObject { + + private final String referenceNumber; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy") + @JsonSerialize(using = LocalDateSerializer.class) + private final LocalDate claimIssueDate; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd MMMM yyyy 'at' HH:mm a") + @JsonSerialize(using = LocalDateTimeSerializer.class) + private final LocalDateTime claimantResponseSubmitDate; + @JsonFormat(shape = JsonFormat.Shape.STRING) + private final BigDecimal defendantAdmittedAmount; + private final PaymentType repaymentType; + @JsonFormat(shape = JsonFormat.Shape.STRING) + private BigDecimal regularPaymentAmount; + private String repaymentFrequency; + private final String claimantRequestRepaymentBy; + private final RespondentResponseTypeSpec claimResponseType; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy") + @JsonSerialize(using = LocalDateSerializer.class) + private final LocalDate firstRepaymentDate; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy") + @JsonSerialize(using = LocalDateSerializer.class) + private final LocalDate lastRepaymentDate; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy") + @JsonSerialize(using = LocalDateSerializer.class) + private final LocalDate paymentSetDateForDefendant; +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/settlementagreement/SettlementAgreementForm.java b/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/settlementagreement/SettlementAgreementForm.java new file mode 100644 index 00000000000..c4a3a5ff11a --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/settlementagreement/SettlementAgreementForm.java @@ -0,0 +1,34 @@ +package uk.gov.hmcts.reform.civil.model.docmosis.settlementagreement; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import uk.gov.hmcts.reform.civil.model.Address; +import uk.gov.hmcts.reform.civil.model.common.MappableObject; +import uk.gov.hmcts.reform.civil.model.docmosis.lip.LipFormParty; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +@Builder +@Getter +@EqualsAndHashCode +public class SettlementAgreementForm implements MappableObject { + + private final String claimReferenceNumber; + private final LipFormParty claimant; + private final LipFormParty defendant; + private final Address claimantCorrespondenceAddress; + private final Address defendantCorrespondenceAddress; + private final String totalClaimAmount; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy") + @JsonSerialize(using = LocalDateSerializer.class) + private final LocalDate settlementAgreedDate; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd MMMM yyyy 'at' HH:mm a") + @JsonSerialize(using = LocalDateTimeSerializer.class) + private final LocalDateTime settlementSubmittedDate; +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/settlementagreement/SettlementAgreementFormMapper.java b/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/settlementagreement/SettlementAgreementFormMapper.java new file mode 100644 index 00000000000..22810de947c --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/docmosis/settlementagreement/SettlementAgreementFormMapper.java @@ -0,0 +1,110 @@ +package uk.gov.hmcts.reform.civil.model.docmosis.settlementagreement; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import uk.gov.hmcts.reform.civil.enums.PaymentFrequencyLRspec; +import uk.gov.hmcts.reform.civil.model.Address; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.citizenui.AdditionalLipPartyDetails; +import uk.gov.hmcts.reform.civil.model.citizenui.CaseDataLiP; +import uk.gov.hmcts.reform.civil.model.docmosis.lip.LipFormParty; +import uk.gov.hmcts.reform.civil.utils.MonetaryConversions; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDate; +import java.util.Optional; + +import static java.util.Objects.isNull; +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; + +@Component +@RequiredArgsConstructor +public class SettlementAgreementFormMapper { + + public SettlementAgreementForm buildFormData(CaseData caseData) { + Optional caseDataLip = Optional.ofNullable(caseData.getCaseDataLiP()); + Optional applicantDetails = + caseDataLip.map(CaseDataLiP::getApplicant1AdditionalLipPartyDetails); + Optional defendantDetails = + caseDataLip.map(CaseDataLiP::getRespondent1AdditionalLipPartyDetails); + caseData.getApplicant1().setPartyEmail(caseData.getClaimantUserDetails() != null + ? caseData.getClaimantUserDetails().getEmail() : null); + LipFormParty claimant = LipFormParty.toLipFormParty( + caseData.getApplicant1(), + getCorrespondenceAddress(applicantDetails), + getContactPerson(applicantDetails) + ); + + LipFormParty defendant = LipFormParty.toLipFormParty( + caseData.getRespondent1(), + getCorrespondenceAddress(defendantDetails), + getContactPerson(defendantDetails) + ); + + String totalClaimAmount = Optional.ofNullable(caseData.getTotalClaimAmount()) + .map(BigDecimal::toString) + .orElse("0"); + + SettlementAgreementForm.SettlementAgreementFormBuilder builder = new SettlementAgreementForm.SettlementAgreementFormBuilder(); + return builder + .claimant(claimant) + .defendant(defendant) + .claimReferenceNumber(caseData.getLegacyCaseReference()) + .totalClaimAmount(getClaimAmount(caseData)) + .settlementAgreedDate(getSettlementDate(caseData)) + .settlementSubmittedDate(caseData.getRespondent1ResponseDate()) + .build(); + } + + private Address getCorrespondenceAddress(Optional partyDetails) { + return partyDetails.map(AdditionalLipPartyDetails::getCorrespondenceAddress).orElse(null); + } + + private String getContactPerson(Optional partyDetails) { + return partyDetails.map(AdditionalLipPartyDetails::getContactPerson).orElse(null); + } + + private LocalDate getSettlementDate(CaseData caseData) { + if (caseData.getDefenceAdmitPartPaymentTimeRouteRequired() == BY_SET_DATE) { + return caseData.getDateForRepayment(); + + } + if (caseData.getDefenceAdmitPartPaymentTimeRouteRequired() == SUGGESTION_OF_REPAYMENT_PLAN) { + return getClaimantFinalRepaymentDate(caseData); + } + return null; + } + + public static LocalDate getClaimantFinalRepaymentDate(CaseData caseData) { + BigDecimal paymentAmount = caseData.getRespondent1RepaymentPlan().getPaymentAmount(); + BigDecimal paymentAmountPounds = MonetaryConversions.penniesToPounds(paymentAmount); + LocalDate firstRepaymentDate = caseData.getRespondent1RepaymentPlan().getFirstRepaymentDate(); + PaymentFrequencyLRspec repaymentFrequency = caseData.getRespondent1RepaymentPlan().getRepaymentFrequency(); + + BigDecimal claimantTotalAmount = caseData.getTotalClaimAmount(); + if (isNull(firstRepaymentDate) || isNull(paymentAmountPounds) || isNull(repaymentFrequency)) { + return null; + } + long numberOfInstallmentsAfterFirst = getNumberOfInstallmentsAfterFirst(claimantTotalAmount, paymentAmountPounds); + + 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 String getClaimAmount(CaseData caseData) { + BigDecimal claimAmount = caseData.getTotalClaimAmount(); + if (caseData.isPartAdmitClaimSpec()) { + claimAmount = caseData.getRespondToAdmittedClaimOwingAmountPounds(); + } + return claimAmount.toString(); + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/DeadlinesCalculator.java b/src/main/java/uk/gov/hmcts/reform/civil/service/DeadlinesCalculator.java index 11693a44e14..5502915e29a 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/DeadlinesCalculator.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/DeadlinesCalculator.java @@ -131,4 +131,8 @@ public LocalDate calculateWhenToBePaid(LocalDateTime responseDate) { dateTime = dateTime.plusDays(daysToAdd); return dateTime.toLocalDate(); } + + public LocalDateTime getRespondToSettlementAgreementDeadline(LocalDateTime fromDateTime) { + return plusWorkingDays(fromDateTime.toLocalDate(), 7).atTime(END_OF_BUSINESS_DAY); + } } 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 84875806e64..0adf4e7b9b2 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 @@ -61,7 +61,10 @@ public enum DocmosisTemplates { // judge final Order 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"); + 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"); + private final String template; private final String documentTitle; diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/manualdetermination/ClaimantLipManualDeterminationFormGenerator.java b/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/manualdetermination/ClaimantLipManualDeterminationFormGenerator.java new file mode 100644 index 00000000000..06864bac884 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/manualdetermination/ClaimantLipManualDeterminationFormGenerator.java @@ -0,0 +1,77 @@ +package uk.gov.hmcts.reform.civil.service.docmosis.manualdetermination; + +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.enums.PaymentFrequencyClaimantResponseLRspec; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.PaymentBySetDate; +import uk.gov.hmcts.reform.civil.model.docmosis.DocmosisDocument; +import uk.gov.hmcts.reform.civil.model.docmosis.manualdetermination.ClaimantLipManualDeterminationForm; +import uk.gov.hmcts.reform.civil.service.docmosis.DocmosisTemplates; +import uk.gov.hmcts.reform.civil.service.docmosis.DocumentGeneratorService; +import uk.gov.hmcts.reform.civil.service.docmosis.TemplateDataGenerator; +import uk.gov.hmcts.reform.civil.service.docmosis.utils.ClaimantResponseUtils; + +import java.time.LocalDate; + +import static java.util.Objects.nonNull; +import static uk.gov.hmcts.reform.civil.service.docmosis.DocmosisTemplates.CLAIMANT_LIP_MANUAL_DETERMINATION_PDF; + +@Service +@Getter +@RequiredArgsConstructor +public class ClaimantLipManualDeterminationFormGenerator implements TemplateDataGenerator { + + private final DocumentManagementService documentManagementService; + private final DocumentGeneratorService documentGeneratorService; + + public CaseDocument generate(CaseData caseData, String authorisation) { + ClaimantLipManualDeterminationForm templateData = getTemplateData(caseData); + DocmosisTemplates template = getDocmosisTemplate(); + DocmosisDocument docmosisDocument = documentGeneratorService.generateDocmosisDocument(templateData, template); + PDF lipManualDeterminationPdf = new PDF(getFileName(template, caseData), docmosisDocument.getBytes(), DocumentType.LIP_MANUAL_DETERMINATION); + return documentManagementService.uploadDocument( + authorisation, + lipManualDeterminationPdf); + } + + private String getFileName(DocmosisTemplates template, CaseData caseData) { + return String.format(template.getDocumentTitle(), caseData.getLegacyCaseReference()); + } + + @Override + public ClaimantLipManualDeterminationForm getTemplateData(CaseData caseData) { + ClaimantLipManualDeterminationForm.ClaimantLipManualDeterminationFormBuilder + manualDeterminationForm = ClaimantLipManualDeterminationForm.builder() + .referenceNumber(caseData.getLegacyCaseReference()) + .claimIssueDate(caseData.getIssueDate()) + .claimantResponseSubmitDate(caseData.getApplicant1ResponseDate()) + .defendantAdmittedAmount(caseData.getRespondToAdmittedClaimOwingAmountPounds()) + .claimantRequestRepaymentBy(ClaimantResponseUtils.getClaimantRepaymentType(caseData)) + .claimResponseType(caseData.getRespondent1ClaimResponseTypeForSpec()) + .regularPaymentAmount(caseData.getApplicant1SuggestInstalmentsPaymentAmountForDefendantSpec()) + .repaymentFrequency(getRepaymentFrequency(caseData.getApplicant1SuggestInstalmentsRepaymentFrequencyForDefendantSpec())) + .repaymentType(caseData.getApplicant1RepaymentOptionForDefendantSpec()) + .firstRepaymentDate(caseData.getApplicant1SuggestInstalmentsFirstRepaymentDateForDefendantSpec()) + .lastRepaymentDate(ClaimantResponseUtils.getClaimantFinalRepaymentDate(caseData)) + .paymentSetDateForDefendant(getRepaymentSetByDate(caseData.getApplicant1RequestedPaymentDateForDefendantSpec())); + return manualDeterminationForm.build(); + } + + private DocmosisTemplates getDocmosisTemplate() { + return CLAIMANT_LIP_MANUAL_DETERMINATION_PDF; + } + + private String getRepaymentFrequency(PaymentFrequencyClaimantResponseLRspec claimantSuggestedRepaymentFrequency) { + return (nonNull(claimantSuggestedRepaymentFrequency)) ? claimantSuggestedRepaymentFrequency.getLabel() : null; + } + + private LocalDate getRepaymentSetByDate(PaymentBySetDate paymentBySetDate) { + return (nonNull(paymentBySetDate)) ? paymentBySetDate.getPaymentSetDate() : null; + } +} \ No newline at end of file diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/settlementagreement/SettlementAgreementFormGenerator.java b/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/settlementagreement/SettlementAgreementFormGenerator.java new file mode 100644 index 00000000000..b3059046405 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/settlementagreement/SettlementAgreementFormGenerator.java @@ -0,0 +1,47 @@ +package uk.gov.hmcts.reform.civil.service.docmosis.settlementagreement; + +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.settlementagreement.SettlementAgreementForm; +import uk.gov.hmcts.reform.civil.model.docmosis.settlementagreement.SettlementAgreementFormMapper; +import uk.gov.hmcts.reform.civil.service.docmosis.DocmosisTemplates; +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.SETTLEMENT_AGREEMENT_PDF; + +@Service +@Getter +@RequiredArgsConstructor +public class SettlementAgreementFormGenerator implements TemplateDataGenerator { + + private final SettlementAgreementFormMapper settlementAgreementFormMapper; + private final DocumentManagementService documentManagementService; + private final DocumentGeneratorService documentGeneratorService; + + public CaseDocument generate(CaseData caseData, String authorisation) { + DocmosisDocument document = documentGeneratorService.generateDocmosisDocument(getTemplateData(caseData), SETTLEMENT_AGREEMENT_PDF); + DocmosisTemplates template = getTemplate(); + PDF pdf = new PDF(getFileName(caseData, template), document.getBytes(), DocumentType.SETTLEMENT_AGREEMENT); + return documentManagementService.uploadDocument(authorisation, pdf); + } + + public SettlementAgreementForm getTemplateData(CaseData caseData) { + return settlementAgreementFormMapper.buildFormData(caseData); + } + + private String getFileName(CaseData caseData, DocmosisTemplates template) { + return String.format(template.getDocumentTitle(), caseData.getLegacyCaseReference()); + } + + private DocmosisTemplates getTemplate() { + return SETTLEMENT_AGREEMENT_PDF; + } +} 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 new file mode 100644 index 00000000000..2ad44e53651 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/utils/ClaimantResponseUtils.java @@ -0,0 +1,52 @@ +package uk.gov.hmcts.reform.civil.service.docmosis.utils; + +import uk.gov.hmcts.reform.civil.enums.PaymentFrequencyClaimantResponseLRspec; +import uk.gov.hmcts.reform.civil.enums.PaymentType; +import uk.gov.hmcts.reform.civil.model.CaseData; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDate; + +import static java.util.Objects.isNull; + +public class ClaimantResponseUtils { + + private ClaimantResponseUtils() { + //NO-OP + } + + public static String getClaimantRepaymentType(CaseData caseData) { + PaymentType claimantRepaymentOption = caseData.getApplicant1RepaymentOptionForDefendantSpec(); + if (claimantRepaymentOption == null) { + return "No payment type selected"; + } + if (claimantRepaymentOption == PaymentType.REPAYMENT_PLAN) { + return "By installments"; + } else { + return claimantRepaymentOption.getDisplayedValue(); + } + } + + public static LocalDate getClaimantFinalRepaymentDate(CaseData caseData) { + BigDecimal paymentAmount = caseData.getApplicant1SuggestInstalmentsPaymentAmountForDefendantSpec(); + LocalDate firstRepaymentDate = caseData.getApplicant1SuggestInstalmentsFirstRepaymentDateForDefendantSpec(); + PaymentFrequencyClaimantResponseLRspec repaymentFrequency = caseData.getApplicant1SuggestInstalmentsRepaymentFrequencyForDefendantSpec(); + + BigDecimal claimantTotalAmount = caseData.getTotalClaimAmount(); + if (isNull(firstRepaymentDate) || isNull(paymentAmount) || isNull(repaymentFrequency)) { + return null; + } + long numberOfInstallmentsAfterFirst = getNumberOfInstallmentsAfterFirst(claimantTotalAmount, 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; + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowLipPredicate.java b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowLipPredicate.java index f1d9c2bcd31..5b81f76ecf0 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowLipPredicate.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowLipPredicate.java @@ -11,7 +11,7 @@ private FlowLipPredicate() { } public static final Predicate isLipCase = caseData -> - caseData.isApplicantNotRepresented(); + caseData.isApplicantNotRepresented() || caseData.isApplicantRepresented(); public static final Predicate agreedToMediation = CaseData::hasClaimantAgreedToFreeMediation; @@ -25,6 +25,6 @@ private FlowLipPredicate() { CaseData::isCcjRequestJudgmentByAdmission; public static final Predicate isRespondentSignSettlementAgreement = - CaseData::isRespondentSignSettlementAgreement; + CaseData::isRespondentRespondedToSettlementAgreement; } 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 c2e6e778b0d..f3a7f026377 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 @@ -14,6 +14,10 @@ import static java.util.Collections.emptyList; import static java.util.Map.entry; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.DEFENDANT_SIGN_SETTLEMENT_AGREEMENT; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.LIFT_BREATHING_SPACE_LIP; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.asyncStitchingComplete; +import static uk.gov.hmcts.reform.civil.enums.CaseCategory.SPEC_CLAIM; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.ACKNOWLEDGEMENT_OF_SERVICE; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.ACKNOWLEDGE_CLAIM; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.ADD_CASE_NOTE; diff --git a/src/main/java/uk/gov/hmcts/reform/cmc/model/ClaimantResponse.java b/src/main/java/uk/gov/hmcts/reform/cmc/model/ClaimantResponse.java index 51fb8190893..927004bea77 100644 --- a/src/main/java/uk/gov/hmcts/reform/cmc/model/ClaimantResponse.java +++ b/src/main/java/uk/gov/hmcts/reform/cmc/model/ClaimantResponse.java @@ -21,6 +21,7 @@ public class ClaimantResponse { private String paymentReceived; private String settleForAmount; private CourtDetermination courtDetermination; + private FormaliseOption formaliseOption; @JsonIgnore public boolean hasCourtDetermination() { diff --git a/src/main/java/uk/gov/hmcts/reform/cmc/model/CmcClaim.java b/src/main/java/uk/gov/hmcts/reform/cmc/model/CmcClaim.java index e3b80c94597..d17de99f2d9 100644 --- a/src/main/java/uk/gov/hmcts/reform/cmc/model/CmcClaim.java +++ b/src/main/java/uk/gov/hmcts/reform/cmc/model/CmcClaim.java @@ -14,16 +14,19 @@ import lombok.Data; import lombok.NoArgsConstructor; import net.minidev.json.annotate.JsonIgnore; +import org.apache.commons.collections4.CollectionUtils; import uk.gov.hmcts.reform.civil.model.citizenui.Claim; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Objects; import java.util.Optional; -import static uk.gov.hmcts.reform.civil.model.citizenui.DtoFieldFormat.DATE_TIME_FORMAT; import static uk.gov.hmcts.reform.civil.model.citizenui.DtoFieldFormat.DATE_FORMAT; @Data @@ -67,7 +70,7 @@ public class CmcClaim implements Claim { @JsonDeserialize(using = LocalDateTimeDeserializer.class) private LocalDateTime createdAt; - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DATE_TIME_FORMAT) + @JsonFormat(shape = JsonFormat.Shape.STRING) @JsonSerialize(using = LocalDateTimeSerializer.class) @JsonDeserialize(using = LocalDateTimeDeserializer.class) private LocalDateTime reDeterminationRequestedAt; @@ -76,10 +79,17 @@ public class CmcClaim implements Claim { @JsonSerialize(using = LocalDateSerializer.class) @JsonDeserialize(using = LocalDateDeserializer.class) private LocalDate admissionPayImmediatelyPastPaymentDate; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DATE_FORMAT) @JsonSerialize(using = LocalDateSerializer.class) @JsonDeserialize(using = LocalDateDeserializer.class) private LocalDate intentionToProceedDeadline; + + @JsonFormat(shape = JsonFormat.Shape.STRING) + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + private LocalDateTime claimantRespondedAt; + private ClaimantResponse claimantResponse; private ClaimState state; private ProceedOfflineReasonType proceedOfflineReason; @@ -226,6 +236,41 @@ public boolean hasClaimantAskedToSignSettlementAgreement() { return hasResponse() && settlement != null && settlement.isAcceptedByClaimant(); } + @Override + public boolean hasClaimantSignedSettlementAgreement() { + return hasClaimantSignedSettlementAgreementOfferAccepted() || hasClaimantSignedSettlementAgreementChosenByCourt(); + } + + private boolean hasClaimantSignedSettlementAgreementOfferAccepted() { + return Objects.nonNull(settlement) && settlement.isOfferAccepted() && isThroughAdmissions(settlement) + && Objects.nonNull(claimantResponse) && !claimantResponse.hasCourtDetermination(); + } + + private boolean hasClaimantSignedSettlementAgreementChosenByCourt() { + return Objects.nonNull(settlement) && settlement.isOfferAccepted() && !settlement.isRejectedByDefendant() && isThroughAdmissions(settlement) + && Objects.nonNull(claimantResponse) && claimantResponse.hasCourtDetermination(); + } + + @Override + public boolean hasClaimantSignedSettlementAgreementAndDeadlineExpired() { + return Objects.nonNull(settlement) && settlement.isOfferAccepted() && isThroughAdmissions(settlement) + && Objects.nonNull(claimantRespondedAt) && claimantRespondedAt.plusDays(7).isBefore(LocalDateTime.now()); + } + + @Override + public boolean hasClaimantAndDefendantSignedSettlementAgreement() { + return Objects.nonNull(settlement) && !settlement.isRejectedByDefendant() && settlement.isSettled() && isThroughAdmissions(settlement); + } + + @Override + public boolean hasDefendantRejectedSettlementAgreement() { + if (!Objects.nonNull(claimantResponse) || !ClaimantResponseType.ACCEPTATION.equals(claimantResponse.getType())) { + return false; + } + return claimantResponse.getFormaliseOption() == FormaliseOption.SETTLEMENT + && Objects.nonNull(settlement) && settlement.isOfferRejected(); + } + @Override @JsonIgnore public boolean hasClaimantAcceptedPartialAdmissionAmount() { @@ -399,4 +444,21 @@ public boolean isPartialAdmissionRejected() { public boolean isClaimantDefaultJudgement() { return false; } + + private boolean isThroughAdmissions(Settlement settlement) { + List partyStatements = new ArrayList<>(settlement.getPartyStatements()); + if (CollectionUtils.isEmpty(partyStatements) || !settlement.hasOffer()) { + return false; + } + + //get the last offer + Collections.reverse(partyStatements); + + return partyStatements.stream() + .filter(PartyStatement::hasOffer) + .findFirst() + .map(PartyStatement::getOffer) + .map(Offer::getPaymentIntention) + .isPresent(); + } } diff --git a/src/main/java/uk/gov/hmcts/reform/cmc/model/FormaliseOption.java b/src/main/java/uk/gov/hmcts/reform/cmc/model/FormaliseOption.java new file mode 100644 index 00000000000..b51f46b3ea6 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/cmc/model/FormaliseOption.java @@ -0,0 +1,16 @@ +package uk.gov.hmcts.reform.cmc.model; + +import lombok.Getter; + +@Getter +public enum FormaliseOption { + CCJ("County Court Judgment"), + SETTLEMENT("Settlement"), + REFER_TO_JUDGE("Refer to Judge"); + + private final String description; + + FormaliseOption(String description) { + this.description = description; + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/cmc/model/Settlement.java b/src/main/java/uk/gov/hmcts/reform/cmc/model/Settlement.java index 6c675737228..4dc2f804195 100644 --- a/src/main/java/uk/gov/hmcts/reform/cmc/model/Settlement.java +++ b/src/main/java/uk/gov/hmcts/reform/cmc/model/Settlement.java @@ -44,6 +44,23 @@ public boolean isAcceptedByDefendant() { && partyStatement.isMadeByDefendant()); } + @JsonIgnore + public boolean isRejectedByDefendant() { + return getPartyStatementStream() + .anyMatch(partyStatement -> partyStatement.isRejected() + && partyStatement.isMadeByDefendant()); + } + + @JsonIgnore + public boolean isOfferAccepted() { + return getPartyStatementStream().anyMatch(PartyStatement::isAccepted); + } + + @JsonIgnore + public boolean isOfferRejected() { + return getPartyStatementStream().anyMatch(PartyStatement::isRejected); + } + @JsonIgnore public boolean isSettled() { Stream partyStatementsStream = getPartyStatementStream(); @@ -63,7 +80,7 @@ public boolean isThroughAdmissions() { .noneMatch(PartyStatement::hasPaymentIntention); } - private boolean hasOffer() { + public boolean hasOffer() { return getPartyStatementStream() .anyMatch(PartyStatement::hasOffer); } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateClaimantLipManualDeterminationCallBackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateClaimantLipManualDeterminationCallBackHandlerTest.java new file mode 100644 index 00000000000..69eafc950af --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateClaimantLipManualDeterminationCallBackHandlerTest.java @@ -0,0 +1,110 @@ +package uk.gov.hmcts.reform.civil.handler.callback.camunda.docmosis; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +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.civil.callback.CallbackParams; +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.sampledata.CaseDataBuilder; +import uk.gov.hmcts.reform.civil.sampledata.PartyBuilder; +import uk.gov.hmcts.reform.civil.service.SystemGeneratedDocumentService; +import uk.gov.hmcts.reform.civil.service.docmosis.manualdetermination.ClaimantLipManualDeterminationFormGenerator; + +import java.time.LocalDateTime; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.never; +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.GENERATE_LIP_CLAIMANT_MANUAL_DETERMINATION; +import static uk.gov.hmcts.reform.civil.documentmanagement.model.DocumentType.LIP_MANUAL_DETERMINATION; + +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = { + GenerateClaimantLipManualDeterminationCallBackHandler.class, + JacksonAutoConfiguration.class +}) +class GenerateClaimantLipManualDeterminationCallBackHandlerTest extends BaseCallbackHandlerTest { + + private static final String BEARER_TOKEN = "BEARER_TOKEN"; + private static final CaseDocument FORM = CaseDocument.builder() + .createdBy("John") + .documentName("document name") + .documentSize(0L) + .documentType(LIP_MANUAL_DETERMINATION) + .createdDatetime(LocalDateTime.now()) + .documentLink(Document.builder() + .documentUrl("fake-url") + .documentFileName("file-name") + .documentBinaryUrl("binary-url") + .build()) + .build(); + @Autowired + private final ObjectMapper mapper = new ObjectMapper(); + @Autowired + private GenerateClaimantLipManualDeterminationCallBackHandler handler; + @MockBean + private ClaimantLipManualDeterminationFormGenerator lipManualDeterminationHandlerFormGenerator; + @MockBean + private SystemGeneratedDocumentService systemGeneratedDocumentService; + + @Test + void shouldGenerateForm_whenAboutToSubmitCalled() { + given(lipManualDeterminationHandlerFormGenerator.generate(any(CaseData.class), anyString())).willReturn(FORM); + + CaseData caseData = CaseDataBuilder.builder() + .respondent1(PartyBuilder.builder() + .soleTrader().build().toBuilder() + .type(Party.Type.COMPANY) + .build()) + .build(); + + handler.handle(callbackParamsOf(caseData, ABOUT_TO_SUBMIT)); + verify(lipManualDeterminationHandlerFormGenerator).generate(caseData, BEARER_TOKEN); + } + + @Test + void shouldNotGenerateForm_whenPartyTypeIsNotCompanyORNotOrganisation() { + given(lipManualDeterminationHandlerFormGenerator.generate(any(CaseData.class), anyString())).willReturn(FORM); + + CaseData caseData = CaseDataBuilder.builder() + .respondent1(PartyBuilder.builder() + .soleTrader().build().toBuilder() + .type(Party.Type.SOLE_TRADER) + .build()) + .build(); + + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + params.getRequest().setEventId(GENERATE_LIP_CLAIMANT_MANUAL_DETERMINATION.name()); + + handler.handle(params); + verify(lipManualDeterminationHandlerFormGenerator, never()).generate(any(CaseData.class), anyString()); + verify(systemGeneratedDocumentService, never()).getSystemGeneratedDocumentsWithAddedDocument(any(CaseDocument.class), any(CaseData.class)); + } + + @Test + void shouldReturnCorrectActivityId_whenRequestedMDForm() { + CaseData caseData = CaseDataBuilder.builder().atStatePendingClaimIssued().build(); + + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + assertThat(handler.camundaActivityId(params)).isEqualTo("Generate_LIP_Claimant_MD"); + } + + @Test + void testHandledEvents() { + assertThat(handler.handledEvents()).contains(GENERATE_LIP_CLAIMANT_MANUAL_DETERMINATION); + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateSettlementAgreementFormCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateSettlementAgreementFormCallbackHandlerTest.java new file mode 100644 index 00000000000..4584aba352e --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateSettlementAgreementFormCallbackHandlerTest.java @@ -0,0 +1,114 @@ +package uk.gov.hmcts.reform.civil.handler.callback.camunda.docmosis; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +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.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.documentmanagement.model.CaseDocument; +import uk.gov.hmcts.reform.civil.documentmanagement.model.Document; +import uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec; +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.sampledata.CaseDataBuilder; +import uk.gov.hmcts.reform.civil.sampledata.PartyBuilder; +import uk.gov.hmcts.reform.civil.service.SystemGeneratedDocumentService; +import uk.gov.hmcts.reform.civil.service.docmosis.settlementagreement.SettlementAgreementFormGenerator; + +import java.time.LocalDateTime; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.never; +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.GENERATE_LIP_SIGN_SETTLEMENT_AGREEMENT_FORM; +import static uk.gov.hmcts.reform.civil.documentmanagement.model.DocumentType.SETTLEMENT_AGREEMENT; + +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = { + GenerateSettlementAgreementFormCallbackHandler.class, + JacksonAutoConfiguration.class, +}) +public class GenerateSettlementAgreementFormCallbackHandlerTest extends BaseCallbackHandlerTest { + + @Autowired + private GenerateSettlementAgreementFormCallbackHandler handler; + @MockBean + private SettlementAgreementFormGenerator formGenerator; + @MockBean + private SystemGeneratedDocumentService systemGeneratedDocumentService; + + private static final String BEARER_TOKEN = "BEARER_TOKEN"; + private static final CaseDocument caseDocument = CaseDocument.builder() + .createdBy("John") + .documentName("document name") + .documentSize(0L) + .documentType(SETTLEMENT_AGREEMENT) + .createdDatetime(LocalDateTime.now()) + .documentLink(Document.builder() + .documentUrl("fake-url") + .documentFileName("file-name") + .documentBinaryUrl("binary-url") + .build()) + .build(); + + @Test + void shouldGenerateForm_whenAboutToSubmitCalled() { + given(formGenerator.generate(any(CaseData.class), anyString())).willReturn(caseDocument); + CaseData caseData = CaseDataBuilder.builder() + .respondent1(PartyBuilder.builder() + .soleTrader().build().toBuilder() + .type(Party.Type.INDIVIDUAL) + .build()) + .build(); + + handler.handle(callbackParamsOf(caseData, ABOUT_TO_SUBMIT)); + verify(formGenerator).generate(caseData, BEARER_TOKEN); + } + + @Test + void shouldNotGenerateForm_whenApplicantNotAcceptedRepaymentPlan() { + given(formGenerator.generate(any(CaseData.class), anyString())).willReturn(caseDocument); + + CaseData caseData = CaseDataBuilder.builder() + .applicant1AcceptFullAdmitPaymentPlanSpec(YesOrNo.YES) + .defenceAdmitPartPaymentTimeRouteRequired(RespondentResponsePartAdmissionPaymentTimeLRspec.IMMEDIATELY) + .respondent1(PartyBuilder.builder() + .soleTrader().build().toBuilder() + .type(Party.Type.ORGANISATION) + .build()) + .build(); + + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + params.getRequest().setEventId(GENERATE_LIP_SIGN_SETTLEMENT_AGREEMENT_FORM.name()); + + handler.handle(params); + verify(formGenerator, never()).generate(any(CaseData.class), anyString()); + verify(systemGeneratedDocumentService, never()).getSystemGeneratedDocumentsWithAddedDocument(any(CaseDocument.class), any(CaseData.class)); + } + + @Test + void shouldReturnCorrectActivityId_whenRequestedSettlementAgreementForm() { + CaseData caseData = CaseDataBuilder.builder().atStatePendingClaimIssued().build(); + + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + assertThat(handler.camundaActivityId(params)).isEqualTo("GenerateSignSettlementAgreement"); + } + + @Test + void testHandledEvents() { + assertThat(handler.handledEvents()).contains(GENERATE_LIP_SIGN_SETTLEMENT_AGREEMENT_FORM); + } + +} + + diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/noticeofchange/UpdateCaseDetailsAfterNoCHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/noticeofchange/UpdateCaseDetailsAfterNoCHandlerTest.java index 45e4813479a..5e4fd43e2bf 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/noticeofchange/UpdateCaseDetailsAfterNoCHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/noticeofchange/UpdateCaseDetailsAfterNoCHandlerTest.java @@ -772,6 +772,31 @@ void shouldUpdateSolicitorDetails_afterNoCSubmittedByRespondentSolicitor2BothRes assertThat(updatedCaseData.getRespondent2LRIndividuals()).isNull(); } + @Test + void shouldUpdateSolicitorDetails_afterNocSubmittedByApplicantSolicitorForClaimantLip() { + CaseData caseData = CaseDataBuilder.builder() + .atStateClaimIssued() + .caseAccessCategory(CaseCategory.SPEC_CLAIM) + .changeOfRepresentation(true, false, NEW_ORG_ID, null, null) + .changeOrganisationRequestField(true, false, null, null, "requester@example.com") + .updateOrgPolicyAfterNoC(true, false, NEW_ORG_ID) + .claimantUserDetails(IdamUserDetails.builder().email("xyz@hmcts.com").id("1234").build()) + .applicant1Represented(NO) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler + .handle(params); + + CaseData updatedCaseData = mapper.convertValue(response.getData(), CaseData.class); + assertThat(updatedCaseData.getApplicantSolicitor1PbaAccounts()).isNull(); + assertThat(updatedCaseData.getApplicantSolicitor1PbaAccountsIsEmpty()).isEqualTo(YES); + assertThat(updatedCaseData.getChangeOrganisationRequestField()).isNull(); + assertThat(updatedCaseData.getApplicantSolicitor1UserDetails().getEmail()) + .isEqualTo("requester@example.com"); + assertThat(updatedCaseData.getApplicant1Represented()).isEqualTo(YES); + } + private void assertSolicitorReferences(boolean isApplicant, boolean isRespondent1, boolean respondent2Exists, CaseData caseData, CaseData updatedCaseData) { if (isApplicant) { diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ApplyNoticeOfChangeDecisionCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ApplyNoticeOfChangeDecisionCallbackHandlerTest.java index 254087e883c..f52d3b76d50 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ApplyNoticeOfChangeDecisionCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ApplyNoticeOfChangeDecisionCallbackHandlerTest.java @@ -21,6 +21,7 @@ import uk.gov.hmcts.reform.civil.callback.CallbackParams; import uk.gov.hmcts.reform.civil.cas.client.CaseAssignmentApi; import uk.gov.hmcts.reform.civil.enums.CaseRole; +import uk.gov.hmcts.reform.civil.enums.YesOrNo; import uk.gov.hmcts.reform.civil.handler.callback.BaseCallbackHandlerTest; import uk.gov.hmcts.reform.civil.service.FeatureToggleService; import uk.gov.hmcts.reform.civil.model.CaseData; @@ -412,6 +413,45 @@ void shouldApplyNoticeOfChange_whenInvokedByRespondent2For1v2DSLiP() { } } + @Test + void shouldApplyNoticeOfChange_whenInvokedByApplicant1ForClaimantLip() { + CaseData caseData = CaseDataBuilder.builder().atStateClaimIssued() + .changeOrganisationRequestField(true, false, "1234", null, REQUESTER_EMAIL) + .applicant1Represented(YesOrNo.NO) + .build(); + CallbackParams params = callbackParamsOf( + caseData, + CaseDetails.builder().data(caseData.toMap(mapper)).build(), + ABOUT_TO_SUBMIT + ); + + CaseDetails caseDetailsAfterNoCApplied = + caseDetailsAfterNoCApplied( + CaseDetails.builder().data(caseData.toMap(mapper)).build(), + APPLICANT_ONE_ORG_POLICY + ); + + when(caseAssignmentApi.applyDecision( + params.getParams().get(BEARER_TOKEN).toString(), + authTokenGenerator.generate(), + DecisionRequest.decisionRequest( + params.getRequest().getCaseDetails()) + )) + .thenReturn( + AboutToStartOrSubmitCallbackResponse.builder() + .data(caseDetailsAfterNoCApplied.getData()).build()); + + AboutToStartOrSubmitCallbackResponse response = + (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + assertChangeOrganisationFieldIsUpdated(response); + assertOrgIDIsUpdated(response, APPLICANT_ONE_ORG_POLICY); + assertThat(response.getData()) + .extracting("businessProcess") + .extracting("status", "camundaEvent") + .contains("READY", "APPLY_NOC_DECISION_LIP"); + } + @Nested class ChangedOrgTest { 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 b58c1b4ddb3..bfa0b30f4bb 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 java.time.LocalDateTime; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -15,6 +16,8 @@ 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.handler.callback.BaseCallbackHandlerTest; import uk.gov.hmcts.reform.civil.helpers.LocationHelper; import uk.gov.hmcts.reform.civil.model.CaseData; @@ -36,6 +39,7 @@ 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.Time; import uk.gov.hmcts.reform.civil.service.citizen.UpdateCaseManagementDetailsService; import uk.gov.hmcts.reform.civil.service.citizenui.ResponseOneVOneShowTagService; @@ -55,6 +59,7 @@ 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.AllocatedTrack.FAST_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.model.Party.Type.COMPANY; @@ -80,6 +85,8 @@ class ClaimantResponseCuiCallbackHandlerTest extends BaseCallbackHandlerTest { private LocationHelper locationHelper; @MockBean private LocationRefDataService locationRefDataService; + @MockBean + private DeadlinesCalculator deadlinesCalculator; @Autowired private ClaimantResponseCuiCallbackHandler handler; private static final String courtLocation = "Site 1 - Adr 1 - AAA 111"; @@ -126,6 +133,7 @@ void before() { .willReturn(getSampleCourLocationsRefObject()); given(time.now()).willReturn(submittedDate); given(locationHelper.updateCaseManagementLocation(any(), any(), any())).willReturn(Optional.ofNullable(locationRefData)); + given(deadlinesCalculator.getRespondToSettlementAgreementDeadline(any())).willReturn(LocalDateTime.MAX); } @Test @@ -253,6 +261,21 @@ void shouldUpdateCaseStateToJudicialReferral_WhenFullDefence_NotPaid_NoMediation } + @Test + void shouldUpdateCaseStateToJudicialReferral_WhenFullDefence_NotPaid_FastTrack() { + + CaseData caseData = + CaseDataBuilder.builder().applicant1PartAdmitIntentionToSettleClaimSpec(NO) + .responseClaimTrack(FAST_CLAIM.name()) + .atStateClaimIssued() + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + assertEquals(CaseState.JUDICIAL_REFERRAL.name(), response.getState()); + + } + @Test void shouldUpdateCaseStateToJudicialReferral_WhenFullDefence() { CaseDataLiP caseDataLiP = CaseDataLiP.builder() @@ -269,6 +292,21 @@ void shouldUpdateCaseStateToJudicialReferral_WhenFullDefence() { assertEquals(CaseState.JUDICIAL_REFERRAL.name(), response.getState()); } + @Test + void shouldUpdateCaseStateToCaseDismissed_WhenFullDefence_FastTrack() { + + CaseData caseData = + CaseDataBuilder.builder().applicant1ProceedWithClaim(NO) + .responseClaimTrack(FAST_CLAIM.name()) + .atStateClaimIssued() + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + assertEquals(CaseState.CASE_DISMISSED.name(), response.getState()); + + } + @Test void shouldOnlyUpdateClaimStatus_whenPartAdmitNotSettled_NoMediation_NoBaseCourt() { Applicant1DQ applicant1DQ = @@ -564,6 +602,8 @@ void shouldChangeCaseState_whenApplicantAcceptRepaymentPlanAndChooseSettlementAg var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); assertThat(response.getState()).isEqualTo(CaseState.All_FINAL_ORDERS_ISSUED.name()); + CaseData data = mapper.convertValue(response.getData(), CaseData.class); + assertThat(data.getRespondent1RespondToSettlementAgreementDeadline()).isEqualTo(LocalDateTime.MAX); } @Test @@ -608,6 +648,41 @@ void shouldUpdateCCJRequestPaymentDetails() { private CaseData getCaseData(AboutToStartOrSubmitCallbackResponse response) { return mapper.convertValue(response.getData(), CaseData.class); } + + @Test + void shouldChangeCaseState_whenApplicantAgreeClaimSettlement() { + CaseData caseData = CaseDataBuilder.builder() + .atStateClaimIssued() + .applicant1PartAdmitIntentionToSettleClaimSpec(YES) + .applicant1PartAdmitConfirmAmountPaidSpec(YES) + .build().toBuilder() + .responseClaimMediationSpecRequired(YES).build(); + + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + assertThat(response.getState()).isEqualTo(CaseState.CASE_SETTLED.name()); + } + + @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(); + + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + assertThat(response.getState()).isEqualTo(CaseState.CASE_SETTLED.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 626a67a7df7..13263a7584e 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 @@ -96,7 +96,7 @@ class AboutToSubmitCallback { @BeforeEach void setup() { - caseData = CaseDataBuilder.builder().atStateClaimDraft().build(); + caseData = CaseDataBuilder.builder().atStateClaimDraft().applicant1OrganisationPolicy(null).build(); params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); given(time.now()).willReturn(submittedDate); given(specReferenceNumberRepository.getSpecReferenceNumber()).willReturn(REFERENCE_NUMBER); @@ -116,5 +116,20 @@ void shouldAddCaseReferenceSubmittedDateAndAllocatedTrack_whenInvoked() { .containsEntry("submittedDate", submittedDate.format(DateTimeFormatter.ISO_DATE_TIME)); } + + @Test + void shouldSetOrganisationPolicies_whenInvoked() { + 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); + + assertThat(response.getData()) + .extracting("respondent1OrganisationPolicy.OrgPolicyCaseAssignedRole") + .isEqualTo("[RESPONDENTSOLICITORONE]"); + assertThat(response.getData()) + .extracting("applicant1OrganisationPolicy.OrgPolicyCaseAssignedRole") + .isEqualTo("[APPLICANTSOLICITORONE]"); + } } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/DefendantSignSettlementAgreementCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/DefendantSignSettlementAgreementCallbackHandlerTest.java index 9b17a6b87d6..a5f6f9a6897 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/DefendantSignSettlementAgreementCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/DefendantSignSettlementAgreementCallbackHandlerTest.java @@ -58,10 +58,10 @@ class AboutToSubmitCallback { @Test void shouldUpdateBusinessProcess() { CaseData caseData = CaseDataBuilder.builder() - .caseDataLip(CaseDataLiP.builder() - .respondentSignSettlementAgreement(YesOrNo.NO) - .build()) - .build(); + .caseDataLip(CaseDataLiP.builder() + .respondentSignSettlementAgreement(YesOrNo.NO) + .build()) + .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimCuiCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimCuiCallbackHandlerTest.java index 9f95795eb66..211ff8116e7 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimCuiCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimCuiCallbackHandlerTest.java @@ -21,6 +21,7 @@ import uk.gov.hmcts.reform.civil.service.DeadlinesCalculator; import uk.gov.hmcts.reform.civil.service.Time; +import java.math.BigDecimal; import java.time.LocalDateTime; import static org.assertj.core.api.Assertions.assertThat; @@ -83,6 +84,7 @@ void setup() { void shouldUpdateBusinessProcessAndClaimStatus_whenDefendantResponseLangIsEnglish() { CaseData caseData = CaseDataBuilder.builder() .atStateClaimIssued() + .totalClaimAmount(BigDecimal.valueOf(5000)) .caseDataLip(CaseDataLiP.builder().respondent1LiPResponse(RespondentLiPResponse.builder().respondent1ResponseLanguage("ENGLISH").build()).build()) .build(); @@ -105,6 +107,7 @@ void shouldUpdateBusinessProcessAndClaimStatus_whenDefendantResponseLangIsEnglis void shouldOnlyUpdateClaimStatus_whenDefendantResponseLangIsBilingual() { CaseData caseData = CaseDataBuilder.builder() .atStateClaimIssued() + .totalClaimAmount(BigDecimal.valueOf(5000)) .caseDataLip(CaseDataLiP.builder().respondent1LiPResponse(RespondentLiPResponse.builder().respondent1ResponseLanguage("BOTH").build()).build()) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/model/CaseDataTest.java b/src/test/java/uk/gov/hmcts/reform/civil/model/CaseDataTest.java index 288a7a35597..8589eae4103 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/model/CaseDataTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/model/CaseDataTest.java @@ -678,6 +678,69 @@ void shouldReturnEmptyArrayListOfManageDocumentsIfNull() { } + @Test + void shouldReturnTrueWhenBilingual() { + + //Given + CaseData caseData = CaseDataBuilder.builder() + .build(); + caseData.setClaimantBilingualLanguagePreference("BOTH"); + + //When + boolean result = caseData.isBilingual(); + + //Then + assertTrue(result); + } + + @Test + void shouldReturnTrueWhenRespondentSignSettlementAgreementIsNotNull() { + + //Given + CaseData caseData = CaseDataBuilder.builder() + .caseDataLip(CaseDataLiP.builder().respondentSignSettlementAgreement(YesOrNo.NO).build()) + .build(); + + //When + boolean isRespondentSignSettlementAgreement = caseData.isRespondentRespondedToSettlementAgreement(); + + //Then + assertTrue(isRespondentSignSettlementAgreement); + } + + @Test + void shouldReturnFalseWhenRespondentSignSettlementAgreementIsNull() { + + //Given + CaseData caseData = CaseDataBuilder.builder() + .caseDataLip(CaseDataLiP.builder().build()) + .build(); + + //When + boolean isRespondentSignSettlementAgreement = caseData.isRespondentRespondedToSettlementAgreement(); + + //Then + assertFalse(isRespondentSignSettlementAgreement); + } + + @Test + void isSignSettlementAgreementDeadlineNotExpired_thenFalse() { + //Given + CaseData caseData = CaseDataBuilder.builder().atStatePriorToRespondToSettlementAgreementDeadline().build(); + //When + //Then + assertThat(caseData.isSettlementAgreementDeadlineExpired()).isFalse(); + } + + @Test + void isSignSettlementAgreementDeadlineExpired_thenTrue() { + //Given + CaseData caseData = CaseDataBuilder.builder().atStatePastRespondToSettlementAgreementDeadline().build(); + //When + //Then + assertThat(caseData.isSettlementAgreementDeadlineExpired()).isTrue(); + } + @Test void shouldReturnClaimFeeInPence_whenClaimFeeExists() { //Given @@ -756,7 +819,7 @@ void shouldReturnTrueWhenRespondentSignSettlementAgreementIsNotNull() { .build(); //When - boolean isRespondentSignSettlementAgreement = caseData.isRespondentSignSettlementAgreement(); + boolean isRespondentSignSettlementAgreement = caseData.isRespondentRespondedToSettlementAgreement(); //Then assertTrue(isRespondentSignSettlementAgreement); @@ -799,22 +862,6 @@ void shouldReturnTrueWhenBothDatesAreNull() { assertTrue(isJudgementDateNotPermitted); } } - - @Test - void shouldReturnFalseWhenRespondentSignSettlementAgreementIsNull() { - - //Given - CaseData caseData = CaseDataBuilder.builder() - .caseDataLip(CaseDataLiP.builder().build()) - .build(); - - //When - boolean isRespondentSignSettlementAgreement = caseData.isRespondentSignSettlementAgreement(); - - //Then - assertFalse(isRespondentSignSettlementAgreement); - - } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/model/docmosis/settlementagreement/SettlementAgreementFormMapperTest.java b/src/test/java/uk/gov/hmcts/reform/civil/model/docmosis/settlementagreement/SettlementAgreementFormMapperTest.java new file mode 100644 index 00000000000..803316f27b7 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/model/docmosis/settlementagreement/SettlementAgreementFormMapperTest.java @@ -0,0 +1,91 @@ +package uk.gov.hmcts.reform.civil.model.docmosis.settlementagreement; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.junit.jupiter.MockitoExtension; +import uk.gov.hmcts.reform.civil.enums.PaymentFrequencyLRspec; +import uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.Party; +import uk.gov.hmcts.reform.civil.model.RepaymentPlanLRspec; +import uk.gov.hmcts.reform.civil.model.citizenui.AdditionalLipPartyDetails; +import uk.gov.hmcts.reform.civil.model.citizenui.CaseDataLiP; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; + +import static org.assertj.core.api.Assertions.assertThat; + +@ExtendWith(MockitoExtension.class) +public class SettlementAgreementFormMapperTest { + + private static final String INDIVIDUAL_TITLE = "Mr."; + private static final String INDIVIDUAL_FIRST_NAME = "FirstName"; + private static final String INDIVIDUAL_LAST_NAME = "LastName"; + private static final String EMAIL = "test@email.com"; + private static final LocalDateTime SUBMITTED_DATE = LocalDateTime.of(2023, 12, 1, 0, 0, 0); + @InjectMocks + private SettlementAgreementFormMapper settlementAgreementFormMapper; + + @Test + void shouldGenerateSettlementAgreementDoc_whenRepaymentTypeSetByDate() { + //Given + CaseData caseData = getCaseData(); + //When + SettlementAgreementForm form = settlementAgreementFormMapper.buildFormData(caseData); + //Then + assertThat(form.getClaimant().name()).isEqualTo(caseData.getApplicant1().getPartyName()); + assertThat(form.getDefendant().name()).isEqualTo(caseData.getRespondent1().getPartyName()); + } + + @Test + void shouldGenerateSettlementAgreementDoc_whenRepaymentTypeInstallments() { + //Given + CaseData caseData = getCaseData().toBuilder() + .defenceAdmitPartPaymentTimeRouteRequired(RespondentResponsePartAdmissionPaymentTimeLRspec.SUGGESTION_OF_REPAYMENT_PLAN) + .respondent1RepaymentPlan(RepaymentPlanLRspec.builder() + .firstRepaymentDate(LocalDate.now().plusDays(5)) + .paymentAmount(BigDecimal.valueOf(200)) + .repaymentFrequency(PaymentFrequencyLRspec.ONCE_ONE_MONTH) + .build()) + .build(); + //When + SettlementAgreementForm form = settlementAgreementFormMapper.buildFormData(caseData); + //Then + assertThat(form.getClaimant().name()).isEqualTo(caseData.getApplicant1().getPartyName()); + assertThat(form.getDefendant().name()).isEqualTo(caseData.getRespondent1().getPartyName()); + } + + private static CaseData getCaseData() { + CaseData caseData = CaseData.builder() + .applicant1(Party.builder() + .individualLastName(INDIVIDUAL_LAST_NAME) + .individualFirstName(INDIVIDUAL_FIRST_NAME) + .individualTitle(INDIVIDUAL_TITLE) + .partyEmail(EMAIL) + .type(Party.Type.INDIVIDUAL) + .build()) + .respondent1(Party.builder() + .individualLastName(INDIVIDUAL_LAST_NAME) + .individualFirstName(INDIVIDUAL_FIRST_NAME) + .individualTitle(INDIVIDUAL_TITLE) + .partyEmail(EMAIL) + .type(Party.Type.INDIVIDUAL) + .build()) + .totalClaimAmount(new BigDecimal(150000)) + .defenceAdmitPartPaymentTimeRouteRequired(RespondentResponsePartAdmissionPaymentTimeLRspec.BY_SET_DATE) + .submittedDate(SUBMITTED_DATE) + .caseDataLiP(CaseDataLiP.builder() + .applicant1AdditionalLipPartyDetails(AdditionalLipPartyDetails + .builder() + .build()) + .respondent1AdditionalLipPartyDetails(AdditionalLipPartyDetails + .builder() + .build()) + .build()) + .build(); + return caseData; + } +} 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 09ca1f58eee..3f969a98228 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 @@ -25,6 +25,7 @@ import uk.gov.hmcts.reform.civil.enums.ResponseIntention; import uk.gov.hmcts.reform.civil.enums.TimelineUploadTypeSpec; import uk.gov.hmcts.reform.civil.enums.YesOrNo; +import uk.gov.hmcts.reform.civil.enums.PaymentType; import uk.gov.hmcts.reform.civil.enums.dj.DisposalHearingBundleType; import uk.gov.hmcts.reform.civil.enums.dj.DisposalHearingFinalDisposalHearingTimeEstimate; import uk.gov.hmcts.reform.civil.enums.dj.DisposalHearingMethodDJ; @@ -154,6 +155,9 @@ import uk.gov.hmcts.reform.civil.model.transferonlinecase.TocTransferCaseReason; import uk.gov.hmcts.reform.civil.referencedata.model.LocationRefData; import uk.gov.hmcts.reform.civil.service.flowstate.FlowState; +import uk.gov.hmcts.reform.civil.enums.PaymentType; +import uk.gov.hmcts.reform.civil.model.PaymentBySetDate; +import uk.gov.hmcts.reform.civil.enums.PaymentFrequencyClaimantResponseLRspec; import java.math.BigDecimal; import java.time.LocalDate; @@ -289,6 +293,11 @@ public class CaseDataBuilder { protected ResponseDocument applicant1DefenceResponseDocument; protected ResponseDocument applicant2DefenceResponseDocument; protected BusinessProcess businessProcess; + protected PaymentType applicant1RepaymentOptionForDefendantSpec; + protected PaymentBySetDate applicant1RequestedPaymentDateForDefendantSpec; + protected BigDecimal applicant1SuggestInstalmentsPaymentAmountForDefendantSpec; + protected PaymentFrequencyClaimantResponseLRspec applicant1SuggestInstalmentsRepaymentFrequencyForDefendantSpec; + protected LocalDate applicant1SuggestInstalmentsFirstRepaymentDateForDefendantSpec; //Case proceeds in caseman protected ClaimProceedsInCaseman claimProceedsInCaseman; @@ -519,6 +528,7 @@ public class CaseDataBuilder { private YesOrNo isFlightDelayClaim; private FlightDelayDetails flightDelayDetails; + private LocalDateTime respondent1RespondToSettlementAgreementDeadline; private ReasonForReconsideration reasonForReconsideration; private UploadMediationDocumentsForm uploadDocumentsForm; @@ -1599,6 +1609,11 @@ public CaseDataBuilder addApplicant2() { return this; } + public CaseDataBuilder applicant1RepaymentOptionForDefendantSpec(PaymentType applicant1RepaymentOptionForDefendantSpec) { + this.applicant1RepaymentOptionForDefendantSpec = applicant1RepaymentOptionForDefendantSpec; + return this; + } + public CaseDataBuilder respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec respondentResponseTypeSpec) { this.respondent1ClaimResponseTypeForSpec = respondentResponseTypeSpec; return this; @@ -6311,6 +6326,16 @@ public CaseDataBuilder atTrialHearingWitnessOfFactWithNegativeInputs() { return this; } + public CaseDataBuilder atStatePriorToRespondToSettlementAgreementDeadline() { + this.respondent1RespondToSettlementAgreementDeadline = LocalDateTime.now().plusDays(1); + return this; + } + + public CaseDataBuilder atStatePastRespondToSettlementAgreementDeadline() { + this.respondent1RespondToSettlementAgreementDeadline = LocalDateTime.now().minusDays(1); + return this; + } + public CaseDataBuilder addApplicantLRIndividual(String firstName, String lastName) { List> individual = wrapElements(PartyFlagStructure.builder() @@ -6430,6 +6455,26 @@ public CaseDataBuilder addRespondent2OrgIndividual(String firstName, String last return this; } + public CaseDataBuilder applicant1RequestedPaymentDateForDefendantSpec(PaymentBySetDate repaymentBySetDate) { + this.applicant1RequestedPaymentDateForDefendantSpec = repaymentBySetDate; + return this; + } + + public CaseDataBuilder applicant1SuggestInstalmentsPaymentAmountForDefendantSpec(BigDecimal suggestedInstallmentPayment) { + this.applicant1SuggestInstalmentsPaymentAmountForDefendantSpec = suggestedInstallmentPayment; + return this; + } + + public CaseDataBuilder applicant1SuggestInstalmentsRepaymentFrequencyForDefendantSpec(PaymentFrequencyClaimantResponseLRspec repaymentFrequency) { + this.applicant1SuggestInstalmentsRepaymentFrequencyForDefendantSpec = repaymentFrequency; + return this; + } + + public CaseDataBuilder applicant1SuggestInstalmentsFirstRepaymentDateForDefendantSpec(LocalDate firstRepaymentDate) { + this.applicant1SuggestInstalmentsFirstRepaymentDateForDefendantSpec = firstRepaymentDate; + return this; + } + public CaseDataBuilder uploadMediationDocumentsChooseOptions(String partyChosen, List documentTypes) { List> mediationNonAttendanceStatement; List> documentsReferred; @@ -6551,7 +6596,11 @@ public CaseData build() { .applicant1DefenceResponseDocument(applicant1DefenceResponseDocument) .claimantDefenceResDocToDefendant2(applicant2DefenceResponseDocument) .defendantDetails(defendantDetails) - + .applicant1RepaymentOptionForDefendantSpec(applicant1RepaymentOptionForDefendantSpec) + .applicant1RequestedPaymentDateForDefendantSpec(applicant1RequestedPaymentDateForDefendantSpec) + .applicant1SuggestInstalmentsPaymentAmountForDefendantSpec(applicant1SuggestInstalmentsPaymentAmountForDefendantSpec) + .applicant1SuggestInstalmentsRepaymentFrequencyForDefendantSpec(applicant1SuggestInstalmentsRepaymentFrequencyForDefendantSpec) + .applicant1SuggestInstalmentsFirstRepaymentDateForDefendantSpec(applicant1SuggestInstalmentsFirstRepaymentDateForDefendantSpec) //Case procceds in Caseman .claimProceedsInCaseman(claimProceedsInCaseman) .claimProceedsInCasemanLR(claimProceedsInCasemanLR) @@ -6764,6 +6813,7 @@ public CaseData build() { .drawDirectionsOrderRequired(drawDirectionsOrderRequired) .transferCourtLocationList(transferCourtLocationList) .reasonForTransfer(reasonForTransfer) + .respondent1RespondToSettlementAgreementDeadline(respondent1RespondToSettlementAgreementDeadline) .applicant1LRIndividuals(applicant1LRIndividuals) .respondent1LRIndividuals(respondent1LRIndividuals) .respondent2LRIndividuals(respondent2LRIndividuals) diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/DeadlinesCalculatorTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/DeadlinesCalculatorTest.java index 1c5337e6c39..751634108e9 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/DeadlinesCalculatorTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/DeadlinesCalculatorTest.java @@ -531,6 +531,18 @@ void shouldReturnDeadlinePlus7days_whenResponseDateIsMondayAfter4pm() { .isTheSame(expectedPaymentDate); } + @Test + void shouldReturnPlus7workingDaysAt4pm_whenResponseDateIsProvided() { + //Given + LocalDateTime providedDate = LocalDate.of(2023, 11, 13).atTime(23, 59); + LocalDateTime expectedDeadline = LocalDate.of(2023, 11, 22).atTime(16, 00); + //When + LocalDateTime deadline = calculator.getRespondToSettlementAgreementDeadline(providedDate); + //Then + assertThat(deadline) + .isTheSame(expectedDeadline); + } + } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/manualdetermination/ClaimantLipManualDeterminationFormGeneratorTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/manualdetermination/ClaimantLipManualDeterminationFormGeneratorTest.java new file mode 100644 index 00000000000..488fb7b97ab --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/manualdetermination/ClaimantLipManualDeterminationFormGeneratorTest.java @@ -0,0 +1,119 @@ +package uk.gov.hmcts.reform.civil.service.docmosis.manualdetermination; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +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.PDF; +import uk.gov.hmcts.reform.civil.enums.PaymentFrequencyClaimantResponseLRspec; +import uk.gov.hmcts.reform.civil.enums.PaymentType; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.PaymentBySetDate; +import uk.gov.hmcts.reform.civil.model.common.MappableObject; +import uk.gov.hmcts.reform.civil.model.docmosis.DocmosisDocument; +import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; +import uk.gov.hmcts.reform.civil.sampledata.CaseDocumentBuilder; +import uk.gov.hmcts.reform.civil.service.docmosis.DocumentGeneratorService; + +import java.math.BigDecimal; +import java.time.LocalDate; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static uk.gov.hmcts.reform.civil.documentmanagement.model.DocumentType.LIP_MANUAL_DETERMINATION; +import static uk.gov.hmcts.reform.civil.service.docmosis.DocmosisTemplates.CLAIMANT_LIP_MANUAL_DETERMINATION_PDF; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = { + ClaimantLipManualDeterminationFormGenerator.class, + JacksonAutoConfiguration.class +}) +class ClaimantLipManualDeterminationFormGeneratorTest { + + private static final String BEARER_TOKEN = "Bearer Token"; + private static final byte[] bytes = {1, 2, 3, 4, 5, 6}; + private static final String REFERENCE_NUMBER = "000MC014"; + private static final String fileName_application = String.format( + CLAIMANT_LIP_MANUAL_DETERMINATION_PDF.getDocumentTitle(), REFERENCE_NUMBER); + private static final CaseDocument CASE_DOCUMENT = CaseDocumentBuilder.builder() + .documentName(fileName_application) + .documentType(LIP_MANUAL_DETERMINATION) + .build(); + @MockBean + private DocumentGeneratorService documentGeneratorService; + @MockBean + private DocumentManagementService documentManagementService; + @Autowired + private ClaimantLipManualDeterminationFormGenerator generator; + + @BeforeEach + void setup() { + when(documentGeneratorService.generateDocmosisDocument(any(MappableObject.class), eq(CLAIMANT_LIP_MANUAL_DETERMINATION_PDF))) + .thenReturn(new DocmosisDocument(CLAIMANT_LIP_MANUAL_DETERMINATION_PDF.getDocumentTitle(), bytes)); + when(documentManagementService + .uploadDocument(BEARER_TOKEN, new PDF(fileName_application, bytes, LIP_MANUAL_DETERMINATION))) + .thenReturn(CASE_DOCUMENT); + } + + @Test + void shouldGenerateClaimantManualDeterminationDoc_whenValidDataIsProvided() { + CaseData caseData = CaseDataBuilder.builder() + .legacyCaseReference(REFERENCE_NUMBER) + .issueDate(LocalDate.now()) + .applicant1RepaymentOptionForDefendantSpec(PaymentType.IMMEDIATELY) + .build(); + + CaseDocument caseDocument = generator.generate(caseData, BEARER_TOKEN); + + assertThat(caseDocument).isNotNull(); + + verify(documentManagementService) + .uploadDocument(BEARER_TOKEN, new PDF(fileName_application, bytes, LIP_MANUAL_DETERMINATION)); + } + + @Test + void shouldGenerateClaimantManualDeterminationDoc_whenPayBySetDate() { + CaseData caseData = CaseDataBuilder.builder() + .legacyCaseReference(REFERENCE_NUMBER) + .issueDate(LocalDate.now()) + .applicant1RepaymentOptionForDefendantSpec(PaymentType.SET_DATE) + .applicant1RequestedPaymentDateForDefendantSpec(PaymentBySetDate.builder().paymentSetDate(LocalDate.now()).build()) + .build(); + + CaseDocument caseDocument = generator.generate(caseData, BEARER_TOKEN); + + assertThat(caseDocument).isNotNull(); + + verify(documentManagementService) + .uploadDocument(BEARER_TOKEN, new PDF(fileName_application, bytes, LIP_MANUAL_DETERMINATION)); + } + + @Test + void shouldGenerateClaimantManualDeterminationDoc_whenPayByInstallment() { + CaseData caseData = CaseDataBuilder.builder() + .legacyCaseReference(REFERENCE_NUMBER) + .issueDate(LocalDate.now()) + .applicant1RepaymentOptionForDefendantSpec(PaymentType.REPAYMENT_PLAN) + .applicant1SuggestInstalmentsPaymentAmountForDefendantSpec(BigDecimal.valueOf(100)) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .applicant1SuggestInstalmentsRepaymentFrequencyForDefendantSpec(PaymentFrequencyClaimantResponseLRspec.ONCE_ONE_MONTH) + .applicant1SuggestInstalmentsFirstRepaymentDateForDefendantSpec(LocalDate.now()) + .build(); + + CaseDocument caseDocument = generator.generate(caseData, BEARER_TOKEN); + + assertThat(caseDocument).isNotNull(); + + verify(documentManagementService) + .uploadDocument(BEARER_TOKEN, new PDF(fileName_application, bytes, LIP_MANUAL_DETERMINATION)); + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/settlementagreement/SettlementAgreementFormGeneratorTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/settlementagreement/SettlementAgreementFormGeneratorTest.java new file mode 100644 index 00000000000..ac4e3be728b --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/settlementagreement/SettlementAgreementFormGeneratorTest.java @@ -0,0 +1,79 @@ +package uk.gov.hmcts.reform.civil.service.docmosis.settlementagreement; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +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.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.settlementagreement.SettlementAgreementForm; +import uk.gov.hmcts.reform.civil.model.docmosis.settlementagreement.SettlementAgreementFormMapper; +import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; +import uk.gov.hmcts.reform.civil.sampledata.CaseDocumentBuilder; +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.Mockito.verify; +import static org.mockito.Mockito.when; +import static uk.gov.hmcts.reform.civil.documentmanagement.model.DocumentType.SETTLEMENT_AGREEMENT; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec.BY_SET_DATE; +import static uk.gov.hmcts.reform.civil.service.docmosis.DocmosisTemplates.SETTLEMENT_AGREEMENT_PDF; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = { + SettlementAgreementFormGenerator.class, + JacksonAutoConfiguration.class +}) +public class SettlementAgreementFormGeneratorTest { + + private static final String BEARER_TOKEN = "Bearer Token"; + private static final byte[] bytes = {1, 2, 3, 4, 5, 6}; + private static final String REFERENCE_NUMBER = "000MC014"; + @MockBean + private DocumentGeneratorService documentGeneratorService; + @MockBean + private DocumentManagementService documentManagementService; + @MockBean + private SettlementAgreementFormMapper settlementAgreementFormMapper; + @Autowired + private SettlementAgreementFormGenerator generator; + + @Test + void shouldGenerateSettlementAgreementDoc_whenValidDataIsProvided() { + String fileName = String.format( + SETTLEMENT_AGREEMENT_PDF.getDocumentTitle(), REFERENCE_NUMBER); + + CaseDocument caseDocument = CaseDocumentBuilder.builder() + .documentName(fileName) + .documentType(SETTLEMENT_AGREEMENT) + .build(); + + when(documentGeneratorService.generateDocmosisDocument(any(SettlementAgreementForm.class), eq(SETTLEMENT_AGREEMENT_PDF))) + .thenReturn(new DocmosisDocument(SETTLEMENT_AGREEMENT_PDF.getDocumentTitle(), bytes)); + + when(documentManagementService + .uploadDocument(BEARER_TOKEN, new PDF(fileName, bytes, SETTLEMENT_AGREEMENT))) + .thenReturn(caseDocument); + + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged() + .legacyCaseReference(REFERENCE_NUMBER) + .defenceAdmitPartPaymentTimeRouteRequired(BY_SET_DATE) + .build(); + + when(settlementAgreementFormMapper.buildFormData(caseData)).thenReturn(SettlementAgreementForm.builder().build()); + + CaseDocument actual = generator.generate(caseData, BEARER_TOKEN); + + verify(documentManagementService) + .uploadDocument(BEARER_TOKEN, new PDF(fileName, bytes, SETTLEMENT_AGREEMENT)); + assertThat(actual).isEqualTo(caseDocument); + } +} 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 new file mode 100644 index 00000000000..a5091c1f542 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/utils/ClaimantResponseUtilsTest.java @@ -0,0 +1,59 @@ +package uk.gov.hmcts.reform.civil.service.docmosis.utils; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.provider.CsvSource; +import uk.gov.hmcts.reform.civil.enums.PaymentFrequencyClaimantResponseLRspec; +import uk.gov.hmcts.reform.civil.enums.PaymentType; +import uk.gov.hmcts.reform.civil.model.CaseData; +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.service.docmosis.utils.ClaimantResponseUtils.getClaimantFinalRepaymentDate; +import static uk.gov.hmcts.reform.civil.service.docmosis.utils.ClaimantResponseUtils.getClaimantRepaymentType; + +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(); + + LocalDate finalDate = getClaimantFinalRepaymentDate(caseData); + assertThat(finalDate).isNotNull(); + } + + @ParameterizedTest + @CsvSource({"IMMEDIATELY,Immediately", "SET_DATE,By a set date", "REPAYMENT_PLAN,By installments"}) + void shouldReturnClaimantRepaymentOption(PaymentType input, String expectedOutput) { + CaseData caseData = CaseData.builder() + .applicant1RepaymentOptionForDefendantSpec(input) + .build(); + + String actualOutput = getClaimantRepaymentType(caseData); + Assertions.assertEquals(expectedOutput, actualOutput); + } + + @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(); + + LocalDate finalDate = getClaimantFinalRepaymentDate(caseData); + assertThat(finalDate).isNull(); + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/cmc/model/CmcClaimTest.java b/src/test/java/uk/gov/hmcts/reform/cmc/model/CmcClaimTest.java index 1aed91528bc..0bd44b12a98 100644 --- a/src/test/java/uk/gov/hmcts/reform/cmc/model/CmcClaimTest.java +++ b/src/test/java/uk/gov/hmcts/reform/cmc/model/CmcClaimTest.java @@ -1,11 +1,12 @@ package uk.gov.hmcts.reform.cmc.model; +import java.time.LocalDateTime; import org.assertj.core.api.AssertionsForClassTypes; import org.elasticsearch.core.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; -import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.mockito.junit.jupiter.MockitoExtension; import uk.gov.hmcts.reform.civil.enums.RespondentResponseType; import uk.gov.hmcts.reform.civil.model.citizenui.DashboardClaimStatus; import uk.gov.hmcts.reform.civil.model.citizenui.DashboardClaimStatusFactory; @@ -17,7 +18,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertTrue; -@ExtendWith(SpringExtension.class) +@ExtendWith(MockitoExtension.class) public class CmcClaimTest { private static final String NAME = "Mr John Clark"; @@ -143,4 +144,145 @@ void given_claimantNotRespondedWithInDeadLine_whenGetStatus_claimEnded() { AssertionsForClassTypes.assertThat(status).isEqualTo(DashboardClaimStatus.CLAIM_ENDED); } + @Test + void shouldReturnTrueIfOfferAcceptedAndClaimantSignedSettlementAgreement() { + //Given + CmcClaim claim = CmcClaim.builder() + .response(Response.builder() + .responseType(RespondentResponseType.FULL_ADMISSION) + .build()) + .settlement(Settlement.builder() + .partyStatements(List.of( + PartyStatement.builder() + .type(StatementType.OFFER) + .offer(Offer.builder() + .paymentIntention(PaymentIntention.builder().build()) + .build()) + .build(), + PartyStatement.builder() + .type(StatementType.ACCEPTATION) + .build())) + .build()) + .claimantResponse(ClaimantResponse.builder().build()) + .build(); + //When + boolean signed = claim.hasClaimantSignedSettlementAgreement(); + //Then + assertThat(signed).isTrue(); + } + + @Test + void shouldReturnTrueIfClaimantSignedSettlementAgreementChosenByCourt() { + //Given + CmcClaim claim = CmcClaim.builder() + .response(Response.builder() + .responseType(RespondentResponseType.FULL_ADMISSION) + .build()) + .settlement(Settlement.builder() + .partyStatements(List.of( + PartyStatement.builder() + .type(StatementType.OFFER) + .offer(Offer.builder() + .paymentIntention(PaymentIntention.builder().build()) + .build()) + .build(), + PartyStatement.builder() + .type(StatementType.ACCEPTATION) + .build())) + .build()) + .claimantResponse(ClaimantResponse.builder() + .courtDetermination(CourtDetermination.builder().build()) + .build()) + .build(); + //When + boolean signed = claim.hasClaimantSignedSettlementAgreement(); + //Then + assertThat(signed).isTrue(); + } + + @Test + void shouldReturnTrueIfSettlementAgreementDeadlineExpired() { + //Given + CmcClaim claim = CmcClaim.builder() + .response(Response.builder() + .responseType(RespondentResponseType.FULL_ADMISSION) + .build()) + .settlement(Settlement.builder() + .partyStatements(List.of( + PartyStatement.builder() + .type(StatementType.OFFER) + .offer(Offer.builder() + .paymentIntention(PaymentIntention.builder().build()) + .build()) + .build(), + PartyStatement.builder() + .type(StatementType.ACCEPTATION) + .build())) + .build()) + .claimantRespondedAt(LocalDateTime.MIN) + .build(); + //When + boolean signed = claim.hasClaimantSignedSettlementAgreementAndDeadlineExpired(); + //Then + assertThat(signed).isTrue(); + } + + @Test + void shouldReturnTrueIfBothSignedSettlementAgreement() { + //Given + CmcClaim claim = CmcClaim.builder() + .response(Response.builder() + .responseType(RespondentResponseType.FULL_ADMISSION) + .build()) + .settlement(Settlement.builder() + .partyStatements(List.of( + PartyStatement.builder() + .type(StatementType.OFFER) + .offer(Offer.builder() + .paymentIntention(PaymentIntention.builder().build()) + .build()) + .build(), + PartyStatement.builder() + .type(StatementType.ACCEPTATION) + .build(), + PartyStatement.builder() + .type(StatementType.COUNTERSIGNATURE) + .build())) + .build()) + .build(); + //When + boolean signed = claim.hasClaimantAndDefendantSignedSettlementAgreement(); + //Then + assertThat(signed).isTrue(); + } + + @Test + void shouldReturnTrueIfDefendantRejectedSettlementAgreement() { + //Given + CmcClaim claim = CmcClaim.builder() + .response(Response.builder() + .responseType(RespondentResponseType.FULL_ADMISSION) + .build()) + .settlement(Settlement.builder() + .partyStatements(List.of( + PartyStatement.builder() + .type(StatementType.OFFER) + .offer(Offer.builder() + .paymentIntention(PaymentIntention.builder().build()) + .build()) + .build(), + PartyStatement.builder() + .type(StatementType.REJECTION) + .build())) + .build()) + .claimantResponse(ClaimantResponse.builder() + .type(ClaimantResponseType.ACCEPTATION) + .formaliseOption(FormaliseOption.SETTLEMENT) + .build()) + .build(); + //When + boolean signed = claim.hasDefendantRejectedSettlementAgreement(); + //Then + assertThat(signed).isTrue(); + } }