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 764454bd2..f41a2522d 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 @@ -1035,7 +1035,7 @@ private String generateApplicationReference(final CourtApplication courtApplicat @SuppressWarnings({"java:S2245"}) private String generateUrn() { return RandomStringUtils.random(4, 0, 0, true, true, null, SECURE_RANDOM).toUpperCase() + - RandomStringUtils.random(7, 0, 0, false, true, null, SECURE_RANDOM); + RandomStringUtils.random(7, 0, 0, false, true, null, SECURE_RANDOM); } diff --git a/progression-domain/progression-domain-aggregate/src/main/java/uk/gov/moj/cpp/progression/aggregate/HearingAggregate.java b/progression-domain/progression-domain-aggregate/src/main/java/uk/gov/moj/cpp/progression/aggregate/HearingAggregate.java index b0c358c37..6484d7318 100644 --- a/progression-domain/progression-domain-aggregate/src/main/java/uk/gov/moj/cpp/progression/aggregate/HearingAggregate.java +++ b/progression-domain/progression-domain-aggregate/src/main/java/uk/gov/moj/cpp/progression/aggregate/HearingAggregate.java @@ -126,7 +126,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@SuppressWarnings({"squid:S1948", "squid:S1172", "squid:S1188", "squid:S3655", "java:S6204"}) +@SuppressWarnings({"squid:S1948", "squid:S1172", "squid:S1188", "squid:S3655", "java:S6204", "squid:S1168"}) public class HearingAggregate implements Aggregate { private static final Logger LOGGER = LoggerFactory.getLogger(HearingAggregate.class); private static final long serialVersionUID = 8888819367477517209L; @@ -147,7 +147,7 @@ public class HearingAggregate implements Aggregate { private final List addedOffencesMovedToHearings = new ArrayList<>(); private Boolean isHearingInitiateEnriched = false; private List seededProsecutionCases = null; - private MarkedHearingConfirmedForReplay markedHearingConfirmedForReplay =null; + private MarkedHearingConfirmedForReplay markedHearingConfirmedForReplay = null; private ZonedDateTime resultSharedDateTime; @@ -179,8 +179,8 @@ public class HearingAggregate implements Aggregate { ); private static final UUID REMAND_STATUS_PROMPT_ID = UUID.fromString("9403f0d7-90b5-4377-84b4-f06a77811362"); - private static final String[] onBailStatusValues = new String[]{ "Conditional Bail", "Unconditional Bail"}; - private static final String[] onBailStatusCodes = new String[]{ "B", "U"}; + private static final String[] onBailStatusValues = new String[]{"Conditional Bail", "Unconditional Bail"}; + private static final String[] onBailStatusCodes = new String[]{"B", "U"}; private static final UUID DEFENDANT_FOUND_UNDER_A_DISABILITY = UUID.fromString("d3d94468-02a4-3259-b55d-38e6d163e820"); @VisibleForTesting @@ -335,7 +335,7 @@ public Object apply(final Object event) { private void handleAddedOffencesMovedToHearing(AddedOffencesMovedToHearing addedOffencesMovedToHearing) { newOffences.addAll(addedOffencesMovedToHearing.getNewOffences().stream().map(Offence::getId).collect(Collectors.toSet())); - if(isHearingInitiateEnriched){ + if (isHearingInitiateEnriched) { return; } if (!addedOffencesMovedToHearings.contains(addedOffencesMovedToHearing)) { @@ -457,6 +457,7 @@ public Stream amendSummonsData(final SummonsApprovedOutcome summonsAppro .withConfirmedProsecutionCaseIds(confirmedProsecutionCaseIdsToSend) .withListDefendantRequests(listDefendantRequestsToSend) .withCourtApplicationPartyListingNeeds(courtApplicationPartyListingNeedsToSend) + .withConfirmedApplicationIds(collectApplicationIds(courtApplicationPartyListingNeedsToSend)) .build()) .withIsSummonsAmended(true) .build()); @@ -464,6 +465,16 @@ public Stream amendSummonsData(final SummonsApprovedOutcome summonsAppro return apply(streamBuilder.build()); } + private List collectApplicationIds(final List courtApplicationPartyListingNeedsToSend) { + if (isNull(courtApplicationPartyListingNeedsToSend)) { + return null; + } + return courtApplicationPartyListingNeedsToSend.stream() + .map(CourtApplicationPartyListingNeeds::getCourtApplicationId) + .filter(Objects::nonNull) + .collect(toList()); + } + private static CourtCentre getCourtCentre(final CourtCentre courtCentre) { return CourtCentre.courtCentre() .withCode(courtCentre.getCode()) @@ -1182,7 +1193,7 @@ private void setHearing(final Hearing hearing) { } } - private Hearing getDeDupHearing(final Hearing hearing){ + private Hearing getDeDupHearing(final Hearing hearing) { Hearing updatedHearing = dedupAllReportingRestrictions(hearing); updatedHearing = deDupAllApplications(updatedHearing); return updatedHearing; @@ -1395,11 +1406,11 @@ public Stream deleteHearing(final UUID hearingId) { public Stream unallocateHearingWhenCourtroomIsRemoved(final UUID hearingId, final Integer estimatedMinutes) { - if (this.deleted || this.duplicate || (HearingListingStatus.HEARING_RESULTED.equals(hearingListingStatus))) { + if (this.deleted || this.duplicate || (HearingListingStatus.HEARING_RESULTED.equals(hearingListingStatus))) { return empty(); } - if (hearing == null || JurisdictionType.MAGISTRATES.equals(hearing.getJurisdictionType()) || hearing.getCourtCentre() ==null) { + if (hearing == null || JurisdictionType.MAGISTRATES.equals(hearing.getJurisdictionType()) || hearing.getCourtCentre() == null) { return empty(); } @@ -1561,7 +1572,8 @@ public Stream updateApplicationHearing(final DefendantUpdate defendantUp /** * DO NOT USE THIS FUNCTION EXCEPT FOR THE PURPOSE MENTIONED BELOW. The aggregate function is * being added to be invoked only by the BDF, purpose of this function to raise - * 'progression.event.hearing.remove.duplicate.application.bdf' event to remove the duplicate application from hearing. + * 'progression.event.hearing.remove.duplicate.application.bdf' event to remove the duplicate + * application from hearing. * * @return The Stream object */ @@ -1876,7 +1888,7 @@ private void onOffencesRemovedFromHearing(final OffencesRemovedFromHearing offen // update newOffences when an offence was deleted from the hearing. final Set offences = hearing.getProsecutionCases().stream().flatMap(pc -> pc.getDefendants().stream()) .flatMap(def -> def.getOffences().stream()).map(Offence::getId).collect(Collectors.toSet()); - newOffences.removeIf( off -> !offences.contains(off)); + newOffences.removeIf(off -> !offences.contains(off)); addedOffencesMovedToHearings.clear(); } final List offencesToBeRemoved = offencesRemovedFromHearing.getOffenceIds(); @@ -1960,7 +1972,7 @@ public Stream processHearingResults(final Hearing hearing, final ZonedDa .withCourtApplications(updatedCourtApplications) .withProsecutionCases(updatedProsecutionCasesForOriginalHearing).build(); final Set ctlExpiredOffenceIds = stopCTLExpiryForV2(hearing, resultIdList); - if(isNotEmpty(ctlExpiredOffenceIds)) { + if (isNotEmpty(ctlExpiredOffenceIds)) { updatedHearing = Hearing.hearing().withValuesFrom(updatedHearing) .withProsecutionCases(ofNullable(updatedHearing.getProsecutionCases()).map(Collection::stream).orElseGet(Stream::empty) .map(prosecutionCase -> ProsecutionCase.prosecutionCase().withValuesFrom(prosecutionCase) @@ -2012,7 +2024,6 @@ public Stream processHearingResults(final Hearing hearing, final ZonedDa } - if (isNotEmpty(hearing.getCourtApplications())) { streamBuilder.add(applicationsResulted() .withHearing(getHearingWithUpdatedProsecutionCases(updatedHearing)) @@ -2038,7 +2049,7 @@ public Stream updateRelatedHearing(final HearingListingNeeds hearingList final Stream.Builder streamBuilder = Stream.builder(); final HearingListingNeeds newHearingListingNeeds = HearingListingNeeds.hearingListingNeeds().withValuesFrom(hearingListingNeeds).build(); - if (! HearingListingStatus.HEARING_RESULTED.equals(this.hearingListingStatus)) { + if (!HearingListingStatus.HEARING_RESULTED.equals(this.hearingListingStatus)) { final Set resultCases = new HashSet<>(); getProsecutionCasesAfterMergeAtDifferentLevel(hearingListingNeeds, resultCases); @@ -2087,7 +2098,7 @@ public Stream updateRelatedHearingForAdhocHearing(final HearingListingNe final Stream.Builder streamBuilder = Stream.builder(); final HearingListingNeeds newHearingListingNeeds = HearingListingNeeds.hearingListingNeeds().withValuesFrom(hearingListingNeeds).build(); - if (! HearingListingStatus.HEARING_RESULTED.equals(this.hearingListingStatus)) { + if (!HearingListingStatus.HEARING_RESULTED.equals(this.hearingListingStatus)) { final Set resultCases = new HashSet<>(); getProsecutionCasesAfterMergeAtDifferentLevel(hearingListingNeeds, resultCases); @@ -2125,7 +2136,7 @@ public Stream updateRelatedHearingForAdhocHearing(final HearingListingNe final Stream events = apply(streamBuilder.build()); return Stream.concat(Stream.concat(events, populateHearingToProbationCaseWorker()), populateHearingToVEP()); - } else { + } else { return Stream.empty(); } @@ -3531,7 +3542,7 @@ public Stream moveOffencesFromHearing(final MoveOffencesFromOldNextHeari // So we need to move new offences to new next hearing // because seeded hearing does not have new offences, and it can't create new next hearing with new offences. final List prosecutionCases = ofNullable(seededProsecutionCases).orElse(this.hearing.getProsecutionCases()); - if(isEmpty(prosecutionCases)){ + if (isEmpty(prosecutionCases)) { return Stream.empty(); } @@ -3558,7 +3569,7 @@ public Stream moveOffencesFromHearing(final MoveOffencesFromOldNextHeari .build()) .filter(seededCase -> nonNull(seededCase.getSeededDefendants())) .collect(toList())) - .build()).filter(event -> ! event.getSeededCase().isEmpty()).map(o -> o)); + .build()).filter(event -> !event.getSeededCase().isEmpty()).map(o -> o)); } @@ -3566,11 +3577,11 @@ public Stream moveOffencesToHearing(final MoveOffencesToNewNextHearing m final Stream.Builder streamBuilder = Stream.builder(); moveOffencesToNewNextHearing.getSeededCase().forEach(seededCase -> - ofNullable(seededCase.getSeededDefendants()).stream().flatMap(Collection::stream).filter(def-> this.hearing.getProsecutionCases().stream() + ofNullable(seededCase.getSeededDefendants()).stream().flatMap(Collection::stream).filter(def -> this.hearing.getProsecutionCases().stream() .filter(pcase -> pcase.getId().equals(seededCase.getId())) .flatMap(pcase -> pcase.getDefendants().stream()) .filter(pdef -> pdef.getId().equals(def.getId())) - .anyMatch(pdef -> def.getSeededOffences().stream().anyMatch( off -> notInHearingState(seededCase.getId(), pdef.getId(), off.getId())))) + .anyMatch(pdef -> def.getSeededOffences().stream().anyMatch(off -> notInHearingState(seededCase.getId(), pdef.getId(), off.getId())))) .forEach(def -> { streamBuilder.add(AddedOffencesMovedToHearing.addedOffencesMovedToHearing() .withHearingId(moveOffencesToNewNextHearing.getHearingId()) @@ -3588,7 +3599,7 @@ public Stream moveOffencesToHearing(final MoveOffencesToNewNextHearing m } public Stream addCasesToHearingBdf(final UUID hearingId, final List cases) { - final Stream events = apply(Stream.of(CaseAddedToHearingBdf.caseAddedToHearingBdf() + final Stream events = apply(Stream.of(CaseAddedToHearingBdf.caseAddedToHearingBdf() .withHearingId(hearingId) .withProsecutionCases(cases) .build())); @@ -3596,25 +3607,25 @@ public Stream addCasesToHearingBdf(final UUID hearingId, final List pcase.getId().equals(caseId)) .flatMap(pcase -> pcase.getDefendants().stream()) .noneMatch(pdef -> pdef.getId().equals(defId)); } + private boolean notInHearingState(final UUID caseId, final UUID defId, final UUID offId) { - return this.hearing.getProsecutionCases().stream().filter(pcase -> pcase.getId().equals(caseId)) + return this.hearing.getProsecutionCases().stream().filter(pcase -> pcase.getId().equals(caseId)) .flatMap(pcase -> pcase.getDefendants().stream()) .filter(def -> def.getId().equals(defId)) - .flatMap(def-> def.getOffences().stream()) + .flatMap(def -> def.getOffences().stream()) .noneMatch(off -> off.getId().equals(offId)); } - private void addNewOffencesToHearing(final Hearing hearing) { - if (addedOffencesMovedToHearings.isEmpty()){ + if (addedOffencesMovedToHearings.isEmpty()) { return; } addedOffencesMovedToHearings.forEach(addedOffencesMovedToHearing -> @@ -3674,11 +3685,11 @@ private static boolean isGuiltyAndHasCTLExpiry(final Offence offence) { isCTLExpiryExists(offence); } - private static boolean isGuilty(final Offence offence) { + private static boolean isGuilty(final Offence offence) { return (nonNull(offence.getPlea()) && GUILTY_PLEA_VALUES.stream() .anyMatch(value -> value.equalsIgnoreCase(offence.getPlea().getPleaValue()))) || - (nonNull(offence.getVerdict()) && isGuiltyVerdict(offence.getVerdict().getVerdictType())) ; + (nonNull(offence.getVerdict()) && isGuiltyVerdict(offence.getVerdict().getVerdictType())); } private static boolean isCTLExpiryExists(final Offence offence) { @@ -3705,7 +3716,7 @@ private static boolean isOnBailAndHasCTLExpiryForV2(final Offence offence) { } private static boolean isResultNotDeleted(final JudicialResult result) { - return !result.getIsDeleted() ; + return !result.getIsDeleted(); } private static boolean isDefendantOnBail(final Defendant defendant) { @@ -3727,7 +3738,7 @@ private static boolean isAnyDefendantsOffencesVerdictIsDefendantFoundUnderADisab } public Stream replayHearingConfirmed(final ReplayHearingConfirmed replayHearingConfirmed) { - if(isNull(this.getHearing())) { + if (isNull(this.getHearing())) { return apply(Stream.of(MarkedHearingConfirmedForReplay.markedHearingConfirmedForReplay() .withConfirmedHearing(replayHearingConfirmed.getConfirmedHearing()) .withSendNotificationToParties(replayHearingConfirmed.getSendNotificationToParties()) @@ -3742,7 +3753,7 @@ public Stream replayHearingConfirmed(final ReplayHearingConfirmed replay } private void addReplayEvent(final Stream.Builder streamBuilder, final Hearing hearing) { - if(!isNull(this.markedHearingConfirmedForReplay)){ + if (!isNull(this.markedHearingConfirmedForReplay)) { streamBuilder.add(HearingConfirmedReplayed.hearingConfirmedReplayed() .withConfirmedHearing(this.markedHearingConfirmedForReplay.getConfirmedHearing()) .withSendNotificationToParties(this.markedHearingConfirmedForReplay.getSendNotificationToParties()) diff --git a/progression-domain/progression-domain-aggregate/src/test/java/uk/gov/moj/cpp/progression/aggregate/HearingAggregateTest.java b/progression-domain/progression-domain-aggregate/src/test/java/uk/gov/moj/cpp/progression/aggregate/HearingAggregateTest.java index 4de4e20da..ca0a44383 100644 --- a/progression-domain/progression-domain-aggregate/src/test/java/uk/gov/moj/cpp/progression/aggregate/HearingAggregateTest.java +++ b/progression-domain/progression-domain-aggregate/src/test/java/uk/gov/moj/cpp/progression/aggregate/HearingAggregateTest.java @@ -6881,6 +6881,37 @@ public void shouldAmendSummonsDataAndProduceSummonsDataPreparedEvent() { assertThat(prepared.getIsSummonsAmended(), is(true)); } + @Test + public void shouldAmendSummonsDataAndPopulateConfirmedApplicationIds() { + final UUID applicationId = randomUUID(); + + final List list = new ArrayList<>(); + list.add(CourtApplicationPartyListingNeeds.courtApplicationPartyListingNeeds() + .withCourtApplicationId(applicationId) + .build()); + + hearingAggregate.createHearingApplicationRequest(list).collect(toList()); + + setField(hearingAggregate, "hearing", + Hearing.hearing() + .withCourtCentre(CourtCentre.courtCentre().withId(randomUUID()).withCode("testCode").build()) + .withHearingDays(of(HearingDay.hearingDay().withSittingDay(ZonedDateTime.now()).build())) + .build()); + + final SummonsApprovedOutcome summonsApprovedOutcome = SummonsApprovedOutcome.summonsApprovedOutcome() + .withPersonalService(true) + .withSummonsSuppressed(false) + .build(); + + final List events = hearingAggregate.amendSummonsData(summonsApprovedOutcome).collect(toList()); + + assertThat(events.size(), is(1)); + final SummonsDataPrepared prepared = (SummonsDataPrepared) events.get(0); + assertThat(prepared.getSummonsData().getConfirmedApplicationIds(), notNullValue()); + assertThat(prepared.getSummonsData().getConfirmedApplicationIds().size(), is(1)); + assertThat(prepared.getSummonsData().getConfirmedApplicationIds().get(0), is(applicationId)); + } + @Test public void shouldReturnEmptyStreamWhenNoListDefendantRequestsAndNoApplicationListingNeeds() { setField(hearingAggregate, "hearing", 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 9a441343e..d4f51ad40 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 @@ -14,12 +14,14 @@ import static javax.json.Json.createObjectBuilder; import static org.apache.commons.collections.CollectionUtils.isEmpty; import static org.apache.commons.collections.CollectionUtils.isNotEmpty; +import static org.apache.commons.lang3.BooleanUtils.isTrue; import static uk.gov.justice.core.courts.CourtApplicationPartyListingNeeds.courtApplicationPartyListingNeeds; import static uk.gov.justice.core.courts.CreateHearingApplicationRequest.createHearingApplicationRequest; import static uk.gov.justice.core.courts.Defendant.defendant; import static uk.gov.justice.core.courts.Hearing.hearing; import static uk.gov.justice.core.courts.HearingDay.hearingDay; import static uk.gov.justice.core.courts.HearingListingStatus.SENT_FOR_LISTING; +import static uk.gov.justice.core.courts.LinkType.FIRST_HEARING; import static uk.gov.justice.core.courts.LinkType.LINKED; import static uk.gov.justice.core.courts.ProsecutionCase.prosecutionCase; import static uk.gov.justice.core.courts.PublicProgressionCourtApplicationSummonsRejected.publicProgressionCourtApplicationSummonsRejected; @@ -45,6 +47,7 @@ import uk.gov.justice.core.courts.CourtApplicationProceedingsInitiated; import uk.gov.justice.core.courts.CourtApplicationSummonsApproved; import uk.gov.justice.core.courts.CourtApplicationSummonsRejected; +import uk.gov.justice.core.courts.CourtCivilApplication; import uk.gov.justice.core.courts.CourtHearingRequest; import uk.gov.justice.core.courts.CourtOrderOffence; import uk.gov.justice.core.courts.CreateHearingApplicationRequest; @@ -78,6 +81,7 @@ import uk.gov.justice.core.courts.SummonsType; import uk.gov.justice.hearing.courts.Initiate; import uk.gov.justice.progression.courts.Hearings; +import uk.gov.justice.progression.query.laa.HearingSummary; import uk.gov.justice.services.common.converter.JsonObjectToObjectConverter; import uk.gov.justice.services.common.converter.ObjectToJsonObjectConverter; import uk.gov.justice.services.core.annotation.Handles; @@ -146,6 +150,7 @@ public class CourtApplicationProcessor { private static final String REMOVE_DEFENDANT_CUSTODIAL_ESTABLISHMENT_FROM_CASE = "progression.command.remove-defendant-custodial-establishment-from-case"; private static final String HEARING_INITIATE_COMMAND = "hearing.initiate"; private static final UUID APPLICATION_HEARING_TYPE_ID = fromString("3449743b-95d6-4836-8941-57f588b52068"); + private static final UUID BREACH_HEARING_TYPE_ID = fromString("136dfc3a-a874-32ce-8493-e50849590b49"); private static final String APPLICATION = "Application"; private static final String PUBLIC_PROGRESSION_COURT_APPLICATION_SUMMONS_APPROVED = "public.progression.court-application-summons-approved"; private static final String PUBLIC_PROGRESSION_COURT_APPLICATION_SUMMONS_REJECTED = "public.progression.court-application-summons-rejected"; @@ -243,7 +248,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())) @@ -330,13 +335,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))); @@ -417,9 +422,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; @@ -510,8 +515,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())); @@ -617,32 +622,32 @@ public void processCourtApplicationReferredToCourtHearing(final JsonEnvelope eve public void courtApplicationSummonsApproved(final JsonEnvelope event) { final CourtApplicationSummonsApproved courtApplicationSummonsApproved = jsonObjectToObjectConverter.convert(event.payloadAsJsonObject(), CourtApplicationSummonsApproved.class); + final UUID caseId = courtApplicationSummonsApproved.getCaseIds().get(0); if (LOGGER.isInfoEnabled()) { - LOGGER.info("Processing event for court-application-summons-approved with application id: {} - Link Type: {} - isAmended: {}", + LOGGER.info("Processing event for court-application-summons-approved with caseId : {} - applicationId: {} - Link Type: {} - isAmended: {}", + caseId, courtApplicationSummonsApproved.getApplicationId(), courtApplicationSummonsApproved.getLinkType(), courtApplicationSummonsApproved.getIsSummonsAmended()); } - final UUID caseId = courtApplicationSummonsApproved.getCaseIds().get(0); - - if (courtApplicationSummonsApproved.getLinkType() == LinkType.FIRST_HEARING && Boolean.TRUE.equals(courtApplicationSummonsApproved.getIsSummonsAmended())) { + if (shouldReGenerateSummonsDocument(courtApplicationSummonsApproved)) { - final Optional firstHearingId = getFirstHearingId(caseId); + final Optional hearingId = getHearingIdForSummonGeneration(courtApplicationSummonsApproved); - if(firstHearingId.isPresent()) { - LOGGER.info("Firing summons amendment requested for application: {} - summonsApprovedOutcome: {}", courtApplicationSummonsApproved.getApplicationId(), courtApplicationSummonsApproved.getSummonsApprovedOutcome()); + if (hearingId.isPresent()) { + LOGGER.info("Firing summons amendment requested for caseId : {}, applicationId : {}, linkType : {} - summonsApprovedOutcome: {}", caseId, courtApplicationSummonsApproved.getApplicationId(), courtApplicationSummonsApproved.getLinkType(), courtApplicationSummonsApproved.getSummonsApprovedOutcome()); final JsonObject amendmentRequestPayload = createObjectBuilder() - .add(HEARING_ID, firstHearingId.get().toString()) + .add(HEARING_ID, hearingId.get().toString()) .add(SUMMONS_APPROVED_OUTCOME, objectToJsonObjectConverter.convert(courtApplicationSummonsApproved.getSummonsApprovedOutcome())) .build(); sender.send(envelop(amendmentRequestPayload).withName(PROGRESSION_COMMAND_AMEND_SUMMONS_DATA).withMetadataFrom(event)); } else { - LOGGER.warn("No first hearing found for case : {}", caseId); + LOGGER.warn("No first/breach hearing found for caseId : {}, applicationId : {}, linkType : {}", caseId, courtApplicationSummonsApproved.getApplicationId(), courtApplicationSummonsApproved.getLinkType()); } - } else if (courtApplicationSummonsApproved.getLinkType() == LinkType.FIRST_HEARING) { + } else if (isFirstHearing(courtApplicationSummonsApproved)) { final PublicProgressionCourtApplicationSummonsApproved summonsApprovedPublicEventPayload = PublicProgressionCourtApplicationSummonsApproved.publicProgressionCourtApplicationSummonsApproved() .withSummonsApprovedOutcome(courtApplicationSummonsApproved.getSummonsApprovedOutcome()) .withId(courtApplicationSummonsApproved.getApplicationId()) @@ -653,6 +658,53 @@ public void courtApplicationSummonsApproved(final JsonEnvelope event) { } } + private Optional getHearingIdForSummonGeneration(final CourtApplicationSummonsApproved courtApplicationSummonsApproved) { + if (isFirstHearing(courtApplicationSummonsApproved)) { + final UUID caseId = courtApplicationSummonsApproved.getCaseIds().get(0); + return getFirstHearingId(caseId); + } else if (isLinkedHearing(courtApplicationSummonsApproved)) { + final UUID applicationId = courtApplicationSummonsApproved.getApplicationId(); + return getBreachHearingId(applicationId); + } else { + return Optional.empty(); + } + } + + private static boolean shouldReGenerateSummonsDocument(final CourtApplicationSummonsApproved courtApplicationSummonsApproved) { + return (isFirstHearing(courtApplicationSummonsApproved) || isLinkedHearing(courtApplicationSummonsApproved)) && isAmendment(courtApplicationSummonsApproved); + } + + private static boolean isAmendment(final CourtApplicationSummonsApproved courtApplicationSummonsApproved) { + return isTrue(courtApplicationSummonsApproved.getIsSummonsAmended()); + } + + private static boolean isFirstHearing(final CourtApplicationSummonsApproved courtApplicationSummonsApproved) { + return courtApplicationSummonsApproved.getLinkType() == FIRST_HEARING; + } + + private static boolean isLinkedHearing(final CourtApplicationSummonsApproved courtApplicationSummonsApproved) { + return courtApplicationSummonsApproved.getLinkType() == LINKED; + } + + private Optional getBreachHearingId(final UUID applicationId) { + final Optional> applicationHearings = progressionService.getHearingsForApplication(applicationId); + + if (applicationHearings.isPresent()) { + final Optional breachHearing = applicationHearings.get().stream() + .filter(h -> nonNull(h.getHearingType()) && BREACH_HEARING_TYPE_ID.equals(h.getHearingType().getId())) + .findFirst(); + + if (breachHearing.isPresent()) { + LOGGER.info("Found breachHearing {} for the application : {}", breachHearing.get().getHearingId(), applicationId); + return ofNullable(breachHearing.get().getHearingId()); + } + } + + LOGGER.warn("breachHearing Not found for the application : {}", applicationId); + + return Optional.empty(); + } + private Optional getFirstHearingId(final UUID caseId) { final Optional caseHearingsResponse = progressionService.getCaseHearings(caseId.toString()); @@ -685,7 +737,7 @@ public void courtApplicationSummonsRejected(final JsonEnvelope jsonEnvelope) { LOGGER.info("Processing event for court-application-summons-rejected with application id: {} - Link Type: {}", courtApplication.getId(), linkType); } - if (linkType == LinkType.FIRST_HEARING) { + if (linkType == FIRST_HEARING) { final PublicProgressionCourtApplicationSummonsRejected summonsRejectedPublicEventPayload = publicProgressionCourtApplicationSummonsRejected() .withId(courtApplication.getId()) .withProsecutionCaseId(courtApplicationSummonsRejected.getCaseIds().get(0)) @@ -943,25 +995,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 (isCivil(courtApplication)) { final CivilFees initialFees = CivilFees.civilFees() .withFeeType(FeeType.INITIAL) .withFeeId(randomUUID()) @@ -986,6 +1038,13 @@ private ProsecutionCase createProsecutionCase(final ProsecutionCase prosecutionC return prosecutionCase().withValuesFrom(prosecutionCase).withDefendants(defendantList).build(); } + private static boolean isCivil(final CourtApplication courtApplication) { + return ofNullable(courtApplication) + .map(CourtApplication::getCourtCivilApplication) + .map(CourtCivilApplication::getIsCivil) + .orElse(false); + } + private Defendant updatedDefendant(final Defendant defendant) { final Predicate offencePredicate = offence -> isNull(offence.getProceedingsConcluded()) || !offence.getProceedingsConcluded(); final List offences = defendant.getOffences().stream().filter(offencePredicate) 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 422a09f87..e5d473e4a 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 @@ -104,6 +104,8 @@ import uk.gov.justice.core.courts.SummonsType; import uk.gov.justice.core.courts.WeekCommencingDate; import uk.gov.justice.hearing.courts.Initiate; +import uk.gov.justice.progression.query.laa.HearingSummary; +import uk.gov.justice.progression.query.laa.HearingType; import uk.gov.justice.services.common.converter.JsonObjectToObjectConverter; import uk.gov.justice.services.common.converter.ObjectToJsonObjectConverter; import uk.gov.justice.services.common.converter.StringToJsonObjectConverter; @@ -888,6 +890,111 @@ public void courtApplicationSummonsApproved_whenSummonsAmended_andHearingsArrayE verify(sender, never()).send(any()); } + @Test + public void courtApplicationSummonsApproved_withLinkedLinkType_whenSummonsAmended_andBreachHearingFound_shouldSendAmendSummonsDataCommand() { + final UUID applicationId = randomUUID(); + final UUID prosecutionCaseId = randomUUID(); + final UUID breachHearingId = randomUUID(); + + final CourtApplicationSummonsApproved courtApplicationSummonsApproved = courtApplicationSummonsApproved() + .withApplicationId(applicationId) + .withLinkType(LinkType.LINKED) + .withCaseIds(singletonList(prosecutionCaseId)) + .withIsSummonsAmended(true) + .withSummonsApprovedOutcome(summonsApprovedOutcome() + .withSummonsSuppressed(false) + .withPersonalService(false) + .withProsecutorCost("£100.00") + .withProsecutorEmailAddress("test@test.com") + .build()) + .build(); + + final HearingType breachHearingType = HearingType.hearingType() + .withId(UUID.fromString("136dfc3a-a874-32ce-8493-e50849590b49")) + .build(); + final HearingSummary breachHearingSummary = HearingSummary.hearingSummary() + .withHearingId(breachHearingId) + .withHearingType(breachHearingType) + .build(); + + when(progressionService.getHearingsForApplication(applicationId)) + .thenReturn(Optional.of(singletonList(breachHearingSummary))); + + final JsonObject payload = objectToJsonObjectConverter.convert(courtApplicationSummonsApproved); + final MetadataBuilder metadataBuilder = getMetadata("progression.event.court-application-summons-approved"); + final JsonEnvelope event = envelopeFrom(metadataBuilder, payload); + + courtApplicationProcessor.courtApplicationSummonsApproved(event); + + final ArgumentCaptor captor = forClass(Envelope.class); + verify(sender).send(captor.capture()); + assertThat(captor.getValue().metadata().name(), is("progression.command.amend-summons-data")); + } + + @Test + public void courtApplicationSummonsApproved_withLinkedLinkType_whenSummonsAmended_andNoBreachHearingFound_shouldNotSendAnyCommand() { + final UUID applicationId = randomUUID(); + final UUID prosecutionCaseId = randomUUID(); + + final CourtApplicationSummonsApproved courtApplicationSummonsApproved = courtApplicationSummonsApproved() + .withApplicationId(applicationId) + .withLinkType(LinkType.LINKED) + .withCaseIds(singletonList(prosecutionCaseId)) + .withIsSummonsAmended(true) + .withSummonsApprovedOutcome(summonsApprovedOutcome() + .withSummonsSuppressed(false) + .withPersonalService(false) + .build()) + .build(); + + final HearingType nonBreachHearingType = HearingType.hearingType() + .withId(randomUUID()) + .build(); + final HearingSummary nonBreachHearingSummary = HearingSummary.hearingSummary() + .withHearingId(randomUUID()) + .withHearingType(nonBreachHearingType) + .build(); + + when(progressionService.getHearingsForApplication(applicationId)) + .thenReturn(Optional.of(singletonList(nonBreachHearingSummary))); + + final JsonObject payload = objectToJsonObjectConverter.convert(courtApplicationSummonsApproved); + final MetadataBuilder metadataBuilder = getMetadata("progression.event.court-application-summons-approved"); + final JsonEnvelope event = envelopeFrom(metadataBuilder, payload); + + courtApplicationProcessor.courtApplicationSummonsApproved(event); + + verify(sender, never()).send(any()); + } + + @Test + public void courtApplicationSummonsApproved_withLinkedLinkType_whenSummonsAmended_andNoHearingsForApplication_shouldNotSendAnyCommand() { + final UUID applicationId = randomUUID(); + final UUID prosecutionCaseId = randomUUID(); + + final CourtApplicationSummonsApproved courtApplicationSummonsApproved = courtApplicationSummonsApproved() + .withApplicationId(applicationId) + .withLinkType(LinkType.LINKED) + .withCaseIds(singletonList(prosecutionCaseId)) + .withIsSummonsAmended(true) + .withSummonsApprovedOutcome(summonsApprovedOutcome() + .withSummonsSuppressed(false) + .withPersonalService(false) + .build()) + .build(); + + when(progressionService.getHearingsForApplication(applicationId)) + .thenReturn(Optional.empty()); + + final JsonObject payload = objectToJsonObjectConverter.convert(courtApplicationSummonsApproved); + final MetadataBuilder metadataBuilder = getMetadata("progression.event.court-application-summons-approved"); + final JsonEnvelope event = envelopeFrom(metadataBuilder, payload); + + courtApplicationProcessor.courtApplicationSummonsApproved(event); + + verify(sender, never()).send(any()); + } + @Test public void courtApplicationSummonsRejected_withLinkedLinkType_shouldNotSendPublicEventButShouldNotify() { final UUID applicationId = randomUUID();