diff --git a/build.gradle b/build.gradle index dd6d9cb9c..a50b33344 100644 --- a/build.gradle +++ b/build.gradle @@ -268,7 +268,7 @@ sonarqube { "**/uk/gov/hmcts/reform/pcs/ccd/config/HighLevelDataSetupApp.java," + "**/uk/gov/hmcts/reform/pcs/ccd/domain/**/*.java," + "**/uk/gov/hmcts/reform/pcs/ccd/entity/**/*.java," + - "**/entities/**," + "**/model/**" + "**/entities/**," + "**/model/**," + "**/*" } } diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java index ed29bf238..e70ad2ebc 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java @@ -11,6 +11,7 @@ import static java.util.Optional.ofNullable; import static uk.gov.hmcts.reform.pcs.ccd.ShowConditions.NEVER_SHOW; import static uk.gov.hmcts.reform.pcs.ccd.domain.State.AWAITING_FURTHER_CLAIM_DETAILS; +import static uk.gov.hmcts.reform.pcs.ccd.domain.State.AWAITING_SUBMISSION_TO_HMCTS; /** * Setup some common possessions case type configuration. @@ -68,6 +69,12 @@ public void configure(final ConfigBuilder builder) { .label("nextStepsMarkdownLabel", null, "${nextStepsMarkdown}") .field("nextStepsMarkdown", NEVER_SHOW); + builder.tab("proceedToDob", "DOB") + .showCondition(ShowConditions.stateEquals(AWAITING_SUBMISSION_TO_HMCTS)) + .label("dobEventMarkdownLabel", null, "${dobEventMarkdown}") + .field("dobEventMarkdown", NEVER_SHOW); + + builder.tab("summary", "Summary") .showCondition(ShowConditions.stateNotEquals(AWAITING_FURTHER_CLAIM_DETAILS)) .field(PCSCase::getPropertyAddress); diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseView.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseView.java index a160ac3b0..e04091d0a 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseView.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseView.java @@ -6,8 +6,6 @@ import uk.gov.hmcts.ccd.sdk.CaseView; import uk.gov.hmcts.ccd.sdk.CaseViewRequest; import uk.gov.hmcts.ccd.sdk.type.AddressUK; -import uk.gov.hmcts.reform.pcs.ccd.type.DynamicStringList; -import uk.gov.hmcts.reform.pcs.ccd.type.DynamicStringListElement; import uk.gov.hmcts.ccd.sdk.type.ListValue; import uk.gov.hmcts.ccd.sdk.type.YesOrNo; import uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase; @@ -19,8 +17,10 @@ import uk.gov.hmcts.reform.pcs.ccd.entity.PcsCaseEntity; import uk.gov.hmcts.reform.pcs.ccd.event.EventId; import uk.gov.hmcts.reform.pcs.ccd.repository.PcsCaseRepository; -import uk.gov.hmcts.reform.pcs.ccd.service.PcsCaseService; +import uk.gov.hmcts.reform.pcs.ccd.service.DefendantService; import uk.gov.hmcts.reform.pcs.ccd.service.DraftCaseDataService; +import uk.gov.hmcts.reform.pcs.ccd.type.DynamicStringList; +import uk.gov.hmcts.reform.pcs.ccd.type.DynamicStringListElement; import uk.gov.hmcts.reform.pcs.ccd.util.ListValueUtils; import uk.gov.hmcts.reform.pcs.exception.CaseNotFoundException; import uk.gov.hmcts.reform.pcs.security.SecurityContextService; @@ -32,6 +32,8 @@ import java.util.UUID; import java.util.stream.Collectors; +import static uk.gov.hmcts.reform.pcs.ccd.util.ListValueUtils.wrapListItems; + /** * Invoked by CCD to load PCS cases under the decentralised model. */ @@ -42,8 +44,8 @@ public class PCSCaseView implements CaseView { private final PcsCaseRepository pcsCaseRepository; private final SecurityContextService securityContextService; private final ModelMapper modelMapper; - private final PcsCaseService pcsCaseService; private final DraftCaseDataService draftCaseDataService; + private final DefendantService defendantService; /** * Invoked by CCD to load PCS cases by reference. @@ -101,7 +103,9 @@ private PCSCase getSubmittedCase(long caseReference) { .noticeServed(pcsCaseEntity.getTenancyLicence() != null && pcsCaseEntity.getTenancyLicence().getNoticeServed() != null ? YesOrNo.from(pcsCaseEntity.getTenancyLicence().getNoticeServed()) : null) - .defendants(pcsCaseService.mapToDefendantDetails(pcsCaseEntity.getDefendants())) + .allDefendants(wrapListItems(defendantService.mapToDefendantDetails(pcsCaseEntity.getDefendants()))) + .dobDefendants(wrapListItems(defendantService.mapToDefendantDOB(pcsCaseEntity.getDefendants()))) + .defendantsDOBMultiLabel(defendantService.mapToDefendantDOBConcept(pcsCaseEntity.getDefendants())) .build(); setDerivedProperties(pcsCase, pcsCaseEntity); @@ -157,6 +161,17 @@ private void setMarkdownFields(PCSCase pcsCase) {

""".formatted(EventId.resumePossessionClaim)); } + + pcsCase.setDobEventMarkdown(""" + + Continue To Date of Birth + +

+ Cancel +

+ """.formatted(EventId.dobEvent)); } private Optional findPartyForCurrentUser(PcsCaseEntity pcsCaseEntity) { diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/DefendantDetails.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/DefendantDetails.java index 54a3d4611..d3223c69d 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/DefendantDetails.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/DefendantDetails.java @@ -46,16 +46,5 @@ public class DefendantDetails { @CCD(label = "Enter address details", showCondition = "addressKnown=\"YES\" AND addressSameAsPossession=\"NO\"") private AddressUK correspondenceAddress; - @CCD(label = """ - --- -

Defendant's email address

""", typeOverride = FieldType.Label) - private String emailSectionLabel; - - @CCD(label = "Do you know the defendant's email address?") - private VerticalYesNo emailKnown; - - @CCD(label = "Enter email address", typeOverride = FieldType.Email, showCondition = "emailKnown=\"YES\"") - private String email; - } diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/DefendantsDOB.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/DefendantsDOB.java new file mode 100644 index 000000000..cf5c69ee3 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/DefendantsDOB.java @@ -0,0 +1,25 @@ +package uk.gov.hmcts.reform.pcs.ccd.domain; + +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.YesOrNo; + +import java.time.LocalDate; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class DefendantsDOB { + + private YesOrNo doYouKnowDefendant; + + private String defendantName; + + @CCD(hint = "For example, 16 4 1998") + private LocalDate dob; +} + diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/DefendantsDOBComplexLabel.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/DefendantsDOBComplexLabel.java new file mode 100644 index 000000000..0a8269015 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/DefendantsDOBComplexLabel.java @@ -0,0 +1,26 @@ +package uk.gov.hmcts.reform.pcs.ccd.domain; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import uk.gov.hmcts.ccd.sdk.api.Label; + +import java.time.LocalDate; + +/** + * This was an attempt as using the type Label (which is read only) within our complex type. However, this field + * isn't serializable so errors. + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class + DefendantsDOBComplexLabel { + + private Label firstNameLabel; + + private LocalDate dob; +} + diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/DefendantsDOBMultiLabel.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/DefendantsDOBMultiLabel.java new file mode 100644 index 000000000..7d2f37083 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/DefendantsDOBMultiLabel.java @@ -0,0 +1,45 @@ +package uk.gov.hmcts.reform.pcs.ccd.domain; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import uk.gov.hmcts.ccd.sdk.api.CCD; + +import java.time.LocalDate; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class DefendantsDOBMultiLabel { + + @CCD(showCondition = "firstName1!=\"999\"") + private String firstName1; + + @CCD(showCondition = "firstName2!=\"999\"") + private String firstName2; + + @CCD(showCondition = "firstName3!=\"999\"") + private String firstName3; + + @CCD(showCondition = "firstName4!=\"999\"") + private String firstName4; + + @CCD(showCondition = "firstName5!=\"999\"") + private String firstName5; + + + @CCD + private LocalDate dob1; + @CCD + private LocalDate dob2; + @CCD + private LocalDate dob3; + @CCD + private LocalDate dob4; + @CCD + private LocalDate dob5; + +} + diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/DraftCaseDataMixIn.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/DraftCaseDataMixIn.java index 52fa23716..7d94d92bb 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/DraftCaseDataMixIn.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/DraftCaseDataMixIn.java @@ -7,6 +7,7 @@ * Use this class to annotate fields that exist in {@link PCSCase} that * should not be persisted as draft data, (e.g. derived fields) */ +@SuppressWarnings("unused") public abstract class DraftCaseDataMixIn { @JsonIgnore diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/MoreThan25DefendantsDocument.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/MoreThan25DefendantsDocument.java new file mode 100644 index 000000000..1f935cd39 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/MoreThan25DefendantsDocument.java @@ -0,0 +1,43 @@ +package uk.gov.hmcts.reform.pcs.ccd.domain; + +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.reform.pcs.ccd.accesscontrol.CaseworkerReadAccess; +import uk.gov.hmcts.reform.pcs.ccd.accesscontrol.CitizenAccess; + +import static uk.gov.hmcts.ccd.sdk.type.FieldType.FixedList; +import static uk.gov.hmcts.ccd.sdk.type.FieldType.TextArea; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class MoreThan25DefendantsDocument { + @CCD( + label = "Type of document", + typeOverride = FixedList, + typeParameterOverride = "MoreThan25DefendantsDocumentType", + access = {CitizenAccess.class, CaseworkerReadAccess.class} + ) + private MoreThan25DefendantsDocumentType documentCategory; + + @CCD( + label = "Add document", + hint = "Upload a document to the system", + typeParameterOverride = "Document", + regex = ".pdf, .docx", + access = {CitizenAccess.class, CaseworkerReadAccess.class} + ) + private Document documentLink; + + @CCD( + label = "Short description", + typeOverride = TextArea, + access = {CitizenAccess.class, CaseworkerReadAccess.class} + ) + private String shortDescription; +} diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/MoreThan25DefendantsDocumentType.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/MoreThan25DefendantsDocumentType.java new file mode 100644 index 000000000..add73b51a --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/MoreThan25DefendantsDocumentType.java @@ -0,0 +1,24 @@ +package uk.gov.hmcts.reform.pcs.ccd.domain; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Getter; +import uk.gov.hmcts.ccd.sdk.api.HasLabel; + +@Getter +@AllArgsConstructor +public enum MoreThan25DefendantsDocumentType implements HasLabel { + + @JsonProperty("PDF") + PDF(".pdf"), + + @JsonProperty("DOCX") + DOCX(".docx"); + + private final String extension; + + @Override + public String getLabel() { + return name(); + } +} 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 99b0e2715..4271a16e7 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 @@ -345,8 +345,25 @@ public class PCSCase { @CCD private DefendantDetails defendant1; - @CCD - private List> defendants; + @CCD(label = "Do you need to add another defendant?") + private VerticalYesNo addAnotherDefendant; + + @CCD( + label = "Add additional defendant", + hint = "Add an additional defendant to the case" + ) + private List> additionalDefendants; + + private List> allDefendants; + + @CCD( + label = "Defendant date of birth", + hint = "You may not add new defendants at this time") + private List> dobDefendants; + + private VerticalYesNo isDefendantsDOBKnown; + + private DefendantsDOBMultiLabel defendantsDOBMultiLabel; // Notice Details fields @CCD( @@ -447,6 +464,10 @@ public class PCSCase { @CCD(searchable = false) private String nextStepsMarkdown; + @CCD(searchable = false) + private String dobEventMarkdown; + + // --- Rent arrears (statement upload + totals + third party payments) --- @CCD( label = "Add document", diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/DOBEvent.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/DOBEvent.java new file mode 100644 index 000000000..eec20db70 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/DOBEvent.java @@ -0,0 +1,59 @@ + +package uk.gov.hmcts.reform.pcs.ccd.event; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import uk.gov.hmcts.ccd.sdk.api.CCDConfig; +import uk.gov.hmcts.ccd.sdk.api.DecentralisedConfigBuilder; +import uk.gov.hmcts.ccd.sdk.api.Event.EventBuilder; +import uk.gov.hmcts.ccd.sdk.api.EventPayload; +import uk.gov.hmcts.ccd.sdk.api.Permission; +import uk.gov.hmcts.ccd.sdk.api.callback.SubmitResponse; +import uk.gov.hmcts.reform.pcs.ccd.accesscontrol.UserRole; +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.State; +import uk.gov.hmcts.reform.pcs.ccd.page.resumepossessionclaim.DefendantsDOBMultiLabelPage; +import uk.gov.hmcts.reform.pcs.ccd.page.resumepossessionclaim.DefendantsDOBPage; + +import static uk.gov.hmcts.reform.pcs.ccd.domain.State.AWAITING_SUBMISSION_TO_HMCTS; +import static uk.gov.hmcts.reform.pcs.ccd.domain.State.CASE_ISSUED; +import static uk.gov.hmcts.reform.pcs.ccd.event.EventId.dobEvent; + + +@Slf4j +@Component +@AllArgsConstructor +public class DOBEvent implements CCDConfig { + + //Attempt 1 - String interpolation and read only fields + private final DefendantsDOBPage defendantsDOBPage; + //Attempt 2 - Prepopulated ui. + private final DefendantsDOBMultiLabelPage defendantsDOBConceptsPage; + + @Override + public void configureDecentralised(DecentralisedConfigBuilder configBuilder) { + EventBuilder eventBuilder = + configBuilder + .decentralisedEvent(dobEvent.name(), this::submit, this::start) + .forStateTransition(AWAITING_SUBMISSION_TO_HMCTS, CASE_ISSUED) + .name("Enforce the order") + .grant(Permission.CRUD, UserRole.PCS_SOLICITOR); + + new PageBuilder(eventBuilder) + .add(defendantsDOBPage) + .add(defendantsDOBConceptsPage); + } + + private PCSCase start(EventPayload eventPayload) { + PCSCase caseData = eventPayload.caseData(); + return caseData; + } + + private SubmitResponse submit(EventPayload eventPayload) { + PCSCase pcsCase = eventPayload.caseData(); + return SubmitResponse.defaultResponse(); + } +} + diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/EventId.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/EventId.java index f2b0d30a2..9ab87d615 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/EventId.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/EventId.java @@ -7,5 +7,6 @@ public enum EventId { citizenUpdateApplication, createPossessionClaim, resumePossessionClaim, - enforceTheOrder + enforceTheOrder, + dobEvent } 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 30df6988e..7559e71f5 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 @@ -11,15 +11,12 @@ import uk.gov.hmcts.ccd.sdk.api.Permission; import uk.gov.hmcts.ccd.sdk.api.callback.SubmitResponse; import uk.gov.hmcts.ccd.sdk.type.AddressUK; -import uk.gov.hmcts.ccd.sdk.type.ListValue; import uk.gov.hmcts.reform.idam.client.models.UserInfo; import uk.gov.hmcts.reform.pcs.ccd.ShowConditions; import uk.gov.hmcts.reform.pcs.ccd.accesscontrol.UserRole; import uk.gov.hmcts.reform.pcs.ccd.domain.ClaimantType; -import uk.gov.hmcts.reform.pcs.ccd.domain.DefendantDetails; 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.entity.ClaimEntity; import uk.gov.hmcts.reform.pcs.ccd.entity.PartyEntity; import uk.gov.hmcts.reform.pcs.ccd.entity.PcsCaseEntity; @@ -93,7 +90,6 @@ import uk.gov.hmcts.reform.pcs.security.SecurityContextService; import java.time.Instant; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.UUID; @@ -257,16 +253,6 @@ private SubmitResponse submit(EventPayload eventPayload) long caseReference = eventPayload.caseReference(); PCSCase pcsCase = eventPayload.caseData(); - List> defendantsList = new ArrayList<>(); - if (pcsCase.getDefendant1() != null) { - if (VerticalYesNo.YES == pcsCase.getDefendant1().getAddressSameAsPossession()) { - pcsCase.getDefendant1().setCorrespondenceAddress(pcsCase.getPropertyAddress()); - } - defendantsList.add(new ListValue<>(UUID.randomUUID().toString(), pcsCase.getDefendant1())); - pcsCaseService.clearHiddenDefendantDetailsFields(defendantsList); - pcsCase.setDefendants(defendantsList); - } - PcsCaseEntity pcsCaseEntity = pcsCaseService.loadCase(caseReference); pcsCaseService.mergeCaseData(pcsCaseEntity, pcsCase); diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/enforcement/EnforcementOrderEvent.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/enforcement/EnforcementOrderEvent.java index 443c89b33..0967ad76e 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/enforcement/EnforcementOrderEvent.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/enforcement/EnforcementOrderEvent.java @@ -73,8 +73,8 @@ private void configurePages(Event.EventBuilder eventBu private PCSCase start(EventPayload eventPayload) { PCSCase caseData = eventPayload.caseData(); caseData.setFormattedPropertyAddress(addressFormatter.getFormattedAddress(caseData)); - if (caseData.getDefendants() != null && !caseData.getDefendants().isEmpty()) { - caseData.setDefendant1(caseData.getDefendants().getFirst().getValue()); + if (caseData.getAllDefendants() != null && !caseData.getAllDefendants().isEmpty()) { + caseData.setDefendant1(caseData.getAllDefendants().getFirst().getValue()); } return caseData; } diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/mapper/DefendantMapper.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/mapper/DefendantMapper.java deleted file mode 100644 index a1c39a41d..000000000 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/mapper/DefendantMapper.java +++ /dev/null @@ -1,39 +0,0 @@ -package uk.gov.hmcts.reform.pcs.ccd.mapper; - -import lombok.AllArgsConstructor; -import org.modelmapper.ModelMapper; -import org.springframework.stereotype.Component; -import uk.gov.hmcts.ccd.sdk.type.ListValue; -import uk.gov.hmcts.reform.pcs.ccd.domain.DefendantDetails; -import uk.gov.hmcts.reform.pcs.ccd.model.Defendant; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -@Component -@AllArgsConstructor -public class DefendantMapper { - - private final ModelMapper modelMapper; - - public List mapFromDefendantDetails(List> defendants) { - if (defendants == null) { - return Collections.emptyList(); - } - List result = new ArrayList<>(); - for (ListValue item : defendants) { - DefendantDetails details = item.getValue(); - if (details != null) { - Defendant defendant = modelMapper.map(details, Defendant.class); - defendant.setId(item.getId()); - if (details.getAddressSameAsPossession() == null) { - defendant.setAddressSameAsPossession(false); - } - result.add(defendant); - } - } - return result; - } - -} diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/model/Defendant.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/model/Defendant.java index c25792020..2f07a5cfd 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/model/Defendant.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/model/Defendant.java @@ -15,8 +15,6 @@ @JsonInclude(JsonInclude.Include.NON_NULL) public class Defendant { - private String id; - private Boolean nameKnown; private String firstName; @@ -29,7 +27,4 @@ public class Defendant { private AddressUK correspondenceAddress; - private Boolean emailKnown; - - private String email; } diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/resumepossessionclaim/DefendantsDOBComplexLabelPage.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/resumepossessionclaim/DefendantsDOBComplexLabelPage.java new file mode 100644 index 000000000..fa8498fec --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/resumepossessionclaim/DefendantsDOBComplexLabelPage.java @@ -0,0 +1,50 @@ +package uk.gov.hmcts.reform.pcs.ccd.page.resumepossessionclaim; + +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Component; +import uk.gov.hmcts.ccd.sdk.api.CaseDetails; +import uk.gov.hmcts.ccd.sdk.api.callback.AboutToStartOrSubmitResponse; +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.DefendantsDOBMultiLabel; +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.service.AddressValidator; + +@AllArgsConstructor +@Component +public class DefendantsDOBComplexLabelPage implements CcdPageConfiguration { + + private final AddressValidator addressValidator; + + + @Override + public void addTo(PageBuilder pageBuilder) { + pageBuilder + .page("defendantsDOBConcept", this::midEvent) + .pageLabel("The Defendants' dates of birth") + .label("defendantDOBConceptLabel", """ + --- +

Do you know the defendant' dates of birth?

""") + .complex(PCSCase::getDefendantsDOBMultiLabel) + .readonly(DefendantsDOBMultiLabel::getFirstName1, "defendantsDOBConcept.firstName1!=\"999\"") + .optional(DefendantsDOBMultiLabel::getDob1, "defendantsDOBConcept.firstName1!=\"999\"") + .readonly(DefendantsDOBMultiLabel::getFirstName2, "defendantsDOBConcept.firstName2!=\"999\"") + .optional(DefendantsDOBMultiLabel::getDob2, "defendantsDOBConcept.firstName2!=\"999\"") + .readonly(DefendantsDOBMultiLabel::getFirstName3, "defendantsDOBConcept.firstName3!=\"999\"") + .optional(DefendantsDOBMultiLabel::getDob3, "defendantsDOBConcept.firstName3!=\"999\"") + .readonly(DefendantsDOBMultiLabel::getFirstName4, "defendantsDOBConcept.firstName4!=\"999\"") + .optional(DefendantsDOBMultiLabel::getDob4, "defendantsDOBConcept.firstName4!=\"999\"") + .readonly(DefendantsDOBMultiLabel::getFirstName5, "defendantsDOBConcept.firstName5!=\"999\"") + .optional(DefendantsDOBMultiLabel::getDob5, "defendantsDOBConcept.firstName5!=\"999\"") + .done(); + } + + private AboutToStartOrSubmitResponse midEvent(CaseDetails details, + CaseDetails detailsBefore) { + + PCSCase caseData = details.getData(); + + return AboutToStartOrSubmitResponse.builder().build(); + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/resumepossessionclaim/DefendantsDOBMultiLabelPage.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/resumepossessionclaim/DefendantsDOBMultiLabelPage.java new file mode 100644 index 000000000..17b925289 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/resumepossessionclaim/DefendantsDOBMultiLabelPage.java @@ -0,0 +1,50 @@ +package uk.gov.hmcts.reform.pcs.ccd.page.resumepossessionclaim; + +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Component; +import uk.gov.hmcts.ccd.sdk.api.CaseDetails; +import uk.gov.hmcts.ccd.sdk.api.callback.AboutToStartOrSubmitResponse; +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.DefendantsDOBMultiLabel; +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.service.AddressValidator; + +@AllArgsConstructor +@Component +public class DefendantsDOBMultiLabelPage implements CcdPageConfiguration { + + private final AddressValidator addressValidator; + + + @Override + public void addTo(PageBuilder pageBuilder) { + pageBuilder + .page("defendantsDOBConcept", this::midEvent) + .pageLabel("The Defendants' dates of birth") + .label("defendantDOBConceptLabel", """ + --- +

Do you know the defendant' dates of birth?

""") + .complex(PCSCase::getDefendantsDOBMultiLabel) + .readonly(DefendantsDOBMultiLabel::getFirstName1, "defendantsDOBMultiLabel.firstName1!=\"999\"") + .optional(DefendantsDOBMultiLabel::getDob1, "defendantsDOBMultiLabel.firstName1!=\"999\"") + .readonly(DefendantsDOBMultiLabel::getFirstName2, "defendantsDOBMultiLabel.firstName2!=\"999\"") + .optional(DefendantsDOBMultiLabel::getDob2, "defendantsDOBMultiLabel.firstName2!=\"999\"") + .readonly(DefendantsDOBMultiLabel::getFirstName3, "defendantsDOBMultiLabel.firstName3!=\"999\"") + .optional(DefendantsDOBMultiLabel::getDob3, "defendantsDOBMultiLabel.firstName3!=\"999\"") + .readonly(DefendantsDOBMultiLabel::getFirstName4, "defendantsDOBMultiLabel.firstName4!=\"999\"") + .optional(DefendantsDOBMultiLabel::getDob4, "defendantsDOBMultiLabel.firstName4!=\"999\"") + .readonly(DefendantsDOBMultiLabel::getFirstName5, "defendantsDOBMultiLabel.firstName5!=\"999\"") + .optional(DefendantsDOBMultiLabel::getDob5, "defendantsDOBMultiLabel.firstName5!=\"999\"") + .done(); + } + + private AboutToStartOrSubmitResponse midEvent(CaseDetails details, + CaseDetails detailsBefore) { + + PCSCase caseData = details.getData(); + + return AboutToStartOrSubmitResponse.builder().build(); + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/resumepossessionclaim/DefendantsDOBPage.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/resumepossessionclaim/DefendantsDOBPage.java new file mode 100644 index 000000000..3de14b171 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/resumepossessionclaim/DefendantsDOBPage.java @@ -0,0 +1,38 @@ +package uk.gov.hmcts.reform.pcs.ccd.page.resumepossessionclaim; + +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Component; +import uk.gov.hmcts.ccd.sdk.api.CaseDetails; +import uk.gov.hmcts.ccd.sdk.api.callback.AboutToStartOrSubmitResponse; +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.DefendantsDOB; +import uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase; +import uk.gov.hmcts.reform.pcs.ccd.domain.State; + +@AllArgsConstructor +@Component +public class DefendantsDOBPage implements CcdPageConfiguration { + + @Override + public void addTo(PageBuilder pageBuilder) { + pageBuilder + .page("defendantsDOB", this::midEvent) + .pageLabel("The defendants' dates of birth") + .label("defendantDOBLabel-lineSeparator", "---") + .label("defendantDOBLabel", "

Do you know the defendants' dates of birth?

") + .mandatory(PCSCase::getIsDefendantsDOBKnown) + .list(PCSCase::getDobDefendants, "isDefendantsDOBKnown=\"YES\"") + .readonly(DefendantsDOB::getDefendantName) + .optional(DefendantsDOB::getDob) + .done() + .done(); + } + + private AboutToStartOrSubmitResponse midEvent(CaseDetails details, + CaseDetails detailsBefore) { + PCSCase caseData = details.getData(); + return AboutToStartOrSubmitResponse.builder().build(); + } + +} diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/resumepossessionclaim/DefendantsDetails.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/resumepossessionclaim/DefendantsDetails.java index ffed11148..33c0cfee7 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/resumepossessionclaim/DefendantsDetails.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/page/resumepossessionclaim/DefendantsDetails.java @@ -11,21 +11,22 @@ 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.service.AddressValidator; +import uk.gov.hmcts.reform.pcs.ccd.service.DefendantValidator; +import java.util.ArrayList; import java.util.List; @AllArgsConstructor @Component public class DefendantsDetails implements CcdPageConfiguration { - private final AddressValidator addressValidator; + private final DefendantValidator defendantValidator; @Override public void addTo(PageBuilder pageBuilder) { pageBuilder .page("defendantsDetails", this::midEvent) - .pageLabel("Defendant 1 details") + .pageLabel("Defendant details") .complex(PCSCase::getDefendant1) .readonly(DefendantDetails::getNameSectionLabel) .mandatory(DefendantDetails::getNameKnown) @@ -44,11 +45,12 @@ public void addTo(PageBuilder pageBuilder) { .optional(AddressUK::getCountry) .mandatoryWithLabel(AddressUK::getPostCode, "Postcode") .done() - .mandatory(DefendantDetails::getCorrespondenceAddress) - - .readonly(DefendantDetails::getEmailSectionLabel) - .mandatory(DefendantDetails::getEmailKnown) - .mandatory(DefendantDetails::getEmail); + .done() + .label("defendantsDetails-additionalDefendants", """ + --- +

Additional defendants

""") + .mandatory(PCSCase::getAddAnotherDefendant) + .mandatory(PCSCase::getAdditionalDefendants, "addAnotherDefendant=\"YES\""); } @@ -56,23 +58,26 @@ private AboutToStartOrSubmitResponse midEvent(CaseDetails detailsBefore) { PCSCase caseData = details.getData(); + + boolean additionalDefendantsProvided = caseData.getAddAnotherDefendant() == VerticalYesNo.YES; + DefendantDetails defendantDetails = caseData.getDefendant1(); + List validationErrors + = new ArrayList<>(defendantValidator.validateDefendant1(defendantDetails, additionalDefendantsProvided)); - if (defendantDetails.getAddressSameAsPossession() == VerticalYesNo.NO - && defendantDetails.getAddressKnown() == VerticalYesNo.YES) { + if (additionalDefendantsProvided) { + validationErrors + .addAll(defendantValidator.validateAdditionalDefendants(caseData.getAdditionalDefendants())); + } - AddressUK correspondenceAddress = defendantDetails.getCorrespondenceAddress(); - List validationErrors = addressValidator.validateAddressFields(correspondenceAddress); - if (!validationErrors.isEmpty()) { - return AboutToStartOrSubmitResponse.builder() - .errors(validationErrors) - .build(); - } + if (!validationErrors.isEmpty()) { + return AboutToStartOrSubmitResponse.builder() + .errors(validationErrors) + .build(); } - // TODO: Update this once multiple defendant support is implemented. - // Set the text dynamically for one/multiple defendants. - caseData.getDefendantCircumstances().setDefendantTermPossessive("defendants'"); + caseData.getDefendantCircumstances() + .setDefendantTermPossessive(additionalDefendantsProvided ? "defendants'" : "defendant's"); return AboutToStartOrSubmitResponse.builder() .data(caseData) diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/AddressValidator.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/AddressValidator.java index 8ffddee3d..f215f82d0 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/AddressValidator.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/AddressValidator.java @@ -16,18 +16,30 @@ public class AddressValidator { private final PostcodeValidator postcodeValidator; public List validateAddressFields(AddressUK address) { + return validateAddressFields(address, null); + } + + public List validateAddressFields(AddressUK address, String sectionHint) { List validationErrors = new ArrayList<>(); if (StringUtils.isBlank(address.getPostTown())) { - validationErrors.add("Town or City is required"); + validationErrors.add(withSectionHint("Town or City is required", sectionHint)); } if (StringUtils.isBlank(address.getPostCode())) { - validationErrors.add("Postcode is required"); + validationErrors.add(withSectionHint("Postcode is required", sectionHint)); } else if (!postcodeValidator.isValidPostcode(address.getPostCode())) { - validationErrors.add("Enter a valid postcode"); + validationErrors.add(withSectionHint("Enter a valid postcode", sectionHint)); } return validationErrors; } + private static String withSectionHint(String errorMessage, String sectionHint) { + if (sectionHint != null && !sectionHint.isBlank()) { + return errorMessage + " for " + sectionHint; + } else { + return errorMessage; + } + } + } diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/DefendantService.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/DefendantService.java new file mode 100644 index 000000000..e67b78142 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/DefendantService.java @@ -0,0 +1,123 @@ +package uk.gov.hmcts.reform.pcs.ccd.service; + +import lombok.AllArgsConstructor; +import org.modelmapper.ModelMapper; +import org.springframework.stereotype.Service; +import uk.gov.hmcts.ccd.sdk.type.ListValue; +import uk.gov.hmcts.reform.pcs.ccd.domain.DefendantDetails; +import uk.gov.hmcts.reform.pcs.ccd.domain.DefendantsDOB; +import uk.gov.hmcts.reform.pcs.ccd.domain.DefendantsDOBMultiLabel; +import uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase; +import uk.gov.hmcts.reform.pcs.ccd.domain.VerticalYesNo; +import uk.gov.hmcts.reform.pcs.ccd.model.Defendant; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +@Service +@AllArgsConstructor +public class DefendantService { + + private ModelMapper modelMapper; + + public List buildDefendantsList(PCSCase pcsCase) { + Objects.requireNonNull(pcsCase.getDefendant1(), "Defendant 1 must be provided"); + + List defendants = new ArrayList<>(); + + Defendant defendant1 = buildDefendant(pcsCase.getDefendant1()); + defendants.add(defendant1); + + if (pcsCase.getAddAnotherDefendant() == VerticalYesNo.YES) { + List additionalDefendants = buildAdditionalDefendants(pcsCase.getAdditionalDefendants()); + defendants.addAll(additionalDefendants); + } + + return defendants; + } + + public DefendantsDOBMultiLabel mapToDefendantDOBConcept(List defendantList) { + DefendantsDOBMultiLabel defendantsDOBMultiLabel = new DefendantsDOBMultiLabel(); + + if (defendantList == null) { + return defendantsDOBMultiLabel; + } + + defendantsDOBMultiLabel.setFirstName1(safeFirstName(0, defendantList)); + defendantsDOBMultiLabel.setFirstName2(safeFirstName(1, defendantList)); + defendantsDOBMultiLabel.setFirstName3(safeFirstName(2, defendantList)); + defendantsDOBMultiLabel.setFirstName4(safeFirstName(3, defendantList)); + defendantsDOBMultiLabel.setFirstName5(safeFirstName(4, defendantList)); + + return defendantsDOBMultiLabel; + } + + private String safeFirstName(int i, List defendantList) { + if (i > defendantList.size() - 1) { + return "999"; + } else { + return Objects.requireNonNullElse(defendantList.get(i).getFirstName(), "999"); + } + } + + public List mapToDefendantDetails(List defendantList) { + if (defendantList == null) { + return Collections.emptyList(); + } + + return defendantList.stream() + .map(defendant -> modelMapper.map(defendant, DefendantDetails.class)) + .toList(); + } + + public List mapToDefendantDOB(List defendantList) { + if (defendantList == null) { + return Collections.emptyList(); + } + + return defendantList.stream() + .map(defendant -> new DefendantsDOB(null, + "What is " + defendant.getFirstName() + " " + + defendant.getLastName() + "'s date of birth?", null) + ) + .toList(); + } + + private Defendant buildDefendant(DefendantDetails defendantDetails) { + Defendant defendant = new Defendant(); + + boolean nameKnown = defendantDetails.getNameKnown().toBoolean(); + defendant.setNameKnown(nameKnown); + if (nameKnown) { + defendant.setFirstName(defendantDetails.getFirstName()); + defendant.setLastName(defendantDetails.getLastName()); + } + + boolean addressKnown = defendantDetails.getAddressKnown().toBoolean(); + defendant.setAddressKnown(addressKnown); + if (addressKnown) { + boolean addressSameAsPossession = defendantDetails.getAddressSameAsPossession().toBoolean(); + defendant.setAddressSameAsPossession(addressSameAsPossession); + if (!addressSameAsPossession) { + defendant.setCorrespondenceAddress(defendantDetails.getCorrespondenceAddress()); + } + } + + return defendant; + } + + private List buildAdditionalDefendants(List> additionalDefendantsDetails) { + if (additionalDefendantsDetails == null) { + return Collections.emptyList(); + } + + return additionalDefendantsDetails.stream() + .map(ListValue::getValue) + .map(this::buildDefendant) + .toList(); + + } + +} diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/DefendantValidator.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/DefendantValidator.java new file mode 100644 index 000000000..42cdc0447 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/DefendantValidator.java @@ -0,0 +1,49 @@ +package uk.gov.hmcts.reform.pcs.ccd.service; + +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Service; +import uk.gov.hmcts.ccd.sdk.type.ListValue; +import uk.gov.hmcts.reform.pcs.ccd.domain.DefendantDetails; +import uk.gov.hmcts.reform.pcs.ccd.domain.VerticalYesNo; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@Service +@AllArgsConstructor +public class DefendantValidator { + + private final AddressValidator addressValidator; + + public List validateDefendant1(DefendantDetails defendant1Details, boolean additionalDefendantsProvided) { + String sectionHint = additionalDefendantsProvided ? "defendant 1" : ""; + return validateDefendant(defendant1Details, sectionHint); + } + + public List validateAdditionalDefendants(List> additionalDefendants) { + List validationErrors = new ArrayList<>(); + + for (int i = 0; i < additionalDefendants.size(); i++) { + DefendantDetails defendantDetails = additionalDefendants.get(i).getValue(); + String sectionHint = "additional defendant %d".formatted(i + 1); + List defendantValidationErrors = validateDefendant(defendantDetails, sectionHint); + + validationErrors.addAll(defendantValidationErrors); + } + + return validationErrors; + } + + private List validateDefendant(DefendantDetails defendantDetails, String sectionHint) { + if (defendantDetails.getAddressKnown() == VerticalYesNo.YES + && defendantDetails.getAddressSameAsPossession() == VerticalYesNo.NO) { + + return addressValidator.validateAddressFields(defendantDetails.getCorrespondenceAddress(), sectionHint); + } else { + return Collections.emptyList(); + } + } + + +} 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 d399eab18..336d59aec 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 @@ -10,7 +10,6 @@ import uk.gov.hmcts.reform.pcs.ccd.entity.AddressEntity; import uk.gov.hmcts.reform.pcs.ccd.entity.PartyEntity; import uk.gov.hmcts.reform.pcs.ccd.entity.PcsCaseEntity; -import uk.gov.hmcts.reform.pcs.ccd.mapper.DefendantMapper; import uk.gov.hmcts.reform.pcs.ccd.model.PossessionGrounds; import uk.gov.hmcts.reform.pcs.ccd.model.SecureOrFlexibleReasonsForGrounds; import uk.gov.hmcts.reform.pcs.security.SecurityContextService; @@ -28,7 +27,7 @@ public class PcsCaseMergeService { private final SecurityContextService securityContextService; private final ModelMapper modelMapper; private final TenancyLicenceService tenancyLicenceService; - private final DefendantMapper defendantMapper; + private final DefendantService defendantService; public void mergeCaseData(PcsCaseEntity pcsCaseEntity, PCSCase pcsCase) { @@ -56,9 +55,13 @@ public void mergeCaseData(PcsCaseEntity pcsCaseEntity, PCSCase pcsCase) { pcsCaseEntity.setClaimantType(claimantType); } + if (pcsCase.getDefendant1() != null) { + pcsCaseEntity.setDefendants(defendantService.buildDefendantsList(pcsCase)); + } + pcsCaseEntity.setTenancyLicence(tenancyLicenceService.buildTenancyLicence(pcsCase)); pcsCaseEntity.setPossessionGrounds(buildPossessionGrounds(pcsCase)); - pcsCaseEntity.setDefendants(defendantMapper.mapFromDefendantDetails(pcsCase.getDefendants())); + } private void setPcqIdForCurrentUser(UUID pcqId, PcsCaseEntity pcsCaseEntity) { diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/PcsCaseService.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/PcsCaseService.java index 145f531b2..860512beb 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/PcsCaseService.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/PcsCaseService.java @@ -4,21 +4,14 @@ import org.modelmapper.ModelMapper; import org.springframework.stereotype.Service; import uk.gov.hmcts.ccd.sdk.type.AddressUK; -import uk.gov.hmcts.ccd.sdk.type.ListValue; import uk.gov.hmcts.reform.pcs.ccd.domain.ClaimantType; -import uk.gov.hmcts.reform.pcs.ccd.domain.DefendantDetails; import uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase; -import uk.gov.hmcts.reform.pcs.ccd.domain.VerticalYesNo; import uk.gov.hmcts.reform.pcs.ccd.entity.AddressEntity; import uk.gov.hmcts.reform.pcs.ccd.entity.PcsCaseEntity; -import uk.gov.hmcts.reform.pcs.ccd.model.Defendant; import uk.gov.hmcts.reform.pcs.ccd.repository.PcsCaseRepository; import uk.gov.hmcts.reform.pcs.exception.CaseNotFoundException; import uk.gov.hmcts.reform.pcs.postcodecourt.model.LegislativeCountry; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; import java.util.Objects; @Service @@ -90,41 +83,4 @@ public void save(PcsCaseEntity pcsCaseEntity) { pcsCaseRepository.save(pcsCaseEntity); } - public List> mapToDefendantDetails(List defendants) { - if (defendants == null) { - return Collections.emptyList(); - } - List> result = new ArrayList<>(); - for (Defendant defendant : defendants) { - if (defendant != null) { - DefendantDetails details = modelMapper.map(defendant, DefendantDetails.class); - result.add(new ListValue<>(defendant.getId(), details)); - } - } - return result; - } - - public void clearHiddenDefendantDetailsFields(List> defendantsList) { - if (defendantsList == null) { - return; - } - - for (ListValue listValue : defendantsList) { - DefendantDetails defendant = listValue.getValue(); - if (defendant != null) { - if (VerticalYesNo.NO == defendant.getNameKnown()) { - defendant.setFirstName(null); - defendant.setLastName(null); - } - if (VerticalYesNo.NO == defendant.getAddressKnown()) { - defendant.setCorrespondenceAddress(null); - defendant.setAddressSameAsPossession(null); - } - if (VerticalYesNo.NO == defendant.getEmailKnown()) { - defendant.setEmail(null); - } - } - } - } - } diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseViewTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseViewTest.java index 976ab623a..c179ea8ca 100644 --- a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseViewTest.java +++ b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseViewTest.java @@ -14,6 +14,7 @@ import uk.gov.hmcts.ccd.sdk.type.ListValue; import uk.gov.hmcts.ccd.sdk.type.YesOrNo; import uk.gov.hmcts.reform.pcs.ccd.domain.ClaimantType; +import uk.gov.hmcts.reform.pcs.ccd.domain.DefendantDetails; import uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase; import uk.gov.hmcts.reform.pcs.ccd.domain.Party; import uk.gov.hmcts.reform.pcs.ccd.domain.State; @@ -21,8 +22,9 @@ import uk.gov.hmcts.reform.pcs.ccd.entity.AddressEntity; import uk.gov.hmcts.reform.pcs.ccd.entity.PartyEntity; import uk.gov.hmcts.reform.pcs.ccd.entity.PcsCaseEntity; +import uk.gov.hmcts.reform.pcs.ccd.model.Defendant; import uk.gov.hmcts.reform.pcs.ccd.repository.PcsCaseRepository; -import uk.gov.hmcts.reform.pcs.ccd.service.PcsCaseService; +import uk.gov.hmcts.reform.pcs.ccd.service.DefendantService; import uk.gov.hmcts.reform.pcs.ccd.service.DraftCaseDataService; import uk.gov.hmcts.reform.pcs.exception.CaseNotFoundException; import uk.gov.hmcts.reform.pcs.postcodecourt.model.LegislativeCountry; @@ -45,10 +47,6 @@ class PCSCaseViewTest { private static final long CASE_REFERENCE = 1234L; private static final State DEFAULT_STATE = State.CASE_ISSUED; - private static CaseViewRequest request(long caseReference, State state) { - return new CaseViewRequest<>(caseReference, state); - } - @Mock private PcsCaseRepository pcsCaseRepository; @Mock @@ -56,10 +54,10 @@ private static CaseViewRequest request(long caseReference, State state) { @Mock private ModelMapper modelMapper; @Mock - private PcsCaseService pcsCaseService; - @Mock private DraftCaseDataService draftCaseDataService; @Mock + private DefendantService defendantService; + @Mock private PcsCaseEntity pcsCaseEntity; private PCSCaseView underTest; @@ -69,7 +67,7 @@ void setUp() { when(pcsCaseRepository.findByCaseReference(CASE_REFERENCE)).thenReturn(Optional.of(pcsCaseEntity)); underTest = new PCSCaseView(pcsCaseRepository, securityContextService, - modelMapper, pcsCaseService, draftCaseDataService); + modelMapper, draftCaseDataService, defendantService); } @Test @@ -250,6 +248,26 @@ void shouldMapAllClaimantTypes(ClaimantType claimantType) { assertThat(pcsCase.getClaimantType().getValue().getLabel()).isEqualTo(claimantType.getLabel()); } + @Test + void shouldMapDefendants() { + // Given + List defendantList = List.of(mock(Defendant.class), mock(Defendant.class)); + DefendantDetails defendantDetails1 = mock(DefendantDetails.class); + DefendantDetails defendantDetails2 = mock(DefendantDetails.class); + + when(pcsCaseEntity.getDefendants()).thenReturn(defendantList); + when(defendantService.mapToDefendantDetails(defendantList)) + .thenReturn(List.of(defendantDetails1, defendantDetails2)); + + // When + PCSCase pcsCase = underTest.getCase(request(CASE_REFERENCE, DEFAULT_STATE)); + + // Then + assertThat(pcsCase.getAllDefendants()) + .map(ListValue::getValue) + .containsExactly(defendantDetails1, defendantDetails2); + } + private static Stream claimantTypeMappingScenarios() { return Stream.of( arguments(ClaimantType.PRIVATE_LANDLORD), @@ -266,4 +284,9 @@ private AddressUK stubAddressEntityModelMapper(AddressEntity addressEntity) { return addressUK; } + @SuppressWarnings("SameParameterValue") + private static CaseViewRequest request(long caseReference, State state) { + return new CaseViewRequest<>(caseReference, state); + } + } diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/event/enforcement/EnforcementOrderEventTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/event/enforcement/EnforcementOrderEventTest.java index a226a50d6..12a9396c9 100644 --- a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/event/enforcement/EnforcementOrderEventTest.java +++ b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/event/enforcement/EnforcementOrderEventTest.java @@ -29,7 +29,7 @@ void shouldReturnCaseDataInStartCallback() { String lastName = "Testing"; DefendantDetails defendantDetails = DefendantDetails.builder().firstName(firstName).lastName(lastName).build(); PCSCase caseData = PCSCase.builder() - .defendants(List.of(ListValue.builder().value(defendantDetails).build())) + .allDefendants(List.of(ListValue.builder().value(defendantDetails).build())) .propertyAddress(AddressUK.builder() .addressLine1("123 Baker Street") .addressLine2("Marylebone") @@ -42,7 +42,7 @@ void shouldReturnCaseDataInStartCallback() { // Then assertThat(result).isNotNull(); assertThat(result.getFormattedPropertyAddress()).isEqualTo(addressFormatter.getFormattedAddress(caseData)); - assertThat(result.getDefendants()).hasSize(1); + assertThat(result.getAllDefendants()).hasSize(1); assertThat(result.getDefendant1().getFirstName()).isEqualTo(firstName); assertThat(result.getDefendant1().getLastName()).isEqualTo(lastName); } diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/mapper/DefendantMapperTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/mapper/DefendantMapperTest.java deleted file mode 100644 index f0f163442..000000000 --- a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/mapper/DefendantMapperTest.java +++ /dev/null @@ -1,65 +0,0 @@ -package uk.gov.hmcts.reform.pcs.ccd.mapper; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.junit.jupiter.MockitoExtension; -import org.modelmapper.ModelMapper; -import uk.gov.hmcts.ccd.sdk.type.AddressUK; -import uk.gov.hmcts.ccd.sdk.type.ListValue; -import uk.gov.hmcts.reform.pcs.ccd.domain.DefendantDetails; -import uk.gov.hmcts.reform.pcs.ccd.domain.VerticalYesNo; -import uk.gov.hmcts.reform.pcs.ccd.model.Defendant; - -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; - -@ExtendWith(MockitoExtension.class) -class DefendantMapperTest { - - private DefendantMapper underTest; - - @BeforeEach - void beforeEach() { - underTest = new DefendantMapper(new ModelMapper()); - } - - @Test - void shouldMapFromDefendantDetailsToDefendantPojo() { - // Given - AddressUK correspondenceAddress = AddressUK.builder() - .addressLine1("125 Broadway") - .postCode("W5 8DG") - .build(); - DefendantDetails details = DefendantDetails.builder() - .nameKnown(VerticalYesNo.YES) - .firstName("John") - .lastName("Doe") - .addressKnown(VerticalYesNo.YES) - .addressSameAsPossession(VerticalYesNo.YES) - .correspondenceAddress(correspondenceAddress) - .emailKnown(VerticalYesNo.NO) - .build(); - - ListValue listValue = new ListValue<>("123", details); - - // When - List result = underTest.mapFromDefendantDetails(List.of(listValue)); - - // Then - assertThat(result).hasSize(1); - Defendant mappedDefendant = result.getFirst(); - - assertThat(mappedDefendant.getId()).isEqualTo("123"); - assertThat(mappedDefendant.getNameKnown()).isTrue(); - assertThat(mappedDefendant.getFirstName()).isEqualTo("John"); - assertThat(mappedDefendant.getLastName()).isEqualTo("Doe"); - assertThat(mappedDefendant.getAddressKnown()).isTrue(); - assertThat(mappedDefendant.getAddressSameAsPossession()).isTrue(); - assertThat(mappedDefendant.getCorrespondenceAddress().getAddressLine1()) - .isEqualTo(correspondenceAddress.getAddressLine1()); - assertThat(mappedDefendant.getEmailKnown()).isFalse(); - } - -} diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/page/resumepossessionclaim/DefendantsDetailsTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/page/resumepossessionclaim/DefendantsDetailsTest.java index 9566dbd84..59774056c 100644 --- a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/page/resumepossessionclaim/DefendantsDetailsTest.java +++ b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/page/resumepossessionclaim/DefendantsDetailsTest.java @@ -3,80 +3,132 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import uk.gov.hmcts.ccd.sdk.api.callback.AboutToStartOrSubmitResponse; -import uk.gov.hmcts.ccd.sdk.type.AddressUK; +import uk.gov.hmcts.ccd.sdk.type.ListValue; import uk.gov.hmcts.reform.pcs.ccd.domain.DefendantCircumstances; import uk.gov.hmcts.reform.pcs.ccd.domain.DefendantDetails; 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.page.BasePageTest; -import uk.gov.hmcts.reform.pcs.ccd.service.AddressValidator; +import uk.gov.hmcts.reform.pcs.ccd.service.DefendantValidator; import java.util.List; +import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.params.provider.Arguments.argumentSet; +import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static uk.gov.hmcts.reform.pcs.ccd.util.ListValueUtils.wrapListItems; @ExtendWith(MockitoExtension.class) class DefendantsDetailsTest extends BasePageTest { @Mock - private AddressValidator addressValidator; + private DefendantValidator defendantValidator; @BeforeEach void setUp() { - setPageUnderTest(new DefendantsDetails(addressValidator)); + setPageUnderTest(new DefendantsDetails(defendantValidator)); } @Test - void shouldReturnValidationErrorsWhenAddressInvalid() { + void shouldValidateSingleDefendant() { // Given - AddressUK correspondenceAddress = mock(AddressUK.class); - - DefendantDetails defendantsDetails = DefendantDetails.builder() - .addressSameAsPossession(VerticalYesNo.NO) - .addressKnown(VerticalYesNo.YES) - .correspondenceAddress(correspondenceAddress) - .build(); + DefendantCircumstances defendantCircumstances = mock(DefendantCircumstances.class); + DefendantDetails defendant1 = mock(DefendantDetails.class); PCSCase caseData = PCSCase.builder() - .defendant1(defendantsDetails) + .defendant1(defendant1) + .defendantCircumstances(defendantCircumstances) + .addAnotherDefendant(VerticalYesNo.NO) .build(); List expectedValidationErrors = List.of("error 1", "error 2"); - when(addressValidator.validateAddressFields(correspondenceAddress)).thenReturn(expectedValidationErrors); + when(defendantValidator.validateDefendant1(defendant1, false)) + .thenReturn(expectedValidationErrors); // When AboutToStartOrSubmitResponse response = callMidEventHandler(caseData); // Then assertThat(response.getErrors()).isEqualTo(expectedValidationErrors); - + verify(defendantValidator, never()).validateAdditionalDefendants(anyList()); } @Test - void shouldSetDefendantTermPossessive() { + void shouldValidateMultipleDefendants() { // Given - DefendantCircumstances defendantCircumstances = new DefendantCircumstances(); - String expectedTermPossessive = "defendants'"; - DefendantDetails defendantDetails = DefendantDetails.builder() - .addressSameAsPossession(VerticalYesNo.YES) + DefendantCircumstances defendantCircumstances = mock(DefendantCircumstances.class); + DefendantDetails defendant1 = mock(DefendantDetails.class); + DefendantDetails additionalDefendant1 = mock(DefendantDetails.class); + DefendantDetails additionalDefendant2 = mock(DefendantDetails.class); + + List> additionalDefendants = wrapListItems(List.of( + additionalDefendant1, + additionalDefendant2 + )); + + PCSCase caseData = PCSCase.builder() + .defendant1(defendant1) + .defendantCircumstances(defendantCircumstances) + .addAnotherDefendant(VerticalYesNo.YES) + .additionalDefendants(additionalDefendants) .build(); + String errorMessage1 = "error 1"; + String errorMessage2 = "error 2"; + String errorMessage3 = "error 3"; + + when(defendantValidator.validateDefendant1(defendant1, true)) + .thenReturn(List.of(errorMessage1, errorMessage2)); + + when(defendantValidator.validateAdditionalDefendants(additionalDefendants)) + .thenReturn(List.of(errorMessage3)); + + // When + AboutToStartOrSubmitResponse response = callMidEventHandler(caseData); + + // Then + assertThat(response.getErrors()).containsExactly(errorMessage1, errorMessage2, errorMessage3); + } + + @ParameterizedTest + @MethodSource("defendantTermScenarios") + void shouldSetDefendantTermPossessive(VerticalYesNo additionalDefendants, String expectedTermPossessive) { + // Given + DefendantCircumstances defendantCircumstances = new DefendantCircumstances(); + DefendantDetails defendant1 = mock(DefendantDetails.class); + PCSCase caseData = PCSCase.builder() - .defendant1(defendantDetails) + .defendant1(defendant1) .defendantCircumstances(defendantCircumstances) + .addAnotherDefendant(additionalDefendants) + .additionalDefendants(List.of()) .build(); // When AboutToStartOrSubmitResponse response = callMidEventHandler(caseData); // Then - assertThat(expectedTermPossessive).isEqualTo(response.getData() - .getDefendantCircumstances().getDefendantTermPossessive()); + assertThat(response.getData() + .getDefendantCircumstances().getDefendantTermPossessive()).isEqualTo(expectedTermPossessive); } + + private static Stream defendantTermScenarios() { + return Stream.of( + argumentSet("No additional defendants", VerticalYesNo.NO, "defendant's"), + argumentSet("Additional defendants", VerticalYesNo.YES, "defendants'") + ); + } + } diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/AddressValidatorTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/AddressValidatorTest.java index fa5e8dc11..dfcf01a3e 100644 --- a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/AddressValidatorTest.java +++ b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/AddressValidatorTest.java @@ -55,6 +55,30 @@ void shouldReturnErrorsIfAddressNotValid(String postTown, assertThat(actualValidationErrors).isEqualTo(expectedValidationErrors); } + @ParameterizedTest + @MethodSource("addressScenarios") + void shouldReturnErrorsWithSectionHintIfAddressNotValid(String postTown, + String postcode, + List expectedValidationErrors) { + // Given + String sectionHint = "some section"; + + AddressUK address = AddressUK.builder() + .postTown(postTown) + .postCode(postcode) + .build(); + + // When + List actualValidationErrors = underTest.validateAddressFields(address, sectionHint); + + // Then + assertThat(actualValidationErrors).hasSameSizeAs(expectedValidationErrors); + for (int i = 0; i < actualValidationErrors.size(); i++) { + assertThat(actualValidationErrors.get(i)) + .isEqualTo(expectedValidationErrors.get(i) + " for " + sectionHint); + } + } + private static Stream addressScenarios() { return Stream.of( // Town, postcode, expected validation errors diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/DefendantServiceTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/DefendantServiceTest.java new file mode 100644 index 000000000..d45683bf2 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/DefendantServiceTest.java @@ -0,0 +1,361 @@ +package uk.gov.hmcts.reform.pcs.ccd.service; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.modelmapper.ModelMapper; +import uk.gov.hmcts.ccd.sdk.type.AddressUK; +import uk.gov.hmcts.reform.pcs.ccd.domain.DefendantDetails; +import uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase; +import uk.gov.hmcts.reform.pcs.ccd.domain.VerticalYesNo; +import uk.gov.hmcts.reform.pcs.ccd.model.Defendant; + +import java.util.List; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.catchThrowable; +import static org.junit.jupiter.params.ParameterizedTest.ARGUMENT_SET_NAME_PLACEHOLDER; +import static org.junit.jupiter.params.provider.Arguments.argumentSet; +import static org.mockito.Mock.Strictness.LENIENT; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static uk.gov.hmcts.reform.pcs.ccd.util.ListValueUtils.wrapListItems; + +@ExtendWith(MockitoExtension.class) +class DefendantServiceTest { + + @Mock + private ModelMapper modelMapper; + @Mock(strictness = LENIENT) + private PCSCase pcsCase; + + private DefendantService underTest; + + @BeforeEach + void setUp() { + underTest = new DefendantService(modelMapper); + } + + @Test + void shouldThrowExceptionForNullDefendant1() { + // Given + when(pcsCase.getDefendant1()).thenReturn(null); + + // When + Throwable throwable = catchThrowable(() -> underTest.buildDefendantsList(pcsCase)); + + // Then + assertThat(throwable) + .isInstanceOf(NullPointerException.class) + .hasMessage("Defendant 1 must be provided"); + } + + @ParameterizedTest(name = ARGUMENT_SET_NAME_PLACEHOLDER) + @MethodSource("singleDefendantScenarios") + void shouldBuildListWithSingleDefendant(DefendantDetails defendant1Details, Defendant expectedDefendant) { + // Given + when(pcsCase.getDefendant1()).thenReturn(defendant1Details); + when(pcsCase.getAddAnotherDefendant()).thenReturn(VerticalYesNo.NO); + + // When + List defendantList = underTest.buildDefendantsList(pcsCase); + + // Then + assertThat(defendantList).containsExactly(expectedDefendant); + } + + @Test + void shouldBuildListWithMultipleDefendants() { + // Given + AddressUK defendant1Address = mock(AddressUK.class); + + DefendantDetails defendant1Details = DefendantDetails.builder() + .nameKnown(VerticalYesNo.YES) + .firstName("defendant 1 first name") + .lastName(("defendant 1 last name")) + .addressKnown(VerticalYesNo.YES) + .addressSameAsPossession(VerticalYesNo.NO) + .correspondenceAddress(defendant1Address) + .build(); + + DefendantDetails defendant2Details = DefendantDetails.builder() + .nameKnown(VerticalYesNo.YES) + .firstName("defendant 2 first name") + .lastName(("defendant 2 last name")) + .addressKnown(VerticalYesNo.NO) + .build(); + + DefendantDetails defendant3Details = DefendantDetails.builder() + .nameKnown(VerticalYesNo.NO) + .addressKnown(VerticalYesNo.YES) + .addressSameAsPossession(VerticalYesNo.YES) + .build(); + + when(pcsCase.getDefendant1()).thenReturn(defendant1Details); + + List additionalDefendantsDetails = List.of(defendant2Details, defendant3Details); + when(pcsCase.getAdditionalDefendants()).thenReturn(wrapListItems(additionalDefendantsDetails)); + when(pcsCase.getAddAnotherDefendant()).thenReturn(VerticalYesNo.YES); + + // When + List defendantList = underTest.buildDefendantsList(pcsCase); + + // Then + Defendant expectedDefendant1 = Defendant.builder() + .nameKnown(true) + .firstName("defendant 1 first name") + .lastName("defendant 1 last name") + .addressKnown(true) + .addressSameAsPossession(false) + .correspondenceAddress(defendant1Address) + .build(); + + Defendant expectedDefendant2 = Defendant.builder() + .nameKnown(true) + .firstName("defendant 2 first name") + .lastName("defendant 2 last name") + .addressKnown(false) + .build(); + + Defendant expectedDefendant3 = Defendant.builder() + .nameKnown(false) + .addressKnown(true) + .addressSameAsPossession(true) + .build(); + + assertThat(defendantList).containsExactly(expectedDefendant1, expectedDefendant2, expectedDefendant3); + } + + @Test + void shouldIgnoreMultipleDefendantsIfAdditionalDefendantsNotIndicated() { + // Given + AddressUK defendant1Address = mock(AddressUK.class); + + DefendantDetails defendant1Details = DefendantDetails.builder() + .nameKnown(VerticalYesNo.YES) + .firstName("defendant 1 first name") + .lastName(("defendant 1 last name")) + .addressKnown(VerticalYesNo.YES) + .addressSameAsPossession(VerticalYesNo.NO) + .correspondenceAddress(defendant1Address) + .build(); + + DefendantDetails defendant2Details = DefendantDetails.builder() + .nameKnown(VerticalYesNo.YES) + .firstName("defendant 2 first name") + .lastName(("defendant 2 last name")) + .addressKnown(VerticalYesNo.NO) + .build(); + + when(pcsCase.getDefendant1()).thenReturn(defendant1Details); + when(pcsCase.getAdditionalDefendants()).thenReturn(wrapListItems(List.of(defendant2Details))); + when(pcsCase.getAddAnotherDefendant()).thenReturn(VerticalYesNo.NO); + + // When + List defendantList = underTest.buildDefendantsList(pcsCase); + + // Then + Defendant expectedDefendant1 = Defendant.builder() + .nameKnown(true) + .firstName("defendant 1 first name") + .lastName("defendant 1 last name") + .addressKnown(true) + .addressSameAsPossession(false) + .correspondenceAddress(defendant1Address) + .build(); + + assertThat(defendantList).containsExactly(expectedDefendant1); + } + + @Test + void shouldIgnoreNullAdditionalDefendantsEvenIfAdditionalIndicated() { + // Given + DefendantDetails defendant1Details = DefendantDetails.builder() + .nameKnown(VerticalYesNo.YES) + .firstName("defendant 1 first name") + .lastName(("defendant 1 last name")) + .addressKnown(VerticalYesNo.NO) + .build(); + + when(pcsCase.getDefendant1()).thenReturn(defendant1Details); + + when(pcsCase.getAdditionalDefendants()).thenReturn(null); + when(pcsCase.getAddAnotherDefendant()).thenReturn(VerticalYesNo.YES); + + // When + List defendantList = underTest.buildDefendantsList(pcsCase); + + // Then + Defendant expectedDefendant1 = Defendant.builder() + .nameKnown(true) + .firstName("defendant 1 first name") + .lastName("defendant 1 last name") + .addressKnown(false) + .build(); + + assertThat(defendantList).containsExactly(expectedDefendant1); + } + + @Test + void shouldBlankFieldsIfNotKnownSelected() { + // Given + AddressUK correspondenceAddress = mock(AddressUK.class); + + DefendantDetails defendantDetails = DefendantDetails.builder() + .nameKnown(VerticalYesNo.NO) + .firstName("should be ignored") + .lastName(("should be ignored")) + .addressKnown(VerticalYesNo.NO) + .addressSameAsPossession(VerticalYesNo.NO) + .correspondenceAddress(correspondenceAddress) + .build(); + + DefendantDetails additionalDefendantDetails = DefendantDetails.builder() + .nameKnown(VerticalYesNo.NO) + .firstName("should be ignored") + .lastName(("should be ignored")) + .addressKnown(VerticalYesNo.NO) + .addressSameAsPossession(VerticalYesNo.NO) + .correspondenceAddress(correspondenceAddress) + .build(); + + when(pcsCase.getDefendant1()).thenReturn(defendantDetails); + when(pcsCase.getAdditionalDefendants()).thenReturn(wrapListItems(List.of(additionalDefendantDetails))); + when(pcsCase.getAddAnotherDefendant()).thenReturn(VerticalYesNo.YES); + + // When + List defendantList = underTest.buildDefendantsList(pcsCase); + + // Then + Defendant expectedDefendant1 = Defendant.builder() + .nameKnown(false) + .addressKnown(false) + .build(); + + Defendant expectedDefendant2 = Defendant.builder() + .nameKnown(false) + .addressKnown(false) + .build(); + + assertThat(defendantList).containsExactly(expectedDefendant1, expectedDefendant2); + } + + @Test + void shouldMapFromNullDefendantListToEmptyDefendantDetailsList() { + // When + List actualDefendantDetails = underTest.mapToDefendantDetails(null); + + // Then + assertThat(actualDefendantDetails).isEmpty(); + } + + @Test + void shouldMapFromDefendantListToDefendantDetailsList() { + // Given + Defendant defendant1 = mock(Defendant.class); + Defendant defendant2 = mock(Defendant.class); + + DefendantDetails defendantDetails1 = mock(DefendantDetails.class); + DefendantDetails defendantDetails2 = mock(DefendantDetails.class); + + when(modelMapper.map(defendant1, DefendantDetails.class)).thenReturn(defendantDetails1); + when(modelMapper.map(defendant2, DefendantDetails.class)).thenReturn(defendantDetails2); + + // When + List actualDefendantDetails + = underTest.mapToDefendantDetails(List.of(defendant1, defendant2)); + + // Then + assertThat(actualDefendantDetails).containsExactly(defendantDetails1, defendantDetails2); + } + + private static Stream singleDefendantScenarios() { + AddressUK correspondenceAddress = mock(AddressUK.class); + + return Stream.of( + argumentSet( + "Name and address not known", + + // Case data DefendantDetails + DefendantDetails.builder() + .nameKnown(VerticalYesNo.NO) + .addressKnown(VerticalYesNo.NO) + .build(), + + // Expected Defendant + Defendant.builder() + .nameKnown(false) + .addressKnown(false) + .build() + ), + + argumentSet( + "Name known, address not known", + + // Case data DefendantDetails + DefendantDetails.builder() + .nameKnown(VerticalYesNo.YES) + .firstName("expected first name") + .lastName(("expected last name")) + .addressKnown(VerticalYesNo.NO) + .build(), + + // Expected Defendant + Defendant.builder() + .nameKnown(true) + .firstName("expected first name") + .lastName("expected last name") + .addressKnown(false) + .build() + ), + + argumentSet( + "Name not known, address same as possession", + + // Case data DefendantDetails + DefendantDetails.builder() + .nameKnown(VerticalYesNo.NO) + .addressKnown(VerticalYesNo.YES) + .addressSameAsPossession(VerticalYesNo.YES) + .build(), + + // Expected Defendant + Defendant.builder() + .nameKnown(false) + .addressKnown(true) + .addressSameAsPossession(true) + .build() + ), + + argumentSet( + "Name known, different correspondence address", + + // Case data DefendantDetails + DefendantDetails.builder() + .nameKnown(VerticalYesNo.YES) + .firstName("expected first name") + .lastName(("expected last name")) + .addressKnown(VerticalYesNo.YES) + .addressSameAsPossession(VerticalYesNo.NO) + .correspondenceAddress(correspondenceAddress) + .build(), + + // Expected Defendant + Defendant.builder() + .nameKnown(true) + .firstName("expected first name") + .lastName("expected last name") + .addressKnown(true) + .addressSameAsPossession(false) + .correspondenceAddress(correspondenceAddress) + .build() + ) + ); + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/DefendantValidatorTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/DefendantValidatorTest.java new file mode 100644 index 000000000..c314b59e1 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/DefendantValidatorTest.java @@ -0,0 +1,106 @@ +package uk.gov.hmcts.reform.pcs.ccd.service; + +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.ccd.sdk.type.AddressUK; +import uk.gov.hmcts.ccd.sdk.type.ListValue; +import uk.gov.hmcts.reform.pcs.ccd.domain.DefendantDetails; +import uk.gov.hmcts.reform.pcs.ccd.domain.VerticalYesNo; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static uk.gov.hmcts.reform.pcs.ccd.util.ListValueUtils.wrapListItems; + +@ExtendWith(MockitoExtension.class) +class DefendantValidatorTest { + + @Mock + private AddressValidator addressValidator; + + private DefendantValidator underTest; + + @BeforeEach + void setUp() { + underTest = new DefendantValidator(addressValidator); + } + + @Test + void shouldValidateDefendant1AddressWithNoSectionHintWhenSingleDefendant() { + // Given + AddressUK defendant1Address = mock(AddressUK.class); + DefendantDetails defendant1 = createDefendantWithAddress(defendant1Address); + + List expectedValidationErrors = List.of("error 1", "error 2"); + when(addressValidator.validateAddressFields(defendant1Address, "")) + .thenReturn(expectedValidationErrors); + + // When + List actualValidationErrors = underTest.validateDefendant1(defendant1, false); + + // Then + assertThat(actualValidationErrors).isEqualTo(expectedValidationErrors); + } + + @Test + void shouldValidateDefendant1AddressWithSectionHintWhenMultipleDefendant() { + // Given + AddressUK defendant1Address = mock(AddressUK.class); + DefendantDetails defendant1 = createDefendantWithAddress(defendant1Address); + + List expectedValidationErrors = List.of("error 1", "error 2"); + when(addressValidator.validateAddressFields(defendant1Address, "defendant 1")) + .thenReturn(expectedValidationErrors); + + // When + List actualValidationErrors = underTest.validateDefendant1(defendant1, true); + + // Then + assertThat(actualValidationErrors).isEqualTo(expectedValidationErrors); + } + + @Test + void shouldValidateAdditionalDefendantAddressesWithSectionHints() { + // Given + AddressUK additionalDefendant1Address = mock(AddressUK.class); + DefendantDetails additionalDefendant1 = createDefendantWithAddress(additionalDefendant1Address); + + AddressUK additionalDefendant2Address = mock(AddressUK.class); + DefendantDetails additionalDefendant2 = createDefendantWithAddress(additionalDefendant2Address); + + List> additionalDefendants = wrapListItems(List.of( + additionalDefendant1, + additionalDefendant2 + )); + + String errorMessage1 = "error 1"; + String errorMessage2 = "error 2"; + String errorMessage3 = "error 3"; + + when(addressValidator.validateAddressFields(additionalDefendant1Address, "additional defendant 1")) + .thenReturn(List.of(errorMessage1)); + + when(addressValidator.validateAddressFields(additionalDefendant2Address, "additional defendant 2")) + .thenReturn(List.of(errorMessage2, errorMessage3)); + + // When + List actualValidationErrors = underTest.validateAdditionalDefendants(additionalDefendants); + + // Then + assertThat(actualValidationErrors).containsExactly(errorMessage1, errorMessage2, errorMessage3); + } + + private static DefendantDetails createDefendantWithAddress(AddressUK address) { + return DefendantDetails.builder() + .addressKnown(VerticalYesNo.YES) + .addressSameAsPossession(VerticalYesNo.NO) + .correspondenceAddress(address) + .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 1f110890a..b414f67a3 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 @@ -9,22 +9,23 @@ import uk.gov.hmcts.ccd.sdk.type.AddressUK; import uk.gov.hmcts.reform.idam.client.models.UserInfo; import uk.gov.hmcts.reform.pcs.ccd.domain.ClaimantType; +import uk.gov.hmcts.reform.pcs.ccd.domain.DefendantDetails; +import uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase; +import uk.gov.hmcts.reform.pcs.ccd.domain.VerticalYesNo; import uk.gov.hmcts.reform.pcs.ccd.domain.wales.DiscretionaryGroundWales; import uk.gov.hmcts.reform.pcs.ccd.domain.wales.EstateManagementGroundsWales; import uk.gov.hmcts.reform.pcs.ccd.domain.wales.MandatoryGroundWales; -import uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase; import uk.gov.hmcts.reform.pcs.ccd.domain.wales.SecureContractDiscretionaryGroundsWales; import uk.gov.hmcts.reform.pcs.ccd.domain.wales.SecureContractMandatoryGroundsWales; -import uk.gov.hmcts.reform.pcs.ccd.domain.VerticalYesNo; import uk.gov.hmcts.reform.pcs.ccd.entity.AddressEntity; import uk.gov.hmcts.reform.pcs.ccd.entity.PartyEntity; import uk.gov.hmcts.reform.pcs.ccd.entity.PcsCaseEntity; -import uk.gov.hmcts.reform.pcs.ccd.mapper.DefendantMapper; +import uk.gov.hmcts.reform.pcs.ccd.model.Defendant; import uk.gov.hmcts.reform.pcs.ccd.type.DynamicStringList; import uk.gov.hmcts.reform.pcs.ccd.type.DynamicStringListElement; -import uk.gov.hmcts.reform.pcs.config.MapperConfig; import uk.gov.hmcts.reform.pcs.security.SecurityContextService; +import java.util.List; import java.util.Set; import java.util.UUID; @@ -32,7 +33,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -46,16 +46,16 @@ class PcsCaseMergeServiceTest { @Mock private TenancyLicenceService tenancyLicenceService; @Mock - private DefendantMapper defendantMapper; + private DefendantService defendantService; private PcsCaseMergeService underTest; @BeforeEach void setUp() { - MapperConfig config = new MapperConfig(); - modelMapper = spy(config.modelMapper()); - underTest = new PcsCaseMergeService(securityContextService, modelMapper, tenancyLicenceService, - defendantMapper); + underTest = new PcsCaseMergeService(securityContextService, + modelMapper, + tenancyLicenceService, + defendantService); } @Test @@ -92,6 +92,23 @@ void shouldChangeFieldsWhenPatchingCase() { verify(pcsCaseEntity).setPropertyAddress(updatedAddressEntity); } + @Test + void shouldUpdateDefendantsWhenDefendant1NotNull() { + // Given + List expectedDefendants = List.of(mock(Defendant.class), mock(Defendant.class)); + PCSCase pcsCase = mock(PCSCase.class); + PcsCaseEntity pcsCaseEntity = mock(PcsCaseEntity.class); + + when(pcsCase.getDefendant1()).thenReturn(mock(DefendantDetails.class)); + when(defendantService.buildDefendantsList(pcsCase)).thenReturn(expectedDefendants); + + // When + underTest.mergeCaseData(pcsCaseEntity, pcsCase); + + // Then + verify(pcsCaseEntity).setDefendants(expectedDefendants); + } + @Test void shouldCreatePartyWithPcqIdForCurrentUser() { PCSCase pcsCase = mock(PCSCase.class); diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/PcsCaseServiceTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/PcsCaseServiceTest.java index 2ef6e02ce..0a7f49c7b 100644 --- a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/PcsCaseServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/PcsCaseServiceTest.java @@ -13,14 +13,11 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.modelmapper.ModelMapper; import uk.gov.hmcts.ccd.sdk.type.AddressUK; -import uk.gov.hmcts.ccd.sdk.type.ListValue; import uk.gov.hmcts.reform.pcs.ccd.domain.ClaimantType; -import uk.gov.hmcts.reform.pcs.ccd.domain.DefendantDetails; import uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase; import uk.gov.hmcts.reform.pcs.ccd.domain.VerticalYesNo; import uk.gov.hmcts.reform.pcs.ccd.entity.AddressEntity; import uk.gov.hmcts.reform.pcs.ccd.entity.PcsCaseEntity; -import uk.gov.hmcts.reform.pcs.ccd.model.Defendant; import uk.gov.hmcts.reform.pcs.ccd.repository.PcsCaseRepository; import uk.gov.hmcts.reform.pcs.ccd.type.DynamicStringList; import uk.gov.hmcts.reform.pcs.ccd.type.DynamicStringListElement; @@ -28,7 +25,6 @@ import uk.gov.hmcts.reform.pcs.exception.CaseNotFoundException; import uk.gov.hmcts.reform.pcs.postcodecourt.model.LegislativeCountry; -import java.util.List; import java.util.Optional; import java.util.stream.Stream; @@ -220,38 +216,6 @@ void shouldSaveCaseToRepository() { verify(pcsCaseRepository).save(pcsCaseEntity); } - @Test - void shouldMapDefendantPojoToDefendantDetails() { - // Given - Defendant defendant = Defendant.builder() - .id("456") - .nameKnown(true) - .firstName("Jane") - .lastName("Smith") - .addressKnown(false) - .addressSameAsPossession(false) - .emailKnown(true) - .email("jane.smith@email.com") - .build(); - - // When - List> result = underTest.mapToDefendantDetails(List.of(defendant)); - - // Then - ListValue listValue = result.getFirst(); - DefendantDetails mappedDefendantDetails = listValue.getValue(); - - assertThat(result).hasSize(1); - assertThat(listValue.getId()).isEqualTo("456"); - assertThat(mappedDefendantDetails.getNameKnown()).isEqualTo(VerticalYesNo.YES); - assertThat(mappedDefendantDetails.getFirstName()).isEqualTo("Jane"); - assertThat(mappedDefendantDetails.getLastName()).isEqualTo("Smith"); - assertThat(mappedDefendantDetails.getAddressKnown()).isEqualTo(VerticalYesNo.NO); - assertThat(mappedDefendantDetails.getAddressSameAsPossession()).isEqualTo(VerticalYesNo.NO); - assertThat(mappedDefendantDetails.getEmailKnown()).isEqualTo(VerticalYesNo.YES); - assertThat(mappedDefendantDetails.getEmail()).isEqualTo("jane.smith@email.com"); - } - private AddressEntity stubAddressUKModelMapper(AddressUK addressUK) { AddressEntity addressEntity = mock(AddressEntity.class); when(modelMapper.map(addressUK, AddressEntity.class)).thenReturn(addressEntity); @@ -263,7 +227,6 @@ void shouldPersistClaimantTypeWhenCreatingCase() { // Given PCSCase pcsCase = mock(PCSCase.class); AddressUK propertyAddress = mock(AddressUK.class); - stubAddressUKModelMapper(propertyAddress); DynamicStringList claimantTypeList = DynamicStringList.builder() .value(DynamicStringListElement.builder() @@ -290,7 +253,6 @@ void shouldSkipClaimantTypeWhenNull() { // Given PCSCase pcsCase = mock(PCSCase.class); AddressUK propertyAddress = mock(AddressUK.class); - stubAddressUKModelMapper(propertyAddress); when(pcsCase.getPropertyAddress()).thenReturn(propertyAddress); when(pcsCase.getClaimantType()).thenReturn(null); @@ -310,7 +272,6 @@ void shouldSkipClaimantTypeWhenValueCodeIsNull() { // Given PCSCase pcsCase = mock(PCSCase.class); AddressUK propertyAddress = mock(AddressUK.class); - stubAddressUKModelMapper(propertyAddress); DynamicStringList claimantTypeList = mock(DynamicStringList.class); when(claimantTypeList.getValueCode()).thenReturn(null); @@ -333,7 +294,6 @@ void shouldPersistAllClaimantTypes(ClaimantType claimantType) { // Given PCSCase pcsCase = mock(PCSCase.class); AddressUK propertyAddress = mock(AddressUK.class); - stubAddressUKModelMapper(propertyAddress); DynamicStringList claimantTypeList = DynamicStringList.builder() .value(DynamicStringListElement.builder()