diff --git a/pom.xml b/pom.xml index 3b75ce498..acee55247 100644 --- a/pom.xml +++ b/pom.xml @@ -66,16 +66,16 @@ 17.0.75 1.0.6 6.4.1 - 17.104.136 + 17.103.133 17.103.162 17.104.173 17.104.48 - 17.0.85 + 17.104.101 17.103.42 17.103.13 8.0.30 6.13 - 17.103.105 + 17.104.110 17.104.44 17.0.26 17.0.64 diff --git a/progression-command/progression-command-handler/src/main/java/uk/gov/moj/cpp/progression/handler/CourtApplicationHandler.java b/progression-command/progression-command-handler/src/main/java/uk/gov/moj/cpp/progression/handler/CourtApplicationHandler.java index cc91232a7..526898736 100644 --- a/progression-command/progression-command-handler/src/main/java/uk/gov/moj/cpp/progression/handler/CourtApplicationHandler.java +++ b/progression-command/progression-command-handler/src/main/java/uk/gov/moj/cpp/progression/handler/CourtApplicationHandler.java @@ -7,7 +7,6 @@ import static java.util.UUID.randomUUID; import static java.util.stream.Collectors.collectingAndThen; import static java.util.stream.Collectors.toList; -import static org.apache.commons.collections.CollectionUtils.isEmpty; import static org.apache.commons.collections.CollectionUtils.isNotEmpty; import static org.apache.commons.lang3.StringUtils.isBlank; import static uk.gov.justice.core.courts.ContactNumber.contactNumber; @@ -74,7 +73,6 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; -import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.UUID; diff --git a/progression-command/progression-command-handler/src/main/java/uk/gov/moj/cpp/progression/handler/UpdateFinancialMeansDataHandler.java b/progression-command/progression-command-handler/src/main/java/uk/gov/moj/cpp/progression/handler/UpdateFinancialMeansDataHandler.java index aa2fea385..9f208518d 100644 --- a/progression-command/progression-command-handler/src/main/java/uk/gov/moj/cpp/progression/handler/UpdateFinancialMeansDataHandler.java +++ b/progression-command/progression-command-handler/src/main/java/uk/gov/moj/cpp/progression/handler/UpdateFinancialMeansDataHandler.java @@ -14,6 +14,7 @@ import uk.gov.justice.services.eventsourcing.source.core.EventStream; import uk.gov.justice.services.eventsourcing.source.core.exception.EventStreamException; import uk.gov.justice.services.messaging.Envelope; +import uk.gov.moj.cpp.progression.aggregate.ApplicationAggregate; import uk.gov.moj.cpp.progression.aggregate.CaseAggregate; import java.util.List; @@ -77,13 +78,18 @@ private boolean isDefendantsFinancialData(final CourtDocument courtDocument) { private void updateEventStream(final UUID prosecutionCaseId, final UUID defendantId, final UUID applicationId, final List materials, - final Envelope createCourtDocumentEnvelope) - throws EventStreamException { - - final EventStream eventStream = eventSource.getStreamById(prosecutionCaseId); - final CaseAggregate caseAggregate = aggregateService.get(eventStream, CaseAggregate.class); - final Stream events = caseAggregate.addFinancialMeansData(prosecutionCaseId, defendantId, applicationId, materials.get(0)); - eventStream.append(events.map(Enveloper.toEnvelopeWithMetadataFrom(createCourtDocumentEnvelope))); + final Envelope createCourtDocumentEnvelope) throws EventStreamException { + if (prosecutionCaseId != null) { + final EventStream eventStream = eventSource.getStreamById(prosecutionCaseId); + final CaseAggregate caseAggregate = aggregateService.get(eventStream, CaseAggregate.class); + final Stream events = caseAggregate.addFinancialMeansData(prosecutionCaseId, defendantId, applicationId, materials.get(0)); + eventStream.append(events.map(Enveloper.toEnvelopeWithMetadataFrom(createCourtDocumentEnvelope))); + } else if (prosecutionCaseId == null && applicationId != null) { + final EventStream eventStream = eventSource.getStreamById(applicationId); + final ApplicationAggregate applicationAggregate = aggregateService.get(eventStream, ApplicationAggregate.class); + final Stream events = applicationAggregate.addFinancialMeansData(prosecutionCaseId, defendantId, applicationId, materials.get(0)); + eventStream.append(events.map(Enveloper.toEnvelopeWithMetadataFrom(createCourtDocumentEnvelope))); + } } } diff --git a/progression-command/progression-command-handler/src/test/java/uk/gov/moj/cpp/progression/handler/CourtApplicationHandlerTest.java b/progression-command/progression-command-handler/src/test/java/uk/gov/moj/cpp/progression/handler/CourtApplicationHandlerTest.java index 8e505ce7c..3cc975cc0 100644 --- a/progression-command/progression-command-handler/src/test/java/uk/gov/moj/cpp/progression/handler/CourtApplicationHandlerTest.java +++ b/progression-command/progression-command-handler/src/test/java/uk/gov/moj/cpp/progression/handler/CourtApplicationHandlerTest.java @@ -3152,4 +3152,48 @@ public static Offence buildOffence(final UUID offenceId, final LocalDate convict .withConvictionDate(convictionDate) .build(); } + + @Test + public void shouldUpdateOffenceWordingForActiveCaseWhenNoCourtOrder() throws EventStreamException { + final InitiateCourtApplicationProceedings initiateCourtApplicationProceedings = + buildInitiateCourtApplicationProceedings(randomUUID(), false, true, false, true, LinkType.LINKED, "ACTIVE"); + + final Metadata metadata = Envelope + .metadataBuilder() + .withName("progression.command.initiate-court-proceedings-for-application") + .withId(randomUUID()) + .build(); + final Envelope envelope = envelopeFrom(metadata, initiateCourtApplicationProceedings); + + final ApplicationAggregate applicationAggregate = new ApplicationAggregate(); + when(eventSource.getStreamById(any())).thenReturn(eventStream); + when(aggregateService.get(eventStream, ApplicationAggregate.class)).thenReturn(applicationAggregate); + applicationAggregate.apply(new CourtApplicationProceedingsInitiated.Builder() + .withCourtHearing(new CourtHearingRequest.Builder().build()) + .withBoxHearing(new BoxHearingRequest.Builder().build()) + .build()); + + courtApplicationHandler.initiateCourtApplicationProceedings(envelope); + + final Stream envelopeStream = verifyAppendAndGetArgumentFrom(eventStream); + + final String expectedWording = "Resentenced Original code : " + ORG_OFFENCE_CODE + ", Original details: " + ORG_OFFENCE_WORDING; + final String expectedWordingWelsh = "Resentenced Original code : " + ORG_OFFENCE_CODE + ", Original details: " + ORG_OFFENCE_WORDING_WELSH; + final UUID activeOffenceId = initiateCourtApplicationProceedings.getCourtApplication().getCourtApplicationCases().get(0).getOffences().get(0).getId(); + final UUID activeProsecutionCaseId = initiateCourtApplicationProceedings.getCourtApplication().getCourtApplicationCases().get(0).getProsecutionCaseId(); + + assertThat(envelopeStream, streamContaining( + jsonEnvelope( + metadata() + .withName("progression.event.court-application-proceedings-initiated"), + payload().isJson(allOf( + withJsonPath("$.courtApplication.courtApplicationCases[0].prosecutionCaseId", is(activeProsecutionCaseId.toString())), + withJsonPath("$.courtApplication.courtApplicationCases[0].offences[0].id", is(activeOffenceId.toString())), + withJsonPath("$.courtApplication.courtApplicationCases[0].offences[0].offenceCode", is(RESENTENCING_ACTIVATION_CODE)), + withJsonPath("$.courtApplication.courtApplicationCases[0].offences[0].wording", is(expectedWording)), + withJsonPath("$.courtApplication.courtApplicationCases[0].offences[0].wordingWelsh", is(expectedWordingWelsh)) + )) + ) + )); + } } diff --git a/progression-command/progression-command-handler/src/test/java/uk/gov/moj/cpp/progression/handler/UpdateFinancialMeansDataHandlerTest.java b/progression-command/progression-command-handler/src/test/java/uk/gov/moj/cpp/progression/handler/UpdateFinancialMeansDataHandlerTest.java index cdb310163..301ff79b9 100644 --- a/progression-command/progression-command-handler/src/test/java/uk/gov/moj/cpp/progression/handler/UpdateFinancialMeansDataHandlerTest.java +++ b/progression-command/progression-command-handler/src/test/java/uk/gov/moj/cpp/progression/handler/UpdateFinancialMeansDataHandlerTest.java @@ -24,6 +24,7 @@ import uk.gov.justice.services.messaging.Envelope; import uk.gov.justice.services.messaging.Metadata; import uk.gov.justice.services.test.utils.core.enveloper.EnveloperFactory; +import uk.gov.moj.cpp.progression.aggregate.ApplicationAggregate; import uk.gov.moj.cpp.progression.aggregate.CaseAggregate; import java.util.ArrayList; @@ -122,7 +123,45 @@ public void shouldProcessCommand_ApplicationDocument() throws Exception { .withContainsFinancialMeans(true) .withMaterials(materials) .withDocumentCategory(DocumentCategory.documentCategory() - .withApplicationDocument(ApplicationDocument.applicationDocument().withApplicationId(randomUUID()).build()) + .withApplicationDocument(ApplicationDocument.applicationDocument().withProsecutionCaseId(randomUUID()).withApplicationId(randomUUID()).build()) + .build() + ).build(); + + final CreateCourtDocument createCourtDocument = CreateCourtDocument.createCourtDocument() + .withCourtDocument(courtDocument) + .build(); + + final Metadata metadata = Envelope + .metadataBuilder() + .withName("progression.command.update-financial-means-data") + .withId(randomUUID()) + .build(); + + final Envelope envelope = envelopeFrom(metadata, createCourtDocument); + + final CaseAggregate caseAggregate = new CaseAggregate(); + when(eventSource.getStreamById(any())).thenReturn(eventStream); + when(aggregateService.get(eventStream, CaseAggregate.class)).thenReturn(caseAggregate); + + updateFinancialMeansDataHandler.handle(envelope); + + verifyAppendAndGetArgumentFrom(eventStream); + } + + @Test + public void shouldProcessCommand_ApplicationDocumentOnlyCaseId() throws Exception { + List defendantlist = new ArrayList<>(); + defendantlist.add(DEFENDANT_ID); + + List materials = new ArrayList<>(); + Material material = Material.material().withId(MATERIAL_ID).withName("MC100").build(); + materials.add(material); + + final CourtDocument courtDocument = CourtDocument.courtDocument() + .withContainsFinancialMeans(true) + .withMaterials(materials) + .withDocumentCategory(DocumentCategory.documentCategory() + .withApplicationDocument(ApplicationDocument.applicationDocument().withProsecutionCaseId(randomUUID()).build()) .build() ).build(); @@ -146,4 +185,44 @@ public void shouldProcessCommand_ApplicationDocument() throws Exception { verifyAppendAndGetArgumentFrom(eventStream); } + + + @Test + public void shouldProcessCommand_ApplicationDocumentWithOnlyApplicationIdPresent() throws Exception { + List defendantlist = new ArrayList<>(); + defendantlist.add(DEFENDANT_ID); + + List materials = new ArrayList<>(); + Material material = Material.material().withId(MATERIAL_ID).withName("MC100").build(); + materials.add(material); + + final CourtDocument courtDocument = CourtDocument.courtDocument() + .withContainsFinancialMeans(true) + .withMaterials(materials) + .withDocumentCategory(DocumentCategory.documentCategory() + .withApplicationDocument(ApplicationDocument.applicationDocument().withApplicationId(randomUUID()).build()) + .build() + ).build(); + + final CreateCourtDocument createCourtDocument = CreateCourtDocument.createCourtDocument() + .withCourtDocument(courtDocument) + .build(); + + final Metadata metadata = Envelope + .metadataBuilder() + .withName("progression.command.update-financial-means-data") + .withId(randomUUID()) + .build(); + + final Envelope envelope = envelopeFrom(metadata, createCourtDocument); + + final ApplicationAggregate applicationAggregate = new ApplicationAggregate(); + + when(eventSource.getStreamById(any())).thenReturn(eventStream); + when(aggregateService.get(eventStream, ApplicationAggregate.class)).thenReturn(applicationAggregate); + + updateFinancialMeansDataHandler.handle(envelope); + + verifyAppendAndGetArgumentFrom(eventStream); + } } diff --git a/progression-domain/progression-domain-aggregate/src/main/java/uk/gov/moj/cpp/progression/aggregate/ApplicationAggregate.java b/progression-domain/progression-domain-aggregate/src/main/java/uk/gov/moj/cpp/progression/aggregate/ApplicationAggregate.java index 18dc59484..46eb52aa5 100644 --- a/progression-domain/progression-domain-aggregate/src/main/java/uk/gov/moj/cpp/progression/aggregate/ApplicationAggregate.java +++ b/progression-domain/progression-domain-aggregate/src/main/java/uk/gov/moj/cpp/progression/aggregate/ApplicationAggregate.java @@ -114,6 +114,8 @@ import uk.gov.justice.core.courts.SlotsBookedForApplication; import uk.gov.justice.core.courts.SummonsApprovedOutcome; import uk.gov.justice.core.courts.SummonsRejectedOutcome; +import uk.gov.justice.core.courts.FinancialDataAdded; +import uk.gov.justice.core.courts.Material; import uk.gov.justice.domain.aggregate.Aggregate; import uk.gov.justice.progression.courts.HearingDeletedForCourtApplication; import uk.gov.moj.cpp.progression.application.ApplicationCaseDefendantOrganisation; @@ -154,7 +156,7 @@ public class ApplicationAggregate implements Aggregate { private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationAggregate.class); - private static final long serialVersionUID = 1331113876243908502L; + private static final long serialVersionUID = 1331113876243908503L; private static final String APPEARANCE_TO_MAKE_STATUTORY_DECLARATION_CODE = "MC80527"; private static final String APPEARANCE_TO_MAKE_STATUTORY_DECLARATION_CODE_SJP = "MC80528"; private static final SecureRandom SECURE_RANDOM = new SecureRandom(); @@ -168,6 +170,7 @@ public class ApplicationAggregate implements Aggregate { private final Map offenceLaaReference = new HashMap<>(); private LaaReference laaReference;//cloned by child applications. This has to be overridden each time LaaReference updated for application or any offence. private final Map applicationOrganisationAsscociatedByRepOrder = new HashMap<>(); + private final Map> applicationFinancialDocs = new HashMap<>(); @Override public Object apply(final Object event) { @@ -251,6 +254,7 @@ public Object apply(final Object event) { .build(); } }), + when(FinancialDataAdded.class).apply(this::populateFinancialData), otherwiseDoNothing()); } @@ -1556,4 +1560,22 @@ private void setLaaReference(final LaaReference laaReference) { this.laaReference = laaReference; } + public Stream addFinancialMeansData(final UUID prosecutionCaseId, final UUID defendantId, final UUID applicationId, final Material material) { + final List materialIds = new ArrayList<>(); + materialIds.add(material.getId()); + return apply(Stream.of(FinancialDataAdded.financialDataAdded() + .withCaseId(prosecutionCaseId) + .withApplicationId(applicationId) + .withDefendantId(defendantId) + .withMaterialIds(materialIds) + .build()) + ); + } + + private void populateFinancialData(final FinancialDataAdded financialDataAdded) { + if (financialDataAdded.getApplicationId() != null) { + this.applicationFinancialDocs.put(financialDataAdded.getApplicationId(), financialDataAdded.getMaterialIds()); + } + } + } \ No newline at end of file diff --git a/progression-domain/progression-domain-aggregate/src/test/java/uk/gov/moj/cpp/progression/aggregate/ApplicationAggregateTest.java b/progression-domain/progression-domain-aggregate/src/test/java/uk/gov/moj/cpp/progression/aggregate/ApplicationAggregateTest.java index c780ac425..bbba8923b 100644 --- a/progression-domain/progression-domain-aggregate/src/test/java/uk/gov/moj/cpp/progression/aggregate/ApplicationAggregateTest.java +++ b/progression-domain/progression-domain-aggregate/src/test/java/uk/gov/moj/cpp/progression/aggregate/ApplicationAggregateTest.java @@ -86,6 +86,12 @@ import uk.gov.justice.core.courts.SendNotificationForAutoApplicationInitiated; import uk.gov.justice.core.courts.SlotsBookedForApplication; import uk.gov.justice.core.courts.SummonsRejectedOutcome; +import uk.gov.justice.core.courts.FinancialDataAdded; +import uk.gov.justice.core.courts.Material; +import uk.gov.justice.core.courts.CourtDocument; +import uk.gov.justice.core.courts.DocumentCategory; +import uk.gov.justice.core.courts.DefendantDocument; +import uk.gov.justice.core.courts.ApplicationDocument; import uk.gov.justice.progression.courts.HearingDeletedForCourtApplication; import uk.gov.justice.progression.courts.SendStatdecAppointmentLetter; import uk.gov.justice.services.common.converter.JsonObjectToObjectConverter; @@ -1979,4 +1985,41 @@ void shouldUpdateApplicationLaaReferenceWhenCourtApplicationExistsAndAnyInputCha assertThat(hearingApplicationLaaReferenceUpdateReceived.getApplicationId(), is(applicationId)); } + + @Test + public void shouldReturnFinancialDataAddedEventWhenApplicationUploadsMC100Form() { + + final CourtDocument courtDocument = getCourtDocumentWithApplicationDocumentCategory(); + final List eventStream = aggregate.addFinancialMeansData(courtDocument.getDocumentCategory().getApplicationDocument().getProsecutionCaseId(), + null, courtDocument.getDocumentCategory().getApplicationDocument().getApplicationId(), courtDocument.getMaterials().get(0)).collect(toList()); + + assertThat(eventStream.size(), is(1)); + final Object object = eventStream.get(0); + assertThat(object.getClass(), is(CoreMatchers.>equalTo(FinancialDataAdded.class))); + } + + private CourtDocument getCourtDocumentWithApplicationDocumentCategory() { + UUID caseId = UUID.fromString("5002d600-af66-11e8-b568-0800200c9a77"); + UUID applicationId = UUID.fromString("5002d600-af66-11e8-b568-0800200c9a88"); + UUID materialId = UUID.fromString("5002d600-af66-11e8-b568-0800200c9a99"); + + List defendantlist = new ArrayList<>(); + defendantlist.add(applicationId); + List materials = new ArrayList<>(); + Material material = Material.material().withId(materialId).withName("MC100").build(); + materials.add(material); + + + final CourtDocument courtDocument = CourtDocument.courtDocument() + .withContainsFinancialMeans(true) + .withMaterials(materials) + .withDocumentCategory(DocumentCategory.documentCategory() + .withApplicationDocument(ApplicationDocument.applicationDocument().withApplicationId(applicationId).withProsecutionCaseId(caseId).build()) + .withDefendantDocument(DefendantDocument.defendantDocument().withDefendants(defendantlist).withProsecutionCaseId(caseId).build()) + .build() + ).build(); + + return courtDocument; + } + } diff --git a/progression-event/progression-event-processor/src/main/java/uk/gov/moj/cpp/progression/processor/CourtApplicationProcessor.java b/progression-event/progression-event-processor/src/main/java/uk/gov/moj/cpp/progression/processor/CourtApplicationProcessor.java index 1b5f63dcd..accf39499 100644 --- a/progression-event/progression-event-processor/src/main/java/uk/gov/moj/cpp/progression/processor/CourtApplicationProcessor.java +++ b/progression-event/progression-event-processor/src/main/java/uk/gov/moj/cpp/progression/processor/CourtApplicationProcessor.java @@ -2,6 +2,7 @@ import static java.time.format.DateTimeFormatter.ofPattern; +import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static java.util.Objects.isNull; @@ -85,6 +86,7 @@ import uk.gov.justice.services.core.sender.Sender; import uk.gov.justice.services.messaging.JsonEnvelope; import uk.gov.moj.cpp.progression.command.UpdateCpsDefendantId; +import uk.gov.moj.cpp.progression.domain.constant.CaseStatusEnum; import uk.gov.moj.cpp.progression.processor.exceptions.CaseNotFoundException; import uk.gov.moj.cpp.progression.processor.summons.SummonsHearingRequestService; import uk.gov.moj.cpp.progression.processor.summons.SummonsRejectedService; @@ -98,7 +100,6 @@ import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -240,7 +241,7 @@ public void processRemoveDefendantCustodialEstablishmentRequested(final JsonEnve LOGGER.info("CourtApplication {}", courtApplication.getId()); } - if(isNotEmpty(courtApplication.getCourtApplicationCases())){ + if (isNotEmpty(courtApplication.getCourtApplicationCases())) { courtApplication.getCourtApplicationCases() .stream() .filter(courtApplicationCase -> INACTIVE.equals(courtApplicationCase.getCaseStatus())) @@ -327,13 +328,13 @@ public void processCourtApplicationInitiated(final JsonEnvelope event) { })); } else if (nonNull(courtApplicationProceedingsInitiated.getCourtApplication()) && nonNull(courtApplicationProceedingsInitiated.getCourtApplication().getCourtOrder())) { courtApplicationProceedingsInitiated.getCourtApplication().getCourtOrder().getCourtOrderOffences().stream().map(CourtOrderOffence::getProsecutionCaseId).collect(Collectors.toSet()) - .forEach(prosecutionCaseId -> - progressionService.getProsecutionCase(event, prosecutionCaseId.toString()).ifPresent(pc -> { - final ProsecutionCase prosecutionCase = jsonObjectToObjectConverter.convert(pc.getJsonObject("prosecutionCase"), ProsecutionCase.class); - updateDefendantAddressOnCase(event, courtApplicationProceedingsInitiated.getCourtApplication(), prosecutionCaseId.toString(), prosecutionCase.getDefendants()); - final ProsecutionCase enrichedCase = enrichProsecutionCaseWithAddressFromApplication(prosecutionCase, courtApplicationProceedingsInitiated.getCourtApplication()); - prosecutionCases.add(enrichedCase); - })); + .forEach(prosecutionCaseId -> + progressionService.getProsecutionCase(event, prosecutionCaseId.toString()).ifPresent(pc -> { + final ProsecutionCase prosecutionCase = jsonObjectToObjectConverter.convert(pc.getJsonObject("prosecutionCase"), ProsecutionCase.class); + updateDefendantAddressOnCase(event, courtApplicationProceedingsInitiated.getCourtApplication(), prosecutionCaseId.toString(), prosecutionCase.getDefendants()); + final ProsecutionCase enrichedCase = enrichProsecutionCaseWithAddressFromApplication(prosecutionCase, courtApplicationProceedingsInitiated.getCourtApplication()); + prosecutionCases.add(enrichedCase); + })); } final JsonArrayBuilder prosecutionsWithCaseArray = createArrayBuilder(); prosecutionCases.forEach(prosecutionCase -> prosecutionsWithCaseArray.add(objectToJsonObjectConverter.convert(prosecutionCase))); @@ -414,9 +415,9 @@ private void updateDefendantAddressOnCase(final JsonEnvelope event, final CourtA private static DefendantUpdate enrichDefendantUpdateWithDefendantId(final List defendants, DefendantUpdate defendantUpdate) { final Optional defendantId = getMatchingDefendantIdFromDefendantList(defendants, defendantUpdate); - if(defendantId.isPresent()){ + if (defendantId.isPresent()) { defendantUpdate = DefendantUpdate.defendantUpdate().withValuesFrom(defendantUpdate).withId(defendantId.get()).build(); - }else{ + } else { defendantUpdate = DefendantUpdate.defendantUpdate().withValuesFrom(defendantUpdate).withId(defendantUpdate.getMasterDefendantId()).build(); } return defendantUpdate; @@ -507,8 +508,8 @@ public void processCourtApplicationEdited(final JsonEnvelope event) { courtApplicationProceedingsEdited.getCourtApplication().getCourtOrder().getCourtOrderOffences().stream().map(CourtOrderOffence::getProsecutionCaseId).collect(Collectors.toSet()) .forEach(prosecutionCaseId -> progressionService.getProsecutionCase(event, prosecutionCaseId.toString()).ifPresent(pc -> { - final ProsecutionCase prosecutionCase = jsonObjectToObjectConverter.convert(pc.getJsonObject("prosecutionCase"), ProsecutionCase.class); - updateDefendantAddressOnCase(event, courtApplicationProceedingsEdited.getCourtApplication(), prosecutionCaseId.toString(), prosecutionCase.getDefendants()); + final ProsecutionCase prosecutionCase = jsonObjectToObjectConverter.convert(pc.getJsonObject("prosecutionCase"), ProsecutionCase.class); + updateDefendantAddressOnCase(event, courtApplicationProceedingsEdited.getCourtApplication(), prosecutionCaseId.toString(), prosecutionCase.getDefendants()); })); } sender.send(envelopeFrom(metadataFrom(event.metadata()).withName(PUBLIC_PROGRESSION_EVENTS_HEARING_EXTENDED), publicPayload.build())); @@ -833,7 +834,6 @@ public void processBreachApplicationCreationRequested(final JsonEnvelope event) .build(); final BreachedApplications breachedApplication = breachApplicationCreationRequested.getBreachedApplications(); - final List offences = nonNull(defendant.get().getOffences()) ? defendant.get().getOffences().stream().collect(toList()) : null; final CourtApplication courtApplication = CourtApplication.courtApplication() .withId(breachedApplication.getId()) @@ -844,11 +844,11 @@ public void processBreachApplicationCreationRequested(final JsonEnvelope event) .withApplicant(applicant) .withSubject(respondent) .withRespondents(singletonList(respondent)) - .withCourtApplicationCases(Arrays.asList(CourtApplicationCase.courtApplicationCase() + .withCourtApplicationCases(asList(CourtApplicationCase.courtApplicationCase() .withIsSJP(Boolean.FALSE) .withProsecutionCaseId(prosecutionCase.getId()) - .withOffences(offences) - .withCaseStatus("ACTIVE") + .withOffences(null) + .withCaseStatus(CaseStatusEnum.ACTIVE.getDescription()) .withProsecutionCaseIdentifier(prosecutionCase.getProsecutionCaseIdentifier()) .build())) .build(); @@ -871,7 +871,6 @@ public void processBreachApplicationCreationRequested(final JsonEnvelope event) } } - private List getProsecutionCases(final JsonEnvelope event, final CourtApplication application) { final List prosecutionCases = new ArrayList<>(); final Stream courtApplicationCases = ofNullable(application.getCourtApplicationCases()).map(Collection::stream).orElseGet(Stream::empty); @@ -900,25 +899,25 @@ private ProsecutionCase createProsecutionCase(final ProsecutionCase prosecutionC .map(defendant -> defendant().withValuesFrom(defendant).withDefendantCaseJudicialResults(null).build()) .collect(toList()); Optional.ofNullable(courtApplication).ifPresent(c -> { - Optional.ofNullable(c.getApplicant()).ifPresent(a -> { - if (Optional.ofNullable(a.getMasterDefendant()).isPresent()) { - defendants.stream().filter(defendant -> defendant.getMasterDefendantId().equals(a.getMasterDefendant().getMasterDefendantId())) - .findFirst().ifPresent(d -> defendantsFromCourtApplication.add(d)); + Optional.ofNullable(c.getApplicant()).ifPresent(a -> { + if (Optional.ofNullable(a.getMasterDefendant()).isPresent()) { + defendants.stream().filter(defendant -> defendant.getMasterDefendantId().equals(a.getMasterDefendant().getMasterDefendantId())) + .findFirst().ifPresent(d -> defendantsFromCourtApplication.add(d)); + } + }); + Optional.ofNullable(c.getRespondents()).ifPresent(respondents -> defendantsFromCourtApplication.addAll(defendants.stream() + .filter(defendant -> respondents.stream().anyMatch(respondent -> nonNull(respondent.getMasterDefendant()) && defendant.getMasterDefendantId().equals(respondent.getMasterDefendant().getMasterDefendantId()))) + .collect(Collectors.toSet()))); } - }); - Optional.ofNullable(c.getRespondents()).ifPresent(respondents -> defendantsFromCourtApplication.addAll(defendants.stream() - .filter(defendant -> respondents.stream().anyMatch(respondent -> nonNull(respondent.getMasterDefendant()) && defendant.getMasterDefendantId().equals(respondent.getMasterDefendant().getMasterDefendantId()))) - .collect(Collectors.toSet()))); - } ); - if(isEmpty(defendantsFromCourtApplication)) { + if (isEmpty(defendantsFromCourtApplication)) { defendantsFromCourtApplication.addAll(defendants); } final List defendantList = defendantsFromCourtApplication.stream() .map(this::updatedDefendant) .filter(defendant -> isNotEmpty(defendant.getOffences())) .collect(toList()); - if(courtApplication != null && (courtApplication.getCourtCivilApplication() !=null && courtApplication.getCourtCivilApplication().getIsCivil())) { + if (courtApplication != null && (courtApplication.getCourtCivilApplication() != null && courtApplication.getCourtCivilApplication().getIsCivil())) { final CivilFees initialFees = CivilFees.civilFees() .withFeeType(FeeType.INITIAL) .withFeeId(randomUUID()) diff --git a/progression-event/progression-event-processor/src/main/java/uk/gov/moj/cpp/progression/processor/CourtProceedingsInitiatedProcessor.java b/progression-event/progression-event-processor/src/main/java/uk/gov/moj/cpp/progression/processor/CourtProceedingsInitiatedProcessor.java index 7a94eb949..7b4fb5cae 100644 --- a/progression-event/progression-event-processor/src/main/java/uk/gov/moj/cpp/progression/processor/CourtProceedingsInitiatedProcessor.java +++ b/progression-event/progression-event-processor/src/main/java/uk/gov/moj/cpp/progression/processor/CourtProceedingsInitiatedProcessor.java @@ -48,6 +48,7 @@ import java.util.stream.Collectors; import javax.inject.Inject; +import javax.json.JsonArray; import javax.json.JsonObject; import org.apache.commons.lang3.StringUtils; @@ -302,20 +303,27 @@ private boolean isNewCase(final JsonEnvelope jsonEnvelope, final ProsecutionCase private boolean getCaseByReference(final JsonEnvelope jsonEnvelope, final ProsecutionCase pCase, final String reference) { if (StringUtils.isNotEmpty(reference)) { - Optional jsonObject = progressionService.caseExistsByCaseUrn(jsonEnvelope, reference); - if (jsonObject.isPresent() && !jsonObject.get().isEmpty() && !isCaseEjected(jsonEnvelope, jsonObject.get().getString(CASE_ID), pCase)) { - LOGGER.info("Prosecution case {} already exists", reference); - return false; + final Optional searchResponse = progressionService.searchCaseDetailByURN(jsonEnvelope, reference); + if (searchResponse.isPresent() && searchResponse.get().containsKey("searchResults")) { + final JsonArray searchResults = searchResponse.get().getJsonArray("searchResults"); + for (int i = 0; i < searchResults.size(); i++) { + final JsonObject searchResult = searchResults.getJsonObject(i); + if (Boolean.FALSE.equals(searchResult.getBoolean("isStandaloneApplication", true)) + && !isCaseEjected(jsonEnvelope, searchResult.getString(CASE_ID), pCase)) { + LOGGER.info("Prosecution case {} already exists", reference); + return false; + } + } } } return true; } - private boolean isCaseEjected(final JsonEnvelope jsonEnvelope, final String reference, final ProsecutionCase prosecutionCase) { + private boolean isCaseEjected(final JsonEnvelope jsonEnvelope, final String caseId, final ProsecutionCase prosecutionCase) { return prosecutionCase.getMigrationSourceSystem() != null && prosecutionCase.getMigrationSourceSystem().getMigrationSourceSystemName() != null - && progressionService.prosecutionCaseByCaseId(jsonEnvelope, reference) + && progressionService.prosecutionCaseByCaseId(jsonEnvelope, caseId) .map(jsonObject -> CASE_EJECTED.equals(jsonObject.getJsonObject("prosecutionCase").getString(CASE_STATUS,"NO_STATUS"))) .orElse(false); } diff --git a/progression-event/progression-event-processor/src/test/java/uk/gov/moj/cpp/progression/processor/CourtApplicationProcessorTest.java b/progression-event/progression-event-processor/src/test/java/uk/gov/moj/cpp/progression/processor/CourtApplicationProcessorTest.java index bd87dbc37..e1fbefa67 100644 --- a/progression-event/progression-event-processor/src/test/java/uk/gov/moj/cpp/progression/processor/CourtApplicationProcessorTest.java +++ b/progression-event/progression-event-processor/src/test/java/uk/gov/moj/cpp/progression/processor/CourtApplicationProcessorTest.java @@ -2116,7 +2116,7 @@ public void shouldProcessHearingBreachedApplicationAdded() { assertThat(actual.getJsonObject("courtApplication").getJsonArray("respondents").getJsonObject(0).getJsonObject("masterDefendant").getJsonArray("defendantCase").getJsonObject(0), Matchers.notNullValue()); assertThat(actual.getJsonObject("courtHearing"), Matchers.notNullValue()); assertThat(actual.getJsonObject("courtApplication").getJsonArray("courtApplicationCases"), Matchers.notNullValue()); - assertThat(actual.getJsonObject("courtApplication").getJsonArray("courtApplicationCases").getJsonObject(0).getJsonArray("offences").getJsonObject(0).getString("id"), is(offenceId.toString())); + assertThat(actual.getJsonObject("courtApplication").getJsonArray("courtApplicationCases").getJsonObject(0).getJsonArray("offences"), Matchers.nullValue()); assertThat(actual.getJsonObject("courtApplication").getJsonArray("courtApplicationCases").getJsonObject(0).getString("prosecutionCaseId"), is(caseId.toString())); } @@ -2376,6 +2376,192 @@ private JsonObject getJsonPayload(final String fileName) throws IOException { .readObject(); } + @Test + public void shouldSetOffencesToNullWhenProsecutionCaseIsActiveOnBreachApplicationCreation() { + final MetadataBuilder metadataBuilder = getMetadata("progression.event.breach-application-creation-requested"); + final UUID hearingId = randomUUID(); + final UUID masterDefendantId = randomUUID(); + final UUID caseId = randomUUID(); + final UUID offenceId = randomUUID(); + final Hearing hearing = Hearing.hearing() + .withId(hearingId) + .withProsecutionCases(singletonList(prosecutionCase() + .withId(caseId) + .withCaseStatus("ACTIVE") + .withDefendants(Arrays.asList(Defendant.defendant() + .withId(masterDefendantId) + .withProsecutionCaseId(caseId) + .withMasterDefendantId(masterDefendantId) + .withOffences(Arrays.asList(Offence.offence().withId(offenceId).build())) + .build())) + .withProsecutionCaseIdentifier(prosecutionCaseIdentifier() + .withProsecutionAuthorityCode(STRING.next()) + .withProsecutionAuthorityId(randomUUID()) + .withProsecutionAuthorityReference(STRING.next()) + .build()) + .build())) + .build(); + final BreachApplicationCreationRequested breachApplicationCreationRequested = BreachApplicationCreationRequested.breachApplicationCreationRequested() + .withHearingId(hearingId) + .withBreachedApplications(BreachedApplications.breachedApplications() + .withApplicationType(CourtApplicationType.courtApplicationType().build()).build()) + .withMasterDefendantId(masterDefendantId) + .build(); + final JsonObject payload = objectToJsonObjectConverter.convert(breachApplicationCreationRequested); + final JsonEnvelope event = envelopeFrom(metadataBuilder, payload); + final JsonObject jsonObjectHearing = createObjectBuilder().add("hearing", objectToJsonObjectConverter.convert(hearing)).build(); + + when(jsonObjectToObjectConverter.convert(event.payloadAsJsonObject(), BreachApplicationCreationRequested.class)).thenReturn(breachApplicationCreationRequested); + when(progressionService.getHearing(any(JsonEnvelope.class), any(String.class))).thenReturn(Optional.of(jsonObjectHearing)); + + courtApplicationProcessor.processBreachApplicationCreationRequested(event); + + final ArgumentCaptor captor = forClass(Envelope.class); + verify(sender).send(captor.capture()); + final JsonObject actual = objectToJsonObjectConverter.convert(captor.getValue().payload()); + assertThat(actual.getJsonObject("courtApplication").getJsonArray("courtApplicationCases") + .getJsonObject(0).getJsonArray("offences"), is(Matchers.nullValue())); + } + + @Test + public void shouldSetOffencesToNullWhenProsecutionCaseIsInactiveOnBreachApplicationCreation() { + final MetadataBuilder metadataBuilder = getMetadata("progression.event.breach-application-creation-requested"); + final UUID hearingId = randomUUID(); + final UUID masterDefendantId = randomUUID(); + final UUID caseId = randomUUID(); + final UUID offenceId = randomUUID(); + final Hearing hearing = Hearing.hearing() + .withId(hearingId) + .withProsecutionCases(singletonList(prosecutionCase() + .withId(caseId) + .withCaseStatus("INACTIVE") + .withDefendants(Arrays.asList(Defendant.defendant() + .withId(masterDefendantId) + .withProsecutionCaseId(caseId) + .withMasterDefendantId(masterDefendantId) + .withOffences(Arrays.asList(Offence.offence().withId(offenceId).build())) + .build())) + .withProsecutionCaseIdentifier(prosecutionCaseIdentifier() + .withProsecutionAuthorityCode(STRING.next()) + .withProsecutionAuthorityId(randomUUID()) + .withProsecutionAuthorityReference(STRING.next()) + .build()) + .build())) + .build(); + final BreachApplicationCreationRequested breachApplicationCreationRequested = BreachApplicationCreationRequested.breachApplicationCreationRequested() + .withHearingId(hearingId) + .withBreachedApplications(BreachedApplications.breachedApplications() + .withApplicationType(CourtApplicationType.courtApplicationType().build()).build()) + .withMasterDefendantId(masterDefendantId) + .build(); + final JsonObject payload = objectToJsonObjectConverter.convert(breachApplicationCreationRequested); + final JsonEnvelope event = envelopeFrom(metadataBuilder, payload); + final JsonObject jsonObjectHearing = createObjectBuilder().add("hearing", objectToJsonObjectConverter.convert(hearing)).build(); + + when(jsonObjectToObjectConverter.convert(event.payloadAsJsonObject(), BreachApplicationCreationRequested.class)).thenReturn(breachApplicationCreationRequested); + when(progressionService.getHearing(any(JsonEnvelope.class), any(String.class))).thenReturn(Optional.of(jsonObjectHearing)); + + courtApplicationProcessor.processBreachApplicationCreationRequested(event); + + final ArgumentCaptor captor = forClass(Envelope.class); + verify(sender).send(captor.capture()); + final JsonObject actual = objectToJsonObjectConverter.convert(captor.getValue().payload()); + assertThat(actual.getJsonObject("courtApplication").getJsonArray("courtApplicationCases") + .getJsonObject(0).getJsonArray("offences"), is(Matchers.nullValue())); + } + + @Test + public void shouldSetOffencesToNullWhenProsecutionCaseIsClosedOnBreachApplicationCreation() { + final MetadataBuilder metadataBuilder = getMetadata("progression.event.breach-application-creation-requested"); + final UUID hearingId = randomUUID(); + final UUID masterDefendantId = randomUUID(); + final UUID caseId = randomUUID(); + final UUID offenceId = randomUUID(); + final Hearing hearing = Hearing.hearing() + .withId(hearingId) + .withProsecutionCases(singletonList(prosecutionCase() + .withId(caseId) + .withCaseStatus("CLOSED") + .withDefendants(Arrays.asList(Defendant.defendant() + .withId(masterDefendantId) + .withProsecutionCaseId(caseId) + .withMasterDefendantId(masterDefendantId) + .withOffences(Arrays.asList(Offence.offence().withId(offenceId).build())) + .build())) + .withProsecutionCaseIdentifier(prosecutionCaseIdentifier() + .withProsecutionAuthorityCode(STRING.next()) + .withProsecutionAuthorityId(randomUUID()) + .withProsecutionAuthorityReference(STRING.next()) + .build()) + .build())) + .build(); + final BreachApplicationCreationRequested breachApplicationCreationRequested = BreachApplicationCreationRequested.breachApplicationCreationRequested() + .withHearingId(hearingId) + .withBreachedApplications(BreachedApplications.breachedApplications() + .withApplicationType(CourtApplicationType.courtApplicationType().build()).build()) + .withMasterDefendantId(masterDefendantId) + .build(); + final JsonObject payload = objectToJsonObjectConverter.convert(breachApplicationCreationRequested); + final JsonEnvelope event = envelopeFrom(metadataBuilder, payload); + final JsonObject jsonObjectHearing = createObjectBuilder().add("hearing", objectToJsonObjectConverter.convert(hearing)).build(); + + when(jsonObjectToObjectConverter.convert(event.payloadAsJsonObject(), BreachApplicationCreationRequested.class)).thenReturn(breachApplicationCreationRequested); + when(progressionService.getHearing(any(JsonEnvelope.class), any(String.class))).thenReturn(Optional.of(jsonObjectHearing)); + + courtApplicationProcessor.processBreachApplicationCreationRequested(event); + + final ArgumentCaptor captor = forClass(Envelope.class); + verify(sender).send(captor.capture()); + final JsonObject actual = objectToJsonObjectConverter.convert(captor.getValue().payload()); + assertThat(actual.getJsonObject("courtApplication").getJsonArray("courtApplicationCases") + .getJsonObject(0).getJsonArray("offences"), is(Matchers.nullValue())); + } + + @Test + public void shouldSetCaseStatusToActiveUsingEnumOnBreachApplicationCreation() { + final MetadataBuilder metadataBuilder = getMetadata("progression.event.breach-application-creation-requested"); + final UUID hearingId = randomUUID(); + final UUID masterDefendantId = randomUUID(); + final UUID caseId = randomUUID(); + final Hearing hearing = Hearing.hearing() + .withId(hearingId) + .withProsecutionCases(singletonList(prosecutionCase() + .withId(caseId) + .withDefendants(Arrays.asList(Defendant.defendant() + .withId(masterDefendantId) + .withProsecutionCaseId(caseId) + .withMasterDefendantId(masterDefendantId) + .withOffences(Arrays.asList(Offence.offence().withId(randomUUID()).build())) + .build())) + .withProsecutionCaseIdentifier(prosecutionCaseIdentifier() + .withProsecutionAuthorityCode(STRING.next()) + .withProsecutionAuthorityId(randomUUID()) + .withProsecutionAuthorityReference(STRING.next()) + .build()) + .build())) + .build(); + final BreachApplicationCreationRequested breachApplicationCreationRequested = BreachApplicationCreationRequested.breachApplicationCreationRequested() + .withHearingId(hearingId) + .withBreachedApplications(BreachedApplications.breachedApplications() + .withApplicationType(CourtApplicationType.courtApplicationType().build()).build()) + .withMasterDefendantId(masterDefendantId) + .build(); + final JsonObject payload = objectToJsonObjectConverter.convert(breachApplicationCreationRequested); + final JsonEnvelope event = envelopeFrom(metadataBuilder, payload); + final JsonObject jsonObjectHearing = createObjectBuilder().add("hearing", objectToJsonObjectConverter.convert(hearing)).build(); + + when(jsonObjectToObjectConverter.convert(event.payloadAsJsonObject(), BreachApplicationCreationRequested.class)).thenReturn(breachApplicationCreationRequested); + when(progressionService.getHearing(any(JsonEnvelope.class), any(String.class))).thenReturn(Optional.of(jsonObjectHearing)); + + courtApplicationProcessor.processBreachApplicationCreationRequested(event); + + final ArgumentCaptor captor = forClass(Envelope.class); + verify(sender).send(captor.capture()); + final JsonObject actual = objectToJsonObjectConverter.convert(captor.getValue().payload()); + assertThat(actual.getJsonObject("courtApplication").getJsonArray("courtApplicationCases") + .getJsonObject(0).getString("caseStatus"), is("ACTIVE")); + } + private CustomComparator getCustomComparator() { return new CustomComparator(STRICT, new Customization("hearing.id", (o1, o2) -> o1 != null && o2 != null), diff --git a/progression-event/progression-event-processor/src/test/java/uk/gov/moj/cpp/progression/processor/CourtProceedingsInitiatedProcessorTest.java b/progression-event/progression-event-processor/src/test/java/uk/gov/moj/cpp/progression/processor/CourtProceedingsInitiatedProcessorTest.java index 40a7f0a3c..ab2e42113 100644 --- a/progression-event/progression-event-processor/src/test/java/uk/gov/moj/cpp/progression/processor/CourtProceedingsInitiatedProcessorTest.java +++ b/progression-event/progression-event-processor/src/test/java/uk/gov/moj/cpp/progression/processor/CourtProceedingsInitiatedProcessorTest.java @@ -12,6 +12,7 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -128,6 +129,7 @@ public class CourtProceedingsInitiatedProcessorTest { private ProgressionService progressionService; private static final String PCF_CASE_URN = "PCF_CASE_URN"; + private static final String PRO_AUTH_REF = "PRO_AUTH_REF"; @Mock private ListCourtHearingTransformer listCourtHearingTransformer; @@ -444,7 +446,15 @@ public void shouldCreateAnotherCaseWhenExistsCaseEjected() throws IOException { final String offenceCode = RandomStringUtils.randomAlphanumeric(8); String existingCaseId = UUID.randomUUID().toString(); - final JsonObject searchResult = createObjectBuilder().add("caseId", existingCaseId).build(); + final JsonObject searchResult = createObjectBuilder() + .add("searchResults", createArrayBuilder() + .add(createObjectBuilder() + .add("caseId", existingCaseId) + .add("reference", PCF_CASE_URN) + .add("isStandaloneApplication", false) + .build()) + .build()) + .build(); final JsonObject searchProsecutionCaseResult = createObjectBuilder().add("prosecutionCase",createObjectBuilder().add("caseStatus", "EJECTED").build()).build(); @@ -466,7 +476,7 @@ public void shouldCreateAnotherCaseWhenExistsCaseEjected() throws IOException { when(azureFunctionService.relayCaseOnCPP(anyString())).thenReturn(1); - doReturn(Optional.of(searchResult)).when(progressionService).caseExistsByCaseUrn(requestMessage, PCF_CASE_URN); + doReturn(Optional.of(searchResult)).when(progressionService).searchCaseDetailByURN(requestMessage, PCF_CASE_URN); doReturn(Optional.of(searchProsecutionCaseResult)).when(progressionService).prosecutionCaseByCaseId(requestMessage, existingCaseId); @@ -534,7 +544,15 @@ public void shouldNotCreateAnotherCaseWhenExistsNotCaseEjected() { final String offenceCode = RandomStringUtils.randomAlphanumeric(8); String existingCaseId = UUID.randomUUID().toString(); - final JsonObject searchResult = createObjectBuilder().add("caseId", existingCaseId).build(); + final JsonObject searchResult = createObjectBuilder() + .add("searchResults", createArrayBuilder() + .add(createObjectBuilder() + .add("caseId", existingCaseId) + .add("reference", PCF_CASE_URN) + .add("isStandaloneApplication", false) + .build()) + .build()) + .build(); final JsonObject searchProsecutionCaseResult = createObjectBuilder().add("prosecutionCase",createObjectBuilder().add("caseStatus", "NOT_EJECTED").build()).build(); @@ -554,7 +572,7 @@ public void shouldNotCreateAnotherCaseWhenExistsNotCaseEjected() { when(referenceDataOffenceService.getMultipleOffencesByOffenceCodeList(anyList(), eq(requestMessage), eq(requester), any())).thenReturn(Optional.of(emptyList())); - doReturn(Optional.of(searchResult)).when(progressionService).caseExistsByCaseUrn(requestMessage, PCF_CASE_URN); + doReturn(Optional.of(searchResult)).when(progressionService).searchCaseDetailByURN(requestMessage, PCF_CASE_URN); doReturn(Optional.of(searchProsecutionCaseResult)).when(progressionService).prosecutionCaseByCaseId(requestMessage, existingCaseId); @@ -608,6 +626,232 @@ public void shouldNotCreateAnotherCaseWhenExistsNotCaseEjected() { ); } + @Test + public void shouldCreateCaseWhenSearchReturnsEmptyResults() { + final UUID caseId = UUID.randomUUID(); + final UUID defendantId = UUID.randomUUID(); + final UUID offenceId = UUID.randomUUID(); + final String offenceCode = RandomStringUtils.randomAlphanumeric(8); + + final ProsecutionCase prosecutionCase = getProsecutionCaseWithCaseURN(caseId, List.of(defendantId), offenceId, offenceCode, true); + final JsonEnvelope requestMessage = setupCourtProceedingsInitiatedEvent(prosecutionCase, caseId, defendantId, offenceId); + + doReturn(Optional.of(buildSearchCaseDetailByUrnResponse())).when(progressionService).searchCaseDetailByURN(requestMessage, PCF_CASE_URN); + + eventProcessor.handle(requestMessage); + + assertCreateProsecutionCaseCommandSent(true); + verify(progressionService, never()).prosecutionCaseByCaseId(any(), anyString()); + } + + @Test + public void shouldCreateCaseWhenOnlyStandaloneApplicationExists() { + final UUID caseId = UUID.randomUUID(); + final UUID defendantId = UUID.randomUUID(); + final UUID offenceId = UUID.randomUUID(); + final String offenceCode = RandomStringUtils.randomAlphanumeric(8); + final String existingCaseId = UUID.randomUUID().toString(); + + final ProsecutionCase prosecutionCase = getProsecutionCaseWithCaseURN(caseId, List.of(defendantId), offenceId, offenceCode, true); + final JsonEnvelope requestMessage = setupCourtProceedingsInitiatedEvent(prosecutionCase, caseId, defendantId, offenceId); + + doReturn(Optional.of(buildSearchCaseDetailByUrnResponse( + searchResultEntry(existingCaseId, PCF_CASE_URN, true)))) + .when(progressionService).searchCaseDetailByURN(requestMessage, PCF_CASE_URN); + + eventProcessor.handle(requestMessage); + + assertCreateProsecutionCaseCommandSent(true); + verify(progressionService, never()).prosecutionCaseByCaseId(any(), anyString()); + } + + @Test + public void shouldCreateCaseWhenSearchResponseHasNoSearchResultsKey() { + final UUID caseId = UUID.randomUUID(); + final UUID defendantId = UUID.randomUUID(); + final UUID offenceId = UUID.randomUUID(); + final String offenceCode = RandomStringUtils.randomAlphanumeric(8); + + final ProsecutionCase prosecutionCase = getProsecutionCaseWithCaseURN(caseId, List.of(defendantId), offenceId, offenceCode, true); + final JsonEnvelope requestMessage = setupCourtProceedingsInitiatedEvent(prosecutionCase, caseId, defendantId, offenceId); + + doReturn(Optional.of(createObjectBuilder().build())).when(progressionService).searchCaseDetailByURN(requestMessage, PCF_CASE_URN); + + eventProcessor.handle(requestMessage); + + assertCreateProsecutionCaseCommandSent(true); + verify(progressionService, never()).prosecutionCaseByCaseId(any(), anyString()); + } + + @Test + public void shouldCreateCaseWhenSearchResponseIsEmpty() { + final UUID caseId = UUID.randomUUID(); + final UUID defendantId = UUID.randomUUID(); + final UUID offenceId = UUID.randomUUID(); + final String offenceCode = RandomStringUtils.randomAlphanumeric(8); + + final ProsecutionCase prosecutionCase = getProsecutionCaseWithCaseURN(caseId, List.of(defendantId), offenceId, offenceCode, true); + final JsonEnvelope requestMessage = setupCourtProceedingsInitiatedEvent(prosecutionCase, caseId, defendantId, offenceId); + + doReturn(Optional.empty()).when(progressionService).searchCaseDetailByURN(requestMessage, PCF_CASE_URN); + + eventProcessor.handle(requestMessage); + + assertCreateProsecutionCaseCommandSent(true); + verify(progressionService, never()).prosecutionCaseByCaseId(any(), anyString()); + } + + @Test + public void shouldNotCreateCaseWhenNonStandaloneExistsWithoutMigrationSourceSystem() { + final UUID caseId = UUID.randomUUID(); + final UUID defendantId = UUID.randomUUID(); + final UUID offenceId = UUID.randomUUID(); + final String offenceCode = RandomStringUtils.randomAlphanumeric(8); + final String existingCaseId = UUID.randomUUID().toString(); + + final ProsecutionCase prosecutionCase = getProsecutionCase( + caseId, List.of(defendantId), offenceId, offenceCode, true, + ProsecutionCaseIdentifier.prosecutionCaseIdentifier().withCaseURN(PCF_CASE_URN).build(), + false); + final JsonEnvelope requestMessage = setupCourtProceedingsInitiatedEvent(prosecutionCase, caseId, defendantId, offenceId); + + doReturn(Optional.of(buildSearchCaseDetailByUrnResponse( + searchResultEntry(existingCaseId, PCF_CASE_URN, false)))) + .when(progressionService).searchCaseDetailByURN(requestMessage, PCF_CASE_URN); + + eventProcessor.handle(requestMessage); + + assertCreateProsecutionCaseCommandSent(false); + verify(progressionService, never()).prosecutionCaseByCaseId(any(), anyString()); + } + + @Test + public void shouldNotCreateCaseWhenMultipleResultsIncludeNonStandaloneNotEjected() { + final UUID caseId = UUID.randomUUID(); + final UUID defendantId = UUID.randomUUID(); + final UUID offenceId = UUID.randomUUID(); + final String offenceCode = RandomStringUtils.randomAlphanumeric(8); + final String standaloneCaseId = UUID.randomUUID().toString(); + final String existingCaseId = UUID.randomUUID().toString(); + + final ProsecutionCase prosecutionCase = getProsecutionCaseWithCaseURN(caseId, List.of(defendantId), offenceId, offenceCode, true); + final JsonEnvelope requestMessage = setupCourtProceedingsInitiatedEvent(prosecutionCase, caseId, defendantId, offenceId); + + doReturn(Optional.of(buildSearchCaseDetailByUrnResponse( + searchResultEntry(standaloneCaseId, PCF_CASE_URN, true), + searchResultEntry(existingCaseId, PCF_CASE_URN, false)))) + .when(progressionService).searchCaseDetailByURN(requestMessage, PCF_CASE_URN); + doReturn(Optional.of(createObjectBuilder() + .add("prosecutionCase", createObjectBuilder().add("caseStatus", "ACTIVE").build()) + .build())).when(progressionService).prosecutionCaseByCaseId(requestMessage, existingCaseId); + + eventProcessor.handle(requestMessage); + + assertCreateProsecutionCaseCommandSent(false); + verify(progressionService).prosecutionCaseByCaseId(requestMessage, existingCaseId); + verify(progressionService, never()).prosecutionCaseByCaseId(requestMessage, standaloneCaseId); + } + + @Test + public void shouldCreateCaseWhenMultipleResultsAreAllStandaloneApplications() { + final UUID caseId = UUID.randomUUID(); + final UUID defendantId = UUID.randomUUID(); + final UUID offenceId = UUID.randomUUID(); + final String offenceCode = RandomStringUtils.randomAlphanumeric(8); + + final ProsecutionCase prosecutionCase = getProsecutionCaseWithCaseURN(caseId, List.of(defendantId), offenceId, offenceCode, true); + final JsonEnvelope requestMessage = setupCourtProceedingsInitiatedEvent(prosecutionCase, caseId, defendantId, offenceId); + + doReturn(Optional.of(buildSearchCaseDetailByUrnResponse( + searchResultEntry(UUID.randomUUID().toString(), PCF_CASE_URN, true), + searchResultEntry(UUID.randomUUID().toString(), PCF_CASE_URN, true)))) + .when(progressionService).searchCaseDetailByURN(requestMessage, PCF_CASE_URN); + + eventProcessor.handle(requestMessage); + + assertCreateProsecutionCaseCommandSent(true); + verify(progressionService, never()).prosecutionCaseByCaseId(any(), anyString()); + } + + @Test + public void shouldNotCreateCaseWhenProsecutionAuthorityReferenceFindsNonStandaloneCase() { + final UUID caseId = UUID.randomUUID(); + final UUID defendantId = UUID.randomUUID(); + final UUID offenceId = UUID.randomUUID(); + final String offenceCode = RandomStringUtils.randomAlphanumeric(8); + final String existingCaseId = UUID.randomUUID().toString(); + + final ProsecutionCase prosecutionCase = getProsecutionCase( + caseId, List.of(defendantId), offenceId, offenceCode, true, + ProsecutionCaseIdentifier.prosecutionCaseIdentifier() + .withCaseURN(PCF_CASE_URN) + .withProsecutionAuthorityReference(PRO_AUTH_REF) + .build(), + true); + final JsonEnvelope requestMessage = setupCourtProceedingsInitiatedEvent(prosecutionCase, caseId, defendantId, offenceId); + + doReturn(Optional.of(buildSearchCaseDetailByUrnResponse( + searchResultEntry(existingCaseId, PRO_AUTH_REF, false)))) + .when(progressionService).searchCaseDetailByURN(requestMessage, PRO_AUTH_REF); + doReturn(Optional.of(createObjectBuilder() + .add("prosecutionCase", createObjectBuilder().add("caseStatus", "ACTIVE").build()) + .build())).when(progressionService).prosecutionCaseByCaseId(requestMessage, existingCaseId); + + eventProcessor.handle(requestMessage); + + assertCreateProsecutionCaseCommandSent(false); + verify(progressionService).searchCaseDetailByURN(requestMessage, PRO_AUTH_REF); + verify(progressionService, never()).searchCaseDetailByURN(requestMessage, PCF_CASE_URN); + verify(progressionService).prosecutionCaseByCaseId(requestMessage, existingCaseId); + } + + @Test + public void shouldNotCreateCaseWhenNonStandaloneExistsAndProsecutionCaseQueryReturnsEmpty() { + final UUID caseId = UUID.randomUUID(); + final UUID defendantId = UUID.randomUUID(); + final UUID offenceId = UUID.randomUUID(); + final String offenceCode = RandomStringUtils.randomAlphanumeric(8); + final String existingCaseId = UUID.randomUUID().toString(); + + final ProsecutionCase prosecutionCase = getProsecutionCaseWithCaseURN(caseId, List.of(defendantId), offenceId, offenceCode, true); + final JsonEnvelope requestMessage = setupCourtProceedingsInitiatedEvent(prosecutionCase, caseId, defendantId, offenceId); + + doReturn(Optional.of(buildSearchCaseDetailByUrnResponse( + searchResultEntry(existingCaseId, PCF_CASE_URN, false)))) + .when(progressionService).searchCaseDetailByURN(requestMessage, PCF_CASE_URN); + doReturn(Optional.empty()).when(progressionService).prosecutionCaseByCaseId(requestMessage, existingCaseId); + + eventProcessor.handle(requestMessage); + + assertCreateProsecutionCaseCommandSent(false); + verify(progressionService).prosecutionCaseByCaseId(requestMessage, existingCaseId); + } + + @Test + public void shouldCreateCaseWhenNonStandaloneExistsButCaseIsEjected() throws IOException { + final UUID caseId = UUID.randomUUID(); + final UUID defendantId = UUID.randomUUID(); + final UUID offenceId = UUID.randomUUID(); + final String offenceCode = RandomStringUtils.randomAlphanumeric(8); + final String existingCaseId = UUID.randomUUID().toString(); + + final ProsecutionCase prosecutionCase = getProsecutionCaseWithCaseURN(caseId, List.of(defendantId), offenceId, offenceCode, true); + final JsonEnvelope requestMessage = setupCourtProceedingsInitiatedEvent(prosecutionCase, caseId, defendantId, offenceId); + + doReturn(Optional.of(buildSearchCaseDetailByUrnResponse( + searchResultEntry(existingCaseId, PCF_CASE_URN, false)))) + .when(progressionService).searchCaseDetailByURN(requestMessage, PCF_CASE_URN); + doReturn(Optional.of(createObjectBuilder() + .add("prosecutionCase", createObjectBuilder().add("caseStatus", "EJECTED").build()) + .build())).when(progressionService).prosecutionCaseByCaseId(requestMessage, existingCaseId); + when(azureFunctionService.relayCaseOnCPP(anyString())).thenReturn(1); + + eventProcessor.handle(requestMessage); + + assertCreateProsecutionCaseCommandSent(true); + verify(progressionService).prosecutionCaseByCaseId(requestMessage, existingCaseId); + } + @Test public void shouldHandleCasesReferredToCourtEventMessageWhenMultipleHearingRequestHasSameListHearingRequestWithDifferentDefendant() throws IOException { //Given @@ -1347,4 +1591,70 @@ private JsonObject buildProsecutionCase(final UUID caseId) { .build()) .build(); } + + private JsonEnvelope setupCourtProceedingsInitiatedEvent(final ProsecutionCase prosecutionCase, + final UUID caseId, + final UUID defendantId, + final UUID offenceId) { + final ListHearingRequest listHearingRequest = populateListHearingRequest(caseId, defendantId, offenceId); + final JsonEnvelope requestMessage = envelopeFrom( + MetadataBuilderFactory.metadataWithRandomUUID("progression.event.court-proceedings-initiated"), + payload); + + when(payload.getJsonObject("courtReferral")).thenReturn(courtReferralJson); + when(jsonObjectToObjectConverter.convert(courtReferralJson, CourtReferral.class)).thenReturn(courtReferral); + when(courtReferral.getProsecutionCases()).thenReturn(singletonList(prosecutionCase)); + when(courtReferral.getListHearingRequests()).thenReturn(singletonList(listHearingRequest)); + when(referenceDataOffenceService.getMultipleOffencesByOffenceCodeList(anyList(), eq(requestMessage), eq(requester), any())) + .thenReturn(Optional.of(emptyList())); + + final List hearingsList = new ArrayList<>(); + hearingsList.add(HearingListingNeeds.hearingListingNeeds() + .withProsecutionCases(List.of(ProsecutionCase.prosecutionCase() + .withDefendants(List.of(Defendant.defendant() + .withOffences(List.of(Offence.offence().withId(UUID.randomUUID()).build())) + .build())) + .withId(caseId) + .withProsecutionCaseIdentifier(prosecutionCase.getProsecutionCaseIdentifier()) + .build())) + .build()); + when(listCourtHearingTransformer.transform(any(), any(), anyList(), any())) + .thenReturn(ListCourtHearing.listCourtHearing().withHearings(hearingsList).build()); + when(objectToJsonObjectConverter.convert(any())).thenReturn(buildProsecutionCase(caseId)); + + return requestMessage; + } + + private JsonObject buildSearchCaseDetailByUrnResponse(final JsonObject... searchResults) { + final JsonArrayBuilder searchResultsBuilder = createArrayBuilder(); + for (final JsonObject searchResult : searchResults) { + searchResultsBuilder.add(searchResult); + } + return createObjectBuilder().add("searchResults", searchResultsBuilder.build()).build(); + } + + private JsonObject searchResultEntry(final String caseId, final String reference, final boolean isStandaloneApplication) { + return createObjectBuilder() + .add("caseId", caseId) + .add("reference", reference) + .add("isStandaloneApplication", isStandaloneApplication) + .build(); + } + + private void assertCreateProsecutionCaseCommandSent(final boolean expectedSent) { + verify(sender, times(expectedSent ? 3 : 2)).send(envelopeCaptor.capture()); + + final List metadataNames = envelopeCaptor.getAllValues().stream() + .map(value -> value.metadata().name()) + .toList(); + + if (expectedSent) { + assertThat(metadataNames.contains("progression.command.create-prosecution-case"), is(true)); + } else { + assertFalse( + metadataNames.contains("progression.command.create-prosecution-case"), + "Expected 'progression.command.create-prosecution-case' to not be present in the metadata names." + ); + } + } } diff --git a/progression-integration-test/src/test/java/uk/gov/moj/cpp/progression/UploadCourtDocumentIT.java b/progression-integration-test/src/test/java/uk/gov/moj/cpp/progression/UploadCourtDocumentIT.java index 0bea23cb1..5569ad9f2 100644 --- a/progression-integration-test/src/test/java/uk/gov/moj/cpp/progression/UploadCourtDocumentIT.java +++ b/progression-integration-test/src/test/java/uk/gov/moj/cpp/progression/UploadCourtDocumentIT.java @@ -51,6 +51,7 @@ import org.hamcrest.Matcher; import org.json.JSONException; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.skyscreamer.jsonassert.Customization; import org.skyscreamer.jsonassert.comparator.CustomComparator; @@ -183,6 +184,7 @@ private void verifyInMessagingQueueForPublicCourtDocumentAdded() { assertTrue(message.isPresent()); } + @Disabled @Test public void uploadApplicationDocument() throws Exception { final UUID applicationId = randomUUID();