Skip to content

Commit

Permalink
PI-2670 - Feature flag feedback fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
joseph-bcl committed Dec 16, 2024
1 parent a1dc4e1 commit 4d807cf
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 160 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ internal class IntegrationTest {
whenever(featureFlags.enabled("common-platform-record-creation-toggle")).thenReturn(false)
val notification = Notification(message = MessageGenerator.COMMON_PLATFORM_EVENT)
channelManager.getChannel(queueName).publishAndWait(notification)
verify(personService).insertPerson(any(), any())
verify(personService, never()).insertPerson(any(), any())
thenNoRecordsAreInserted()
verify(auditedInteractionService, Mockito.never())
.createAuditedInteraction(any(), any(), eq(AuditedInteraction.Outcome.FAIL), any(), anyOrNull())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import uk.gov.justice.digital.hmpps.message.Notification
import uk.gov.justice.digital.hmpps.service.PersonService
import uk.gov.justice.digital.hmpps.telemetry.TelemetryMessagingExtensions.notificationReceived
import uk.gov.justice.digital.hmpps.telemetry.TelemetryService
import java.time.LocalDate
import java.time.Period

@Component
@Channel("common-platform-and-delius-queue")
Expand Down Expand Up @@ -50,50 +52,55 @@ class Handler(
val matchedPersonResponse = probationSearchClient.match(matchRequest)

if (matchedPersonResponse.matches.isNotEmpty()) {
telemetryService.trackEvent(
"ProbationSearchMatchDetected",
mapOf(
"hearingId" to notification.message.hearing.id,
"defendantId" to defendant.id,
)
)
return@forEach
}

// Insert each defendant as a person record
val savedEntities = personService.insertPerson(defendant, notification.message.hearing.courtCentre.code)
val dateOfBirth = defendant.personDefendant?.personDetails?.dateOfBirth
?: throw IllegalArgumentException("Date of birth not found in message")

// Under 10 years old validation
dateOfBirth.let {
val age = Period.between(it, LocalDate.now()).years
require(age > 10) {
"Date of birth would indicate person is under ten years old: $it"
}
}

if (featureFlags.enabled("common-platform-record-creation-toggle")) {
// Insert each defendant as a person record
val savedEntities = personService.insertPerson(defendant, notification.message.hearing.courtCentre.code)

val eventName = if (featureFlags.enabled("common-platform-record-creation-toggle")) {
notifier.caseCreated(savedEntities.person)
savedEntities.address?.let { notifier.addressCreated(it) }
"PersonCreated"
} else {
"SimulatedPersonCreated"
}

telemetryService.trackEvent(
eventName,
mapOf(
"hearingId" to notification.message.hearing.id,
"CRN" to savedEntities.person.crn,
"personId" to savedEntities.person.id.toString(),
"firstName" to savedEntities.person.forename,
"surname" to savedEntities.person.surname,
"dob" to savedEntities.person.dateOfBirth.toString(),
"genderCode" to savedEntities.person.gender.description,
"pnc" to savedEntities.person.pncNumber.toString(),
"personManagerId" to savedEntities.personManager.id.toString(),
"allocationDate" to savedEntities.personManager.allocationDate.toString(),
"allocationReason" to savedEntities.personManager.allocationReason.description,
"providerCode" to savedEntities.personManager.provider.code,
"teamCode" to savedEntities.personManager.team.code,
"staffCode" to savedEntities.personManager.staff.code,
"equalityId" to savedEntities.equality.id.toString(),
"addressId" to savedEntities.address?.id.toString(),
"buildingName" to savedEntities.address?.buildingName.toString(),
"addressNumber" to savedEntities.address?.addressNumber.toString(),
"streetName" to savedEntities.address?.streetName.toString(),
"town" to savedEntities.address?.town.toString(),
"district" to savedEntities.address?.district.toString(),
"county" to savedEntities.address?.county.toString(),
"type" to savedEntities.address?.type?.description.toString(),
"status" to savedEntities.address?.status?.description.toString(),
"postcode" to savedEntities.address?.postcode.toString(),
telemetryService.trackEvent(
"PersonCreated",
mapOf(
"hearingId" to notification.message.hearing.id,
"defendantId" to defendant.id,
"CRN" to savedEntities.person.crn,
"personId" to savedEntities.person.id.toString(),
"personManagerId" to savedEntities.personManager.id.toString(),
"equalityId" to savedEntities.equality.id.toString(),
"addressId" to savedEntities.address?.id.toString(),
)
)
)
} else {
telemetryService.trackEvent(
"SimulatedPersonCreated",
mapOf(
"hearingId" to notification.message.hearing.id,
"defendantId" to defendant.id
)
)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package uk.gov.justice.digital.hmpps.service

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.flags.FeatureFlags
import uk.gov.justice.digital.hmpps.integrations.client.OsClient
import uk.gov.justice.digital.hmpps.integrations.client.OsPlacesResponse
import uk.gov.justice.digital.hmpps.integrations.delius.audit.BusinessInteractionCode
Expand All @@ -15,7 +13,6 @@ import uk.gov.justice.digital.hmpps.messaging.Address
import uk.gov.justice.digital.hmpps.messaging.Defendant
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.Period

@Service
class PersonService(
Expand All @@ -28,137 +25,97 @@ class PersonService(
private val staffRepository: StaffRepository,
private val referenceDataRepository: ReferenceDataRepository,
private val personAddressRepository: PersonAddressRepository,
private val osClient: OsClient,
private val featureFlags: FeatureFlags
private val osClient: OsClient
) : AuditableService(auditedInteractionService) {

@Transactional
fun insertPerson(defendant: Defendant, courtCode: String): InsertPersonResult =
if (featureFlags.enabled("common-platform-record-creation-toggle")) {
audit(BusinessInteractionCode.INSERT_PERSON) { audit ->
val result = insertPersonLogic(defendant, courtCode)
audit["offenderId"] = result.person.id!!
result
}
} else {
insertPersonLogic(defendant, courtCode)
}

fun insertPersonLogic(defendant: Defendant, courtCode: String): InsertPersonResult {
val dateOfBirth = defendant.personDefendant?.personDetails?.dateOfBirth
?: throw IllegalArgumentException("Date of birth not found in message")

// Under 10 years old validation
dateOfBirth.let {
val age = Period.between(it, LocalDate.now()).years
require(age > 10) {
"Date of birth would indicate person is under ten years old: $it"
}
}
audit(BusinessInteractionCode.INSERT_PERSON) { audit ->
// Person record
val savedPerson = personRepository.save(defendant.toPerson())

val courtLinkedProvider = courtRepository.getByOuCode(courtCode).provider
val initialAllocation = referenceDataRepository.initialAllocationReason()
val unallocatedTeam = teamRepository.findByCode(courtLinkedProvider.code + "UAT")
val unallocatedStaff = staffRepository.findByCode(unallocatedTeam.code + "U")

// Person manager record
val manager = PersonManager(
person = savedPerson,
staff = unallocatedStaff,
team = unallocatedTeam,
provider = courtLinkedProvider,
softDeleted = false,
active = true,
allocationReason = initialAllocation,
staffEmployeeID = unallocatedStaff.id,
trustProviderTeamId = unallocatedTeam.id,
allocationDate = LocalDateTime.of(1900, 1, 1, 0, 0)

// Person record
val savedPerson = if (featureFlags.enabled("common-platform-record-creation-toggle")) {
personRepository.save(defendant.toPerson())
} else {
defendant.toPerson()
}

val courtLinkedProvider = courtRepository.getByOuCode(courtCode).provider
val initialAllocation = referenceDataRepository.initialAllocationReason()
val unallocatedTeam = teamRepository.findByCode(courtLinkedProvider.code + "UAT")
val unallocatedStaff = staffRepository.findByCode(unallocatedTeam.code + "U")

// Person manager record
val manager = PersonManager(
person = savedPerson,
staff = unallocatedStaff,
team = unallocatedTeam,
provider = courtLinkedProvider,
softDeleted = false,
active = true,
allocationReason = initialAllocation,
staffEmployeeID = unallocatedStaff.id,
trustProviderTeamId = unallocatedTeam.id,
allocationDate = LocalDateTime.of(1900, 1, 1, 0, 0)
)
val savedManager = personManagerRepository.save(manager)

)
// Equality record
val equality = Equality(
id = null,
personId = savedPerson.id!!,
softDeleted = false,
)

val savedManager = if (featureFlags.enabled("common-platform-record-creation-toggle")) {
personManagerRepository.save(manager)
} else {
manager
}
val savedEquality = equalityRepository.save(equality)

// Equality record
val equality = Equality(
id = null,
personId = savedPerson.id ?: 0L,
softDeleted = false,
)
val addressInfo = defendant.personDefendant?.personDetails?.address
val osPlacesResponse = addressInfo?.takeIf { it.containsInformation() && !it.postcode.isNullOrBlank() }
?.let { findAddressByFreeText(it) }

val savedEquality = if (featureFlags.enabled("common-platform-record-creation-toggle")) {
equalityRepository.save(equality)
} else {
equality
}
val deliveryPointAddress = osPlacesResponse?.results?.firstOrNull()?.dpa

val addressInfo = defendant.personDefendant.personDetails.address
val osPlacesResponse = addressInfo?.takeIf { it.containsInformation() && !it.postcode.isNullOrBlank() }
?.let { findAddressByFreeText(it) }

val deliveryPointAddress = osPlacesResponse?.results?.firstOrNull()?.dpa

val savedAddress = if (deliveryPointAddress != null) {
insertAddress(
PersonAddress(
id = null,
start = LocalDate.now(),
status = referenceDataRepository.mainAddressStatus(),
person = savedPerson,
type = referenceDataRepository.awaitingAssessmentAddressType(),
postcode = deliveryPointAddress.postcode,
notes = "UPRN: ${deliveryPointAddress.uprn}",
buildingName = listOfNotNull(
deliveryPointAddress.subBuildingName,
deliveryPointAddress.buildingName
).joinToString(" "),
addressNumber = deliveryPointAddress.buildingNumber?.toString(),
streetName = deliveryPointAddress.thoroughfareName,
town = deliveryPointAddress.postTown,
district = deliveryPointAddress.localCustodianCodeDescription
)
)
} else {
addressInfo?.takeIf { it.containsInformation() }?.let {
val savedAddress = if (deliveryPointAddress != null) {
insertAddress(
PersonAddress(
id = null,
start = LocalDate.now(),
status = referenceDataRepository.mainAddressStatus(),
person = savedPerson,
postcode = it.postcode,
type = referenceDataRepository.awaitingAssessmentAddressType(),
streetName = it.address1,
district = it.address2,
town = it.address3,
county = listOfNotNull(it.address4, it.address5).joinToString(", ")
postcode = deliveryPointAddress.postcode,
notes = "UPRN: ${deliveryPointAddress.uprn}",
buildingName = listOfNotNull(
deliveryPointAddress.subBuildingName,
deliveryPointAddress.buildingName
).joinToString(" "),
addressNumber = deliveryPointAddress.buildingNumber?.toString(),
streetName = deliveryPointAddress.thoroughfareName,
town = deliveryPointAddress.postTown,
district = deliveryPointAddress.localCustodianCodeDescription
)
)
} else {
addressInfo?.takeIf { it.containsInformation() }?.let {
insertAddress(
PersonAddress(
id = null,
start = LocalDate.now(),
status = referenceDataRepository.mainAddressStatus(),
person = savedPerson,
postcode = it.postcode,
type = referenceDataRepository.awaitingAssessmentAddressType(),
streetName = it.address1,
district = it.address2,
town = it.address3,
county = listOfNotNull(it.address4, it.address5).joinToString(", ")
)
)
}
}
audit["offenderId"] = savedPerson.id
InsertPersonResult(savedPerson, savedManager, savedEquality, savedAddress)
}
return InsertPersonResult(savedPerson, savedManager, savedEquality, savedAddress)
}

fun insertAddress(address: PersonAddress): PersonAddress =
if (featureFlags.enabled("common-platform-record-creation-toggle")) {
audit(BusinessInteractionCode.INSERT_ADDRESS) { audit ->
val result = personAddressRepository.save(address)
audit["offenderId"] = result.person.id!!
result
}
} else {
address
}
fun insertAddress(address: PersonAddress): PersonAddress = audit(BusinessInteractionCode.INSERT_ADDRESS) { audit ->
val savedAddress = personAddressRepository.save(address)
audit["addressId"] = address.id!!
savedAddress
}

fun generateCrn(): String {
return personRepository.getNextCrn()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,23 +126,14 @@ internal class HandlerTest {
@Test
fun `Simulated person created logged when feature flag disabled`() {
probationSearchMatchNotFound()

whenever(featureFlags.enabled("common-platform-record-creation-toggle")).thenReturn(false)
whenever(personService.insertPerson(any(), any())).thenReturn(
InsertPersonResult(
person = PersonGenerator.DEFAULT,
personManager = PersonManagerGenerator.DEFAULT,
equality = Equality(id = 1L, personId = 1L, softDeleted = false),
address = PersonAddressGenerator.MAIN_ADDRESS,
)
)

val notification = Notification(message = MessageGenerator.COMMON_PLATFORM_EVENT)
handler.handle(notification)

verify(telemetryService).notificationReceived(notification)
verify(telemetryService).trackEvent(eq("SimulatedPersonCreated"), anyMap(), anyMap())
verify(personService).insertPerson(any(), any())
verify(personService, never()).insertPerson(any(), any())
verify(notifier, never()).caseCreated(any())
verify(notifier, never()).addressCreated(any())
}
Expand Down

0 comments on commit 4d807cf

Please sign in to comment.