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 7b0a5787a9c..0e87454b33f 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); @@ -98,6 +102,11 @@ private CallbackResponse aboutToSubmit(CallbackParams callbackParams) { return response.build(); } + private LocalDateTime getRespondToSettlementAgreementDeadline(CaseData caseData, LocalDateTime responseDate) { + return caseData.hasApplicant1SignedSettlementAgreement() + ? deadlinesCalculator.getRespondToSettlementAgreementDeadline(responseDate) : null; + } + private boolean isProceedsInHeritageSystemAllowed(CaseData caseData) { ClaimantLiPResponse applicant1Response = Optional.ofNullable(caseData.getCaseDataLiP()) .map(CaseDataLiP::getApplicant1LiPResponse) 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 5d6320049d1..7f6461af11f 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 @@ -464,6 +464,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; @@ -1137,6 +1138,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()) @@ -1166,8 +1177,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/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/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/flowstate/FlowLipPredicate.java b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowLipPredicate.java index f1d9c2bcd31..dcb4f480d99 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 @@ -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/user/ClaimantResponseCuiCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandlerTest.java index 1f69df2ee88..0613c780c48 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; @@ -36,6 +37,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; @@ -81,6 +83,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"; @@ -127,6 +131,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 @@ -595,6 +600,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 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/model/CaseDataTest.java b/src/test/java/uk/gov/hmcts/reform/civil/model/CaseDataTest.java index 288a7a35597..e91db239a01 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 @@ -679,6 +679,53 @@ void shouldReturnEmptyArrayListOfManageDocumentsIfNull() { } @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(); + } + void shouldReturnClaimFeeInPence_whenClaimFeeExists() { //Given CaseData caseData = CaseData.builder() @@ -756,7 +803,7 @@ void shouldReturnTrueWhenRespondentSignSettlementAgreementIsNotNull() { .build(); //When - boolean isRespondentSignSettlementAgreement = caseData.isRespondentSignSettlementAgreement(); + boolean isRespondentSignSettlementAgreement = caseData.isRespondentRespondedToSettlementAgreement(); //Then assertTrue(isRespondentSignSettlementAgreement); @@ -799,22 +846,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/sampledata/CaseDataBuilder.java b/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilder.java index 09ca1f58eee..136bc1c95cf 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 @@ -519,6 +519,7 @@ public class CaseDataBuilder { private YesOrNo isFlightDelayClaim; private FlightDelayDetails flightDelayDetails; + private LocalDateTime respondent1RespondToSettlementAgreementDeadline; private ReasonForReconsideration reasonForReconsideration; private UploadMediationDocumentsForm uploadDocumentsForm; @@ -6311,6 +6312,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() @@ -6764,6 +6775,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/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(); + } }