Skip to content

Commit

Permalink
PI-1573 add ECSL Release behind feature flag (#2410)
Browse files Browse the repository at this point in the history
  • Loading branch information
anthony-britton-moj authored Oct 19, 2023
1 parent 13f15c0 commit cf86a62
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ class DataLoader(
createTemporaryAbsenceReturnFromRotl()
createIrcReleased()
createIrcInCustody()
createReleasableEcslPerson()
}

private fun createReferenceData() {
Expand Down Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ object NotificationGenerator {
val PRISONER_ROTL_RETURN = ResourceLoader.notification<HmppsDomainEvent>("prisoner-received-rotl")
val PRISONER_IRC_RELEASED = ResourceLoader.notification<HmppsDomainEvent>("prisoner-received-irc-released")
val PRISONER_IRC_IN_CUSTODY = ResourceLoader.notification<HmppsDomainEvent>("prisoner-received-irc-custody")
val PRISONER_RELEASED_ECSL = ResourceLoader.notification<HmppsDomainEvent>("prisoner-released-ecsl")
}
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Original file line number Diff line number Diff line change
@@ -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"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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,
Expand Down Expand Up @@ -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"
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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")
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down

0 comments on commit cf86a62

Please sign in to comment.