diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/DocumentType.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/DocumentType.java index 2ebad4bcf0..b169a92189 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/DocumentType.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/DocumentType.java @@ -34,6 +34,7 @@ public enum DocumentType implements HasLabel { ELECTRICAL_INSTALLATION_CONDITION("Electrical installation condition"), DEFENDANT_RESPONSE("Defendant response"), COUNTERCLAIM("Counterclaim"), + GENERAL_APPLICATION("General application"), OTHER("Other document"); private final String label; 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 edf128b6a3..2d7228d77b 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 @@ -746,4 +746,11 @@ public class PCSCase { typeParameterOverride = "CaseStateOption" ) private CaseStateOption targetState; + + @CCD( + label = "Add document", + hint = "Upload a document to the system", + searchable = false + ) + private Document uploadSingleDocument; } diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/caseworker/EnterGenAppRequest.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/caseworker/EnterGenAppRequest.java index cea1adbe9d..09339ccb68 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/caseworker/EnterGenAppRequest.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/caseworker/EnterGenAppRequest.java @@ -7,12 +7,15 @@ 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.ccd.sdk.type.ListValue; import uk.gov.hmcts.reform.pcs.ccd.annotation.JacksonMoneyGBP; import uk.gov.hmcts.reform.pcs.ccd.domain.VerticalYesNo; import java.math.BigDecimal; import java.time.LocalDate; +import java.util.List; import static uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase.MAX_MONETARY_AMOUNT; @@ -57,4 +60,11 @@ public class EnterGenAppRequest { ) private String hwfReference; + @CCD( + label = "Add document", + hint = "Upload a document to the system", + searchable = false + ) + private List> relatedEvidence; + } diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/caseworker/entergenapp/EnterGenApp.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/caseworker/entergenapp/EnterGenApp.java index b7164cb74c..a6fcdadbcb 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/caseworker/entergenapp/EnterGenApp.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/caseworker/entergenapp/EnterGenApp.java @@ -108,8 +108,7 @@ private SubmitResponse submit(EventPayload eventPayload) PartyEntity applicantParty = partyService.getPartyEntityByEntityId( caseData.getPartyRadioList().getValueCode(), caseReference); - genAppService.createGenAppEntity( - caseData.getEnterGenAppRequest(), pcsCaseEntity, applicantParty, GenAppState.GEN_APP_ISSUED); + genAppService.createGenAppEntity(caseData, pcsCaseEntity, applicantParty, GenAppState.GEN_APP_ISSUED); return SubmitResponse.builder().build(); } diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/caseworker/entergenapp/UploadGeneralApplication.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/caseworker/entergenapp/UploadGeneralApplication.java index 6fd6c70a07..9310f9af96 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/caseworker/entergenapp/UploadGeneralApplication.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/caseworker/entergenapp/UploadGeneralApplication.java @@ -2,27 +2,17 @@ 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; public class UploadGeneralApplication implements CcdPageConfiguration { - private static final String PLACEHOLDER_BANNER = """ -
-
-

- Placeholder -

-
-
- """; - @Override public void addTo(PageBuilder pageBuilder) { pageBuilder .page("uploadGeneralApplication") .pageLabel("Upload general application") .label("uploadGeneralApplication-lineSeparator", "---") - .label("uploadGeneralApplication-placeholder", PLACEHOLDER_BANNER); + .mandatory(PCSCase::getUploadSingleDocument); } } diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/caseworker/entergenapp/UploadRelatedEvidence.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/caseworker/entergenapp/UploadRelatedEvidence.java index 5da267d493..8d15a88386 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/caseworker/entergenapp/UploadRelatedEvidence.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/caseworker/entergenapp/UploadRelatedEvidence.java @@ -2,27 +2,20 @@ 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.caseworker.EnterGenAppRequest; public class UploadRelatedEvidence implements CcdPageConfiguration { - private static final String PLACEHOLDER_BANNER = """ -
-
-

- Placeholder -

-
-
- """; - @Override public void addTo(PageBuilder pageBuilder) { pageBuilder .page("uploadRelatedEvidence") .pageLabel("Upload related evidence") .label("uploadRelatedEvidence-lineSeparator", "---") - .label("uploadRelatedEvidence-placeholder", PLACEHOLDER_BANNER); + .complex(PCSCase::getEnterGenAppRequest) + .optional(EnterGenAppRequest::getRelatedEvidence) + .done(); } } diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/document/DocumentService.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/document/DocumentService.java index f388779e6b..795034651e 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/document/DocumentService.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/document/DocumentService.java @@ -403,6 +403,8 @@ private Optional mapDocumentTypeToCategory(DocumentType docume case CERTIFICATE_OF_SUITABILITY_AS_LF, LEGAL_AID_CERTIFICATE -> Optional.of(CaseFileCategory.CORRESPONDENCE); + case GENERAL_APPLICATION -> + Optional.of(CaseFileCategory.APPLICATIONS); case NOTICE_SERVED, POLICE_REPORT, // Defendant access-code letters aren't shown on the case file diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/genapp/GenAppService.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/genapp/GenAppService.java index b2a30d0e03..6584f323b4 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/genapp/GenAppService.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/genapp/GenAppService.java @@ -1,9 +1,13 @@ package uk.gov.hmcts.reform.pcs.ccd.service.genapp; +import org.apache.commons.io.FilenameUtils; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; +import uk.gov.hmcts.ccd.sdk.type.Document; import uk.gov.hmcts.ccd.sdk.type.ListValue; import uk.gov.hmcts.reform.pcs.ccd.domain.CaseFileCategory; +import uk.gov.hmcts.reform.pcs.ccd.domain.DocumentType; +import uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase; import uk.gov.hmcts.reform.pcs.ccd.domain.UploadedDocument; import uk.gov.hmcts.reform.pcs.ccd.domain.VerticalYesNo; import uk.gov.hmcts.reform.pcs.ccd.domain.caseworker.EnterGenAppRequest; @@ -33,6 +37,8 @@ @Service public class GenAppService { + private static final String GENERAL_APPLICATION_FILENAME = "General Application"; + private final GenAppRepository genAppRepository; private final DocumentService documentService; private final DocumentNameService documentNameService; @@ -122,18 +128,19 @@ public GenAppEntity createGenAppEntity(GenAppRequest genAppRequest, return genAppRepository.save(genAppEntity); } - public void createGenAppEntity(EnterGenAppRequest enterGenAppRequest, + public void createGenAppEntity(PCSCase caseData, PcsCaseEntity pcsCaseEntity, PartyEntity applicantParty, GenAppState initialState) { + EnterGenAppRequest enterGenAppRequest = caseData.getEnterGenAppRequest(); + GenAppEntity genAppEntity = GenAppEntity.builder() .type(enterGenAppRequest.getApplicationTypeOption().getStandardGenAppType()) - .applicationSubmittedDate(LocalDateTime.now(utcClock)) .party(applicantParty) .applicationReceivedDate(enterGenAppRequest.getDateReceived()) - .within14Days(enterGenAppRequest.getWithin14Days()) .applicationSubmittedDate(LocalDateTime.now(utcClock)) + .within14Days(enterGenAppRequest.getWithin14Days()) .state(initialState) .feeAmountReceived(enterGenAppRequest.getFeeAmountReceived()) .appliedForHwf(enterGenAppRequest.getAppliedForHwf()) @@ -153,9 +160,65 @@ public void createGenAppEntity(EnterGenAppRequest enterGenAppRequest, genAppEntity.setHelpWithFeesEntity(helpWithFeesEntity); } + Document uploadedGenApp = caseData.getUploadSingleDocument(); + DocumentEntity submissionDocument = createSubmissionDocumentEntity( + uploadedGenApp, pcsCaseEntity, genAppEntity, applicantParty.getId() + ); + genAppEntity.setSubmissionDocument(submissionDocument); + + List additionalEvidenceDocuments = createRelatedEvidenceDocumentEntities( + enterGenAppRequest.getRelatedEvidence(), pcsCaseEntity, genAppEntity, applicantParty.getId() + ); + genAppEntity.setDocuments(additionalEvidenceDocuments); + genAppRepository.save(genAppEntity); } + private DocumentEntity createSubmissionDocumentEntity(Document document, + PcsCaseEntity pcsCaseEntity, + GenAppEntity genAppEntity, + UUID applicantPartyId) { + + if (document == null) { + return null; + } + + ClaimEntity mainClaimEntity = pcsCaseEntity.getClaims().getFirst(); + String extension = FilenameUtils.getExtension(document.getFilename()); + String newFileName = GENERAL_APPLICATION_FILENAME + "." + extension; + String renamedFilename = documentNameService + .appendGenAppPostfix(newFileName, genAppEntity, mainClaimEntity, applicantPartyId); + + DocumentEntity documentEntity = buildDocumentEntity(document, pcsCaseEntity, genAppEntity, renamedFilename, + CaseFileCategory.APPLICATIONS.getId(), DocumentType.GENERAL_APPLICATION); + + return documentRepository.save(documentEntity); + } + + private List createRelatedEvidenceDocumentEntities( + List> relatedEvidenceDocuments, PcsCaseEntity pcsCaseEntity, GenAppEntity genAppEntity, + UUID applicantPartyId) { + + if (relatedEvidenceDocuments == null) { + return List.of(); + } + + ClaimEntity mainClaimEntity = pcsCaseEntity.getClaims().getFirst(); + + List documentEntities = relatedEvidenceDocuments.stream() + .map(ListValue::getValue) + .map(document -> { + String renamedFilename = documentNameService + .appendGenAppPostfix(document.getFilename(), genAppEntity, mainClaimEntity, applicantPartyId); + + return buildDocumentEntity(document, pcsCaseEntity, genAppEntity, renamedFilename, + null, null); + }) + .toList(); + + return documentRepository.saveAll(documentEntities); + } + private List createDocumentEntities(List> uploadedDocuments, PcsCaseEntity pcsCaseEntity, GenAppEntity genAppEntity, @@ -174,23 +237,33 @@ private List createDocumentEntities(List genAppEntityCaptor; @Captor + private ArgumentCaptor documentEntityCaptor; + @Captor private ArgumentCaptor> documentEntityListCaptor; private GenAppService underTest; @@ -673,7 +677,9 @@ void shouldAddCreatedEntityToCase() { .build(); // When - underTest.createGenAppEntity(enterGenAppRequest, pcsCaseEntity, applicantParty, GEN_APP_ISSUED); + underTest.createGenAppEntity( + PCSCase.builder().enterGenAppRequest(enterGenAppRequest).build(), + pcsCaseEntity, applicantParty, GEN_APP_ISSUED); // Then verify(pcsCaseEntity).addGenApp(genAppEntityCaptor.capture()); @@ -689,7 +695,9 @@ void shouldSetApplicationSubmittedDate() { .build(); // When - underTest.createGenAppEntity(enterGenAppRequest, pcsCaseEntity, applicantParty, GEN_APP_ISSUED); + underTest.createGenAppEntity( + PCSCase.builder().enterGenAppRequest(enterGenAppRequest).build(), + pcsCaseEntity, applicantParty, GEN_APP_ISSUED); // Then GenAppEntity genAppEntity = getSavedGenAppEntity(); @@ -705,7 +713,9 @@ void shouldSetGenAppType(EnterGenAppType enterGenAppType) { .build(); // When - underTest.createGenAppEntity(enterGenAppRequest, pcsCaseEntity, applicantParty, GEN_APP_ISSUED); + underTest.createGenAppEntity( + PCSCase.builder().enterGenAppRequest(enterGenAppRequest).build(), + pcsCaseEntity, applicantParty, GEN_APP_ISSUED); // Then GenAppEntity genAppEntity = getSavedGenAppEntity(); @@ -721,7 +731,9 @@ void shouldSetSomethingElseDetailsForSomethingElseType() { .build(); // When - underTest.createGenAppEntity(enterGenAppRequest, pcsCaseEntity, applicantParty, GEN_APP_ISSUED); + underTest.createGenAppEntity( + PCSCase.builder().enterGenAppRequest(enterGenAppRequest).build(), + pcsCaseEntity, applicantParty, GEN_APP_ISSUED); // Then GenAppEntity genAppEntity = getSavedGenAppEntity(); @@ -739,7 +751,9 @@ void shouldNotSetSomethingElseDetailsIfNotSomethingElseType(EnterGenAppType ente .build(); // When - underTest.createGenAppEntity(enterGenAppRequest, pcsCaseEntity, applicantParty, GEN_APP_ISSUED); + underTest.createGenAppEntity( + PCSCase.builder().enterGenAppRequest(enterGenAppRequest).build(), + pcsCaseEntity, applicantParty, GEN_APP_ISSUED); // Then GenAppEntity genAppEntity = getSavedGenAppEntity(); @@ -755,7 +769,9 @@ void shouldSetGenAppState(GenAppState genAppState) { .build(); // When - underTest.createGenAppEntity(enterGenAppRequest, pcsCaseEntity, applicantParty, genAppState); + underTest.createGenAppEntity( + PCSCase.builder().enterGenAppRequest(enterGenAppRequest).build(), + pcsCaseEntity, applicantParty, genAppState); // Then GenAppEntity genAppEntity = getSavedGenAppEntity(); @@ -772,7 +788,9 @@ void shouldSetApplicationReceivedDate() { .build(); // When - underTest.createGenAppEntity(enterGenAppRequest, pcsCaseEntity, applicantParty, GEN_APP_ISSUED); + underTest.createGenAppEntity( + PCSCase.builder().enterGenAppRequest(enterGenAppRequest).build(), + pcsCaseEntity, applicantParty, GEN_APP_ISSUED); // Then GenAppEntity genAppEntity = getSavedGenAppEntity(); @@ -789,7 +807,9 @@ void shouldSetWithin14DaysFlag(VerticalYesNo within14Days) { .build(); // When - underTest.createGenAppEntity(enterGenAppRequest, pcsCaseEntity, applicantParty, GEN_APP_ISSUED); + underTest.createGenAppEntity( + PCSCase.builder().enterGenAppRequest(enterGenAppRequest).build(), + pcsCaseEntity, applicantParty, GEN_APP_ISSUED); // Then GenAppEntity genAppEntity = getSavedGenAppEntity(); @@ -807,7 +827,9 @@ void shouldSetFeeAmountReceived() { .build(); // When - underTest.createGenAppEntity(enterGenAppRequest, pcsCaseEntity, applicantParty, GEN_APP_ISSUED); + underTest.createGenAppEntity( + PCSCase.builder().enterGenAppRequest(enterGenAppRequest).build(), + pcsCaseEntity, applicantParty, GEN_APP_ISSUED); // Then GenAppEntity genAppEntity = getSavedGenAppEntity(); @@ -826,7 +848,9 @@ void shouldSetHwfFlagAndReferenceWhenYes() { .build(); // When - underTest.createGenAppEntity(enterGenAppRequest, pcsCaseEntity, applicantParty, GEN_APP_ISSUED); + underTest.createGenAppEntity( + PCSCase.builder().enterGenAppRequest(enterGenAppRequest).build(), + pcsCaseEntity, applicantParty, GEN_APP_ISSUED); // Then GenAppEntity genAppEntity = getSavedGenAppEntity(); @@ -846,7 +870,9 @@ void shouldSetHwfFlagButNotReferenceWhenNo() { .build(); // When - underTest.createGenAppEntity(enterGenAppRequest, pcsCaseEntity, applicantParty, GEN_APP_ISSUED); + underTest.createGenAppEntity( + PCSCase.builder().enterGenAppRequest(enterGenAppRequest).build(), + pcsCaseEntity, applicantParty, GEN_APP_ISSUED); // Then GenAppEntity genAppEntity = getSavedGenAppEntity(); @@ -854,6 +880,131 @@ void shouldSetHwfFlagButNotReferenceWhenNo() { assertThat(genAppEntity.getHelpWithFeesEntity()).isNull(); } + @Test + void shouldSaveUploadedGenAppAsSubmissionDocument() { + // Given + UUID applicantPartyId = UUID.randomUUID(); + when(applicantParty.getId()).thenReturn(applicantPartyId); + + String renamedFilename = "General Application GA1 - Claimant 1.docx"; + when(documentNameService.appendGenAppPostfix(eq("General Application.docx"), isA(GenAppEntity.class), + eq(mainClaim), eq(applicantPartyId) + )) + .thenReturn(renamedFilename); + + DocumentEntity savedDocumentEntity = mock(DocumentEntity.class); + when(documentRepository.save(isA(DocumentEntity.class))).thenReturn(savedDocumentEntity); + + EnterGenAppRequest enterGenAppRequest = EnterGenAppRequest.builder() + .applicationTypeOption(EnterGenAppType.SET_ASIDE) + .build(); + + Document uploadedGenApp = Document.builder() + .filename("my application.docx") + .url("test url") + .binaryUrl("test binary url") + .build(); + + // When + underTest.createGenAppEntity( + PCSCase.builder().enterGenAppRequest(enterGenAppRequest).uploadSingleDocument(uploadedGenApp).build(), + pcsCaseEntity, applicantParty, GEN_APP_ISSUED); + + // Then + GenAppEntity genAppEntity = getSavedGenAppEntity(); + assertThat(genAppEntity.getSubmissionDocument()).isEqualTo(savedDocumentEntity); + + verify(documentRepository).save(documentEntityCaptor.capture()); + DocumentEntity documentEntity = documentEntityCaptor.getValue(); + assertThat(documentEntity.getFileName()).isEqualTo(renamedFilename); + assertThat(documentEntity.getUrl()).isEqualTo("test url"); + assertThat(documentEntity.getBinaryUrl()).isEqualTo("test binary url"); + assertThat(documentEntity.getType()).isEqualTo(DocumentType.GENERAL_APPLICATION); + assertThat(documentEntity.getCategoryId()).isEqualTo(CaseFileCategory.APPLICATIONS.getId()); + } + + @Test + void shouldNotSaveSubmissionDocumentWhenUploadedGenAppIsNull() { + // Given + EnterGenAppRequest enterGenAppRequest = EnterGenAppRequest.builder() + .applicationTypeOption(EnterGenAppType.SET_ASIDE) + .build(); + + // When + underTest.createGenAppEntity( + PCSCase.builder().enterGenAppRequest(enterGenAppRequest).build(), + pcsCaseEntity, applicantParty, GEN_APP_ISSUED); + + // Then + GenAppEntity genAppEntity = getSavedGenAppEntity(); + assertThat(genAppEntity.getSubmissionDocument()).isNull(); + verify(documentRepository, never()).save(any(DocumentEntity.class)); + } + + @Test + void shouldSaveRelatedEvidenceDocuments() { + // Given + Document evidenceDocument = Document.builder() + .filename("circumstance statement.docx") + .url("evidence url") + .binaryUrl("evidence binary url") + .build(); + + UUID applicantPartyId = UUID.randomUUID(); + when(applicantParty.getId()).thenReturn(applicantPartyId); + + String renamedFilename = "circumstance statement GA1 - Claimant 1.docx"; + when(documentNameService.appendGenAppPostfix(eq("circumstance statement.docx"), isA(GenAppEntity.class), + eq(mainClaim), eq(applicantPartyId) + )) + .thenReturn(renamedFilename); + + List savedDocumentEntities = List.of(mock(DocumentEntity.class)); + when(documentRepository.saveAll(anyList())).thenReturn(savedDocumentEntities); + + EnterGenAppRequest enterGenAppRequest = EnterGenAppRequest.builder() + .applicationTypeOption(EnterGenAppType.SET_ASIDE) + .relatedEvidence(List.of(ListValue.builder().value(evidenceDocument).build())) + .build(); + + // When + underTest.createGenAppEntity( + PCSCase.builder().enterGenAppRequest(enterGenAppRequest).build(), + pcsCaseEntity, applicantParty, GEN_APP_ISSUED); + + // Then + GenAppEntity genAppEntity = getSavedGenAppEntity(); + assertThat(genAppEntity.getDocuments()).isEqualTo(savedDocumentEntities); + + verify(documentRepository).saveAll(documentEntityListCaptor.capture()); + assertThat(documentEntityListCaptor.getValue()).hasSize(1); + DocumentEntity documentEntity = documentEntityListCaptor.getValue().getFirst(); + assertThat(documentEntity.getFileName()).isEqualTo(renamedFilename); + assertThat(documentEntity.getUrl()).isEqualTo("evidence url"); + assertThat(documentEntity.getBinaryUrl()).isEqualTo("evidence binary url"); + assertThat(documentEntity.getType()).isNull(); + assertThat(documentEntity.getCategoryId()).isNull(); + } + + @Test + void shouldNotSaveRelatedEvidenceDocumentsWhenListIsNull() { + // Given + EnterGenAppRequest enterGenAppRequest = EnterGenAppRequest.builder() + .applicationTypeOption(EnterGenAppType.SET_ASIDE) + .relatedEvidence(null) + .build(); + + // When + underTest.createGenAppEntity( + PCSCase.builder().enterGenAppRequest(enterGenAppRequest).build(), + pcsCaseEntity, applicantParty, GEN_APP_ISSUED); + + // Then + GenAppEntity genAppEntity = getSavedGenAppEntity(); + assertThat(genAppEntity.getDocuments()).isEmpty(); + verify(documentRepository, never()).saveAll(anyList()); + } + } private GenAppEntity getSavedGenAppEntity() {