Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
f9c3672
Added additional document page
nicole-samuels May 18, 2026
a09712d
Merge branch 'HDPI-6421-upload-doc-legal-rep' into HDPI-6404-upload-d…
nicole-samuels May 18, 2026
b5ac28c
Added new screen to configurer and updated test
nicole-samuels May 18, 2026
c1a76a4
Adding legal rep document upload class
nicole-samuels May 18, 2026
4f9d0b5
changed name of additional documents and updated document content
nicole-samuels May 19, 2026
d2b7a28
updated the additional document page with common page content
nicole-samuels May 20, 2026
2ce7ec4
Removed save and return common page content
nicole-samuels May 20, 2026
1585a13
Merge branch 'HDPI-6421-upload-doc-legal-rep' into HDPI-6404-upload-d…
nicole-samuels May 20, 2026
c875f9e
HDPI-6404 Updated character limit and persisted case data
nicole-samuels May 21, 2026
e4e0d85
Merged HDPI-6241
nicole-samuels Jun 3, 2026
92ca85a
Merge branch 'HDPI-6421-upload-doc-legal-rep' into HDPI-6404-upload-d…
madhavi1203 Jun 11, 2026
b26e3a6
Updated content for upload page
nicole-samuels Jun 12, 2026
e16ff97
Merge branch 'HDPI-6421-upload-doc-legal-rep' into HDPI-6404-upload-d…
marianadpereira Jun 16, 2026
cdfd587
Merge branch 'HDPI-6421-upload-doc-legal-rep' into HDPI-6404-upload-d…
nicole-samuels Jun 17, 2026
1337f75
Updated title and spacing
nicole-samuels Jun 17, 2026
5d0a654
Merge branch 'HDPI-6421-upload-doc-legal-rep' into HDPI-6404-upload-d…
marianadpereira Jun 29, 2026
8e38ef3
Added LegalRepDocumentTypeWales
nicole-samuels Jun 29, 2026
c4b1eea
updated submit method and document service
nicole-samuels Jun 29, 2026
da6a594
Merge branch 'HDPI-6421-upload-doc-legal-rep' into HDPI-6404-upload-d…
nicole-samuels Jun 29, 2026
15e0d1a
removed duplicate import
nicole-samuels Jun 29, 2026
f82d4e5
Merge branch 'HDPI-6421-upload-doc-legal-rep' into HDPI-6404-upload-d…
nicole-samuels Jun 30, 2026
66e96e1
Added LegalREpDocumentType for English and Welsh journey
nicole-samuels Jul 2, 2026
ce26670
Updated DocumentService to ddded mapping to categoryId for legalRepDo…
nicole-samuels Jul 2, 2026
05ab994
Updated DocumentService by removing Optional.of for categoryId mappin…
nicole-samuels Jul 2, 2026
2f9927e
updated DocumentService for legalRepDocument
nicole-samuels Jul 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package uk.gov.hmcts.reform.pcs.ccd.domain.legalrepdocumentupload;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import uk.gov.hmcts.ccd.sdk.api.CCD;
import uk.gov.hmcts.ccd.sdk.type.Document;
import uk.gov.hmcts.ccd.sdk.type.FieldType;
import uk.gov.hmcts.reform.pcs.ccd.domain.legalrepdocumentupload.wales.LegalRepDocumentTypeWales;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class LegalRepDocument {

@CCD(
label = "Type of document",
typeOverride = FieldType.FixedList,
typeParameterOverride = "LegalRepDocumentType"
)
private LegalRepDocumentType legalRepDocumentType;

@CCD(
label = "Type of document",
typeOverride = FieldType.FixedList,
typeParameterOverride = "LegalRepDocumentTypeWales"
)
private LegalRepDocumentTypeWales legalRepDocumentTypeWales;

@CCD(label = "Document")
private Document document;

@CCD(label = "Short description",
max = 60
)
private String description;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package uk.gov.hmcts.reform.pcs.ccd.domain.legalrepdocumentupload;

import lombok.AllArgsConstructor;
import lombok.Getter;
import uk.gov.hmcts.ccd.sdk.api.HasLabel;

@AllArgsConstructor
@Getter
public enum LegalRepDocumentType implements HasLabel {

RENT_STATEMENT("Rent or payments"),
TENANCY_AGREEMENT("Tenancy agreement"),
CORRESPONDENCE_FROM_DEFENDANT("Correspondence from defendant"),
CORRESPONDENCE_FROM_CLAIMANT("Correspondence from claimant"),
PHOTOGRAPHIC_EVIDENCE("Photographic evidence"),
CERTIFICATE_OF_SUITABILITY_AS_LF("Certificate of suitability as litigation friend"),
LEGAL_AID_CERTIFICATE("Legal aid certificate"),
OTHER("Other document"),
WITNESS_STATEMENT("Witness statement");

private final String label;

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
import lombok.Data;
import lombok.NoArgsConstructor;
import uk.gov.hmcts.ccd.sdk.api.CCD;
import uk.gov.hmcts.ccd.sdk.type.ListValue;
import uk.gov.hmcts.ccd.sdk.type.YesOrNo;
import uk.gov.hmcts.reform.pcs.ccd.type.DynamicStringList;

import java.util.List;

import static uk.gov.hmcts.ccd.sdk.type.FieldType.DynamicRadioList;

@Builder
Expand All @@ -26,7 +29,17 @@ public class LegalRepDocumentUploadDetails {
@JsonProperty("DocumentUploadCategories")
private DynamicStringList validCategories;


@CCD(
label = "Add document",
hint = "Upload a document to the system"
)
private List<ListValue<LegalRepDocument>> legalRepDocuments;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like it's not specified in the ticket, but ideally each ticket that captures some data from the user should include persisting it to the DB. Otherwise there is a chance that it can get forgotten about.


@CCD(searchable = false)
private YesOrNo showExistingApplicationPage;

@CCD(searchable = false)
private YesOrNo isWales;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package uk.gov.hmcts.reform.pcs.ccd.domain.legalrepdocumentupload.wales;

import lombok.AllArgsConstructor;
import lombok.Getter;
import uk.gov.hmcts.ccd.sdk.api.HasLabel;

@AllArgsConstructor
@Getter
public enum LegalRepDocumentTypeWales implements HasLabel {

RENT_STATEMENT("Rent or payments"),
OCCUPATION_LICENCE("Occupation licence"),
CORRESPONDENCE_FROM_DEFENDANT("Correspondence from defendant"),
CORRESPONDENCE_FROM_CLAIMANT("Correspondence from claimant"),
PHOTOGRAPHIC_EVIDENCE("Photographic evidence"),
CERTIFICATE_OF_SUITABILITY_AS_LF("Certificate of suitability as litigation friend"),
LEGAL_AID_CERTIFICATE("Legal aid certificate"),
OTHER("Other document"),
WITNESS_STATEMENT("Witness statement");

private final String label;

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@
import uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase;
import uk.gov.hmcts.reform.pcs.ccd.domain.State;
import uk.gov.hmcts.reform.pcs.ccd.domain.VerticalYesNo;
import uk.gov.hmcts.reform.pcs.ccd.domain.legalrepdocumentupload.LegalRepDocument;
import uk.gov.hmcts.reform.pcs.ccd.domain.legalrepdocumentupload.LegalRepDocumentUploadDetails;
import uk.gov.hmcts.reform.pcs.ccd.domain.legalrepdocumentupload.DocumentUploadCategory;
import uk.gov.hmcts.reform.pcs.ccd.entity.PcsCaseEntity;
import uk.gov.hmcts.reform.pcs.ccd.page.legalrepdocumentupload.LegalRepDocumentUploadConfigurer;
import uk.gov.hmcts.reform.pcs.ccd.service.PcsCaseService;
import uk.gov.hmcts.reform.pcs.ccd.service.document.DocumentService;
import uk.gov.hmcts.reform.pcs.ccd.type.DynamicStringList;
import uk.gov.hmcts.reform.pcs.ccd.type.DynamicStringListElement;

Expand All @@ -31,6 +33,7 @@

import uk.gov.hmcts.reform.pcs.ccd.entity.GenAppEntity;
import uk.gov.hmcts.reform.pcs.ccd.domain.genapp.GenAppType;
import uk.gov.hmcts.reform.pcs.postcodecourt.model.LegislativeCountry;

import static uk.gov.hmcts.reform.pcs.ccd.event.EventId.legalRepDocumentUpload;

Expand All @@ -40,6 +43,7 @@ public class LegalRepDocumentUpload implements CCDConfig<PCSCase, State, UserRol

private final LegalRepDocumentUploadConfigurer legalRepDocumentUploadConfigurer;
private final PcsCaseService pcsCaseService;
private final DocumentService documentService;

@Override
public void configureDecentralised(DecentralisedConfigBuilder<PCSCase, State, UserRole> configBuilder) {
Expand Down Expand Up @@ -86,6 +90,10 @@ private PCSCase start(EventPayload<PCSCase, State> eventPayload) {
// By default, Main claim is always added
caseData.getLegalRepDocumentUploadDetails().setShowExistingApplicationPage(validCategoryItems.size() >= 2
? YesOrNo.YES : YesOrNo.NO);

boolean isWalesClaim = pcsCaseEntity.getLegislativeCountry() == LegislativeCountry.WALES;
caseData.getLegalRepDocumentUploadDetails().setIsWales(isWalesClaim ? YesOrNo.YES : YesOrNo.NO);

return caseData;
}

Expand Down Expand Up @@ -131,7 +139,31 @@ GenAppType mapCategoryToGenAppType(DocumentUploadCategory category) {
};
}

private SubmitResponse<State> submit(EventPayload<PCSCase, State> eventPayload) {
return SubmitResponse.defaultResponse();
SubmitResponse<State> submit(EventPayload<PCSCase, State> eventPayload) {
Long caseReference = eventPayload.caseReference();
PcsCaseEntity pcsCaseEntity = pcsCaseService.loadCase(caseReference);
PCSCase pcsCase = eventPayload.caseData();

List<LegalRepDocument> legalRepDocuments = documentService.createLegalRepDocuments(pcsCase);

boolean isDocumentNull = legalRepDocuments.stream()
.anyMatch(doc -> doc == null || doc.getDocument() == null);

if (isDocumentNull) {
return errorResponse("Your files were not submitted. Try again.");
}

documentService.createDocumentEntitiesFromLegalRepDocuments(legalRepDocuments,pcsCaseEntity);

return SubmitResponse.<State>builder()
.build();
}

@SuppressWarnings("SameParameterValue")
private SubmitResponse<State> errorResponse(String message) {
return SubmitResponse.<State>builder()
.errors(List.of(message))
.build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@
@AllArgsConstructor
public class LegalRepDocumentUploadConfigurer implements PageConfigurer {

private final UploadAdditionalDocumentsPage uploadAdditionalDocumentsPage;

@Override
public void configurePages(PageBuilder pageBuilder) {
pageBuilder
.add(new UploadAdditionalDocumentsInformationPage())
.add(new ExistingApplicationPage());
.add(new ExistingApplicationPage())
.add(uploadAdditionalDocumentsPage);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package uk.gov.hmcts.reform.pcs.ccd.page.legalrepdocumentupload;

import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;
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.legalrepdocumentupload.LegalRepDocument;
import uk.gov.hmcts.reform.pcs.ccd.domain.legalrepdocumentupload.LegalRepDocumentUploadDetails;
import uk.gov.hmcts.reform.pcs.ccd.page.CcdPage;
import uk.gov.hmcts.reform.pcs.ccd.service.TextAreaValidationService;

import static uk.gov.hmcts.reform.pcs.ccd.ShowConditions.NEVER_SHOW;

@Component
@AllArgsConstructor
public class UploadAdditionalDocumentsPage implements CcdPageConfiguration, CcdPage {

private static final String DESCRIPTION_LABEL = "Short description";
private final TextAreaValidationService textAreaValidationService;
public static final String DOCUMENT_DETAILS_CONTENT = """
<p class="govuk-body">
You should only upload documents that are relevant to the claim.
</p>

<p class="govuk-body">
Before you upload the document, give it a name that tells the court what it is,
for example ‘witness statement’, or ‘tenancy agreement’.
</p>

<p class="govuk-body">
You can upload the following file types: DOC/DOCX (Word), XLS/XLSM
(Excel), PPT/PPTX (PowerPoint), PDF, RTF, TXT, CSV, JPG/JPEG, PNG, BMP,
TIF/TIFF.
</p>

<p class="govuk-body govuk-!-font-weight-bold govuk-!-margin-0">
Before you upload your documents
</p>

<p class="govuk-body">
Give your document a name that explains what it is.
</p>

""";

@Override
public void addTo(PageBuilder pageBuilder) {
String pageKey = getPageKey();
pageBuilder
.page(pageKey)
.pageLabel("Upload additional documents")
.label(pageKey + "-line-separator", "---")
.label(pageKey + "-content", DOCUMENT_DETAILS_CONTENT)
.complex(PCSCase::getLegalRepDocumentUploadDetails)
.readonly(LegalRepDocumentUploadDetails::getIsWales, NEVER_SHOW)
.list(LegalRepDocumentUploadDetails::getLegalRepDocuments)
.mandatory(LegalRepDocument::getLegalRepDocumentType, "isWales = \"No\"")
.mandatory(LegalRepDocument::getLegalRepDocumentTypeWales, "isWales = \"Yes\"")
.mandatory(LegalRepDocument::getDocument)
.mandatory(LegalRepDocument::getDescription)
.done()
.build();
}

@Override
public String getPageKey() {
return CcdPage.derivePageKey(this.getClass());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,13 @@
import uk.gov.hmcts.reform.pcs.ccd.domain.enforcetheorder.EnforcementOrder;
import uk.gov.hmcts.reform.pcs.ccd.domain.enforcetheorder.warrantofrestitution.EvidenceDocumentType;
import uk.gov.hmcts.reform.pcs.ccd.domain.enforcetheorder.warrantofrestitution.EvidenceOfDefendants;
import uk.gov.hmcts.reform.pcs.ccd.domain.legalrepdocumentupload.LegalRepDocumentType;
import uk.gov.hmcts.reform.pcs.ccd.domain.legalrepdocumentupload.wales.LegalRepDocumentTypeWales;
import uk.gov.hmcts.reform.pcs.ccd.domain.legalrepdocumentupload.LegalRepDocument;
import uk.gov.hmcts.reform.pcs.ccd.domain.legalrepdocumentupload.LegalRepDocumentUploadDetails;
import uk.gov.hmcts.reform.pcs.ccd.domain.wales.OccupationLicenceDetailsWales;
import uk.gov.hmcts.reform.pcs.ccd.entity.ClaimEntity;
import uk.gov.hmcts.reform.pcs.ccd.domain.wales.WalesDocuments;
import uk.gov.hmcts.reform.pcs.ccd.entity.ClaimEntity;
import uk.gov.hmcts.reform.pcs.ccd.entity.DocumentEntity;
import uk.gov.hmcts.reform.pcs.ccd.entity.GenAppEntity;
import uk.gov.hmcts.reform.pcs.ccd.entity.PcsCaseEntity;
Expand Down Expand Up @@ -414,11 +417,81 @@ private DocumentType mapEvidenceDocumentTypeToDocumentType(EvidenceDocumentType
};
}

private DocumentType mapLegalRepDocumentTypeToDocumentType(LegalRepDocumentType legalRepDocumentType) {
return switch (legalRepDocumentType) {
case RENT_STATEMENT -> DocumentType.RENT_STATEMENT;
case TENANCY_AGREEMENT -> DocumentType.TENANCY_AGREEMENT;
case CORRESPONDENCE_FROM_CLAIMANT -> DocumentType.CORRESPONDENCE_FROM_CLAIMANT;
case CORRESPONDENCE_FROM_DEFENDANT -> DocumentType.CORRESPONDENCE_FROM_DEFENDANT;
case PHOTOGRAPHIC_EVIDENCE -> DocumentType.PHOTOGRAPHIC_EVIDENCE;
case CERTIFICATE_OF_SUITABILITY_AS_LF -> DocumentType.CERTIFICATE_OF_SUITABILITY_AS_LF;
case LEGAL_AID_CERTIFICATE -> DocumentType.LEGAL_AID_CERTIFICATE;
case OTHER -> DocumentType.OTHER;
case WITNESS_STATEMENT -> DocumentType.WITNESS_STATEMENT;
};
}

private DocumentType mapLegalRepDocumentTypeToDocumentType(LegalRepDocumentTypeWales legalRepDocumentTypeWales) {
return switch (legalRepDocumentTypeWales) {
case RENT_STATEMENT -> DocumentType.RENT_STATEMENT;
case OCCUPATION_LICENCE -> DocumentType.OCCUPATION_LICENCE;
case CORRESPONDENCE_FROM_CLAIMANT -> DocumentType.CORRESPONDENCE_FROM_CLAIMANT;
case CORRESPONDENCE_FROM_DEFENDANT -> DocumentType.CORRESPONDENCE_FROM_DEFENDANT;
case PHOTOGRAPHIC_EVIDENCE -> DocumentType.PHOTOGRAPHIC_EVIDENCE;
case CERTIFICATE_OF_SUITABILITY_AS_LF -> DocumentType.CERTIFICATE_OF_SUITABILITY_AS_LF;
case LEGAL_AID_CERTIFICATE -> DocumentType.LEGAL_AID_CERTIFICATE;
case OTHER -> DocumentType.OTHER;
case WITNESS_STATEMENT -> DocumentType.WITNESS_STATEMENT;
};
}

@Builder
@Data
private static class DocumentHolder {
private Document document;
private DocumentType type;
private String description;
}

public List<LegalRepDocument> createLegalRepDocuments(PCSCase pcsCase) {
LegalRepDocumentUploadDetails legalRepDocumentUploadDetails = pcsCase.getLegalRepDocumentUploadDetails();

return legalRepDocumentUploadDetails.getLegalRepDocuments().stream()
.map(ListValue::getValue).toList();
}

public DocumentType resolveDocumentType(LegalRepDocument legalRepDoc) {
if (legalRepDoc.getLegalRepDocumentTypeWales() != null) {
return mapLegalRepDocumentTypeToDocumentType(legalRepDoc.getLegalRepDocumentTypeWales());
}
return mapLegalRepDocumentTypeToDocumentType(legalRepDoc.getLegalRepDocumentType());
}

public void createDocumentEntitiesFromLegalRepDocuments(
List<LegalRepDocument> legalRepDocuments,
PcsCaseEntity pcsCaseEntity
) {
List<DocumentEntity> documentEntities = legalRepDocuments.stream()
.map(legalRepDoc -> {

DocumentType resolvedDocumentType = resolveDocumentType(legalRepDoc);

String categoryId = mapDocumentTypeToCategory(resolvedDocumentType)
.map(CaseFileCategory::getId)
.orElse(null);

return DocumentEntity.builder()
.pcsCase(pcsCaseEntity)
.url(legalRepDoc.getDocument().getUrl())
.fileName(legalRepDoc.getDocument().getFilename())
.binaryUrl(legalRepDoc.getDocument().getBinaryUrl())
.description(legalRepDoc.getDescription())
.type(resolvedDocumentType)
.categoryId(categoryId)
.build();
})
.toList();

pcsCaseEntity.addDocuments(documentEntities);
}
}
Loading