From cf86a62eb5748b30a7af0c2200dec58c7598744b Mon Sep 17 00:00:00 2001 From: Anthony Britton <105213050+anthony-britton-moj@users.noreply.github.com> Date: Thu, 19 Oct 2023 12:31:35 +0100 Subject: [PATCH] PI-1573 add ECSL Release behind feature flag (#2410) --- .../justice/digital/hmpps/data/DataLoader.kt | 6 +++ .../data/generator/NotificationGenerator.kt | 1 + .../hmpps/data/generator/PersonGenerator.kt | 1 + .../messages/prisoner-released-ecsl.json | 17 ++++++++ .../digital/hmpps/PcstdIntegrationTest.kt | 40 ++++++++++++++++++- .../digital/hmpps/PcstdIntegrationTestBase.kt | 4 +- .../wellknown/ReleaseTypeCode.kt | 3 +- .../hmpps/messaging/actions/ReleaseAction.kt | 12 ++++-- .../application-prisoner-movement.yml | 9 +++++ 9 files changed, 85 insertions(+), 8 deletions(-) create mode 100644 projects/prison-custody-status-to-delius/src/dev/resources/messages/prisoner-released-ecsl.json diff --git a/projects/prison-custody-status-to-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt b/projects/prison-custody-status-to-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt index 3627d59d39..e9cd76029d 100644 --- a/projects/prison-custody-status-to-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt +++ b/projects/prison-custody-status-to-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt @@ -94,6 +94,7 @@ class DataLoader( createTemporaryAbsenceReturnFromRotl() createIrcReleased() createIrcInCustody() + createReleasableEcslPerson() } private fun createReferenceData() { @@ -153,6 +154,11 @@ class DataLoader( createEvent(EventGenerator.custodialEvent(PersonGenerator.RELEASABLE, InstitutionGenerator.DEFAULT)) } + private fun createReleasableEcslPerson() { + createPerson(PersonGenerator.RELEASABLE_ECSL) + createEvent(EventGenerator.custodialEvent(PersonGenerator.RELEASABLE_ECSL, InstitutionGenerator.DEFAULT)) + } + private fun createRecallablePerson() { createPerson(PersonGenerator.RECALLABLE) val event = EventGenerator.previouslyReleasedEvent( diff --git a/projects/prison-custody-status-to-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/NotificationGenerator.kt b/projects/prison-custody-status-to-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/NotificationGenerator.kt index ce8cfa6522..18ee88e19c 100644 --- a/projects/prison-custody-status-to-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/NotificationGenerator.kt +++ b/projects/prison-custody-status-to-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/NotificationGenerator.kt @@ -15,4 +15,5 @@ object NotificationGenerator { val PRISONER_ROTL_RETURN = ResourceLoader.notification("prisoner-received-rotl") val PRISONER_IRC_RELEASED = ResourceLoader.notification("prisoner-received-irc-released") val PRISONER_IRC_IN_CUSTODY = ResourceLoader.notification("prisoner-received-irc-custody") + val PRISONER_RELEASED_ECSL = ResourceLoader.notification("prisoner-released-ecsl") } diff --git a/projects/prison-custody-status-to-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/PersonGenerator.kt b/projects/prison-custody-status-to-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/PersonGenerator.kt index 79f97c6993..701751df66 100644 --- a/projects/prison-custody-status-to-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/PersonGenerator.kt +++ b/projects/prison-custody-status-to-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/PersonGenerator.kt @@ -15,6 +15,7 @@ object PersonGenerator { val ROTL = generate(NotificationGenerator.PRISONER_ROTL_RETURN.nomsId()) val IRC_RELEASED = generate(NotificationGenerator.PRISONER_IRC_RELEASED.nomsId()) val IRC_IN_CUSTODY = generate(NotificationGenerator.PRISONER_IRC_IN_CUSTODY.nomsId()) + val RELEASABLE_ECSL = generate(NotificationGenerator.PRISONER_RELEASED_ECSL.nomsId()) fun generate(nomsNumber: String, id: Long = IdGenerator.getAndIncrement()) = Person(id, nomsNumber) } diff --git a/projects/prison-custody-status-to-delius/src/dev/resources/messages/prisoner-released-ecsl.json b/projects/prison-custody-status-to-delius/src/dev/resources/messages/prisoner-released-ecsl.json new file mode 100644 index 0000000000..83b07483e7 --- /dev/null +++ b/projects/prison-custody-status-to-delius/src/dev/resources/messages/prisoner-released-ecsl.json @@ -0,0 +1,17 @@ +{ + "Type": "Notification", + "MessageId": "682dd2a4-c193-461c-a8e9-cc976a961aa5", + "TopicArn": "", + "Message": "{\"eventType\":\"prison-offender-events.prisoner.released\",\"additionalInformation\":{\"nomsNumber\":\"A0013AA\",\"reason\":\"RELEASED\",\"details\":\"Movement reason code ECSL\",\"nomisMovementReasonCode\":\"ECSL\",\"currentLocation\":\"OUTSIDE_PRISON\",\"prisonId\":\"WSI\",\"currentPrisonStatus\":\"NOT_UNDER_PRISON_CARE\"},\"version\":1,\"occurredAt\":\"2022-05-04T07:03:50.912169+01:00\",\"publishedAt\":\"2022-05-04T08:00:33.477735848+01:00\",\"description\":\"A prisoner has been released from prison\",\"personReference\":{\"identifiers\":[{\"type\":\"NOMS\",\"value\":\"A0013AA\"}]}}", + "Timestamp": "2022-05-04T07:00:33.487Z", + "SignatureVersion": "1", + "Signature": "", + "SigningCertURL": "", + "UnsubscribeURL": "", + "MessageAttributes": { + "eventType": { + "Type": "String", + "Value": "prison-offender-events.prisoner.released" + } + } +} \ No newline at end of file diff --git a/projects/prison-custody-status-to-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/PcstdIntegrationTest.kt b/projects/prison-custody-status-to-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/PcstdIntegrationTest.kt index 2f6ebd9e8a..9d3acaf0b1 100644 --- a/projects/prison-custody-status-to-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/PcstdIntegrationTest.kt +++ b/projects/prison-custody-status-to-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/PcstdIntegrationTest.kt @@ -18,6 +18,7 @@ import uk.gov.justice.digital.hmpps.integrations.delius.recall.entity.RecallReas import uk.gov.justice.digital.hmpps.integrations.delius.referencedata.wellknown.CustodialStatusCode import uk.gov.justice.digital.hmpps.integrations.delius.referencedata.wellknown.CustodyEventTypeCode import uk.gov.justice.digital.hmpps.integrations.delius.referencedata.wellknown.InstitutionCode +import uk.gov.justice.digital.hmpps.integrations.delius.referencedata.wellknown.ReleaseTypeCode import uk.gov.justice.digital.hmpps.test.CustomMatchers.isCloseTo import java.time.ZonedDateTime @@ -33,7 +34,7 @@ class PcstdIntegrationTest : PcstdIntegrationTestBase() { val custody = getCustody(nomsNumber) assertFalse(custody.isInCustody()) - verifyRelease(custody, notification.message.occurredAt) + verifyRelease(custody, notification.message.occurredAt, ReleaseTypeCode.ADULT_LICENCE) verifyCustodyHistory( custody, @@ -440,4 +441,41 @@ class PcstdIntegrationTest : PcstdIntegrationTestBase() { ) } } + + @Test + fun `release a ecsl prisoner`() { + whenever(featureFlags.enabled("messages_released_ecsl")).thenReturn(true) + val notification = NotificationGenerator.PRISONER_RELEASED_ECSL + val nomsNumber = notification.nomsId() + assertTrue(getCustody(nomsNumber).isInCustody()) + + channelManager.getChannel(queueName).publishAndWait(notification) + + val custody = getCustody(nomsNumber) + assertFalse(custody.isInCustody()) + + verifyRelease(custody, notification.message.occurredAt, ReleaseTypeCode.END_CUSTODY_SUPERVISED_LICENCE) + + verifyCustodyHistory( + custody, + CustodyEventTester(CustodyEventTypeCode.STATUS_CHANGE, "Released on Licence"), + CustodyEventTester( + CustodyEventTypeCode.LOCATION_CHANGE, + InstitutionGenerator.STANDARD_INSTITUTIONS[InstitutionCode.IN_COMMUNITY]?.description + ) + ) + + verifyContact(custody, ContactType.Code.RELEASE_FROM_CUSTODY) + + verifyTelemetry("Released", "LocationUpdated", "StatusUpdated") { + mapOf( + "occurredAt" to notification.message.occurredAt.toString(), + "nomsNumber" to "A0013AA", + "institution" to "WSI", + "reason" to "RELEASED", + "movementReason" to "ECSL", + "movementType" to "Released" + ) + } + } } diff --git a/projects/prison-custody-status-to-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/PcstdIntegrationTestBase.kt b/projects/prison-custody-status-to-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/PcstdIntegrationTestBase.kt index 5104228ef8..0bfaf17ba4 100644 --- a/projects/prison-custody-status-to-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/PcstdIntegrationTestBase.kt +++ b/projects/prison-custody-status-to-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/PcstdIntegrationTestBase.kt @@ -99,13 +99,13 @@ open class PcstdIntegrationTestBase { internal fun getPrisonManagers(nomsNumber: String) = prisonManagerRepository.findAll().filter { it.personId == getPersonId(nomsNumber) } - internal fun verifyRelease(custody: Custody, dateTime: ZonedDateTime) { + internal fun verifyRelease(custody: Custody, dateTime: ZonedDateTime, releaseType: ReleaseTypeCode) { val release = getReleases(custody).single() assertThat( release.date.withZoneSameInstant(EuropeLondon), equalTo(dateTime.truncatedTo(ChronoUnit.DAYS)) ) - assertThat(release.type.code, equalTo(ReleaseTypeCode.ADULT_LICENCE.code)) + assertThat(release.type.code, equalTo(releaseType.code)) } internal fun verifyRecall(custody: Custody, dateTime: ZonedDateTime, rrc: RecallReason.Code) { diff --git a/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/referencedata/wellknown/ReleaseTypeCode.kt b/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/referencedata/wellknown/ReleaseTypeCode.kt index 656e35ca0b..c68633948e 100644 --- a/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/referencedata/wellknown/ReleaseTypeCode.kt +++ b/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/referencedata/wellknown/ReleaseTypeCode.kt @@ -1,5 +1,6 @@ package uk.gov.justice.digital.hmpps.integrations.delius.referencedata.wellknown enum class ReleaseTypeCode(val code: String) { - ADULT_LICENCE("ADL") + ADULT_LICENCE("ADL"), + END_CUSTODY_SUPERVISED_LICENCE("ECSL") } diff --git a/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/actions/ReleaseAction.kt b/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/actions/ReleaseAction.kt index c20c7c17da..b625f58cd2 100644 --- a/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/actions/ReleaseAction.kt +++ b/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/actions/ReleaseAction.kt @@ -100,8 +100,12 @@ private fun PrisonerMovement.occurredBefore(sentenceDate: ZonedDateTime, recalle return occurredAt.isBefore(sentenceDate) || recalledDateTime?.let { occurredAt.isBefore(it) } ?: false } -private fun PrisonerMovement.releaseType(): ReleaseTypeCode = - when (type) { - PrisonerMovement.Type.RELEASED -> ReleaseTypeCode.ADULT_LICENCE - else -> throw IgnorableMessageException("UnsupportedReleaseType") +private fun PrisonerMovement.releaseType(): ReleaseTypeCode { + if (type != PrisonerMovement.Type.RELEASED) { + throw IgnorableMessageException("UnsupportedReleaseType") } + return when (reason) { + "ECSL" -> ReleaseTypeCode.END_CUSTODY_SUPERVISED_LICENCE + else -> ReleaseTypeCode.ADULT_LICENCE + } +} diff --git a/projects/prison-custody-status-to-delius/src/main/resources/application-prisoner-movement.yml b/projects/prison-custody-status-to-delius/src/main/resources/application-prisoner-movement.yml index 18b08a9d9e..d719b0a0ff 100644 --- a/projects/prison-custody-status-to-delius/src/main/resources/application-prisoner-movement.yml +++ b/projects/prison-custody-status-to-delius/src/main/resources/application-prisoner-movement.yml @@ -40,6 +40,15 @@ prisoner.movement.configs: - UpdateStatus - UpdateLocation featureFlag: messages_released_irc + - types: + - RELEASED + reasons: + - ECSL + actionNames: + - Release + - UpdateStatus + - UpdateLocation + featureFlag: messages_released_ecsl - types: - RELEASED actionNames: