diff --git a/src/e2eTest/data/page-data/statementOfTruth.page.data.ts b/src/e2eTest/data/page-data/statementOfTruth.page.data.ts index 2f1543f4ba..ffc0ac17eb 100644 --- a/src/e2eTest/data/page-data/statementOfTruth.page.data.ts +++ b/src/e2eTest/data/page-data/statementOfTruth.page.data.ts @@ -1,5 +1,21 @@ export const statementOfTruth = { - title: 'Create a case - HM Courts & Tribunals Service - GOV.UK', - mainHeader: 'Statement of truth', - continue: 'Continue' + title: `Create a case - HM Courts & Tribunals Service - GOV.UK`, + mainHeader: `Statement of truth`, + caseNumberParagraph: `Case number:`, + cancelLink: `Cancel`, + previousLink: `Previous`, + continueButton: `Continue`, + completedByLabel: `Completed by`, + claimantRadioOption: `Claimant`, + claimantLegalRepresentativeRadioOption: `Claimant’s legal representative (as defined by CPR 2.3 (1))`, + signThisStatementHiddenCheckbox: `The claimant believes that the facts stated in this claim form are true. I am authorised by the claimant to sign this statement.`, + fullNameHiddenTextLabel: `Full name`, + nameOfFirmHiddenTextLabel: `Name of firm`, + positionOrOfficeHeldHiddenTextLabel: `Position or office held`, + fullNameHiddenTextInput: `John Doe`, + nameOfFirmHiddenTextInput: `Doe & Co Solicitors`, + positionOrOfficeHeldHiddenTextInput: `Solicitor`, + iBelieveTheFactsHiddenCheckbox: `I believe that the facts stated in this claim form are true.`, + iUnderstandThatProceedingsParagraph: `I understand that proceedings for contempt of court may be brought against anyone who makes, or causes to be made, a false statement in a document verified by a statement of truth without an honest belief in its truth.`, + cymraegToggleLink: `Cymraeg`, } diff --git a/src/e2eTest/test-README.md b/src/e2eTest/test-README.md index 48efb3f708..a2f73b8f17 100644 --- a/src/e2eTest/test-README.md +++ b/src/e2eTest/test-README.md @@ -135,7 +135,7 @@ Playwright 1.30+ | TypeScript 4.9+ | selectUnderlesseeOrMortgageeDetails | `performAction('selectUnderlesseeOrMortgageeDetails', { nameOption: 'Yes', addressOption: 'Yes', anotherUnderlesseeOrMortgageeOption: 'Yes'})` | | addDefendantDetails | `performAction('addDefendantDetails', { nameOption: defendantDetails.no, correspondenceAddressOption: defendantDetails.no, addAdditionalDefendantsOption: defendantDetails.no})` | | selectProhibitedConductStandardContract | `performAction('selectProhibitedConductStandardContract', prohibitedConductStandardContractWales.yes)` | -| addDefendantDetails | `performAction('addDefendantDetails', { nameOption: defendantDetails.no, correspondenceAddressOption: defendantDetails.no, addAdditionalDefendantsOption: defendantDetails.no})` | +| selectStatementOfTruth | `performAction('selectStatementOfTruth', {completedBy: statementOfTruth.completedByLabel, option :statementOfTruth.claimantRadioOption})` | | submitAddressCheckYourAnswers | `submitAddressCheckYourAnswers')` | ### Validations | Validation | Example Usage | diff --git a/src/e2eTest/tests/createCase.saveResume.spec.ts b/src/e2eTest/tests/createCase.saveResume.spec.ts index 5553be9b1d..cbb07d8fa8 100644 --- a/src/e2eTest/tests/createCase.saveResume.spec.ts +++ b/src/e2eTest/tests/createCase.saveResume.spec.ts @@ -191,7 +191,12 @@ test.describe('[Create Case - With resume claim options]', async () => { option: languageUsed.english }); await performAction('completingYourClaim', completeYourClaim.submitAndClaimNow); - await performAction('clickButton', statementOfTruth.continue); + await performAction('selectStatementOfTruth', { + completedBy: statementOfTruth.claimantRadioOption, + iBelieveCheckbox: statementOfTruth.iBelieveTheFactsHiddenCheckbox, + fullNameTextInput: statementOfTruth.fullNameHiddenTextInput, + positionOrOfficeTextInput: statementOfTruth.positionOrOfficeHeldHiddenTextInput + }); await performAction('clickButton', checkYourAnswers.saveAndContinue); await performValidation('bannerAlert', 'Case #.* has been updated with event: Make a claim'); await performValidations( @@ -308,8 +313,7 @@ test.describe('[Create Case - With resume claim options]', async () => { question: languageUsed.whichLanguageUsedQuestion, option: languageUsed.english }); - await performAction('completingYourClaim', completeYourClaim.submitAndClaimNow); - await performAction('clickButton', statementOfTruth.continue); + await performAction('completingYourClaim', completeYourClaim.saveItForLater); await performAction('clickButton', checkYourAnswers.saveAndContinue); await performValidation('bannerAlert', 'Case #.* has been updated with event: Make a claim'); await performValidations( diff --git a/src/e2eTest/tests/createCase.spec.ts b/src/e2eTest/tests/createCase.spec.ts index a0f4f3f4a1..6d2b75327f 100644 --- a/src/e2eTest/tests/createCase.spec.ts +++ b/src/e2eTest/tests/createCase.spec.ts @@ -192,7 +192,12 @@ test.describe('[Create Case - England] @regression', async () => { await performAction('selectApplications', applications.yes); await performAction('selectLanguageUsed', {question: languageUsed.whichLanguageUsedQuestion, option: languageUsed.english}); await performAction('completingYourClaim', completeYourClaim.submitAndClaimNow); - await performAction('clickButton', statementOfTruth.continue); + await performAction('selectStatementOfTruth', { + completedBy: statementOfTruth.claimantRadioOption, + iBelieveCheckbox: statementOfTruth.iBelieveTheFactsHiddenCheckbox, + fullNameTextInput: statementOfTruth.fullNameHiddenTextInput, + positionOrOfficeTextInput: statementOfTruth.positionOrOfficeHeldHiddenTextInput + }); await performAction('clickButton', checkYourAnswers.saveAndContinue); await performValidation('bannerAlert', 'Case #.* has been updated with event: Make a claim'); await performValidations( @@ -317,7 +322,13 @@ test.describe('[Create Case - England] @regression', async () => { await performAction('selectApplications', applications.yes); await performAction('selectLanguageUsed', {question: languageUsed.whichLanguageUsedQuestion, option: languageUsed.english}); await performAction('completingYourClaim', completeYourClaim.submitAndClaimNow); - await performAction('clickButton', statementOfTruth.continue); + await performAction('selectStatementOfTruth', { + completedBy: statementOfTruth.claimantLegalRepresentativeRadioOption, + signThisStatementCheckbox: statementOfTruth.signThisStatementHiddenCheckbox, + fullNameTextInput: statementOfTruth.fullNameHiddenTextInput, + nameOfFirmTextInput: statementOfTruth.nameOfFirmHiddenTextInput, + positionOrOfficeTextInput: statementOfTruth.positionOrOfficeHeldHiddenTextInput + }); await performAction('clickButton', checkYourAnswers.saveAndContinue); await performValidation('bannerAlert', 'Case #.* has been updated with event: Make a claim'); await performValidations( diff --git a/src/e2eTest/utils/actions/custom-actions/createCase.action.ts b/src/e2eTest/utils/actions/custom-actions/createCase.action.ts index 04e074e085..0860437b20 100644 --- a/src/e2eTest/utils/actions/custom-actions/createCase.action.ts +++ b/src/e2eTest/utils/actions/custom-actions/createCase.action.ts @@ -6,7 +6,7 @@ import {performAction, performActions, performValidation} from '@utils/controlle import {createCase, addressDetails, housingPossessionClaim, defendantDetails, claimantName, contactPreferences, mediationAndSettlement, tenancyLicenceDetails, resumeClaimOptions, rentDetails, accessTokenApiData, caseApiData, dailyRentAmount, reasonsForPossession, detailsOfRentArrears, claimantType, claimType, groundsForPossession, preActionProtocol, noticeOfYourIntention, borderPostcode, rentArrearsPossessionGrounds, rentArrearsOrBreachOfTenancy, noticeDetails, moneyJudgment, whatAreYourGroundsForPossession, languageUsed, defendantCircumstances, applications, claimantCircumstances, claimingCosts, alternativesToPossession, reasonsForRequestingADemotionOrder, statementOfExpressTerms, reasonsForRequestingASuspensionOrder, uploadAdditionalDocs, additionalReasonsForPossession, completeYourClaim, home, search, userIneligible, - whatAreYourGroundsForPossessionWales, underlesseeOrMortgageeDetails, reasonsForRequestingASuspensionAndDemotionOrder, provideMoreDetailsOfClaim, addressCheckYourAnswers} from "@data/page-data"; + whatAreYourGroundsForPossessionWales, underlesseeOrMortgageeDetails, reasonsForRequestingASuspensionAndDemotionOrder, provideMoreDetailsOfClaim, addressCheckYourAnswers, statementOfTruth} from "@data/page-data"; export let caseInfo: { id: string; fid: string; state: string }; export let caseNumber: string; @@ -63,7 +63,8 @@ export class CreateCaseAction implements IAction { ['selectUnderlesseeOrMortgageeEntitledToClaim', () => this.selectUnderlesseeOrMortgageeEntitledToClaim(fieldName as actionRecord)], ['selectUnderlesseeOrMortgageeDetails', () => this.selectUnderlesseeOrMortgageeDetails(fieldName as actionRecord)], ['wantToUploadDocuments', () => this.wantToUploadDocuments(fieldName as actionRecord)], - ['uploadAdditionalDocs', () => this.uploadAdditionalDocs(fieldName as actionRecord)] + ['uploadAdditionalDocs', () => this.uploadAdditionalDocs(fieldName as actionRecord)], + ['selectStatementOfTruth', () => this.selectStatementOfTruth(fieldName as actionRecord)] ]); const actionToPerform = actionsMap.get(action); if (!actionToPerform) throw new Error(`No action found for '${action}'`); @@ -758,6 +759,30 @@ export class CreateCaseAction implements IAction { } + private async selectStatementOfTruth(claimantDetails: actionRecord) { + await performValidation('text', {elementType: 'paragraph', text: 'Case number: '+caseNumber}); + await performValidation('text', { + elementType: 'paragraph', + text: `Property address: ${addressInfo.buildingStreet}, ${addressInfo.townCity}, ${addressInfo.engOrWalPostcode}` + }); + await performAction('clickRadioButton', { + question: statementOfTruth.completedByLabel, + option: claimantDetails.completedBy + }); + if(claimantDetails.completedBy == statementOfTruth.claimantRadioOption){ + await performAction('check', claimantDetails.iBelieveCheckbox); + await performAction('inputText', statementOfTruth.fullNameHiddenTextLabel, claimantDetails.fullNameTextInput); + await performAction('inputText', statementOfTruth.positionOrOfficeHeldHiddenTextLabel, claimantDetails.positionOrOfficeTextInput); + } + if(claimantDetails.completedBy == statementOfTruth.claimantLegalRepresentativeRadioOption){ + await performAction('check', claimantDetails.signThisStatementCheckbox); + await performAction('inputText', statementOfTruth.fullNameHiddenTextLabel, claimantDetails.fullNameTextInput); + await performAction('inputText', statementOfTruth.nameOfFirmHiddenTextLabel, claimantDetails.nameOfFirmTextInput); + await performAction('inputText', statementOfTruth.positionOrOfficeHeldHiddenTextLabel, claimantDetails.positionOrOfficeTextInput); + } + await performAction('clickButton', statementOfTruth.continueButton); + } + private async reloginAndFindTheCase(userInfo: actionData) { await performAction('navigateToUrl', process.env.MANAGE_CASE_BASE_URL); await performAction('login', userInfo); diff --git a/src/e2eTest/utils/actions/custom-actions/custom-actions-enforcement/makeClaim.action.ts b/src/e2eTest/utils/actions/custom-actions/custom-actions-enforcement/makeClaim.action.ts index 92ac90f01b..27f4b82db4 100644 --- a/src/e2eTest/utils/actions/custom-actions/custom-actions-enforcement/makeClaim.action.ts +++ b/src/e2eTest/utils/actions/custom-actions/custom-actions-enforcement/makeClaim.action.ts @@ -100,7 +100,12 @@ export class MakeClaimAction implements IAction { option: languageUsed.english, }); await performAction('completingYourClaim', completeYourClaim.submitAndClaimNow); - await performAction('clickButton', statementOfTruth.continue); + await performAction('selectStatementOfTruth', { + completedBy: statementOfTruth.claimantRadioOption, + iBelieveCheckbox: statementOfTruth.iBelieveTheFactsHiddenCheckbox, + fullNameTextInput: statementOfTruth.fullNameHiddenTextInput, + positionOrOfficeTextInput: statementOfTruth.positionOrOfficeHeldHiddenTextInput + }); await performAction('clickButton', checkYourAnswers.saveAndContinue); await performValidation('bannerAlert', 'Case #.* has been updated with event: Make a claim'); } diff --git a/src/e2eTest/utils/registry/action.registry.ts b/src/e2eTest/utils/registry/action.registry.ts index f393f33dda..8be8b185dd 100644 --- a/src/e2eTest/utils/registry/action.registry.ts +++ b/src/e2eTest/utils/registry/action.registry.ts @@ -84,6 +84,7 @@ export class ActionRegistry { ['selectProhibitedConductStandardContract', new CreateCaseWalesAction()], ['selectOccupationContractOrLicenceDetails', new CreateCaseWalesAction()], ['provideMoreDetailsOfClaim', new CreateCaseAction()], + ['selectStatementOfTruth', new CreateCaseAction()], ['selectAsbQuestions', new CreateCaseWalesAction()] ]); diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/PCSCase.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/PCSCase.java index 36ce1fbc69..067d11b31d 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/PCSCase.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/PCSCase.java @@ -767,6 +767,9 @@ public class PCSCase { ) private WaysToPay waysToPay; + @CCD + private StatementOfTruthDetails statementOfTruth; + @CCD(searchable = false) private YesOrNo showPreActionProtocolPageWales; diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/StatementOfTruthAgreementClaimant.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/StatementOfTruthAgreementClaimant.java new file mode 100644 index 0000000000..f0bdfb641d --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/StatementOfTruthAgreementClaimant.java @@ -0,0 +1,21 @@ +package uk.gov.hmcts.reform.pcs.ccd.domain; + +import uk.gov.hmcts.ccd.sdk.api.HasLabel; + +public enum StatementOfTruthAgreementClaimant implements HasLabel { + + BELIEVE_TRUE("I believe that the facts stated in this claim form are true."); + + private final String label; + + StatementOfTruthAgreementClaimant(String label) { + this.label = label; + } + + @Override + public String getLabel() { + return label; + } + +} + diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/StatementOfTruthAgreementLegalRep.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/StatementOfTruthAgreementLegalRep.java new file mode 100644 index 0000000000..5a3d25c8ef --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/StatementOfTruthAgreementLegalRep.java @@ -0,0 +1,22 @@ +package uk.gov.hmcts.reform.pcs.ccd.domain; + +import uk.gov.hmcts.ccd.sdk.api.HasLabel; + +public enum StatementOfTruthAgreementLegalRep implements HasLabel { + + AGREED("The claimant believes that the facts stated in this claim form are true. " + + "I am authorised by the claimant to sign this statement."); + + private final String label; + + StatementOfTruthAgreementLegalRep(String label) { + this.label = label; + } + + @Override + public String getLabel() { + return label; + } + +} + diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/StatementOfTruthCompletedBy.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/StatementOfTruthCompletedBy.java new file mode 100644 index 0000000000..ae044a3722 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/StatementOfTruthCompletedBy.java @@ -0,0 +1,12 @@ +package uk.gov.hmcts.reform.pcs.ccd.domain; + +import uk.gov.hmcts.ccd.sdk.api.CCD; + +public enum StatementOfTruthCompletedBy { + + @CCD(label = "Claimant") CLAIMANT, + + @CCD(label = "Claimant’s legal representative (as defined by CPR 2.3 (1))") + LEGAL_REPRESENTATIVE + +} diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/StatementOfTruthDetails.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/StatementOfTruthDetails.java new file mode 100644 index 0000000000..3c42e78723 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/StatementOfTruthDetails.java @@ -0,0 +1,48 @@ +package uk.gov.hmcts.reform.pcs.ccd.domain; + +import lombok.Builder; +import lombok.Data; +import uk.gov.hmcts.ccd.sdk.api.CCD; +import uk.gov.hmcts.ccd.sdk.api.ComplexType; + +import java.util.List; + +import static uk.gov.hmcts.ccd.sdk.type.FieldType.MultiSelectList; + +@Data +@Builder +@ComplexType(generate = true) +public class StatementOfTruthDetails { + + @CCD(label = "Completed by") + private StatementOfTruthCompletedBy completedBy; + + @CCD( + typeOverride = MultiSelectList, + typeParameterOverride = "StatementOfTruthAgreementClaimant" + ) + private List agreementClaimant; + + @CCD(label = "Full name") + private String fullNameClaimant; + + @CCD(label = "Position or office held") + private String positionClaimant; + + @CCD( + typeOverride = MultiSelectList, + typeParameterOverride = "StatementOfTruthAgreementLegalRep" + ) + private List agreementLegalRep; + + @CCD(label = "Full name") + private String fullNameLegalRep; + + @CCD(label = "Name of firm") + private String firmNameLegalRep; + + @CCD(label = "Position or office held") + private String positionLegalRep; + +} + diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/entity/PcsCaseEntity.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/entity/PcsCaseEntity.java index 01658d8be3..0a1a009405 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/entity/PcsCaseEntity.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/entity/PcsCaseEntity.java @@ -25,6 +25,7 @@ import uk.gov.hmcts.reform.pcs.ccd.model.Defendant; import uk.gov.hmcts.reform.pcs.ccd.model.PartyDocumentDto; import uk.gov.hmcts.reform.pcs.ccd.model.PossessionGrounds; +import uk.gov.hmcts.reform.pcs.ccd.model.StatementOfTruth; import uk.gov.hmcts.reform.pcs.ccd.model.UnderlesseeMortgagee; import uk.gov.hmcts.reform.pcs.postcodecourt.model.LegislativeCountry; @@ -95,6 +96,10 @@ public class PcsCaseEntity { @JdbcTypeCode(SqlTypes.JSON) private List partyDocuments; + @Column(name = "statement_of_truth") + @JdbcTypeCode(SqlTypes.JSON) + private StatementOfTruth statementOfTruth; + @Column(name = "underlessee_mortgagee_details") @JdbcTypeCode(SqlTypes.JSON) private List underlesseesMortgagees; diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/ResumePossessionClaim.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/ResumePossessionClaim.java index 9e7274a287..5251a1d691 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/ResumePossessionClaim.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/ResumePossessionClaim.java @@ -224,6 +224,7 @@ public void configureDecentralised(DecentralisedConfigBuilder eventPayload) { diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/model/StatementOfTruth.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/model/StatementOfTruth.java new file mode 100644 index 0000000000..ee7f4c88e5 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/model/StatementOfTruth.java @@ -0,0 +1,37 @@ +package uk.gov.hmcts.reform.pcs.ccd.model; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import uk.gov.hmcts.reform.pcs.ccd.domain.StatementOfTruthAgreementClaimant; +import uk.gov.hmcts.reform.pcs.ccd.domain.StatementOfTruthAgreementLegalRep; +import uk.gov.hmcts.reform.pcs.ccd.domain.StatementOfTruthCompletedBy; + + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +public class StatementOfTruth { + + private StatementOfTruthCompletedBy completedBy; + + private StatementOfTruthAgreementClaimant agreementClaimant; + + private String fullNameClaimant; + + private String positionClaimant; + + private StatementOfTruthAgreementLegalRep agreementLegalRep; + + private String fullNameLegalRep; + + private String firmNameLegalRep; + + private String positionLegalRep; + +} + diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/makeaclaim/StatementOfTruth.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/makeaclaim/StatementOfTruth.java index d9e11d8314..470d39f0db 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/makeaclaim/StatementOfTruth.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/makeaclaim/StatementOfTruth.java @@ -2,28 +2,44 @@ import uk.gov.hmcts.reform.pcs.ccd.common.CcdPageConfiguration; import uk.gov.hmcts.reform.pcs.ccd.common.PageBuilder; +import uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase; +import uk.gov.hmcts.reform.pcs.ccd.domain.StatementOfTruthDetails; import uk.gov.hmcts.reform.pcs.ccd.page.CommonPageContent; public class StatementOfTruth implements CcdPageConfiguration { @Override public void addTo(PageBuilder pageBuilder) { - pageBuilder - .page("statementOfTruth") + pageBuilder.page("statementOfTruth") .pageLabel("Statement of truth") .showCondition("completionNextStep=\"SUBMIT_AND_PAY_NOW\"") - - // ---------- Horizontal separator ---------- - .label("statementOfTruth-separator", "---") - .label( - "statementOfTruth-content", + .label("statementOfTruth-body", """ -

