From 9a5adb990c511e559bec7ded86a3ea7ace6cedbf Mon Sep 17 00:00:00 2001 From: AbuSalam22 <136581242+AbuSalam22@users.noreply.github.com> Date: Thu, 31 Oct 2024 16:49:36 +0000 Subject: [PATCH] DTSCCI-685 --- .../RespondToClaimSpecCallbackHandler.java | 1231 +--------------- .../DetermineLoggedInSolicitor.java | 108 ++ .../HandleAdmitPartOfClaim.java | 404 ++++++ .../HandleDefendAllClaim.java | 563 ++++++++ .../HandleRespondentResponseTypeForSpec.java | 41 + .../PopulateRespondent1Copy.java | 162 +++ .../RespondToClaimSpecUtils.java | 77 + .../SetApplicantResponseDeadline.java | 588 ++++++++ .../SetGenericResponseTypeFlag.java | 487 +++++++ .../SetUploadTimelineTypeFlag.java | 85 ++ .../ValidateDateOfBirth.java | 107 ++ .../ValidateLengthOfUnemployment.java | 42 + .../ValidateMediationUnavailableDates.java | 45 + .../ValidateRespondentExperts.java | 84 ++ .../ValidateRespondentPaymentDate.java | 45 + .../ValidateRespondentWitnesses.java | 105 ++ .../ValidateUnavailableDates.java | 53 + ...RespondToClaimSpecCallbackHandlerTest.java | 34 +- .../DetermineLoggedInSolicitorTest.java | 153 ++ .../HandleAdmitPartOfClaimTest.java | 1247 +++++++++++++++++ .../HandleDefendAllClaimTest.java | 648 +++++++++ ...ndleRespondentResponseTypeForSpecTest.java | 87 ++ .../PopulateRespondent1CopyTest.java | 248 ++++ .../SetApplicantResponseDeadlineTest.java | 1013 +++++++++++++ .../SetGenericResponseTypeFlagTest.java | 709 ++++++++++ .../SetUploadTimelineTypeFlagTest.java | 171 +++ .../ValidateDateOfBirthTest.java | 282 ++++ .../ValidateLengthOfUnemploymentTest.java | 117 ++ ...ValidateMediationUnavailableDatesTest.java | 113 ++ .../ValidateRespondentExpertsTest.java | 292 ++++ .../ValidateRespondentPaymentDateTest.java | 61 + .../ValidateRespondentWitnessesTest.java | 328 +++++ .../ValidateUnavailableDatesTest.java | 99 ++ 33 files changed, 8649 insertions(+), 1180 deletions(-) create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/DetermineLoggedInSolicitor.java create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/HandleAdmitPartOfClaim.java create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/HandleDefendAllClaim.java create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/HandleRespondentResponseTypeForSpec.java create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/PopulateRespondent1Copy.java create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/RespondToClaimSpecUtils.java create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/SetApplicantResponseDeadline.java create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/SetGenericResponseTypeFlag.java create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/SetUploadTimelineTypeFlag.java create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateDateOfBirth.java create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateLengthOfUnemployment.java create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateMediationUnavailableDates.java create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateRespondentExperts.java create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateRespondentPaymentDate.java create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateRespondentWitnesses.java create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateUnavailableDates.java create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/DetermineLoggedInSolicitorTest.java create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/HandleAdmitPartOfClaimTest.java create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/HandleDefendAllClaimTest.java create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/HandleRespondentResponseTypeForSpecTest.java create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/PopulateRespondent1CopyTest.java create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/SetApplicantResponseDeadlineTest.java create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/SetGenericResponseTypeFlagTest.java create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/SetUploadTimelineTypeFlagTest.java create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateDateOfBirthTest.java create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateLengthOfUnemploymentTest.java create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateMediationUnavailableDatesTest.java create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateRespondentExpertsTest.java create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateRespondentPaymentDateTest.java create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateRespondentWitnessesTest.java create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateUnavailableDatesTest.java diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandler.java index 52f52a8cd64..1741725db21 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandler.java @@ -14,28 +14,35 @@ import uk.gov.hmcts.reform.civil.constants.SpecJourneyConstantLRSpec; import uk.gov.hmcts.reform.civil.documentmanagement.model.CaseDocument; import uk.gov.hmcts.reform.civil.documentmanagement.model.DocumentType; -import uk.gov.hmcts.reform.civil.enums.AllocatedTrack; import uk.gov.hmcts.reform.civil.enums.CaseRole; import uk.gov.hmcts.reform.civil.enums.CaseState; import uk.gov.hmcts.reform.civil.enums.DocCategory; -import uk.gov.hmcts.reform.civil.enums.MultiPartyResponseTypeFlags; -import uk.gov.hmcts.reform.civil.enums.MultiPartyScenario; import uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec; import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec; -import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpecPaidStatus; -import uk.gov.hmcts.reform.civil.enums.TimelineUploadTypeSpec; import uk.gov.hmcts.reform.civil.enums.YesOrNo; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.DetermineLoggedInSolicitor; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.HandleAdmitPartOfClaim; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.HandleDefendAllClaim; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.HandleRespondentResponseTypeForSpec; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.PopulateRespondent1Copy; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.SetGenericResponseTypeFlag; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.SetUploadTimelineTypeFlag; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.ValidateDateOfBirth; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.ValidateLengthOfUnemployment; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.ValidateMediationUnavailableDates; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.ValidateRespondentExperts; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.ValidateRespondentPaymentDate; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.ValidateRespondentWitnesses; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.ValidateUnavailableDates; import uk.gov.hmcts.reform.civil.handler.callback.user.spec.CaseDataToTextGenerator; import uk.gov.hmcts.reform.civil.handler.callback.user.spec.RespondToClaimConfirmationHeaderSpecGenerator; import uk.gov.hmcts.reform.civil.handler.callback.user.spec.RespondToClaimConfirmationTextSpecGenerator; -import uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag; import uk.gov.hmcts.reform.civil.helpers.LocationHelper; import uk.gov.hmcts.reform.civil.model.Address; import uk.gov.hmcts.reform.civil.model.BusinessProcess; 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.RespondToClaim; import uk.gov.hmcts.reform.civil.model.RespondToClaimAdmitPartLRspec; import uk.gov.hmcts.reform.civil.model.ResponseDocument; import uk.gov.hmcts.reform.civil.model.StatementOfTruth; @@ -43,11 +50,9 @@ import uk.gov.hmcts.reform.civil.model.common.Element; import uk.gov.hmcts.reform.civil.model.dq.Expert; import uk.gov.hmcts.reform.civil.model.dq.Experts; -import uk.gov.hmcts.reform.civil.model.dq.Hearing; import uk.gov.hmcts.reform.civil.model.dq.RequestedCourt; import uk.gov.hmcts.reform.civil.model.dq.Respondent1DQ; import uk.gov.hmcts.reform.civil.model.dq.Respondent2DQ; -import uk.gov.hmcts.reform.civil.model.dq.SmallClaimHearing; import uk.gov.hmcts.reform.civil.model.dq.Witnesses; import uk.gov.hmcts.reform.civil.referencedata.model.LocationRefData; import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; @@ -64,10 +69,7 @@ import uk.gov.hmcts.reform.civil.utils.DQResponseDocumentUtils; import uk.gov.hmcts.reform.civil.utils.ElementUtils; import uk.gov.hmcts.reform.civil.utils.FrcDocumentsUtils; -import uk.gov.hmcts.reform.civil.utils.MonetaryConversions; import uk.gov.hmcts.reform.civil.utils.UnavailabilityDatesUtils; -import uk.gov.hmcts.reform.civil.validation.DateOfBirthValidator; -import uk.gov.hmcts.reform.civil.validation.PaymentDateValidator; import uk.gov.hmcts.reform.civil.validation.PostcodeValidator; import uk.gov.hmcts.reform.civil.validation.UnavailableDateValidator; import uk.gov.hmcts.reform.civil.validation.interfaces.DefendantAddressValidator; @@ -75,18 +77,14 @@ import uk.gov.hmcts.reform.civil.validation.interfaces.WitnessesValidator; import uk.gov.hmcts.reform.idam.client.models.UserInfo; -import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Collections; -import java.util.EnumSet; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; -import java.util.Set; import static java.lang.String.format; import static java.util.Objects.nonNull; @@ -97,42 +95,17 @@ import static uk.gov.hmcts.reform.civil.callback.CallbackType.MID; import static uk.gov.hmcts.reform.civil.callback.CallbackType.SUBMITTED; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.DEFENDANT_RESPONSE_SPEC; -import static uk.gov.hmcts.reform.civil.constants.SpecJourneyConstantLRSpec.DISPUTES_THE_CLAIM; -import static uk.gov.hmcts.reform.civil.enums.CaseRole.APPLICANTSOLICITORONE; import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORONE; import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORTWO; -import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_ONE; import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_ONE_LEGAL_REP; import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_TWO_LEGAL_REP; import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.TWO_V_ONE; import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.getMultiPartyScenario; import static uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec.IMMEDIATELY; -import static uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec.SUGGESTION_OF_REPAYMENT_PLAN; -import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.COUNTER_CLAIM; -import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.FULL_ADMISSION; import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.FULL_DEFENCE; import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.PART_ADMISSION; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; -import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.BOTH_RESPONDENTS_DISPUTE; -import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1; -import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_2; -import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.CURRENT_ADMITS_PART_OR_FULL; -import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.NEED_FINANCIAL_DETAILS_1; -import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.NEED_FINANCIAL_DETAILS_2; -import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.ONLY_RESPONDENT_1_DISPUTES; -import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.ONLY_RESPONDENT_2_DISPUTES; -import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.REPAYMENT_PLAN_2; -import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.RESPONDENT_1_ADMITS_PART_OR_FULL; -import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.RESPONDENT_1_PAID_LESS; -import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.RESPONDENT_2_ADMITS_PART_OR_FULL; -import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.RESPONDENT_2_PAID_LESS; -import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.SOMEONE_DISPUTES; -import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.TIMELINE_MANUALLY; -import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.TIMELINE_UPLOAD; -import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.WHEN_WILL_CLAIM_BE_PAID; -import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.WHY_1_DOES_NOT_PAY_IMMEDIATELY; -import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.WHY_2_DOES_NOT_PAY_IMMEDIATELY; import static uk.gov.hmcts.reform.civil.helpers.DateFormatHelper.DATE; import static uk.gov.hmcts.reform.civil.helpers.DateFormatHelper.formatLocalDateTime; import static uk.gov.hmcts.reform.civil.model.dq.Expert.fromSmallClaimExpertDetails; @@ -140,7 +113,6 @@ import static uk.gov.hmcts.reform.civil.utils.ElementUtils.buildElemCaseDocument; import static uk.gov.hmcts.reform.civil.utils.ElementUtils.wrapElements; import static uk.gov.hmcts.reform.civil.utils.ExpertUtils.addEventAndDateAddedToRespondentExperts; -import static uk.gov.hmcts.reform.civil.utils.MediationUnavailableDatesUtils.checkUnavailable; import static uk.gov.hmcts.reform.civil.utils.PartyUtils.populateDQPartyIds; import static uk.gov.hmcts.reform.civil.utils.WitnessUtils.addEventAndDateAddedToRespondentWitnesses; @@ -152,13 +124,11 @@ public class RespondToClaimSpecCallbackHandler extends CallbackHandler private static final List EVENTS = Collections.singletonList(DEFENDANT_RESPONSE_SPEC); private static final String DEF2 = "Defendant 2"; - private final DateOfBirthValidator dateOfBirthValidator; private final UnavailableDateValidator unavailableDateValidator; private final ObjectMapper objectMapper; private final Time time; private final DeadlinesCalculator deadlinesCalculator; private final PostcodeValidator postcodeValidator; - private final PaymentDateValidator paymentDateValidator; private final List confirmationTextSpecGenerators; private final List confirmationHeaderGenerators; private final FeatureToggleService toggleService; @@ -172,6 +142,20 @@ public class RespondToClaimSpecCallbackHandler extends CallbackHandler private final DeadlineExtensionCalculatorService deadlineCalculatorService; private final FrcDocumentsUtils frcDocumentsUtils; private final DQResponseDocumentUtils dqResponseDocumentUtils; + private final ValidateMediationUnavailableDates validateMediationUnavailableDates; + private final HandleDefendAllClaim handleDefendAllClaim; + private final HandleAdmitPartOfClaim handleAdmitPartOfClaim; + private final HandleRespondentResponseTypeForSpec handleRespondentResponseTypeForSpec; + private final SetGenericResponseTypeFlag setGenericResponseTypeFlag; + private final SetUploadTimelineTypeFlag setUploadTimelineTypeFlag; + private final DetermineLoggedInSolicitor determineLoggedInSolicitor; + private final PopulateRespondent1Copy populateRespondent1Copy; + private final ValidateRespondentWitnesses validateRespondentWitnesses; + private final ValidateRespondentExperts validateRespondentExperts; + private final ValidateUnavailableDates validateUnavailableDates; + private final ValidateDateOfBirth validateDateOfBirth; + private final ValidateRespondentPaymentDate validateRespondentPaymentDate; + private final ValidateLengthOfUnemployment validateLengthOfUnemployment; @Override public List handledEvents() { @@ -206,869 +190,27 @@ protected Map callbacks() { } private CallbackResponse validateMediationUnavailableDates(CallbackParams callbackParams) { - CaseData caseData = callbackParams.getCaseData(); - List errors = new ArrayList<>(); - if ((caseData.getResp1MediationAvailability() != null - && YES.equals(caseData.getResp1MediationAvailability().getIsMediationUnavailablityExists()))) { - checkUnavailable(errors, caseData.getResp1MediationAvailability().getUnavailableDatesForMediation()); - } else if (caseData.getResp2MediationAvailability() != null - && YES.equals(caseData.getResp2MediationAvailability().getIsMediationUnavailablityExists())) { - checkUnavailable(errors, caseData.getResp2MediationAvailability().getUnavailableDatesForMediation()); - } - - return AboutToStartOrSubmitCallbackResponse.builder() - .errors(errors) - .build(); + return validateMediationUnavailableDates.execute(callbackParams); } private CallbackResponse handleDefendAllClaim(CallbackParams callbackParams) { - CaseData caseData = callbackParams.getCaseData(); - List errors = paymentDateValidator.validate(Optional.ofNullable(caseData.getRespondToClaim()) - .orElseGet(() -> RespondToClaim.builder().build())); - if (!errors.isEmpty()) { - return AboutToStartOrSubmitCallbackResponse.builder() - .errors(errors) - .build(); - } - CaseData.CaseDataBuilder updatedCase = caseData.toBuilder(); - updatedCase.showConditionFlags(whoDisputesFullDefence(caseData)); - if (SpecJourneyConstantLRSpec.DEFENDANT_RESPONSE_SPEC.equals(callbackParams.getRequest().getEventId())) { - populateRespondentResponseTypeSpecPaidStatus(caseData, updatedCase); - if (caseData.getRespondent1ClaimResponsePaymentAdmissionForSpec() - == RespondentResponseTypeSpecPaidStatus.PAID_LESS_THAN_CLAIMED_AMOUNT - || DISPUTES_THE_CLAIM.equals(caseData.getDefenceRouteRequired()) - || DISPUTES_THE_CLAIM.equals(caseData.getDefenceRouteRequired2()) - || caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION - || caseData.getRespondent2ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION) { - updatedCase.specPaidLessAmountOrDisputesOrPartAdmission(YES); - } else { - updatedCase.specPaidLessAmountOrDisputesOrPartAdmission(NO); - } - if (YES.equals(caseData.getIsRespondent2())) { - if (RespondentResponseTypeSpecPaidStatus.PAID_LESS_THAN_CLAIMED_AMOUNT - != caseData.getRespondent1ClaimResponsePaymentAdmissionForSpec() - && (DISPUTES_THE_CLAIM.equals(caseData.getDefenceRouteRequired2()) - || caseData.getRespondent2ClaimResponseTypeForSpec() - == RespondentResponseTypeSpec.PART_ADMISSION)) { - updatedCase.specDisputesOrPartAdmission(YES); - } else { - updatedCase.specDisputesOrPartAdmission(NO); - } - } else { - if (RespondentResponseTypeSpecPaidStatus.PAID_LESS_THAN_CLAIMED_AMOUNT - != caseData.getRespondent1ClaimResponsePaymentAdmissionForSpec() - && (DISPUTES_THE_CLAIM.equals(caseData.getDefenceRouteRequired()) - || caseData.getRespondent1ClaimResponseTypeForSpec() - == RespondentResponseTypeSpec.PART_ADMISSION)) { - updatedCase.specDisputesOrPartAdmission(YES); - } else { - updatedCase.specDisputesOrPartAdmission(NO); - } - } - AllocatedTrack allocatedTrack = getAllocatedTrack(caseData); - updatedCase.responseClaimTrack(allocatedTrack.name()); - } - return AboutToStartOrSubmitCallbackResponse.builder() - .data(updatedCase.build().toMap(objectMapper)) - .build(); + return handleDefendAllClaim.execute(callbackParams); } - // called on full_admit, also called after whenWillClaimBePaid private CallbackResponse handleAdmitPartOfClaim(CallbackParams callbackParams) { - CaseData caseData = callbackParams.getCaseData(); - List errors = paymentDateValidator.validate(Optional.ofNullable(caseData.getRespondToAdmittedClaim()) - .orElseGet(() -> RespondToClaim.builder().build())); - if (!errors.isEmpty()) { - return AboutToStartOrSubmitCallbackResponse.builder() - .errors(errors) - .build(); - } - CaseData.CaseDataBuilder updatedCaseData = caseData.toBuilder(); - - if (YES.equals(caseData.getIsRespondent2()) && YES.equals(caseData.getSpecDefenceFullAdmitted2Required())) { - updatedCaseData.fullAdmissionAndFullAmountPaid(YES); - } else if (YES.equals(caseData.getIsRespondent1()) - && YES.equals(caseData.getSpecDefenceFullAdmittedRequired())) { - updatedCaseData.fullAdmissionAndFullAmountPaid(YES); - } else { - updatedCaseData.fullAdmissionAndFullAmountPaid(NO); - } - - if (YES.equals(caseData.getIsRespondent1()) && caseData.getDefenceAdmitPartPaymentTimeRouteRequired() != null) { - updatedCaseData.defenceAdmitPartPaymentTimeRouteGeneric( - caseData.getDefenceAdmitPartPaymentTimeRouteRequired()); - } else if (YES.equals(caseData.getIsRespondent2()) - && caseData.getDefenceAdmitPartPaymentTimeRouteRequired2() != null) { - updatedCaseData.defenceAdmitPartPaymentTimeRouteGeneric( - caseData.getDefenceAdmitPartPaymentTimeRouteRequired2()); - } - - if (YES.equals(caseData.getIsRespondent2()) && YES.equals(caseData.getSpecDefenceAdmitted2Required())) { - updatedCaseData.partAdmittedByEitherRespondents(YES); - } else if (YES.equals(caseData.getIsRespondent1()) && YES.equals(caseData.getSpecDefenceAdmittedRequired())) { - updatedCaseData.partAdmittedByEitherRespondents(YES); - } else { - updatedCaseData.partAdmittedByEitherRespondents(NO); - } - - if (YES.equals(caseData.getDefenceAdmitPartEmploymentTypeRequired())) { - updatedCaseData.respondToClaimAdmitPartEmploymentTypeLRspecGeneric( - caseData.getRespondToClaimAdmitPartEmploymentTypeLRspec()); - } - if (YES.equals(caseData.getDefenceAdmitPartEmploymentType2Required())) { - updatedCaseData.respondToClaimAdmitPartEmploymentTypeLRspecGeneric( - caseData.getRespondToClaimAdmitPartEmploymentTypeLRspec2()); - } - if (caseData.getRespondToAdmittedClaimOwingAmount() != null) { - BigDecimal valuePounds = MonetaryConversions - .penniesToPounds(caseData.getRespondToAdmittedClaimOwingAmount()); - updatedCaseData.respondToAdmittedClaimOwingAmountPounds(valuePounds); - } - if (YES.equals(caseData.getDefenceAdmitPartEmploymentType2Required())) { - updatedCaseData.respondToClaimAdmitPartEmploymentTypeLRspecGeneric( - caseData.getRespondToClaimAdmitPartEmploymentTypeLRspec2()); - } - Optional.ofNullable(caseData.getRespondToAdmittedClaimOwingAmount()) - .map(MonetaryConversions::penniesToPounds) - .ifPresent(updatedCaseData::respondToAdmittedClaimOwingAmountPounds); - Optional.ofNullable(caseData.getRespondToAdmittedClaimOwingAmount2()) - .map(MonetaryConversions::penniesToPounds) - .ifPresent(updatedCaseData::respondToAdmittedClaimOwingAmountPounds2); - if (RespondentResponseTypeSpecPaidStatus.PAID_LESS_THAN_CLAIMED_AMOUNT - == caseData.getRespondent1ClaimResponsePaymentAdmissionForSpec() - || DISPUTES_THE_CLAIM.equals(caseData.getDefenceRouteRequired()) - || RespondentResponseTypeSpec.PART_ADMISSION == caseData.getRespondent1ClaimResponseTypeForSpec()) { - updatedCaseData.specPaidLessAmountOrDisputesOrPartAdmission(YES); - } else { - updatedCaseData.specPaidLessAmountOrDisputesOrPartAdmission(NO); - } - if (RespondentResponseTypeSpecPaidStatus.PAID_LESS_THAN_CLAIMED_AMOUNT - != caseData.getRespondent1ClaimResponsePaymentAdmissionForSpec() - && (DISPUTES_THE_CLAIM.equals(caseData.getDefenceRouteRequired()) - || caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION)) { - updatedCaseData.specDisputesOrPartAdmission(YES); - } else { - updatedCaseData.specDisputesOrPartAdmission(NO); - } - if (caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION - && caseData.getSpecDefenceAdmittedRequired() == NO) { - updatedCaseData.specPartAdmitPaid(NO); - } else if (caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.FULL_ADMISSION - && caseData.getSpecDefenceFullAdmittedRequired() == NO) { - updatedCaseData.specFullAdmitPaid(NO); - } - if (SpecJourneyConstantLRSpec.DEFENDANT_RESPONSE_SPEC.equals(callbackParams.getRequest().getEventId())) { - AllocatedTrack allocatedTrack = getAllocatedTrack(caseData); - updatedCaseData.responseClaimTrack(allocatedTrack.name()); - } - Set currentShowFlags = new HashSet<>(caseData.getShowConditionFlags()); - currentShowFlags.removeAll(EnumSet.of( - NEED_FINANCIAL_DETAILS_1, - NEED_FINANCIAL_DETAILS_2, - WHY_1_DOES_NOT_PAY_IMMEDIATELY, - WHY_2_DOES_NOT_PAY_IMMEDIATELY, - WHEN_WILL_CLAIM_BE_PAID - )); - currentShowFlags.addAll(checkNecessaryFinancialDetails(caseData)); - if (mustWhenWillClaimBePaidBeShown(caseData)) { - currentShowFlags.add(WHEN_WILL_CLAIM_BE_PAID); - } - updatedCaseData.showConditionFlags(currentShowFlags); - - return AboutToStartOrSubmitCallbackResponse.builder() - .data(updatedCaseData.build().toMap(objectMapper)) - .build(); + return handleAdmitPartOfClaim.execute(callbackParams); } - private Set checkNecessaryFinancialDetails(CaseData caseData) { - Set necessary = EnumSet.noneOf(DefendantResponseShowTag.class); - MultiPartyScenario scenario = MultiPartyScenario.getMultiPartyScenario(caseData); - if (caseData.getShowConditionFlags().contains(CAN_ANSWER_RESPONDENT_1)) { - if (caseData.getRespondent1().getType() != Party.Type.COMPANY - && caseData.getRespondent1().getType() != Party.Type.ORGANISATION && needFinancialInfo1(caseData)) { - necessary.add(NEED_FINANCIAL_DETAILS_1); - } - - if (respondent1doesNotPayImmediately(caseData, scenario)) { - necessary.add(WHY_1_DOES_NOT_PAY_IMMEDIATELY); - } - } - - if (caseData.getShowConditionFlags().contains(CAN_ANSWER_RESPONDENT_2)) { - if (caseData.getRespondent2().getType() != Party.Type.COMPANY - && caseData.getRespondent2().getType() != Party.Type.ORGANISATION) { - if ((scenario == ONE_V_TWO_TWO_LEGAL_REP && needFinancialInfo21v2ds(caseData)) - || (scenario == ONE_V_TWO_ONE_LEGAL_REP - && ((caseData.getRespondentResponseIsSame() != YES && needFinancialInfo21v2ds(caseData)) - || (needFinancialInfo1(caseData) && caseData.getRespondentResponseIsSame() == YES)))) { - necessary.add(NEED_FINANCIAL_DETAILS_2); - } - - if (respondent2doesNotPayImmediately(caseData, scenario)) { - necessary.add(WHY_2_DOES_NOT_PAY_IMMEDIATELY); - } - } - - if (respondent2doesNotPayImmediately(caseData, scenario)) { - necessary.add(WHY_2_DOES_NOT_PAY_IMMEDIATELY); - } - - if ((caseData.getRespondentResponseIsSame() == YES - && caseData.getDefenceAdmitPartPaymentTimeRouteRequired() == SUGGESTION_OF_REPAYMENT_PLAN) - || caseData.getDefenceAdmitPartPaymentTimeRouteRequired2() == SUGGESTION_OF_REPAYMENT_PLAN) { - necessary.add(REPAYMENT_PLAN_2); - } - } - - return necessary; - } - - private boolean respondent1doesNotPayImmediately(CaseData caseData, MultiPartyScenario scenario) { - if (YES.equals(caseData.getIsRespondent1()) - && caseData.getRespondentClaimResponseTypeForSpecGeneric() != COUNTER_CLAIM - && caseData.getRespondentClaimResponseTypeForSpecGeneric() != FULL_DEFENCE - && (scenario != ONE_V_TWO_ONE_LEGAL_REP || caseData.getRespondentResponseIsSame() == YES)) { - return caseData.getDefenceAdmitPartPaymentTimeRouteRequired() != IMMEDIATELY - && caseData.getSpecDefenceFullAdmittedRequired() != YES - && caseData.getSpecDefenceAdmittedRequired() != YES; - } - return false; - } - - private boolean respondent2doesNotPayImmediately(CaseData caseData, MultiPartyScenario scenario) { - if (caseData.getRespondentClaimResponseTypeForSpecGeneric() != COUNTER_CLAIM - && caseData.getRespondentClaimResponseTypeForSpecGeneric() != FULL_DEFENCE) { - if (scenario == ONE_V_TWO_ONE_LEGAL_REP && caseData.getRespondentResponseIsSame() == YES) { - return caseData.getDefenceAdmitPartPaymentTimeRouteRequired() != IMMEDIATELY - && caseData.getSpecDefenceFullAdmittedRequired() != YES - && caseData.getSpecDefenceAdmittedRequired() != YES; - } else if (caseData.getRespondentResponseIsSame() != null || scenario == ONE_V_TWO_TWO_LEGAL_REP) { - return caseData.getDefenceAdmitPartPaymentTimeRouteRequired2() != IMMEDIATELY - && caseData.getSpecDefenceFullAdmitted2Required() != YES - && caseData.getSpecDefenceAdmitted2Required() != YES; - } - } - return false; - } - - /** - * this condition has been copied from ccd's on the moment of writing. - * - * @param caseData the case data - * @return true if the financial details for r1 are needed. Doesn't consider if the r1 - */ - private boolean needFinancialInfo1(CaseData caseData) { - return caseData.getDefenceAdmitPartPaymentTimeRouteRequired() != IMMEDIATELY - && caseData.getSpecDefenceAdmittedRequired() != YES - && caseData.getSpecDefenceFullAdmittedRequired() != YES - && caseData.getRespondentClaimResponseTypeForSpecGeneric() != FULL_DEFENCE - && caseData.getRespondentClaimResponseTypeForSpecGeneric() != RespondentResponseTypeSpec.COUNTER_CLAIM - && caseData.getMultiPartyResponseTypeFlags() != MultiPartyResponseTypeFlags.COUNTER_ADMIT_OR_ADMIT_PART - && (caseData.getSameSolicitorSameResponse() != NO - || MultiPartyScenario.getMultiPartyScenario(caseData) == ONE_V_TWO_TWO_LEGAL_REP) - && caseData.getDefendantSingleResponseToBothClaimants() != NO; - } - - /** - * Adapts the conditions from needFinancialInfo1 for use with 2nd solicitor. - * - * @param caseData case data - * @return true if the financial details for 2nd defendant are needed, in a 1v2 different solicitor claim. - */ - private boolean needFinancialInfo21v2ds(CaseData caseData) { - return caseData.getDefenceAdmitPartPaymentTimeRouteRequired2() != IMMEDIATELY - && caseData.getSpecDefenceAdmitted2Required() != YES - && caseData.getSpecDefenceFullAdmitted2Required() != YES - && caseData.getRespondentClaimResponseTypeForSpecGeneric() != FULL_DEFENCE - && caseData.getRespondentClaimResponseTypeForSpecGeneric() != RespondentResponseTypeSpec.COUNTER_CLAIM; - } - - /** - * From the responseType, if we choose A, advance for a while, then backtrack and choose B, part of our responses - * in A stay in frontend and may influence screens that A and B have in common. - * - *

Why does that happen? - * Frontend keeps an object with the CaseData information. - * In mid callbacks frontend sends part of that object, which gets deserialized into an instance of CaseData. - * We can modify that caseData, but since where using objectMapper.setSerializationInclusion(Include.NON_EMPTY) - * we only send anything not empty, not null. That means we cannot signal frontend to "clean" info. - * What we can do, however, is change info.

- * - *

For instance, the field specDefenceFullAdmittedRequired is only accessible from FULL_ADMISSION. - * If the user went to full admission, checked specDefenceFullAdmittedRequired = yes - * and then went back and to part admit, a bunch of screens common to both options won't appear because their - * condition to show include that specDefenceFullAdmittedRequired != yes. So, if in this method we say that whenever - * responseType is not full admission, then specDefenceFullAdmittedRequired = No, since that is not empty, gets sent - * to frontend and frontend overwrites that field on its copy.

- * - * @param callbackParams parameters from frontend. - * @return caseData cleaned from backtracked paths. - */ private CallbackResponse handleRespondentResponseTypeForSpec(CallbackParams callbackParams) { - CaseData caseData = callbackParams.getCaseData(); - if (caseData.getRespondent1ClaimResponseTypeForSpec() != RespondentResponseTypeSpec.FULL_ADMISSION - || caseData.getRespondent2ClaimResponseTypeForSpec() != RespondentResponseTypeSpec.FULL_ADMISSION) { - caseData = caseData.toBuilder().specDefenceFullAdmittedRequired(NO).build(); - } - return AboutToStartOrSubmitCallbackResponse.builder() - .data(caseData.toMap(objectMapper)) - .build(); + return handleRespondentResponseTypeForSpec.execute(callbackParams); } private CallbackResponse setGenericResponseTypeFlag(CallbackParams callbackParams) { - CaseData caseData = callbackParams.getCaseData(); - CaseData.CaseDataBuilder updatedData = - caseData.toBuilder().multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.NOT_FULL_DEFENCE); - - if ((RespondentResponseTypeSpec.FULL_ADMISSION.equals(caseData.getClaimant1ClaimResponseTypeForSpec()) - || RespondentResponseTypeSpec.PART_ADMISSION.equals(caseData.getClaimant1ClaimResponseTypeForSpec()) - || RespondentResponseTypeSpec.COUNTER_CLAIM.equals(caseData.getClaimant1ClaimResponseTypeForSpec())) - && - (RespondentResponseTypeSpec.FULL_ADMISSION.equals(caseData.getClaimant2ClaimResponseTypeForSpec()) - || RespondentResponseTypeSpec.PART_ADMISSION.equals(caseData.getClaimant2ClaimResponseTypeForSpec()) - || RespondentResponseTypeSpec.COUNTER_CLAIM.equals(caseData.getClaimant2ClaimResponseTypeForSpec()))) { - updatedData.multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.COUNTER_ADMIT_OR_ADMIT_PART); - } - //this logic to be removed when ccd supports AND-OR combinations - MultiPartyScenario multiPartyScenario = getMultiPartyScenario(caseData); - if (ONE_V_ONE.equals(multiPartyScenario)) { - updatedData.respondentClaimResponseTypeForSpecGeneric(caseData.getRespondent1ClaimResponseTypeForSpec()); - if (caseData.getRespondent1ClaimResponseTypeForSpec() == FULL_DEFENCE) { - updatedData.multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.FULL_DEFENCE); - } else if (caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.COUNTER_CLAIM) { - updatedData.multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.COUNTER_ADMIT_OR_ADMIT_PART); - } else if (caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.FULL_ADMISSION - || caseData.getRespondent2ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.FULL_ADMISSION) { - updatedData.multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.FULL_ADMISSION); - } - } - - Set someAdmission = EnumSet.of(PART_ADMISSION, FULL_ADMISSION); - if (TWO_V_ONE.equals(multiPartyScenario) - && someAdmission.contains(caseData.getRespondent1ClaimResponseTypeForSpec()) - && someAdmission.contains(caseData.getRespondent2ClaimResponseTypeForSpec())) { - updatedData.specFullAdmissionOrPartAdmission(YES); - } else { - updatedData.specFullAdmissionOrPartAdmission(NO); - } - - if (ONE_V_TWO_ONE_LEGAL_REP.equals(multiPartyScenario) - && Objects.equals( - caseData.getRespondent1ClaimResponseTypeForSpec(), - caseData.getRespondent2ClaimResponseTypeForSpec() - )) { - updatedData.respondentResponseIsSame(YES); - caseData = caseData.toBuilder() - .respondentResponseIsSame(YES) - .build(); - } - if (ONE_V_TWO_ONE_LEGAL_REP.equals(multiPartyScenario) - && caseData.getRespondentResponseIsSame().equals(NO)) { - updatedData.sameSolicitorSameResponse(NO); - if (FULL_DEFENCE.equals(caseData.getRespondent1ClaimResponseTypeForSpec()) - || FULL_DEFENCE.equals(caseData.getRespondent2ClaimResponseTypeForSpec())) { - updatedData.respondentClaimResponseTypeForSpecGeneric(FULL_DEFENCE); - } - } else if (ONE_V_TWO_ONE_LEGAL_REP.equals(multiPartyScenario) - && caseData.getRespondentResponseIsSame().equals(YES)) { - updatedData.sameSolicitorSameResponse(YES); - updatedData.respondentClaimResponseTypeForSpecGeneric(caseData.getRespondent1ClaimResponseTypeForSpec()); - if (FULL_DEFENCE.equals(caseData.getRespondent1ClaimResponseTypeForSpec()) - || RespondentResponseTypeSpec.COUNTER_CLAIM.equals(caseData.getRespondent1ClaimResponseTypeForSpec())) { - updatedData.multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.FULL_DEFENCE); - } - } else { - updatedData.respondentClaimResponseTypeForSpecGeneric(caseData.getRespondent1ClaimResponseTypeForSpec()); - } - - UserInfo userInfo = userService.getUserInfo(callbackParams.getParams().get(BEARER_TOKEN).toString()); - if (ONE_V_TWO_TWO_LEGAL_REP.equals(multiPartyScenario)) { - if (coreCaseUserService.userHasCaseRole( - caseData.getCcdCaseReference().toString(), - userInfo.getUid(), - RESPONDENTSOLICITORTWO - )) { - updatedData.respondentClaimResponseTypeForSpecGeneric( - caseData.getRespondent2ClaimResponseTypeForSpec()); - } else { - updatedData.respondentClaimResponseTypeForSpecGeneric( - caseData.getRespondent1ClaimResponseTypeForSpec()); - } - } - - if (ONE_V_TWO_TWO_LEGAL_REP.equals(multiPartyScenario) - && ((YES.equals(caseData.getIsRespondent1()) - && RespondentResponseTypeSpec.PART_ADMISSION.equals(caseData.getRespondent1ClaimResponseTypeForSpec())) - || (YES.equals(caseData.getIsRespondent2()) - && RespondentResponseTypeSpec.PART_ADMISSION.equals(caseData.getRespondent2ClaimResponseTypeForSpec())))) { - updatedData.multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.PART_ADMISSION); - } - - if (YES.equals(caseData.getIsRespondent2())) { - updatedData.respondentClaimResponseTypeForSpecGeneric(caseData.getRespondent2ClaimResponseTypeForSpec()); - } - - if (caseData.getRespondent1ClaimResponseTypeForSpec() == FULL_DEFENCE - || caseData.getRespondent2ClaimResponseTypeForSpec() == FULL_DEFENCE - || caseData.getClaimant1ClaimResponseTypeForSpec() == FULL_DEFENCE - || caseData.getClaimant2ClaimResponseTypeForSpec() == FULL_DEFENCE) { - updatedData.multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.FULL_DEFENCE); - } - - if ((YES.equals(caseData.getIsRespondent1()) - && (caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION - || caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.FULL_ADMISSION)) - || (YES.equals(caseData.getIsRespondent2()) - && (caseData.getRespondent2ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION - || caseData.getRespondent2ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.FULL_ADMISSION))) { - updatedData.specFullAdmissionOrPartAdmission(YES); - } - if (RespondentResponseTypeSpec.FULL_ADMISSION.equals(caseData.getRespondent2ClaimResponseTypeForSpec()) - || RespondentResponseTypeSpec.PART_ADMISSION.equals(caseData.getRespondent2ClaimResponseTypeForSpec()) - || RespondentResponseTypeSpec.COUNTER_CLAIM.equals(caseData.getRespondent2ClaimResponseTypeForSpec())) { - updatedData.multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.COUNTER_ADMIT_OR_ADMIT_PART); - } - if (caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION - || caseData.getRespondent1ClaimResponseTypeForSpec() == FULL_DEFENCE) { - updatedData.specFullDefenceOrPartAdmission1V1(YES); - } - if (caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION - || caseData.getRespondent1ClaimResponseTypeForSpec() == FULL_DEFENCE - || caseData.getRespondent2ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION - || caseData.getRespondent2ClaimResponseTypeForSpec() == FULL_DEFENCE) { - updatedData.specFullDefenceOrPartAdmission(YES); - } else { - updatedData.specFullDefenceOrPartAdmission(NO); - } - if (caseData.getRespondent1ClaimResponseTypeForSpec() != RespondentResponseTypeSpec.FULL_ADMISSION - || caseData.getRespondent2ClaimResponseTypeForSpec() != RespondentResponseTypeSpec.FULL_ADMISSION) { - updatedData.specDefenceFullAdmittedRequired(NO); - } - - if (YES.equals(caseData.getSpecPaidLessAmountOrDisputesOrPartAdmission()) - && !MultiPartyResponseTypeFlags.COUNTER_ADMIT_OR_ADMIT_PART - .equals(caseData.getMultiPartyResponseTypeFlags()) - && (!RespondentResponseTypeSpecPaidStatus.PAID_FULL_OR_MORE_THAN_CLAIMED_AMOUNT - .equals(caseData.getRespondent1ClaimResponsePaymentAdmissionForSpec()))) { - updatedData.showHowToAddTimeLinePage(YES); - } - - if (YES.equals(caseData.getIsRespondent1())) { - if (RespondentResponseTypeSpec.COUNTER_CLAIM.equals(caseData.getRespondent1ClaimResponseTypeForSpec())) { - updatedData.showHowToAddTimeLinePage(NO); - updatedData.multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.COUNTER_ADMIT_OR_ADMIT_PART); - } else if (RespondentResponseTypeSpec.FULL_ADMISSION - .equals(caseData.getRespondent1ClaimResponseTypeForSpec())) { - updatedData.showHowToAddTimeLinePage(NO); - } - } else if (YES.equals(caseData.getIsRespondent2())) { - if (RespondentResponseTypeSpec.COUNTER_CLAIM.equals(caseData.getRespondent2ClaimResponseTypeForSpec())) { - updatedData.showHowToAddTimeLinePage(NO); - updatedData.multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.COUNTER_ADMIT_OR_ADMIT_PART); - } else if (RespondentResponseTypeSpec.FULL_ADMISSION - .equals(caseData.getRespondent2ClaimResponseTypeForSpec())) { - updatedData.showHowToAddTimeLinePage(NO); - } - } - - if (YES.equals(caseData.getIsRespondent2()) && YES.equals(caseData.getSpecDefenceAdmittedRequired())) { - updatedData.partAdmittedByEitherRespondents(YES); - } else if (YES.equals(caseData.getIsRespondent1()) && YES.equals(caseData.getSpecDefenceAdmitted2Required())) { - updatedData.partAdmittedByEitherRespondents(YES); - } else { - updatedData.partAdmittedByEitherRespondents(NO); - } - - if (YES.equals(caseData.getIsRespondent2()) && YES.equals(caseData.getSpecDefenceFullAdmitted2Required())) { - updatedData.fullAdmissionAndFullAmountPaid(YES); - } else if (YES.equals(caseData.getIsRespondent1()) - && YES.equals(caseData.getSpecDefenceFullAdmittedRequired())) { - updatedData.fullAdmissionAndFullAmountPaid(YES); - } else { - updatedData.fullAdmissionAndFullAmountPaid(NO); - } - - if (YES.equals(caseData.getIsRespondent1()) && caseData.getDefenceAdmitPartPaymentTimeRouteRequired() != null) { - updatedData.defenceAdmitPartPaymentTimeRouteGeneric( - caseData.getDefenceAdmitPartPaymentTimeRouteRequired()); - } else if (YES.equals(caseData.getIsRespondent2()) - && caseData.getDefenceAdmitPartPaymentTimeRouteRequired2() != null) { - updatedData.defenceAdmitPartPaymentTimeRouteGeneric( - caseData.getDefenceAdmitPartPaymentTimeRouteRequired2()); - } else { - //workaround - updatedData.defenceAdmitPartPaymentTimeRouteGeneric( - IMMEDIATELY); - } - - Set updatedShowConditions = whoDisputesPartAdmission(caseData); - EnumSet anyAdmission = EnumSet.of( - RespondentResponseTypeSpec.PART_ADMISSION, - RespondentResponseTypeSpec.FULL_ADMISSION - ); - if (updatedShowConditions.contains(CAN_ANSWER_RESPONDENT_1) - && anyAdmission.contains(caseData.getRespondent1ClaimResponseTypeForSpec())) { - updatedShowConditions.add(RESPONDENT_1_ADMITS_PART_OR_FULL); - if (caseData.getRespondentResponseIsSame() == YES) { - updatedShowConditions.add(RESPONDENT_2_ADMITS_PART_OR_FULL); - } - } - if (caseData.getShowConditionFlags().contains(CAN_ANSWER_RESPONDENT_2) - && anyAdmission.contains(caseData.getRespondent2ClaimResponseTypeForSpec())) { - updatedShowConditions.add(RESPONDENT_2_ADMITS_PART_OR_FULL); - } - if (someoneDisputes(caseData)) { - updatedShowConditions.add(SOMEONE_DISPUTES); - } - if ((anyAdmission.contains(caseData.getRespondent1ClaimResponseTypeForSpec()) - && YES.equals(caseData.getIsRespondent1())) - || (anyAdmission.contains(caseData.getRespondent2ClaimResponseTypeForSpec()) - && YES.equals(caseData.getIsRespondent2()))) { - updatedShowConditions.removeIf(EnumSet.of( - CURRENT_ADMITS_PART_OR_FULL - )::contains); - updatedShowConditions.add(CURRENT_ADMITS_PART_OR_FULL); - } - updatedData.showConditionFlags(updatedShowConditions); - - return AboutToStartOrSubmitCallbackResponse.builder() - .data(updatedData.build().toMap(objectMapper)) - .build(); + return setGenericResponseTypeFlag.execute(callbackParams); } private CallbackResponse setUploadTimelineTypeFlag(CallbackParams callbackParams) { - CaseData caseData = callbackParams.getCaseData(); - CaseData.CaseDataBuilder updatedData = caseData.toBuilder(); - Set updatedShowConditions = new HashSet<>(caseData.getShowConditionFlags()); - updatedShowConditions.removeIf(EnumSet.of( - TIMELINE_UPLOAD, - TIMELINE_MANUALLY - )::contains); - - if ((YES.equals(caseData.getIsRespondent1()) - && caseData.getSpecClaimResponseTimelineList() == TimelineUploadTypeSpec.UPLOAD) - || (YES.equals(caseData.getIsRespondent2()) - && caseData.getSpecClaimResponseTimelineList2() == TimelineUploadTypeSpec.UPLOAD)) { - updatedShowConditions.add(TIMELINE_UPLOAD); - } else if ((YES.equals(caseData.getIsRespondent1()) - && caseData.getSpecClaimResponseTimelineList() == TimelineUploadTypeSpec.MANUAL) - || (YES.equals(caseData.getIsRespondent2()) - && caseData.getSpecClaimResponseTimelineList2() == TimelineUploadTypeSpec.MANUAL)) { - updatedShowConditions.add(TIMELINE_MANUALLY); - } - updatedData.showConditionFlags(updatedShowConditions); - - return AboutToStartOrSubmitCallbackResponse.builder() - .data(updatedData.build().toMap(objectMapper)) - .build(); - } - - /** - * The condition to show the right title for why does X disputes the claim is too complex for the current - * abilities of front, so we have to take care of it in back. - * This method may add the flags only_respondent_1_disputes, only_respondent_2_disputes or both_respondent_dispute. - * - * @param caseData the current case data - * @return updated copy of caseData.showConditionFlag - */ - private Set whoDisputesPartAdmission(CaseData caseData) { - Set tags = new HashSet<>(caseData.getShowConditionFlags()); - removeWhoDisputesAndWhoPaidLess(tags); - tags.addAll(whoDisputesBcoPartAdmission(caseData)); - return tags; - } - - static final String UNKNOWN_MP_SCENARIO = "Unknown mp scenario"; - - /** - * Returns the flags that should be active because part admission has been chosen. - * - * @param caseData the claim info - * @return flags to describe who disputes because a response is part admission - */ - private Set whoDisputesBcoPartAdmission(CaseData caseData) { - Set tags = EnumSet.noneOf(DefendantResponseShowTag.class); - MultiPartyScenario mpScenario = getMultiPartyScenario(caseData); - switch (mpScenario) { - case ONE_V_ONE: - if (caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION) { - tags.add(ONLY_RESPONDENT_1_DISPUTES); - } - break; - case TWO_V_ONE: - if ((caseData.getDefendantSingleResponseToBothClaimants() == YES - && caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION) - || caseData.getClaimant1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION - || caseData.getClaimant2ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION) { - tags.add(ONLY_RESPONDENT_1_DISPUTES); - } - break; - case ONE_V_TWO_ONE_LEGAL_REP: - if (caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION) { - if (caseData.getRespondentResponseIsSame() == YES - || caseData.getRespondent2ClaimResponseTypeForSpec() - == RespondentResponseTypeSpec.PART_ADMISSION) { - tags.add(DefendantResponseShowTag.BOTH_RESPONDENTS_DISPUTE); - } else { - tags.add(ONLY_RESPONDENT_1_DISPUTES); - } - } else if (caseData.getRespondent2ClaimResponseTypeForSpec() - == RespondentResponseTypeSpec.PART_ADMISSION) { - tags.add(DefendantResponseShowTag.ONLY_RESPONDENT_2_DISPUTES); - } - break; - case ONE_V_TWO_TWO_LEGAL_REP: - if (caseData.getShowConditionFlags().contains(DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1) - && caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION) { - tags.add(ONLY_RESPONDENT_1_DISPUTES); - } else if (caseData.getShowConditionFlags().contains(DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_2) - && caseData.getRespondent2ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION) { - tags.add(DefendantResponseShowTag.ONLY_RESPONDENT_2_DISPUTES); - } - break; - default: - throw new UnsupportedOperationException(UNKNOWN_MP_SCENARIO); - } - return tags; - } - - private boolean someoneDisputes(CaseData caseData) { - if (TWO_V_ONE.equals(getMultiPartyScenario(caseData))) { - return ((caseData.getClaimant1ClaimResponseTypeForSpec() == FULL_DEFENCE - || caseData.getClaimant2ClaimResponseTypeForSpec() == FULL_DEFENCE) - || caseData.getRespondent1ClaimResponseTypeForSpec() == FULL_DEFENCE - || caseData.getRespondent1ClaimResponseTypeForSpec() == PART_ADMISSION); - } else { - return someoneDisputes(caseData, CAN_ANSWER_RESPONDENT_1, - caseData.getRespondent1ClaimResponseTypeForSpec() - ) - || someoneDisputes(caseData, CAN_ANSWER_RESPONDENT_2, - caseData.getRespondent2ClaimResponseTypeForSpec() - ); - } - } - - private boolean someoneDisputes(CaseData caseData, DefendantResponseShowTag respondent, - RespondentResponseTypeSpec response) { - return caseData.getShowConditionFlags().contains(respondent) - && (response == FULL_DEFENCE - || (response == PART_ADMISSION && !NO.equals(caseData.getRespondentResponseIsSame()))); - } - - private Set whoDisputesFullDefence(CaseData caseData) { - Set tags = new HashSet<>(caseData.getShowConditionFlags()); - // in case of backtracking - removeWhoDisputesAndWhoPaidLess(tags); - Set bcoPartAdmission = whoDisputesBcoPartAdmission(caseData); - MultiPartyScenario mpScenario = getMultiPartyScenario(caseData); - switch (mpScenario) { - case ONE_V_ONE: - fullDefenceAndPaidLess( - caseData.getRespondent1ClaimResponseTypeForSpec(), - caseData.getDefenceRouteRequired(), - caseData.getRespondToClaim(), - caseData.getTotalClaimAmount(), - ONLY_RESPONDENT_1_DISPUTES, - DefendantResponseShowTag.RESPONDENT_1_PAID_LESS - ).ifPresent(bcoPartAdmission::add); - break; - case TWO_V_ONE: - if (!bcoPartAdmission.contains(ONLY_RESPONDENT_1_DISPUTES)) { - if (caseData.getDefendantSingleResponseToBothClaimants() == YES) { - fullDefenceAndPaidLess( - caseData.getRespondent1ClaimResponseTypeForSpec(), - caseData.getDefenceRouteRequired(), - caseData.getRespondToClaim(), - caseData.getTotalClaimAmount(), - ONLY_RESPONDENT_1_DISPUTES, - DefendantResponseShowTag.RESPONDENT_1_PAID_LESS - ).ifPresent(bcoPartAdmission::add); - } else { - fullDefenceAndPaidLess( - caseData.getClaimant1ClaimResponseTypeForSpec(), - caseData.getDefenceRouteRequired(), - caseData.getRespondToClaim(), - caseData.getTotalClaimAmount(), - ONLY_RESPONDENT_1_DISPUTES, - DefendantResponseShowTag.RESPONDENT_1_PAID_LESS - ).ifPresent(bcoPartAdmission::add); - - fullDefenceAndPaidLess( - caseData.getClaimant2ClaimResponseTypeForSpec(), - caseData.getDefenceRouteRequired(), - caseData.getRespondToClaim(), - caseData.getTotalClaimAmount(), - ONLY_RESPONDENT_1_DISPUTES, - DefendantResponseShowTag.RESPONDENT_1_PAID_LESS - ).ifPresent(bcoPartAdmission::add); - } - } - break; - case ONE_V_TWO_ONE_LEGAL_REP: - if (caseData.getRespondentResponseIsSame() == YES) { - fullDefenceAndPaidLess( - caseData.getRespondent1ClaimResponseTypeForSpec(), - caseData.getDefenceRouteRequired(), - caseData.getRespondToClaim(), - caseData.getTotalClaimAmount(), - BOTH_RESPONDENTS_DISPUTE, - DefendantResponseShowTag.RESPONDENT_1_PAID_LESS - ).ifPresent(tag -> { - bcoPartAdmission.add(tag); - if (tag == DefendantResponseShowTag.RESPONDENT_1_PAID_LESS) { - bcoPartAdmission.add(DefendantResponseShowTag.RESPONDENT_2_PAID_LESS); - } - }); - } else { - fullDefenceAndPaidLess( - caseData.getRespondent1ClaimResponseTypeForSpec(), - caseData.getDefenceRouteRequired(), - caseData.getRespondToClaim(), - caseData.getTotalClaimAmount(), - ONLY_RESPONDENT_1_DISPUTES, - DefendantResponseShowTag.RESPONDENT_1_PAID_LESS - ).ifPresent(bcoPartAdmission::add); - if (caseData.getRespondentResponseIsSame() == YES) { - if (bcoPartAdmission.contains(RESPONDENT_1_PAID_LESS)) { - bcoPartAdmission.add(RESPONDENT_2_PAID_LESS); - } - } else { - fullDefenceAndPaidLess( - caseData.getRespondent2ClaimResponseTypeForSpec(), - // if only 2nd defends, defenceRouteRequired2 field is not used - caseData.getDefenceRouteRequired(), - caseData.getRespondToClaim(), - caseData.getTotalClaimAmount(), - DefendantResponseShowTag.ONLY_RESPONDENT_2_DISPUTES, - DefendantResponseShowTag.RESPONDENT_2_PAID_LESS - ).ifPresent(bcoPartAdmission::add); - } - EnumSet bothOnlyDisputes = EnumSet.of( - DefendantResponseShowTag.ONLY_RESPONDENT_1_DISPUTES, - DefendantResponseShowTag.ONLY_RESPONDENT_2_DISPUTES - ); - if (bcoPartAdmission.containsAll(bothOnlyDisputes)) { - bcoPartAdmission.removeAll(bothOnlyDisputes); - bcoPartAdmission.add(BOTH_RESPONDENTS_DISPUTE); - } - } - break; - case ONE_V_TWO_TWO_LEGAL_REP: - if (tags.contains(DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1)) { - fullDefenceAndPaidLess( - caseData.getRespondent1ClaimResponseTypeForSpec(), - caseData.getDefenceRouteRequired(), - caseData.getRespondToClaim(), - caseData.getTotalClaimAmount(), - ONLY_RESPONDENT_1_DISPUTES, - DefendantResponseShowTag.RESPONDENT_1_PAID_LESS - ).ifPresent(bcoPartAdmission::add); - } else if (tags.contains(DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_2)) { - fullDefenceAndPaidLess( - caseData.getRespondent2ClaimResponseTypeForSpec(), - caseData.getDefenceRouteRequired2(), - caseData.getRespondToClaim2(), - caseData.getTotalClaimAmount(), - DefendantResponseShowTag.ONLY_RESPONDENT_2_DISPUTES, - DefendantResponseShowTag.RESPONDENT_2_PAID_LESS - ).ifPresent(bcoPartAdmission::add); - } - break; - default: - throw new UnsupportedOperationException(UNKNOWN_MP_SCENARIO); - } - tags.addAll(bcoPartAdmission); - if (tags.contains(ONLY_RESPONDENT_1_DISPUTES) - || tags.contains(ONLY_RESPONDENT_2_DISPUTES) - || tags.contains(BOTH_RESPONDENTS_DISPUTE)) { - tags.add(SOMEONE_DISPUTES); - } - return tags; - } - - private void removeWhoDisputesAndWhoPaidLess(Set tags) { - tags.removeIf(EnumSet.of( - ONLY_RESPONDENT_1_DISPUTES, - DefendantResponseShowTag.ONLY_RESPONDENT_2_DISPUTES, - DefendantResponseShowTag.BOTH_RESPONDENTS_DISPUTE, - SOMEONE_DISPUTES, - DefendantResponseShowTag.CURRENT_ADMITS_PART_OR_FULL, - DefendantResponseShowTag.RESPONDENT_1_PAID_LESS, - DefendantResponseShowTag.RESPONDENT_2_PAID_LESS, - WHEN_WILL_CLAIM_BE_PAID, - RESPONDENT_1_ADMITS_PART_OR_FULL, - RESPONDENT_2_ADMITS_PART_OR_FULL, - NEED_FINANCIAL_DETAILS_1, - NEED_FINANCIAL_DETAILS_2, - DefendantResponseShowTag.WHY_1_DOES_NOT_PAY_IMMEDIATELY, - WHY_2_DOES_NOT_PAY_IMMEDIATELY, - REPAYMENT_PLAN_2, - DefendantResponseShowTag.MEDIATION - )::contains); - } - - private Optional fullDefenceAndPaidLess( - RespondentResponseTypeSpec responseType, - String fullDefenceRoute, - RespondToClaim responseDetails, - BigDecimal claimedAmount, - DefendantResponseShowTag ifDisputing, - DefendantResponseShowTag ifPaidLess) { - if (FULL_DEFENCE == responseType) { - if (DISPUTES_THE_CLAIM.equals(fullDefenceRoute)) { - return Optional.ofNullable(ifDisputing); - } else if (Optional.ofNullable(responseDetails) - .map(RespondToClaim::getHowMuchWasPaid) - .map(MonetaryConversions::penniesToPounds) - .map(wasPaid1 -> wasPaid1.compareTo(claimedAmount) < 0) - .orElse(false)) { - return Optional.ofNullable(ifPaidLess); - } - } - return Optional.empty(); - } - - private void populateRespondentResponseTypeSpecPaidStatus(CaseData caseData, - CaseData.CaseDataBuilder updated) { - if (SpecJourneyConstantLRSpec.HAS_PAID_THE_AMOUNT_CLAIMED.equals(caseData.getDefenceRouteRequired()) - && caseData.getRespondToClaim().getHowMuchWasPaid() != null) { - // CIV-208 howMuchWasPaid is pence, totalClaimAmount is pounds, hence the need for conversion - int comparison = caseData.getRespondToClaim().getHowMuchWasPaid() - .compareTo(new BigDecimal(MonetaryConversions.poundsToPennies(caseData.getTotalClaimAmount()))); - if (comparison < 0) { - updated.respondent1ClaimResponsePaymentAdmissionForSpec( - RespondentResponseTypeSpecPaidStatus.PAID_LESS_THAN_CLAIMED_AMOUNT).build(); - } else { - updated.respondent1ClaimResponsePaymentAdmissionForSpec( - RespondentResponseTypeSpecPaidStatus.PAID_FULL_OR_MORE_THAN_CLAIMED_AMOUNT).build(); - } - } else { - updated.respondent1ClaimResponsePaymentAdmissionForSpec(RespondentResponseTypeSpecPaidStatus.DID_NOT_PAY) - .build(); - } - - if (YES.equals(caseData.getIsRespondent2())) { - if (SpecJourneyConstantLRSpec.HAS_PAID_THE_AMOUNT_CLAIMED.equals(caseData.getDefenceRouteRequired2()) - && caseData.getRespondToClaim2().getHowMuchWasPaid() != null) { - // CIV-208 howMuchWasPaid is pence, totalClaimAmount is pounds, hence the need for conversion - int comparison = caseData.getRespondToClaim2().getHowMuchWasPaid() - .compareTo(new BigDecimal(MonetaryConversions.poundsToPennies(caseData.getTotalClaimAmount()))); - if (comparison < 0) { - updated.respondent1ClaimResponsePaymentAdmissionForSpec( - RespondentResponseTypeSpecPaidStatus.PAID_LESS_THAN_CLAIMED_AMOUNT).build(); - } else { - updated.respondent1ClaimResponsePaymentAdmissionForSpec( - RespondentResponseTypeSpecPaidStatus.PAID_FULL_OR_MORE_THAN_CLAIMED_AMOUNT).build(); - } - } else { - updated.respondent1ClaimResponsePaymentAdmissionForSpec(null).build(); - } - } - } - - private AllocatedTrack getAllocatedTrack(CaseData caseData) { - return AllocatedTrack.getAllocatedTrack(caseData.getTotalClaimAmount(), null, null, - toggleService, caseData); + return setUploadTimelineTypeFlag.execute(callbackParams); } private CallbackResponse validateCorrespondenceApplicantAddress(CallbackParams callbackParams) { @@ -1080,90 +222,11 @@ private CallbackResponse validateCorrespondenceApplicantAddress(CallbackParams c } private CallbackResponse determineLoggedInSolicitor(CallbackParams callbackParams) { - var caseData = callbackParams.getCaseData(); - - var updatedCaseData = caseData.toBuilder(); - if (solicitorHasCaseRole(callbackParams, RESPONDENTSOLICITORONE)) { - updatedCaseData.isRespondent1(YES); - updatedCaseData.isRespondent2(NO); - updatedCaseData.isApplicant1(NO); - } else if (solicitorHasCaseRole(callbackParams, RESPONDENTSOLICITORTWO)) { - updatedCaseData.isRespondent1(NO); - updatedCaseData.isRespondent2(YES); - updatedCaseData.isApplicant1(NO); - } else if (solicitorHasCaseRole(callbackParams, APPLICANTSOLICITORONE)) { - updatedCaseData.isRespondent1(NO); - updatedCaseData.isRespondent2(NO); - updatedCaseData.isApplicant1(YES); - } - - if (YES.equals(caseData.getIsRespondent2())) { - if (caseData.getRespondent2DetailsForClaimDetailsTab() != null - && ("Company".equals(caseData.getRespondent2DetailsForClaimDetailsTab().getPartyTypeDisplayValue()) - || "Organisation".equals( - caseData.getRespondent2DetailsForClaimDetailsTab().getPartyTypeDisplayValue()))) { - updatedCaseData.neitherCompanyNorOrganisation(NO); - } else { - updatedCaseData.neitherCompanyNorOrganisation(YES); - } - } else { - if ((caseData.getRespondent1DetailsForClaimDetailsTab() != null - && ("Company".equals(caseData.getRespondent1DetailsForClaimDetailsTab().getPartyTypeDisplayValue()) - || "Organisation".equals( - caseData.getRespondent1DetailsForClaimDetailsTab().getPartyTypeDisplayValue())))) { - updatedCaseData.neitherCompanyNorOrganisation(NO); - } else { - updatedCaseData.neitherCompanyNorOrganisation(YES); - } - } - - return AboutToStartOrSubmitCallbackResponse.builder() - .data(updatedCaseData.build().toMap(objectMapper)) - .build(); + return determineLoggedInSolicitor.execute(callbackParams); } private CallbackResponse populateRespondent1Copy(CallbackParams callbackParams) { - var caseData = callbackParams.getCaseData(); - Set initialShowTags = getInitialShowTags(callbackParams); - var updatedCaseData = caseData.toBuilder() - .respondent1Copy(caseData.getRespondent1()) - .respondent1ClaimResponseTestForSpec(caseData.getRespondent1ClaimResponseTypeForSpec()) - .respondent2ClaimResponseTestForSpec(caseData.getRespondent2ClaimResponseTypeForSpec()) - .showConditionFlags(initialShowTags); - if (toggleService.isCarmEnabledForCase(caseData)) { - updatedCaseData.showCarmFields(YES); - } else { - updatedCaseData.showCarmFields(NO); - } - - updatedCaseData.respondent1DetailsForClaimDetailsTab(caseData.getRespondent1().toBuilder().flags(null).build()); - - ofNullable(caseData.getRespondent2()) - .ifPresent(r2 -> updatedCaseData.respondent2Copy(r2) - .respondent2DetailsForClaimDetailsTab(r2.toBuilder().flags(null).build()) - ); - - DynamicList courtLocationList = courtLocationUtils.getLocationsFromList(fetchLocationData(callbackParams)); - if (initialShowTags.contains(CAN_ANSWER_RESPONDENT_1)) { - updatedCaseData.respondent1DQ(Respondent1DQ.builder() - .respondToCourtLocation( - RequestedCourt.builder() - .responseCourtLocations(courtLocationList) - .build()) - .build()); - } - if (initialShowTags.contains(CAN_ANSWER_RESPONDENT_2)) { - updatedCaseData.respondent2DQ(Respondent2DQ.builder() - .respondToCourtLocation2( - RequestedCourt.builder() - .responseCourtLocations(courtLocationList) - .build()) - .build()); - } - - return AboutToStartOrSubmitCallbackResponse.builder() - .data(updatedCaseData.build().toMap(objectMapper)) - .build(); + return populateRespondent1Copy.execute(callbackParams); } private List fetchLocationData(CallbackParams callbackParams) { @@ -1171,79 +234,12 @@ private List fetchLocationData(CallbackParams callbackParams) { return locationRefDataService.getCourtLocationsForDefaultJudgments(authToken); } - private Set getInitialShowTags(CallbackParams callbackParams) { - CaseData caseData = callbackParams.getCaseData(); - MultiPartyScenario mpScenario = getMultiPartyScenario(caseData); - Set set = EnumSet.noneOf(DefendantResponseShowTag.class); - switch (mpScenario) { - case ONE_V_ONE, TWO_V_ONE: - set.add(DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1); - break; - case ONE_V_TWO_ONE_LEGAL_REP: - set.add(DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1); - set.add(DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_2); - break; - case ONE_V_TWO_TWO_LEGAL_REP: - UserInfo userInfo = userService.getUserInfo(callbackParams.getParams().get(BEARER_TOKEN).toString()); - List roles = coreCaseUserService.getUserCaseRoles( - callbackParams.getCaseData().getCcdCaseReference().toString(), - userInfo.getUid() - ); - if (roles.contains(RESPONDENTSOLICITORONE.getFormattedName())) { - set.add(DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1); - } - if (roles.contains(RESPONDENTSOLICITORTWO.getFormattedName())) { - set.add(DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_2); - } - break; - default: - throw new UnsupportedOperationException(UNKNOWN_MP_SCENARIO); - } - return set; - } - private CallbackResponse validateRespondentWitnesses(CallbackParams callbackParams) { - CaseData caseData = callbackParams.getCaseData(); - if (!ONE_V_ONE.equals(MultiPartyScenario.getMultiPartyScenario(caseData))) { - if (solicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORONE)) { - return validateR1Witnesses(caseData); - } else if (solicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORTWO)) { - return validateWitnesses(callbackParams.getCaseData().getRespondent2DQ()); - } else if (respondent2HasSameLegalRep(caseData) - && caseData.getRespondentResponseIsSame() != null && caseData.getRespondentResponseIsSame() == NO - && caseData.getRespondent2DQ() != null && caseData.getRespondent2DQ().getRespondent2DQWitnesses() != null) { - return validateWitnesses(callbackParams.getCaseData().getRespondent2DQ()); - } - } - return validateR1Witnesses(caseData); - } - - private CallbackResponse validateR1Witnesses(CaseData caseData) { - List errors = new ArrayList<>(); - if (caseData.getRespondent1DQWitnessesRequiredSpec() == YES - && caseData.getRespondent1DQWitnessesDetailsSpec() == null) { - errors.add("Witness details required"); - } - return AboutToStartOrSubmitCallbackResponse.builder() - .errors(errors) - .build(); + return validateRespondentWitnesses.execute(callbackParams); } private CallbackResponse validateRespondentExperts(CallbackParams callbackParams) { - CaseData caseData = callbackParams.getCaseData(); - if (!ONE_V_ONE.equals(MultiPartyScenario.getMultiPartyScenario(caseData))) { - if (solicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORONE)) { - return validateExperts(callbackParams.getCaseData().getRespondent1DQ()); - } else if (solicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORTWO)) { - return validateExperts(callbackParams.getCaseData().getRespondent2DQ()); - } else if (respondent2HasSameLegalRep(caseData) - && caseData.getRespondentResponseIsSame() != null && caseData.getRespondentResponseIsSame() == NO - && caseData.getRespondent2DQ() != null - && caseData.getRespondent2DQ().getRespondent2DQExperts() != null) { - return validateExperts(callbackParams.getCaseData().getRespondent2DQ()); - } - } - return validateExperts(callbackParams.getCaseData().getRespondent1DQ()); + return validateRespondentExperts.execute(callbackParams); } private boolean respondent2HasSameLegalRep(CaseData caseData) { @@ -1252,86 +248,11 @@ private boolean respondent2HasSameLegalRep(CaseData caseData) { } private CallbackResponse validateUnavailableDates(CallbackParams callbackParams) { - // UnavailableDates validation & field (model) needs to be created. - // This will be taken care via different story, - // because we don't have AC around this date field validation in ROC-9455 - CaseData caseData = callbackParams.getCaseData(); - List errors; - if (SpecJourneyConstantLRSpec.SMALL_CLAIM.equals(caseData.getResponseClaimTrack())) { - SmallClaimHearing smallClaimHearing = caseData.getRespondent1DQ().getRespondent1DQHearingSmallClaim(); - if (YES.equals(caseData.getIsRespondent2())) { - smallClaimHearing = caseData.getRespondent2DQ().getRespondent2DQHearingSmallClaim(); - } - errors = unavailableDateValidator.validateSmallClaimsHearing(smallClaimHearing); - - } else { - Hearing hearingLRspec = caseData.getRespondent1DQ().getRespondent1DQHearingFastClaim(); - errors = unavailableDateValidator.validateFastClaimHearing(hearingLRspec); - } - - return AboutToStartOrSubmitCallbackResponse.builder() - .errors(errors) - .build(); + return validateUnavailableDates.execute(callbackParams); } private CallbackResponse validateDateOfBirth(CallbackParams callbackParams) { - Party respondent = callbackParams.getCaseData().getRespondent1(); - if (respondent == null && callbackParams.getCaseData().getRespondent2() != null) { - respondent = callbackParams.getCaseData().getRespondent2(); - } - List errors = dateOfBirthValidator.validate(respondent); - - CaseData caseData = callbackParams.getCaseData(); - errors.addAll(correspondenceAddressCorrect(caseData)); - CaseData.CaseDataBuilder updatedData = caseData.toBuilder(); - if (ONE_V_TWO_TWO_LEGAL_REP.equals(getMultiPartyScenario(caseData)) - && YES.equals(caseData.getAddRespondent2())) { - if (solicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORTWO) - && solicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORONE)) { - updatedData.sameSolicitorSameResponse(YES).build(); - } else { - updatedData.sameSolicitorSameResponse(NO).build(); - } - } else if (ONE_V_TWO_ONE_LEGAL_REP.equals(getMultiPartyScenario(caseData)) - && YES.equals(caseData.getAddRespondent2())) { - if (NO.equals(caseData.getRespondentResponseIsSame())) { - updatedData.sameSolicitorSameResponse(NO).build(); - } else { - updatedData.sameSolicitorSameResponse(YES).build(); - } - - } - - return AboutToStartOrSubmitCallbackResponse.builder() - .data(updatedData.build().toMap(objectMapper)) - .errors(errors) - .build(); - } - - /** - * Checks that the address of case data was ok when the applicant set it, or that its postcode is correct - * if the defendant has modified. - * - * @param caseData the case data - * @return errors of the correspondence address (if any) - */ - private List correspondenceAddressCorrect(CaseData caseData) { - if (caseData.getIsRespondent1() == YesOrNo.YES - && caseData.getSpecAoSRespondentCorrespondenceAddressRequired() == YesOrNo.NO) { - return postcodeValidator.validate( - Optional.ofNullable(caseData.getSpecAoSRespondentCorrespondenceAddressdetails()) - .map(Address::getPostCode) - .orElse(null) - ); - } else if (caseData.getIsRespondent2() == YesOrNo.YES - && caseData.getSpecAoSRespondent2CorrespondenceAddressRequired() == YesOrNo.NO) { - return postcodeValidator.validate( - Optional.ofNullable(caseData.getSpecAoSRespondent2CorrespondenceAddressdetails()) - .map(Address::getPostCode) - .orElse(null) - ); - } - return Collections.emptyList(); + return validateDateOfBirth.execute(callbackParams); } private CallbackResponse resetStatementOfTruth(CallbackParams callbackParams) { @@ -1638,9 +559,9 @@ private void assembleResponseDocumentsSpec(CaseData caseData, CaseData.CaseDataB uk.gov.hmcts.reform.civil.documentmanagement.model.Document respondent1ClaimDocument = respondent1SpecDefenceResponseDocument.getFile(); if (respondent1ClaimDocument != null) { Element documentElement = buildElemCaseDocument( - respondent1ClaimDocument, "Defendant", - updatedCaseData.build().getRespondent1ResponseDate(), - DocumentType.DEFENDANT_DEFENCE + respondent1ClaimDocument, "Defendant", + updatedCaseData.build().getRespondent1ResponseDate(), + DocumentType.DEFENDANT_DEFENCE ); assignCategoryId.assignCategoryIdToDocument( respondent1ClaimDocument, @@ -1656,9 +577,9 @@ private void assembleResponseDocumentsSpec(CaseData caseData, CaseData.CaseDataB uk.gov.hmcts.reform.civil.documentmanagement.model.Document respondent2ClaimDocument = respondent2SpecDefenceResponseDocument.getFile(); if (respondent2ClaimDocument != null) { Element documentElement = buildElemCaseDocument( - respondent2ClaimDocument, DEF2, - updatedCaseData.build().getRespondent2ResponseDate(), - DocumentType.DEFENDANT_DEFENCE + respondent2ClaimDocument, DEF2, + updatedCaseData.build().getRespondent2ResponseDate(), + DocumentType.DEFENDANT_DEFENCE ); assignCategoryId.assignCategoryIdToDocument( respondent2ClaimDocument, @@ -1673,16 +594,16 @@ private void assembleResponseDocumentsSpec(CaseData caseData, CaseData.CaseDataB uk.gov.hmcts.reform.civil.documentmanagement.model.Document respondent2ClaimDocument = respondent2SpecDefenceResponseDocument.getFile(); if (respondent2ClaimDocument != null) { Element documentElement = buildElemCaseDocument( - respondent2ClaimDocument, DEF2, - updatedCaseData.build().getRespondent2ResponseDate(), - DocumentType.DEFENDANT_DEFENCE + respondent2ClaimDocument, DEF2, + updatedCaseData.build().getRespondent2ResponseDate(), + DocumentType.DEFENDANT_DEFENCE ); assignCategoryId.assignCategoryIdToDocument( respondent2ClaimDocument, DocCategory.DEF2_DEFENSE_DQ.getValue() ); CaseDocument copy = assignCategoryId - .copyCaseDocumentWithCategoryId(documentElement.getValue(), DocCategory.DQ_DEF2.getValue()); + .copyCaseDocumentWithCategoryId(documentElement.getValue(), DocCategory.DQ_DEF2.getValue()); defendantUploads.add(documentElement); if (Objects.nonNull(copy)) { defendantUploads.add(ElementUtils.element(copy)); @@ -1864,35 +785,11 @@ private String getDefaultConfirmationBody(CaseData caseData) { } private CallbackResponse validateRespondentPaymentDate(CallbackParams callbackParams) { - - CaseData caseData = callbackParams.getCaseData(); - - List errors = paymentDateValidator - .validate(Optional.ofNullable(caseData.getRespondToClaimAdmitPartLRspec()) - .orElseGet(() -> RespondToClaimAdmitPartLRspec.builder().build())); - - return AboutToStartOrSubmitCallbackResponse.builder() - .errors(errors) - .build(); + return validateRespondentPaymentDate.execute(callbackParams); } private CallbackResponse validateLengthOfUnemployment(CallbackParams callbackParams) { - - CaseData caseData = callbackParams.getCaseData(); - List errors = new ArrayList<>(); - - if (caseData.getRespondToClaimAdmitPartUnemployedLRspec() != null - && caseData.getRespondToClaimAdmitPartUnemployedLRspec().getLengthOfUnemployment() != null - && caseData.getRespondToClaimAdmitPartUnemployedLRspec().getLengthOfUnemployment() - .getNumberOfYearsInUnemployment().contains(".") - || caseData.getRespondToClaimAdmitPartUnemployedLRspec() - .getLengthOfUnemployment().getNumberOfMonthsInUnemployment().contains(".")) { - errors.add("Length of time unemployed must be a whole number, for example, 10."); - } - - return AboutToStartOrSubmitCallbackResponse.builder() - .errors(errors) - .build(); + return validateLengthOfUnemployment.execute(callbackParams); } private CallbackResponse validateDefendant1RepaymentPlan(CallbackParams callbackParams) { @@ -1919,29 +816,6 @@ private CallbackResponse validateRepaymentPlan(RepaymentPlanLRspec repaymentPlan .build(); } - /** - * WhenWillClaimBePaid has to be shown if the respondent admits (full or part) and say they didn't pay. - * At the moment of writing, full admit doesn't ask for how much the respondent paid (if they say they paid) - * and part admit doesn't ask when will the amount be paid even if paid less. - * - * @param caseData claim data - * @return true if pageId WhenWillClaimBePaid must be shown - */ - public boolean mustWhenWillClaimBePaidBeShown(CaseData caseData) { - // 1v1 or 1v2 dif sol - if (caseData.getShowConditionFlags().contains(CAN_ANSWER_RESPONDENT_1)) { - // admit part not pay or admit full not pay - return caseData.getSpecDefenceFullAdmittedRequired() == NO - || caseData.getSpecDefenceAdmittedRequired() == NO; - } else if (caseData.getShowConditionFlags().contains(CAN_ANSWER_RESPONDENT_2)) { - // admit part not pay or admit full not pay - return caseData.getSpecDefenceFullAdmitted2Required() == NO - || caseData.getSpecDefenceAdmitted2Required() == NO; - } - - return false; - } - private void clearTempDocuments(CaseData.CaseDataBuilder builder) { CaseData caseData = builder.build(); // these documents are added to defendantUploads, if we do not remove/null the original, @@ -1956,5 +830,4 @@ private void clearTempDocuments(CaseData.CaseDataBuilder builder) { builder.respondent2DQ(builder.build().getRespondent2DQ().toBuilder().respondent2DQDraftDirections(null).build()); } } - } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/DetermineLoggedInSolicitor.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/DetermineLoggedInSolicitor.java new file mode 100644 index 00000000000..2048ca28200 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/DetermineLoggedInSolicitor.java @@ -0,0 +1,108 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +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.CallbackParams; +import uk.gov.hmcts.reform.civil.enums.CaseRole; +import uk.gov.hmcts.reform.civil.handler.callback.user.task.CaseTask; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.Party; +import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; +import uk.gov.hmcts.reform.civil.service.UserService; +import uk.gov.hmcts.reform.idam.client.models.UserInfo; + +import static uk.gov.hmcts.reform.civil.callback.CallbackParams.Params.BEARER_TOKEN; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.APPLICANTSOLICITORONE; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORONE; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORTWO; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; + +@Component +@RequiredArgsConstructor +@Slf4j +public class DetermineLoggedInSolicitor implements CaseTask { + + private final UserService userService; + private final CoreCaseUserService coreCaseUserService; + private final ObjectMapper objectMapper; + + public CallbackResponse execute(CallbackParams callbackParams) { + var caseData = callbackParams.getCaseData(); + var caseId = caseData.getCcdCaseReference(); + log.info("Executing DetermineLoggedInSolicitor for case ID: {}", caseId); + + var updatedCaseData = caseData.toBuilder(); + + updateSolicitorRoles(callbackParams, updatedCaseData, caseId); + updateCompanyOrOrganisationStatus(caseData, updatedCaseData, caseId); + + log.info("Completed DetermineLoggedInSolicitor for case ID: {}", caseId); + return AboutToStartOrSubmitCallbackResponse.builder() + .data(updatedCaseData.build().toMap(objectMapper)) + .build(); + } + + private void updateSolicitorRoles(CallbackParams callbackParams, CaseData.CaseDataBuilder updatedCaseData, Long caseId) { + log.debug("Updating solicitor roles for case ID: {}", caseId); + if (solicitorHasCaseRole(callbackParams, RESPONDENTSOLICITORONE)) { + updatedCaseData.isRespondent1(YES); + updatedCaseData.isRespondent2(NO); + updatedCaseData.isApplicant1(NO); + log.info("Solicitor role updated to RESPONDENTSOLICITORONE for case ID: {}", caseId); + } else if (solicitorHasCaseRole(callbackParams, RESPONDENTSOLICITORTWO)) { + updatedCaseData.isRespondent1(NO); + updatedCaseData.isRespondent2(YES); + updatedCaseData.isApplicant1(NO); + log.info("Solicitor role updated to RESPONDENTSOLICITORTWO for case ID: {}", caseId); + } else if (solicitorHasCaseRole(callbackParams, APPLICANTSOLICITORONE)) { + updatedCaseData.isRespondent1(NO); + updatedCaseData.isRespondent2(NO); + updatedCaseData.isApplicant1(YES); + log.info("Solicitor role updated to APPLICANTSOLICITORONE for case ID: {}", caseId); + } + } + + private void updateCompanyOrOrganisationStatus(CaseData caseData, CaseData.CaseDataBuilder updatedCaseData, Long caseId) { + log.debug("Updating company or organisation status for case ID: {}", caseId); + if (YES.equals(caseData.getIsRespondent2())) { + if (isCompanyOrOrganisation(caseData.getRespondent2DetailsForClaimDetailsTab())) { + updatedCaseData.neitherCompanyNorOrganisation(NO); + log.info("Respondent 2 is a company or organisation for case ID: {}", caseId); + } else { + updatedCaseData.neitherCompanyNorOrganisation(YES); + log.info("Respondent 2 is neither a company nor organisation for case ID: {}", caseId); + } + } else { + if (isCompanyOrOrganisation(caseData.getRespondent1DetailsForClaimDetailsTab())) { + updatedCaseData.neitherCompanyNorOrganisation(NO); + log.info("Respondent 1 is a company or organisation for case ID: {}", caseId); + } else { + updatedCaseData.neitherCompanyNorOrganisation(YES); + log.info("Respondent 1 is neither a company nor organisation for case ID: {}", caseId); + } + } + } + + private boolean isCompanyOrOrganisation(Party party) { + return party != null && ("Company".equals(party.getPartyTypeDisplayValue()) + || "Organisation".equals(party.getPartyTypeDisplayValue())); + } + + private boolean solicitorHasCaseRole(CallbackParams callbackParams, CaseRole caseRole) { + CaseData caseData = callbackParams.getCaseData(); + UserInfo userInfo = userService.getUserInfo(callbackParams.getParams().get(BEARER_TOKEN).toString()); + + boolean hasRole = coreCaseUserService.userHasCaseRole( + caseData.getCcdCaseReference().toString(), + userInfo.getUid(), + caseRole + ); + log.debug("Solicitor has case role {}: {}", caseRole, hasRole); + return hasRole; + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/HandleAdmitPartOfClaim.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/HandleAdmitPartOfClaim.java new file mode 100644 index 00000000000..64a323196b5 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/HandleAdmitPartOfClaim.java @@ -0,0 +1,404 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +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.CallbackParams; +import uk.gov.hmcts.reform.civil.constants.SpecJourneyConstantLRSpec; +import uk.gov.hmcts.reform.civil.enums.AllocatedTrack; +import uk.gov.hmcts.reform.civil.enums.MultiPartyResponseTypeFlags; +import uk.gov.hmcts.reform.civil.enums.MultiPartyScenario; +import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec; +import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpecPaidStatus; +import uk.gov.hmcts.reform.civil.enums.YesOrNo; +import uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag; +import uk.gov.hmcts.reform.civil.handler.callback.user.task.CaseTask; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.Party; +import uk.gov.hmcts.reform.civil.model.RespondToClaim; +import uk.gov.hmcts.reform.civil.service.FeatureToggleService; +import uk.gov.hmcts.reform.civil.utils.MonetaryConversions; +import uk.gov.hmcts.reform.civil.validation.PaymentDateValidator; + +import java.util.EnumSet; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +import static uk.gov.hmcts.reform.civil.constants.SpecJourneyConstantLRSpec.DISPUTES_THE_CLAIM; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_ONE_LEGAL_REP; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_TWO_LEGAL_REP; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec.IMMEDIATELY; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec.SUGGESTION_OF_REPAYMENT_PLAN; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.COUNTER_CLAIM; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.FULL_DEFENCE; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_2; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.NEED_FINANCIAL_DETAILS_1; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.NEED_FINANCIAL_DETAILS_2; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.REPAYMENT_PLAN_2; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.WHEN_WILL_CLAIM_BE_PAID; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.WHY_1_DOES_NOT_PAY_IMMEDIATELY; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.WHY_2_DOES_NOT_PAY_IMMEDIATELY; + +@Component +@RequiredArgsConstructor +@Slf4j +public class HandleAdmitPartOfClaim implements CaseTask { + + private final ObjectMapper objectMapper; + private final FeatureToggleService toggleService; + private final PaymentDateValidator paymentDateValidator; + private final RespondToClaimSpecUtils respondToClaimSpecUtils; + + public CallbackResponse execute(CallbackParams callbackParams) { + CaseData caseData = callbackParams.getCaseData(); + String caseId = String.valueOf(caseData.getCcdCaseReference()); + + log.info("Executing HandleAdmitPartOfClaim for caseId: {}", caseId); + + List errors = validatePaymentDate(caseData); + if (!errors.isEmpty()) { + log.warn("Validation failed for caseId: {}. Errors: {}", caseId, errors); + return buildErrorResponse(errors); + } + + CaseData.CaseDataBuilder updatedCaseData = caseData.toBuilder(); + + updateFullAdmissionAndFullAmountPaid(caseData, updatedCaseData, caseId); + updateDefenceAdmitPartPaymentTimeRoute(caseData, updatedCaseData, caseId); + updatePartAdmittedByEitherRespondents(caseData, updatedCaseData, caseId); + updateEmploymentType(caseData, updatedCaseData, caseId); + updateOwingAmount(caseData, updatedCaseData, caseId); + updateSpecPaidLessAmountOrDisputesOrPartAdmission(caseData, updatedCaseData, caseId); + updateSpecDisputesOrPartAdmission(caseData, updatedCaseData, caseId); + updateSpecPartAdmitPaid(caseData, updatedCaseData, caseId); + updateSpecFullAdmitPaid(caseData, updatedCaseData, caseId); + updateResponseClaimTrack(callbackParams, caseData, updatedCaseData, caseId); + updateShowConditionFlags(caseData, updatedCaseData, caseId); + + log.info("Successfully executed HandleAdmitPartOfClaim for caseId: {}", caseId); + return buildSuccessResponse(updatedCaseData); + } + + private List validatePaymentDate(CaseData caseData) { + return paymentDateValidator.validate(Optional.ofNullable(caseData.getRespondToAdmittedClaim()) + .orElseGet(() -> RespondToClaim.builder().build())); + } + + private CallbackResponse buildErrorResponse(List errors) { + return AboutToStartOrSubmitCallbackResponse.builder() + .errors(errors) + .build(); + } + + private void updateFullAdmissionAndFullAmountPaid(CaseData caseData, CaseData.CaseDataBuilder updatedCaseData, String caseId) { + if (YES.equals(caseData.getIsRespondent2()) && YES.equals(caseData.getSpecDefenceFullAdmitted2Required())) { + updatedCaseData.fullAdmissionAndFullAmountPaid(YES); + log.debug("Set fullAdmissionAndFullAmountPaid to YES for caseId: {}", caseId); + } else if (YES.equals(caseData.getIsRespondent1()) && YES.equals(caseData.getSpecDefenceFullAdmittedRequired())) { + updatedCaseData.fullAdmissionAndFullAmountPaid(YES); + log.debug("Set fullAdmissionAndFullAmountPaid to YES for caseId: {}", caseId); + } else { + updatedCaseData.fullAdmissionAndFullAmountPaid(NO); + log.debug("Set fullAdmissionAndFullAmountPaid to NO for caseId: {}", caseId); + } + } + + private void updateDefenceAdmitPartPaymentTimeRoute(CaseData caseData, CaseData.CaseDataBuilder updatedCaseData, String caseId) { + if (YES.equals(caseData.getIsRespondent1()) && caseData.getDefenceAdmitPartPaymentTimeRouteRequired() != null) { + updatedCaseData.defenceAdmitPartPaymentTimeRouteGeneric(caseData.getDefenceAdmitPartPaymentTimeRouteRequired()); + log.debug("Updated defenceAdmitPartPaymentTimeRouteGeneric for respondent1, caseId: {}", caseId); + } else if (YES.equals(caseData.getIsRespondent2()) && caseData.getDefenceAdmitPartPaymentTimeRouteRequired2() != null) { + updatedCaseData.defenceAdmitPartPaymentTimeRouteGeneric(caseData.getDefenceAdmitPartPaymentTimeRouteRequired2()); + log.debug("Updated defenceAdmitPartPaymentTimeRouteGeneric for respondent2, caseId: {}", caseId); + } + } + + private void updatePartAdmittedByEitherRespondents(CaseData caseData, CaseData.CaseDataBuilder updatedCaseData, String caseId) { + if (YES.equals(caseData.getIsRespondent2()) && YES.equals(caseData.getSpecDefenceAdmitted2Required())) { + updatedCaseData.partAdmittedByEitherRespondents(YES); + log.debug("Set partAdmittedByEitherRespondents to YES for respondent2, caseId: {}", caseId); + } else if (YES.equals(caseData.getIsRespondent1()) && YES.equals(caseData.getSpecDefenceAdmittedRequired())) { + updatedCaseData.partAdmittedByEitherRespondents(YES); + log.debug("Set partAdmittedByEitherRespondents to YES for respondent1, caseId: {}", caseId); + } else { + updatedCaseData.partAdmittedByEitherRespondents(NO); + log.debug("Set partAdmittedByEitherRespondents to NO for caseId: {}", caseId); + } + } + + private void updateEmploymentType(CaseData caseData, CaseData.CaseDataBuilder updatedCaseData, String caseId) { + if (YES.equals(caseData.getDefenceAdmitPartEmploymentTypeRequired())) { + updatedCaseData.respondToClaimAdmitPartEmploymentTypeLRspecGeneric(caseData.getRespondToClaimAdmitPartEmploymentTypeLRspec()); + log.debug("Updated respondToClaimAdmitPartEmploymentTypeLRspec for respondent1, caseId: {}", caseId); + } + if (YES.equals(caseData.getDefenceAdmitPartEmploymentType2Required())) { + updatedCaseData.respondToClaimAdmitPartEmploymentTypeLRspecGeneric(caseData.getRespondToClaimAdmitPartEmploymentTypeLRspec2()); + log.debug("Updated respondToClaimAdmitPartEmploymentTypeLRspec for respondent2, caseId: {}", caseId); + } + } + + private void updateOwingAmount(CaseData caseData, CaseData.CaseDataBuilder updatedCaseData, String caseId) { + Optional.ofNullable(caseData.getRespondToAdmittedClaimOwingAmount()) + .map(MonetaryConversions::penniesToPounds) + .ifPresent(amount -> { + updatedCaseData.respondToAdmittedClaimOwingAmountPounds(amount); + log.debug("Updated respondToAdmittedClaimOwingAmountPounds for respondent1, caseId: {}", caseId); + }); + Optional.ofNullable(caseData.getRespondToAdmittedClaimOwingAmount2()) + .map(MonetaryConversions::penniesToPounds) + .ifPresent(amount -> { + updatedCaseData.respondToAdmittedClaimOwingAmountPounds2(amount); + log.debug("Updated respondToAdmittedClaimOwingAmountPounds2 for respondent2, caseId: {}", caseId); + }); + } + + private void updateSpecPaidLessAmountOrDisputesOrPartAdmission(CaseData caseData, CaseData.CaseDataBuilder updatedCaseData, String caseId) { + if (RespondentResponseTypeSpecPaidStatus.PAID_LESS_THAN_CLAIMED_AMOUNT == caseData.getRespondent1ClaimResponsePaymentAdmissionForSpec() + || DISPUTES_THE_CLAIM.equals(caseData.getDefenceRouteRequired()) + || RespondentResponseTypeSpec.PART_ADMISSION == caseData.getRespondent1ClaimResponseTypeForSpec()) { + updatedCaseData.specPaidLessAmountOrDisputesOrPartAdmission(YES); + log.debug("Set specPaidLessAmountOrDisputesOrPartAdmission to YES for caseId: {}", caseId); + } else { + updatedCaseData.specPaidLessAmountOrDisputesOrPartAdmission(NO); + log.debug("Set specPaidLessAmountOrDisputesOrPartAdmission to NO for caseId: {}", caseId); + } + } + + private void updateSpecDisputesOrPartAdmission(CaseData caseData, CaseData.CaseDataBuilder updatedCaseData, String caseId) { + if (RespondentResponseTypeSpecPaidStatus.PAID_LESS_THAN_CLAIMED_AMOUNT != caseData.getRespondent1ClaimResponsePaymentAdmissionForSpec() + && (DISPUTES_THE_CLAIM.equals(caseData.getDefenceRouteRequired()) + || caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION)) { + updatedCaseData.specDisputesOrPartAdmission(YES); + log.debug("Set specDisputesOrPartAdmission to YES for caseId: {}", caseId); + } else { + updatedCaseData.specDisputesOrPartAdmission(NO); + log.debug("Set specDisputesOrPartAdmission to NO for caseId: {}", caseId); + } + } + + private void updateSpecPartAdmitPaid(CaseData caseData, CaseData.CaseDataBuilder updatedCaseData, String caseId) { + if (caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION + && caseData.getSpecDefenceAdmittedRequired() == NO) { + updatedCaseData.specPartAdmitPaid(NO); + log.debug("Set specPartAdmitPaid to NO for caseId: {}", caseId); + } + } + + private void updateSpecFullAdmitPaid(CaseData caseData, CaseData.CaseDataBuilder updatedCaseData, String caseId) { + if (caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.FULL_ADMISSION + && caseData.getSpecDefenceFullAdmittedRequired() == NO) { + updatedCaseData.specFullAdmitPaid(NO); + log.debug("Set specFullAdmitPaid to NO for caseId: {}", caseId); + } + } + + private void updateResponseClaimTrack(CallbackParams callbackParams, CaseData caseData, CaseData.CaseDataBuilder updatedCaseData, String caseId) { + if (SpecJourneyConstantLRSpec.DEFENDANT_RESPONSE_SPEC.equals(callbackParams.getRequest().getEventId())) { + AllocatedTrack allocatedTrack = getAllocatedTrack(caseData); + updatedCaseData.responseClaimTrack(allocatedTrack.name()); + log.debug("Set responseClaimTrack to {} for caseId: {}", allocatedTrack.name(), caseId); + } + } + + private void updateShowConditionFlags(CaseData caseData, CaseData.CaseDataBuilder updatedCaseData, String caseId) { + Set currentShowFlags = new HashSet<>(caseData.getShowConditionFlags()); + currentShowFlags.removeAll(EnumSet.of( + NEED_FINANCIAL_DETAILS_1, + NEED_FINANCIAL_DETAILS_2, + WHY_1_DOES_NOT_PAY_IMMEDIATELY, + WHY_2_DOES_NOT_PAY_IMMEDIATELY, + WHEN_WILL_CLAIM_BE_PAID + )); + currentShowFlags.addAll(checkNecessaryFinancialDetails(caseData)); + if (mustWhenWillClaimBePaidBeShown(caseData)) { + currentShowFlags.add(WHEN_WILL_CLAIM_BE_PAID); + log.debug("Added WHEN_WILL_CLAIM_BE_PAID to showConditionFlags for caseId: {}", caseId); + } + updatedCaseData.showConditionFlags(currentShowFlags); + log.debug("Updated showConditionFlags for caseId: {}", caseId); + } + + private CallbackResponse buildSuccessResponse(CaseData.CaseDataBuilder updatedCaseData) { + return AboutToStartOrSubmitCallbackResponse.builder() + .data(updatedCaseData.build().toMap(objectMapper)) + .build(); + } + + private AllocatedTrack getAllocatedTrack(CaseData caseData) { + return AllocatedTrack.getAllocatedTrack(caseData.getTotalClaimAmount(), null, null, toggleService, caseData); + } + + private Set checkNecessaryFinancialDetails(CaseData caseData) { + Set necessary = EnumSet.noneOf(DefendantResponseShowTag.class); + MultiPartyScenario scenario = MultiPartyScenario.getMultiPartyScenario(caseData); + + if (caseData.getShowConditionFlags().contains(CAN_ANSWER_RESPONDENT_1)) { + checkRespondent1FinancialDetails(caseData, necessary, scenario); + } + + if (caseData.getShowConditionFlags().contains(CAN_ANSWER_RESPONDENT_2)) { + checkRespondent2FinancialDetails(caseData, necessary, scenario); + } + + return necessary; + } + + private void checkRespondent1FinancialDetails(CaseData caseData, Set necessary, MultiPartyScenario scenario) { + if (caseData.getRespondent1().getType() != Party.Type.COMPANY + && caseData.getRespondent1().getType() != Party.Type.ORGANISATION && needFinancialInfo1(caseData)) { + necessary.add(NEED_FINANCIAL_DETAILS_1); + log.debug("Added NEED_FINANCIAL_DETAILS_1 for respondent1, caseId: {}", caseData.getCcdCaseReference()); + } + + if (respondent1doesNotPayImmediately(caseData, scenario)) { + necessary.add(WHY_1_DOES_NOT_PAY_IMMEDIATELY); + log.debug("Added WHY_1_DOES_NOT_PAY_IMMEDIATELY for respondent1, caseId: {}", caseData.getCcdCaseReference()); + } + } + + private void checkRespondent2FinancialDetails(CaseData caseData, Set necessary, MultiPartyScenario scenario) { + if (isRespondent2Individual(caseData)) { + addFinancialDetailsForRespondent2(caseData, necessary, scenario); + } + + if (respondent2doesNotPayImmediately(caseData, scenario)) { + necessary.add(WHY_2_DOES_NOT_PAY_IMMEDIATELY); + log.debug("Added WHY_2_DOES_NOT_PAY_IMMEDIATELY for respondent2, caseId: {}", caseData.getCcdCaseReference()); + } + + if (isRepaymentPlanRequired(caseData)) { + necessary.add(REPAYMENT_PLAN_2); + log.debug("Added REPAYMENT_PLAN_2 for respondent2, caseId: {}", caseData.getCcdCaseReference()); + } + } + + private boolean isRespondent2Individual(CaseData caseData) { + return caseData.getRespondent2().getType() != Party.Type.COMPANY + && caseData.getRespondent2().getType() != Party.Type.ORGANISATION; + } + + private void addFinancialDetailsForRespondent2(CaseData caseData, Set necessary, MultiPartyScenario scenario) { + if ((scenario == ONE_V_TWO_TWO_LEGAL_REP && needFinancialInfo21v2ds(caseData)) + || (scenario == ONE_V_TWO_ONE_LEGAL_REP + && ((caseData.getRespondentResponseIsSame() != YES && needFinancialInfo21v2ds(caseData)) + || (needFinancialInfo1(caseData) && caseData.getRespondentResponseIsSame() == YES)))) { + necessary.add(NEED_FINANCIAL_DETAILS_2); + log.debug("Added NEED_FINANCIAL_DETAILS_2 for respondent2, caseId: {}", caseData.getCcdCaseReference()); + } + } + + private boolean isRepaymentPlanRequired(CaseData caseData) { + return (caseData.getRespondentResponseIsSame() == YES + && caseData.getDefenceAdmitPartPaymentTimeRouteRequired() == SUGGESTION_OF_REPAYMENT_PLAN) + || caseData.getDefenceAdmitPartPaymentTimeRouteRequired2() == SUGGESTION_OF_REPAYMENT_PLAN; + } + + private boolean mustWhenWillClaimBePaidBeShown(CaseData caseData) { + if (caseData.getShowConditionFlags().contains(CAN_ANSWER_RESPONDENT_1)) { + return isClaimNotFullyAdmitted(caseData.getSpecDefenceFullAdmittedRequired(), caseData.getSpecDefenceAdmittedRequired()); + } else if (caseData.getShowConditionFlags().contains(CAN_ANSWER_RESPONDENT_2)) { + return isClaimNotFullyAdmitted(caseData.getSpecDefenceFullAdmitted2Required(), caseData.getSpecDefenceAdmitted2Required()); + } + return false; + } + + private boolean isClaimNotFullyAdmitted(YesOrNo fullAdmittedRequired, YesOrNo admittedRequired) { + return fullAdmittedRequired == NO || admittedRequired == NO; + } + + private boolean needFinancialInfo1(CaseData caseData) { + return isPaymentNotImmediate(caseData) + && isNotFullyAdmitted(caseData) + && isNotFullDefenceOrCounterClaim(caseData) + && isNotCounterAdmitOrAdmitPart(caseData) + && isSameSolicitorOrOneVTwoTwoLegalRep(caseData) + && isNotSingleResponseToBothClaimants(caseData); + } + + private boolean isPaymentNotImmediate(CaseData caseData) { + return caseData.getDefenceAdmitPartPaymentTimeRouteRequired() != IMMEDIATELY; + } + + private boolean isNotFullyAdmitted(CaseData caseData) { + return caseData.getSpecDefenceAdmittedRequired() != YES + && caseData.getSpecDefenceFullAdmittedRequired() != YES; + } + + private boolean isNotFullDefenceOrCounterClaim(CaseData caseData) { + return caseData.getRespondentClaimResponseTypeForSpecGeneric() != FULL_DEFENCE + && caseData.getRespondentClaimResponseTypeForSpecGeneric() != RespondentResponseTypeSpec.COUNTER_CLAIM; + } + + private boolean isNotCounterAdmitOrAdmitPart(CaseData caseData) { + return caseData.getMultiPartyResponseTypeFlags() != MultiPartyResponseTypeFlags.COUNTER_ADMIT_OR_ADMIT_PART; + } + + private boolean isSameSolicitorOrOneVTwoTwoLegalRep(CaseData caseData) { + return caseData.getSameSolicitorSameResponse() != NO + || MultiPartyScenario.getMultiPartyScenario(caseData) == ONE_V_TWO_TWO_LEGAL_REP; + } + + private boolean isNotSingleResponseToBothClaimants(CaseData caseData) { + return caseData.getDefendantSingleResponseToBothClaimants() != NO; + } + + private boolean respondent1doesNotPayImmediately(CaseData caseData, MultiPartyScenario scenario) { + return isRespondent1Involved(caseData) + && isNotCounterClaimOrFullDefence(caseData) + && isPaymentNotImmediateForRespondent1(caseData, scenario); + } + + private boolean isRespondent1Involved(CaseData caseData) { + return YES.equals(caseData.getIsRespondent1()); + } + + private boolean isNotCounterClaimOrFullDefence(CaseData caseData) { + return caseData.getRespondentClaimResponseTypeForSpecGeneric() != COUNTER_CLAIM + && caseData.getRespondentClaimResponseTypeForSpecGeneric() != FULL_DEFENCE; + } + + private boolean isPaymentNotImmediateForRespondent1(CaseData caseData, MultiPartyScenario scenario) { + return (scenario != ONE_V_TWO_ONE_LEGAL_REP || caseData.getRespondentResponseIsSame() == YES) + && caseData.getDefenceAdmitPartPaymentTimeRouteRequired() != IMMEDIATELY + && caseData.getSpecDefenceFullAdmittedRequired() != YES + && caseData.getSpecDefenceAdmittedRequired() != YES; + } + + private boolean needFinancialInfo21v2ds(CaseData caseData) { + return caseData.getDefenceAdmitPartPaymentTimeRouteRequired2() != IMMEDIATELY + && caseData.getSpecDefenceAdmitted2Required() != YES + && caseData.getSpecDefenceFullAdmitted2Required() != YES + && caseData.getRespondentClaimResponseTypeForSpecGeneric() != FULL_DEFENCE + && caseData.getRespondentClaimResponseTypeForSpecGeneric() != RespondentResponseTypeSpec.COUNTER_CLAIM; + } + + private boolean respondent2doesNotPayImmediately(CaseData caseData, MultiPartyScenario scenario) { + return isNotCounterClaimOrFullDefence(caseData) + && (isOneVTwoOneLegalRepAndSameResponse(caseData, scenario) || isOneVTwoTwoLegalRepOrDifferentResponse(caseData, scenario)); + } + + private boolean isOneVTwoOneLegalRepAndSameResponse(CaseData caseData, MultiPartyScenario scenario) { + return scenario == ONE_V_TWO_ONE_LEGAL_REP && caseData.getRespondentResponseIsSame() == YES + && isPaymentNotImmediateForRespondent1(caseData, scenario); + } + + private boolean isOneVTwoTwoLegalRepOrDifferentResponse(CaseData caseData, MultiPartyScenario scenario) { + return (caseData.getRespondentResponseIsSame() != null || scenario == ONE_V_TWO_TWO_LEGAL_REP) + && isPaymentNotImmediateForRespondent2(caseData); + } + + private boolean isPaymentNotImmediateForRespondent2(CaseData caseData) { + return caseData.getDefenceAdmitPartPaymentTimeRouteRequired2() != IMMEDIATELY + && caseData.getSpecDefenceFullAdmitted2Required() != YES + && caseData.getSpecDefenceAdmitted2Required() != YES; + } + +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/HandleDefendAllClaim.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/HandleDefendAllClaim.java new file mode 100644 index 00000000000..52fa5bbc239 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/HandleDefendAllClaim.java @@ -0,0 +1,563 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +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.CallbackParams; +import uk.gov.hmcts.reform.civil.constants.SpecJourneyConstantLRSpec; +import uk.gov.hmcts.reform.civil.enums.AllocatedTrack; +import uk.gov.hmcts.reform.civil.enums.MultiPartyScenario; +import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec; +import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpecPaidStatus; +import uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag; +import uk.gov.hmcts.reform.civil.handler.callback.user.task.CaseTask; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.RespondToClaim; +import uk.gov.hmcts.reform.civil.service.FeatureToggleService; +import uk.gov.hmcts.reform.civil.utils.MonetaryConversions; +import uk.gov.hmcts.reform.civil.validation.PaymentDateValidator; + +import java.math.BigDecimal; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +import static uk.gov.hmcts.reform.civil.constants.SpecJourneyConstantLRSpec.DISPUTES_THE_CLAIM; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.getMultiPartyScenario; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.FULL_DEFENCE; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.BOTH_RESPONDENTS_DISPUTE; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_2; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.ONLY_RESPONDENT_1_DISPUTES; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.ONLY_RESPONDENT_2_DISPUTES; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.SOMEONE_DISPUTES; + +@Component +@RequiredArgsConstructor +@Slf4j +public class HandleDefendAllClaim implements CaseTask { + + private final ObjectMapper objectMapper; + private final FeatureToggleService toggleService; + private final PaymentDateValidator paymentDateValidator; + + static final String UNKNOWN_MP_SCENARIO = "Unknown mp scenario"; + + public CallbackResponse execute(CallbackParams callbackParams) { + CaseData caseData = callbackParams.getCaseData(); + String caseId = String.valueOf(caseData.getCcdCaseReference()); + + log.info("Executing HandleDefendAllClaim for caseId: {}", caseId); + + List errors = validatePaymentDate(caseData); + if (!errors.isEmpty()) { + log.warn("Validation failed for caseId: {}. Errors: {}", caseId, errors); + return buildErrorResponse(errors); + } + + CaseData.CaseDataBuilder updatedCase = caseData.toBuilder(); + + log.debug("Updating showConditionFlags for caseId: {}", caseId); + updatedCase.showConditionFlags(whoDisputesFullDefence(caseData, caseId)); + log.debug("Updated showConditionFlags for caseId: {}", caseId); + + if (isDefendantResponseSpec(callbackParams)) { + log.debug("Handling Defendant Response Spec for caseId: {}", caseId); + handleDefendantResponseSpec(caseData, updatedCase, caseId); + log.debug("Completed handling Defendant Response Spec for caseId: {}", caseId); + } + + log.info("Successfully executed HandleDefendAllClaim for caseId: {}", caseId); + return buildCallbackResponse(updatedCase); + } + + private List validatePaymentDate(CaseData caseData) { + return paymentDateValidator.validate(Optional.ofNullable(caseData.getRespondToClaim()) + .orElseGet(() -> RespondToClaim.builder().build())); + } + + private CallbackResponse buildErrorResponse(List errors) { + return AboutToStartOrSubmitCallbackResponse.builder() + .errors(errors) + .build(); + } + + private boolean isDefendantResponseSpec(CallbackParams callbackParams) { + return SpecJourneyConstantLRSpec.DEFENDANT_RESPONSE_SPEC.equals(callbackParams.getRequest().getEventId()); + } + + private void handleDefendantResponseSpec(CaseData caseData, CaseData.CaseDataBuilder updatedCase, String caseId) { + log.debug("Populating Respondent Response Type Spec Paid Status for caseId: {}", caseId); + populateRespondentResponseTypeSpecPaidStatus(caseData, updatedCase, caseId); + + log.debug("Updating specPaidLessAmountOrDisputesOrPartAdmission for caseId: {}", caseId); + updateSpecPaidLessAmountOrDisputesOrPartAdmission(caseData, updatedCase, caseId); + + log.debug("Updating specDisputesOrPartAdmission for caseId: {}", caseId); + updateSpecDisputesOrPartAdmission(caseData, updatedCase, caseId); + + AllocatedTrack allocatedTrack = getAllocatedTrack(caseData); + updatedCase.responseClaimTrack(allocatedTrack.name()); + log.debug("Set responseClaimTrack to {} for caseId: {}", allocatedTrack.name(), caseId); + } + + private void updateSpecPaidLessAmountOrDisputesOrPartAdmission(CaseData caseData, CaseData.CaseDataBuilder updatedCase, String caseId) { + if (isPaidLessOrDisputesOrPartAdmission(caseData)) { + updatedCase.specPaidLessAmountOrDisputesOrPartAdmission(YES); + log.debug("Set specPaidLessAmountOrDisputesOrPartAdmission to YES for caseId: {}", caseId); + } else { + updatedCase.specPaidLessAmountOrDisputesOrPartAdmission(NO); + log.debug("Set specPaidLessAmountOrDisputesOrPartAdmission to NO for caseId: {}", caseId); + } + } + + private boolean isPaidLessOrDisputesOrPartAdmission(CaseData caseData) { + return caseData.getRespondent1ClaimResponsePaymentAdmissionForSpec() == RespondentResponseTypeSpecPaidStatus.PAID_LESS_THAN_CLAIMED_AMOUNT + || DISPUTES_THE_CLAIM.equals(caseData.getDefenceRouteRequired()) + || DISPUTES_THE_CLAIM.equals(caseData.getDefenceRouteRequired2()) + || caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION + || caseData.getRespondent2ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION; + } + + private void updateSpecDisputesOrPartAdmission(CaseData caseData, CaseData.CaseDataBuilder updatedCase, String caseId) { + if (YES.equals(caseData.getIsRespondent2())) { + if (isRespondent2DisputesOrPartAdmission(caseData)) { + updatedCase.specDisputesOrPartAdmission(YES); + log.debug("Set specDisputesOrPartAdmission to YES for respondent2, caseId: {}", caseId); + } else { + updatedCase.specDisputesOrPartAdmission(NO); + log.debug("Set specDisputesOrPartAdmission to NO for respondent2, caseId: {}", caseId); + } + } else { + if (isRespondent1DisputesOrPartAdmission(caseData)) { + updatedCase.specDisputesOrPartAdmission(YES); + log.debug("Set specDisputesOrPartAdmission to YES for respondent1, caseId: {}", caseId); + } else { + updatedCase.specDisputesOrPartAdmission(NO); + log.debug("Set specDisputesOrPartAdmission to NO for respondent1, caseId: {}", caseId); + } + } + } + + private boolean isRespondent2DisputesOrPartAdmission(CaseData caseData) { + return RespondentResponseTypeSpecPaidStatus.PAID_LESS_THAN_CLAIMED_AMOUNT != caseData.getRespondent1ClaimResponsePaymentAdmissionForSpec() + && (DISPUTES_THE_CLAIM.equals(caseData.getDefenceRouteRequired2()) + || caseData.getRespondent2ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION); + } + + private boolean isRespondent1DisputesOrPartAdmission(CaseData caseData) { + return RespondentResponseTypeSpecPaidStatus.PAID_LESS_THAN_CLAIMED_AMOUNT != caseData.getRespondent1ClaimResponsePaymentAdmissionForSpec() + && (DISPUTES_THE_CLAIM.equals(caseData.getDefenceRouteRequired()) + || caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION); + } + + private CallbackResponse buildCallbackResponse(CaseData.CaseDataBuilder updatedCase) { + return AboutToStartOrSubmitCallbackResponse.builder() + .data(updatedCase.build().toMap(objectMapper)) + .build(); + } + + private Set whoDisputesFullDefence(CaseData caseData, String caseId) { + Set tags = new HashSet<>(caseData.getShowConditionFlags()); + log.debug("Removing dispute and payment-related tags for caseId: {}", caseId); + removeWhoDisputesAndWhoPaidLess(tags, caseId); + Set bcoPartAdmission = whoDisputesBcoPartAdmission(caseData, caseId); + MultiPartyScenario mpScenario = getMultiPartyScenario(caseData); + + switch (mpScenario) { + case ONE_V_ONE: + handleOneVOne(caseData, bcoPartAdmission, caseId); + break; + case TWO_V_ONE: + handleTwoVOne(caseData, bcoPartAdmission, caseId); + break; + case ONE_V_TWO_ONE_LEGAL_REP: + handleOneVTwoOneLegalRep(caseData, bcoPartAdmission, caseId); + break; + case ONE_V_TWO_TWO_LEGAL_REP: + handleOneVTwoTwoLegalRep(caseData, bcoPartAdmission, tags, caseId); + break; + default: + log.error("Unsupported MultiPartyScenario: {} for caseId: {}", mpScenario, caseId); + throw new UnsupportedOperationException(UNKNOWN_MP_SCENARIO); + } + + tags.addAll(bcoPartAdmission); + log.debug("Added BCO Part Admission tags for caseId: {}", caseId); + addSomeoneDisputesTag(tags, caseId); + return tags; + } + + private void handleOneVOne(CaseData caseData, Set bcoPartAdmission, String caseId) { + log.debug("Handling ONE_V_ONE scenario for caseId: {}", caseId); + fullDefenceAndPaidLess( + caseData.getRespondent1ClaimResponseTypeForSpec(), + caseData.getDefenceRouteRequired(), + caseData.getRespondToClaim(), + caseData.getTotalClaimAmount(), + ONLY_RESPONDENT_1_DISPUTES, + DefendantResponseShowTag.RESPONDENT_1_PAID_LESS + ).ifPresent(tag -> { + bcoPartAdmission.add(tag); + log.debug("Added {} for ONE_V_ONE scenario, caseId: {}", tag, caseId); + }); + } + + private void handleTwoVOne(CaseData caseData, Set bcoPartAdmission, String caseId) { + log.debug("Handling TWO_V_ONE scenario for caseId: {}", caseId); + if (!bcoPartAdmission.contains(ONLY_RESPONDENT_1_DISPUTES)) { + if (YES.equals(caseData.getDefendantSingleResponseToBothClaimants())) { + handleSingleResponseToBothClaimants(caseData, bcoPartAdmission, caseId); + } else { + handleSeparateResponses(caseData, bcoPartAdmission, caseId); + } + } + } + + private void handleOneVTwoOneLegalRep(CaseData caseData, Set bcoPartAdmission, String caseId) { + log.debug("Handling ONE_V_TWO_ONE_LEGAL_REP scenario for caseId: {}", caseId); + if (YES.equals(caseData.getRespondentResponseIsSame())) { + handleSameResponse(caseData, bcoPartAdmission, caseId); + } else { + handleDifferentResponses(caseData, bcoPartAdmission, caseId); + } + } + + private void handleOneVTwoTwoLegalRep(CaseData caseData, Set bcoPartAdmission, Set tags, String caseId) { + log.debug("Handling ONE_V_TWO_TWO_LEGAL_REP scenario for caseId: {}", caseId); + if (tags.contains(CAN_ANSWER_RESPONDENT_1)) { + handleRespondent1(caseData, bcoPartAdmission, caseId); + } else if (tags.contains(CAN_ANSWER_RESPONDENT_2)) { + handleRespondent2(caseData, bcoPartAdmission, caseId); + } + } + + private void handleSingleResponseToBothClaimants(CaseData caseData, Set bcoPartAdmission, String caseId) { + log.debug("Handling single response to both claimants for caseId: {}", caseId); + fullDefenceAndPaidLess( + caseData.getRespondent1ClaimResponseTypeForSpec(), + caseData.getDefenceRouteRequired(), + caseData.getRespondToClaim(), + caseData.getTotalClaimAmount(), + ONLY_RESPONDENT_1_DISPUTES, + DefendantResponseShowTag.RESPONDENT_1_PAID_LESS + ).ifPresent(tag -> { + bcoPartAdmission.add(tag); + log.debug("Added {} for single response to both claimants, caseId: {}", tag, caseId); + }); + } + + private void handleSeparateResponses(CaseData caseData, Set bcoPartAdmission, String caseId) { + log.debug("Handling separate responses for claimants in TWO_V_ONE scenario, caseId: {}", caseId); + fullDefenceAndPaidLess( + caseData.getClaimant1ClaimResponseTypeForSpec(), + caseData.getDefenceRouteRequired(), + caseData.getRespondToClaim(), + caseData.getTotalClaimAmount(), + ONLY_RESPONDENT_1_DISPUTES, + DefendantResponseShowTag.RESPONDENT_1_PAID_LESS + ).ifPresent(tag -> { + bcoPartAdmission.add(tag); + log.debug("Added {} for separate response from claimant1, caseId: {}", tag, caseId); + }); + + fullDefenceAndPaidLess( + caseData.getClaimant2ClaimResponseTypeForSpec(), + caseData.getDefenceRouteRequired(), + caseData.getRespondToClaim(), + caseData.getTotalClaimAmount(), + ONLY_RESPONDENT_1_DISPUTES, + DefendantResponseShowTag.RESPONDENT_1_PAID_LESS + ).ifPresent(tag -> { + bcoPartAdmission.add(tag); + log.debug("Added {} for separate response from claimant2, caseId: {}", tag, caseId); + }); + } + + private void handleSameResponse(CaseData caseData, Set bcoPartAdmission, String caseId) { + log.debug("Handling same response from respondents in ONE_V_TWO_ONE_LEGAL_REP scenario, caseId: {}", caseId); + fullDefenceAndPaidLess( + caseData.getRespondent1ClaimResponseTypeForSpec(), + caseData.getDefenceRouteRequired(), + caseData.getRespondToClaim(), + caseData.getTotalClaimAmount(), + BOTH_RESPONDENTS_DISPUTE, + DefendantResponseShowTag.RESPONDENT_1_PAID_LESS + ).ifPresent(tag -> { + bcoPartAdmission.add(tag); + log.debug("Added {} for same response from respondents, caseId: {}", tag, caseId); + if (tag == DefendantResponseShowTag.RESPONDENT_1_PAID_LESS) { + bcoPartAdmission.add(DefendantResponseShowTag.RESPONDENT_2_PAID_LESS); + log.debug("Added RESPONDENT_2_PAID_LESS for same response from respondents, caseId: {}", caseId); + } + }); + } + + private void handleDifferentResponses(CaseData caseData, Set bcoPartAdmission, String caseId) { + log.debug("Handling different responses from respondents in ONE_V_TWO_ONE_LEGAL_REP scenario, caseId: {}", caseId); + fullDefenceAndPaidLess( + caseData.getRespondent1ClaimResponseTypeForSpec(), + caseData.getDefenceRouteRequired(), + caseData.getRespondToClaim(), + caseData.getTotalClaimAmount(), + ONLY_RESPONDENT_1_DISPUTES, + DefendantResponseShowTag.RESPONDENT_1_PAID_LESS + ).ifPresent(tag -> { + bcoPartAdmission.add(tag); + log.debug("Added {} for respondent1 different response, caseId: {}", tag, caseId); + }); + + if (YES.equals(caseData.getRespondentResponseIsSame())) { + if (bcoPartAdmission.contains(DefendantResponseShowTag.RESPONDENT_1_PAID_LESS)) { + bcoPartAdmission.add(DefendantResponseShowTag.RESPONDENT_2_PAID_LESS); + log.debug("Added RESPONDENT_2_PAID_LESS as responses are same, caseId: {}", caseId); + } + } else { + fullDefenceAndPaidLess( + caseData.getRespondent2ClaimResponseTypeForSpec(), + caseData.getDefenceRouteRequired2(), + caseData.getRespondToClaim2(), + caseData.getTotalClaimAmount(), + DefendantResponseShowTag.ONLY_RESPONDENT_2_DISPUTES, + DefendantResponseShowTag.RESPONDENT_2_PAID_LESS + ).ifPresent(tag -> { + bcoPartAdmission.add(tag); + log.debug("Added {} for respondent2 different response, caseId: {}", tag, caseId); + }); + } + + EnumSet bothOnlyDisputes = EnumSet.of( + DefendantResponseShowTag.ONLY_RESPONDENT_1_DISPUTES, + DefendantResponseShowTag.ONLY_RESPONDENT_2_DISPUTES + ); + if (bcoPartAdmission.containsAll(bothOnlyDisputes)) { + bcoPartAdmission.removeAll(bothOnlyDisputes); + bcoPartAdmission.add(BOTH_RESPONDENTS_DISPUTE); + log.debug("Set BOTH_RESPONDENTS_DISPUTE after removing individual disputes, caseId: {}", caseId); + } + } + + private void handleRespondent1(CaseData caseData, Set bcoPartAdmission, String caseId) { + log.debug("Handling Respondent1 in ONE_V_TWO_TWO_LEGAL_REP scenario for caseId: {}", caseId); + fullDefenceAndPaidLess( + caseData.getRespondent1ClaimResponseTypeForSpec(), + caseData.getDefenceRouteRequired(), + caseData.getRespondToClaim(), + caseData.getTotalClaimAmount(), + ONLY_RESPONDENT_1_DISPUTES, + DefendantResponseShowTag.RESPONDENT_1_PAID_LESS + ).ifPresent(tag -> { + bcoPartAdmission.add(tag); + log.debug("Added {} for respondent1 in ONE_V_TWO_TWO_LEGAL_REP, caseId: {}", tag, caseId); + }); + } + + private void handleRespondent2(CaseData caseData, Set bcoPartAdmission, String caseId) { + log.debug("Handling Respondent2 in ONE_V_TWO_TWO_LEGAL_REP scenario for caseId: {}", caseId); + fullDefenceAndPaidLess( + caseData.getRespondent2ClaimResponseTypeForSpec(), + caseData.getDefenceRouteRequired2(), + caseData.getRespondToClaim2(), + caseData.getTotalClaimAmount(), + DefendantResponseShowTag.ONLY_RESPONDENT_2_DISPUTES, + DefendantResponseShowTag.RESPONDENT_2_PAID_LESS + ).ifPresent(tag -> { + bcoPartAdmission.add(tag); + log.debug("Added {} for respondent2 in ONE_V_TWO_TWO_LEGAL_REP, caseId: {}", tag, caseId); + }); + } + + private void addSomeoneDisputesTag(Set tags, String caseId) { + if (tags.contains(ONLY_RESPONDENT_1_DISPUTES) + || tags.contains(ONLY_RESPONDENT_2_DISPUTES) + || tags.contains(BOTH_RESPONDENTS_DISPUTE)) { + tags.add(SOMEONE_DISPUTES); + log.debug("Added SOMEONE_DISPUTES tag, caseId: {}", caseId); + } + } + + private void populateRespondentResponseTypeSpecPaidStatus(CaseData caseData, CaseData.CaseDataBuilder updated, String caseId) { + log.debug("Updating Respondent1PaidStatus for caseId: {}", caseId); + updateRespondent1PaidStatus(caseData, updated, caseId); + if (YES.equals(caseData.getIsRespondent2())) { + log.debug("Updating Respondent2PaidStatus for caseId: {}", caseId); + updateRespondent2PaidStatus(caseData, updated, caseId); + } + } + + private void updateRespondent1PaidStatus(CaseData caseData, CaseData.CaseDataBuilder updated, String caseId) { + if (SpecJourneyConstantLRSpec.HAS_PAID_THE_AMOUNT_CLAIMED.equals(caseData.getDefenceRouteRequired()) + && caseData.getRespondToClaim().getHowMuchWasPaid() != null) { + setRespondent1PaidStatus(caseData, updated, caseId); + } else { + updated.respondent1ClaimResponsePaymentAdmissionForSpec(RespondentResponseTypeSpecPaidStatus.DID_NOT_PAY).build(); + log.debug("Set respondent1ClaimResponsePaymentAdmissionForSpec to DID_NOT_PAY for caseId: {}", caseId); + } + } + + private void setRespondent1PaidStatus(CaseData caseData, CaseData.CaseDataBuilder updated, String caseId) { + int comparison = caseData.getRespondToClaim().getHowMuchWasPaid() + .compareTo(new BigDecimal(MonetaryConversions.poundsToPennies(caseData.getTotalClaimAmount()))); + if (comparison < 0) { + updated.respondent1ClaimResponsePaymentAdmissionForSpec(RespondentResponseTypeSpecPaidStatus.PAID_LESS_THAN_CLAIMED_AMOUNT).build(); + log.debug("Set respondent1ClaimResponsePaymentAdmissionForSpec to PAID_LESS_THAN_CLAIMED_AMOUNT for caseId: {}", caseId); + } else { + updated.respondent1ClaimResponsePaymentAdmissionForSpec(RespondentResponseTypeSpecPaidStatus.PAID_FULL_OR_MORE_THAN_CLAIMED_AMOUNT).build(); + log.debug("Set respondent1ClaimResponsePaymentAdmissionForSpec to PAID_FULL_OR_MORE_THAN_CLAIMED_AMOUNT for caseId: {}", caseId); + } + } + + private void updateRespondent2PaidStatus(CaseData caseData, CaseData.CaseDataBuilder updated, String caseId) { + if (SpecJourneyConstantLRSpec.HAS_PAID_THE_AMOUNT_CLAIMED.equals(caseData.getDefenceRouteRequired2()) + && caseData.getRespondToClaim2().getHowMuchWasPaid() != null) { + setRespondent2PaidStatus(caseData, updated, caseId); + } else { + updated.respondent1ClaimResponsePaymentAdmissionForSpec(null).build(); + log.debug("Set respondent1ClaimResponsePaymentAdmissionForSpec to null for caseId: {}", caseId); + } + } + + private void setRespondent2PaidStatus(CaseData caseData, CaseData.CaseDataBuilder updated, String caseId) { + int comparison = caseData.getRespondToClaim2().getHowMuchWasPaid() + .compareTo(new BigDecimal(MonetaryConversions.poundsToPennies(caseData.getTotalClaimAmount()))); + if (comparison < 0) { + updated.respondent1ClaimResponsePaymentAdmissionForSpec(RespondentResponseTypeSpecPaidStatus.PAID_LESS_THAN_CLAIMED_AMOUNT).build(); + log.debug("Set respondent1ClaimResponsePaymentAdmissionForSpec to PAID_LESS_THAN_CLAIMED_AMOUNT for respondent2, caseId: {}", caseId); + } else { + updated.respondent1ClaimResponsePaymentAdmissionForSpec(RespondentResponseTypeSpecPaidStatus.PAID_FULL_OR_MORE_THAN_CLAIMED_AMOUNT).build(); + log.debug("Set respondent1ClaimResponsePaymentAdmissionForSpec to PAID_FULL_OR_MORE_THAN_CLAIMED_AMOUNT for respondent2, caseId: {}", caseId); + } + } + + private AllocatedTrack getAllocatedTrack(CaseData caseData) { + return AllocatedTrack.getAllocatedTrack(caseData.getTotalClaimAmount(), null, null, + toggleService, caseData); + } + + private void removeWhoDisputesAndWhoPaidLess(Set tags, String caseId) { + tags.removeIf(tag -> EnumSet.of( + ONLY_RESPONDENT_1_DISPUTES, + DefendantResponseShowTag.ONLY_RESPONDENT_2_DISPUTES, + DefendantResponseShowTag.BOTH_RESPONDENTS_DISPUTE, + SOMEONE_DISPUTES, + DefendantResponseShowTag.CURRENT_ADMITS_PART_OR_FULL, + DefendantResponseShowTag.RESPONDENT_1_PAID_LESS, + DefendantResponseShowTag.RESPONDENT_2_PAID_LESS, + DefendantResponseShowTag.WHEN_WILL_CLAIM_BE_PAID, + DefendantResponseShowTag.RESPONDENT_1_ADMITS_PART_OR_FULL, + DefendantResponseShowTag.RESPONDENT_2_ADMITS_PART_OR_FULL, + DefendantResponseShowTag.NEED_FINANCIAL_DETAILS_1, + DefendantResponseShowTag.NEED_FINANCIAL_DETAILS_2, + DefendantResponseShowTag.WHY_2_DOES_NOT_PAY_IMMEDIATELY, + DefendantResponseShowTag.REPAYMENT_PLAN_2, + DefendantResponseShowTag.MEDIATION + ).contains(tag)); + log.debug("Removed dispute and payment-related tags for caseId: {}", caseId); + } + + private Set whoDisputesBcoPartAdmission(CaseData caseData, String caseId) { + Set tags = EnumSet.noneOf(DefendantResponseShowTag.class); + MultiPartyScenario mpScenario = getMultiPartyScenario(caseData); + + switch (mpScenario) { + case ONE_V_ONE: + handleOneVOnePartAdmission(caseData, tags, caseId); + break; + case TWO_V_ONE: + handleTwoVOnePartAdmission(caseData, tags, caseId); + break; + case ONE_V_TWO_ONE_LEGAL_REP: + handleOneVTwoOneLegalRepPartAdmission(caseData, tags, caseId); + break; + case ONE_V_TWO_TWO_LEGAL_REP: + handleOneVTwoTwoLegalRepPartAdmission(caseData, tags, caseId); + break; + default: + log.error("Unsupported MultiPartyScenario: {} for caseId: {}", mpScenario, caseId); + throw new UnsupportedOperationException(UNKNOWN_MP_SCENARIO); + } + return tags; + } + + private void handleOneVOnePartAdmission(CaseData caseData, Set tags, String caseId) { + if (caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION) { + tags.add(ONLY_RESPONDENT_1_DISPUTES); + log.debug("Added ONLY_RESPONDENT_1_DISPUTES for ONE_V_ONE scenario, caseId: {}", caseId); + } + } + + private void handleTwoVOnePartAdmission(CaseData caseData, Set tags, String caseId) { + if ((YES.equals(caseData.getDefendantSingleResponseToBothClaimants()) + && RespondentResponseTypeSpec.PART_ADMISSION == caseData.getRespondent1ClaimResponseTypeForSpec()) + || RespondentResponseTypeSpec.PART_ADMISSION == caseData.getRespondent1ClaimResponseTypeForSpec() + || RespondentResponseTypeSpec.PART_ADMISSION == caseData.getRespondent2ClaimResponseTypeForSpec()) { + tags.add(ONLY_RESPONDENT_1_DISPUTES); + log.debug("Added ONLY_RESPONDENT_1_DISPUTES for TWO_V_ONE scenario, caseId: {}", caseId); + } + } + + private void handleOneVTwoOneLegalRepPartAdmission(CaseData caseData, Set tags, String caseId) { + if (caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION) { + if (YES.equals(caseData.getRespondentResponseIsSame()) + || caseData.getRespondent2ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION) { + tags.add(BOTH_RESPONDENTS_DISPUTE); + log.debug("Added BOTH_RESPONDENTS_DISPUTE for ONE_V_TWO_ONE_LEGAL_REP scenario, caseId: {}", caseId); + } else { + tags.add(ONLY_RESPONDENT_1_DISPUTES); + log.debug("Added ONLY_RESPONDENT_1_DISPUTES for ONE_V_TWO_ONE_LEGAL_REP scenario, caseId: {}", caseId); + } + } else if (caseData.getRespondent2ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION) { + tags.add(ONLY_RESPONDENT_2_DISPUTES); + log.debug("Added ONLY_RESPONDENT_2_DISPUTES for ONE_V_TWO_ONE_LEGAL_REP scenario, caseId: {}", caseId); + } + } + + private void handleOneVTwoTwoLegalRepPartAdmission(CaseData caseData, Set tags, String caseId) { + if (tags.contains(CAN_ANSWER_RESPONDENT_1) + && caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION) { + tags.add(ONLY_RESPONDENT_1_DISPUTES); + log.debug("Added ONLY_RESPONDENT_1_DISPUTES for ONE_V_TWO_TWO_LEGAL_REP scenario, caseId: {}", caseId); + } else if (tags.contains(CAN_ANSWER_RESPONDENT_2) + && caseData.getRespondent2ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION) { + tags.add(ONLY_RESPONDENT_2_DISPUTES); + log.debug("Added ONLY_RESPONDENT_2_DISPUTES for ONE_V_TWO_TWO_LEGAL_REP scenario, caseId: {}", caseId); + } + } + + private Optional fullDefenceAndPaidLess( + RespondentResponseTypeSpec responseType, + String fullDefenceRoute, + RespondToClaim responseDetails, + BigDecimal claimedAmount, + DefendantResponseShowTag ifDisputing, + DefendantResponseShowTag ifPaidLess) { + + if (FULL_DEFENCE == responseType) { + if (isClaimDisputed(fullDefenceRoute)) { + return Optional.ofNullable(ifDisputing); + } else if (isPaidLessThanClaimed(responseDetails, claimedAmount)) { + return Optional.ofNullable(ifPaidLess); + } + } + return Optional.empty(); + } + + private boolean isClaimDisputed(String fullDefenceRoute) { + return DISPUTES_THE_CLAIM.equals(fullDefenceRoute); + } + + private boolean isPaidLessThanClaimed(RespondToClaim responseDetails, BigDecimal claimedAmount) { + return Optional.ofNullable(responseDetails) + .map(RespondToClaim::getHowMuchWasPaid) + .map(MonetaryConversions::penniesToPounds) + .map(wasPaid -> wasPaid.compareTo(claimedAmount) < 0) + .orElse(false); + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/HandleRespondentResponseTypeForSpec.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/HandleRespondentResponseTypeForSpec.java new file mode 100644 index 00000000000..3cbbc035dd6 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/HandleRespondentResponseTypeForSpec.java @@ -0,0 +1,41 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +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.CallbackParams; +import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec; +import uk.gov.hmcts.reform.civil.handler.callback.user.task.CaseTask; +import uk.gov.hmcts.reform.civil.model.CaseData; + +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; + +@Component +@RequiredArgsConstructor +@Slf4j +public class HandleRespondentResponseTypeForSpec implements CaseTask { + + private final ObjectMapper objectMapper; + + public CallbackResponse execute(CallbackParams callbackParams) { + CaseData caseData = callbackParams.getCaseData(); + Long caseId = caseData.getCcdCaseReference(); + + log.info("Executing HandleRespondentResponseTypeForSpec for caseId: {}", caseId); + + if (caseData.getRespondent1ClaimResponseTypeForSpec() != RespondentResponseTypeSpec.FULL_ADMISSION + || caseData.getRespondent2ClaimResponseTypeForSpec() != RespondentResponseTypeSpec.FULL_ADMISSION) { + log.info("Setting specDefenceFullAdmittedRequired to NO for caseId: {}", caseId); + caseData = caseData.toBuilder().specDefenceFullAdmittedRequired(NO).build(); + } + + log.info("Completed HandleRespondentResponseTypeForSpec for caseId: {}", caseId); + + return AboutToStartOrSubmitCallbackResponse.builder() + .data(caseData.toMap(objectMapper)) + .build(); + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/PopulateRespondent1Copy.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/PopulateRespondent1Copy.java new file mode 100644 index 00000000000..02208d563d2 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/PopulateRespondent1Copy.java @@ -0,0 +1,162 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +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.CallbackParams; +import uk.gov.hmcts.reform.civil.enums.MultiPartyScenario; +import uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag; +import uk.gov.hmcts.reform.civil.handler.callback.user.task.CaseTask; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.common.DynamicList; +import uk.gov.hmcts.reform.civil.model.dq.RequestedCourt; +import uk.gov.hmcts.reform.civil.model.dq.Respondent1DQ; +import uk.gov.hmcts.reform.civil.model.dq.Respondent2DQ; +import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; +import uk.gov.hmcts.reform.civil.service.FeatureToggleService; +import uk.gov.hmcts.reform.civil.service.UserService; +import uk.gov.hmcts.reform.civil.utils.CourtLocationUtils; +import uk.gov.hmcts.reform.idam.client.models.UserInfo; + +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + +import static java.util.Optional.ofNullable; +import static uk.gov.hmcts.reform.civil.callback.CallbackParams.Params.BEARER_TOKEN; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORONE; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORTWO; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.getMultiPartyScenario; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_2; + +@Component +@RequiredArgsConstructor +@Slf4j +public class PopulateRespondent1Copy implements CaseTask { + + private final UserService userService; + private final CoreCaseUserService coreCaseUserService; + private final FeatureToggleService toggleService; + private final CourtLocationUtils courtLocationUtils; + private final ObjectMapper objectMapper; + private final RespondToClaimSpecUtils respondToClaimSpecUtils; + + private static final String UNKNOWN_MP_SCENARIO = "Unknown mp scenario"; + + public CallbackResponse execute(CallbackParams callbackParams) { + var caseData = callbackParams.getCaseData(); + var caseId = caseData.getCcdCaseReference(); + log.info("Executing PopulateRespondent1Copy for case ID: {}", caseId); + + Set initialShowTags = getInitialShowTags(callbackParams); + var updatedCaseData = caseData.toBuilder() + .respondent1Copy(caseData.getRespondent1()) + .respondent1ClaimResponseTestForSpec(caseData.getRespondent1ClaimResponseTypeForSpec()) + .respondent2ClaimResponseTestForSpec(caseData.getRespondent2ClaimResponseTypeForSpec()) + .showConditionFlags(initialShowTags); + + updateCarmFields(caseData, updatedCaseData, caseId); + updateRespondentDetails(caseData, updatedCaseData, caseId); + updateCourtLocations(callbackParams, initialShowTags, updatedCaseData, caseId); + + log.info("Completed PopulateRespondent1Copy for case ID: {}", caseId); + return AboutToStartOrSubmitCallbackResponse.builder() + .data(updatedCaseData.build().toMap(objectMapper)) + .build(); + } + + private void updateCarmFields(CaseData caseData, CaseData.CaseDataBuilder updatedCaseData, Long caseId) { + log.debug("Updating CARM fields for case ID: {}", caseId); + if (toggleService.isCarmEnabledForCase(caseData)) { + updatedCaseData.showCarmFields(YES); + log.info("CARM fields enabled for case ID: {}", caseId); + } else { + updatedCaseData.showCarmFields(NO); + log.info("CARM fields disabled for case ID: {}", caseId); + } + } + + private void updateRespondentDetails(CaseData caseData, CaseData.CaseDataBuilder updatedCaseData, Long caseId) { + log.debug("Updating respondent details for case ID: {}", caseId); + updatedCaseData.respondent1DetailsForClaimDetailsTab(caseData.getRespondent1().toBuilder().flags(null).build()); + + ofNullable(caseData.getRespondent2()) + .ifPresent(r2 -> { + updatedCaseData.respondent2Copy(r2) + .respondent2DetailsForClaimDetailsTab(r2.toBuilder().flags(null).build()); + log.info("Respondent 2 details updated for case ID: {}", caseId); + }); + } + + private void updateCourtLocations(CallbackParams callbackParams, Set initialShowTags, CaseData.CaseDataBuilder updatedCaseData, Long caseId) { + log.debug("Updating court locations for case ID: {}", caseId); + DynamicList courtLocationList = courtLocationUtils.getLocationsFromList(respondToClaimSpecUtils.getLocationData(callbackParams)); + if (initialShowTags.contains(CAN_ANSWER_RESPONDENT_1)) { + updatedCaseData.respondent1DQ(Respondent1DQ.builder() + .respondToCourtLocation( + RequestedCourt.builder() + .responseCourtLocations(courtLocationList) + .build()) + .build()); + log.info("Court locations updated for Respondent 1 for case ID: {}", caseId); + } + if (initialShowTags.contains(CAN_ANSWER_RESPONDENT_2)) { + updatedCaseData.respondent2DQ(Respondent2DQ.builder() + .respondToCourtLocation2( + RequestedCourt.builder() + .responseCourtLocations(courtLocationList) + .build()) + .build()); + log.info("Court locations updated for Respondent 2 for case ID: {}", caseId); + } + } + + private Set getInitialShowTags(CallbackParams callbackParams) { + CaseData caseData = callbackParams.getCaseData(); + var caseId = caseData.getCcdCaseReference(); + log.debug("Getting initial show tags for case ID: {}", caseId); + MultiPartyScenario mpScenario = getMultiPartyScenario(caseData); + Set set = EnumSet.noneOf(DefendantResponseShowTag.class); + + switch (mpScenario) { + case ONE_V_ONE, TWO_V_ONE: + set.add(DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1); + break; + case ONE_V_TWO_ONE_LEGAL_REP: + set.add(DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1); + set.add(DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_2); + break; + case ONE_V_TWO_TWO_LEGAL_REP: + handleTwoLegalRepScenario(callbackParams, set, caseId); + break; + default: + log.error("Unknown multi-party scenario for case ID: {}", caseId); + throw new UnsupportedOperationException(UNKNOWN_MP_SCENARIO); + } + log.info("Initial show tags determined for case ID: {}", caseId); + return set; + } + + private void handleTwoLegalRepScenario(CallbackParams callbackParams, Set set, Long caseId) { + log.debug("Handling two legal rep scenario for case ID: {}", caseId); + UserInfo userInfo = userService.getUserInfo(callbackParams.getParams().get(BEARER_TOKEN).toString()); + List roles = coreCaseUserService.getUserCaseRoles( + callbackParams.getCaseData().getCcdCaseReference().toString(), + userInfo.getUid() + ); + if (roles.contains(RESPONDENTSOLICITORONE.getFormattedName())) { + set.add(DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1); + log.info("Role RESPONDENTSOLICITORONE found for case ID: {}", caseId); + } + if (roles.contains(RESPONDENTSOLICITORTWO.getFormattedName())) { + set.add(DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_2); + log.info("Role RESPONDENTSOLICITORTWO found for case ID: {}", caseId); + } + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/RespondToClaimSpecUtils.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/RespondToClaimSpecUtils.java new file mode 100644 index 00000000000..c85abd0637e --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/RespondToClaimSpecUtils.java @@ -0,0 +1,77 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.enums.CaseRole; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.referencedata.model.LocationRefData; +import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; +import uk.gov.hmcts.reform.civil.service.UserService; +import uk.gov.hmcts.reform.civil.service.flowstate.IStateFlowEngine; +import uk.gov.hmcts.reform.civil.service.referencedata.LocationReferenceDataService; +import uk.gov.hmcts.reform.idam.client.models.UserInfo; + +import java.util.List; + +import static uk.gov.hmcts.reform.civil.callback.CallbackParams.Params.BEARER_TOKEN; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_2; +import static uk.gov.hmcts.reform.civil.service.flowstate.FlowFlag.TWO_RESPONDENT_REPRESENTATIVES; + +@Component +@RequiredArgsConstructor +@Slf4j +public class RespondToClaimSpecUtils { + + static final String UNKNOWN_MP_SCENARIO = "Unknown mp scenario"; + + private final LocationReferenceDataService locationRefDataService; + private final UserService userService; + private final IStateFlowEngine stateFlowEngine; + private final CoreCaseUserService coreCaseUserService; + + public boolean isWhenWillClaimBePaidShown(CaseData caseData) { + boolean result = isRespondent1AdmitsAndNotPaid(caseData) || isRespondent2AdmitsAndNotPaid(caseData); + return result; + } + + private boolean isRespondent1AdmitsAndNotPaid(CaseData caseData) { + boolean condition = caseData.getShowConditionFlags().contains(CAN_ANSWER_RESPONDENT_1) + && (caseData.getSpecDefenceFullAdmittedRequired() == NO + || caseData.getSpecDefenceAdmittedRequired() == NO); + return condition; + } + + private boolean isRespondent2AdmitsAndNotPaid(CaseData caseData) { + boolean condition = caseData.getShowConditionFlags().contains(CAN_ANSWER_RESPONDENT_2) + && (caseData.getSpecDefenceFullAdmitted2Required() == NO + || caseData.getSpecDefenceAdmitted2Required() == NO); + return condition; + } + + public boolean isRespondent2HasSameLegalRep(CaseData caseData) { + return caseData.getRespondent2SameLegalRepresentative() != null + && caseData.getRespondent2SameLegalRepresentative() == YES; + } + + public List getLocationData(CallbackParams callbackParams) { + String authToken = callbackParams.getParams().get(BEARER_TOKEN).toString(); + return locationRefDataService.getCourtLocationsForDefaultJudgments(authToken); + } + + public boolean isSolicitorRepresentsOnlyOneOfRespondents(CallbackParams callbackParams, CaseRole caseRole) { + CaseData caseData = callbackParams.getCaseData(); + UserInfo userInfo = userService.getUserInfo(callbackParams.getParams().get(BEARER_TOKEN).toString()); + + return stateFlowEngine.evaluate(caseData).isFlagSet(TWO_RESPONDENT_REPRESENTATIVES) + && coreCaseUserService.userHasCaseRole( + caseData.getCcdCaseReference().toString(), + userInfo.getUid(), + caseRole + ); + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/SetApplicantResponseDeadline.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/SetApplicantResponseDeadline.java new file mode 100644 index 00000000000..8eee76de064 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/SetApplicantResponseDeadline.java @@ -0,0 +1,588 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +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.CallbackParams; +import uk.gov.hmcts.reform.civil.documentmanagement.model.CaseDocument; +import uk.gov.hmcts.reform.civil.documentmanagement.model.DocumentType; +import uk.gov.hmcts.reform.civil.enums.CaseRole; +import uk.gov.hmcts.reform.civil.enums.CaseState; +import uk.gov.hmcts.reform.civil.enums.DocCategory; +import uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec; +import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec; +import uk.gov.hmcts.reform.civil.enums.YesOrNo; +import uk.gov.hmcts.reform.civil.handler.callback.user.task.CaseTask; +import uk.gov.hmcts.reform.civil.helpers.LocationHelper; +import uk.gov.hmcts.reform.civil.model.Address; +import uk.gov.hmcts.reform.civil.model.BusinessProcess; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.Party; +import uk.gov.hmcts.reform.civil.model.RespondToClaimAdmitPartLRspec; +import uk.gov.hmcts.reform.civil.model.ResponseDocument; +import uk.gov.hmcts.reform.civil.model.StatementOfTruth; +import uk.gov.hmcts.reform.civil.model.common.DynamicList; +import uk.gov.hmcts.reform.civil.model.common.Element; +import uk.gov.hmcts.reform.civil.model.dq.Expert; +import uk.gov.hmcts.reform.civil.model.dq.Experts; +import uk.gov.hmcts.reform.civil.model.dq.RequestedCourt; +import uk.gov.hmcts.reform.civil.model.dq.Respondent1DQ; +import uk.gov.hmcts.reform.civil.model.dq.Respondent2DQ; +import uk.gov.hmcts.reform.civil.model.dq.Witnesses; +import uk.gov.hmcts.reform.civil.referencedata.model.LocationRefData; +import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; +import uk.gov.hmcts.reform.civil.service.DeadlinesCalculator; +import uk.gov.hmcts.reform.civil.service.FeatureToggleService; +import uk.gov.hmcts.reform.civil.service.Time; +import uk.gov.hmcts.reform.civil.service.UserService; +import uk.gov.hmcts.reform.civil.service.citizenui.responsedeadline.DeadlineExtensionCalculatorService; +import uk.gov.hmcts.reform.civil.service.flowstate.IStateFlowEngine; +import uk.gov.hmcts.reform.civil.utils.AssignCategoryId; +import uk.gov.hmcts.reform.civil.utils.CaseFlagsInitialiser; +import uk.gov.hmcts.reform.civil.utils.CourtLocationUtils; +import uk.gov.hmcts.reform.civil.utils.DQResponseDocumentUtils; +import uk.gov.hmcts.reform.civil.utils.ElementUtils; +import uk.gov.hmcts.reform.civil.utils.FrcDocumentsUtils; +import uk.gov.hmcts.reform.civil.utils.UnavailabilityDatesUtils; +import uk.gov.hmcts.reform.idam.client.models.UserInfo; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +import static java.util.Objects.nonNull; +import static java.util.Optional.ofNullable; +import static uk.gov.hmcts.reform.civil.callback.CallbackParams.Params.BEARER_TOKEN; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.DEFENDANT_RESPONSE_SPEC; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORONE; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORTWO; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_ONE_LEGAL_REP; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_TWO_LEGAL_REP; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.TWO_V_ONE; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.getMultiPartyScenario; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec.IMMEDIATELY; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.FULL_DEFENCE; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.PART_ADMISSION; +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.dq.Expert.fromSmallClaimExpertDetails; +import static uk.gov.hmcts.reform.civil.service.flowstate.FlowFlag.TWO_RESPONDENT_REPRESENTATIVES; +import static uk.gov.hmcts.reform.civil.utils.ElementUtils.buildElemCaseDocument; +import static uk.gov.hmcts.reform.civil.utils.ElementUtils.wrapElements; +import static uk.gov.hmcts.reform.civil.utils.ExpertUtils.addEventAndDateAddedToRespondentExperts; +import static uk.gov.hmcts.reform.civil.utils.PartyUtils.populateDQPartyIds; +import static uk.gov.hmcts.reform.civil.utils.WitnessUtils.addEventAndDateAddedToRespondentWitnesses; + +@Component +@RequiredArgsConstructor +@Slf4j +public class SetApplicantResponseDeadline implements CaseTask { + + private final UserService userService; + private final CoreCaseUserService coreCaseUserService; + private final FeatureToggleService toggleService; + private final ObjectMapper objectMapper; + private final CaseFlagsInitialiser caseFlagsInitialiser; + private final Time time; + private final DeadlineExtensionCalculatorService deadlineCalculatorService; + private final IStateFlowEngine stateFlowEngine; + private final DeadlinesCalculator deadlinesCalculator; + private final FrcDocumentsUtils frcDocumentsUtils; + private final CourtLocationUtils courtLocationUtils; + private final RespondToClaimSpecUtils respondToClaimSpecUtils; + private final AssignCategoryId assignCategoryId; + private final DQResponseDocumentUtils dqResponseDocumentUtils; + + private static final String DEF2 = "Defendant 2"; + + public CallbackResponse execute(CallbackParams callbackParams) { + CaseData caseData = callbackParams.getCaseData(); + LocalDateTime responseDate = time.now(); + Party updatedRespondent1; + + if (NO.equals(caseData.getSpecAoSApplicantCorrespondenceAddressRequired())) { + updatedRespondent1 = caseData.getRespondent1().toBuilder() + .primaryAddress(caseData.getSpecAoSApplicantCorrespondenceAddressdetails()).build(); + } else { + updatedRespondent1 = caseData.getRespondent1().toBuilder() + .primaryAddress(caseData.getRespondent1Copy().getPrimaryAddress()) + .build(); + } + + if (caseData.getRespondent1Copy() != null) { + updatedRespondent1 = + updatedRespondent1.toBuilder().flags(caseData.getRespondent1Copy().getFlags()).build(); + } + + CaseData.CaseDataBuilder updatedData = caseData.toBuilder() + .respondent1(updatedRespondent1) + .respondent1Copy(null); + + if (respondToClaimSpecUtils.isRespondent2HasSameLegalRep(caseData) + && caseData.getRespondentResponseIsSame() != null && caseData.getRespondentResponseIsSame() == YES) { + updatedData.respondent2ClaimResponseTypeForSpec(caseData.getRespondent1ClaimResponseTypeForSpec()); + updatedData + .respondent2ResponseDate(responseDate); + } + + // if present, persist the 2nd respondent address in the same fashion as above, i.e ignore for 1v1 + if (ofNullable(caseData.getRespondent2()).isPresent() + && ofNullable(caseData.getRespondent2Copy()).isPresent()) { + var updatedRespondent2 = caseData.getRespondent2().toBuilder() + .primaryAddress(caseData.getRespondent2Copy().getPrimaryAddress()) + .flags(caseData.getRespondent2Copy().getFlags()) + .build(); + updatedData.respondent2(updatedRespondent2).respondent2Copy(null); + updatedData.respondent2DetailsForClaimDetailsTab(updatedRespondent2.toBuilder().flags(null).build()); + } + + if (caseData.getDefenceAdmitPartPaymentTimeRouteRequired() != null + && caseData.getDefenceAdmitPartPaymentTimeRouteRequired() == IMMEDIATELY + && ifResponseTypeIsPartOrFullAdmission(caseData)) { + LocalDate whenBePaid = deadlineCalculatorService.calculateExtendedDeadline( + LocalDate.now(), + RespondentResponsePartAdmissionPaymentTimeLRspec.DAYS_TO_PAY_IMMEDIATELY); + updatedData.respondToClaimAdmitPartLRspec(RespondToClaimAdmitPartLRspec.builder() + .whenWillThisAmountBePaid(whenBePaid).build()); + } + + CaseRole respondentTwoCaseRoleToCheck; + + respondentTwoCaseRoleToCheck = RESPONDENTSOLICITORTWO; + + if (solicitorRepresentsOnlyOneOfRespondents(callbackParams, respondentTwoCaseRoleToCheck)) { + updatedData.respondent2ResponseDate(responseDate) + .businessProcess(BusinessProcess.ready(DEFENDANT_RESPONSE_SPEC)); + + if (caseData.getRespondent1ResponseDate() != null) { + updatedData + .applicant1ResponseDeadline(getApplicant1ResponseDeadline(responseDate)); + } + + // 1v1, 2v1 + // represents 1st respondent - need to set deadline if only 1 respondent, + // or wait for 2nd respondent response before setting deadline + // moving statement of truth value to correct field, this was not possible in mid event. + StatementOfTruth statementOfTruth = caseData.getUiStatementOfTruth(); + Respondent2DQ.Respondent2DQBuilder dq = caseData.getRespondent2DQ().toBuilder() + .respondent2DQStatementOfTruth(statementOfTruth); + handleCourtLocationForRespondent2DQ(caseData, updatedData, dq, callbackParams); + updatedData.respondent2DQ(dq.build()); + // resetting statement of truth to make sure it's empty the next time it appears in the UI. + updatedData.uiStatementOfTruth(StatementOfTruth.builder().build()); + } else { + updatedData + .respondent1ResponseDate(responseDate) + .applicant1ResponseDeadline(getApplicant1ResponseDeadline(responseDate)) + .businessProcess(BusinessProcess.ready(DEFENDANT_RESPONSE_SPEC)); + + if (caseData.getRespondent2() != null && caseData.getRespondent2Copy() != null) { + Party updatedRespondent2; + + if (NO.equals(caseData.getSpecAoSRespondent2HomeAddressRequired())) { + updatedRespondent2 = caseData.getRespondent2().toBuilder() + .primaryAddress(caseData.getSpecAoSRespondent2HomeAddressDetails()).build(); + } else { + updatedRespondent2 = caseData.getRespondent2().toBuilder() + .primaryAddress(caseData.getRespondent2Copy().getPrimaryAddress()).build(); + } + + updatedData + .respondent2(updatedRespondent2.toBuilder() + .flags(caseData.getRespondent2Copy().getFlags()).build()) + .respondent2Copy(null); + updatedData.respondent2DetailsForClaimDetailsTab(updatedRespondent2.toBuilder().flags(null).build()); + } + + // moving statement of truth value to correct field, this was not possible in mid event. + StatementOfTruth statementOfTruth = caseData.getUiStatementOfTruth(); + Respondent1DQ.Respondent1DQBuilder dq = caseData.getRespondent1DQ().toBuilder() + .respondent1DQStatementOfTruth(statementOfTruth) + .respondent1DQWitnesses(Witnesses.builder() + .witnessesToAppear(caseData.getRespondent1DQWitnessesRequiredSpec()) + .details(caseData.getRespondent1DQWitnessesDetailsSpec()) + .build()); + handleCourtLocationForRespondent1DQ(caseData, dq, callbackParams); + updatedData.respondent1DQ(dq.build()); + // resetting statement of truth to make sure it's empty the next time it appears in the UI. + updatedData.uiStatementOfTruth(StatementOfTruth.builder().build()); + } + if (solicitorHasCaseRole(callbackParams, respondentTwoCaseRoleToCheck) + && FULL_DEFENCE.equals(caseData.getRespondent2ClaimResponseTypeForSpec())) { + updatedData.defenceAdmitPartPaymentTimeRouteRequired(null); + } + + if (caseData.getRespondent1DQWitnessesSmallClaim() != null) { + updatedData.respondent1DQ( + updatedData.build().getRespondent1DQ().toBuilder().respondent1DQWitnesses( + caseData.getRespondent1DQWitnessesSmallClaim()).build()); + } + + if (caseData.getRespondent2DQWitnessesSmallClaim() != null) { + updatedData.respondent2DQ( + updatedData.build().getRespondent2DQ().toBuilder().respondent2DQWitnesses( + caseData.getRespondent2DQWitnessesSmallClaim()).build()); + } + + if (caseData.getRespondent1DQ() != null + && YES.equals(caseData.getResponseClaimExpertSpecRequired()) + && caseData.getRespondent1DQ().getSmallClaimExperts() != null) { + Expert expert = fromSmallClaimExpertDetails(caseData.getRespondent1DQ().getSmallClaimExperts()); + updatedData.respondent1DQ( + updatedData.build().getRespondent1DQ().toBuilder() + .respondent1DQExperts(Experts.builder() + .expertRequired(caseData.getResponseClaimExpertSpecRequired()) + .details(wrapElements(expert)) + .build()) + .build()); + } else if (caseData.getRespondent1DQ() != null + && NO.equals(caseData.getResponseClaimExpertSpecRequired())) { + updatedData.respondent1DQ( + updatedData.build().getRespondent1DQ().toBuilder() + .respondent1DQExperts(Experts.builder() + .expertRequired(caseData.getResponseClaimExpertSpecRequired()) + .build()) + .build()); + } + + if (caseData.getRespondent2DQ() != null + && YES.equals(caseData.getResponseClaimExpertSpecRequired2()) + && caseData.getRespondent2DQ().getSmallClaimExperts() != null) { + Expert expert = fromSmallClaimExpertDetails(caseData.getRespondent2DQ().getSmallClaimExperts()); + updatedData.respondent2DQ( + updatedData.build().getRespondent2DQ().toBuilder() + .respondent2DQExperts(Experts.builder() + .expertRequired(caseData.getResponseClaimExpertSpecRequired2()) + .details(wrapElements(expert)) + .build()) + .build()); + } else if (caseData.getRespondent2DQ() != null + && NO.equals(caseData.getResponseClaimExpertSpecRequired2())) { + updatedData.respondent2DQ( + updatedData.build().getRespondent2DQ().toBuilder() + .respondent2DQExperts(Experts.builder() + .expertRequired(caseData.getResponseClaimExpertSpecRequired()) + .build()) + .build()); + } + + UnavailabilityDatesUtils.rollUpUnavailabilityDatesForRespondent(updatedData, + toggleService.isUpdateContactDetailsEnabled()); + + updatedData.respondent1DetailsForClaimDetailsTab(updatedData.build().getRespondent1().toBuilder().flags(null).build()); + if (ofNullable(caseData.getRespondent2()).isPresent()) { + updatedData.respondent2DetailsForClaimDetailsTab(updatedData.build().getRespondent2().toBuilder().flags(null).build()); + } + + if (toggleService.isUpdateContactDetailsEnabled()) { + addEventAndDateAddedToRespondentExperts(updatedData); + addEventAndDateAddedToRespondentWitnesses(updatedData); + } + + if (toggleService.isHmcEnabled()) { + populateDQPartyIds(updatedData); + } + + caseFlagsInitialiser.initialiseCaseFlags(DEFENDANT_RESPONSE_SPEC, updatedData); + + // casefileview changes need to assign documents into specific folders, this is help determine + // which user is "creating" the document and therefore which folder to move the documents + // into, when directions order is generated in GenerateDirectionsQuestionnaireCallbackHandler + UserInfo userInfo = userService.getUserInfo(callbackParams.getParams().get(BEARER_TOKEN).toString()); + updatedData.respondent2DocumentGeneration(null); + if (!coreCaseUserService.userHasCaseRole(caseData.getCcdCaseReference() + .toString(), userInfo.getUid(), RESPONDENTSOLICITORONE) + && coreCaseUserService.userHasCaseRole(caseData.getCcdCaseReference() + .toString(), userInfo.getUid(), RESPONDENTSOLICITORTWO)) { + updatedData.respondent2DocumentGeneration("userRespondent2"); + } + + updateCorrespondenceAddress(callbackParams, updatedData, caseData); + + if (getMultiPartyScenario(caseData) == ONE_V_TWO_TWO_LEGAL_REP + && isAwaitingAnotherDefendantResponse(caseData)) { + + if (isDefending(caseData)) { + assembleResponseDocumentsSpec(caseData, updatedData); + } + + return AboutToStartOrSubmitCallbackResponse.builder() + .data(updatedData.build().toMap(objectMapper)) + .build(); + } else if (getMultiPartyScenario(caseData) == ONE_V_TWO_TWO_LEGAL_REP + && !isAwaitingAnotherDefendantResponse(caseData)) { + if (!FULL_DEFENCE.equals(caseData.getRespondent1ClaimResponseTypeForSpec()) + || !FULL_DEFENCE.equals(caseData.getRespondent2ClaimResponseTypeForSpec())) { + return AboutToStartOrSubmitCallbackResponse.builder() + .data(updatedData.build().toMap(objectMapper)) + .state(CaseState.PROCEEDS_IN_HERITAGE_SYSTEM.name()) + .build(); + } + } else if (getMultiPartyScenario(caseData) == ONE_V_TWO_ONE_LEGAL_REP && twoVsOneDivergent(caseData)) { + return AboutToStartOrSubmitCallbackResponse.builder() + .data(updatedData.build().toMap(objectMapper)) + .state(CaseState.PROCEEDS_IN_HERITAGE_SYSTEM.name()) + .build(); + } else if (getMultiPartyScenario(caseData) == TWO_V_ONE && twoVsOneDivergent(caseData)) { + return AboutToStartOrSubmitCallbackResponse.builder() + .data(updatedData.build().toMap(objectMapper)) + .state(CaseState.PROCEEDS_IN_HERITAGE_SYSTEM.name()) + .build(); + } + assembleResponseDocumentsSpec(caseData, updatedData); + + return AboutToStartOrSubmitCallbackResponse.builder() + .data(updatedData.build().toMap(objectMapper)) + .state(CaseState.AWAITING_APPLICANT_INTENTION.name()) + .build(); + } + + private boolean ifResponseTypeIsPartOrFullAdmission(CaseData caseData) { + return (RespondentResponseTypeSpec.PART_ADMISSION.equals(caseData.getRespondent1ClaimResponseTypeForSpec()) + || RespondentResponseTypeSpec.PART_ADMISSION.equals( + caseData.getRespondent2ClaimResponseTypeForSpec()) + ) || (RespondentResponseTypeSpec.FULL_ADMISSION.equals(caseData.getRespondent1ClaimResponseTypeForSpec()) + || RespondentResponseTypeSpec.FULL_ADMISSION.equals( + caseData.getRespondent2ClaimResponseTypeForSpec()) + ); + } + + private void updateCorrespondenceAddress(CallbackParams callbackParams, + CaseData.CaseDataBuilder updatedCaseData, + CaseData caseData) { + if (solicitorHasCaseRole(callbackParams, RESPONDENTSOLICITORONE) + && caseData.getSpecAoSRespondentCorrespondenceAddressRequired() == YesOrNo.NO) { + Address newAddress = caseData.getSpecAoSRespondentCorrespondenceAddressdetails(); + updatedCaseData.specRespondentCorrespondenceAddressdetails(newAddress) + .specAoSRespondentCorrespondenceAddressdetails(Address.builder().build()); + if (getMultiPartyScenario(caseData) == ONE_V_TWO_ONE_LEGAL_REP) { + // to keep with heading tab + updatedCaseData.specRespondent2CorrespondenceAddressdetails(newAddress); + } + } else if (solicitorHasCaseRole(callbackParams, RESPONDENTSOLICITORTWO) + && caseData.getSpecAoSRespondent2CorrespondenceAddressRequired() == YesOrNo.NO) { + updatedCaseData.specRespondent2CorrespondenceAddressdetails( + caseData.getSpecAoSRespondent2CorrespondenceAddressdetails()) + .specAoSRespondent2CorrespondenceAddressdetails(Address.builder().build()); + } + } + + private LocalDateTime getApplicant1ResponseDeadline(LocalDateTime responseDate) { + return deadlinesCalculator.calculateApplicantResponseDeadlineSpec(responseDate); + } + + private void handleCourtLocationForRespondent2DQ(CaseData caseData, CaseData.CaseDataBuilder updatedCase, + Respondent2DQ.Respondent2DQBuilder dq, + CallbackParams callbackParams) { + Optional optCourtLocation = getCourtLocationDefendant2(caseData, callbackParams); + if (optCourtLocation.isPresent()) { + LocationRefData courtLocation = optCourtLocation.get(); + dq.respondent2DQRequestedCourt(caseData.getRespondent2DQ().getRespondToCourtLocation2().toBuilder() + .responseCourtLocations(null) + .caseLocation(LocationHelper.buildCaseLocation(courtLocation)) + .responseCourtCode(courtLocation.getCourtLocationCode()).build()) + .respondToCourtLocation2(RequestedCourt.builder() + .responseCourtLocations(null) + .responseCourtCode(courtLocation.getCourtLocationCode()) + .reasonForHearingAtSpecificCourt( + caseData.getRespondent2DQ().getRespondToCourtLocation2() + .getReasonForHearingAtSpecificCourt() + ) + .build()); + updatedCase.responseClaimCourtLocation2Required(YES); + } else { + updatedCase.responseClaimCourtLocation2Required(NO); + } + } + + private void handleCourtLocationForRespondent1DQ(CaseData caseData, + Respondent1DQ.Respondent1DQBuilder dq, + CallbackParams callbackParams) { + Optional optCourtLocation = getCourtLocationDefendant1(caseData, callbackParams); + // data for court location + if (optCourtLocation.isPresent()) { + LocationRefData courtLocation = optCourtLocation.get(); + + dq.respondent1DQRequestedCourt(caseData.getRespondent1DQ() + .getRespondToCourtLocation().toBuilder() + .reasonForHearingAtSpecificCourt( + caseData.getRespondent1DQ() + .getRespondToCourtLocation() + .getReasonForHearingAtSpecificCourt()) + .responseCourtLocations(null) + .caseLocation(LocationHelper.buildCaseLocation(courtLocation)) + .responseCourtCode(courtLocation.getCourtLocationCode()).build()); + dq.respondToCourtLocation(RequestedCourt.builder() + .responseCourtLocations(null) + .responseCourtCode(courtLocation.getCourtLocationCode()) + + .build()) + .responseClaimCourtLocationRequired(YES); + } else { + dq.responseClaimCourtLocationRequired(NO); + } + } + + private boolean solicitorHasCaseRole(CallbackParams callbackParams, CaseRole caseRole) { + CaseData caseData = callbackParams.getCaseData(); + UserInfo userInfo = userService.getUserInfo(callbackParams.getParams().get(BEARER_TOKEN).toString()); + + return coreCaseUserService.userHasCaseRole( + caseData.getCcdCaseReference().toString(), + userInfo.getUid(), + caseRole + ); + } + + private boolean isAwaitingAnotherDefendantResponse(CaseData caseData) { + return caseData.getRespondent1ClaimResponseTypeForSpec() == null + || caseData.getRespondent2ClaimResponseTypeForSpec() == null; + } + + private boolean isDefending(CaseData caseData) { + return FULL_DEFENCE.equals(caseData.getRespondent1ClaimResponseTypeForSpec()) + || FULL_DEFENCE.equals(caseData.getRespondent2ClaimResponseTypeForSpec()) + || PART_ADMISSION.equals(caseData.getRespondent1ClaimResponseTypeForSpec()) + || PART_ADMISSION.equals(caseData.getRespondent2ClaimResponseTypeForSpec() + ); + } + + private void assembleResponseDocumentsSpec(CaseData caseData, CaseData.CaseDataBuilder updatedCaseData) { + List> defendantUploads = nonNull(caseData.getDefendantResponseDocuments()) + ? caseData.getDefendantResponseDocuments() : new ArrayList<>(); + + ResponseDocument respondent1SpecDefenceResponseDocument = caseData.getRespondent1SpecDefenceResponseDocument(); + if (respondent1SpecDefenceResponseDocument != null) { + uk.gov.hmcts.reform.civil.documentmanagement.model.Document respondent1ClaimDocument = respondent1SpecDefenceResponseDocument.getFile(); + if (respondent1ClaimDocument != null) { + Element documentElement = buildElemCaseDocument( + respondent1ClaimDocument, "Defendant", + updatedCaseData.build().getRespondent1ResponseDate(), + DocumentType.DEFENDANT_DEFENCE + ); + assignCategoryId.assignCategoryIdToDocument( + respondent1ClaimDocument, + DocCategory.DEF1_DEFENSE_DQ.getValue() + ); + defendantUploads.add(documentElement); + } + } + Respondent1DQ respondent1DQ = caseData.getRespondent1DQ(); + if (respondent1DQ != null) { + ResponseDocument respondent2SpecDefenceResponseDocument = caseData.getRespondent2SpecDefenceResponseDocument(); + if (respondent2SpecDefenceResponseDocument != null) { + uk.gov.hmcts.reform.civil.documentmanagement.model.Document respondent2ClaimDocument = respondent2SpecDefenceResponseDocument.getFile(); + if (respondent2ClaimDocument != null) { + Element documentElement = buildElemCaseDocument( + respondent2ClaimDocument, DEF2, + updatedCaseData.build().getRespondent2ResponseDate(), + DocumentType.DEFENDANT_DEFENCE + ); + assignCategoryId.assignCategoryIdToDocument( + respondent2ClaimDocument, + DocCategory.DEF2_DEFENSE_DQ.getValue() + ); + defendantUploads.add(documentElement); + } + } + } else { + ResponseDocument respondent2SpecDefenceResponseDocument = caseData.getRespondent2SpecDefenceResponseDocument(); + if (respondent2SpecDefenceResponseDocument != null) { + uk.gov.hmcts.reform.civil.documentmanagement.model.Document respondent2ClaimDocument = respondent2SpecDefenceResponseDocument.getFile(); + if (respondent2ClaimDocument != null) { + Element documentElement = buildElemCaseDocument( + respondent2ClaimDocument, DEF2, + updatedCaseData.build().getRespondent2ResponseDate(), + DocumentType.DEFENDANT_DEFENCE + ); + assignCategoryId.assignCategoryIdToDocument( + respondent2ClaimDocument, + DocCategory.DEF2_DEFENSE_DQ.getValue() + ); + CaseDocument copy = assignCategoryId + .copyCaseDocumentWithCategoryId(documentElement.getValue(), DocCategory.DQ_DEF2.getValue()); + defendantUploads.add(documentElement); + if (Objects.nonNull(copy)) { + defendantUploads.add(ElementUtils.element(copy)); + } + } + } + } + + List> additionalDocuments = dqResponseDocumentUtils.buildDefendantResponseDocuments(updatedCaseData.build()); + defendantUploads.addAll(additionalDocuments); + + if (!defendantUploads.isEmpty()) { + updatedCaseData.defendantResponseDocuments(defendantUploads); + } + + frcDocumentsUtils.assembleDefendantsFRCDocuments(caseData); + clearTempDocuments(updatedCaseData); + } + + private boolean twoVsOneDivergent(CaseData caseData) { + return (!FULL_DEFENCE.equals(caseData.getClaimant1ClaimResponseTypeForSpec()) + && FULL_DEFENCE.equals(caseData.getClaimant2ClaimResponseTypeForSpec())) + || (!FULL_DEFENCE.equals(caseData.getClaimant2ClaimResponseTypeForSpec()) + && FULL_DEFENCE.equals(caseData.getClaimant1ClaimResponseTypeForSpec())); + } + + private Optional getCourtLocationDefendant2(CaseData caseData, CallbackParams callbackParams) { + if (caseData.getRespondent2DQ() != null + && caseData.getRespondent2DQ().getRespondToCourtLocation2() != null) { + DynamicList courtLocations = caseData + .getRespondent2DQ().getRespondToCourtLocation2().getResponseCourtLocations(); + LocationRefData courtLocation = courtLocationUtils.findPreferredLocationData( + respondToClaimSpecUtils.getLocationData(callbackParams), courtLocations); + return Optional.ofNullable(courtLocation); + } else { + return Optional.empty(); + } + } + + private Optional getCourtLocationDefendant1(CaseData caseData, CallbackParams callbackParams) { + if (caseData.getRespondent1DQ() != null + && caseData.getRespondent1DQ().getRespondToCourtLocation() != null) { + DynamicList courtLocations = caseData + .getRespondent1DQ().getRespondToCourtLocation().getResponseCourtLocations(); + LocationRefData courtLocation = courtLocationUtils.findPreferredLocationData( + respondToClaimSpecUtils.getLocationData(callbackParams), courtLocations); + return Optional.ofNullable(courtLocation); + } else { + return Optional.empty(); + } + } + + private void clearTempDocuments(CaseData.CaseDataBuilder builder) { + CaseData caseData = builder.build(); + // these documents are added to defendantUploads, if we do not remove/null the original, + // case file view will show duplicate documents + builder.respondent1SpecDefenceResponseDocument(null); + builder.respondent2SpecDefenceResponseDocument(null); + + if (nonNull(caseData.getRespondent1DQ())) { + builder.respondent1DQ(builder.build().getRespondent1DQ().toBuilder().respondent1DQDraftDirections(null).build()); + } + if (nonNull(caseData.getRespondent2DQ())) { + builder.respondent2DQ(builder.build().getRespondent2DQ().toBuilder().respondent2DQDraftDirections(null).build()); + } + } + + private boolean solicitorRepresentsOnlyOneOfRespondents(CallbackParams callbackParams, CaseRole caseRole) { + CaseData caseData = callbackParams.getCaseData(); + UserInfo userInfo = userService.getUserInfo(callbackParams.getParams().get(BEARER_TOKEN).toString()); + + return stateFlowEngine.evaluate(caseData).isFlagSet(TWO_RESPONDENT_REPRESENTATIVES) + && coreCaseUserService.userHasCaseRole( + caseData.getCcdCaseReference().toString(), + userInfo.getUid(), + caseRole + ); + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/SetGenericResponseTypeFlag.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/SetGenericResponseTypeFlag.java new file mode 100644 index 00000000000..60442c8e71c --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/SetGenericResponseTypeFlag.java @@ -0,0 +1,487 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +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.CallbackParams; +import uk.gov.hmcts.reform.civil.enums.MultiPartyResponseTypeFlags; +import uk.gov.hmcts.reform.civil.enums.MultiPartyScenario; +import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec; +import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpecPaidStatus; +import uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag; +import uk.gov.hmcts.reform.civil.handler.callback.user.task.CaseTask; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; +import uk.gov.hmcts.reform.civil.service.UserService; +import uk.gov.hmcts.reform.idam.client.models.UserInfo; + +import java.util.EnumSet; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +import static uk.gov.hmcts.reform.civil.callback.CallbackParams.Params.BEARER_TOKEN; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORTWO; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_ONE; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_ONE_LEGAL_REP; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_TWO_LEGAL_REP; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.TWO_V_ONE; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.getMultiPartyScenario; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec.IMMEDIATELY; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.FULL_ADMISSION; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.FULL_DEFENCE; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.PART_ADMISSION; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_2; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.CURRENT_ADMITS_PART_OR_FULL; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.NEED_FINANCIAL_DETAILS_1; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.NEED_FINANCIAL_DETAILS_2; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.ONLY_RESPONDENT_1_DISPUTES; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.REPAYMENT_PLAN_2; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.RESPONDENT_1_ADMITS_PART_OR_FULL; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.RESPONDENT_2_ADMITS_PART_OR_FULL; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.SOMEONE_DISPUTES; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.WHEN_WILL_CLAIM_BE_PAID; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.WHY_2_DOES_NOT_PAY_IMMEDIATELY; + +@Component +@RequiredArgsConstructor +@Slf4j +public class SetGenericResponseTypeFlag implements CaseTask { + + private final ObjectMapper objectMapper; + private final UserService userService; + private final CoreCaseUserService coreCaseUserService; + private final RespondToClaimSpecUtils respondToClaimSpecUtilsDisputeDetails; + + private static final String UNKNOWN_MP_SCENARIO = "Unknown mp scenario"; + + public CallbackResponse execute(CallbackParams callbackParams) { + CaseData caseData = callbackParams.getCaseData(); + CaseData.CaseDataBuilder updatedData = + caseData.toBuilder().multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.NOT_FULL_DEFENCE); + + setFlagBasedOnClaimants(caseData, updatedData); + MultiPartyScenario multiPartyScenario = getMultiPartyScenario(caseData); + handleMultiPartyScenario(caseData, updatedData, multiPartyScenario); + setSpecFullAdmissionOrPartAdmission(caseData, updatedData, multiPartyScenario); + handleLegalRepScenario(callbackParams, caseData, updatedData, multiPartyScenario); + setFullDefenceFlags(caseData, updatedData); + setShowHowToAddTimeLinePage(caseData, updatedData); + setPartOrFullAdmissionFlags(caseData, updatedData); + updateShowConditionFlags(caseData, updatedData); + additionalFlagSettings(caseData, updatedData); + + return AboutToStartOrSubmitCallbackResponse.builder() + .data(updatedData.build().toMap(objectMapper)) + .build(); + } + + private void setFlagBasedOnClaimants(CaseData caseData, CaseData.CaseDataBuilder updatedData) { + if (isClaimant1ConditionMet(caseData) && isClaimant2ConditionMet(caseData)) { + updatedData.multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.COUNTER_ADMIT_OR_ADMIT_PART); + } + } + + private boolean isClaimant1ConditionMet(CaseData caseData) { + return RespondentResponseTypeSpec.FULL_ADMISSION == caseData.getClaimant1ClaimResponseTypeForSpec() + || RespondentResponseTypeSpec.PART_ADMISSION == caseData.getClaimant1ClaimResponseTypeForSpec() + || RespondentResponseTypeSpec.COUNTER_CLAIM == caseData.getClaimant1ClaimResponseTypeForSpec(); + } + + private boolean isClaimant2ConditionMet(CaseData caseData) { + return RespondentResponseTypeSpec.FULL_ADMISSION == caseData.getClaimant2ClaimResponseTypeForSpec() + || RespondentResponseTypeSpec.PART_ADMISSION == caseData.getClaimant2ClaimResponseTypeForSpec() + || RespondentResponseTypeSpec.COUNTER_CLAIM == caseData.getClaimant2ClaimResponseTypeForSpec(); + } + + private void handleMultiPartyScenario(CaseData caseData, CaseData.CaseDataBuilder updatedData, MultiPartyScenario scenario) { + if (ONE_V_ONE == scenario) { + handleOneVOneScenario(caseData, updatedData); + } + } + + private void handleOneVOneScenario(CaseData caseData, CaseData.CaseDataBuilder updatedData) { + updatedData.respondentClaimResponseTypeForSpecGeneric(caseData.getRespondent1ClaimResponseTypeForSpec()); + RespondentResponseTypeSpec respondent1Response = caseData.getRespondent1ClaimResponseTypeForSpec(); + + if (RespondentResponseTypeSpec.FULL_DEFENCE == respondent1Response) { + updatedData.multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.FULL_DEFENCE); + } else if (RespondentResponseTypeSpec.COUNTER_CLAIM == respondent1Response) { + updatedData.multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.COUNTER_ADMIT_OR_ADMIT_PART); + } else if (RespondentResponseTypeSpec.FULL_ADMISSION == respondent1Response + || RespondentResponseTypeSpec.FULL_ADMISSION == caseData.getRespondent2ClaimResponseTypeForSpec()) { + updatedData.multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.FULL_ADMISSION); + } + } + + private void handleOneVOneScenario(CaseData caseData, Set tags) { + if (caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION) { + tags.add(ONLY_RESPONDENT_1_DISPUTES); + } + } + + private void handleTwoVOneScenario(CaseData caseData, Set tags) { + if ((caseData.getDefendantSingleResponseToBothClaimants() == YES + && caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION) + || caseData.getClaimant1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION + || caseData.getClaimant2ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION) { + tags.add(ONLY_RESPONDENT_1_DISPUTES); + } + } + + private void handleOneVTwoOneLegalRepScenario(CaseData caseData, Set tags) { + if (caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION) { + if (caseData.getRespondentResponseIsSame() == YES + || caseData.getRespondent2ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION) { + tags.add(DefendantResponseShowTag.BOTH_RESPONDENTS_DISPUTE); + } else { + tags.add(ONLY_RESPONDENT_1_DISPUTES); + } + } else if (caseData.getRespondent2ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION) { + tags.add(DefendantResponseShowTag.ONLY_RESPONDENT_2_DISPUTES); + } + } + + private void handleOneVTwoOneLegalRepScenario(CaseData caseData, CaseData.CaseDataBuilder updatedData) { + if (isSameResponse(caseData)) { + handleSameResponse(caseData, updatedData); + } else { + handleDifferentResponses(caseData, updatedData); + } + } + + private void handleOneVTwoTwoLegalRepScenario(CaseData caseData, Set tags) { + if (caseData.getShowConditionFlags().contains(DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1) + && caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION) { + tags.add(ONLY_RESPONDENT_1_DISPUTES); + } else if (caseData.getShowConditionFlags().contains(DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_2) + && caseData.getRespondent2ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.PART_ADMISSION) { + tags.add(DefendantResponseShowTag.ONLY_RESPONDENT_2_DISPUTES); + } + } + + private void handleOneVTwoTwoLegalRepScenario(CallbackParams callbackParams, CaseData caseData, CaseData.CaseDataBuilder updatedData) { + UserInfo userInfo = userService.getUserInfo(callbackParams.getParams().get(BEARER_TOKEN).toString()); + if (coreCaseUserService.userHasCaseRole(caseData.getCcdCaseReference().toString(), userInfo.getUid(), RESPONDENTSOLICITORTWO)) { + updatedData.respondentClaimResponseTypeForSpecGeneric(caseData.getRespondent2ClaimResponseTypeForSpec()); + } else { + updatedData.respondentClaimResponseTypeForSpecGeneric(caseData.getRespondent1ClaimResponseTypeForSpec()); + } + + RespondentResponseTypeSpec respondent1Response = caseData.getRespondent1ClaimResponseTypeForSpec(); + RespondentResponseTypeSpec respondent2Response = caseData.getRespondent2ClaimResponseTypeForSpec(); + if ((YES.equals(caseData.getIsRespondent1()) && RespondentResponseTypeSpec.PART_ADMISSION == respondent1Response) + || (YES.equals(caseData.getIsRespondent2()) && RespondentResponseTypeSpec.PART_ADMISSION == respondent2Response)) { + updatedData.multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.PART_ADMISSION); + } + } + + private void setSpecFullAdmissionOrPartAdmission(CaseData caseData, CaseData.CaseDataBuilder updatedData, MultiPartyScenario scenario) { + Set someAdmission = EnumSet.of(PART_ADMISSION, FULL_ADMISSION); + if (TWO_V_ONE == scenario + && someAdmission.contains(caseData.getRespondent1ClaimResponseTypeForSpec()) + && someAdmission.contains(caseData.getRespondent2ClaimResponseTypeForSpec())) { + updatedData.specFullAdmissionOrPartAdmission(YES); + } else { + updatedData.specFullAdmissionOrPartAdmission(NO); + } + } + + private void handleLegalRepScenario(CallbackParams callbackParams, CaseData caseData, CaseData.CaseDataBuilder updatedData, MultiPartyScenario scenario) { + if (ONE_V_TWO_ONE_LEGAL_REP == scenario) { + handleOneVTwoOneLegalRepScenario(caseData, updatedData); + } else if (ONE_V_TWO_TWO_LEGAL_REP == scenario) { + handleOneVTwoTwoLegalRepScenario(callbackParams, caseData, updatedData); + } + } + + private boolean isSameResponse(CaseData caseData) { + return Objects.equals(caseData.getRespondent1ClaimResponseTypeForSpec(), caseData.getRespondent2ClaimResponseTypeForSpec()); + } + + private void handleSameResponse(CaseData caseData, CaseData.CaseDataBuilder updatedData) { + updatedData.respondentResponseIsSame(YES); + caseData = caseData.toBuilder().respondentResponseIsSame(YES).build(); + updatedData.sameSolicitorSameResponse(YES); + updatedData.respondentClaimResponseTypeForSpecGeneric(caseData.getRespondent1ClaimResponseTypeForSpec()); + setMultiPartyResponseTypeFlags(updatedData, caseData.getRespondent1ClaimResponseTypeForSpec()); + } + + private void handleDifferentResponses(CaseData caseData, CaseData.CaseDataBuilder updatedData) { + updatedData.sameSolicitorSameResponse(NO); + RespondentResponseTypeSpec respondent1Response = caseData.getRespondent1ClaimResponseTypeForSpec(); + RespondentResponseTypeSpec respondent2Response = caseData.getRespondent2ClaimResponseTypeForSpec(); + if (RespondentResponseTypeSpec.FULL_DEFENCE == respondent1Response || RespondentResponseTypeSpec.FULL_DEFENCE == respondent2Response) { + updatedData.respondentClaimResponseTypeForSpecGeneric(RespondentResponseTypeSpec.FULL_DEFENCE); + } + } + + private void setMultiPartyResponseTypeFlags(CaseData.CaseDataBuilder updatedData, RespondentResponseTypeSpec response) { + if (RespondentResponseTypeSpec.FULL_DEFENCE == response || RespondentResponseTypeSpec.COUNTER_CLAIM == response) { + updatedData.multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.FULL_DEFENCE); + } + } + + private void setFullDefenceFlags(CaseData caseData, CaseData.CaseDataBuilder updatedData) { + if (RespondentResponseTypeSpec.FULL_DEFENCE == caseData.getRespondent1ClaimResponseTypeForSpec() + || RespondentResponseTypeSpec.FULL_DEFENCE == caseData.getRespondent2ClaimResponseTypeForSpec() + || RespondentResponseTypeSpec.FULL_DEFENCE == caseData.getClaimant1ClaimResponseTypeForSpec() + || RespondentResponseTypeSpec.FULL_DEFENCE == caseData.getClaimant2ClaimResponseTypeForSpec()) { + updatedData.multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.FULL_DEFENCE); + } + } + + private void setShowHowToAddTimeLinePage(CaseData caseData, CaseData.CaseDataBuilder updatedData) { + if (shouldShowHowToAddTimeLinePage(caseData)) { + updatedData.showHowToAddTimeLinePage(YES); + } + + if (shouldHideHowToAddTimeLinePageForRespondent1(caseData)) { + updatedData.showHowToAddTimeLinePage(NO); + updatedData.multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.COUNTER_ADMIT_OR_ADMIT_PART); + } else if (shouldHideHowToAddTimeLinePageForRespondent2(caseData)) { + updatedData.showHowToAddTimeLinePage(NO); + } + } + + private boolean shouldShowHowToAddTimeLinePage(CaseData caseData) { + return YES.equals(caseData.getSpecPaidLessAmountOrDisputesOrPartAdmission()) + && !MultiPartyResponseTypeFlags.COUNTER_ADMIT_OR_ADMIT_PART.equals(caseData.getMultiPartyResponseTypeFlags()) + && !RespondentResponseTypeSpecPaidStatus.PAID_FULL_OR_MORE_THAN_CLAIMED_AMOUNT + .equals(caseData.getRespondent1ClaimResponsePaymentAdmissionForSpec()); + } + + private boolean shouldHideHowToAddTimeLinePageForRespondent1(CaseData caseData) { + return YES.equals(caseData.getIsRespondent1()) + && RespondentResponseTypeSpec.COUNTER_CLAIM == caseData.getRespondent1ClaimResponseTypeForSpec(); + } + + private boolean shouldHideHowToAddTimeLinePageForRespondent2(CaseData caseData) { + return YES.equals(caseData.getIsRespondent2()) + && RespondentResponseTypeSpec.COUNTER_CLAIM == caseData.getRespondent2ClaimResponseTypeForSpec() + || RespondentResponseTypeSpec.FULL_ADMISSION == caseData.getRespondent2ClaimResponseTypeForSpec(); + } + + private void setPartOrFullAdmissionFlags(CaseData caseData, CaseData.CaseDataBuilder updatedData) { + if (isPartAdmittedByEitherRespondents(caseData)) { + updatedData.partAdmittedByEitherRespondents(YES); + } else { + updatedData.partAdmittedByEitherRespondents(NO); + } + + if (isFullAdmissionAndFullAmountPaid(caseData)) { + updatedData.fullAdmissionAndFullAmountPaid(YES); + } else { + updatedData.fullAdmissionAndFullAmountPaid(NO); + } + + if (isDefenceAdmitPartPaymentTimeRouteRequired(caseData)) { + updatedData.defenceAdmitPartPaymentTimeRouteGeneric(caseData.getDefenceAdmitPartPaymentTimeRouteRequired()); + } else if (isDefenceAdmitPartPaymentTimeRouteRequired2(caseData)) { + updatedData.defenceAdmitPartPaymentTimeRouteGeneric(caseData.getDefenceAdmitPartPaymentTimeRouteRequired2()); + } else { + updatedData.defenceAdmitPartPaymentTimeRouteGeneric(IMMEDIATELY); + } + } + + private boolean isPartAdmittedByEitherRespondents(CaseData caseData) { + return (YES.equals(caseData.getIsRespondent2()) && YES.equals(caseData.getSpecDefenceAdmittedRequired())) + || (YES.equals(caseData.getIsRespondent1()) && YES.equals(caseData.getSpecDefenceAdmitted2Required())); + } + + private boolean isFullAdmissionAndFullAmountPaid(CaseData caseData) { + return (YES.equals(caseData.getIsRespondent2()) && YES.equals(caseData.getSpecDefenceFullAdmitted2Required())) + || (YES.equals(caseData.getIsRespondent1()) && YES.equals(caseData.getSpecDefenceFullAdmittedRequired())); + } + + private boolean isDefenceAdmitPartPaymentTimeRouteRequired(CaseData caseData) { + return YES.equals(caseData.getIsRespondent1()) && caseData.getDefenceAdmitPartPaymentTimeRouteRequired() != null; + } + + private boolean isDefenceAdmitPartPaymentTimeRouteRequired2(CaseData caseData) { + return YES.equals(caseData.getIsRespondent2()) && caseData.getDefenceAdmitPartPaymentTimeRouteRequired2() != null; + } + + private void updateShowConditionFlags(CaseData caseData, CaseData.CaseDataBuilder updatedData) { + Set updatedShowConditions = whoDisputesPartAdmission(caseData); + EnumSet anyAdmission = EnumSet.of( + RespondentResponseTypeSpec.PART_ADMISSION, + RespondentResponseTypeSpec.FULL_ADMISSION + ); + + if (shouldAddRespondent1AdmitsPartOrFull(caseData, updatedShowConditions, anyAdmission)) { + updatedShowConditions.add(RESPONDENT_1_ADMITS_PART_OR_FULL); + if (YES.equals(caseData.getRespondentResponseIsSame())) { + updatedShowConditions.add(RESPONDENT_2_ADMITS_PART_OR_FULL); + } + } + + if (shouldAddRespondent2AdmitsPartOrFull(caseData, anyAdmission)) { + updatedShowConditions.add(RESPONDENT_2_ADMITS_PART_OR_FULL); + } + + if (someoneDisputes(caseData)) { + updatedShowConditions.add(SOMEONE_DISPUTES); + } + + if (shouldAddCurrentAdmitsPartOrFull(caseData, anyAdmission)) { + updatedShowConditions.removeIf(condition -> condition == CURRENT_ADMITS_PART_OR_FULL); + updatedShowConditions.add(CURRENT_ADMITS_PART_OR_FULL); + } + + updatedData.showConditionFlags(updatedShowConditions); + } + + private boolean shouldAddRespondent1AdmitsPartOrFull(CaseData caseData, Set updatedShowConditions, EnumSet anyAdmission) { + return updatedShowConditions.contains(CAN_ANSWER_RESPONDENT_1) + && anyAdmission.contains(caseData.getRespondent1ClaimResponseTypeForSpec()); + } + + private boolean shouldAddRespondent2AdmitsPartOrFull(CaseData caseData, EnumSet anyAdmission) { + return caseData.getShowConditionFlags().contains(CAN_ANSWER_RESPONDENT_2) + && anyAdmission.contains(caseData.getRespondent2ClaimResponseTypeForSpec()); + } + + private boolean shouldAddCurrentAdmitsPartOrFull(CaseData caseData, EnumSet anyAdmission) { + return (anyAdmission.contains(caseData.getRespondent1ClaimResponseTypeForSpec()) + && YES.equals(caseData.getIsRespondent1())) + || (anyAdmission.contains(caseData.getRespondent2ClaimResponseTypeForSpec()) + && YES.equals(caseData.getIsRespondent2())); + } + + private void additionalFlagSettings(CaseData caseData, CaseData.CaseDataBuilder updatedData) { + if (isSpecFullAdmissionOrPartAdmission(caseData)) { + updatedData.specFullAdmissionOrPartAdmission(YES); + } + + if (isCounterAdmitOrAdmitPart(caseData)) { + updatedData.multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.COUNTER_ADMIT_OR_ADMIT_PART); + } + + if (isSpecFullDefenceOrPartAdmission1V1(caseData)) { + updatedData.specFullDefenceOrPartAdmission1V1(YES); + } + + if (isSpecFullDefenceOrPartAdmission(caseData)) { + updatedData.specFullDefenceOrPartAdmission(YES); + } else { + updatedData.specFullDefenceOrPartAdmission(NO); + } + + if (isSpecDefenceFullAdmittedRequired(caseData)) { + updatedData.specDefenceFullAdmittedRequired(NO); + } + } + + private boolean isSpecFullAdmissionOrPartAdmission(CaseData caseData) { + return (YES.equals(caseData.getIsRespondent1()) + && (RespondentResponseTypeSpec.PART_ADMISSION == caseData.getRespondent1ClaimResponseTypeForSpec() + || RespondentResponseTypeSpec.FULL_ADMISSION == caseData.getRespondent1ClaimResponseTypeForSpec())) + || (YES.equals(caseData.getIsRespondent2()) + && (RespondentResponseTypeSpec.PART_ADMISSION == caseData.getRespondent2ClaimResponseTypeForSpec() + || RespondentResponseTypeSpec.FULL_ADMISSION == caseData.getRespondent2ClaimResponseTypeForSpec())); + } + + private boolean isCounterAdmitOrAdmitPart(CaseData caseData) { + return RespondentResponseTypeSpec.FULL_ADMISSION == caseData.getRespondent2ClaimResponseTypeForSpec() + || RespondentResponseTypeSpec.PART_ADMISSION == caseData.getRespondent2ClaimResponseTypeForSpec() + || RespondentResponseTypeSpec.COUNTER_CLAIM == caseData.getRespondent2ClaimResponseTypeForSpec(); + } + + private boolean isSpecFullDefenceOrPartAdmission1V1(CaseData caseData) { + return RespondentResponseTypeSpec.PART_ADMISSION == caseData.getRespondent1ClaimResponseTypeForSpec() + || RespondentResponseTypeSpec.FULL_DEFENCE == caseData.getRespondent1ClaimResponseTypeForSpec(); + } + + private boolean isSpecFullDefenceOrPartAdmission(CaseData caseData) { + return RespondentResponseTypeSpec.PART_ADMISSION == caseData.getRespondent1ClaimResponseTypeForSpec() + || RespondentResponseTypeSpec.FULL_DEFENCE == caseData.getRespondent1ClaimResponseTypeForSpec() + || RespondentResponseTypeSpec.PART_ADMISSION == caseData.getRespondent2ClaimResponseTypeForSpec() + || RespondentResponseTypeSpec.FULL_DEFENCE == caseData.getRespondent2ClaimResponseTypeForSpec(); + } + + private boolean isSpecDefenceFullAdmittedRequired(CaseData caseData) { + return RespondentResponseTypeSpec.FULL_ADMISSION != caseData.getRespondent1ClaimResponseTypeForSpec() + || RespondentResponseTypeSpec.FULL_ADMISSION != caseData.getRespondent2ClaimResponseTypeForSpec(); + } + + private Set whoDisputesPartAdmission(CaseData caseData) { + Set tags = new HashSet<>(caseData.getShowConditionFlags()); + removeWhoDisputesAndWhoPaidLess(tags); + tags.addAll(whoDisputesBcoPartAdmission(caseData)); + return tags; + } + + private boolean someoneDisputes(CaseData caseData) { + if (TWO_V_ONE.equals(getMultiPartyScenario(caseData))) { + return ((caseData.getClaimant1ClaimResponseTypeForSpec() == FULL_DEFENCE + || caseData.getClaimant2ClaimResponseTypeForSpec() == FULL_DEFENCE) + || caseData.getRespondent1ClaimResponseTypeForSpec() == FULL_DEFENCE + || caseData.getRespondent1ClaimResponseTypeForSpec() == PART_ADMISSION); + } else { + return someoneDisputes(caseData, CAN_ANSWER_RESPONDENT_1, + caseData.getRespondent1ClaimResponseTypeForSpec() + ) + || someoneDisputes(caseData, CAN_ANSWER_RESPONDENT_2, + caseData.getRespondent2ClaimResponseTypeForSpec() + ); + } + } + + private boolean someoneDisputes(CaseData caseData, DefendantResponseShowTag respondent, + RespondentResponseTypeSpec response) { + return caseData.getShowConditionFlags().contains(respondent) + && (response == FULL_DEFENCE + || (response == PART_ADMISSION && !NO.equals(caseData.getRespondentResponseIsSame()))); + } + + private void removeWhoDisputesAndWhoPaidLess(Set tags) { + tags.removeIf(EnumSet.of( + ONLY_RESPONDENT_1_DISPUTES, + DefendantResponseShowTag.ONLY_RESPONDENT_2_DISPUTES, + DefendantResponseShowTag.BOTH_RESPONDENTS_DISPUTE, + SOMEONE_DISPUTES, + DefendantResponseShowTag.CURRENT_ADMITS_PART_OR_FULL, + DefendantResponseShowTag.RESPONDENT_1_PAID_LESS, + DefendantResponseShowTag.RESPONDENT_2_PAID_LESS, + WHEN_WILL_CLAIM_BE_PAID, + RESPONDENT_1_ADMITS_PART_OR_FULL, + RESPONDENT_2_ADMITS_PART_OR_FULL, + NEED_FINANCIAL_DETAILS_1, + NEED_FINANCIAL_DETAILS_2, + DefendantResponseShowTag.WHY_1_DOES_NOT_PAY_IMMEDIATELY, + WHY_2_DOES_NOT_PAY_IMMEDIATELY, + REPAYMENT_PLAN_2, + DefendantResponseShowTag.MEDIATION + )::contains); + } + + private Set whoDisputesBcoPartAdmission(CaseData caseData) { + Set tags = EnumSet.noneOf(DefendantResponseShowTag.class); + MultiPartyScenario mpScenario = getMultiPartyScenario(caseData); + + switch (mpScenario) { + case ONE_V_ONE: + handleOneVOneScenario(caseData, tags); + break; + case TWO_V_ONE: + handleTwoVOneScenario(caseData, tags); + break; + case ONE_V_TWO_ONE_LEGAL_REP: + handleOneVTwoOneLegalRepScenario(caseData, tags); + break; + case ONE_V_TWO_TWO_LEGAL_REP: + handleOneVTwoTwoLegalRepScenario(caseData, tags); + break; + default: + throw new UnsupportedOperationException(UNKNOWN_MP_SCENARIO); + } + return tags; + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/SetUploadTimelineTypeFlag.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/SetUploadTimelineTypeFlag.java new file mode 100644 index 00000000000..6fce3a54d79 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/SetUploadTimelineTypeFlag.java @@ -0,0 +1,85 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +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.CallbackParams; +import uk.gov.hmcts.reform.civil.enums.TimelineUploadTypeSpec; +import uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag; +import uk.gov.hmcts.reform.civil.handler.callback.user.task.CaseTask; +import uk.gov.hmcts.reform.civil.model.CaseData; + +import java.util.EnumSet; +import java.util.HashSet; +import java.util.Set; + +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.TIMELINE_MANUALLY; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.TIMELINE_UPLOAD; + +@Component +@RequiredArgsConstructor +@Slf4j +public class SetUploadTimelineTypeFlag implements CaseTask { + + private final ObjectMapper objectMapper; + + public CallbackResponse execute(CallbackParams callbackParams) { + CaseData caseData = callbackParams.getCaseData(); + Long caseId = caseData.getCcdCaseReference(); + log.info("Executing SetUploadTimelineTypeFlag for case ID: {}", caseId); + + CaseData.CaseDataBuilder updatedData = caseData.toBuilder(); + Set updatedShowConditions = getUpdatedShowConditions(caseData); + + updateShowConditions(caseData, updatedShowConditions); + + updatedData.showConditionFlags(updatedShowConditions); + + log.info("Updated show conditions for case ID {}: {}", caseId, updatedShowConditions); + + return AboutToStartOrSubmitCallbackResponse.builder() + .data(updatedData.build().toMap(objectMapper)) + .build(); + } + + private Set getUpdatedShowConditions(CaseData caseData) { + Set updatedShowConditions = new HashSet<>(caseData.getShowConditionFlags()); + updatedShowConditions.removeIf(EnumSet.of( + TIMELINE_UPLOAD, + TIMELINE_MANUALLY + )::contains); + return updatedShowConditions; + } + + private void updateShowConditions(CaseData caseData, Set updatedShowConditions) { + if (shouldAddTimelineUpload(caseData)) { + log.info("Adding TIMELINE_UPLOAD flag for case ID: {}", caseData.getCcdCaseReference()); + updatedShowConditions.add(TIMELINE_UPLOAD); + } else if (shouldAddTimelineManually(caseData)) { + log.info("Adding TIMELINE_MANUALLY flag for case ID: {}", caseData.getCcdCaseReference()); + updatedShowConditions.add(TIMELINE_MANUALLY); + } + } + + private boolean shouldAddTimelineUpload(CaseData caseData) { + boolean result = (YES.equals(caseData.getIsRespondent1()) + && caseData.getSpecClaimResponseTimelineList() == TimelineUploadTypeSpec.UPLOAD) + || (YES.equals(caseData.getIsRespondent2()) + && caseData.getSpecClaimResponseTimelineList2() == TimelineUploadTypeSpec.UPLOAD); + log.info("Checking shouldAddTimelineUpload for case ID {}: {}", caseData.getCcdCaseReference(), result); + return result; + } + + private boolean shouldAddTimelineManually(CaseData caseData) { + boolean result = (YES.equals(caseData.getIsRespondent1()) + && caseData.getSpecClaimResponseTimelineList() == TimelineUploadTypeSpec.MANUAL) + || (YES.equals(caseData.getIsRespondent2()) + && caseData.getSpecClaimResponseTimelineList2() == TimelineUploadTypeSpec.MANUAL); + log.info("Checking shouldAddTimelineManually for case ID {}: {}", caseData.getCcdCaseReference(), result); + return result; + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateDateOfBirth.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateDateOfBirth.java new file mode 100644 index 00000000000..f4df3fc6e98 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateDateOfBirth.java @@ -0,0 +1,107 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +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.CallbackParams; +import uk.gov.hmcts.reform.civil.enums.YesOrNo; +import uk.gov.hmcts.reform.civil.handler.callback.user.task.CaseTask; +import uk.gov.hmcts.reform.civil.model.Address; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.Party; +import uk.gov.hmcts.reform.civil.validation.DateOfBirthValidator; +import uk.gov.hmcts.reform.civil.validation.PostcodeValidator; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORONE; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORTWO; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_ONE_LEGAL_REP; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_TWO_LEGAL_REP; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.getMultiPartyScenario; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; + +@Component +@RequiredArgsConstructor +@Slf4j +public class ValidateDateOfBirth implements CaseTask { + + private final DateOfBirthValidator dateOfBirthValidator; + private final PostcodeValidator postcodeValidator; + private final ObjectMapper objectMapper; + private final RespondToClaimSpecUtils respondToClaimSpecUtils; + + public CallbackResponse execute(CallbackParams callbackParams) { + CaseData caseData = callbackParams.getCaseData(); + log.info("Executing ValidateDateOfBirth"); + + Party respondent = getRespondent(caseData); + List errors = dateOfBirthValidator.validate(respondent); + errors.addAll(correspondenceAddressCorrect(caseData)); + + CaseData.CaseDataBuilder updatedData = caseData.toBuilder(); + updateSameSolicitorSameResponse(caseData, updatedData, callbackParams); + + log.info("Completed ValidateDateOfBirth"); + return AboutToStartOrSubmitCallbackResponse.builder() + .data(updatedData.build().toMap(objectMapper)) + .errors(errors) + .build(); + } + + private Party getRespondent(CaseData caseData) { + Party respondent = caseData.getRespondent1(); + if (respondent == null && caseData.getRespondent2() != null) { + respondent = caseData.getRespondent2(); + } + return respondent; + } + + private void updateSameSolicitorSameResponse(CaseData caseData, CaseData.CaseDataBuilder updatedData, CallbackParams callbackParams) { + log.info("Updating sameSolicitorSameResponse"); + + if (ONE_V_TWO_TWO_LEGAL_REP.equals(getMultiPartyScenario(caseData)) && YES.equals(caseData.getAddRespondent2())) { + if (respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORTWO) + && respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORONE)) { + updatedData.sameSolicitorSameResponse(YES).build(); + } else { + updatedData.sameSolicitorSameResponse(NO).build(); + } + } else if (ONE_V_TWO_ONE_LEGAL_REP.equals(getMultiPartyScenario(caseData)) && YES.equals(caseData.getAddRespondent2())) { + if (NO.equals(caseData.getRespondentResponseIsSame())) { + updatedData.sameSolicitorSameResponse(NO).build(); + } else { + updatedData.sameSolicitorSameResponse(YES).build(); + } + } + } + + private List correspondenceAddressCorrect(CaseData caseData) { + log.info("Validating correspondence address"); + + if (isRespondent1AddressRequired(caseData)) { + return validatePostcode(caseData.getSpecAoSRespondentCorrespondenceAddressdetails()); + } else if (isRespondent2AddressRequired(caseData)) { + return validatePostcode(caseData.getSpecAoSRespondent2CorrespondenceAddressdetails()); + } + return Collections.emptyList(); + } + + private boolean isRespondent1AddressRequired(CaseData caseData) { + return caseData.getIsRespondent1() == YesOrNo.YES && caseData.getSpecAoSRespondentCorrespondenceAddressRequired() == YesOrNo.NO; + } + + private boolean isRespondent2AddressRequired(CaseData caseData) { + return caseData.getIsRespondent2() == YesOrNo.YES && caseData.getSpecAoSRespondent2CorrespondenceAddressRequired() == YesOrNo.NO; + } + + private List validatePostcode(Address address) { + return postcodeValidator.validate(Optional.ofNullable(address).map(Address::getPostCode).orElse(null)); + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateLengthOfUnemployment.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateLengthOfUnemployment.java new file mode 100644 index 00000000000..be59879ed79 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateLengthOfUnemployment.java @@ -0,0 +1,42 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +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.CallbackParams; +import uk.gov.hmcts.reform.civil.handler.callback.user.task.CaseTask; +import uk.gov.hmcts.reform.civil.model.CaseData; + +import java.util.ArrayList; +import java.util.List; + +@Component +@RequiredArgsConstructor +@Slf4j +public class ValidateLengthOfUnemployment implements CaseTask { + + public CallbackResponse execute(CallbackParams callbackParams) { + log.info("Executing ValidateLengthOfUnemployment task"); + CaseData caseData = callbackParams.getCaseData(); + List errors = new ArrayList<>(); + + if (caseData.getRespondToClaimAdmitPartUnemployedLRspec() != null) { + log.debug("RespondToClaimAdmitPartUnemployedLRspec is not null"); + var lengthOfUnemployment = caseData.getRespondToClaimAdmitPartUnemployedLRspec().getLengthOfUnemployment(); + if (lengthOfUnemployment != null) { + log.debug("LengthOfUnemployment is not null"); + if (lengthOfUnemployment.getNumberOfYearsInUnemployment().contains(".") + || lengthOfUnemployment.getNumberOfMonthsInUnemployment().contains(".")) { + errors.add("Length of time unemployed must be a whole number, for example, 10."); + } + } + } + + log.info("Validation completed with {} errors", errors.size()); + return AboutToStartOrSubmitCallbackResponse.builder() + .errors(errors) + .build(); + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateMediationUnavailableDates.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateMediationUnavailableDates.java new file mode 100644 index 00000000000..0209f842b84 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateMediationUnavailableDates.java @@ -0,0 +1,45 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +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.CallbackParams; +import uk.gov.hmcts.reform.civil.handler.callback.user.task.CaseTask; +import uk.gov.hmcts.reform.civil.model.CaseData; + +import java.util.ArrayList; +import java.util.List; + +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; +import static uk.gov.hmcts.reform.civil.utils.MediationUnavailableDatesUtils.checkUnavailable; + +@Component +@RequiredArgsConstructor +@Slf4j +public class ValidateMediationUnavailableDates implements CaseTask { + + public CallbackResponse execute(CallbackParams callbackParams) { + log.info("Executing ValidateMediationUnavailableDates with callbackParams: {}", callbackParams); + CaseData caseData = callbackParams.getCaseData(); + List errors = new ArrayList<>(); + + if (caseData.getResp1MediationAvailability() != null + && YES.equals(caseData.getResp1MediationAvailability().getIsMediationUnavailablityExists())) { + log.info("Respondent 1 Mediation Unavailability exists. Checking unavailable dates."); + checkUnavailable(errors, caseData.getResp1MediationAvailability().getUnavailableDatesForMediation()); + } else if (caseData.getResp2MediationAvailability() != null + && YES.equals(caseData.getResp2MediationAvailability().getIsMediationUnavailablityExists())) { + log.info("Respondent 2 Mediation Unavailability exists. Checking unavailable dates."); + checkUnavailable(errors, caseData.getResp2MediationAvailability().getUnavailableDatesForMediation()); + } else { + log.info("No Mediation Unavailability exists for Respondent 1 or Respondent 2."); + } + + log.info("Validation errors: {}", errors); + return AboutToStartOrSubmitCallbackResponse.builder() + .errors(errors) + .build(); + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateRespondentExperts.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateRespondentExperts.java new file mode 100644 index 00000000000..53655918b65 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateRespondentExperts.java @@ -0,0 +1,84 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import uk.gov.hmcts.reform.ccd.client.model.CallbackResponse; +import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.enums.CaseRole; +import uk.gov.hmcts.reform.civil.enums.MultiPartyScenario; +import uk.gov.hmcts.reform.civil.handler.callback.user.task.CaseTask; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.validation.interfaces.ExpertsValidator; + +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORONE; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORTWO; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_ONE; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; + +@Component +@RequiredArgsConstructor +@Slf4j +public class ValidateRespondentExperts implements CaseTask, ExpertsValidator { + + private final RespondToClaimSpecUtils respondToClaimSpecUtils; + + public CallbackResponse execute(CallbackParams callbackParams) { + CaseData caseData = callbackParams.getCaseData(); + log.info("Executing validation for case ID: {}", caseData.getCcdCaseReference()); + + if (!ONE_V_ONE.equals(MultiPartyScenario.getMultiPartyScenario(caseData))) { + log.info("Handling multi-party scenario for case ID: {}", caseData.getCcdCaseReference()); + return handleMultiPartyScenario(callbackParams, caseData); + } + + log.info("Validating experts for respondent 1 in case ID: {}", caseData.getCcdCaseReference()); + return validateExperts(caseData.getRespondent1DQ()); + } + + private CallbackResponse handleMultiPartyScenario(CallbackParams callbackParams, CaseData caseData) { + if (isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORONE)) { + log.info("Solicitor represents only respondent 1 in case ID: {}", caseData.getCcdCaseReference()); + return validateExperts(caseData.getRespondent1DQ()); + } else if (isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORTWO)) { + log.info("Solicitor represents only respondent 2 in case ID: {}", caseData.getCcdCaseReference()); + return validateExperts(caseData.getRespondent2DQ()); + } else if (isRespondent2HasDifferentLegalRepAndExperts(caseData)) { + log.info("Respondent 2 has different legal representation and experts in case ID: {}", caseData.getCcdCaseReference()); + return validateExperts(caseData.getRespondent2DQ()); + } + + log.info("Validating experts for respondent 1 in case ID: {}", caseData.getCcdCaseReference()); + return validateExperts(caseData.getRespondent1DQ()); + } + + private boolean isSolicitorRepresentsOnlyOneOfRespondents(CallbackParams callbackParams, CaseRole caseRole) { + boolean result = respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, caseRole); + log.debug("Solicitor represents only one of respondents for case role {}: {}", caseRole, result); + return result; + } + + private boolean isRespondent2HasDifferentLegalRepAndExperts(CaseData caseData) { + boolean result = hasSameLegalRep(caseData) && isRespondentResponseDifferent(caseData) && hasRespondent2Experts(caseData); + log.debug("Respondent 2 has different legal rep and experts: {}", result); + return result; + } + + private boolean hasSameLegalRep(CaseData caseData) { + boolean result = respondToClaimSpecUtils.isRespondent2HasSameLegalRep(caseData); + log.debug("Respondent 2 has same legal rep: {}", result); + return result; + } + + private boolean isRespondentResponseDifferent(CaseData caseData) { + boolean result = caseData.getRespondentResponseIsSame() != null && caseData.getRespondentResponseIsSame() == NO; + log.debug("Respondent response is different: {}", result); + return result; + } + + private boolean hasRespondent2Experts(CaseData caseData) { + boolean result = caseData.getRespondent2DQ() != null && caseData.getRespondent2DQ().getRespondent2DQExperts() != null; + log.debug("Respondent 2 has experts: {}", result); + return result; + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateRespondentPaymentDate.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateRespondentPaymentDate.java new file mode 100644 index 00000000000..3646ef88a2f --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateRespondentPaymentDate.java @@ -0,0 +1,45 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +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.CallbackParams; +import uk.gov.hmcts.reform.civil.handler.callback.user.task.CaseTask; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.RespondToClaimAdmitPartLRspec; +import uk.gov.hmcts.reform.civil.validation.PaymentDateValidator; + +import java.util.List; +import java.util.Optional; + +@Component +@RequiredArgsConstructor +@Slf4j +public class ValidateRespondentPaymentDate implements CaseTask { + + private final PaymentDateValidator paymentDateValidator; + + public CallbackResponse execute(CallbackParams callbackParams) { + CaseData caseData = callbackParams.getCaseData(); + log.info("Executing payment date validation for case ID: {}", caseData.getCcdCaseReference()); + + List errors = paymentDateValidator + .validate(Optional.ofNullable(caseData.getRespondToClaimAdmitPartLRspec()) + .orElseGet(() -> { + log.warn("RespondToClaimAdmitPartLRspec is null for case ID: {}", caseData.getCcdCaseReference()); + return RespondToClaimAdmitPartLRspec.builder().build(); + })); + + if (errors.isEmpty()) { + log.info("Payment date validation passed for case ID: {}", caseData.getCcdCaseReference()); + } else { + log.error("Payment date validation failed for case ID: {} with errors: {}", caseData.getCcdCaseReference(), errors); + } + + return AboutToStartOrSubmitCallbackResponse.builder() + .errors(errors) + .build(); + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateRespondentWitnesses.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateRespondentWitnesses.java new file mode 100644 index 00000000000..f5aefd36458 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateRespondentWitnesses.java @@ -0,0 +1,105 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +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.CallbackParams; +import uk.gov.hmcts.reform.civil.enums.MultiPartyScenario; +import uk.gov.hmcts.reform.civil.handler.callback.user.task.CaseTask; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.validation.interfaces.WitnessesValidator; + +import java.util.ArrayList; +import java.util.List; + +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORONE; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORTWO; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_ONE; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; + +@Component +@RequiredArgsConstructor +@Slf4j +public class ValidateRespondentWitnesses implements CaseTask, WitnessesValidator { + + private final RespondToClaimSpecUtils respondToClaimSpecUtils; + + public CallbackResponse execute(CallbackParams callbackParams) { + log.info("Executing validation for callbackParams"); + CaseData caseData = callbackParams.getCaseData(); + MultiPartyScenario scenario = MultiPartyScenario.getMultiPartyScenario(caseData); + + if (!ONE_V_ONE.equals(scenario)) { + log.info("Handling multi-party scenario"); + return handleMultiPartyScenario(callbackParams, caseData); + } + log.info("Validating R1 witnesses"); + return validateR1Witnesses(caseData); + } + + private CallbackResponse handleMultiPartyScenario(CallbackParams callbackParams, CaseData caseData) { + if (respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents( + callbackParams, + RESPONDENTSOLICITORONE + )) { + log.info("Solicitor represents only one of respondents: RESPONDENTSOLICITORONE"); + return validateR1Witnesses(caseData); + } else if (respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents( + callbackParams, + RESPONDENTSOLICITORTWO + )) { + log.info("Solicitor represents only one of respondents: RESPONDENTSOLICITORTWO"); + return validateWitnesses(caseData.getRespondent2DQ()); + } else if (shouldValidateRespondent2Witnesses(caseData)) { + log.info("Validating respondent 2 witnesses"); + return validateWitnesses(caseData.getRespondent2DQ()); + } + log.info("Defaulting to validate R1 witnesses"); + return validateR1Witnesses(caseData); + } + + private boolean shouldValidateRespondent2Witnesses(CaseData caseData) { + log.info("Checking if should validate respondent 2 witnesses"); + return respondent2HasSameLegalRep(caseData) + && isRespondentResponseDifferent(caseData) + && hasRespondent2DQ(caseData) + && hasRespondent2DQWitnesses(caseData); + } + + private boolean isRespondentResponseDifferent(CaseData caseData) { + log.info("Checking if respondent response is different"); + return caseData.getRespondentResponseIsSame() != null + && caseData.getRespondentResponseIsSame() == NO; + } + + private boolean hasRespondent2DQ(CaseData caseData) { + log.info("Checking if respondent 2 DQ exists"); + return caseData.getRespondent2DQ() != null; + } + + private boolean hasRespondent2DQWitnesses(CaseData caseData) { + log.info("Checking if respondent 2 DQ witnesses exist"); + return caseData.getRespondent2DQ().getRespondent2DQWitnesses() != null; + } + + private CallbackResponse validateR1Witnesses(CaseData caseData) { + List errors = new ArrayList<>(); + if (caseData.getRespondent1DQWitnessesRequiredSpec() == YES + && caseData.getRespondent1DQWitnessesDetailsSpec() == null) { + log.error("Witness details required"); + errors.add("Witness details required"); + } + return AboutToStartOrSubmitCallbackResponse.builder() + .errors(errors) + .build(); + } + + private boolean respondent2HasSameLegalRep(CaseData caseData) { + log.info("Checking if respondent 2 has same legal representative"); + return caseData.getRespondent2SameLegalRepresentative() != null + && caseData.getRespondent2SameLegalRepresentative() == YES; + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateUnavailableDates.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateUnavailableDates.java new file mode 100644 index 00000000000..f7e466f2b73 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandler/ValidateUnavailableDates.java @@ -0,0 +1,53 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +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.CallbackParams; +import uk.gov.hmcts.reform.civil.constants.SpecJourneyConstantLRSpec; +import uk.gov.hmcts.reform.civil.handler.callback.user.task.CaseTask; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.dq.Hearing; +import uk.gov.hmcts.reform.civil.model.dq.SmallClaimHearing; +import uk.gov.hmcts.reform.civil.validation.UnavailableDateValidator; + +import java.util.List; + +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; + +@Component +@RequiredArgsConstructor +@Slf4j +public class ValidateUnavailableDates implements CaseTask { + + private final UnavailableDateValidator unavailableDateValidator; + + public CallbackResponse execute(CallbackParams callbackParams) { + CaseData caseData = callbackParams.getCaseData(); + Long caseId = caseData.getCcdCaseReference(); + log.info("Executing ValidateUnavailableDates for caseId: {}", caseId); + List errors; + + if (SpecJourneyConstantLRSpec.SMALL_CLAIM.equals(caseData.getResponseClaimTrack())) { + log.info("Processing small claim track for caseId: {}", caseId); + SmallClaimHearing smallClaimHearing = caseData.getRespondent1DQ().getRespondent1DQHearingSmallClaim(); + if (YES.equals(caseData.getIsRespondent2())) { + log.info("Respondent 2 is involved, using Respondent 2 DQ hearing small claim for caseId: {}", caseId); + smallClaimHearing = caseData.getRespondent2DQ().getRespondent2DQHearingSmallClaim(); + } + errors = unavailableDateValidator.validateSmallClaimsHearing(smallClaimHearing); + + } else { + log.info("Processing fast claim track for caseId: {}", caseId); + Hearing hearingLRspec = caseData.getRespondent1DQ().getRespondent1DQHearingFastClaim(); + errors = unavailableDateValidator.validateFastClaimHearing(hearingLRspec); + } + + log.info("Validation errors for caseId {}: {}", caseId, errors); + return AboutToStartOrSubmitCallbackResponse.builder() + .errors(errors) + .build(); + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandlerTest.java index 5820eb583c3..e268077598d 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandlerTest.java @@ -38,6 +38,22 @@ import uk.gov.hmcts.reform.civil.enums.YesOrNo; import uk.gov.hmcts.reform.civil.enums.dq.UnavailableDateType; import uk.gov.hmcts.reform.civil.handler.callback.BaseCallbackHandlerTest; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.DetermineLoggedInSolicitor; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.HandleAdmitPartOfClaim; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.HandleDefendAllClaim; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.HandleRespondentResponseTypeForSpec; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.PopulateRespondent1Copy; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.RespondToClaimSpecUtils; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.SetApplicantResponseDeadline; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.SetGenericResponseTypeFlag; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.SetUploadTimelineTypeFlag; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.ValidateDateOfBirth; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.ValidateLengthOfUnemployment; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.ValidateMediationUnavailableDates; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.ValidateRespondentExperts; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.ValidateRespondentPaymentDate; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.ValidateRespondentWitnesses; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.ValidateUnavailableDates; import uk.gov.hmcts.reform.civil.handler.callback.user.spec.RespondToClaimConfirmationHeaderSpecGenerator; import uk.gov.hmcts.reform.civil.handler.callback.user.spec.RespondToClaimConfirmationTextSpecGenerator; import uk.gov.hmcts.reform.civil.handler.callback.user.spec.response.confirmation.CounterClaimConfirmationText; @@ -159,7 +175,23 @@ SimpleStateFlowEngine.class, SimpleStateFlowBuilder.class, AssignCategoryId.class, - FrcDocumentsUtils.class + FrcDocumentsUtils.class, + DetermineLoggedInSolicitor.class, + HandleAdmitPartOfClaim.class, + HandleDefendAllClaim.class, + HandleRespondentResponseTypeForSpec.class, + PopulateRespondent1Copy.class, + RespondToClaimSpecUtils.class, + SetApplicantResponseDeadline.class, + SetGenericResponseTypeFlag.class, + SetUploadTimelineTypeFlag.class, + ValidateMediationUnavailableDates.class, + ValidateUnavailableDates.class, + ValidateDateOfBirth.class, + ValidateRespondentPaymentDate.class, + ValidateLengthOfUnemployment.class, + ValidateRespondentWitnesses.class, + ValidateRespondentExperts.class }) class RespondToClaimSpecCallbackHandlerTest extends BaseCallbackHandlerTest { diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/DetermineLoggedInSolicitorTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/DetermineLoggedInSolicitorTest.java new file mode 100644 index 00000000000..1b52f700fea --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/DetermineLoggedInSolicitorTest.java @@ -0,0 +1,153 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandlertaskstests; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import uk.gov.hmcts.reform.ccd.client.model.AboutToStartOrSubmitCallbackResponse; +import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.enums.YesOrNo; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.DetermineLoggedInSolicitor; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.Party; +import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; +import uk.gov.hmcts.reform.civil.service.UserService; +import uk.gov.hmcts.reform.idam.client.models.UserInfo; + +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; +import static uk.gov.hmcts.reform.civil.callback.CallbackParams.Params.BEARER_TOKEN; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.APPLICANTSOLICITORONE; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORONE; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORTWO; + +@ExtendWith(MockitoExtension.class) +class DetermineLoggedInSolicitorTest { + + @Mock + private UserService userService; + + @Mock + private CoreCaseUserService coreCaseUserService; + + private DetermineLoggedInSolicitor determineLoggedInSolicitor; + + private CallbackParams callbackParams; + + @BeforeEach + void setUp() { + ObjectMapper objectMapper = new ObjectMapper(); + determineLoggedInSolicitor = new DetermineLoggedInSolicitor(userService, coreCaseUserService, objectMapper); + CaseData caseData = CaseData.builder().ccdCaseReference(1234L).build(); + UserInfo userInfo = UserInfo.builder().uid("userId").build(); + callbackParams = CallbackParams.builder() + .caseData(caseData) + .params(Map.of(BEARER_TOKEN, "token")) + .build(); + when(userService.getUserInfo(any())).thenReturn(userInfo); + } + + @Test + void shouldSetRespondent1RoleWhenSolicitorHasRespondent1Role() { + when(coreCaseUserService.userHasCaseRole("1234", "userId", RESPONDENTSOLICITORONE)).thenReturn(true); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(); + + assertRoles(response, "Yes", "No", "No"); + } + + @Test + void shouldSetRespondent2RoleWhenSolicitorHasRespondent2Role() { + when(coreCaseUserService.userHasCaseRole("1234", "userId", RESPONDENTSOLICITORONE)).thenReturn(false); + when(coreCaseUserService.userHasCaseRole("1234", "userId", RESPONDENTSOLICITORTWO)).thenReturn(true); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(); + + assertRoles(response, "No", "Yes", "No"); + } + + @Test + void shouldSetApplicant1RoleWhenSolicitorHasApplicant1Role() { + when(coreCaseUserService.userHasCaseRole("1234", "userId", RESPONDENTSOLICITORONE)).thenReturn(false); + when(coreCaseUserService.userHasCaseRole("1234", "userId", RESPONDENTSOLICITORTWO)).thenReturn(false); + when(coreCaseUserService.userHasCaseRole("1234", "userId", APPLICANTSOLICITORONE)).thenReturn(true); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(); + + assertRoles(response, "No", "No", "Yes"); + } + + @Test + void shouldSetNoRolesWhenSolicitorHasNoRoles() { + when(coreCaseUserService.userHasCaseRole("1234", "userId", RESPONDENTSOLICITORONE)).thenReturn(false); + when(coreCaseUserService.userHasCaseRole("1234", "userId", RESPONDENTSOLICITORTWO)).thenReturn(false); + when(coreCaseUserService.userHasCaseRole("1234", "userId", APPLICANTSOLICITORONE)).thenReturn(false); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(); + + assertRoles(response, null, null, null); + } + + @Test + void shouldSetNeitherCompanyNorOrganisationToNoWhenPartyIsCompany() { + CaseData caseData = buildCaseData(Party.Type.COMPANY); + + callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(); + + assertThat(response.getData()).containsEntry("neitherCompanyNorOrganisation", "No"); + } + + @Test + void shouldSetNeitherCompanyNorOrganisationToNoWhenPartyIsOrganisation() { + CaseData caseData = buildCaseData(Party.Type.ORGANISATION); + + callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(); + + assertThat(response.getData()).containsEntry("neitherCompanyNorOrganisation", "No"); + } + + @Test + void shouldSetNeitherCompanyNorOrganisationToYesWhenPartyIsNeitherCompanyNorOrganisation() { + CaseData caseData = buildCaseData(Party.Type.INDIVIDUAL); + + callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(); + + assertThat(response.getData()).containsEntry("neitherCompanyNorOrganisation", "Yes"); + } + + private AboutToStartOrSubmitCallbackResponse executeCallback() { + return (AboutToStartOrSubmitCallbackResponse) determineLoggedInSolicitor.execute(callbackParams); + } + + private void assertRoles(AboutToStartOrSubmitCallbackResponse response, String isRespondent1, String isRespondent2, String isApplicant1) { + assertThat(response.getData()).containsEntry("isRespondent1", isRespondent1); + assertThat(response.getData()).containsEntry("isRespondent2", isRespondent2); + assertThat(response.getData()).containsEntry("isApplicant1", isApplicant1); + } + + private CaseData buildCaseData(Party.Type partyType) { + return CaseData.builder() + .isRespondent2(YesOrNo.YES) + .respondent2DetailsForClaimDetailsTab(Party.builder().type(partyType).build()) + .ccdCaseReference(1234L) + .build(); + } + + private CallbackParams buildCallbackParams(CaseData caseData) { + return CallbackParams.builder() + .caseData(caseData) + .params(Map.of(BEARER_TOKEN, "token")) + .build(); + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/HandleAdmitPartOfClaimTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/HandleAdmitPartOfClaimTest.java new file mode 100644 index 00000000000..7c2f60dcf54 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/HandleAdmitPartOfClaimTest.java @@ -0,0 +1,1247 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandlertaskstests; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.junit.jupiter.MockitoExtension; +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.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.enums.EmploymentTypeCheckboxFixedListLRspec; +import uk.gov.hmcts.reform.civil.enums.MultiPartyResponseTypeFlags; +import uk.gov.hmcts.reform.civil.enums.MultiPartyScenario; +import uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec; +import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec; +import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpecPaidStatus; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.HandleAdmitPartOfClaim; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.RespondToClaimSpecUtils; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.Party; +import uk.gov.hmcts.reform.civil.service.FeatureToggleService; +import uk.gov.hmcts.reform.civil.validation.PaymentDateValidator; + +import java.math.BigDecimal; +import java.util.Collections; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; +import static uk.gov.hmcts.reform.civil.constants.SpecJourneyConstantLRSpec.DEFENDANT_RESPONSE_SPEC; +import static uk.gov.hmcts.reform.civil.constants.SpecJourneyConstantLRSpec.DISPUTES_THE_CLAIM; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_ONE_LEGAL_REP; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_TWO_LEGAL_REP; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec.BY_SET_DATE; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec.IMMEDIATELY; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec.SUGGESTION_OF_REPAYMENT_PLAN; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.COUNTER_CLAIM; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.FULL_DEFENCE; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.PART_ADMISSION; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_2; + +@ExtendWith(MockitoExtension.class) +class HandleAdmitPartOfClaimTest { + + @Mock + private FeatureToggleService toggleService; + + @Mock + private PaymentDateValidator paymentDateValidator; + + private HandleAdmitPartOfClaim handleAdmitPartOfClaim; + + @Mock + private RespondToClaimSpecUtils respondToClaimSpecUtils; + + @BeforeEach + void setUp() { + ObjectMapper objectMapper = new ObjectMapper(); + handleAdmitPartOfClaim = new HandleAdmitPartOfClaim( + objectMapper, + toggleService, + paymentDateValidator, + respondToClaimSpecUtils + ); + } + + @Test + void shouldReturnErrorResponseWhenPaymentsAreInvalid() { + CallbackParams callbackParams = CallbackParams.builder().caseData(CaseData.builder().build()).build(); + when(paymentDateValidator.validate(any())).thenReturn(List.of("Error")); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertEquals(AboutToStartOrSubmitCallbackResponse.class, response.getClass()); + assertEquals(Collections.singletonList("Error"), ((AboutToStartOrSubmitCallbackResponse) response).getErrors()); + } + + @Test + void shouldReturnSuccessResponseWhenPaymentsAreValid() { + CaseData caseData = CaseData.builder() + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertEquals(AboutToStartOrSubmitCallbackResponse.class, response.getClass()); + assertNull(((AboutToStartOrSubmitCallbackResponse) response).getErrors()); + } + + @Test + void shouldUpdateAdmissionFlagsCorrectly() { + CaseData caseData = CaseData.builder() + .isRespondent1(YES) + .specDefenceFullAdmittedRequired(YES) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey( + "fullAdmissionAndFullAmountPaid")); + assertEquals( + YES.name(), + ((AboutToStartOrSubmitCallbackResponse) response).getData().get("fullAdmissionAndFullAmountPaid").toString().toUpperCase() + ); + } + + @Test + void shouldUpdatePaymentRouteFlagsCorrectly() { + CaseData caseData = CaseData.builder() + .isRespondent1(YES) + .defenceAdmitPartPaymentTimeRouteRequired(IMMEDIATELY) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey( + "defenceAdmitPartPaymentTimeRouteGeneric")); + RespondentResponsePartAdmissionPaymentTimeLRspec actualValue = RespondentResponsePartAdmissionPaymentTimeLRspec.valueOf( + (String) ((AboutToStartOrSubmitCallbackResponse) response).getData().get( + "defenceAdmitPartPaymentTimeRouteGeneric") + ); + assertEquals(IMMEDIATELY, actualValue); + } + + @Test + void shouldUpdateRespondentsAdmissionStatusCorrectly() { + CaseData caseData = CaseData.builder() + .isRespondent2(YES) + .specDefenceAdmitted2Required(YES) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey( + "partAdmittedByEitherRespondents")); + assertEquals( + YES.name(), + ((AboutToStartOrSubmitCallbackResponse) response).getData().get("partAdmittedByEitherRespondents").toString().toUpperCase() + ); + } + + @Test + void shouldUpdateEmploymentTypeCorrectly() { + CaseData caseData = CaseData.builder() + .defenceAdmitPartEmploymentTypeRequired(YES) + .respondToClaimAdmitPartEmploymentTypeLRspec(Collections.singletonList(EmploymentTypeCheckboxFixedListLRspec.EMPLOYED)) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey( + "respondToClaimAdmitPartEmploymentTypeLRspecGeneric")); + List actualList = (List) ((AboutToStartOrSubmitCallbackResponse) response).getData().get( + "respondToClaimAdmitPartEmploymentTypeLRspecGeneric"); + List employmentTypeList = actualList.stream() + .map(item -> EmploymentTypeCheckboxFixedListLRspec.valueOf((String) item)) + .toList(); + assertEquals(Collections.singletonList(EmploymentTypeCheckboxFixedListLRspec.EMPLOYED), employmentTypeList); + } + + @Test + void shouldUpdateClaimOwingAmountsCorrectly() { + CaseData caseData = CaseData.builder() + .respondToAdmittedClaimOwingAmount(BigDecimal.valueOf(1000)) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey( + "respondToAdmittedClaimOwingAmountPounds")); + BigDecimal actualValue = new BigDecimal((String) ((AboutToStartOrSubmitCallbackResponse) response).getData().get( + "respondToAdmittedClaimOwingAmountPounds")); + assertEquals(0, BigDecimal.valueOf(10.0).compareTo(actualValue)); + } + + @Test + void shouldUpdateSpecPaidOrDisputeStatusCorrectly() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponsePaymentAdmissionForSpec(RespondentResponseTypeSpecPaidStatus.PAID_LESS_THAN_CLAIMED_AMOUNT) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey( + "specPaidLessAmountOrDisputesOrPartAdmission")); + assertEquals( + YES.name(), + ((AboutToStartOrSubmitCallbackResponse) response).getData().get( + "specPaidLessAmountOrDisputesOrPartAdmission").toString().toUpperCase() + ); + } + + @Test + void shouldUpdateSpecPaidOrDisputeStatusToNoCorrectly() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponsePaymentAdmissionForSpec(RespondentResponseTypeSpecPaidStatus.PAID_FULL_OR_MORE_THAN_CLAIMED_AMOUNT) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey( + "specPaidLessAmountOrDisputesOrPartAdmission")); + assertEquals( + NO.name(), + ((AboutToStartOrSubmitCallbackResponse) response).getData().get( + "specPaidLessAmountOrDisputesOrPartAdmission").toString().toUpperCase() + ); + } + + /*@Test + void shouldUpdateShowConditionFlagsCorrectly() { + Party respondent1 = Party.builder().type(Party.Type.INDIVIDUAL).build(); + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .showConditionFlags(Collections.singleton(CAN_ANSWER_RESPONDENT_1)) + .defenceAdmitPartPaymentTimeRouteRequired(SUGGESTION_OF_REPAYMENT_PLAN) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .respondent1(respondent1) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + lenient().when(respondToClaimSpecUtils.isWhenWillClaimBePaidShown(any())).thenReturn(true); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn( + ONE_V_TWO_TWO_LEGAL_REP); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey("showConditionFlags")); + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().get("showConditionFlags").toString().contains( + "WHEN_WILL_CLAIM_BE_PAID")); + } + }*/ + + @Test + void shouldUpdateAllocatedTrackCorrectly() { + CaseData caseData = CaseData.builder() + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey("responseClaimTrack")); + assertEquals( + "SMALL_CLAIM", + ((AboutToStartOrSubmitCallbackResponse) response).getData().get("responseClaimTrack") + ); + } + + @Test + void shouldUpdateFullAdmissionAndFullAmountPaidWhenRespondent2AndFullAdmitted2Required() { + CaseData caseData = CaseData.builder() + .isRespondent2(YES) + .specDefenceFullAdmitted2Required(YES) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder() + .eventId(DEFENDANT_RESPONSE_SPEC) + .build(); + + CallbackParams callbackParams = CallbackParams.builder() + .caseData(caseData) + .request(callbackRequest) + .build(); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey( + "fullAdmissionAndFullAmountPaid")); + assertEquals( + YES.name(), + ((AboutToStartOrSubmitCallbackResponse) response).getData().get("fullAdmissionAndFullAmountPaid").toString().toUpperCase() + ); + } + + @Test + void shouldUpdatePaymentRouteFlagsForRespondent2() { + CaseData caseData = CaseData.builder() + .isRespondent2(YES) + .defenceAdmitPartPaymentTimeRouteRequired2(IMMEDIATELY) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder() + .eventId(DEFENDANT_RESPONSE_SPEC) + .build(); + + CallbackParams callbackParams = CallbackParams.builder() + .caseData(caseData) + .request(callbackRequest) + .build(); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey( + "defenceAdmitPartPaymentTimeRouteGeneric")); + RespondentResponsePartAdmissionPaymentTimeLRspec actualValue = RespondentResponsePartAdmissionPaymentTimeLRspec.valueOf( + (String) ((AboutToStartOrSubmitCallbackResponse) response).getData().get( + "defenceAdmitPartPaymentTimeRouteGeneric") + ); + assertEquals(IMMEDIATELY, actualValue); + } + + @Test + void shouldUpdateRespondentsAdmissionStatusForRespondent1() { + CaseData caseData = CaseData.builder() + .isRespondent1(YES) + .specDefenceAdmittedRequired(YES) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder() + .eventId(DEFENDANT_RESPONSE_SPEC) + .build(); + + CallbackParams callbackParams = CallbackParams.builder() + .caseData(caseData) + .request(callbackRequest) + .build(); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey( + "partAdmittedByEitherRespondents")); + assertEquals( + YES.name(), + ((AboutToStartOrSubmitCallbackResponse) response).getData().get("partAdmittedByEitherRespondents").toString().toUpperCase() + ); + } + + @Test + void shouldUpdateEmploymentTypeForRespondent2() { + CaseData caseData = CaseData.builder() + .defenceAdmitPartEmploymentType2Required(YES) + .respondToClaimAdmitPartEmploymentTypeLRspec2(Collections.singletonList( + EmploymentTypeCheckboxFixedListLRspec.EMPLOYED)) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder() + .eventId(DEFENDANT_RESPONSE_SPEC) + .build(); + + CallbackParams callbackParams = CallbackParams.builder() + .caseData(caseData) + .request(callbackRequest) + .build(); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey( + "respondToClaimAdmitPartEmploymentTypeLRspecGeneric")); + List actualList = (List) ((AboutToStartOrSubmitCallbackResponse) response).getData().get( + "respondToClaimAdmitPartEmploymentTypeLRspecGeneric"); + List employmentTypeList = actualList.stream() + .map(item -> EmploymentTypeCheckboxFixedListLRspec.valueOf((String) item)) + .toList(); + assertEquals(Collections.singletonList(EmploymentTypeCheckboxFixedListLRspec.EMPLOYED), employmentTypeList); + } + + @Test + void isPartAdmitNotPaid() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .specDefenceAdmittedRequired(NO) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey("specPartAdmitPaid")); + assertEquals( + NO.name(), + ((AboutToStartOrSubmitCallbackResponse) response).getData().get("specPartAdmitPaid").toString().toUpperCase() + ); + } + + @Test + void isFullAdmitNotPaid() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .specDefenceFullAdmittedRequired(NO) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey("specFullAdmitPaid")); + assertEquals( + NO.name(), + ((AboutToStartOrSubmitCallbackResponse) response).getData().get("specFullAdmitPaid").toString().toUpperCase() + ); + } + + @Test + void isSpecPaidLessOrDisputeWhenDefenceRouteIsDisputeTheClaim() { + CaseData caseData = CaseData.builder() + .defenceRouteRequired(DISPUTES_THE_CLAIM) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey( + "specPaidLessAmountOrDisputesOrPartAdmission")); + assertEquals( + YES.name(), + ((AboutToStartOrSubmitCallbackResponse) response).getData().get( + "specPaidLessAmountOrDisputesOrPartAdmission").toString().toUpperCase() + ); + } + + @Test + void isPartAdmitPaid() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .specDefenceAdmittedRequired(YES) + .specPartAdmitPaid(YES) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey("specPartAdmitPaid")); + assertEquals( + YES.name(), + ((AboutToStartOrSubmitCallbackResponse) response).getData().get("specPartAdmitPaid").toString().toUpperCase() + ); + } + + @Test + void isFullAdmitPaid() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .specDefenceFullAdmittedRequired(YES) + .specFullAdmitPaid(YES) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey("specFullAdmitPaid")); + assertEquals( + YES.name(), + ((AboutToStartOrSubmitCallbackResponse) response).getData().get("specFullAdmitPaid").toString().toUpperCase() + ); + } + + @Test + void shouldNotUpdateAllocatedTrackWhenEventIdIsNotDefendantResponseSpec() { + CaseData caseData = CaseData.builder() + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId("DISPUTES_THE_CLAIM").build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey("responseClaimTrack")); + } + + @Test + void shouldReturnTrueWhenFinancialDetailsNeededForRespondent2() { + Party respondent2 = Party.builder().type(Party.Type.INDIVIDUAL).build(); + CaseData caseData = CaseData.builder() + .isRespondent2(YES) + .respondent2(respondent2) + .showConditionFlags(Collections.singleton(CAN_ANSWER_RESPONDENT_2)) + .defenceAdmitPartPaymentTimeRouteRequired2(SUGGESTION_OF_REPAYMENT_PLAN) + .specDefenceAdmitted2Required(NO) + .respondent2ClaimResponseTypeForSpec(PART_ADMISSION) + .multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.COUNTER_ADMIT_OR_ADMIT_PART) + .sameSolicitorSameResponse(YES) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder() + .eventId(DEFENDANT_RESPONSE_SPEC) + .build(); + + CallbackParams callbackParams = CallbackParams.builder() + .caseData(caseData) + .request(callbackRequest) + .build(); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey("showConditionFlags")); + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().get("showConditionFlags").toString().contains( + "NEED_FINANCIAL_DETAILS_2")); + } + + /*@Test + void shouldReturnTrueWhenAllConditionsAreMet() { + + CaseData caseData = CaseData.builder() + .defenceAdmitPartPaymentTimeRouteRequired(SUGGESTION_OF_REPAYMENT_PLAN) + .specDefenceAdmittedRequired(NO) + .specDefenceFullAdmittedRequired(NO) + .respondentClaimResponseTypeForSpecGeneric(PART_ADMISSION) + .multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.PART_ADMISSION) + .sameSolicitorSameResponse(YES) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder() + .eventId(DEFENDANT_RESPONSE_SPEC) + .build(); + + CallbackParams callbackParams = CallbackParams.builder() + .caseData(caseData) + .request(callbackRequest) + .build(); + + lenient().when(respondToClaimSpecUtils.isWhenWillClaimBePaidShown(any())).thenReturn(true); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey("showConditionFlags")); + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().get("showConditionFlags").toString().contains( + "WHEN_WILL_CLAIM_BE_PAID")); + }*/ + + /*@Test + void shouldAddWhy1DoesNotPayImmediatelyWhenRespondent1DoesNotPayImmediately() { + + Party respondent1 = Party.builder().type(Party.Type.INDIVIDUAL).build(); + CaseData caseData = CaseData.builder() + .isRespondent1(YES) + .respondent1(respondent1) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder() + .eventId(DEFENDANT_RESPONSE_SPEC) + .build(); + + CallbackParams callbackParams = CallbackParams.builder() + .caseData(caseData) + .request(callbackRequest) + .build(); + + when(respondToClaimSpecUtils.isRespondent1DoesNotPayImmediately( + caseData, + MultiPartyScenario.ONE_V_ONE + )).thenReturn(true); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey("showConditionFlags")); + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().get("showConditionFlags").toString().contains( + "WHY_1_DOES_NOT_PAY_IMMEDIATELY")); + }*/ + + /*@Test + void shouldAddWhy2DoesNotPayImmediatelyWhenRespondent2DoesNotPayImmediately() { + + Party respondent2 = Party.builder().type(Party.Type.INDIVIDUAL).build(); + CaseData caseData = CaseData.builder() + .isRespondent2(YES) + .respondent2(respondent2) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder() + .eventId(DEFENDANT_RESPONSE_SPEC) + .build(); + + CallbackParams callbackParams = CallbackParams.builder() + .caseData(caseData) + .request(callbackRequest) + .build(); + + when(respondToClaimSpecUtils.isRespondent2DoesNotPayImmediately(caseData, ONE_V_TWO_TWO_LEGAL_REP)).thenReturn( + true); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey("showConditionFlags")); + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().get("showConditionFlags").toString().contains( + "WHY_2_DOES_NOT_PAY_IMMEDIATELY")); + }*/ + + /*@Test + void shouldUpdateShowConditionFlagsCorrectly_WhenSingleLegalRepresentative() { + Party respondent1 = Party.builder().type(Party.Type.COMPANY).build(); + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .showConditionFlags(Collections.singleton(CAN_ANSWER_RESPONDENT_1)) + .defenceAdmitPartPaymentTimeRouteRequired(SUGGESTION_OF_REPAYMENT_PLAN) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .respondent1(respondent1) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + lenient().when(respondToClaimSpecUtils.isWhenWillClaimBePaidShown(any())).thenReturn(true); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn( + ONE_V_TWO_TWO_LEGAL_REP); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey("showConditionFlags")); + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().get("showConditionFlags").toString().contains( + "WHEN_WILL_CLAIM_BE_PAID")); + } + }*/ + + @Test + void shouldReturnFalseWhenRespondentIsOrganisation() { + + Party respondent1 = Party.builder().type(Party.Type.ORGANISATION).build(); + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .showConditionFlags(Collections.singleton(CAN_ANSWER_RESPONDENT_1)) + .defenceAdmitPartPaymentTimeRouteRequired(SUGGESTION_OF_REPAYMENT_PLAN) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .respondent1(respondent1) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + lenient().when(respondToClaimSpecUtils.isWhenWillClaimBePaidShown(any())).thenReturn(true); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertFalse(((AboutToStartOrSubmitCallbackResponse) response).getData().get("showConditionFlags").toString().contains( + "NEED_FINANCIAL_DETAILS_1")); + } + + @Test + void shouldReturnTrueWhenNonCorporatePartyAndScenarioRequiresInfo() { + + Party respondent1 = Party.builder().type(Party.Type.INDIVIDUAL).build(); + CaseData caseData = CaseData.builder() + .respondent1(respondent1) + .defenceAdmitPartPaymentTimeRouteRequired(SUGGESTION_OF_REPAYMENT_PLAN) + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .sameSolicitorSameResponse(YES) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .showConditionFlags(Collections.singleton(CAN_ANSWER_RESPONDENT_1)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + lenient().when(respondToClaimSpecUtils.isWhenWillClaimBePaidShown(any())).thenReturn(true); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn( + ONE_V_TWO_ONE_LEGAL_REP); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().get("showConditionFlags").toString().contains( + "NEED_FINANCIAL_DETAILS_1")); + } + } + + /*@Test + void shouldShowNeedFinancialDetailsForRespondent1_WhenIndividualRespondentAndOneVTwoOneLegalRep() { + + Party respondent1 = Party.builder().type(Party.Type.INDIVIDUAL).build(); + CaseData caseData = CaseData.builder() + .respondent1(respondent1) + .defenceAdmitPartPaymentTimeRouteRequired(SUGGESTION_OF_REPAYMENT_PLAN) + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .sameSolicitorSameResponse(YES) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .showConditionFlags(Collections.singleton(CAN_ANSWER_RESPONDENT_1)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + lenient().when(respondToClaimSpecUtils.isWhenWillClaimBePaidShown(any())).thenReturn(true); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(TWO_V_ONE); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertFalse(((AboutToStartOrSubmitCallbackResponse) response).getData().get("showConditionFlags").toString().contains( + "NEED_FINANCIAL_DETAILS_1")); + } + }*/ + + @Test + void shouldReturnFalseWhenAnyConditionFailsForNonCorporatePartyAndScenario() { + + Party respondent1 = Party.builder().type(Party.Type.INDIVIDUAL).build(); + CaseData caseData = CaseData.builder() + .respondent1(respondent1) + .defenceAdmitPartPaymentTimeRouteRequired(BY_SET_DATE) + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .specDefenceAdmittedRequired(YES) + .respondentClaimResponseTypeForSpecGeneric(PART_ADMISSION) + .multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.PART_ADMISSION) + .sameSolicitorSameResponse(YES) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .showConditionFlags(Collections.singleton(CAN_ANSWER_RESPONDENT_1)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + lenient().when(respondToClaimSpecUtils.isWhenWillClaimBePaidShown(any())).thenReturn(true); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn( + ONE_V_TWO_ONE_LEGAL_REP); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertFalse(((AboutToStartOrSubmitCallbackResponse) response).getData().get("showConditionFlags").toString().contains( + "NEED_FINANCIAL_DETAILS_1")); + } + } + + @Test + void shouldNotShowNeedFinancialDetailsWhenPaymentRouteBySetDateAndAdmissionRequired() { + Party respondent1 = Party.builder().type(Party.Type.INDIVIDUAL).build(); + CaseData caseData = CaseData.builder() + .respondent1(respondent1) + .defenceAdmitPartPaymentTimeRouteRequired(IMMEDIATELY) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .specDefenceAdmittedRequired(YES) + .specDefenceFullAdmittedRequired(YES) + .multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.COUNTER_ADMIT_OR_ADMIT_PART) + .sameSolicitorSameResponse(YES) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .showConditionFlags(Collections.singleton(CAN_ANSWER_RESPONDENT_1)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + lenient().when(respondToClaimSpecUtils.isWhenWillClaimBePaidShown(any())).thenReturn(true); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn( + ONE_V_TWO_ONE_LEGAL_REP); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertFalse(((AboutToStartOrSubmitCallbackResponse) response).getData().get("showConditionFlags").toString().contains( + "NEED_FINANCIAL_DETAILS_1")); + } + } + + @Test + void shouldNotShowNeedFinancialDetailsWhenFullAdmissionRequiredAndOneVTwoOneLegalRep() { + + Party respondent1 = Party.builder().type(Party.Type.INDIVIDUAL).build(); + CaseData caseData = CaseData.builder() + .respondent1(respondent1) + .defenceAdmitPartPaymentTimeRouteRequired(SUGGESTION_OF_REPAYMENT_PLAN) + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .sameSolicitorSameResponse(YES) + .specDefenceFullAdmittedRequired(YES) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .showConditionFlags(Collections.singleton(CAN_ANSWER_RESPONDENT_1)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + lenient().when(respondToClaimSpecUtils.isWhenWillClaimBePaidShown(any())).thenReturn(true); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn( + ONE_V_TWO_ONE_LEGAL_REP); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertFalse(((AboutToStartOrSubmitCallbackResponse) response).getData().get("showConditionFlags").toString().contains( + "NEED_FINANCIAL_DETAILS_1")); + } + } + + @Test + void shouldAddNeedFinancialDetailsWhenScenarioIsOneVTwoTwoLegalRepAndSameSolicitorResponseIsNo() { + + Party respondent1 = Party.builder().type(Party.Type.INDIVIDUAL).build(); + CaseData caseData = CaseData.builder() + .respondent1(respondent1) + .defenceAdmitPartPaymentTimeRouteRequired(SUGGESTION_OF_REPAYMENT_PLAN) + .respondent1ClaimResponseTypeForSpec(FULL_DEFENCE) + .respondentClaimResponseTypeForSpecGeneric(COUNTER_CLAIM) + .respondentClaimResponseTypeForSpecGeneric(FULL_DEFENCE) + .multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.COUNTER_ADMIT_OR_ADMIT_PART) + .sameSolicitorSameResponse(YES) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .showConditionFlags(Collections.singleton(CAN_ANSWER_RESPONDENT_1)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + lenient().when(respondToClaimSpecUtils.isWhenWillClaimBePaidShown(any())).thenReturn(true); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn( + ONE_V_TWO_ONE_LEGAL_REP); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertFalse(((AboutToStartOrSubmitCallbackResponse) response).getData().get("showConditionFlags").toString().contains( + "NEED_FINANCIAL_DETAILS_1")); + } + } + + @Test + void shouldAddNeedFinancialDetailsWhenRespondent1DoesNotPayImmediatelyInOneVTwoTwoLegalRepScenario() { + + Party respondent1 = Party.builder().type(Party.Type.INDIVIDUAL).build(); + CaseData caseData = CaseData.builder() + .respondent1(respondent1) + .defenceAdmitPartPaymentTimeRouteRequired(SUGGESTION_OF_REPAYMENT_PLAN) + .respondent1ClaimResponseTypeForSpec(FULL_DEFENCE) + .respondentClaimResponseTypeForSpecGeneric(COUNTER_CLAIM) + .multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.NOT_FULL_DEFENCE) + .sameSolicitorSameResponse(YES) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .showConditionFlags(Collections.singleton(CAN_ANSWER_RESPONDENT_1)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + lenient().when(respondToClaimSpecUtils.isWhenWillClaimBePaidShown(any())).thenReturn(true); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn( + ONE_V_TWO_ONE_LEGAL_REP); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertFalse(((AboutToStartOrSubmitCallbackResponse) response).getData().get("showConditionFlags").toString().contains( + "NEED_FINANCIAL_DETAILS_1")); + } + } + + @Test + void shouldNotShowNeedFinancialDetailsWhenScenarioIsOneVTwoOneLegalRepAndOtherConditionsFail() { + + Party respondent1 = Party.builder().type(Party.Type.INDIVIDUAL).build(); + CaseData caseData = CaseData.builder() + .respondent1(respondent1) + .defenceAdmitPartPaymentTimeRouteRequired(SUGGESTION_OF_REPAYMENT_PLAN) + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .multiPartyResponseTypeFlags(MultiPartyResponseTypeFlags.COUNTER_ADMIT_OR_ADMIT_PART) + .sameSolicitorSameResponse(YES) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .showConditionFlags(Collections.singleton(CAN_ANSWER_RESPONDENT_1)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + lenient().when(respondToClaimSpecUtils.isWhenWillClaimBePaidShown(any())).thenReturn(true); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn( + ONE_V_TWO_ONE_LEGAL_REP); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertFalse(((AboutToStartOrSubmitCallbackResponse) response).getData().get("showConditionFlags").toString().contains( + "NEED_FINANCIAL_DETAILS_1")); + } + } + + @Test + void shouldNotShowNeedFinancialDetailsWhenSameSolicitorResponseIsNoInOneVTwoOneLegalRep() { + + Party respondent1 = Party.builder().type(Party.Type.INDIVIDUAL).build(); + CaseData caseData = CaseData.builder() + .respondent1(respondent1) + .defenceAdmitPartPaymentTimeRouteRequired(SUGGESTION_OF_REPAYMENT_PLAN) + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .sameSolicitorSameResponse(NO) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .showConditionFlags(Collections.singleton(CAN_ANSWER_RESPONDENT_1)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + lenient().when(respondToClaimSpecUtils.isWhenWillClaimBePaidShown(any())).thenReturn(true); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn( + ONE_V_TWO_ONE_LEGAL_REP); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertFalse(((AboutToStartOrSubmitCallbackResponse) response).getData().get("showConditionFlags").toString().contains( + "NEED_FINANCIAL_DETAILS_1")); + } + } + + @Test + void shouldShowNeedFinancialDetailsForRespondent2WhenSameSolicitorResponseIsNoInOneVTwoTwoLegalRepScenario() { + + Party respondent1 = Party.builder().type(Party.Type.INDIVIDUAL).build(); + CaseData caseData = CaseData.builder() + .respondent1(respondent1) + .defenceAdmitPartPaymentTimeRouteRequired(SUGGESTION_OF_REPAYMENT_PLAN) + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .sameSolicitorSameResponse(NO) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .showConditionFlags(Collections.singleton(CAN_ANSWER_RESPONDENT_1)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + lenient().when(respondToClaimSpecUtils.isWhenWillClaimBePaidShown(any())).thenReturn(true); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn( + ONE_V_TWO_TWO_LEGAL_REP); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().get("showConditionFlags").toString().contains( + "NEED_FINANCIAL_DETAILS_1")); + } + } + + /*@Test + void shouldUpdateShowConditionFlagsCorrectlyWhenMultipleLegalRepresentatives() { + Party respondent1 = Party.builder().type(Party.Type.INDIVIDUAL).build(); + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .showConditionFlags(Collections.singleton(CAN_ANSWER_RESPONDENT_1)) + .defenceAdmitPartPaymentTimeRouteRequired(IMMEDIATELY) + .specDefenceAdmitted2Required(YES) + .respondentClaimResponseTypeForSpecGeneric(FULL_DEFENCE) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .respondent1(respondent1) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + lenient().when(respondToClaimSpecUtils.isWhenWillClaimBePaidShown(any())).thenReturn(true); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn( + ONE_V_TWO_TWO_LEGAL_REP); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey("showConditionFlags")); + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().get("showConditionFlags").toString().contains( + "WHEN_WILL_CLAIM_BE_PAID")); + } + }*/ + + @Test + void shouldAddNeedFinancialDetails2WhenScenarioIsOneVTwoTwoLegalRepAndSameSolicitorResponseIsNo() { + + Party respondent2 = Party.builder().type(Party.Type.INDIVIDUAL).build(); + CaseData caseData = CaseData.builder() + .respondent2(respondent2) + .defenceAdmitPartPaymentTimeRouteRequired2(SUGGESTION_OF_REPAYMENT_PLAN) + .respondent2ClaimResponseTypeForSpec(PART_ADMISSION) + .sameSolicitorSameResponse(NO) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .showConditionFlags(Collections.singleton(CAN_ANSWER_RESPONDENT_2)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder() + .eventId(DEFENDANT_RESPONSE_SPEC) + .build(); + CallbackParams callbackParams = CallbackParams.builder() + .caseData(caseData) + .request(callbackRequest) + .build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + lenient().when(respondToClaimSpecUtils.isWhenWillClaimBePaidShown(any())).thenReturn(true); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn( + ONE_V_TWO_TWO_LEGAL_REP); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response) + .getData() + .get("showConditionFlags") + .toString() + .contains("NEED_FINANCIAL_DETAILS_2")); + } + } + + @Test + void shouldShowNeedFinancialDetailsForRespondent1ForIndividualRespondentInOneVTwoTwoLegalRepScenario() { + + Party respondent1 = Party.builder().type(Party.Type.INDIVIDUAL).build(); + CaseData caseData = CaseData.builder() + .respondent1(respondent1) + .defenceAdmitPartPaymentTimeRouteRequired(SUGGESTION_OF_REPAYMENT_PLAN) + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .sameSolicitorSameResponse(YES) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .showConditionFlags(Collections.singleton(CAN_ANSWER_RESPONDENT_1)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + lenient().when(respondToClaimSpecUtils.isWhenWillClaimBePaidShown(any())).thenReturn(true); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn( + ONE_V_TWO_TWO_LEGAL_REP); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().get("showConditionFlags").toString().contains( + "NEED_FINANCIAL_DETAILS_1")); + } + } + + @Test + void shouldShowNeedFinancialDetailsForRespondent2WhenFinancialDetailsAreNeededInOneVTwoTwoLegalRep() { + + Party respondent2 = Party.builder().type(Party.Type.INDIVIDUAL).build(); + CaseData caseData = CaseData.builder() + .isRespondent2(YES) + .respondent2(respondent2) + .showConditionFlags(Collections.singleton(CAN_ANSWER_RESPONDENT_2)) + .defenceAdmitPartPaymentTimeRouteRequired2(IMMEDIATELY) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder() + .eventId(DEFENDANT_RESPONSE_SPEC) + .build(); + + CallbackParams callbackParams = CallbackParams.builder() + .caseData(caseData) + .request(callbackRequest) + .build(); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey("showConditionFlags")); + } + + @Test + void shouldShowNeedFinancialDetailsForRespondent2WhenRespondent2HasFullDefenceInOneVTwoTwoLegalRep() { + + Party respondent2 = Party.builder().type(Party.Type.INDIVIDUAL).build(); + CaseData caseData = CaseData.builder() + .isRespondent2(YES) + .respondent2(respondent2) + .showConditionFlags(Collections.singleton(CAN_ANSWER_RESPONDENT_2)) + .respondentClaimResponseTypeForSpecGeneric(FULL_DEFENCE) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder() + .eventId(DEFENDANT_RESPONSE_SPEC) + .build(); + + CallbackParams callbackParams = CallbackParams.builder() + .caseData(caseData) + .request(callbackRequest) + .build(); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey("showConditionFlags")); + } + + /*@Test + void shouldUpdateShowConditionFlagsCorrectlyForRespondentOneWithImmediatePayment() { + Party respondent1 = Party.builder().type(Party.Type.INDIVIDUAL).build(); + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .showConditionFlags(Collections.singleton(CAN_ANSWER_RESPONDENT_1)) + .defenceAdmitPartPaymentTimeRouteRequired(IMMEDIATELY) + .specDefenceFullAdmitted2Required(YES) + .respondentClaimResponseTypeForSpecGeneric(FULL_DEFENCE) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .respondent1(respondent1) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + lenient().when(respondToClaimSpecUtils.isWhenWillClaimBePaidShown(any())).thenReturn(true); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn( + ONE_V_TWO_TWO_LEGAL_REP); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey("showConditionFlags")); + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().get("showConditionFlags").toString().contains( + "WHEN_WILL_CLAIM_BE_PAID")); + } + }*/ + + /*@Test + void shouldUpdateShowConditionFlagsCorrectlyForRespondentOneWithRepaymentPlan() { + Party respondent1 = Party.builder().type(Party.Type.INDIVIDUAL).build(); + CaseData caseData = CaseData.builder() + .respondentClaimResponseTypeForSpecGeneric(COUNTER_CLAIM) + .showConditionFlags(Collections.singleton(CAN_ANSWER_RESPONDENT_1)) + .defenceAdmitPartPaymentTimeRouteRequired(SUGGESTION_OF_REPAYMENT_PLAN) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .respondent1(respondent1) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + lenient().when(respondToClaimSpecUtils.isWhenWillClaimBePaidShown(any())).thenReturn(true); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn( + ONE_V_TWO_TWO_LEGAL_REP); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey("showConditionFlags")); + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().get("showConditionFlags").toString().contains( + "WHEN_WILL_CLAIM_BE_PAID")); + } + }*/ + + @Test + void shouldUpdateSpecPaidOrDisputeStatusToNoCorrectlyWhenFullOrMoreThanClaimedPaid() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponsePaymentAdmissionForSpec(RespondentResponseTypeSpecPaidStatus.PAID_FULL_OR_MORE_THAN_CLAIMED_AMOUNT) + .respondentResponseIsSame(YES) + .defenceAdmitPartPaymentTimeRouteRequired(SUGGESTION_OF_REPAYMENT_PLAN) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey( + "specPaidLessAmountOrDisputesOrPartAdmission")); + assertEquals( + NO.name(), + ((AboutToStartOrSubmitCallbackResponse) response).getData().get( + "specPaidLessAmountOrDisputesOrPartAdmission").toString().toUpperCase() + ); + } + + @Test + void shouldUpdateSpecPaidOrDisputeStatusToNoCorrectlyWhenImmediatePaymentRequired() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponsePaymentAdmissionForSpec(RespondentResponseTypeSpecPaidStatus.PAID_FULL_OR_MORE_THAN_CLAIMED_AMOUNT) + .respondentResponseIsSame(YES) + .defenceAdmitPartPaymentTimeRouteRequired(IMMEDIATELY) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleAdmitPartOfClaim.execute(callbackParams); + + assertTrue(((AboutToStartOrSubmitCallbackResponse) response).getData().containsKey( + "specPaidLessAmountOrDisputesOrPartAdmission")); + assertEquals(NO.name(), ((AboutToStartOrSubmitCallbackResponse) response).getData().get( + "specPaidLessAmountOrDisputesOrPartAdmission").toString().toUpperCase() + ); + } +} + diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/HandleDefendAllClaimTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/HandleDefendAllClaimTest.java new file mode 100644 index 00000000000..006bdf7fc3e --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/HandleDefendAllClaimTest.java @@ -0,0 +1,648 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandlertaskstests; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.junit.jupiter.MockitoExtension; +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.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.constants.SpecJourneyConstantLRSpec; +import uk.gov.hmcts.reform.civil.enums.MultiPartyScenario; +import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec; +import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpecPaidStatus; +import uk.gov.hmcts.reform.civil.enums.YesOrNo; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.HandleDefendAllClaim; +import uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.RespondToClaim; +import uk.gov.hmcts.reform.civil.service.FeatureToggleService; +import uk.gov.hmcts.reform.civil.validation.PaymentDateValidator; + +import java.math.BigDecimal; +import java.util.Collections; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; +import static uk.gov.hmcts.reform.civil.constants.SpecJourneyConstantLRSpec.DEFENDANT_RESPONSE_SPEC; + +@ExtendWith(MockitoExtension.class) +class HandleDefendAllClaimTest { + + @Mock + private FeatureToggleService toggleService; + + @Mock + private PaymentDateValidator paymentDateValidator; + + @InjectMocks + private HandleDefendAllClaim handleDefendAllClaim; + + @BeforeEach + void setUp() { + ObjectMapper objectMapper = new ObjectMapper(); + handleDefendAllClaim = new HandleDefendAllClaim( + objectMapper, + toggleService, + paymentDateValidator + ); + } + + @Test + void shouldReturnErrorResponseWhenPaymentsAreInvalid() { + CaseData caseData = CaseData.builder().build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).build(); + when(paymentDateValidator.validate(any())).thenReturn(List.of("Error")); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertEquals(List.of("Error"), callbackResponse.getErrors()); + } + + @Test + void shouldReturnSuccessResponseWhenPaymentsAreValid() { + CaseData caseData = CaseData.builder() + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertTrue(callbackResponse.getErrors() == null || callbackResponse.getErrors().isEmpty()); + } + + @Test + void shouldUpdateSpecPaidOrDisputeStatusCorrectly() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponsePaymentAdmissionForSpec(RespondentResponseTypeSpecPaidStatus.PAID_LESS_THAN_CLAIMED_AMOUNT) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertTrue(callbackResponse.getData().containsKey("specPaidLessAmountOrDisputesOrPartAdmission")); + assertEquals( + YesOrNo.YES.name(), + callbackResponse.getData().get("specPaidLessAmountOrDisputesOrPartAdmission").toString().toUpperCase() + ); + } + + @Test + void shouldSetSpecDisputesOrPartAdmissionWhenConditionMet() { + CaseData caseData = CaseData.builder() + .isRespondent1(YesOrNo.YES) + .defenceRouteRequired("DISPUTES_THE_CLAIM") + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertTrue(callbackResponse.getData().containsKey("specDisputesOrPartAdmission")); + assertEquals( + YesOrNo.YES.name(), + callbackResponse.getData().get("specDisputesOrPartAdmission").toString().toUpperCase() + ); + } + + @Test + void shouldReturnTrueWhenResponseTypeIsPartAdmission() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertTrue(callbackResponse.getData().containsKey("specDisputesOrPartAdmission")); + assertEquals( + YesOrNo.YES.name(), + callbackResponse.getData().get("specDisputesOrPartAdmission").toString().toUpperCase() + ); + } + + @Test + void shouldReturnTrueWhenRespondent2ResponseTypeIsPartAdmission() { + CaseData caseData = CaseData.builder() + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .isRespondent2(YesOrNo.YES) + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertTrue(callbackResponse.getData().containsKey("specDisputesOrPartAdmission")); + assertEquals( + YesOrNo.YES.name(), + callbackResponse.getData().get("specDisputesOrPartAdmission").toString().toUpperCase() + ); + } + + @Test + void shouldSetSpecDisputesOrPartAdmissionWhenDefenceRouteRequired2IsDispute() { + CaseData caseData = CaseData.builder() + .isRespondent2(YesOrNo.YES) + .defenceRouteRequired2("DISPUTES_THE_CLAIM") + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertTrue(callbackResponse.getData().containsKey("specDisputesOrPartAdmission")); + assertEquals( + YesOrNo.YES.name(), + callbackResponse.getData().get("specDisputesOrPartAdmission").toString().toUpperCase() + ); + } + + @Test + void shouldSetSpecDisputesOrPartAdmissionWhenDefenceRouteRequired2IsDispute1() { + CaseData caseData = CaseData.builder() + .defendantSingleResponseToBothClaimants(YesOrNo.NO) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .defenceRouteRequired("DISPUTES_THE_CLAIM") + .defenceRouteRequired2("DISPUTES_THE_CLAIM") + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertTrue(callbackResponse.getData().containsKey("specDisputesOrPartAdmission")); + assertEquals( + YesOrNo.YES.name(), + callbackResponse.getData().get("specDisputesOrPartAdmission").toString().toUpperCase() + ); + } + + @Test + void shouldHandleTwoVOneWithSeparateResponses() { + CaseData caseData = CaseData.builder() + .totalClaimAmount(BigDecimal.valueOf(1000)) + .defendantSingleResponseToBothClaimants(YesOrNo.NO) + .claimant1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .defenceRouteRequired("DISPUTES_THE_CLAIM") + .claimant2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .defenceRouteRequired2("DISPUTES_THE_CLAIM") + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertTrue(callbackResponse.getData().containsKey("specDisputesOrPartAdmission")); + assertEquals( + YesOrNo.YES.name(), + callbackResponse.getData().get("specDisputesOrPartAdmission").toString().toUpperCase() + ); + } + + @Test + void shouldHandleTwoVOneWithSingleResponse() { + CaseData caseData = CaseData.builder() + .totalClaimAmount(BigDecimal.valueOf(1000)) + .defendantSingleResponseToBothClaimants(YesOrNo.YES) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .defenceRouteRequired("DISPUTES_THE_CLAIM") + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertTrue(callbackResponse.getData().containsKey("specDisputesOrPartAdmission")); + assertEquals( + YesOrNo.YES.name(), + callbackResponse.getData().get("specDisputesOrPartAdmission").toString().toUpperCase() + ); + } + + @Test + void shouldAddTagWhenFullDefenceAndPaidLess() { + CaseData caseData = CaseData.builder() + .claimant1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .defenceRouteRequired("DISPUTES_THE_CLAIM") + .respondToClaim(RespondToClaim.builder().howMuchWasPaid(BigDecimal.valueOf(500)).build()) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertTrue(callbackResponse.getData().containsKey("specDisputesOrPartAdmission")); + assertEquals( + YesOrNo.YES.name(), + callbackResponse.getData().get("specDisputesOrPartAdmission").toString().toUpperCase() + ); + } + + @Test + void shouldHandleTwoVOneScenarioCorrectly() { + CaseData caseData = CaseData.builder() + .totalClaimAmount(BigDecimal.valueOf(1000)) + .defendantSingleResponseToBothClaimants(YesOrNo.NO) + .claimant1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .defenceRouteRequired("DISPUTES_THE_CLAIM") + .claimant2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .defenceRouteRequired2("DISPUTES_THE_CLAIM") + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(MultiPartyScenario.TWO_V_ONE); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertTrue(callbackResponse.getData().containsKey("specDisputesOrPartAdmission")); + assertEquals( + YesOrNo.YES.name(), + callbackResponse.getData().get("specDisputesOrPartAdmission").toString().toUpperCase() + ); + } + } + + @Test + void shouldHandleOneVOneScenarioWhenDefendantSingleResponseToBothClaimantsIsYes() { + CaseData caseData = CaseData.builder() + .totalClaimAmount(BigDecimal.valueOf(1000)) + .defendantSingleResponseToBothClaimants(YesOrNo.YES) + .claimant1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .defenceRouteRequired("DISPUTES_THE_CLAIM") + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(MultiPartyScenario.TWO_V_ONE); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertTrue(callbackResponse.getData().containsKey("specDisputesOrPartAdmission")); + assertEquals( + YesOrNo.YES.name(), + callbackResponse.getData().get("specDisputesOrPartAdmission").toString().toUpperCase() + ); + } + } + + @Test + void shouldHandleOneVTwoOneLegalRepScenarioCorrectly() { + CaseData caseData = CaseData.builder() + .respondentResponseIsSame(YesOrNo.YES) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .defendantSingleResponseToBothClaimants(YesOrNo.NO) + .claimant1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .defenceRouteRequired("DISPUTES_THE_CLAIM") + .claimant2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .defenceRouteRequired2("DISPUTES_THE_CLAIM") + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(MultiPartyScenario.ONE_V_TWO_ONE_LEGAL_REP); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertTrue(callbackResponse.getData().containsKey("specDisputesOrPartAdmission")); + assertEquals( + YesOrNo.YES.name(), + callbackResponse.getData().get("specDisputesOrPartAdmission").toString().toUpperCase() + ); + } + } + + @Test + void shouldHandleOneVTwoTwoLegalRepScenarioCorrectly() { + CaseData caseData = CaseData.builder() + .totalClaimAmount(BigDecimal.valueOf(1000)) + .defendantSingleResponseToBothClaimants(YesOrNo.NO) + .claimant1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .defenceRouteRequired("DISPUTES_THE_CLAIM") + .claimant2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .defenceRouteRequired2("DISPUTES_THE_CLAIM") + .showConditionFlags(Collections.singleton(DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1)) + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(MultiPartyScenario.ONE_V_TWO_TWO_LEGAL_REP); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertTrue(callbackResponse.getData().containsKey("specDisputesOrPartAdmission")); + assertEquals( + YesOrNo.YES.name(), + callbackResponse.getData().get("specDisputesOrPartAdmission").toString().toUpperCase() + ); + } + } + + @Test + void shouldHandleOneVTwoOneLegalRepScenarioWithSingleResponseToBothClaimantsSetToNo() { + CaseData caseData = CaseData.builder() + .respondentResponseIsSame(YesOrNo.NO) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .defendantSingleResponseToBothClaimants(YesOrNo.NO) + .claimant1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .defenceRouteRequired("DISPUTES_THE_CLAIM") + .claimant2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .defenceRouteRequired2("DISPUTES_THE_CLAIM") + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(MultiPartyScenario.ONE_V_TWO_ONE_LEGAL_REP); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertTrue(callbackResponse.getData().containsKey("specDisputesOrPartAdmission")); + assertEquals( + YesOrNo.YES.name(), + callbackResponse.getData().get("specDisputesOrPartAdmission").toString().toUpperCase() + ); + } + } + + @Test + void shouldHandleOneVTwoTwoLegalRepScenarioWithCanAnswerRespondent2() { + CaseData caseData = CaseData.builder() + .totalClaimAmount(BigDecimal.valueOf(1000)) + .defendantSingleResponseToBothClaimants(YesOrNo.NO) + .claimant1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .defenceRouteRequired("DISPUTES_THE_CLAIM") + .claimant2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .defenceRouteRequired2("DISPUTES_THE_CLAIM") + .showConditionFlags(Collections.singleton(DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_2)) + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(MultiPartyScenario.ONE_V_TWO_TWO_LEGAL_REP); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertTrue(callbackResponse.getData().containsKey("specDisputesOrPartAdmission")); + assertEquals( + YesOrNo.YES.name(), + callbackResponse.getData().get("specDisputesOrPartAdmission").toString().toUpperCase() + ); + } + } + + @Test + void shouldAddSomeoneDisputesWhenOnlyRespondent1Disputes() { + CaseData caseData = CaseData.builder() + .showConditionFlags(Collections.singleton(DefendantResponseShowTag.ONLY_RESPONDENT_1_DISPUTES)) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertTrue(callbackResponse.getData().containsKey("specDisputesOrPartAdmission")); + } + + @Test + void shouldAddSomeoneDisputesWhenOnlyRespondent2Disputes() { + CaseData caseData = CaseData.builder() + .showConditionFlags(Collections.singleton(DefendantResponseShowTag.ONLY_RESPONDENT_2_DISPUTES)) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertTrue(callbackResponse.getData().containsKey("specDisputesOrPartAdmission")); + } + + @Test + void shouldAddSomeoneDisputesWhenBothRespondentsDispute() { + CaseData caseData = CaseData.builder() + .showConditionFlags(Collections.singleton(DefendantResponseShowTag.BOTH_RESPONDENTS_DISPUTE)) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertTrue(callbackResponse.getData().containsKey("specDisputesOrPartAdmission")); + } + + @Test + void shouldSetPaidStatusToPaidLessThanClaimedAmountWhenPaidLess() { + CaseData caseData = CaseData.builder() + .defenceRouteRequired(SpecJourneyConstantLRSpec.HAS_PAID_THE_AMOUNT_CLAIMED) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .respondToClaim(RespondToClaim.builder() + .howMuchWasPaid(BigDecimal.valueOf(50_000)) + .build()) + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder() + .eventId(DEFENDANT_RESPONSE_SPEC) + .build(); + CallbackParams callbackParams = CallbackParams.builder() + .caseData(caseData) + .request(callbackRequest) + .build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertTrue(callbackResponse.getData().containsKey("specPaidLessAmountOrDisputesOrPartAdmission")); + } + + @Test + void shouldAddSpecDisputesOrPartAdmissionWhenBothRespondentsDispute() { + CaseData caseData = CaseData.builder() + .showConditionFlags(Collections.singleton(DefendantResponseShowTag.BOTH_RESPONDENTS_DISPUTE)) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder().eventId("HAS_PAID_THE_AMOUNT_CLAIMED").build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertTrue(callbackResponse.getData().containsKey("specDisputesOrPartAdmission")); + } + + @Test + void shouldSetSpecDisputesOrPartAdmissionForOneVTwoTwoLegalRepScenario() { + CaseData caseData = CaseData.builder() + .totalClaimAmount(BigDecimal.valueOf(1000)) + .defendantSingleResponseToBothClaimants(YesOrNo.NO) + .claimant1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .defenceRouteRequired("DISPUTES_THE_CLAIM") + .claimant2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .defenceRouteRequired2("DISPUTES_THE_CLAIM") + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(MultiPartyScenario.ONE_V_TWO_TWO_LEGAL_REP); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertTrue(callbackResponse.getData().containsKey("specDisputesOrPartAdmission")); + assertEquals( + YesOrNo.YES.name(), + callbackResponse.getData().get("specDisputesOrPartAdmission").toString().toUpperCase() + ); + } + } + + @Test + void shouldReturnPaidLessTagWhenPaidLessThanClaimedAmount() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .defenceRouteRequired("HAS_PAID_THE_AMOUNT_CLAIMED") + .totalClaimAmount(BigDecimal.valueOf(1000)) + .respondToClaim(RespondToClaim.builder().howMuchWasPaid(BigDecimal.valueOf(500)).build()) + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertTrue(callbackResponse.getData().containsKey("specPaidLessAmountOrDisputesOrPartAdmission")); + } + + @Test + void shouldNotReturnPaidLessTagWhenPaidEqualOrMoreThanClaimedAmount() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .defenceRouteRequired("HAS_PAID_THE_AMOUNT_CLAIMED") + .respondToClaim(RespondToClaim.builder().howMuchWasPaid(BigDecimal.valueOf(1000)).build()) + .totalClaimAmount(BigDecimal.valueOf(1000)) + .build(); + + CallbackRequest callbackRequest = CallbackRequest.builder().eventId(DEFENDANT_RESPONSE_SPEC).build(); + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).request(callbackRequest).build(); + + when(paymentDateValidator.validate(any())).thenReturn(Collections.emptyList()); + + CallbackResponse response = handleDefendAllClaim.execute(callbackParams); + + AboutToStartOrSubmitCallbackResponse callbackResponse = (AboutToStartOrSubmitCallbackResponse) response; + assertTrue(callbackResponse.getData().containsKey("specPaidLessAmountOrDisputesOrPartAdmission")); + assertEquals( + YesOrNo.NO.name(), + callbackResponse.getData().get("specPaidLessAmountOrDisputesOrPartAdmission").toString().toUpperCase() + ); + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/HandleRespondentResponseTypeForSpecTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/HandleRespondentResponseTypeForSpecTest.java new file mode 100644 index 00000000000..a723a9241ed --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/HandleRespondentResponseTypeForSpecTest.java @@ -0,0 +1,87 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandlertaskstests; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.junit.jupiter.MockitoExtension; +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.CallbackParams; +import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.HandleRespondentResponseTypeForSpec; +import uk.gov.hmcts.reform.civil.model.CaseData; + +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; + +@ExtendWith(MockitoExtension.class) +class HandleRespondentResponseTypeForSpecTest { + + @InjectMocks + private HandleRespondentResponseTypeForSpec handleRespondentResponseTypeForSpec; + + private ObjectMapper objectMapper; + + @BeforeEach + void setUp() { + objectMapper = new ObjectMapper(); + handleRespondentResponseTypeForSpec = new HandleRespondentResponseTypeForSpec(objectMapper); + } + + private void assertSpecDefenceFullAdmittedRequired(CaseData caseData, Object expectedValue) { + CallbackParams callbackParams = CallbackParams.builder().caseData(caseData).build(); + CallbackResponse response = handleRespondentResponseTypeForSpec.execute(callbackParams); + + Map responseData = ((AboutToStartOrSubmitCallbackResponse) response).getData(); + + CaseData updatedCaseData = objectMapper.convertValue(responseData, CaseData.class); + + assertEquals(expectedValue, updatedCaseData.getSpecDefenceFullAdmittedRequired()); + } + + @Test + void shouldSetSpecDefenceFullAdmittedRequiredToNoWhenNotFullAdmission() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .build(); + + assertSpecDefenceFullAdmittedRequired(caseData, NO); + } + + @Test + void shouldNotChangeSpecDefenceFullAdmittedRequiredWhenFullAdmission() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .specDefenceFullAdmittedRequired(YES) + .build(); + + assertSpecDefenceFullAdmittedRequired(caseData, YES); + } + + @Test + void shouldSetSpecDefenceFullAdmittedRequiredToNoWhenRespondent2ResponseTypeIsNull() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .respondent2ClaimResponseTypeForSpec(null) + .build(); + + assertSpecDefenceFullAdmittedRequired(caseData, NO); + } + + @Test + void shouldSetSpecDefenceFullAdmittedRequiredToNoWhenRespondent2ResponseTypeIsNotFullAdmission() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .build(); + + assertSpecDefenceFullAdmittedRequired(caseData, NO); + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/PopulateRespondent1CopyTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/PopulateRespondent1CopyTest.java new file mode 100644 index 00000000000..fd80b1d75c4 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/PopulateRespondent1CopyTest.java @@ -0,0 +1,248 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandlertaskstests; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import uk.gov.hmcts.reform.ccd.client.model.AboutToStartOrSubmitCallbackResponse; +import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.PopulateRespondent1Copy; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.RespondToClaimSpecUtils; +import uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.Party; +import uk.gov.hmcts.reform.civil.model.Party.Type; +import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; +import uk.gov.hmcts.reform.civil.service.FeatureToggleService; +import uk.gov.hmcts.reform.civil.service.UserService; +import uk.gov.hmcts.reform.civil.utils.CourtLocationUtils; +import uk.gov.hmcts.reform.idam.client.models.UserInfo; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; +import static uk.gov.hmcts.reform.civil.callback.CallbackParams.Params.BEARER_TOKEN; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; + +@ExtendWith(MockitoExtension.class) +class PopulateRespondent1CopyTest { + + private PopulateRespondent1Copy populateRespondent1Copy; + + @Mock + private UserService userService; + + @Mock + private CoreCaseUserService coreCaseUserService; + + @Mock + private FeatureToggleService toggleService; + + @Mock + private CourtLocationUtils courtLocationUtils; + + @Mock + private RespondToClaimSpecUtils respondToClaimSpecUtils; + + private ObjectMapper objectMapper; + + private CaseData caseData; + private UserInfo userInfo; + + @BeforeEach + void setUp() { + objectMapper = new ObjectMapper(); + populateRespondent1Copy = new PopulateRespondent1Copy( + userService, + coreCaseUserService, + toggleService, + courtLocationUtils, + objectMapper, + respondToClaimSpecUtils + ); + caseData = CaseData.builder() + .respondent1(Party.builder().type(Type.INDIVIDUAL).build()) + .respondent2(Party.builder().type(Type.INDIVIDUAL).build()) + .ccdCaseReference(1234L) + .build(); + + userInfo = UserInfo.builder() + .uid("testUserId") + .build(); + } + + @Test + void shouldPopulateRespondent1Copy() { + when(toggleService.isCarmEnabledForCase(any())).thenReturn(true); + when(courtLocationUtils.getLocationsFromList(any())).thenReturn(null); + when(userService.getUserInfo(any())).thenReturn(userInfo); + when(coreCaseUserService.getUserCaseRoles(any(), any())).thenReturn(List.of("RESPONDENTSOLICITORONE")); + + Map params = new HashMap<>(); + params.put(BEARER_TOKEN, "testBearerToken"); + + CallbackParams callbackParams = CallbackParams.builder() + .caseData(caseData) + .params(params) + .build(); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) populateRespondent1Copy.execute( + callbackParams); + + Map responseData = response.getData(); + CaseData updatedCaseData = objectMapper.convertValue(responseData, CaseData.class); + assertEquals(caseData.getRespondent1(), updatedCaseData.getRespondent1Copy()); + assertEquals(YES, updatedCaseData.getShowCarmFields()); + } + + @Test + void shouldNotShowCarmFieldsWhenToggleIsDisabled() { + when(toggleService.isCarmEnabledForCase(any())).thenReturn(false); + when(courtLocationUtils.getLocationsFromList(any())).thenReturn(null); + when(userService.getUserInfo(any())).thenReturn(userInfo); + when(coreCaseUserService.getUserCaseRoles(any(), any())).thenReturn(List.of("RESPONDENTSOLICITORONE")); + + Map params = new HashMap<>(); + params.put(BEARER_TOKEN, "testBearerToken"); + + CallbackParams callbackParams = CallbackParams.builder() + .caseData(caseData) + .params(params) + .build(); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) populateRespondent1Copy.execute( + callbackParams); + + Map responseData = response.getData(); + CaseData updatedCaseData = objectMapper.convertValue(responseData, CaseData.class); + assertEquals(NO, updatedCaseData.getShowCarmFields()); + } + + @Test + void shouldHandleOneVTwoTwoLegalRepScenario() { + when(toggleService.isCarmEnabledForCase(any())).thenReturn(true); + when(courtLocationUtils.getLocationsFromList(any())).thenReturn(null); + when(userService.getUserInfo(any())).thenReturn(userInfo); + when(coreCaseUserService.getUserCaseRoles(any(), any())).thenReturn(List.of( + "RESPONDENTSOLICITORONE", + "RESPONDENTSOLICITORTWO" + )); + + Map params = new HashMap<>(); + params.put(BEARER_TOKEN, "testBearerToken"); + + CallbackParams callbackParams = CallbackParams.builder() + .caseData(caseData) + .params(params) + .build(); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) populateRespondent1Copy.execute( + callbackParams); + + Map responseData = response.getData(); + CaseData updatedCaseData = objectMapper.convertValue(responseData, CaseData.class); + assertEquals(caseData.getRespondent1(), updatedCaseData.getRespondent1Copy()); + assertEquals(caseData.getRespondent2(), updatedCaseData.getRespondent2Copy()); + assertEquals(YES, updatedCaseData.getShowCarmFields()); + } + + @Test + void shouldHandleOneVOneScenario() { + when(toggleService.isCarmEnabledForCase(any())).thenReturn(true); + when(courtLocationUtils.getLocationsFromList(any())).thenReturn(null); + + caseData = CaseData.builder() + .respondent1(Party.builder().type(Type.INDIVIDUAL).build()) + .respondent2(null) + .build(); + + Map params = new HashMap<>(); + params.put(BEARER_TOKEN, "testBearerToken"); + + CallbackParams callbackParams = CallbackParams.builder() + .caseData(caseData) + .params(params) + .build(); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) populateRespondent1Copy.execute(callbackParams); + + Map responseData = response.getData(); + CaseData updatedCaseData = objectMapper.convertValue(responseData, CaseData.class); + assertEquals(caseData.getRespondent1(), updatedCaseData.getRespondent1Copy()); + assertNull(updatedCaseData.getRespondent2Copy()); + assertEquals(YES, updatedCaseData.getShowCarmFields()); + } + + @Test + void shouldHandleOneVTwoOneLegalRepScenario() { + when(toggleService.isCarmEnabledForCase(any())).thenReturn(true); + when(courtLocationUtils.getLocationsFromList(any())).thenReturn(null); + + caseData = CaseData.builder() + .respondent1(Party.builder().type(Type.INDIVIDUAL).build()) + .respondent2(Party.builder().type(Type.INDIVIDUAL).build()) + .respondent2SameLegalRepresentative(YES) + .ccdCaseReference(1234L) + .build(); + + Map params = new HashMap<>(); + params.put(BEARER_TOKEN, "testBearerToken"); + + CallbackParams callbackParams = CallbackParams.builder() + .caseData(caseData) + .params(params) + .build(); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) populateRespondent1Copy.execute(callbackParams); + + Map responseData = response.getData(); + CaseData updatedCaseData = objectMapper.convertValue(responseData, CaseData.class); + + assertEquals(caseData.getRespondent1(), updatedCaseData.getRespondent1Copy()); + assertEquals(caseData.getRespondent2(), updatedCaseData.getRespondent2Copy()); + + assertEquals(YES, updatedCaseData.getShowCarmFields()); + } + + @Test + void shouldAddRespondent1TagWhenSolicitorOneRoleIsPresent() { + when(toggleService.isCarmEnabledForCase(any())).thenReturn(true); + when(courtLocationUtils.getLocationsFromList(any())).thenReturn(null); + + caseData = CaseData.builder() + .respondent1(Party.builder().type(Type.INDIVIDUAL).build()) + .respondent2(null) + .ccdCaseReference(1234L) + .build(); + + Map params = new HashMap<>(); + params.put(BEARER_TOKEN, "testBearerToken"); + + CallbackParams callbackParams = CallbackParams.builder() + .caseData(caseData) + .params(params) + .build(); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) populateRespondent1Copy.execute(callbackParams); + + Map responseData = response.getData(); + CaseData updatedCaseData = objectMapper.convertValue(responseData, CaseData.class); + + Set showTags = updatedCaseData.getShowConditionFlags(); + assertTrue(showTags.contains(DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1)); + + assertEquals(caseData.getRespondent1(), updatedCaseData.getRespondent1Copy()); + assertNull(updatedCaseData.getRespondent2Copy()); + assertEquals(YES, updatedCaseData.getShowCarmFields()); + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/SetApplicantResponseDeadlineTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/SetApplicantResponseDeadlineTest.java new file mode 100644 index 00000000000..62dd9f54195 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/SetApplicantResponseDeadlineTest.java @@ -0,0 +1,1013 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandlertaskstests; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.junit.jupiter.MockitoExtension; +import uk.gov.hmcts.reform.ccd.client.model.AboutToStartOrSubmitCallbackResponse; +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.CaseRole; +import uk.gov.hmcts.reform.civil.enums.MultiPartyScenario; +import uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.RespondToClaimSpecUtils; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.SetApplicantResponseDeadline; +import uk.gov.hmcts.reform.civil.model.Address; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.CourtLocation; +import uk.gov.hmcts.reform.civil.model.Party; +import uk.gov.hmcts.reform.civil.model.ResponseDocument; +import uk.gov.hmcts.reform.civil.model.caseflags.Flags; +import uk.gov.hmcts.reform.civil.model.common.Element; +import uk.gov.hmcts.reform.civil.model.dq.ExpertDetails; +import uk.gov.hmcts.reform.civil.model.dq.Experts; +import uk.gov.hmcts.reform.civil.model.dq.RequestedCourt; +import uk.gov.hmcts.reform.civil.model.dq.Respondent1DQ; +import uk.gov.hmcts.reform.civil.model.dq.Respondent2DQ; +import uk.gov.hmcts.reform.civil.model.dq.Witnesses; +import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; +import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; +import uk.gov.hmcts.reform.civil.service.DeadlinesCalculator; +import uk.gov.hmcts.reform.civil.service.FeatureToggleService; +import uk.gov.hmcts.reform.civil.service.Time; +import uk.gov.hmcts.reform.civil.service.UserService; +import uk.gov.hmcts.reform.civil.service.citizenui.responsedeadline.DeadlineExtensionCalculatorService; +import uk.gov.hmcts.reform.civil.service.flowstate.IStateFlowEngine; +import uk.gov.hmcts.reform.civil.stateflow.StateFlow; +import uk.gov.hmcts.reform.civil.utils.AssignCategoryId; +import uk.gov.hmcts.reform.civil.utils.CaseFlagsInitialiser; +import uk.gov.hmcts.reform.civil.utils.CourtLocationUtils; +import uk.gov.hmcts.reform.civil.utils.DQResponseDocumentUtils; +import uk.gov.hmcts.reform.civil.utils.FrcDocumentsUtils; +import uk.gov.hmcts.reform.idam.client.models.UserInfo; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static uk.gov.hmcts.reform.civil.callback.CallbackParams.Params.BEARER_TOKEN; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORONE; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORTWO; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_ONE_LEGAL_REP; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_TWO_LEGAL_REP; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec.IMMEDIATELY; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.FULL_DEFENCE; +import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.PART_ADMISSION; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; + +@ExtendWith(MockitoExtension.class) +class SetApplicantResponseDeadlineTest { + + private SetApplicantResponseDeadline setApplicantResponseDeadline; + + @Mock + private IStateFlowEngine stateFlowEngine; + + @Mock + private CoreCaseUserService coreCaseUserService; + + @Mock + private StateFlow mockedStateFlow; + + @Mock + private UserService userService; + + @Mock + private Time time; + + @Mock + private DeadlinesCalculator deadlinesCalculator; + + @Mock + private FeatureToggleService toggleService; + + @Mock + private CaseFlagsInitialiser caseFlagsInitialiser; + + @Mock + private FrcDocumentsUtils frcDocumentsUtils; + + @Mock + private DeadlineExtensionCalculatorService deadlineCalculatorService; + + @Mock + private CourtLocationUtils courtLocationUtils; + + @Mock + private AssignCategoryId assignCategoryId; + + @Mock + private RespondToClaimSpecUtils respondToClaimSpecUtils; + + @Mock + private DQResponseDocumentUtils dqResponseDocumentUtils; + + private ObjectMapper objectMapper; + + @BeforeEach + void setUp() { + objectMapper = new ObjectMapper(); + objectMapper.registerModule(new com.fasterxml.jackson.datatype.jsr310.JavaTimeModule()); + setApplicantResponseDeadline = new SetApplicantResponseDeadline( + userService, + coreCaseUserService, + toggleService, + objectMapper, + caseFlagsInitialiser, + time, + deadlineCalculatorService, + stateFlowEngine, + deadlinesCalculator, + frcDocumentsUtils, + courtLocationUtils, + respondToClaimSpecUtils, + assignCategoryId, + dqResponseDocumentUtils + ); + when(mockedStateFlow.isFlagSet(any())).thenReturn(true); + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + when(stateFlowEngine.evaluate(any(CaseData.class))).thenReturn(mockedStateFlow); + } + + private AboutToStartOrSubmitCallbackResponse executeCallback(CallbackParams callbackParams) { + return (AboutToStartOrSubmitCallbackResponse) setApplicantResponseDeadline.execute(callbackParams); + } + + @Test + void shouldSetApplicantResponseDeadlineWhenMultiPartyScenarioOneVOne() { + Party respondent1Copy = buildParty(); + + CaseData caseData = buildCaseData( + CaseDataBuilder.builder() + .atStateClaimDetailsNotified() + .respondent1Copy(respondent1Copy) + .respondent1DQ(new Respondent1DQ()) + ); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + assertNull(response.getErrors()); + assertThat(response).isNotNull(); + } + + @Test + void shouldSetApplicantResponseDeadlineWhenSolicitorRepresentsOnlyRespondentOne() { + when(coreCaseUserService.userHasCaseRole("1594901956117591", "uid", RESPONDENTSOLICITORTWO)) + .thenReturn(true); + when(time.now()).thenReturn(LocalDateTime.now()); + + Party respondent1Copy = buildParty(); + + CaseData caseData = buildCaseData( + CaseDataBuilder.builder() + .atStateClaimDetailsNotified() + .respondent1Copy(respondent1Copy) + .respondent2DQ(new Respondent2DQ()) + ); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + assertNull(response.getErrors()); + assertThat(response).isNotNull(); + } + + @Test + void shouldSetApplicantResponseDeadlineWhenRespondent2HasDifferentResponseAndExperts() { + when(coreCaseUserService.userHasCaseRole(anyString(), anyString(), any(CaseRole.class))).thenReturn(true); + when(time.now()).thenReturn(LocalDateTime.now()); + + Party respondent1Copy = buildParty(); + + CaseData caseData = buildCaseData( + CaseDataBuilder.builder() + .atStateClaimDetailsNotified() + .respondentResponseIsSame(NO) + .respondent1Copy(respondent1Copy) + .respondent2DQ(new Respondent2DQ()) + ); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + assertNull(response.getErrors()); + assertThat(response).isNotNull(); + } + + @Test + void shouldUpdatePaymentTimeRouteWhenConditionsAreMet() { + when(coreCaseUserService.userHasCaseRole(anyString(), anyString(), any(CaseRole.class))).thenReturn(true); + when(time.now()).thenReturn(LocalDateTime.now()); + + Party respondent1Copy = buildParty(); + + CaseData caseData = buildCaseData( + CaseDataBuilder.builder() + .atStateClaimDetailsNotified() + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .defenceAdmitPartPaymentTimeRouteRequired(IMMEDIATELY) + .respondent1Copy(respondent1Copy) + .respondent2DQ(new Respondent2DQ()) + ); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + assertNull(response.getErrors()); + assertThat(response).isNotNull(); + } + + @Test + void shouldNotUpdatePaymentTimeRouteWhenDefenceAdmitPartPaymentTimeRouteRequiredIsNull() { + when(coreCaseUserService.userHasCaseRole(anyString(), anyString(), any(CaseRole.class))).thenReturn(true); + when(time.now()).thenReturn(LocalDateTime.now()); + + Party respondent1Copy = buildParty(); + + CaseData caseData = buildCaseData( + CaseDataBuilder.builder() + .atStateClaimDetailsNotified() + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .respondent1Copy(respondent1Copy) + .respondent2DQ(new Respondent2DQ()) + .defenceAdmitPartPaymentTimeRouteRequired(null) + ); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + assertNull(response.getErrors()); + assertThat(response).isNotNull(); + verify(deadlineCalculatorService, never()).calculateExtendedDeadline(any(LocalDate.class), anyInt()); + } + + @Test + void shouldNotUpdatePaymentTimeRouteWhenDefenceAdmitPartPaymentTimeRouteRequiredIsNotImmediately() { + when(coreCaseUserService.userHasCaseRole(anyString(), anyString(), any(CaseRole.class))).thenReturn(true); + when(time.now()).thenReturn(LocalDateTime.now()); + + Party respondent1Copy = buildParty(); + + CaseData caseData = buildCaseData( + CaseDataBuilder.builder() + .atStateClaimDetailsNotified() + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .respondent1Copy(respondent1Copy) + .respondent2DQ(new Respondent2DQ()) + .defenceAdmitPartPaymentTimeRouteRequired(RespondentResponsePartAdmissionPaymentTimeLRspec.BY_SET_DATE) + ); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + assertNull(response.getErrors()); + assertThat(response).isNotNull(); + verify(deadlineCalculatorService, never()).calculateExtendedDeadline(any(LocalDate.class), anyInt()); + } + + @Test + void shouldNotUpdatePaymentTimeRouteWhenResponseTypeIsNotPartOrFullAdmission() { + when(coreCaseUserService.userHasCaseRole(anyString(), anyString(), any(CaseRole.class))).thenReturn(true); + when(time.now()).thenReturn(LocalDateTime.now()); + + Party respondent1Copy = buildParty(); + + CaseData caseData = buildCaseData( + CaseDataBuilder.builder() + .atStateClaimDetailsNotified() + .respondent1ClaimResponseTypeForSpec(FULL_DEFENCE) + .respondent1Copy(respondent1Copy) + .respondent2DQ(new Respondent2DQ()) + .defenceAdmitPartPaymentTimeRouteRequired(IMMEDIATELY) + ); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + assertNull(response.getErrors()); + assertThat(response).isNotNull(); + verify(deadlineCalculatorService, never()).calculateExtendedDeadline(any(LocalDate.class), anyInt()); + } + + @Test + void shouldNotUpdateRespondent2ClaimResponseTypeAndResponseDateWhenRespondentResponseIsSameIsNull() { + LocalDateTime responseDate = LocalDateTime.now(); + + when(time.now()).thenReturn(responseDate); + + Party respondent1Copy = buildParty(); + + CaseData caseData = buildCaseData( + CaseDataBuilder.builder() + .atStateClaimDetailsNotified() + .respondentResponseIsSame(null) + .respondent1ClaimResponseTypeForSpec(FULL_DEFENCE) + .respondent1Copy(respondent1Copy) + .respondent1DQ(new Respondent1DQ()) + ); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + CaseData updatedCaseData = objectMapper.convertValue(response.getData(), CaseData.class); + + assertThat(updatedCaseData.getRespondent2ClaimResponseTypeForSpec()).isNull(); + assertThat(updatedCaseData.getRespondent2ResponseDate()).isNull(); + } + + @Test + void shouldNotUpdateRespondent2ClaimResponseTypeAndResponseDateWhenRespondentResponseIsSameIsNo() { + LocalDateTime responseDate = LocalDateTime.now(); + + when(time.now()).thenReturn(responseDate); + + Party respondent1Copy = buildParty(); + + CaseData caseData = buildCaseData( + CaseDataBuilder.builder() + .atStateClaimDetailsNotified() + .respondentResponseIsSame(NO) + .respondent1ClaimResponseTypeForSpec(FULL_DEFENCE) + .respondent1Copy(respondent1Copy) + .respondent1DQ(new Respondent1DQ()) + ); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + CaseData updatedCaseData = objectMapper.convertValue(response.getData(), CaseData.class); + + assertThat(updatedCaseData.getRespondent2ClaimResponseTypeForSpec()).isNull(); + assertThat(updatedCaseData.getRespondent2ResponseDate()).isNull(); + } + + @Test + void shouldUpdateRespondent1PrimaryAddressWhenSpecAoSApplicantCorrespondenceAddressRequiredIsNo() { + Address correspondenceAddress = buildAddress("123 Test Street", "AB12 3CD"); + + Party respondent1 = Party.builder() + .primaryAddress(buildAddress("Old Address", "")) + .type(Party.Type.INDIVIDUAL) + .build(); + + CaseData caseData = buildCaseData( + CaseDataBuilder.builder() + .atStateClaimDetailsNotified() + .respondent1(respondent1) + .atSpecAoSApplicantCorrespondenceAddressRequired(NO) + .atSpecAoSApplicantCorrespondenceAddressDetails(correspondenceAddress) + .respondent1DQ(new Respondent1DQ()) + ); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + CaseData updatedCaseData = objectMapper.convertValue(response.getData(), CaseData.class); + + assertThat(updatedCaseData.getRespondent1().getPrimaryAddress()).isEqualTo(correspondenceAddress); + } + + @Test + void shouldUpdateRespondent2WhenBothRespondent2AndRespondent2CopyArePresent() { + Address address = buildAddress("123 Test Street", "AB12 3CD"); + + Party respondent1 = Party.builder() + .primaryAddress(buildAddress("Old Address", "")) + .type(Party.Type.INDIVIDUAL) + .build(); + + Party respondent2 = Party.builder() + .primaryAddress(buildAddress("Old Address", "")) + .type(Party.Type.INDIVIDUAL) + .build(); + + Party respondent2Copy = Party.builder() + .primaryAddress(address) + .flags(new Flags()) + .build(); + + CaseData caseData = buildCaseData( + CaseDataBuilder.builder() + .atStateClaimDetailsNotified() + .respondent1Copy(respondent1) + .respondent1DQ(new Respondent1DQ()) + .respondent2(respondent2) + .respondent2Copy(respondent2Copy) + ); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + CaseData updatedCaseData = objectMapper.convertValue(response.getData(), CaseData.class); + + assertThat(updatedCaseData.getRespondent2().getPrimaryAddress()).isEqualTo(address); + assertThat(updatedCaseData.getRespondent2().getFlags()).isEqualTo(new Flags()); + assertNull(updatedCaseData.getRespondent2Copy()); + assertThat(updatedCaseData.getRespondent2DetailsForClaimDetailsTab().getPrimaryAddress()).isEqualTo(address); + assertNull(updatedCaseData.getRespondent2DetailsForClaimDetailsTab().getFlags()); + } + + @Test + void shouldNotUpdateRespondent2WhenRespondent2CopyIsNotPresent() { + Address address = buildAddress("123 Test Street", "AB12 3CD"); + + Party respondent1 = Party.builder() + .primaryAddress(buildAddress("Old Address", "")) + .type(Party.Type.INDIVIDUAL) + .build(); + + Party respondent2 = Party.builder() + .primaryAddress(address) + .type(Party.Type.INDIVIDUAL) + .flags(new Flags()) + .build(); + + CaseData caseData = buildCaseData( + CaseDataBuilder.builder() + .atStateClaimDetailsNotified() + .respondent1Copy(respondent1) + .respondent1DQ(new Respondent1DQ()) + .respondent2(respondent2) + ); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + CaseData updatedCaseData = objectMapper.convertValue(response.getData(), CaseData.class); + + assertThat(updatedCaseData.getRespondent2().getPrimaryAddress()).isEqualTo(address); + assertThat(updatedCaseData.getRespondent2().getFlags()).isEqualTo(new Flags()); + assertNull(updatedCaseData.getRespondent2Copy()); + assertThat(updatedCaseData.getRespondent2DetailsForClaimDetailsTab().getPrimaryAddress()).isEqualTo(address); + assertNull(updatedCaseData.getRespondent2DetailsForClaimDetailsTab().getFlags()); + } + + @Test + void shouldUpdateRespondent2PrimaryAddressWhenSpecAoSRespondent2HomeAddressRequiredIsNo() { + Address expectedAddress = buildAddress("123 Test Street", "AB1 2CD"); + + Party respondent1 = Party.builder() + .primaryAddress(buildAddress("Old Address", "")) + .type(Party.Type.INDIVIDUAL) + .build(); + + Party respondent2 = Party.builder() + .primaryAddress(expectedAddress) + .type(Party.Type.INDIVIDUAL) + .flags(new Flags()) + .build(); + + CaseData caseData = CaseData.builder() + .specAoSRespondent2HomeAddressRequired(NO) + .specAoSRespondent2HomeAddressDetails(expectedAddress) + .respondent1(respondent1) + .respondent1Copy(respondent1) + .respondent1DQ(new Respondent1DQ()) + .respondent2(respondent2) + .respondent2Copy(respondent2) + .ccdCaseReference(1234L) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + CaseData updatedCaseData = objectMapper.convertValue(response.getData(), CaseData.class); + + assertThat(updatedCaseData.getRespondent2().getPrimaryAddress()).isEqualTo(expectedAddress); + } + + @Test + void shouldSetDefenceAdmitPartPaymentTimeRouteRequiredToNullWhenSolicitorTwoAndFullDefence() { + Party respondent1 = Party.builder() + .primaryAddress(buildAddress("Old Address", "")) + .type(Party.Type.INDIVIDUAL) + .build(); + + Party respondent2 = Party.builder() + .primaryAddress(buildAddress("123 Test Street", "AB12 3CD")) + .type(Party.Type.INDIVIDUAL) + .build(); + + CaseData caseData = CaseData.builder() + .respondent2ClaimResponseTypeForSpec(FULL_DEFENCE) + .respondent1(respondent1) + .respondent1Copy(respondent1) + .respondent1DQ(new Respondent1DQ()) + .respondent2(respondent2) + .respondent2Copy(respondent2) + .respondent2DQ(new Respondent2DQ()) + .ccdCaseReference(1234L) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + when(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).thenReturn(true); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + CaseData updatedCaseData = objectMapper.convertValue(response.getData(), CaseData.class); + assertNull(updatedCaseData.getDefenceAdmitPartPaymentTimeRouteRequired()); + } + + @Test + void shouldAddEventAndDateToExpertsAndWitnessesWhenUpdateContactDetailsToggleIsEnabled() { + when(coreCaseUserService.userHasCaseRole(anyString(), anyString(), any(CaseRole.class))).thenReturn(true); + when(time.now()).thenReturn(LocalDateTime.now()); + when(toggleService.isUpdateContactDetailsEnabled()).thenReturn(true); + + Party respondent1Copy = buildParty(); + + CaseData caseData = buildCaseData( + CaseDataBuilder.builder() + .atStateClaimDetailsNotified() + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .respondent1Copy(respondent1Copy) + .respondent1ResponseDate(LocalDateTime.now()) + .respondent2DQ(new Respondent2DQ()) + .defenceAdmitPartPaymentTimeRouteRequired(RespondentResponsePartAdmissionPaymentTimeLRspec.BY_SET_DATE) + ); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + assertNull(response.getErrors()); + assertThat(response).isNotNull(); + } + + @Test + void shouldPopulateDQPartyIdsWhenHmcToggleIsEnabled() { + when(coreCaseUserService.userHasCaseRole(anyString(), anyString(), any(CaseRole.class))).thenReturn(true); + when(time.now()).thenReturn(LocalDateTime.now()); + when(toggleService.isHmcEnabled()).thenReturn(true); + Party respondent1Copy = buildParty(); + CaseData caseData = buildCaseData( + CaseDataBuilder.builder() + .atStateClaimDetailsNotified() + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .respondent1Copy(respondent1Copy) + .respondent2DQ(new Respondent2DQ()) + .defenceAdmitPartPaymentTimeRouteRequired(RespondentResponsePartAdmissionPaymentTimeLRspec.BY_SET_DATE) + ); + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + assertNull(response.getErrors()); + assertThat(response).isNotNull(); + } + + @Test + void shouldUpdateWitnessesWhenRespondent1DQWitnessesSmallClaimIsNotNull() { + Witnesses respondent1Witnesses = Witnesses.builder().build(); + Witnesses respondent2Witnesses = Witnesses.builder().build(); + + Respondent1DQ respondent1DQ = Respondent1DQ.builder().build(); + Respondent2DQ respondent2DQ = Respondent2DQ.builder().build(); + + Party respondent1 = Party.builder() + .primaryAddress(buildAddress("Old Address", "")) + .type(Party.Type.INDIVIDUAL) + .build(); + + CaseData caseData = CaseData.builder() + .respondent1(respondent1) + .respondent1Copy(respondent1) + .respondent1DQWitnessesSmallClaim(respondent1Witnesses) + .respondent2DQWitnessesSmallClaim(respondent2Witnesses) + .respondent1DQ(respondent1DQ) + .respondent2DQ(respondent2DQ) + .ccdCaseReference(1234L) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + CaseData updatedCaseData = objectMapper.convertValue(response.getData(), CaseData.class); + assertThat(updatedCaseData.getRespondent1DQ().getRespondent1DQWitnesses()).isEqualTo(respondent1Witnesses); + assertThat(updatedCaseData.getRespondent2DQ().getRespondent2DQWitnesses()).isEqualTo(respondent2Witnesses); + } + + @Test + void shouldUpdateRespondent1ExpertsWhenExpertRequiredIsYesAndDetailsPresent() { + Witnesses respondent1Witnesses = Witnesses.builder().build(); + + Respondent1DQ respondent1DQ = Respondent1DQ.builder().respondToClaimExperts(ExpertDetails.builder().build()).build(); + + Party respondent1 = Party.builder() + .primaryAddress(buildAddress("Old Address", "")) + .type(Party.Type.INDIVIDUAL) + .build(); + + CaseData caseData = CaseData.builder() + .responseClaimExpertSpecRequired(YES) + .respondent1DQ(respondent1DQ) + .respondent1(respondent1) + .respondent1Copy(respondent1) + .respondent1DQWitnessesSmallClaim(respondent1Witnesses) + .ccdCaseReference(1234L) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + Map responseData = response.getData(); + + Witnesses actualWitnesses = objectMapper.convertValue( + responseData.get("respondent1DQWitnesses"), + Witnesses.class + ); + + assertThat(actualWitnesses).isEqualTo(respondent1Witnesses); + } + + @Test + void shouldUpdateRespondent1ExpertsWhenExpertRequiredIsNo() { + Witnesses respondent1Witnesses = Witnesses.builder().build(); + + Party respondent1 = Party.builder() + .primaryAddress(buildAddress("Old Address", "")) + .type(Party.Type.INDIVIDUAL) + .build(); + + CaseData caseData = CaseData.builder() + .responseClaimExpertSpecRequired(NO) + .respondent1DQ(new Respondent1DQ()) + .respondent1(respondent1) + .respondent1Copy(respondent1) + .respondent1DQWitnessesSmallClaim(respondent1Witnesses) + .ccdCaseReference(1234L) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + Map responseData = response.getData(); + + Experts actualExperts = objectMapper.convertValue(responseData.get("respondent1DQExperts"), Experts.class); + + assertThat(actualExperts.getExpertRequired()).isEqualTo(NO); + assertThat(actualExperts.getDetails()).isNull(); + } + + @Test + void shouldUpdateRespondent2ExpertsWhenExpertRequiredIsYesAndDetailsPresent() { + Witnesses respondent2Witnesses = Witnesses.builder().build(); + + Respondent2DQ respondent2DQ = Respondent2DQ.builder().respondToClaimExperts2(ExpertDetails.builder().build()).build(); + + Party respondent1 = Party.builder() + .primaryAddress(buildAddress("Old Address", "")) + .type(Party.Type.INDIVIDUAL) + .build(); + + Party respondent2 = Party.builder() + .primaryAddress(buildAddress("Old Address", "")) + .type(Party.Type.INDIVIDUAL) + .build(); + + CaseData caseData = CaseData.builder() + .responseClaimExpertSpecRequired2(YES) + .respondent1DQ(new Respondent1DQ()) + .respondent1(respondent1) + .respondent1Copy(respondent1) + .respondent2DQ(respondent2DQ) + .respondent2(respondent2) + .respondent2Copy(respondent2) + .respondent2DQWitnessesSmallClaim(respondent2Witnesses) + .ccdCaseReference(1234L) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + Map responseData = response.getData(); + + Witnesses actualWitnesses = objectMapper.convertValue( + responseData.get("respondent2DQWitnesses"), + Witnesses.class + ); + + assertThat(actualWitnesses).isEqualTo(respondent2Witnesses); + } + + @Test + void shouldUpdateRespondent2ExpertsWhenExpertRequiredIsNo() { + Witnesses respondent2Witnesses = Witnesses.builder().build(); + + Party respondent1 = Party.builder() + .primaryAddress(buildAddress("Old Address", "")) + .type(Party.Type.INDIVIDUAL) + .build(); + + Party respondent2 = Party.builder() + .primaryAddress(buildAddress("Old Address", "")) + .type(Party.Type.INDIVIDUAL) + .build(); + + CaseData caseData = CaseData.builder() + .responseClaimExpertSpecRequired2(NO) + .respondent1DQ(new Respondent1DQ()) + .respondent1(respondent1) + .respondent1Copy(respondent1) + .respondent2DQ(new Respondent2DQ()) + .respondent2(respondent2) + .respondent2Copy(respondent2) + .respondent2DQWitnessesSmallClaim(respondent2Witnesses) + .ccdCaseReference(1234L) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + Map responseData = response.getData(); + + Experts actualExperts = objectMapper.convertValue(responseData.get("respondent2DQExperts"), Experts.class); + + assertThat(actualExperts.getDetails()).isNull(); + } + + @Test + void shouldUpdateRespondent1CorrespondenceAddressWhenSolicitorOnePresentAndCorrespondenceNotRequired() { + when(coreCaseUserService.userHasCaseRole(eq("1234"), anyString(), eq(RESPONDENTSOLICITORONE))).thenReturn(true); + when(coreCaseUserService.userHasCaseRole( + eq("1234"), + anyString(), + eq(RESPONDENTSOLICITORTWO) + )).thenReturn(false); + + Party respondent1 = Party.builder() + .primaryAddress(buildAddress("Old Address", "")) + .type(Party.Type.INDIVIDUAL) + .build(); + + CaseData caseData = CaseData.builder() + .specAoSRespondentCorrespondenceAddressRequired(NO) + .respondent1(respondent1) + .respondent1Copy(respondent1) + .respondent1DQ(new Respondent1DQ()) + .ccdCaseReference(1234L) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + CaseData updatedCaseData = objectMapper.convertValue(response.getData(), CaseData.class); + + assertThat(updatedCaseData.getSpecAoSRespondentCorrespondenceAddressdetails()).isNotNull(); + assertThat(updatedCaseData.getSpecAoSRespondentCorrespondenceAddressdetails()).isEqualTo(Address.builder().build()); + } + + @Test + void shouldUpdateRespondent12CorrespondenceAddressWhenSolicitorTwoPresentAndCorrespondenceNotRequired() { + when(coreCaseUserService.userHasCaseRole( + eq("1234"), + anyString(), + eq(RESPONDENTSOLICITORONE) + )).thenReturn(false); + when(coreCaseUserService.userHasCaseRole(eq("1234"), anyString(), eq(RESPONDENTSOLICITORTWO))).thenReturn(true); + + Party respondent1 = Party.builder() + .primaryAddress(buildAddress("Old Address", "")) + .type(Party.Type.INDIVIDUAL) + .build(); + + CaseData caseData = CaseData.builder() + .specAoSRespondent2CorrespondenceAddressRequired(NO) + .respondent1(respondent1) + .respondent1Copy(respondent1) + .respondent1DQ(new Respondent1DQ()) + .respondent2DQ(new Respondent2DQ()) + .ccdCaseReference(1234L) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + CaseData updatedCaseData = objectMapper.convertValue(response.getData(), CaseData.class); + + assertThat(updatedCaseData.getSpecAoSRespondent2CorrespondenceAddressdetails()).isNotNull(); + assertThat(updatedCaseData.getSpecAoSRespondent2CorrespondenceAddressdetails()).isEqualTo(Address.builder().build()); + } + + @Test + void shouldUpdateRespondent1WitnessesWhenExpertRequiredIsYesAndDetailsPresent() { + Witnesses respondent1Witnesses = Witnesses.builder().build(); + + Respondent1DQ respondent1DQ = Respondent1DQ.builder().build(); + + Party respondent1 = Party.builder() + .primaryAddress(buildAddress("Old Address", "")) + .type(Party.Type.INDIVIDUAL) + .build(); + + CaseData caseData = CaseData.builder() + .responseClaimExpertSpecRequired(YES) + .respondent1DQ(respondent1DQ) + .respondent1(respondent1) + .respondent1Copy(respondent1) + .respondent1DQWitnessesSmallClaim(respondent1Witnesses) + .ccdCaseReference(1234L) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + Map responseData = response.getData(); + + Witnesses actualWitnesses = objectMapper.convertValue( + responseData.get("respondent1DQWitnesses"), + Witnesses.class + ); + + assertThat(actualWitnesses).isEqualTo(respondent1Witnesses); + } + + @Test + void shouldUpdateRespondent2WitnessesWhenExpertRequiredIsYesAndDetailsPresent() { + Witnesses respondent2Witnesses = Witnesses.builder().build(); + + Respondent2DQ respondent2DQ = Respondent2DQ.builder().build(); + + Party respondent1 = Party.builder() + .primaryAddress(buildAddress("Old Address", "")) + .type(Party.Type.INDIVIDUAL) + .build(); + + Party respondent2 = Party.builder() + .primaryAddress(buildAddress("Old Address", "")) + .type(Party.Type.INDIVIDUAL) + .build(); + + CaseData caseData = CaseData.builder() + .responseClaimExpertSpecRequired2(YES) + .respondent1DQ(new Respondent1DQ()) + .respondent1(respondent1) + .respondent1Copy(respondent1) + .respondent2DQ(respondent2DQ) + .respondent2(respondent2) + .respondent2Copy(respondent2) + .respondent2DQWitnessesSmallClaim(respondent2Witnesses) + .ccdCaseReference(1234L) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + Map responseData = response.getData(); + + Witnesses actualWitnesses = objectMapper.convertValue( + responseData.get("respondent2DQWitnesses"), + Witnesses.class + ); + + assertThat(actualWitnesses).isEqualTo(respondent2Witnesses); + } + + @Test + void shouldNotUpdatePaymentTimeRouteWhenDefenceAdmitPartPaymentTimeRouteRequiredIsNotImmediately1() { + when(coreCaseUserService.userHasCaseRole(anyString(), anyString(), any(CaseRole.class))).thenReturn(true); + when(time.now()).thenReturn(LocalDateTime.now()); + + Party respondent1Copy = buildParty(); + + CaseData caseData = buildCaseData( + CaseDataBuilder.builder() + .atStateClaimDetailsNotified() + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .respondent2ClaimResponseTypeForSpec(PART_ADMISSION) + .respondent1Copy(respondent1Copy) + .respondent2DQ(new Respondent2DQ()) + .defenceAdmitPartPaymentTimeRouteRequired(RespondentResponsePartAdmissionPaymentTimeLRspec.BY_SET_DATE) + ); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn( + ONE_V_TWO_TWO_LEGAL_REP); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + assertNull(response.getErrors()); + assertThat(response).isNotNull(); + verify(deadlineCalculatorService, never()).calculateExtendedDeadline(any(LocalDate.class), anyInt()); + } + } + + @Test + void shouldUpdateRespondent1CorrespondenceAddressWhenSolicitorOnePresentAndCorrespondenceNotRequired1() { + when(coreCaseUserService.userHasCaseRole(eq("1234"), anyString(), eq(RESPONDENTSOLICITORONE))).thenReturn(true); + when(coreCaseUserService.userHasCaseRole( + eq("1234"), + anyString(), + eq(RESPONDENTSOLICITORTWO) + )).thenReturn(false); + + Party respondent1 = Party.builder() + .primaryAddress(buildAddress("Old Address", "")) + .type(Party.Type.INDIVIDUAL) + .build(); + + ResponseDocument testDocument = ResponseDocument.builder() + .file(Document.builder() + .documentUrl("fake-url") + .documentFileName("file-name") + .documentBinaryUrl("binary-url") + .build()) + .build(); + + List> defendantUploads = new ArrayList<>(); + + CaseData caseData = CaseData.builder() + .specAoSRespondentCorrespondenceAddressRequired(NO) + .respondent1(respondent1) + .respondent1Copy(respondent1) + .respondent1DQ(Respondent1DQ.builder() + .respondToCourtLocation(RequestedCourt.builder().build()) + .build()) + .ccdCaseReference(1234L) + .defendantResponseDocuments(defendantUploads) + .courtLocation(CourtLocation.builder().build()) + .respondent1SpecDefenceResponseDocument(testDocument) + .respondent2SpecDefenceResponseDocument(testDocument) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn( + ONE_V_TWO_ONE_LEGAL_REP); + + AboutToStartOrSubmitCallbackResponse response = executeCallback(callbackParams); + + CaseData updatedCaseData = objectMapper.convertValue(response.getData(), CaseData.class); + + assertThat(updatedCaseData.getSpecAoSRespondentCorrespondenceAddressdetails()).isNotNull(); + assertThat(updatedCaseData.getSpecAoSRespondentCorrespondenceAddressdetails()).isEqualTo(Address.builder().build()); + } + } + + private Address buildAddress(String line1, String postCode) { + return Address.builder() + .addressLine1(line1) + .postCode(postCode) + .build(); + } + + private Party buildParty() { + return Party.builder() + .primaryAddress(buildAddress("123 Test Street", "AB12 3CD")) + .build(); + } + + private CaseData buildCaseData(CaseDataBuilder builder) { + return builder.build(); + } + + private CallbackParams buildCallbackParams(CaseData caseData) { + return CallbackParams.builder() + .caseData(caseData) + .params(Map.of(BEARER_TOKEN, "Bearer token")) + .build(); + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/SetGenericResponseTypeFlagTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/SetGenericResponseTypeFlagTest.java new file mode 100644 index 00000000000..88cde7869d5 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/SetGenericResponseTypeFlagTest.java @@ -0,0 +1,709 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandlertaskstests; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.junit.jupiter.MockitoExtension; +import uk.gov.hmcts.reform.ccd.client.model.AboutToStartOrSubmitCallbackResponse; +import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.enums.MultiPartyScenario; +import uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec; +import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.RespondToClaimSpecUtils; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.SetGenericResponseTypeFlag; +import uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; +import uk.gov.hmcts.reform.civil.service.UserService; +import uk.gov.hmcts.reform.idam.client.models.UserInfo; + +import java.util.EnumSet; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; +import static uk.gov.hmcts.reform.civil.callback.CallbackParams.Params.BEARER_TOKEN; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORTWO; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_ONE; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_ONE_LEGAL_REP; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_TWO_LEGAL_REP; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.TWO_V_ONE; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; + +@ExtendWith(MockitoExtension.class) +class SetGenericResponseTypeFlagTest { + + private static final String BEARER_TOKEN_VALUE = "Bearer token"; + private static final String MULTI_PARTY_RESPONSE_TYPE_FLAGS = "multiPartyResponseTypeFlags"; + private static final String RESPONDENT_CLAIM_RESPONSE_TYPE_GENERIC = "respondentClaimResponseTypeForSpecGeneric"; + private static final String SPEC_FULL_ADMISSION_OR_PART_ADMISSION = "specFullAdmissionOrPartAdmission"; + private static final String DEFENCE_ADMIT_PART_PAYMENT_TIME_ROUTE_GENERIC = "defenceAdmitPartPaymentTimeRouteGeneric"; + private static final String RESPONDENT_RESPONSE_IS_SAME = "respondentResponseIsSame"; + private static final String SAME_SOLICITOR_SAME_RESPONSE = "sameSolicitorSameResponse"; + + private SetGenericResponseTypeFlag setGenericResponseTypeFlag; + + @Mock + private UserService userService; + + @Mock + private CoreCaseUserService coreCaseUserService; + + @Mock + private RespondToClaimSpecUtils respondToClaimSpecUtilsDisputeDetails; + + @BeforeEach + void setUp() { + ObjectMapper objectMapper = new ObjectMapper(); + setGenericResponseTypeFlag = new SetGenericResponseTypeFlag(objectMapper, userService, coreCaseUserService, respondToClaimSpecUtilsDisputeDetails); + } + + @Test + void shouldSetGenericResponseTypeFlagForOneVOneScenario() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .build(); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, ONE_V_ONE); + + assertEquals("FULL_DEFENCE", response.getData().get(RESPONDENT_CLAIM_RESPONSE_TYPE_GENERIC)); + assertEquals("FULL_DEFENCE", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + } + + @Test + void shouldSetGenericResponseTypeFlagForTwoVOneScenario() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .build(); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, TWO_V_ONE); + + assertEquals("COUNTER_ADMIT_OR_ADMIT_PART", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + assertEquals("Yes", response.getData().get(SPEC_FULL_ADMISSION_OR_PART_ADMISSION)); + } + + /*@Test + void shouldSetGenericResponseTypeFlagForOneVTwoOneLegalRepScenario() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .build(); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, ONE_V_TWO_ONE_LEGAL_REP); + + assertEquals("No", response.getData().get(RESPONDENT_RESPONSE_IS_SAME)); + assertEquals("No", response.getData().get(SAME_SOLICITOR_SAME_RESPONSE)); + assertEquals("FULL_DEFENCE", response.getData().get(RESPONDENT_CLAIM_RESPONSE_TYPE_GENERIC)); + }*/ + + @Test + void shouldSetGenericResponseTypeFlagForOneVTwoTwoLegalRepScenario() { + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + + CaseData caseData = CaseData.builder() + .isRespondent1(YES) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .isRespondent2(YES) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .ccdCaseReference(1234L) + .build(); + + when(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).thenReturn(true); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, ONE_V_TWO_TWO_LEGAL_REP); + + assertEquals("PART_ADMISSION", response.getData().get(RESPONDENT_CLAIM_RESPONSE_TYPE_GENERIC)); + assertEquals("COUNTER_ADMIT_OR_ADMIT_PART", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + assertEquals("Yes", response.getData().get(SPEC_FULL_ADMISSION_OR_PART_ADMISSION)); + } + + @Test + void shouldSetCounterAdmitOrAdmitPartFlagWhenBothClaimantsHaveAdmissionOrCounterClaim() { + CaseData caseData = CaseData.builder() + .claimant1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .claimant2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = + (AboutToStartOrSubmitCallbackResponse) setGenericResponseTypeFlag.execute(callbackParams); + + assertEquals("COUNTER_ADMIT_OR_ADMIT_PART", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + } + + @Test + void shouldSetCounterAdmitOrAdmitPartFlagWhenBothClaimantsHaveFullAdmission() { + CaseData caseData = CaseData.builder() + .claimant1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .claimant2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = + (AboutToStartOrSubmitCallbackResponse) setGenericResponseTypeFlag.execute(callbackParams); + + assertEquals("COUNTER_ADMIT_OR_ADMIT_PART", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + } + + @Test + void shouldSetCounterAdmitOrAdmitPartFlagWhenBothClaimantsHavePartAdmission() { + CaseData caseData = CaseData.builder() + .claimant1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .claimant2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = + (AboutToStartOrSubmitCallbackResponse) setGenericResponseTypeFlag.execute(callbackParams); + + assertEquals("COUNTER_ADMIT_OR_ADMIT_PART", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + } + + @Test + void shouldSetCounterAdmitOrAdmitPartFlagWhenBothClaimantsHaveCounterClaim() { + CaseData caseData = CaseData.builder() + .claimant1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.COUNTER_CLAIM) + .claimant2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.COUNTER_CLAIM) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = + (AboutToStartOrSubmitCallbackResponse) setGenericResponseTypeFlag.execute(callbackParams); + + assertEquals("COUNTER_ADMIT_OR_ADMIT_PART", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + } + + @Test + void shouldSetFullDefenceFlagWhenResponseTypeIsFullDefence() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = + (AboutToStartOrSubmitCallbackResponse) setGenericResponseTypeFlag.execute(callbackParams); + + assertEquals("FULL_DEFENCE", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + } + + @Test + void shouldSetCounterClaimFlagWhenResponseTypeIsCounterClaim() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.COUNTER_CLAIM) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = + (AboutToStartOrSubmitCallbackResponse) setGenericResponseTypeFlag.execute(callbackParams); + + assertEquals("COUNTER_ADMIT_OR_ADMIT_PART", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + } + + @Test + void shouldSetFullAdmissionFlagWhenResponseTypeIsFullAdmission() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = + (AboutToStartOrSubmitCallbackResponse) setGenericResponseTypeFlag.execute(callbackParams); + + assertEquals("FULL_ADMISSION", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + } + + @Test + void shouldSetSpecFullAdmissionOrPartAdmissionWhenTwoVOneAndBothRespondentsHaveAdmission() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .build(); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, TWO_V_ONE); + + assertEquals("Yes", response.getData().get(SPEC_FULL_ADMISSION_OR_PART_ADMISSION)); + } + + @Test + void shouldSetFullDefenceFlagWhenRespondent1HasFullDefence() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = + (AboutToStartOrSubmitCallbackResponse) setGenericResponseTypeFlag.execute(callbackParams); + + assertEquals("FULL_DEFENCE", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + } + + @Test + void shouldSetFullDefenceFlagWhenRespondent1HasCounterClaim() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.COUNTER_CLAIM) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = + (AboutToStartOrSubmitCallbackResponse) setGenericResponseTypeFlag.execute(callbackParams); + + assertEquals("COUNTER_ADMIT_OR_ADMIT_PART", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + } + + /*@Test + void shouldHandleDifferentResponseForOneVTwoOneLegalRep() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .build(); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, ONE_V_TWO_ONE_LEGAL_REP); + + assertEquals("FULL_DEFENCE", response.getData().get(RESPONDENT_CLAIM_RESPONSE_TYPE_GENERIC)); + }*/ + + @Test + void shouldNotSetCounterAdmitOrAdmitPartFlagWhenOnlyOneClaimantHasCounterClaim() { + CaseData caseData = CaseData.builder() + .claimant1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.COUNTER_CLAIM) + .claimant2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = + (AboutToStartOrSubmitCallbackResponse) setGenericResponseTypeFlag.execute(callbackParams); + + assertEquals("FULL_DEFENCE", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + } + + @Test + void shouldNotSetFullAdmissionFlagWhenRespondent2DoesNotHaveFullAdmission() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = + (AboutToStartOrSubmitCallbackResponse) setGenericResponseTypeFlag.execute(callbackParams); + + assertNotEquals("FULL_ADMISSION", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + assertEquals("No", response.getData().get(SPEC_FULL_ADMISSION_OR_PART_ADMISSION)); + } + + @Test + void shouldNotSetFullAdmissionFlagWhenRespondent2ResponseTypeIsNull() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .respondent2ClaimResponseTypeForSpec(null) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = + (AboutToStartOrSubmitCallbackResponse) setGenericResponseTypeFlag.execute(callbackParams); + + assertEquals("FULL_ADMISSION", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + assertEquals("No", response.getData().get(SPEC_FULL_ADMISSION_OR_PART_ADMISSION)); + } + + @Test + void shouldNotSetFullAdmissionFlagWhenRespondent2ClaimResponseTypeIsNull() { + CaseData caseData = CaseData.builder() + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = + (AboutToStartOrSubmitCallbackResponse) setGenericResponseTypeFlag.execute(callbackParams); + + assertNotEquals("FULL_ADMISSION", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + assertEquals("No", response.getData().get(SPEC_FULL_ADMISSION_OR_PART_ADMISSION)); + } + + @Test + void shouldNotSetSpecFullAdmissionOrPartAdmissionWhenRespondent2DoesNotHaveAdmission() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .build(); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, TWO_V_ONE); + + assertEquals("FULL_DEFENCE", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + assertEquals("No", response.getData().get(SPEC_FULL_ADMISSION_OR_PART_ADMISSION)); + } + + /*@Test + void shouldSetFullDefenceFlagWhenRespondent1HasCounterClaimInOneVTwoOneLegalRepScenario() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.COUNTER_CLAIM) + .build(); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, ONE_V_TWO_ONE_LEGAL_REP); + + assertEquals("NOT_FULL_DEFENCE", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + }*/ + + /*@Test + void shouldSetFullDefenceFlagWhenBothRespondentsHaveFullDefenceInOneVTwoOneLegalRepScenario() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .build(); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, ONE_V_TWO_ONE_LEGAL_REP); + + assertEquals("FULL_DEFENCE", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + }*/ + + /*@Test + void shouldSetFullDefenceFlagWhenBothRespondentsHaveCounterClaimInOneVTwoOneLegalRepScenario() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.COUNTER_CLAIM) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.COUNTER_CLAIM) + .build(); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, ONE_V_TWO_ONE_LEGAL_REP); + + assertEquals("COUNTER_ADMIT_OR_ADMIT_PART", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + }*/ + + /*@Test + void shouldHandleDifferentResponsesForRespondentsInOneVTwoOneLegalRepScenario() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .build(); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, ONE_V_TWO_ONE_LEGAL_REP); + + assertEquals("FULL_DEFENCE", response.getData().get(RESPONDENT_CLAIM_RESPONSE_TYPE_GENERIC)); + }*/ + + @Test + void shouldSetGenericResponseTypeFlagWhenBothRespondentsHavePartAdmissionInOneVTwoTwoLegalRepScenario() { + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + + CaseData caseData = CaseData.builder() + .isRespondent1(YES) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .isRespondent2(YES) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .ccdCaseReference(1234L) + .build(); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, ONE_V_TWO_TWO_LEGAL_REP); + + assertEquals("COUNTER_ADMIT_OR_ADMIT_PART", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + } + + @Test + void shouldSetGenericResponseTypeFlagWhenUserHasRespondentSolicitorTwoRoleInOneVTwoTwoLegalRepScenario() { + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + + CaseData caseData = CaseData.builder() + .isRespondent1(YES) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .isRespondent2(YES) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .ccdCaseReference(1234L) + .build(); + + when(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).thenReturn(true); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, ONE_V_TWO_TWO_LEGAL_REP); + + assertEquals("PART_ADMISSION", response.getData().get(RESPONDENT_CLAIM_RESPONSE_TYPE_GENERIC)); + assertEquals("COUNTER_ADMIT_OR_ADMIT_PART", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + } + + /*@Test + void shouldSetGenericResponseTypeFlagWhenRespondent2HasPartAdmissionInOneVTwoTwoLegalRepScenario() { + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + + CaseData caseData = CaseData.builder() + .isRespondent2(YES) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .ccdCaseReference(1234L) + .build(); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, ONE_V_TWO_TWO_LEGAL_REP); + + assertEquals("PART_ADMISSION", response.getData().get(RESPONDENT_CLAIM_RESPONSE_TYPE_GENERIC)); + assertEquals("COUNTER_ADMIT_OR_ADMIT_PART", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + }*/ + + /*@Test + void shouldSetGenericResponseTypeFlagWhenRespondent1HasFullAdmissionAndRespondent2HasPartAdmissionInOneVTwoTwoLegalRepScenario() { + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + + CaseData caseData = CaseData.builder() + .isRespondent1(YES) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .isRespondent2(YES) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .ccdCaseReference(1234L) + .build(); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, ONE_V_TWO_TWO_LEGAL_REP); + + assertEquals("PART_ADMISSION", response.getData().get(RESPONDENT_CLAIM_RESPONSE_TYPE_GENERIC)); + assertEquals("COUNTER_ADMIT_OR_ADMIT_PART", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + }*/ + + @Test + void shouldNotSetCounterAdmitOrAdmitPartFlagWhenClaimant1HasFullDefence() { + CaseData caseData = CaseData.builder() + .claimant1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + AboutToStartOrSubmitCallbackResponse response = + (AboutToStartOrSubmitCallbackResponse) setGenericResponseTypeFlag.execute(callbackParams); + + assertEquals("FULL_DEFENCE", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + } + + @Test + void shouldSetGenericResponseTypeFlagWhenBothRespondentsHaveFullDefenceInOneVTwoTwoLegalRepScenario() { + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + + CaseData caseData = CaseData.builder() + .isRespondent1(YES) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .isRespondent2(YES) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .ccdCaseReference(1234L) + .build(); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, ONE_V_TWO_TWO_LEGAL_REP); + + assertEquals("FULL_DEFENCE", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + } + + @Test + void shouldSetGenericResponseTypeFlagWhenRespondent1HasFullDefenceAndRespondent2HasFullAdmissionInOneVTwoTwoLegalRepScenario() { + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + + CaseData caseData = CaseData.builder() + .isRespondent1(YES) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .isRespondent2(YES) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .ccdCaseReference(1234L) + .build(); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, ONE_V_TWO_TWO_LEGAL_REP); + + assertEquals("COUNTER_ADMIT_OR_ADMIT_PART", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + } + + @Test + void shouldSetGenericResponseTypeFlagWhenRespondent1HasFullDefenceAndImmediatePaymentRouteInOneVTwoTwoLegalRepScenario() { + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + + CaseData caseData = CaseData.builder() + .isRespondent1(YES) + .defenceAdmitPartPaymentTimeRouteRequired(RespondentResponsePartAdmissionPaymentTimeLRspec.IMMEDIATELY) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .isRespondent2(YES) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .ccdCaseReference(1234L) + .build(); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, ONE_V_TWO_TWO_LEGAL_REP); + + assertEquals("COUNTER_ADMIT_OR_ADMIT_PART", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + assertEquals("IMMEDIATELY", response.getData().get(DEFENCE_ADMIT_PART_PAYMENT_TIME_ROUTE_GENERIC)); + } + + @Test + void shouldSetGenericResponseTypeFlagWhenRespondent2HasFullAdmissionAndImmediatePaymentRouteInOneVTwoTwoLegalRepScenario() { + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + + CaseData caseData = CaseData.builder() + .isRespondent2(YES) + .defenceAdmitPartPaymentTimeRouteRequired2(RespondentResponsePartAdmissionPaymentTimeLRspec.IMMEDIATELY) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .isRespondent1(YES) + .ccdCaseReference(1234L) + .build(); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, ONE_V_TWO_TWO_LEGAL_REP); + + assertEquals("COUNTER_ADMIT_OR_ADMIT_PART", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + assertEquals("IMMEDIATELY", response.getData().get(DEFENCE_ADMIT_PART_PAYMENT_TIME_ROUTE_GENERIC)); + } + + /*@Test + void shouldSetGenericResponseTypeFlagWhenRespondent1HasFullAdmissionAndSameResponseInOneVTwoOneLegalRepScenario() { + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + + CaseData caseData = CaseData.builder() + .showConditionFlags(EnumSet.of(DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1)) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .respondentResponseIsSame(YES) + .build(); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, ONE_V_TWO_ONE_LEGAL_REP); + + assertEquals("FULL_ADMISSION", response.getData().get(RESPONDENT_CLAIM_RESPONSE_TYPE_GENERIC)); + assertEquals("NOT_FULL_DEFENCE", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + }*/ + + @Test + void shouldSetGenericResponseTypeFlagWhenRespondent1HasDifferentResponseInOneVTwoOneLegalRepScenario() { + CaseData caseData = CaseData.builder() + .showConditionFlags(EnumSet.of(DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1)) + .respondentResponseIsSame(NO) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .build(); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, ONE_V_TWO_ONE_LEGAL_REP); + + assertEquals("No", response.getData().get(RESPONDENT_RESPONSE_IS_SAME)); + assertEquals("No", response.getData().get(SAME_SOLICITOR_SAME_RESPONSE)); + assertEquals("FULL_DEFENCE", response.getData().get(RESPONDENT_CLAIM_RESPONSE_TYPE_GENERIC)); + assertEquals("FULL_DEFENCE", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + } + + @Test + void shouldSetGenericResponseTypeFlagWhenRespondent2HasFullAdmissionAndSameResponseInOneVTwoOneLegalRepScenario() { + CaseData caseData = CaseData.builder() + .showConditionFlags(EnumSet.of(DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_2)) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .respondentResponseIsSame(YES) + .build(); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, ONE_V_TWO_ONE_LEGAL_REP); + + assertEquals("COUNTER_ADMIT_OR_ADMIT_PART", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + } + + /*@Test + void shouldSetGenericResponseTypeFlagWhenRespondent2HasFullDefenceAndSameResponseInOneVTwoOneLegalRepScenario() { + CaseData caseData = CaseData.builder() + .showConditionFlags(EnumSet.of(DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_2)) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .respondentResponseIsSame(YES) + .build(); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, ONE_V_TWO_ONE_LEGAL_REP); + + assertEquals("FULL_DEFENCE", response.getData().get(RESPONDENT_CLAIM_RESPONSE_TYPE_GENERIC)); + assertEquals("FULL_DEFENCE", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + }*/ + + @Test + void shouldNotSetSpecFullAdmissionOrPartAdmissionWhenRespondent2HasNoAdmission() { + CaseData caseData = CaseData.builder() + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .build(); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, TWO_V_ONE); + + assertEquals("FULL_DEFENCE", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + assertEquals("No", response.getData().get(SPEC_FULL_ADMISSION_OR_PART_ADMISSION)); + } + + /*@Test + void shouldNotSetFullDefenceFlagWhenRespondent1ClaimResponseTypeIsNotCounterClaim() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .build(); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, ONE_V_TWO_ONE_LEGAL_REP); + + assertEquals("COUNTER_ADMIT_OR_ADMIT_PART", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + }*/ + + @Test + void shouldSetGenericResponseTypeFlagForOneVTwoTwoLegalRepScenarioWithRespondent2NotResponding() { + when(userService.getUserInfo(anyString())).thenReturn(UserInfo.builder().uid("uid").build()); + + CaseData caseData = CaseData.builder() + .isRespondent1(YES) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .isRespondent2(NO) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .ccdCaseReference(1234L) + .build(); + + when(coreCaseUserService.userHasCaseRole(any(), any(), eq(RESPONDENTSOLICITORTWO))).thenReturn(true); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, ONE_V_TWO_TWO_LEGAL_REP); + + assertEquals("PART_ADMISSION", response.getData().get(RESPONDENT_CLAIM_RESPONSE_TYPE_GENERIC)); + assertEquals("COUNTER_ADMIT_OR_ADMIT_PART", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + assertEquals("Yes", response.getData().get(SPEC_FULL_ADMISSION_OR_PART_ADMISSION)); + } + + @Test + void shouldSetGenericResponseTypeFlagWhenRespondent1HasFullAdmissionAndResponsesAreSameInOneVTwoOneLegalRepScenario() { + CaseData caseData = CaseData.builder() + .showConditionFlags(EnumSet.of(DefendantResponseShowTag.CAN_ANSWER_RESPONDENT_1)) + .respondent2ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .respondentResponseIsSame(YES) + .build(); + + AboutToStartOrSubmitCallbackResponse response = executeWithMockedScenario(caseData, ONE_V_TWO_ONE_LEGAL_REP); + + assertEquals("COUNTER_ADMIT_OR_ADMIT_PART", response.getData().get(MULTI_PARTY_RESPONSE_TYPE_FLAGS)); + } + + /*@Test + void shouldAddSomeoneDisputesWhenIsSomeoneDisputesReturnsTrue() { + CaseData caseData = CaseData.builder() + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .build(); + + CallbackParams callbackParams = buildCallbackParams(caseData); + + when(respondToClaimSpecUtilsDisputeDetails.isSomeoneDisputes(caseData)).thenReturn(true); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) setGenericResponseTypeFlag.execute(callbackParams); + + assertTrue(((List) response.getData().get("showConditionFlags")).contains("SOMEONE_DISPUTES")); + }*/ + + private CallbackParams buildCallbackParams(CaseData caseData) { + return CallbackParams.builder() + .caseData(caseData) + .params(Map.of(BEARER_TOKEN, BEARER_TOKEN_VALUE)) + .build(); + } + + private AboutToStartOrSubmitCallbackResponse executeWithMockedScenario(CaseData caseData, MultiPartyScenario scenario) { + try (MockedStatic mockedScenarioStatic = mockStatic(MultiPartyScenario.class)) { + mockedScenarioStatic.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(scenario); + return (AboutToStartOrSubmitCallbackResponse) setGenericResponseTypeFlag.execute(buildCallbackParams(caseData)); + } + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/SetUploadTimelineTypeFlagTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/SetUploadTimelineTypeFlagTest.java new file mode 100644 index 00000000000..199454ab0ce --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/SetUploadTimelineTypeFlagTest.java @@ -0,0 +1,171 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandlertaskstests; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import uk.gov.hmcts.reform.ccd.client.model.AboutToStartOrSubmitCallbackResponse; +import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.enums.TimelineUploadTypeSpec; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.SetUploadTimelineTypeFlag; +import uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag; +import uk.gov.hmcts.reform.civil.model.CaseData; + +import java.util.EnumSet; +import java.util.HashSet; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.TIMELINE_MANUALLY; +import static uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.DefendantResponseShowTag.TIMELINE_UPLOAD; + +@ExtendWith(MockitoExtension.class) +class SetUploadTimelineTypeFlagTest { + + private ObjectMapper objectMapper; + + @Mock + private CallbackParams callbackParams; + + private SetUploadTimelineTypeFlag setUploadTimelineTypeFlag; + + private CaseData caseData; + + @BeforeEach + void setUp() { + objectMapper = new ObjectMapper(); + setUploadTimelineTypeFlag = new SetUploadTimelineTypeFlag(objectMapper); + caseData = CaseData.builder() + .isRespondent1(YES) + .build(); + + when(callbackParams.getCaseData()).thenReturn(caseData); + } + + private void assertFlags(AboutToStartOrSubmitCallbackResponse response, Set expectedFlags) { + Set actualFlags = objectMapper.convertValue( + response.getData().get("showConditionFlags"), + objectMapper.getTypeFactory().constructCollectionType(Set.class, DefendantResponseShowTag.class) + ); + assertThat(actualFlags).isEqualTo(expectedFlags); + } + + @Test + void shouldAddTimelineUploadFlagWhenTimelineIsUpload() { + caseData = caseData.toBuilder() + .specClaimResponseTimelineList(TimelineUploadTypeSpec.UPLOAD) + .build(); + + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) setUploadTimelineTypeFlag.execute(callbackParams); + assertFlags(response, EnumSet.of(TIMELINE_UPLOAD)); + } + + @Test + void shouldAddTimelineManualFlagWhenTimelineIsManual() { + caseData = caseData.toBuilder() + .specClaimResponseTimelineList(TimelineUploadTypeSpec.MANUAL) + .build(); + + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) setUploadTimelineTypeFlag.execute(callbackParams); + assertFlags(response, EnumSet.of(TIMELINE_MANUALLY)); + } + + @Test + void shouldRemoveExistingTimelineFlags() { + caseData = caseData.toBuilder() + .specClaimResponseTimelineList(TimelineUploadTypeSpec.UPLOAD) + .showConditionFlags(new HashSet<>(EnumSet.of(TIMELINE_MANUALLY, TIMELINE_UPLOAD))) + .build(); + + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) setUploadTimelineTypeFlag.execute(callbackParams); + assertFlags(response, EnumSet.of(TIMELINE_UPLOAD)); + } + + @Test + void shouldNotAddTimelineManualFlagWhenTimelineIsNotManual() { + caseData = caseData.toBuilder() + .specClaimResponseTimelineList(null) + .isRespondent1(YES) + .build(); + + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) setUploadTimelineTypeFlag.execute(callbackParams); + assertFlags(response, new HashSet<>()); + } + + @Test + void shouldNotAddTimelineUploadFlagWhenRespondent1IsNotYes() { + caseData = caseData.toBuilder() + .specClaimResponseTimelineList(TimelineUploadTypeSpec.UPLOAD) + .isRespondent1(null) + .build(); + + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) setUploadTimelineTypeFlag.execute(callbackParams); + assertFlags(response, new HashSet<>()); + } + + @Test + void shouldAddTimelineUploadFlagForRespondent2WhenTimelineIsUpload() { + caseData = caseData.toBuilder() + .isRespondent2(YES) + .specClaimResponseTimelineList2(TimelineUploadTypeSpec.UPLOAD) + .build(); + + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) setUploadTimelineTypeFlag.execute(callbackParams); + assertFlags(response, EnumSet.of(TIMELINE_UPLOAD)); + } + + @Test + void shouldAddTimelineManualFlagForRespondent2WhenTimelineIsManual() { + caseData = caseData.toBuilder() + .isRespondent2(YES) + .specClaimResponseTimelineList2(TimelineUploadTypeSpec.MANUAL) + .build(); + + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) setUploadTimelineTypeFlag.execute(callbackParams); + assertFlags(response, EnumSet.of(TIMELINE_MANUALLY)); + } + + @Test + void shouldAddTimelineManualFlagWhenRespondent1TimelineIsManual() { + caseData = caseData.toBuilder() + .isRespondent1(YES) + .specClaimResponseTimelineList(TimelineUploadTypeSpec.MANUAL) + .build(); + + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) setUploadTimelineTypeFlag.execute(callbackParams); + assertFlags(response, EnumSet.of(TIMELINE_MANUALLY)); + } + + @Test + void shouldNotAddAnyTimelineFlagForRespondent2WhenTimelineIsNull() { + caseData = caseData.toBuilder() + .isRespondent2(YES) + .specClaimResponseTimelineList2(null) + .build(); + + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) setUploadTimelineTypeFlag.execute(callbackParams); + assertFlags(response, new HashSet<>()); + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateDateOfBirthTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateDateOfBirthTest.java new file mode 100644 index 00000000000..eb1feb794f9 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateDateOfBirthTest.java @@ -0,0 +1,282 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandlertaskstests; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.junit.jupiter.MockitoExtension; +import uk.gov.hmcts.reform.ccd.client.model.AboutToStartOrSubmitCallbackResponse; +import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.enums.MultiPartyScenario; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.RespondToClaimSpecUtils; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.ValidateDateOfBirth; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.Party; +import uk.gov.hmcts.reform.civil.validation.DateOfBirthValidator; +import uk.gov.hmcts.reform.civil.validation.PostcodeValidator; + +import java.util.Collections; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORONE; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORTWO; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_ONE_LEGAL_REP; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_TWO_LEGAL_REP; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; + +@Slf4j +@ExtendWith(MockitoExtension.class) +class ValidateDateOfBirthTest { + + @InjectMocks + private ValidateDateOfBirth validateDateOfBirth; + + @Mock + private DateOfBirthValidator dateOfBirthValidator; + + @Mock + private PostcodeValidator postcodeValidator; + + @Mock + private ObjectMapper objectMapper; + + @Mock + private RespondToClaimSpecUtils respondToClaimSpecUtils; + + @Mock + private CallbackParams callbackParams; + + private CaseData caseData; + + @BeforeEach + void setUp() { + caseData = CaseData.builder().build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + } + + @Test + void shouldReturnErrorsWhenDateOfBirthIsInvalid() { + Party respondent = Party.builder().build(); + when(dateOfBirthValidator.validate(respondent)).thenReturn(Collections.singletonList("Invalid date of birth")); + when(callbackParams.getCaseData()).thenReturn(caseData.toBuilder().respondent1(respondent).build()); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateDateOfBirth.execute(callbackParams); + + assertThat(response.getErrors()).contains("Invalid date of birth"); + } + + @Test + void shouldReturnNoErrorsWhenDateOfBirthIsValid() { + Party respondent = Party.builder().build(); + when(dateOfBirthValidator.validate(respondent)).thenReturn(Collections.emptyList()); + when(callbackParams.getCaseData()).thenReturn(caseData.toBuilder().respondent1(respondent).build()); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateDateOfBirth.execute(callbackParams); + + assertThat(response.getErrors()).isEmpty(); + } + + @Test + void shouldReturnErrorsWhenCorrespondenceAddressIsInvalid() { + when(postcodeValidator.validate(null)).thenReturn(Collections.singletonList("Invalid postcode")); + caseData = caseData.toBuilder() + .isRespondent1(YES) + .specAoSRespondentCorrespondenceAddressRequired(NO) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateDateOfBirth.execute(callbackParams); + + assertThat(response.getErrors()).contains("Invalid postcode"); + } + + @Test + void shouldReturnNoErrorsWhenCorrespondenceAddressIsValid() { + when(callbackParams.getCaseData()).thenReturn(caseData.toBuilder().isRespondent1(YES).build()); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateDateOfBirth.execute(callbackParams); + + assertThat(response.getErrors()).isEmpty(); + } + + @Test + void shouldReturnErrorsWhenRespondent1IsNullAndRespondent2IsNotNull() { + Party respondent2 = Party.builder().build(); + when(dateOfBirthValidator.validate(respondent2)).thenReturn(Collections.singletonList("Invalid date of birth")); + when(callbackParams.getCaseData()).thenReturn(caseData.toBuilder().respondent2(respondent2).build()); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateDateOfBirth.execute(callbackParams); + + assertThat(response.getErrors()).contains("Invalid date of birth"); + } + + @Test + void shouldReturnNoErrorsWhenRespondent1IsNotNullAndRespondent2IsNull() { + Party respondent1 = Party.builder().build(); + when(dateOfBirthValidator.validate(respondent1)).thenReturn(Collections.emptyList()); + when(callbackParams.getCaseData()).thenReturn(caseData.toBuilder().respondent1(respondent1).build()); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateDateOfBirth.execute(callbackParams); + + assertThat(response.getErrors()).isEmpty(); + } + + @Test + void shouldReturnErrorsWhenBothRespondentsAreNull() { + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateDateOfBirth.execute(callbackParams); + + assertThat(response.getErrors()).isEmpty(); + } + + @Test + void shouldReturnErrorsWhenSpecAoSRespondent2CorrespondenceAddressRequiredIsNO() { + when(postcodeValidator.validate(null)).thenReturn(Collections.singletonList("Invalid postcode")); + caseData = caseData.toBuilder() + .isRespondent2(YES) + .specAoSRespondent2CorrespondenceAddressRequired(NO) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateDateOfBirth.execute(callbackParams); + + assertThat(response.getErrors()).contains("Invalid postcode"); + } + + @Test + void shouldReturnNoErrorsWhenSpecAoSRespondentCorrespondenceAddressRequiredIsYES() { + caseData = caseData.toBuilder() + .isRespondent1(YES) + .specAoSRespondentCorrespondenceAddressRequired(YES) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateDateOfBirth.execute(callbackParams); + + assertThat(response.getErrors()).isEmpty(); + } + + @Test + void shouldReturnNoErrorsWhenSpecAoSRespondent2CorrespondenceAddressRequiredIsYES() { + caseData = caseData.toBuilder() + .isRespondent2(YES) + .specAoSRespondent2CorrespondenceAddressRequired(YES) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateDateOfBirth.execute(callbackParams); + + assertThat(response.getErrors()).isEmpty(); + } + + @Test + void shouldSetSameSolicitorSameResponseToYesWhenBothSolicitorsRepresentOnlyOneRespondent() { + caseData = CaseData.builder() + .addRespondent2(YES) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_TWO_LEGAL_REP); + when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORTWO)).thenReturn(true); + when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORONE)).thenReturn(true); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateDateOfBirth.execute(callbackParams); + + assertThat(response.getErrors()).isEmpty(); + } + } + + @Test + void shouldSetSameSolicitorSameResponseToYesWhenOnlySecondSolicitorRepresentsOneRespondent() { + caseData = CaseData.builder() + .addRespondent2(YES) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_TWO_LEGAL_REP); + when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORTWO)).thenReturn(true); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateDateOfBirth.execute(callbackParams); + + assertThat(response.getErrors()).isEmpty(); + } + } + + @Test + void shouldSetSameSolicitorSameResponseToYesWhenNoSolicitorRepresentsOneRespondent() { + caseData = CaseData.builder() + .addRespondent2(YES) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_TWO_LEGAL_REP); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateDateOfBirth.execute(callbackParams); + + assertThat(response.getErrors()).isEmpty(); + + } + } + + @Test + void shouldSetSameSolicitorSameResponseToNoWhenOneVTwoOneLegalRepAndRespondentResponseIsNotSame() { + caseData = CaseData.builder() + .addRespondent2(YES) + .respondentResponseIsSame(NO) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_ONE_LEGAL_REP); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateDateOfBirth.execute(callbackParams); + + assertThat(response.getErrors()).isEmpty(); + } + } + + @Test + void shouldNotSetSameSolicitorSameResponseWhenAddRespondent2IsNoAndRespondentResponseIsNotSame() { + caseData = CaseData.builder() + .addRespondent2(NO) + .respondentResponseIsSame(NO) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_ONE_LEGAL_REP); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateDateOfBirth.execute(callbackParams); + + assertThat(response.getErrors()).isEmpty(); + } + } + + @Test + void shouldSetSameSolicitorSameResponseToYesWhenOneVTwoOneLegalRepAndRespondentResponseIsSame() { + caseData = CaseData.builder() + .addRespondent2(YES) + .respondentResponseIsSame(YES) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_ONE_LEGAL_REP); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateDateOfBirth.execute(callbackParams); + + assertThat(response.getErrors()).isEmpty(); + } + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateLengthOfUnemploymentTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateLengthOfUnemploymentTest.java new file mode 100644 index 00000000000..86a0328f7a0 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateLengthOfUnemploymentTest.java @@ -0,0 +1,117 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandlertaskstests; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import uk.gov.hmcts.reform.ccd.client.model.AboutToStartOrSubmitCallbackResponse; +import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.ValidateLengthOfUnemployment; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.LengthOfUnemploymentComplexTypeLRspec; +import uk.gov.hmcts.reform.civil.model.UnemployedComplexTypeLRspec; + +import java.util.Collections; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class ValidateLengthOfUnemploymentTest { + + @InjectMocks + private ValidateLengthOfUnemployment validateLengthOfUnemployment; + + @Mock + private CallbackParams callbackParams; + + private CaseData caseData; + + @BeforeEach + void setUp() { + caseData = CaseData.builder().build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + } + + @Test + void shouldReturnErrorsWhenLengthOfUnemploymentIsInvalid() { + caseData = caseData.toBuilder() + .respondToClaimAdmitPartUnemployedLRspec( + buildUnemployedComplexType(buildLengthOfUnemployment("1.5", "2.5")) + ).build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateLengthOfUnemployment.execute(callbackParams); + + List expectedErrors = Collections.singletonList("Length of time unemployed must be a whole number, for example, 10."); + assertThat(response.getErrors()).isEqualTo(expectedErrors); + } + + @Test + void shouldReturnNoErrorsWhenLengthOfUnemploymentIsValid() { + caseData = caseData.toBuilder() + .respondToClaimAdmitPartUnemployedLRspec( + buildUnemployedComplexType(buildLengthOfUnemployment("2", "3")) + ).build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateLengthOfUnemployment.execute(callbackParams); + + assertThat(response.getErrors()).isEmpty(); + } + + @Test + void shouldReturnNoErrorsWhenRespondToClaimAdmitPartUnemployedLRspecIsNull() { + caseData = caseData.toBuilder() + .respondToClaimAdmitPartUnemployedLRspec(null) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateLengthOfUnemployment.execute(callbackParams); + + assertThat(response.getErrors()).isEmpty(); + } + + @Test + void shouldReturnNoErrorsWhenLengthOfUnemploymentIsNull() { + caseData = caseData.toBuilder() + .respondToClaimAdmitPartUnemployedLRspec( + buildUnemployedComplexType(null) + ).build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateLengthOfUnemployment.execute(callbackParams); + + assertThat(response.getErrors()).isEmpty(); + } + + @Test + void shouldReturnErrorWhenNumberOfMonthsInUnemploymentIsNotWholeNumber() { + caseData = caseData.toBuilder() + .respondToClaimAdmitPartUnemployedLRspec( + buildUnemployedComplexType(buildLengthOfUnemployment("2", "3.5")) + ).build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateLengthOfUnemployment.execute(callbackParams); + + List expectedErrors = Collections.singletonList("Length of time unemployed must be a whole number, for example, 10."); + assertThat(response.getErrors()).isEqualTo(expectedErrors); + } + + private LengthOfUnemploymentComplexTypeLRspec buildLengthOfUnemployment(String years, String months) { + return LengthOfUnemploymentComplexTypeLRspec.builder() + .numberOfYearsInUnemployment(years) + .numberOfMonthsInUnemployment(months) + .build(); + } + + private UnemployedComplexTypeLRspec buildUnemployedComplexType(LengthOfUnemploymentComplexTypeLRspec lengthOfUnemployment) { + return UnemployedComplexTypeLRspec.builder() + .lengthOfUnemployment(lengthOfUnemployment) + .build(); + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateMediationUnavailableDatesTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateMediationUnavailableDatesTest.java new file mode 100644 index 00000000000..862822f85ac --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateMediationUnavailableDatesTest.java @@ -0,0 +1,113 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandlertaskstests; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import uk.gov.hmcts.reform.ccd.client.model.AboutToStartOrSubmitCallbackResponse; +import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.enums.YesOrNo; +import uk.gov.hmcts.reform.civil.enums.dq.UnavailableDateType; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.ValidateMediationUnavailableDates; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.UnavailableDate; +import uk.gov.hmcts.reform.civil.model.mediation.MediationAvailability; + +import java.time.LocalDate; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; +import static uk.gov.hmcts.reform.civil.utils.ElementUtils.wrapElements; + +@ExtendWith(MockitoExtension.class) +class ValidateMediationUnavailableDatesTest { + + @InjectMocks + private ValidateMediationUnavailableDates validateMediationUnavailableDates; + + @Mock + private CallbackParams callbackParams; + + @BeforeEach + void setUp() { + when(callbackParams.getCaseData()).thenReturn(CaseData.builder().build()); + } + + @Test + void shouldReturnErrorsWhenResp1MediationAvailabilityExists() { + MediationAvailability mediationAvailability = buildMediationAvailability(YES, LocalDate.now().minusYears(5)); + CaseData caseData = CaseData.builder() + .resp1MediationAvailability(mediationAvailability) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateMediationUnavailableDates.execute(callbackParams); + + assertThat(response.getErrors()).isNotEmpty(); + } + + @Test + void shouldReturnNoErrorsWhenResp1MediationAvailabilityDoesNotExist() { + MediationAvailability mediationAvailability = buildMediationAvailability(NO, LocalDate.now().minusYears(5)); + CaseData caseData = CaseData.builder() + .resp1MediationAvailability(mediationAvailability) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateMediationUnavailableDates.execute(callbackParams); + + assertThat(response.getErrors()).isEmpty(); + } + + @Test + void shouldReturnErrorsWhenResp2MediationAvailabilityExists() { + MediationAvailability mediationAvailability = buildMediationAvailability(YES, LocalDate.now().minusYears(5)); + CaseData caseData = CaseData.builder() + .resp2MediationAvailability(mediationAvailability) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateMediationUnavailableDates.execute(callbackParams); + + assertThat(response.getErrors()).isNotEmpty(); + } + + @Test + void shouldReturnNoErrorsWhenResp2MediationAvailabilityDoesNotExist() { + MediationAvailability mediationAvailability = buildMediationAvailability(NO, LocalDate.now().minusYears(5)); + CaseData caseData = CaseData.builder() + .resp2MediationAvailability(mediationAvailability) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateMediationUnavailableDates.execute(callbackParams); + + assertThat(response.getErrors()).isEmpty(); + } + + @Test + void shouldReturnNoErrorsWhenNoMediationAvailabilityExists() { + CaseData caseData = CaseData.builder().build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateMediationUnavailableDates.execute(callbackParams); + + assertThat(response.getErrors()).isEmpty(); + } + + private static MediationAvailability buildMediationAvailability(YesOrNo isUnavailable, LocalDate date) { + return MediationAvailability.builder() + .isMediationUnavailablityExists(isUnavailable) + .unavailableDatesForMediation(wrapElements( + UnavailableDate.builder() + .unavailableDateType(UnavailableDateType.SINGLE_DATE) + .date(date) + .build() + )) + .build(); + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateRespondentExpertsTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateRespondentExpertsTest.java new file mode 100644 index 00000000000..603adfe25ee --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateRespondentExpertsTest.java @@ -0,0 +1,292 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandlertaskstests; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.junit.jupiter.MockitoExtension; +import uk.gov.hmcts.reform.ccd.client.model.CallbackResponse; +import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.enums.MultiPartyScenario; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.RespondToClaimSpecUtils; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.ValidateRespondentExperts; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.dq.Experts; +import uk.gov.hmcts.reform.civil.model.dq.Respondent1DQ; +import uk.gov.hmcts.reform.civil.model.dq.Respondent2DQ; +import uk.gov.hmcts.reform.civil.model.dq.Witnesses; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORONE; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORTWO; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_ONE; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_ONE_LEGAL_REP; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_TWO_LEGAL_REP; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.TWO_V_ONE; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; + +@ExtendWith(MockitoExtension.class) +class ValidateRespondentExpertsTest { + + @Mock + private RespondToClaimSpecUtils respondToClaimSpecUtils; + + @Mock + private CallbackParams callbackParams; + + @InjectMocks + private ValidateRespondentExperts validateRespondentExperts; + + private CaseData caseData; + + @BeforeEach + void setUp() { + Respondent1DQ respondent1DQ = Respondent1DQ.builder().build(); + Respondent2DQ respondent2DQ = Respondent2DQ.builder().build(); + caseData = CaseData.builder() + .respondent1DQ(respondent1DQ) + .respondent2DQ(respondent2DQ) + .build(); + } + + @Test + void shouldReturnResponseForOneVOneScenario() { + when(callbackParams.getCaseData()).thenReturn(caseData); + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_ONE); + + CallbackResponse response = validateRespondentExperts.execute(callbackParams); + + assertThat(response).isNotNull(); + } + } + + @Test + void shouldHandleOneVTwoOneLegalRepScenario() { + when(callbackParams.getCaseData()).thenReturn(caseData); + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_ONE_LEGAL_REP); + lenient().when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORONE)).thenReturn(true); + + CallbackResponse response = validateRespondentExperts.execute(callbackParams); + + assertThat(response).isNotNull(); + } + } + + @Test + void shouldValidateRespondent2Experts() { + when(callbackParams.getCaseData()).thenReturn(caseData); + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_ONE_LEGAL_REP); + lenient().when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORTWO)).thenReturn(true); + + CallbackResponse response = validateRespondentExperts.execute(callbackParams); + + assertThat(response).isNotNull(); + } + } + + @Test + void shouldHandleTwoVOneScenario() { + when(callbackParams.getCaseData()).thenReturn(caseData); + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(TWO_V_ONE); + + CallbackResponse response = validateRespondentExperts.execute(callbackParams); + + assertThat(response).isNotNull(); + } + } + + @Test + void shouldHandleOneVTwoTwoLegalRepScenario() { + when(callbackParams.getCaseData()).thenReturn(caseData); + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_TWO_LEGAL_REP); + + CallbackResponse response = validateRespondentExperts.execute(callbackParams); + + assertThat(response).isNotNull(); + } + } + + @Test + void shouldReturnTrueWhenRespondentResponseIsNotSame() { + Respondent1DQ respondent1DQ = Respondent1DQ.builder().build(); + Respondent2DQ respondent2DQ = Respondent2DQ.builder().build(); + caseData = CaseData.builder() + .respondentResponseIsSame(NO) + .respondent1DQ(respondent1DQ) + .respondent2DQ(respondent2DQ) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_TWO_LEGAL_REP); + + CallbackResponse response = validateRespondentExperts.execute(callbackParams); + + assertThat(response).isNotNull(); + } + } + + @Test + void shouldReturnFalseWhenRespondentResponseIsSame() { + Respondent1DQ respondent1DQ = Respondent1DQ.builder().build(); + Respondent2DQ respondent2DQ = Respondent2DQ.builder().build(); + caseData = CaseData.builder() + .respondentResponseIsSame(YES) + .respondent1DQ(respondent1DQ) + .respondent2DQ(respondent2DQ) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_TWO_LEGAL_REP); + + CallbackResponse response = validateRespondentExperts.execute(callbackParams); + + assertThat(response).isNotNull(); + } + } + + @Test + void shouldReturnFalseWhenRespondentResponseIsNull() { + Respondent1DQ respondent1DQ = Respondent1DQ.builder().build(); + Respondent2DQ respondent2DQ = Respondent2DQ.builder().build(); + caseData = CaseData.builder() + .respondentResponseIsSame(null) + .respondent1DQ(respondent1DQ) + .respondent2DQ(respondent2DQ) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_TWO_LEGAL_REP); + + CallbackResponse response = validateRespondentExperts.execute(callbackParams); + + assertThat(response).isNotNull(); + } + } + + @Test + void shouldHandleRespondent2HasDifferentLegalRepScenario() { + Respondent1DQ respondent1DQ = Respondent1DQ.builder().build(); + Witnesses respondent2DQWitnesses = Witnesses.builder() + .witnessesToAppear(YES) + .build(); + Respondent2DQ respondent2DQ = Respondent2DQ.builder() + .respondent2DQWitnesses(respondent2DQWitnesses) + .build(); + caseData = CaseData.builder() + .respondent1DQ(respondent1DQ) + .respondent2DQ(respondent2DQ) + .respondentResponseIsSame(NO) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_ONE_LEGAL_REP); + lenient().when(respondToClaimSpecUtils.isRespondent2HasSameLegalRep(caseData)).thenReturn(true); + lenient().when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORONE)).thenReturn(false); + lenient().when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORTWO)).thenReturn(false); + + CallbackResponse response = validateRespondentExperts.execute(callbackParams); + + assertThat(response).isNotNull(); + } + } + + @Test + void shouldHandleRespondent2HasSameLegalRepScenario() { + Respondent1DQ respondent1DQ = Respondent1DQ.builder().build(); + Respondent2DQ respondent2DQ = Respondent2DQ.builder().respondent2DQExperts(null).build(); + caseData = CaseData.builder() + .respondent1DQ(respondent1DQ) + .respondent2DQ(respondent2DQ) + .respondentResponseIsSame(YES) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_ONE_LEGAL_REP); + lenient().when(respondToClaimSpecUtils.isRespondent2HasSameLegalRep(caseData)).thenReturn(true); + lenient().when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORONE)).thenReturn(false); + lenient().when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORTWO)).thenReturn(false); + + CallbackResponse response = validateRespondentExperts.execute(callbackParams); + + assertThat(response).isNotNull(); + } + } + + @Test + void shouldHandleRespondent2DQExpertsIsNull() { + Respondent1DQ respondent1DQ = Respondent1DQ.builder().build(); + Respondent2DQ respondent2DQ = Respondent2DQ.builder().respondent2DQExperts(null).build(); + caseData = CaseData.builder() + .respondent1DQ(respondent1DQ) + .respondent2DQ(respondent2DQ) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_ONE_LEGAL_REP); + lenient().when(respondToClaimSpecUtils.isRespondent2HasSameLegalRep(caseData)).thenReturn(true); + lenient().when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORONE)).thenReturn(false); + lenient().when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORTWO)).thenReturn(false); + + CallbackResponse response = validateRespondentExperts.execute(callbackParams); + + assertThat(response).isNotNull(); + } + } + + @Test + void shouldValidateRespondent2ExpertsWhenConditionsAreMet() { + Respondent1DQ respondent1DQ = Respondent1DQ.builder().build(); + Respondent2DQ respondent2DQ = Respondent2DQ.builder().respondent2DQExperts(new Experts()).build(); + caseData = CaseData.builder() + .respondentResponseIsSame(NO) + .respondent1DQ(respondent1DQ) + .respondent2DQ(respondent2DQ) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_ONE_LEGAL_REP); + lenient().when(respondToClaimSpecUtils.isRespondent2HasSameLegalRep(caseData)).thenReturn(true); + lenient().when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORONE)).thenReturn(false); + lenient().when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORTWO)).thenReturn(false); + + CallbackResponse response = validateRespondentExperts.execute(callbackParams); + + assertThat(response).isNotNull(); + } + } + + @Test + void shouldHandleWhenRespondent2DQIsNull() { + Respondent1DQ respondent1DQ = Respondent1DQ.builder().build(); + Witnesses respondent2DQWitnesses = Witnesses.builder() + .witnessesToAppear(YES) + .build(); + caseData = CaseData.builder() + .respondent1DQ(respondent1DQ) + .respondent2DQWitnessesSmallClaim(respondent2DQWitnesses) + .respondentResponseIsSame(NO) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_ONE_LEGAL_REP); + lenient().when(respondToClaimSpecUtils.isRespondent2HasSameLegalRep(caseData)).thenReturn(true); + lenient().when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORONE)).thenReturn(false); + lenient().when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORTWO)).thenReturn(false); + + CallbackResponse response = validateRespondentExperts.execute(callbackParams); + + assertThat(response).isNotNull(); + } + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateRespondentPaymentDateTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateRespondentPaymentDateTest.java new file mode 100644 index 00000000000..6dd29dcf54b --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateRespondentPaymentDateTest.java @@ -0,0 +1,61 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandlertaskstests; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import uk.gov.hmcts.reform.ccd.client.model.AboutToStartOrSubmitCallbackResponse; +import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.ValidateRespondentPaymentDate; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.RespondToClaimAdmitPartLRspec; +import uk.gov.hmcts.reform.civil.validation.PaymentDateValidator; + +import java.util.Collections; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class ValidateRespondentPaymentDateTest { + + @InjectMocks + private ValidateRespondentPaymentDate validateRespondentPaymentDate; + + @Mock + private PaymentDateValidator paymentDateValidator; + + @Mock + private CallbackParams callbackParams; + + private RespondToClaimAdmitPartLRspec respondToClaimAdmitPartLRspec; + + @BeforeEach + void setUp() { + respondToClaimAdmitPartLRspec = RespondToClaimAdmitPartLRspec.builder().build(); + CaseData caseData = CaseData.builder().respondToClaimAdmitPartLRspec(respondToClaimAdmitPartLRspec).build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + } + + @Test + void shouldReturnErrorsWhenPaymentDateIsInvalid() { + List errors = Collections.singletonList("Invalid payment date"); + when(paymentDateValidator.validate(respondToClaimAdmitPartLRspec)).thenReturn(errors); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateRespondentPaymentDate.execute(callbackParams); + + assertThat(response.getErrors()).isEqualTo(errors); + } + + @Test + void shouldReturnNoErrorsWhenPaymentDateIsValid() { + when(paymentDateValidator.validate(respondToClaimAdmitPartLRspec)).thenReturn(Collections.emptyList()); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateRespondentPaymentDate.execute(callbackParams); + + assertThat(response.getErrors()).isEmpty(); + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateRespondentWitnessesTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateRespondentWitnessesTest.java new file mode 100644 index 00000000000..3307da70c8b --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateRespondentWitnessesTest.java @@ -0,0 +1,328 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandlertaskstests; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.junit.jupiter.MockitoExtension; +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.CallbackParams; +import uk.gov.hmcts.reform.civil.enums.MultiPartyScenario; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.RespondToClaimSpecUtils; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.ValidateRespondentWitnesses; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.common.Element; +import uk.gov.hmcts.reform.civil.model.dq.Respondent1DQ; +import uk.gov.hmcts.reform.civil.model.dq.Respondent2DQ; +import uk.gov.hmcts.reform.civil.model.dq.Witness; +import uk.gov.hmcts.reform.civil.model.dq.Witnesses; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORONE; +import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORTWO; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_ONE_LEGAL_REP; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; +import static uk.gov.hmcts.reform.civil.utils.ElementUtils.element; + +@ExtendWith(MockitoExtension.class) +class ValidateRespondentWitnessesTest { + + @InjectMocks + private ValidateRespondentWitnesses validateRespondentWitnesses; + + @Mock + private RespondToClaimSpecUtils respondToClaimSpecUtils; + + @Mock + private CallbackParams callbackParams; + + private CaseData caseData; + + @BeforeEach + void setUp() { + caseData = CaseData.builder().build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + } + + @Test + void shouldReturnErrorsWhenWitnessDetailsAreMissing() { + caseData = CaseData.builder() + .respondent1DQWitnessesRequiredSpec(YES) + .build(); + + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateRespondentWitnesses.execute(callbackParams); + + assertThat(response.getErrors()).contains("Witness details required"); + } + + @Test + void shouldReturnNoErrorsWhenWitnessDetailsArePresent() { + List> witnessDetails = List.of(element(Witness.builder().firstName("First").build())); + caseData = CaseData.builder() + .respondent1DQWitnessesRequiredSpec(YES) + .respondent1DQWitnessesDetailsSpec(witnessDetails) + .build(); + + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateRespondentWitnesses.execute(callbackParams); + + assertThat(response.getErrors()).isEmpty(); + } + + @Test + void shouldHandleMultiPartyScenario() { + try (MockedStatic mockedStatic = mockStatic(MultiPartyScenario.class)) { + mockedStatic.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(MultiPartyScenario.ONE_V_ONE); + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateRespondentWitnesses.execute(callbackParams); + + assertThat(response.getErrors()).isEmpty(); + } + } + + @Test + void shouldHandleMultiPartyScenarioWhenNotOneVOne() { + try (MockedStatic mockedStatic = mockStatic(MultiPartyScenario.class)) { + mockedStatic.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_ONE_LEGAL_REP); + when(callbackParams.getCaseData()).thenReturn(caseData); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateRespondentWitnesses.execute(callbackParams); + + assertThat(response.getErrors()).isEmpty(); + } + } + + @Test + void shouldValidateRespondent2Experts() { + Respondent1DQ respondent1DQ = Respondent1DQ.builder().build(); + Respondent2DQ respondent2DQ = Respondent2DQ.builder().build(); + caseData = CaseData.builder() + .respondent1DQ(respondent1DQ) + .respondent2DQ(respondent2DQ) + .build(); + + when(callbackParams.getCaseData()).thenReturn(caseData); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_ONE_LEGAL_REP); + lenient().when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORTWO)).thenReturn(true); + + CallbackResponse response = validateRespondentWitnesses.execute(callbackParams); + + assertThat(response).isNotNull(); + } + } + + @Test + void shouldHandleOneVTwoOneLegalRepScenario() { + Respondent1DQ respondent1DQ = Respondent1DQ.builder().build(); + Respondent2DQ respondent2DQ = Respondent2DQ.builder().build(); + caseData = CaseData.builder() + .respondent1DQ(respondent1DQ) + .respondent2DQ(respondent2DQ) + .build(); + + when(callbackParams.getCaseData()).thenReturn(caseData); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_ONE_LEGAL_REP); + when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORONE)).thenReturn(true); + + CallbackResponse response = validateRespondentWitnesses.execute(callbackParams); + + assertThat(response).isNotNull(); + } + } + + @Test + void shouldHandleRespondent2HasDifferentLegalRepScenario() { + Respondent1DQ respondent1DQ = Respondent1DQ.builder().build(); + Witnesses respondent2DQWitnesses = Witnesses.builder() + .witnessesToAppear(YES) + .build(); + Respondent2DQ respondent2DQ = Respondent2DQ.builder() + .respondent2DQWitnesses(respondent2DQWitnesses) + .build(); + caseData = CaseData.builder() + .respondent1DQ(respondent1DQ) + .respondent2DQ(respondent2DQ) + .respondentResponseIsSame(NO) + .build(); + + when(callbackParams.getCaseData()).thenReturn(caseData); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_ONE_LEGAL_REP); + lenient().when(respondToClaimSpecUtils.isRespondent2HasSameLegalRep(caseData)).thenReturn(true); + when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORONE)).thenReturn(false); + when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORTWO)).thenReturn(false); + + CallbackResponse response = validateRespondentWitnesses.execute(callbackParams); + + assertThat(response).isNotNull(); + } + } + + @Test + void shouldHandleRespondentResponseIsSameIsNull() { + Respondent1DQ respondent1DQ = Respondent1DQ.builder().build(); + Respondent2DQ respondent2DQ = Respondent2DQ.builder().build(); + caseData = CaseData.builder() + .respondent1DQ(respondent1DQ) + .respondent2DQ(respondent2DQ) + .respondentResponseIsSame(null) + .build(); + + when(callbackParams.getCaseData()).thenReturn(caseData); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_ONE_LEGAL_REP); + lenient().when(respondToClaimSpecUtils.isRespondent2HasSameLegalRep(caseData)).thenReturn(true); + when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORONE)).thenReturn(false); + when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORTWO)).thenReturn(false); + + CallbackResponse response = validateRespondentWitnesses.execute(callbackParams); + + assertThat(response).isNotNull(); + } + } + + @Test + void shouldHandleRespondent2DQWitnessesIsNotNull() { + Respondent1DQ respondent1DQ = Respondent1DQ.builder().build(); + Witnesses respondent2DQWitnesses = Witnesses.builder().witnessesToAppear(YES).build(); + Respondent2DQ respondent2DQ = Respondent2DQ.builder().respondent2DQWitnesses(respondent2DQWitnesses).build(); + caseData = CaseData.builder() + .respondent1DQ(respondent1DQ) + .respondent2DQ(respondent2DQ) + .build(); + + when(callbackParams.getCaseData()).thenReturn(caseData); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_ONE_LEGAL_REP); + lenient().when(respondToClaimSpecUtils.isRespondent2HasSameLegalRep(caseData)).thenReturn(true); + when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORONE)).thenReturn(false); + when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORTWO)).thenReturn(false); + + CallbackResponse response = validateRespondentWitnesses.execute(callbackParams); + + assertThat(response).isNotNull(); + } + } + + @Test + void shouldHandleRespondent2HasDifferentLegalRepScenarioWhenWitnessesAreNull() { + Respondent1DQ respondent1DQ = Respondent1DQ.builder().build(); + Respondent2DQ respondent2DQ = Respondent2DQ.builder().build(); + caseData = CaseData.builder() + .respondent1DQ(respondent1DQ) + .respondent2DQ(respondent2DQ) + .respondentResponseIsSame(NO) + .build(); + + when(callbackParams.getCaseData()).thenReturn(caseData); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_ONE_LEGAL_REP); + lenient().when(respondToClaimSpecUtils.isRespondent2HasSameLegalRep(caseData)).thenReturn(true); + when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORONE)).thenReturn(false); + when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORTWO)).thenReturn(false); + + CallbackResponse response = validateRespondentWitnesses.execute(callbackParams); + + assertThat(response).isNotNull(); + } + } + + @Test + void shouldHandleRespondent2HasDifferentLegalRepScenarioWhenResponseIsSame() { + Respondent1DQ respondent1DQ = Respondent1DQ.builder().build(); + Witnesses respondent2DQWitnesses = Witnesses.builder() + .witnessesToAppear(YES) + .build(); + Respondent2DQ respondent2DQ = Respondent2DQ.builder() + .respondent2DQWitnesses(respondent2DQWitnesses) + .build(); + caseData = CaseData.builder() + .respondent1DQ(respondent1DQ) + .respondent2DQ(respondent2DQ) + .respondentResponseIsSame(YES) + .build(); + + when(callbackParams.getCaseData()).thenReturn(caseData); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_ONE_LEGAL_REP); + lenient().when(respondToClaimSpecUtils.isRespondent2HasSameLegalRep(caseData)).thenReturn(true); + when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORONE)).thenReturn(false); + when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORTWO)).thenReturn(false); + + CallbackResponse response = validateRespondentWitnesses.execute(callbackParams); + + assertThat(response).isNotNull(); + } + } + + @Test + void shouldHandleRespondent2DQIsNull() { + Respondent1DQ respondent1DQ = Respondent1DQ.builder().build(); + caseData = CaseData.builder() + .respondent1DQ(respondent1DQ) + .respondent2DQ(null) + .build(); + + when(callbackParams.getCaseData()).thenReturn(caseData); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_ONE_LEGAL_REP); + lenient().when(respondToClaimSpecUtils.isRespondent2HasSameLegalRep(caseData)).thenReturn(true); + when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORONE)).thenReturn(false); + when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORTWO)).thenReturn(false); + + CallbackResponse response = validateRespondentWitnesses.execute(callbackParams); + + assertThat(response).isNotNull(); + } + } + + @Test + void shouldHandleRespondent2DQIsNotNullButWitnessesAreNull() { + Respondent1DQ respondent1DQ = Respondent1DQ.builder().build(); + Witnesses respondent2DQWitnesses = Witnesses.builder() + .witnessesToAppear(YES) + .build(); + + caseData = CaseData.builder() + .respondent1DQ(respondent1DQ) + .respondentResponseIsSame(NO) + .respondent2DQWitnessesSmallClaim(respondent2DQWitnesses) + .build(); + + when(callbackParams.getCaseData()).thenReturn(caseData); + + try (MockedStatic mockedScenario = mockStatic(MultiPartyScenario.class)) { + mockedScenario.when(() -> MultiPartyScenario.getMultiPartyScenario(caseData)).thenReturn(ONE_V_TWO_ONE_LEGAL_REP); + lenient().when(respondToClaimSpecUtils.isRespondent2HasSameLegalRep(caseData)).thenReturn(true); + when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORONE)).thenReturn(false); + when(respondToClaimSpecUtils.isSolicitorRepresentsOnlyOneOfRespondents(callbackParams, RESPONDENTSOLICITORTWO)).thenReturn(false); + + CallbackResponse response = validateRespondentWitnesses.execute(callbackParams); + + assertThat(response).isNotNull(); + } + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateUnavailableDatesTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateUnavailableDatesTest.java new file mode 100644 index 00000000000..f2691f8bfd5 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/respondtoclaimspeccallbackhandlertaskstests/ValidateUnavailableDatesTest.java @@ -0,0 +1,99 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandlertaskstests; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import uk.gov.hmcts.reform.ccd.client.model.AboutToStartOrSubmitCallbackResponse; +import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.constants.SpecJourneyConstantLRSpec; +import uk.gov.hmcts.reform.civil.handler.callback.user.respondtoclaimspeccallbackhandler.ValidateUnavailableDates; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.dq.Hearing; +import uk.gov.hmcts.reform.civil.model.dq.Respondent1DQ; +import uk.gov.hmcts.reform.civil.model.dq.Respondent2DQ; +import uk.gov.hmcts.reform.civil.model.dq.SmallClaimHearing; +import uk.gov.hmcts.reform.civil.validation.UnavailableDateValidator; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; + +@ExtendWith(MockitoExtension.class) +class ValidateUnavailableDatesTest { + + @InjectMocks + private ValidateUnavailableDates validateUnavailableDates; + + @Mock + private UnavailableDateValidator unavailableDateValidator; + + @Mock + private CallbackParams callbackParams; + + private CaseData caseData; + + @BeforeEach + void setUp() { + caseData = CaseData.builder() + .respondent1DQ(Respondent1DQ.builder().build()) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + } + + private void setupCaseDataForSmallClaim(SmallClaimHearing smallClaimHearing, boolean isRespondent2) { + caseData = CaseData.builder() + .responseClaimTrack(SpecJourneyConstantLRSpec.SMALL_CLAIM) + .isRespondent2(isRespondent2 ? YES : NO) + .respondent1DQ(Respondent1DQ.builder().respondent1DQHearingSmallClaim(isRespondent2 ? null : smallClaimHearing).build()) + .respondent2DQ(isRespondent2 ? Respondent2DQ.builder().respondent2DQHearingSmallClaim(smallClaimHearing).build() : null) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + } + + private void setupCaseDataForFastClaim(Hearing hearing) { + caseData = CaseData.builder() + .responseClaimTrack("FAST_CLAIM") + .respondent1DQ(Respondent1DQ.builder().respondent1DQHearingFastClaim(hearing).build()) + .build(); + when(callbackParams.getCaseData()).thenReturn(caseData); + } + + @Test + void shouldReturnErrorsForRespondent2SmallClaimHearing() { + SmallClaimHearing smallClaimHearing = SmallClaimHearing.builder().build(); + setupCaseDataForSmallClaim(smallClaimHearing, true); + when(unavailableDateValidator.validateSmallClaimsHearing(smallClaimHearing)).thenReturn(List.of("Error")); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateUnavailableDates.execute(callbackParams); + + assertThat(response.getErrors()).contains("Error"); + } + + @Test + void shouldReturnNoErrorsForRespondent1SmallClaimHearing() { + SmallClaimHearing smallClaimHearing = SmallClaimHearing.builder().build(); + setupCaseDataForSmallClaim(smallClaimHearing, false); + when(unavailableDateValidator.validateSmallClaimsHearing(smallClaimHearing)).thenReturn(List.of()); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateUnavailableDates.execute(callbackParams); + + assertThat(response.getErrors()).isEmpty(); + } + + @Test + void shouldReturnErrorsForFastClaimHearing() { + Hearing hearing = Hearing.builder().build(); + setupCaseDataForFastClaim(hearing); + when(unavailableDateValidator.validateFastClaimHearing(hearing)).thenReturn(List.of("Error")); + + AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) validateUnavailableDates.execute(callbackParams); + + assertThat(response.getErrors()).contains("Error"); + } +}