diff --git a/projects/manage-pom-cases-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt b/projects/manage-pom-cases-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt index f4afd04742..da83a70576 100644 --- a/projects/manage-pom-cases-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt +++ b/projects/manage-pom-cases-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt @@ -89,8 +89,8 @@ class DataLoader( ) districtRepository.save(ProviderGenerator.DEFAULT_DISTRICT) - teamRepository.saveAll(PersonManagerGenerator.ALL.map { it.team } + ProviderGenerator.POM_TEAM) - val staffMap = staffRepository.saveAll(PersonManagerGenerator.ALL.map { it.staff }).associateBy { it.code } + teamRepository.saveAll(PersonManagerGenerator.ALL.map { it.team } + ProviderGenerator.POM_TEAM + ProviderGenerator.UNALLOCATED_TEAM) + val staffMap = staffRepository.saveAll(PersonManagerGenerator.ALL.map { it.staff } + ProviderGenerator.UNALLOCATED_STAFF).associateBy { it.code } UserGenerator.DEFAULT_STAFF_USER = staffUserRepository.save( StaffUser( UserGenerator.DEFAULT_STAFF_USER.username, diff --git a/projects/manage-pom-cases-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ProviderGenerator.kt b/projects/manage-pom-cases-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ProviderGenerator.kt index a9dfea3fc5..5df1e388b7 100644 --- a/projects/manage-pom-cases-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ProviderGenerator.kt +++ b/projects/manage-pom-cases-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ProviderGenerator.kt @@ -15,7 +15,9 @@ object ProviderGenerator { val DEFAULT_DISTRICT = generateDistrict("N03LDU1") val DEFAULT_TEAM = generateTeam("N03DEF", district = DEFAULT_DISTRICT) val POM_TEAM = generateTeam("N03POM", district = DEFAULT_DISTRICT) + val UNALLOCATED_TEAM = generateTeam("N03ALL", district = DEFAULT_DISTRICT) val DEFAULT_STAFF = generateStaff("N03DEF0", "Default", "Staff", user = UserGenerator.DEFAULT_STAFF_USER) + val UNALLOCATED_STAFF = generateStaff("N03ALLU", "Unallocated", "Staff") fun generateProvider(providerCode: String, prisonCode: String?, id: Long = IdGenerator.getAndIncrement()) = ProbationArea( diff --git a/projects/manage-pom-cases-and-delius/src/dev/resources/messages/deallocation.json b/projects/manage-pom-cases-and-delius/src/dev/resources/messages/deallocation.json new file mode 100644 index 0000000000..e772b0bfb8 --- /dev/null +++ b/projects/manage-pom-cases-and-delius/src/dev/resources/messages/deallocation.json @@ -0,0 +1,13 @@ +{ + "Type": "Notification", + "MessageId": "63ba0b4b-340e-4853-b343-6429965a3961", + "TopicArn": "arn:aws:sns:eu-west-2:000000000000:domain-event", + "Message": "{\"eventType\":\"offender-management.allocation.changed\",\"detailUrl\":\"http://localhost:{wiremock.port}/api/pom-allocation/A0123BY/3\",\"occurredAt\":\"2023-10-10T14:25:19.102Z\",\"personReference\":{\"identifiers\":[{\"type\":\"NOMS\",\"value\":\"A0123BY\"}]}}", + "Timestamp": "2023-10-10T14:25:20.000Z", + "MessageAttributes": { + "eventType": { + "Type": "String", + "Value": "offender-management.allocation.changed" + } + } +} \ No newline at end of file diff --git a/projects/manage-pom-cases-and-delius/src/dev/resources/messages/not-yet-allocation.json b/projects/manage-pom-cases-and-delius/src/dev/resources/messages/not-yet-allocation.json new file mode 100644 index 0000000000..e30ecd2ce2 --- /dev/null +++ b/projects/manage-pom-cases-and-delius/src/dev/resources/messages/not-yet-allocation.json @@ -0,0 +1,13 @@ +{ + "Type": "Notification", + "MessageId": "63ba0b4b-340e-4853-b343-6429965a3961", + "TopicArn": "arn:aws:sns:eu-west-2:000000000000:domain-event", + "Message": "{\"eventType\":\"offender-management.allocation.changed\",\"detailUrl\":\"http://localhost:{wiremock.port}/api/pom-allocation/A0123BY/0\",\"occurredAt\":\"2023-05-09T13:25:19.102Z\",\"personReference\":{\"identifiers\":[{\"type\":\"NOMS\",\"value\":\"A0123BY\"}]}}", + "Timestamp": "2023-05-09T13:25:20.000Z", + "MessageAttributes": { + "eventType": { + "Type": "String", + "Value": "offender-management.allocation.changed" + } + } +} \ No newline at end of file diff --git a/projects/manage-pom-cases-and-delius/src/dev/resources/simulations/__files/deallocation.json b/projects/manage-pom-cases-and-delius/src/dev/resources/simulations/__files/deallocation.json new file mode 100644 index 0000000000..1d0ec6b22c --- /dev/null +++ b/projects/manage-pom-cases-and-delius/src/dev/resources/simulations/__files/deallocation.json @@ -0,0 +1,4 @@ +{ + "status": "error", + "message": "Not allocated" +} \ No newline at end of file diff --git a/projects/manage-pom-cases-and-delius/src/dev/resources/simulations/__files/not-yet-allocation.json b/projects/manage-pom-cases-and-delius/src/dev/resources/simulations/__files/not-yet-allocation.json new file mode 100644 index 0000000000..8bb56fe8f2 --- /dev/null +++ b/projects/manage-pom-cases-and-delius/src/dev/resources/simulations/__files/not-yet-allocation.json @@ -0,0 +1,4 @@ +{ + "status": "error", + "message": "Not ready for allocation" +} \ No newline at end of file diff --git a/projects/manage-pom-cases-and-delius/src/dev/resources/simulations/mappings/manage-pom-cases-api.json b/projects/manage-pom-cases-and-delius/src/dev/resources/simulations/mappings/manage-pom-cases-api.json index 4d567beb1b..1e771fab1e 100644 --- a/projects/manage-pom-cases-and-delius/src/dev/resources/simulations/mappings/manage-pom-cases-api.json +++ b/projects/manage-pom-cases-and-delius/src/dev/resources/simulations/mappings/manage-pom-cases-api.json @@ -39,6 +39,19 @@ "bodyFileName": "create-handover-and-start-date.json" } }, + { + "request": { + "method": "GET", + "url": "/api/pom-allocation/A0123BY/0" + }, + "response": { + "headers": { + "Content-Type": "application/json" + }, + "status": 404, + "bodyFileName": "not-yet-allocation.json" + } + }, { "request": { "method": "GET", @@ -64,6 +77,19 @@ "status": 200, "bodyFileName": "pom-reallocated.json" } + }, + { + "request": { + "method": "GET", + "url": "/api/pom-allocation/A0123BY/3" + }, + "response": { + "headers": { + "Content-Type": "application/json" + }, + "status": 404, + "bodyFileName": "deallocation.json" + } } ] } \ No newline at end of file diff --git a/projects/manage-pom-cases-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AllocationMessagingIntegrationTest.kt b/projects/manage-pom-cases-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AllocationMessagingIntegrationTest.kt index 45a5d66030..758167aeae 100644 --- a/projects/manage-pom-cases-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AllocationMessagingIntegrationTest.kt +++ b/projects/manage-pom-cases-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AllocationMessagingIntegrationTest.kt @@ -10,7 +10,9 @@ import org.junit.jupiter.api.MethodOrderer import org.junit.jupiter.api.Order import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestMethodOrder +import org.mockito.kotlin.any import org.mockito.kotlin.argumentCaptor +import org.mockito.kotlin.never import org.mockito.kotlin.verify import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Value @@ -18,6 +20,7 @@ import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.mock.mockito.MockBean import org.springframework.boot.test.mock.mockito.SpyBean import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator +import uk.gov.justice.digital.hmpps.data.generator.ProviderGenerator import uk.gov.justice.digital.hmpps.integrations.delius.contact.entity.ContactRepository import uk.gov.justice.digital.hmpps.integrations.delius.contact.entity.ContactType import uk.gov.justice.digital.hmpps.integrations.delius.provider.entity.PrisonManagerRepository @@ -27,7 +30,6 @@ import uk.gov.justice.digital.hmpps.integrations.delius.provider.entity.StaffRep import uk.gov.justice.digital.hmpps.messaging.HmppsChannelManager import uk.gov.justice.digital.hmpps.resourceloader.ResourceLoader.notification import uk.gov.justice.digital.hmpps.telemetry.TelemetryService -import java.time.Duration import java.time.ZonedDateTime import kotlin.jvm.optionals.getOrNull @@ -49,7 +51,7 @@ internal class AllocationMessagingIntegrationTest { @SpyBean lateinit var staffRepository: StaffRepository - @Autowired + @SpyBean lateinit var prisonManagerRepository: PrisonManagerRepository @Autowired @@ -57,6 +59,26 @@ internal class AllocationMessagingIntegrationTest { @Order(1) @Test + fun `no change if not yet ready to allocate`() { + val notification = prepNotification( + notification("not-yet-allocation"), + wireMockServer.port() + ) + + channelManager.getChannel(queueName).publishAndWait(notification) + + verify(prisonManagerRepository, never()).save(any()) + verify(telemetryService).trackEvent( + "NotReadyToAllocate", + mapOf( + "nomsId" to "A0123BY", + "allocationDate" to "09/05/2023 14:25:19" + ) + ) + } + + @Order(2) + @Test fun `allocate first POM successfully`() { val notification = prepNotification( notification("new-allocation"), @@ -80,16 +102,16 @@ internal class AllocationMessagingIntegrationTest { assertThat(contacts.map { it.type.code }, hasItems(ContactType.Code.POM_AUTO_ALLOCATION.value)) verify(telemetryService).trackEvent( - "POM Allocated", + "PomAllocated", mapOf( "prisonId" to "SWI", "nomsId" to "A0123BY", - "allocationDate" to "2023-05-09" + "allocationDate" to "09/05/2023 14:25:19" ) ) } - @Order(2) + @Order(3) @Test fun `reallocate POM successfully`() { // add RO to existing pom to test RO behaviour @@ -104,7 +126,7 @@ internal class AllocationMessagingIntegrationTest { wireMockServer.port() ) - channelManager.getChannel(queueName).publishAndWait(notification, Duration.ofSeconds(180)) + channelManager.getChannel(queueName).publishAndWait(notification) val captor = argumentCaptor() verify(staffRepository).save(captor.capture()) @@ -133,11 +155,53 @@ internal class AllocationMessagingIntegrationTest { ) verify(telemetryService).trackEvent( - "POM Allocated", + "PomAllocated", mapOf( "prisonId" to "SWI", "nomsId" to "A0123BY", - "allocationDate" to "2023-10-09" + "allocationDate" to "09/10/2023 14:25:19" + ) + ) + } + + @Order(4) + @Test + fun `deallocate POM successfully`() { + val existingPom = prisonManagerRepository.findActiveManagerAtDate(PersonGenerator.DEFAULT.id, ZonedDateTime.now())!! + + val notification = prepNotification( + notification("deallocation"), + wireMockServer.port() + ) + + channelManager.getChannel(queueName).publishAndWait(notification) + + verify(staffRepository, never()).save(any()) + + val prisonManager = prisonManagerRepository.findActiveManagerAtDate(PersonGenerator.DEFAULT.id, ZonedDateTime.now()) + assertThat(prisonManager?.allocationReason?.code, equalTo("AUT")) + assertThat(prisonManager?.staff?.code, equalTo(ProviderGenerator.UNALLOCATED_STAFF.code)) + assertThat(prisonManager?.staff?.forename, equalTo(ProviderGenerator.UNALLOCATED_STAFF.forename)) + assertThat(prisonManager?.staff?.surname, equalTo(ProviderGenerator.UNALLOCATED_STAFF.surname)) + + val previousPom = prisonManagerRepository.findById(existingPom.id).getOrNull() + assertNotNull(previousPom?.endDate) + assertNotNull(previousPom?.responsibleOfficer?.endDate) + + val contacts = contactRepository.findAll().filter { it.personId == PersonGenerator.DEFAULT.id } + assertThat( + contacts.map { it.type.code }, + hasItems( + ContactType.Code.POM_AUTO_ALLOCATION.value, + ContactType.Code.RESPONSIBLE_OFFICER_CHANGE.value + ) + ) + + verify(telemetryService).trackEvent( + "PomDeallocated", + mapOf( + "nomsId" to "A0123BY", + "allocationDate" to "10/10/2023 15:25:19" ) ) } diff --git a/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/exception/Feign404Decoder.kt b/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/exception/Feign404Decoder.kt new file mode 100644 index 0000000000..f8a1bfa0b0 --- /dev/null +++ b/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/exception/Feign404Decoder.kt @@ -0,0 +1,32 @@ +package uk.gov.justice.digital.hmpps.exception + +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue +import feign.FeignException.errorStatus +import feign.Response +import feign.codec.ErrorDecoder +import org.springframework.stereotype.Component +import java.lang.Exception + +@Component +class Feign404Decoder(private val objectMapper: ObjectMapper) : ErrorDecoder { + override fun decode(methodKey: String?, response: Response): Exception? { + return response.body().asInputStream()?.use { ins -> + objectMapper.readValue(ins).message?.let { + NotAllocatedException( + when (it) { + "Not allocated" -> NotAllocatedException.Reason.DEALLOCATED + else -> NotAllocatedException.Reason.PRE_ALLOCATION + } + ) + } ?: errorStatus(methodKey, response) + } + } +} + +data class ErrorResponse(val message: String?) +class NotAllocatedException(val reason: Reason) : Exception("POM Not Allocated: $reason") { + enum class Reason { + DEALLOCATED, PRE_ALLOCATION + } +} diff --git a/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/provider/entity/PrisonManager.kt b/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/provider/entity/PrisonManager.kt index b08a946ba6..7c1acbf2eb 100644 --- a/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/provider/entity/PrisonManager.kt +++ b/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/provider/entity/PrisonManager.kt @@ -98,6 +98,8 @@ class PrisonManager( @Column(nullable = false) var lastUpdatedDatetime: ZonedDateTime = ZonedDateTime.now() + fun isUnallocated() = staff.code.endsWith("U") + enum class AllocationReasonCode(val value: String, val ctc: ContactType.Code) { AUTO("AUT", ContactType.Code.POM_AUTO_ALLOCATION), INTERNAL("INA", ContactType.Code.POM_INTERNAL_ALLOCATION), diff --git a/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/provider/entity/StaffRepository.kt b/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/provider/entity/StaffRepository.kt index 987df7b473..20fa5a981f 100644 --- a/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/provider/entity/StaffRepository.kt +++ b/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/provider/entity/StaffRepository.kt @@ -2,6 +2,7 @@ package uk.gov.justice.digital.hmpps.integrations.delius.provider.entity import org.springframework.data.jpa.repository.JpaRepository import org.springframework.data.jpa.repository.Query +import uk.gov.justice.digital.hmpps.exception.NotFoundException interface StaffRepository : JpaRepository { fun findTopByProbationAreaIdAndForenameIgnoreCaseAndSurnameIgnoreCase( @@ -20,4 +21,9 @@ interface StaffRepository : JpaRepository { nativeQuery = true ) fun getLatestStaffReference(regex: String): String? + + fun findByCode(code: String): Staff? } + +fun StaffRepository.getByCode(code: String) = + findByCode(code) ?: throw NotFoundException("Staff", "code", code) diff --git a/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/provider/entity/Team.kt b/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/provider/entity/Team.kt index b1e5b2f927..257fd0124c 100644 --- a/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/provider/entity/Team.kt +++ b/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/provider/entity/Team.kt @@ -32,6 +32,7 @@ class Team( ) { companion object { val POM_SUFFIX = "POM" + val UNALLOCATED_SUFFIX = "ALL" } } diff --git a/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/managepomcases/ManagePomCasesClient.kt b/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/managepomcases/ManagePomCasesClient.kt index cf626566c7..9659f205b4 100644 --- a/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/managepomcases/ManagePomCasesClient.kt +++ b/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/managepomcases/ManagePomCasesClient.kt @@ -22,10 +22,16 @@ data class Handover( @JsonAlias("handoverStartDate") val startDate: LocalDate? ) +sealed interface AllocationResponse + data class PomAllocation( val manager: Name, val prison: Prison -) +) : AllocationResponse + +data object PomDeallocated : AllocationResponse + +data object PomNotAllocated : AllocationResponse data class Prison( val code: String diff --git a/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/services/PomAllocated.kt b/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/services/PomAllocated.kt index df799c3e7f..821fc2d6ac 100644 --- a/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/services/PomAllocated.kt +++ b/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/services/PomAllocated.kt @@ -1,15 +1,18 @@ package uk.gov.justice.digital.hmpps.services import org.springframework.stereotype.Service +import uk.gov.justice.digital.hmpps.datetime.DeliusDateTimeFormatter +import uk.gov.justice.digital.hmpps.exception.NotAllocatedException import uk.gov.justice.digital.hmpps.integrations.delius.person.entity.PersonRepository import uk.gov.justice.digital.hmpps.integrations.managepomcases.ManagePomCasesClient import uk.gov.justice.digital.hmpps.integrations.managepomcases.PomAllocation +import uk.gov.justice.digital.hmpps.integrations.managepomcases.PomDeallocated +import uk.gov.justice.digital.hmpps.integrations.managepomcases.PomNotAllocated import uk.gov.justice.digital.hmpps.message.HmppsDomainEvent import uk.gov.justice.digital.hmpps.messaging.IgnorableMessageException import uk.gov.justice.digital.hmpps.telemetry.TelemetryService import java.net.URI import java.time.ZonedDateTime -import java.time.format.DateTimeFormatter @Service class PomAllocated( @@ -19,19 +22,41 @@ class PomAllocated( private val telemetryService: TelemetryService ) { fun process(event: HmppsDomainEvent) = try { - val pomAllocation = event.detailUrl?.let { pomCasesClient.getPomAllocation(URI.create(it)) } - ?: throw IgnorableMessageException( - "No POM Allocation data available", - mapOf("detailUrl" to event.detailUrl.orNotProvided()) - ) + val pomAllocation = try { + event.detailUrl?.let { pomCasesClient.getPomAllocation(URI.create(it)) } + ?: throw IgnorableMessageException( + "No POM Allocation data available", + mapOf("detailUrl" to event.detailUrl.orNotProvided()) + ) + } catch (e: Exception) { + when (val nae = e.cause) { + is NotAllocatedException -> when (nae.reason) { + NotAllocatedException.Reason.DEALLOCATED -> PomDeallocated + else -> PomNotAllocated + } + else -> throw e + } + } val nomsId = event.personReference.findNomsNumber() - val personId = nomsId?.let { personRepository.findIdFromNomsId(it) } ?: throw IgnorableMessageException("PersonNotFound") - prisonManagerService.allocatePrisonManager(personId, event.occurredAt, pomAllocation) - telemetryService.trackEvent("POM Allocated", pomAllocation.properties(nomsId, event.occurredAt)) + when (pomAllocation) { + is PomAllocation -> { + prisonManagerService.allocatePrisonManager(personId, event.occurredAt, pomAllocation) + telemetryService.trackEvent("PomAllocated", pomAllocation.properties(nomsId, event.occurredAt)) + } + + is PomDeallocated -> { + prisonManagerService.deallocatePrisonManager(personId, event.occurredAt) + telemetryService.trackEvent("PomDeallocated", event.properties()) + } + + else -> { + telemetryService.trackEvent("NotReadyToAllocate", event.properties()) + } + } } catch (ime: IgnorableMessageException) { telemetryService.trackEvent( ime.message, @@ -44,6 +69,11 @@ class PomAllocated( fun PomAllocation.properties(nomsId: String?, allocationDate: ZonedDateTime) = listOfNotNull( "prisonId" to prison.code, "nomsId" to nomsId.orNotProvided(), - "allocationDate" to allocationDate.format(DateTimeFormatter.ISO_LOCAL_DATE) + "allocationDate" to DeliusDateTimeFormatter.format(allocationDate) ).toMap() + + fun HmppsDomainEvent.properties() = mapOf( + "nomsId" to personReference.findNomsNumber().orNotProvided(), + "allocationDate" to DeliusDateTimeFormatter.format(occurredAt) + ) } diff --git a/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/services/PrisonManagerService.kt b/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/services/PrisonManagerService.kt index 1c12cbc7d2..a16a7a389e 100644 --- a/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/services/PrisonManagerService.kt +++ b/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/services/PrisonManagerService.kt @@ -45,6 +45,19 @@ class PrisonManagerService( } } + @Transactional + fun deallocatePrisonManager(personId: Long, deallocationDate: ZonedDateTime) { + val currentPom = prisonManagerRepository.findActiveManagerAtDate(personId, deallocationDate) + if (currentPom?.isUnallocated() == false) { + val probationArea = currentPom.probationArea + val team = teamRepository.getByCode(probationArea.code + Team.UNALLOCATED_SUFFIX) + val staff = staffService.getStaffByCode(team.code + "U") + val newPom = currentPom.changeTo(personId, deallocationDate, probationArea, team, staff) + prisonManagerRepository.saveAndFlush(currentPom) + newPom?.let { prisonManagerRepository.save(it) } + } + } + private fun getStaff( probationArea: ProbationArea, team: Team, @@ -91,7 +104,7 @@ class PrisonManagerService( ) = if (this?.hasChanged(probationArea, team, staff) != false) { val allocationReasonCode = when { - this == null -> PrisonManager.AllocationReasonCode.AUTO + this == null || staff.isUnallocated() -> PrisonManager.AllocationReasonCode.AUTO this.probationArea.id == probationArea.id -> PrisonManager.AllocationReasonCode.INTERNAL else -> PrisonManager.AllocationReasonCode.EXTERNAL } diff --git a/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/services/StaffService.kt b/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/services/StaffService.kt index b2f047ef64..6e6607c57d 100644 --- a/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/services/StaffService.kt +++ b/projects/manage-pom-cases-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/services/StaffService.kt @@ -11,6 +11,7 @@ import uk.gov.justice.digital.hmpps.integrations.delius.provider.entity.StaffRep import uk.gov.justice.digital.hmpps.integrations.delius.provider.entity.StaffTeam import uk.gov.justice.digital.hmpps.integrations.delius.provider.entity.StaffTeamRepository import uk.gov.justice.digital.hmpps.integrations.delius.provider.entity.Team +import uk.gov.justice.digital.hmpps.integrations.delius.provider.entity.getByCode import java.time.ZonedDateTime @Service @@ -48,4 +49,6 @@ class StaffService( staffName.forename, staffName.surname ) + + fun getStaffByCode(code: String) = staffRepository.getByCode(code) }