Statement of truth

-

- This is a placeholder page for the statement of truth functionality. + --- +

+ I understand that proceedings for contempt of court may be brought against + anyone who makes, or causes to be made, a false statement in a document + verified by a statement of truth without an honest belief in its truth.

""" ) + .complex(PCSCase::getStatementOfTruth) + .mandatory(StatementOfTruthDetails::getCompletedBy) + .mandatory(StatementOfTruthDetails::getAgreementClaimant, + "statementOfTruth.completedBy=\"CLAIMANT\"") + .mandatory(StatementOfTruthDetails::getFullNameClaimant, + "statementOfTruth.completedBy=\"CLAIMANT\"") + .mandatory(StatementOfTruthDetails::getPositionClaimant, + "statementOfTruth.completedBy=\"CLAIMANT\"") + .mandatory(StatementOfTruthDetails::getAgreementLegalRep, + "statementOfTruth.completedBy=\"LEGAL_REPRESENTATIVE\"") + .mandatory(StatementOfTruthDetails::getFullNameLegalRep, + "statementOfTruth.completedBy=\"LEGAL_REPRESENTATIVE\"") + .mandatory(StatementOfTruthDetails::getFirmNameLegalRep, + "statementOfTruth.completedBy=\"LEGAL_REPRESENTATIVE\"") + .mandatory(StatementOfTruthDetails::getPositionLegalRep, + "statementOfTruth.completedBy=\"LEGAL_REPRESENTATIVE\"") + .done() .label("statementOfTruth-saveAndReturn", CommonPageContent.SAVE_AND_RETURN); } } diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/resumepossessionclaim/RentArrearsGroundForPossessionAdditionalGrounds.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/resumepossessionclaim/RentArrearsGroundForPossessionAdditionalGrounds.java index b83096ebfa..95c258dc9d 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/resumepossessionclaim/RentArrearsGroundForPossessionAdditionalGrounds.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/resumepossessionclaim/RentArrearsGroundForPossessionAdditionalGrounds.java @@ -60,13 +60,10 @@ public AboutToStartOrSubmitResponse midEvent(CaseDetails mergedMandatory = new HashSet<>(); Set mergedDiscretionary = new HashSet<>(); Set rentArrearsGrounds = caseData.getRentArrearsGrounds(); - log.warn("rentArrearsGrounds: {}", rentArrearsGrounds); if (rentArrearsGrounds != null) { if (rentArrearsGrounds.contains(RentArrearsGround.SERIOUS_RENT_ARREARS_GROUND8)) { @@ -86,7 +83,6 @@ public AboutToStartOrSubmitResponse midEvent(CaseDetails midEvent(CaseDetails midEvent(CaseDetailsbuilder() .errors(List.of("Please select at least one ground")) .build(); } - log.warn("Validation passed (conditional additional requirement)."); - // Backward compatibility: if no rent arrears grounds or additional-only input present, // use existing canonical sets boolean noRentArrearsGrounds = rentArrearsGrounds == null || rentArrearsGrounds.isEmpty(); @@ -155,8 +145,6 @@ public AboutToStartOrSubmitResponse midEvent(CaseDetailsbuilder() .data(caseData) .build(); diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/PcsCaseMergeService.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/PcsCaseMergeService.java index 2d5e7c1971..79c7e9a72b 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/PcsCaseMergeService.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/PcsCaseMergeService.java @@ -28,6 +28,7 @@ public class PcsCaseMergeService { private final ModelMapper modelMapper; private final TenancyLicenceService tenancyLicenceService; private final DefendantService defendantService; + private final StatementOfTruthService statementOfTruthService; private final UnderlesseeMortgageeService underlesseeMortgageService; public void mergeCaseData(PcsCaseEntity pcsCaseEntity, PCSCase pcsCase) { @@ -66,7 +67,7 @@ public void mergeCaseData(PcsCaseEntity pcsCaseEntity, PCSCase pcsCase) { pcsCaseEntity.setTenancyLicence(tenancyLicenceService.buildTenancyLicence(pcsCase)); pcsCaseEntity.setPossessionGrounds(buildPossessionGrounds(pcsCase)); - + pcsCaseEntity.setStatementOfTruth(statementOfTruthService.buildStatementOfTruth(pcsCase)); } private void setPcqIdForCurrentUser(UUID pcqId, PcsCaseEntity pcsCaseEntity) { diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/StatementOfTruthService.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/StatementOfTruthService.java new file mode 100644 index 0000000000..9b8b9ec14d --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/StatementOfTruthService.java @@ -0,0 +1,52 @@ +package uk.gov.hmcts.reform.pcs.ccd.service; + +import org.springframework.stereotype.Service; +import uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase; +import uk.gov.hmcts.reform.pcs.ccd.domain.StatementOfTruthAgreementClaimant; +import uk.gov.hmcts.reform.pcs.ccd.domain.StatementOfTruthAgreementLegalRep; +import uk.gov.hmcts.reform.pcs.ccd.domain.StatementOfTruthCompletedBy; +import uk.gov.hmcts.reform.pcs.ccd.domain.StatementOfTruthDetails; +import uk.gov.hmcts.reform.pcs.ccd.model.StatementOfTruth; + +import java.util.List; + +@Service +public class StatementOfTruthService { + + public StatementOfTruth buildStatementOfTruth(PCSCase pcsCase) { + if (pcsCase.getStatementOfTruth() == null + || pcsCase.getStatementOfTruth().getCompletedBy() == null) { + return null; + } + + StatementOfTruthDetails details = pcsCase.getStatementOfTruth(); + StatementOfTruthCompletedBy completedBy = details.getCompletedBy(); + StatementOfTruth.StatementOfTruthBuilder builder = StatementOfTruth.builder() + .completedBy(completedBy); + + if (completedBy == StatementOfTruthCompletedBy.CLAIMANT) { + List agreementClaimantList = details.getAgreementClaimant(); + builder.agreementClaimant( + agreementClaimantList != null && !agreementClaimantList.isEmpty() + ? agreementClaimantList.getFirst() + : null) + .fullNameClaimant(details.getFullNameClaimant()) + .positionClaimant(details.getPositionClaimant()); + } else if (completedBy == StatementOfTruthCompletedBy.LEGAL_REPRESENTATIVE) { + List agreementLegalRepList = details.getAgreementLegalRep(); + builder.agreementLegalRep( + agreementLegalRepList != null && !agreementLegalRepList.isEmpty() + ? agreementLegalRepList.getFirst() + : null) + .fullNameLegalRep(details.getFullNameLegalRep()) + .firmNameLegalRep(details.getFirmNameLegalRep()) + .positionLegalRep(details.getPositionLegalRep()); + } + + return builder.build(); + } + +} + + + diff --git a/src/main/resources/db/migration/V037__add_statement_of_truth_column.sql b/src/main/resources/db/migration/V037__add_statement_of_truth_column.sql new file mode 100644 index 0000000000..00861e89d7 --- /dev/null +++ b/src/main/resources/db/migration/V037__add_statement_of_truth_column.sql @@ -0,0 +1,2 @@ +ALTER TABLE pcs_case ADD COLUMN statement_of_truth JSONB; + diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/page/enforcement/VerbalOrWrittenThreatsRiskPageTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/page/enforcement/VerbalOrWrittenThreatsRiskPageTest.java index 203fd8b9cb..07fedd026e 100644 --- a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/page/enforcement/VerbalOrWrittenThreatsRiskPageTest.java +++ b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/page/enforcement/VerbalOrWrittenThreatsRiskPageTest.java @@ -58,7 +58,7 @@ void shouldRejectTextOver6800Characters() { PCSCase caseData = PCSCase.builder() .enforcementOrder(EnforcementOrder.builder() .enforcementRiskCategories(Set.of(RiskCategory.VERBAL_OR_WRITTEN_THREATS)) - .riskDetails(uk.gov.hmcts.reform.pcs.ccd.domain.enforcement.EnforcementRiskDetails + .riskDetails(EnforcementRiskDetails .builder() .enforcementVerbalOrWrittenThreatsDetails(longText) .build()) diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/page/enforcement/ViolentAggressiveRiskPageTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/page/enforcement/ViolentAggressiveRiskPageTest.java index 979ac13f40..eaf7663a1b 100644 --- a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/page/enforcement/ViolentAggressiveRiskPageTest.java +++ b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/page/enforcement/ViolentAggressiveRiskPageTest.java @@ -57,7 +57,7 @@ void shouldRejectTextOver6800Characters() { PCSCase caseData = PCSCase.builder() .enforcementOrder(EnforcementOrder.builder() .enforcementRiskCategories(Set.of(RiskCategory.VIOLENT_OR_AGGRESSIVE)) - .riskDetails(uk.gov.hmcts.reform.pcs.ccd.domain.enforcement.EnforcementRiskDetails.builder() + .riskDetails(EnforcementRiskDetails.builder() .enforcementViolentDetails(longText) .build()) .build()) diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/PcsCaseMergeServiceTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/PcsCaseMergeServiceTest.java index 2f1bdeb522..68a0fddcea 100644 --- a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/PcsCaseMergeServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/PcsCaseMergeServiceTest.java @@ -50,6 +50,8 @@ class PcsCaseMergeServiceTest { @Mock private DefendantService defendantService; @Mock + private StatementOfTruthService statementOfTruthService; + @Mock private UnderlesseeMortgageeService underlesseeMortgageService; private PcsCaseMergeService underTest; @@ -60,6 +62,7 @@ void setUp() { modelMapper, tenancyLicenceService, defendantService, + statementOfTruthService, underlesseeMortgageService); } diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/StatementOfTruthServiceTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/StatementOfTruthServiceTest.java new file mode 100644 index 0000000000..09372436a2 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/StatementOfTruthServiceTest.java @@ -0,0 +1,110 @@ +package uk.gov.hmcts.reform.pcs.ccd.service; + +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.pcs.ccd.domain.PCSCase; +import uk.gov.hmcts.reform.pcs.ccd.domain.StatementOfTruthAgreementClaimant; +import uk.gov.hmcts.reform.pcs.ccd.domain.StatementOfTruthAgreementLegalRep; +import uk.gov.hmcts.reform.pcs.ccd.domain.StatementOfTruthCompletedBy; +import uk.gov.hmcts.reform.pcs.ccd.domain.StatementOfTruthDetails; +import uk.gov.hmcts.reform.pcs.ccd.model.StatementOfTruth; + +import java.util.Arrays; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class StatementOfTruthServiceTest { + + private final StatementOfTruthService statementOfTruthService = new StatementOfTruthService(); + + @Mock + private PCSCase pcsCase; + + @Mock + private StatementOfTruthDetails statementOfTruthDetails; + + @Test + void shouldReturnNullWhenStatementOfTruthIsNull() { + // Given + when(pcsCase.getStatementOfTruth()).thenReturn(null); + + // When + StatementOfTruth result = statementOfTruthService.buildStatementOfTruth(pcsCase); + + // Then + assertThat(result).isNull(); + } + + @Test + void shouldReturnNullWhenStatementOfTruthCompletedByIsNull() { + // Given + when(pcsCase.getStatementOfTruth()).thenReturn(statementOfTruthDetails); + when(statementOfTruthDetails.getCompletedBy()).thenReturn(null); + + // When + StatementOfTruth result = statementOfTruthService.buildStatementOfTruth(pcsCase); + + // Then + assertThat(result).isNull(); + } + + @Test + void shouldBuildStatementOfTruthForClaimant() { + // Given + when(pcsCase.getStatementOfTruth()).thenReturn(statementOfTruthDetails); + when(statementOfTruthDetails.getCompletedBy()).thenReturn(StatementOfTruthCompletedBy.CLAIMANT); + when(statementOfTruthDetails.getAgreementClaimant()) + .thenReturn(Arrays.asList(StatementOfTruthAgreementClaimant.BELIEVE_TRUE)); + when(statementOfTruthDetails.getFullNameClaimant()).thenReturn("John Smith"); + when(statementOfTruthDetails.getPositionClaimant()).thenReturn("Director"); + + // When + StatementOfTruth result = statementOfTruthService.buildStatementOfTruth(pcsCase); + + // Then + assertThat(result).isNotNull(); + assertThat(result.getCompletedBy()).isEqualTo(StatementOfTruthCompletedBy.CLAIMANT); + assertThat(result.getAgreementClaimant()).isEqualTo(StatementOfTruthAgreementClaimant.BELIEVE_TRUE); + assertThat(result.getFullNameClaimant()).isEqualTo("John Smith"); + assertThat(result.getPositionClaimant()).isEqualTo("Director"); + // Legal rep fields should be null + assertThat(result.getAgreementLegalRep()).isNull(); + assertThat(result.getFullNameLegalRep()).isNull(); + assertThat(result.getFirmNameLegalRep()).isNull(); + assertThat(result.getPositionLegalRep()).isNull(); + } + + @Test + void shouldBuildStatementOfTruthForLegalRepresentative() { + // Given + when(pcsCase.getStatementOfTruth()).thenReturn(statementOfTruthDetails); + when(statementOfTruthDetails.getCompletedBy()) + .thenReturn(StatementOfTruthCompletedBy.LEGAL_REPRESENTATIVE); + when(statementOfTruthDetails.getAgreementLegalRep()) + .thenReturn(Arrays.asList(StatementOfTruthAgreementLegalRep.AGREED)); + when(statementOfTruthDetails.getFullNameLegalRep()).thenReturn("Jane Doe"); + when(statementOfTruthDetails.getFirmNameLegalRep()).thenReturn("Smith & Co Solicitors"); + when(statementOfTruthDetails.getPositionLegalRep()).thenReturn("Partner"); + + // When + StatementOfTruth result = statementOfTruthService.buildStatementOfTruth(pcsCase); + + // Then + assertThat(result).isNotNull(); + assertThat(result.getCompletedBy()).isEqualTo(StatementOfTruthCompletedBy.LEGAL_REPRESENTATIVE); + assertThat(result.getAgreementLegalRep()).isEqualTo(StatementOfTruthAgreementLegalRep.AGREED); + assertThat(result.getFullNameLegalRep()).isEqualTo("Jane Doe"); + assertThat(result.getFirmNameLegalRep()).isEqualTo("Smith & Co Solicitors"); + assertThat(result.getPositionLegalRep()).isEqualTo("Partner"); + // Claimant fields should be null + assertThat(result.getAgreementClaimant()).isNull(); + assertThat(result.getFullNameClaimant()).isNull(); + assertThat(result.getPositionClaimant()).isNull(); + } + +} + diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/TextAreaValidationServiceTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/TextAreaValidationServiceTest.java index 271186f8cf..a3163cca2f 100644 --- a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/TextAreaValidationServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/TextAreaValidationServiceTest.java @@ -8,6 +8,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import uk.gov.hmcts.ccd.sdk.api.callback.AboutToStartOrSubmitResponse; +import java.util.ArrayList; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; @@ -36,7 +37,7 @@ class ValidateTextAreaTests { @DisplayName("Should not add error when field value is null") void shouldNotAddErrorWhenFieldValueIsNull() { // Given - List errors = new java.util.ArrayList<>(); + List errors = new ArrayList<>(); // When textAreaValidationService.validateTextArea(null, "Test Field", 100, errors); @@ -49,7 +50,7 @@ void shouldNotAddErrorWhenFieldValueIsNull() { @DisplayName("Should not add error when field value is empty") void shouldNotAddErrorWhenFieldValueIsEmpty() { // Given - List errors = new java.util.ArrayList<>(); + List errors = new ArrayList<>(); // When textAreaValidationService.validateTextArea("", "Test Field", 100, errors); @@ -62,7 +63,7 @@ void shouldNotAddErrorWhenFieldValueIsEmpty() { @DisplayName("Should not add error when field value is within limit") void shouldNotAddErrorWhenFieldValueIsWithinLimit() { // Given - List errors = new java.util.ArrayList<>(); + List errors = new ArrayList<>(); String fieldValue = "a".repeat(100); // When @@ -76,7 +77,7 @@ void shouldNotAddErrorWhenFieldValueIsWithinLimit() { @DisplayName("Should add error when field value exceeds limit") void shouldAddErrorWhenFieldValueExceedsLimit() { // Given - List errors = new java.util.ArrayList<>(); + List errors = new ArrayList<>(); String fieldValue = "a".repeat(101); String fieldLabel = "Test Field"; int maxCharacters = 100; @@ -95,7 +96,7 @@ void shouldAddErrorWhenFieldValueExceedsLimit() { @DisplayName("Should add multiple errors when called multiple times") void shouldAddMultipleErrorsWhenCalledMultipleTimes() { // Given - List errors = new java.util.ArrayList<>(); + List errors = new ArrayList<>(); // When textAreaValidationService.validateTextArea("a".repeat(101), "Field 1", 100, errors);