Skip to content

Commit

Permalink
Backfill case notes
Browse files Browse the repository at this point in the history
  • Loading branch information
anthony-britton-moj committed Jan 21, 2025
1 parent f9d6fe6 commit 33d54bb
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 123 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,13 @@ class CaseNotesIntegrationTest {

verify(telemetryService).trackEvent(
eq("CaseNotesMigrated"),
eq(mapOf("nomsId" to "A4578BX", "cause" to "probation-case.prison-identifier.added", "count" to "4")),
eq(
mapOf(
"nomsId" to "A4578BX",
"cause" to "probation-case.prison-identifier.added",
"total" to "4",
)
),
anyMap()
)
val saved = caseNoteRepository.findAll().filter { it.offenderId == offender.id }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,48 @@ import org.slf4j.LoggerFactory
import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import uk.gov.justice.digital.hmpps.audit.service.AuditableService
import uk.gov.justice.digital.hmpps.audit.service.AuditedInteractionService
import uk.gov.justice.digital.hmpps.audit.entity.AuditedInteraction
import uk.gov.justice.digital.hmpps.audit.entity.AuditedInteraction.Outcome.SUCCESS
import uk.gov.justice.digital.hmpps.audit.repository.AuditedInteractionRepository
import uk.gov.justice.digital.hmpps.audit.repository.BusinessInteractionRepository
import uk.gov.justice.digital.hmpps.audit.repository.getByCode
import uk.gov.justice.digital.hmpps.exceptions.OffenderNotFoundException
import uk.gov.justice.digital.hmpps.integrations.delius.audit.BusinessInteractionCode.CASE_NOTES_MERGE
import uk.gov.justice.digital.hmpps.integrations.delius.entity.CaseNote
import uk.gov.justice.digital.hmpps.integrations.delius.entity.CaseNoteType
import uk.gov.justice.digital.hmpps.integrations.delius.model.DeliusCaseNote
import uk.gov.justice.digital.hmpps.integrations.delius.repository.*
import uk.gov.justice.digital.hmpps.security.ServiceContext
import uk.gov.justice.digital.hmpps.service.AssignmentService
import java.time.ZonedDateTime
import java.time.temporal.ChronoUnit

@Service
class DeliusService(
auditedInteractionService: AuditedInteractionService,
private val businessInteractionRepository: BusinessInteractionRepository,
private val auditedInteractionRepository: AuditedInteractionRepository,
private val caseNoteRepository: CaseNoteRepository,
private val nomisTypeRepository: CaseNoteNomisTypeRepository,
private val caseNoteTypeRepository: CaseNoteTypeRepository,
private val offenderRepository: OffenderRepository,
private val assignmentService: AssignmentService,
private val relatedService: CaseNoteRelatedService
) : AuditableService(auditedInteractionService) {
) {
@Transactional
fun mergeCaseNote(@Valid caseNote: DeliusCaseNote) = audit(CASE_NOTES_MERGE) { audit ->
audit["nomisId"] = caseNote.header.legacyId
caseNote.header.uuid?.also { audit["dpsId"] = it }

fun mergeCaseNote(@Valid caseNote: DeliusCaseNote) {
val existing = caseNote.urn?.let { caseNoteRepository.findByExternalReference(it) }
?: caseNoteRepository.findByNomisId(caseNote.header.legacyId)

val entity = if (existing == null) caseNote.newEntity() else existing.updateFrom(caseNote)
if (entity != null) {
caseNoteRepository.save(entity)
audit["contactId"] = entity.id
}
(if (existing == null) caseNote.newEntity() else existing.updateFrom(caseNote))
?.let(caseNoteRepository::save)
?.also {
auditCaseNoteMerge(
AuditedInteraction.Parameters(
"dpsId" to caseNote.header.uuid.toString(),
"contactId" to it.id.toString()
)
)
}
}

private fun CaseNote.updateFrom(caseNote: DeliusCaseNote): CaseNote? {
Expand All @@ -59,6 +67,19 @@ class DeliusService(
}
}

private fun auditCaseNoteMerge(params: AuditedInteraction.Parameters) {
val bi = businessInteractionRepository.getByCode(CASE_NOTES_MERGE.code)
auditedInteractionRepository.save(
AuditedInteraction(
businessInteractionId = bi.id,
userId = ServiceContext.servicePrincipal()!!.userId,
dateTime = ZonedDateTime.now(),
parameters = params,
outcome = SUCCESS
)
)
}

private fun DeliusCaseNote.newEntity(): CaseNote {
val offender = offenderRepository.findByNomsIdAndSoftDeletedIsFalse(header.nomisId)
?: throw OffenderNotFoundException(header.nomisId)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,25 @@ import uk.gov.justice.digital.hmpps.converter.NotificationConverter
import uk.gov.justice.digital.hmpps.integrations.prison.CaseNoteTypesOfInterest
import uk.gov.justice.digital.hmpps.message.HmppsDomainEvent
import uk.gov.justice.digital.hmpps.message.Notification
import uk.gov.justice.digital.hmpps.messaging.Handler.Companion.CASE_NOTE_PUBLISHED
import uk.gov.justice.digital.hmpps.messaging.Handler.Companion.PERSON_CASE_NOTE_CREATED
import uk.gov.justice.digital.hmpps.messaging.Handler.Companion.PERSON_CASE_NOTE_UPDATED

@Component
@Channel("prison-case-notes-to-probation-queue")
class Handler(
private val caseNotePublished: CaseNotePublished,
private val prisonIdentifierAdded: PrisonIdentifierAdded,
private val personCaseNote: PersonCaseNote,
override val converter: NotificationConverter<HmppsDomainEvent>,
) : NotificationHandler<HmppsDomainEvent> {

companion object {
const val CASE_NOTE_PUBLISHED = "prison.case-note.published"
const val PRISON_IDENTIFIER_ADDED = "probation-case.prison-identifier.added"
const val PERSON_CASE_NOTE_CREATED = "person.case-note.created"
const val PERSON_CASE_NOTE_UPDATED = "person.case-note.updated"
}

@Publish(
messages = [
Message(name = "prison/case-note-published"),
Message(title = PRISON_IDENTIFIER_ADDED, payload = Schema(HmppsDomainEvent::class)),
Message(title = PERSON_CASE_NOTE_CREATED, payload = Schema(HmppsDomainEvent::class)),
Message(title = PERSON_CASE_NOTE_UPDATED, payload = Schema(HmppsDomainEvent::class)),
Expand All @@ -41,14 +37,10 @@ class Handler(
when {
notification.eventType == PRISON_IDENTIFIER_ADDED -> prisonIdentifierAdded.handle(notification.message)
notification.isCaseNoteOfInterest() -> personCaseNote.handle(notification.message)
notification.publishedOfInterest() -> caseNotePublished.handle(notification.message)
}
}
}

private fun Notification<*>.publishedOfInterest(): Boolean =
eventType == CASE_NOTE_PUBLISHED

private fun Notification<*>.isCaseNoteOfInterest(): Boolean =
(eventType == PERSON_CASE_NOTE_CREATED || eventType == PERSON_CASE_NOTE_UPDATED) && typeIsOfInterest()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import uk.gov.justice.digital.hmpps.integrations.delius.service.DeliusService
import uk.gov.justice.digital.hmpps.integrations.prison.*
import uk.gov.justice.digital.hmpps.integrations.prison.CaseNoteTypesOfInterest.forSearchRequest
import uk.gov.justice.digital.hmpps.integrations.prison.PrisonCaseNoteFilters
import uk.gov.justice.digital.hmpps.integrations.prison.PrisonCaseNotesClient
import uk.gov.justice.digital.hmpps.integrations.prison.SearchCaseNotes
import uk.gov.justice.digital.hmpps.integrations.prison.toDeliusCaseNote
import uk.gov.justice.digital.hmpps.message.HmppsDomainEvent
import uk.gov.justice.digital.hmpps.telemetry.TelemetryService
import java.net.URI
Expand All @@ -27,13 +30,24 @@ class PrisonIdentifierAdded(
val caseNotes = caseNotesApi.searchCaseNotes(uri, SearchCaseNotes(forSearchRequest())).content
.filter { cn -> PrisonCaseNoteFilters.filters.none { it.predicate.invoke(cn) } }

caseNotes.forEach { deliusService.mergeCaseNote(it.toDeliusCaseNote()) }
val exceptions = caseNotes.mapNotNull { pcn ->
try {
deliusService.mergeCaseNote(pcn.toDeliusCaseNote())
null
} catch (e: Exception) {
e
}
}

if (exceptions.isNotEmpty()) {
throw exceptions.first()
}

telemetryService.trackEvent(
"CaseNotesMigrated", mapOf(
"nomsId" to nomsId,
"cause" to event.eventType,
"count" to caseNotes.size.toString()
"total" to caseNotes.size.toString(),
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ spring:
datasource:
hikari:
auto-commit: false
maximum-pool-size: 25
maximum-pool-size: 20
jpa:
hibernate.ddl-auto: validate
properties:
Expand All @@ -30,7 +30,7 @@ spring:
provider:
hmpps-auth:
token-uri: http://localhost:${wiremock.port}/auth/oauth/token
threads.virtual.enabled: true
threads.virtual.enabled: false

delius.db.username: PrisonCaseNotesToProbation

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.junit.jupiter.MockitoSettings
import org.mockito.kotlin.*
import org.mockito.quality.Strictness
import uk.gov.justice.digital.hmpps.audit.service.AuditedInteractionService
import uk.gov.justice.digital.hmpps.audit.repository.AuditedInteractionRepository
import uk.gov.justice.digital.hmpps.audit.repository.BusinessInteractionRepository
import uk.gov.justice.digital.hmpps.data.generator.*
import uk.gov.justice.digital.hmpps.exception.NotFoundException
import uk.gov.justice.digital.hmpps.exceptions.OffenderNotFoundException
Expand All @@ -28,13 +29,18 @@ import uk.gov.justice.digital.hmpps.integrations.delius.repository.CaseNoteTypeR
import uk.gov.justice.digital.hmpps.integrations.delius.repository.OffenderRepository
import uk.gov.justice.digital.hmpps.integrations.prison.toDeliusCaseNote
import uk.gov.justice.digital.hmpps.service.AssignmentService
import java.time.ZonedDateTime
import java.util.*

@ExtendWith(MockitoExtension::class)
@MockitoSettings(strictness = Strictness.LENIENT)
class DeliusServiceTest {

@Mock
lateinit var businessInteractionRepository: BusinessInteractionRepository

@Mock
lateinit var auditedInteractionRepository: AuditedInteractionRepository

@Mock
lateinit var caseNoteRepository: CaseNoteRepository

Expand All @@ -50,9 +56,6 @@ class DeliusServiceTest {
@Mock
lateinit var assignmentService: AssignmentService

@Mock
lateinit var auditedInteractionService: AuditedInteractionService

@Mock
lateinit var caseNoteRelatedService: CaseNoteRelatedService

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,14 @@ import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.kotlin.*
import org.springframework.http.HttpStatus
import org.springframework.web.client.HttpClientErrorException
import org.springframework.web.client.HttpStatusCodeException
import org.springframework.web.server.ResponseStatusException
import uk.gov.justice.digital.hmpps.audit.service.AuditedInteractionService
import uk.gov.justice.digital.hmpps.data.generator.CaseNoteMessageGenerator
import uk.gov.justice.digital.hmpps.exceptions.OffenderNotFoundException
import uk.gov.justice.digital.hmpps.exceptions.StaffCodeExhaustedException
import uk.gov.justice.digital.hmpps.integrations.delius.service.DeliusService
import uk.gov.justice.digital.hmpps.integrations.prison.PrisonCaseNote
import uk.gov.justice.digital.hmpps.integrations.prison.PrisonCaseNotesClient
import uk.gov.justice.digital.hmpps.message.MessageAttributes
import uk.gov.justice.digital.hmpps.message.Notification
import uk.gov.justice.digital.hmpps.prepMessage
import uk.gov.justice.digital.hmpps.prepNotification
import uk.gov.justice.digital.hmpps.telemetry.TelemetryService
import java.net.URI
Expand All @@ -31,6 +28,9 @@ import java.time.ZonedDateTime
@ExtendWith(MockitoExtension::class)
internal class PersonCaseNoteTest {

@Mock
private lateinit var auditedInteractionService: AuditedInteractionService

@Mock
private lateinit var prisonCaseNotesClient: PrisonCaseNotesClient

Expand Down

0 comments on commit 33d54bb

Please sign in to comment.