From f98faf3ebaaf5351e873bdc8508b430015333374 Mon Sep 17 00:00:00 2001 From: "Joseph.Dundon" Date: Wed, 23 Oct 2024 16:45:03 +0100 Subject: [PATCH] PI-2575 - Entity changes to match delius database - Removed oracle profile from application.yml --- .../hmpps/data/generator/PersonGenerator.kt | 5 +- .../data/generator/ReferenceDataGenerator.kt | 10 +- .../src/dev/resources/db/oracle.sql | 4 +- .../justice/digital/hmpps/IntegrationTest.kt | 14 +-- .../integrations/delius/entity/Equality.kt | 2 + .../integrations/delius/entity/Person.kt | 26 ++++- .../delius/entity/PersonManager.kt | 5 + .../delius/entity/ReferenceData.kt | 18 +-- .../digital/hmpps/messaging/Handler.kt | 82 ++------------ .../digital/hmpps/service/AddressService.kt | 23 ---- .../digital/hmpps/service/PersonService.kt | 89 +++++++++++++-- .../src/main/resources/application.yml | 4 - .../digital/hmpps/messaging/HandlerTest.kt | 30 ----- .../hmpps/service/AddressServiceTest.kt | 42 ------- .../hmpps/service/PersonServiceTest.kt | 105 ------------------ 15 files changed, 141 insertions(+), 318 deletions(-) delete mode 100644 projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AddressService.kt delete mode 100644 projects/common-platform-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/AddressServiceTest.kt delete mode 100644 projects/common-platform-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/PersonServiceTest.kt diff --git a/projects/common-platform-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/PersonGenerator.kt b/projects/common-platform-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/PersonGenerator.kt index 778db68c86..9054d5584f 100644 --- a/projects/common-platform-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/PersonGenerator.kt +++ b/projects/common-platform-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/PersonGenerator.kt @@ -18,7 +18,10 @@ object PersonGenerator { forename = UUID.randomUUID().toString().substring(0, 15), surname = UUID.randomUUID().toString().substring(0, 15), dateOfBirth = LocalDate.now().minusYears(Random.nextInt(16, 76).toLong()), - gender = if (Random.nextBoolean()) ReferenceDataGenerator.GENDER_MALE else ReferenceDataGenerator.GENDER_FEMALE + gender = if (Random.nextBoolean()) ReferenceDataGenerator.GENDER_MALE else ReferenceDataGenerator.GENDER_FEMALE, + surnameSoundex = "surnameSoundex", + firstNameSoundex = "firstNameSoundex", + middleNameSoundex = null ) } diff --git a/projects/common-platform-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ReferenceDataGenerator.kt b/projects/common-platform-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ReferenceDataGenerator.kt index d702df66b4..82d5722d6f 100644 --- a/projects/common-platform-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ReferenceDataGenerator.kt +++ b/projects/common-platform-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ReferenceDataGenerator.kt @@ -37,7 +37,7 @@ object DatasetGenerator { } object CourtGenerator { - val UNKNOWN_COURT_N07_PROVIDER = generate(code = "UNKNCT", nationalCourtCode = "A00AA00") + val UNKNOWN_COURT_N07_PROVIDER = generate(code = "UNKNCT", ouCode = "A00AA00") fun generate( id: Long = IdGenerator.getAndIncrement(), @@ -45,13 +45,13 @@ object CourtGenerator { selectable: Boolean = true, courtName: String = "Court not known", provider: Provider = ProviderGenerator.DEFAULT, - nationalCourtCode: String? = null, + ouCode: String? = null, ) = Court( id = id, code = code, selectable = selectable, - courtName = courtName, - probationArea = provider, - nationalCourtCode = nationalCourtCode + name = courtName, + provider = provider, + ouCode = ouCode ) } \ No newline at end of file diff --git a/projects/common-platform-and-delius/src/dev/resources/db/oracle.sql b/projects/common-platform-and-delius/src/dev/resources/db/oracle.sql index a7ab3f64c6..5f651dd9cc 100644 --- a/projects/common-platform-and-delius/src/dev/resources/db/oracle.sql +++ b/projects/common-platform-and-delius/src/dev/resources/db/oracle.sql @@ -1,10 +1,10 @@ -CREATE OR REPLACE PACKAGE offender_support_api IS +CREATE OR REPLACE PACKAGE offender_support_api AS FUNCTION getNextCRN RETURN VARCHAR2; END offender_support_api; GRANT EXECUTE ON offender_support_api TO delius_app_schema; -CREATE OR REPLACE PACKAGE BODY offender_support_api IS +CREATE OR REPLACE PACKAGE BODY offender_support_api AS FUNCTION getNextCRN RETURN VARCHAR2 IS BEGIN RETURN 'A111111'; diff --git a/projects/common-platform-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/IntegrationTest.kt b/projects/common-platform-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/IntegrationTest.kt index cc86f17379..1d5a2a9084 100644 --- a/projects/common-platform-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/IntegrationTest.kt +++ b/projects/common-platform-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/IntegrationTest.kt @@ -28,7 +28,6 @@ import uk.gov.justice.digital.hmpps.integrations.delius.person.entity.PersonAddr import uk.gov.justice.digital.hmpps.message.HmppsDomainEvent import uk.gov.justice.digital.hmpps.message.Notification import uk.gov.justice.digital.hmpps.messaging.HmppsChannelManager -import uk.gov.justice.digital.hmpps.service.AddressService 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 @@ -67,9 +66,6 @@ internal class IntegrationTest { @SpyBean lateinit var personService: PersonService - @SpyBean - lateinit var addressService: AddressService - @BeforeEach fun setup() { doReturn("A111111").whenever(personService).generateCrn() @@ -97,8 +93,8 @@ internal class IntegrationTest { val notification = Notification(message = MessageGenerator.COMMON_PLATFORM_EVENT) channelManager.getChannel(queueName).publishAndWait(notification) verify(personService, never()).insertPerson(any(), any()) + verify(personService, never()).insertAddress(any()) verify(personRepository, never()).save(any()) - verify(addressService, never()).insertAddress(any()) verify(addressRepository, never()).save(any()) verify(auditedInteractionService, Mockito.never()).createAuditedInteraction( any(), @@ -126,7 +122,7 @@ internal class IntegrationTest { channelManager.getChannel(queueName).publishAndWait(notification) verify(personService, never()).insertPerson(any(), any()) - verify(addressService, never()).insertAddress(any()) + verify(personService, never()).insertAddress(any()) verify(addressRepository, never()).save(any()) verify(personRepository, never()).save(any()) verify(auditedInteractionService, Mockito.never()) @@ -150,8 +146,8 @@ internal class IntegrationTest { channelManager.getChannel(queueName).publishAndWait(notification) verify(personService, never()).insertPerson(any(), any()) + verify(personService, never()).insertAddress(any()) verify(personRepository, never()).save(any()) - verify(addressService, never()).insertAddress(any()) verify(addressRepository, never()).save(any()) verify(auditedInteractionService, Mockito.never()) .createAuditedInteraction(any(), any(), any(), any(), anyOrNull()) @@ -205,7 +201,7 @@ internal class IntegrationTest { val notification = Notification(message = MessageGenerator.COMMON_PLATFORM_EVENT) channelManager.getChannel(queueName).publishAndWait(notification) - verify(addressService).insertAddress(any()) + verify(personService).insertAddress(any()) verify(addressRepository).save(check { assertThat(it.start, Matchers.equalTo(LocalDate.now())) @@ -242,7 +238,7 @@ internal class IntegrationTest { val notification = Notification(message = MessageGenerator.COMMON_PLATFORM_EVENT_BLANK_ADDRESS) channelManager.getChannel(queueName).publishAndWait(notification) - verify(addressService, never()).insertAddress(any()) + verify(personService, never()).insertAddress(any()) verify(addressRepository, never()).save(any()) diff --git a/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/entity/Equality.kt b/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/entity/Equality.kt index bccf55ba36..d648334960 100644 --- a/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/entity/Equality.kt +++ b/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/entity/Equality.kt @@ -5,12 +5,14 @@ import org.springframework.data.annotation.CreatedBy import org.springframework.data.annotation.CreatedDate import org.springframework.data.annotation.LastModifiedBy import org.springframework.data.annotation.LastModifiedDate +import org.springframework.data.jpa.domain.support.AuditingEntityListener import org.springframework.data.jpa.repository.JpaRepository import java.time.ZonedDateTime @Entity @Table(name = "equality") @SequenceGenerator(name = "equality_id_seq", sequenceName = "equality_id_seq", allocationSize = 1) +@EntityListeners(AuditingEntityListener::class) class Equality( @Id @Column(name = "equality_id") diff --git a/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/entity/Person.kt b/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/entity/Person.kt index 8d1f89732e..cceab59eee 100644 --- a/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/entity/Person.kt +++ b/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/entity/Person.kt @@ -8,6 +8,7 @@ import org.springframework.data.annotation.LastModifiedBy import org.springframework.data.annotation.LastModifiedDate import org.springframework.data.jpa.domain.support.AuditingEntityListener import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.data.jpa.repository.Query import java.time.LocalDate import java.time.ZonedDateTime @@ -34,6 +35,15 @@ class Person( @Column(name = "first_name", length = 35) val forename: String, + @Column + val surnameSoundex: String, + + @Column + val firstNameSoundex: String, + + @Column + val middleNameSoundex: String?, + @Column(name = "second_name", length = 35) val secondName: String? = null, @@ -75,11 +85,23 @@ class Person( @LastModifiedDate var lastUpdatedDatetime: ZonedDateTime = ZonedDateTime.now(), + @LastModifiedDate + var lastUpdatedDatetimeDiversit: ZonedDateTime = ZonedDateTime.now(), + + @LastModifiedBy + var lastUpdatedUserIdDiversity: Long = 0, + @CreatedBy var createdByUserId: Long = 0, @LastModifiedBy var lastUpdatedUserId: Long = 0, -) -interface PersonRepository : JpaRepository \ No newline at end of file + @Column + val partitionAreaId: Long = 0L + ) + +interface PersonRepository : JpaRepository{ + @Query("SELECT SOUNDEX(:name) FROM DUAL", nativeQuery = true) + fun getSoundex(name: String): String +} \ No newline at end of file diff --git a/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/entity/PersonManager.kt b/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/entity/PersonManager.kt index 3a7aaa951a..36ace96365 100644 --- a/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/entity/PersonManager.kt +++ b/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/entity/PersonManager.kt @@ -7,6 +7,7 @@ import org.springframework.data.annotation.CreatedBy import org.springframework.data.annotation.CreatedDate import org.springframework.data.annotation.LastModifiedBy import org.springframework.data.annotation.LastModifiedDate +import org.springframework.data.jpa.domain.support.AuditingEntityListener import org.springframework.data.jpa.repository.JpaRepository import java.time.LocalDate import java.time.LocalDateTime @@ -16,6 +17,7 @@ import java.time.ZonedDateTime @Table(name = "offender_manager") @SQLRestriction("soft_deleted = 0 and active_flag = 1") @SequenceGenerator(name = "offender_manager_id_seq", sequenceName = "offender_manager_id_seq", allocationSize = 1) +@EntityListeners(AuditingEntityListener::class) class PersonManager( @Id @Column(name = "offender_manager_id") @@ -75,6 +77,9 @@ class PersonManager( @LastModifiedBy var lastUpdatedUserId: Long = 0, + + @Column + val partitionAreaId: Long = 0L ) @Immutable diff --git a/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/entity/ReferenceData.kt b/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/entity/ReferenceData.kt index 913ad87a41..9b47cfb158 100644 --- a/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/entity/ReferenceData.kt +++ b/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/entity/ReferenceData.kt @@ -101,21 +101,21 @@ class Court( @Column(name = "court_id", nullable = false) val id: Long, - @Column(name = "code", length = 6, nullable = false) + @Column(columnDefinition = "char(6)", nullable = false) val code: String, @Convert(converter = YesNoConverter::class) val selectable: Boolean = true, - @Column(name = "code_description", length = 80) - val courtName: String, + @Column(name = "court_name", length = 80) + val name: String, @ManyToOne @JoinColumn(name = "probation_area_id") - val probationArea: Provider, + val provider: Provider, - @Column(name = "national_court_code") - val nationalCourtCode: String? + @Column(name = "court_ou_code") + val ouCode: String? ) interface ReferenceDataRepository : JpaRepository { @@ -149,5 +149,7 @@ fun ReferenceDataRepository.awaitingAssessmentAddressType() = ?: throw NotFoundException("Address Type", "code", ReferenceData.StandardRefDataCode.AWAITING_ASSESSMENT.code) interface CourtRepository : JpaRepository { - fun findByNationalCourtCode(nationalCourtCode: String): Court -} \ No newline at end of file + fun findByOuCode(ouCode: String): Court? +} +fun CourtRepository.getByOuCode(ouCode: String) = + findByOuCode(ouCode) ?: throw NotFoundException("Court", "ouCode", ouCode) diff --git a/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/Handler.kt b/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/Handler.kt index 1bf0322248..d4ecc80e51 100644 --- a/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/Handler.kt +++ b/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/Handler.kt @@ -4,16 +4,11 @@ import org.openfolder.kotlinasyncapi.annotation.Schema import org.openfolder.kotlinasyncapi.annotation.channel.Channel import org.openfolder.kotlinasyncapi.annotation.channel.Message import org.openfolder.kotlinasyncapi.annotation.channel.Publish -import org.slf4j.Logger -import org.slf4j.LoggerFactory import org.springframework.stereotype.Component import uk.gov.justice.digital.hmpps.converter.NotificationConverter import uk.gov.justice.digital.hmpps.integrations.client.ProbationMatchRequest import uk.gov.justice.digital.hmpps.integrations.client.ProbationSearchClient -import uk.gov.justice.digital.hmpps.integrations.delius.entity.* -import uk.gov.justice.digital.hmpps.integrations.delius.person.entity.PersonAddress import uk.gov.justice.digital.hmpps.message.Notification -import uk.gov.justice.digital.hmpps.service.AddressService 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 @@ -26,8 +21,6 @@ class Handler( override val converter: NotificationConverter, private val telemetryService: TelemetryService, private val personService: PersonService, - private val addressService: AddressService, - private val referenceDataRepository: ReferenceDataRepository, private val probationSearchClient: ProbationSearchClient ) : NotificationHandler { @@ -58,58 +51,18 @@ class Handler( val matchedPersonResponse = probationSearchClient.match(matchRequest) if (matchedPersonResponse.matches.isNotEmpty()) { - log.debug("Matching offender(s) found for: {}", matchRequest) return } - defendants.forEach { defendant -> // Insert each defendant as a person record - val savedPerson = personService.insertPerson(defendant.toPerson(), courtCode) - - val address = defendant.personDefendant?.personDetails?.address - - // Insert each defendant's address record - val savedAddress = if (address.containsInformation()) { - addressService.insertAddress( - PersonAddress( - id = null, - start = LocalDate.now(), - status = referenceDataRepository.mainAddressStatus(), - personId = savedPerson.id!!, - notes = address?.buildNotes(), - postcode = address?.postcode, - type = referenceDataRepository.awaitingAssessmentAddressType() - ) - ) - } else { - log.debug("No address found for defendant with pncId: {}", defendant.pncId) - null - } - } - } + val savedPerson = personService.insertPerson(defendant, courtCode) - companion object { - val log: Logger = LoggerFactory.getLogger(this::class.java) - } - - fun Defendant.toPerson(): Person { - val personDetails = personDefendant?.personDetails ?: throw IllegalArgumentException("No person found") - val genderCode = personDetails.gender.toDeliusGender() - - return Person( - id = null, - crn = personService.generateCrn(), - croNumber = this.croNumber, - pncNumber = this.pncId, - forename = personDetails.firstName, - secondName = personDetails.middleName, - telephoneNumber = personDetails.contact?.home, - mobileNumber = personDetails.contact?.mobile, - surname = personDetails.lastName, - dateOfBirth = personDetails.dateOfBirth, - gender = referenceDataRepository.findByCodeAndDatasetCode(genderCode, DatasetCode.GENDER)!!, - softDeleted = false - ) + telemetryService.trackEvent("PersonCreated", mapOf( + "CRN" to savedPerson.crn, + "personId" to savedPerson.id.toString(), + "hearingId" to notification.message.hearing.id) + ) + } } fun CommonPlatformHearing.toProbationMatchRequest(): ProbationMatchRequest { @@ -124,27 +77,6 @@ class Handler( croNumber = defendant.croNumber ) } - - fun String.toDeliusGender() = ReferenceData.GenderCode.entries.find { it.commonPlatformValue == this }?.deliusValue - ?: throw IllegalStateException("Gender not found: $this") - - fun Address?.containsInformation(): Boolean { - return this != null && listOf( - this.address1, this.address2, this.address3, - this.address4, this.address5, this.postcode - ).any { !it.isNullOrBlank() } - } - - fun Address.buildNotes(): String { - return listOf( - "Address record automatically created by common-platform-delius-service with the following information:", - "Address1: ${this.address1 ?: "N/A"}", - "Address2: ${this.address2 ?: "N/A"}", - "Address3: ${this.address3 ?: "N/A"}", - "Address4: ${this.address4 ?: "N/A"}", - "Postcode: ${this.postcode ?: "N/A"}" - ).joinToString("\n") - } } diff --git a/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AddressService.kt b/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AddressService.kt deleted file mode 100644 index 3cab13df31..0000000000 --- a/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AddressService.kt +++ /dev/null @@ -1,23 +0,0 @@ -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.integrations.delius.audit.BusinessInteractionCode -import uk.gov.justice.digital.hmpps.integrations.delius.person.entity.PersonAddress -import uk.gov.justice.digital.hmpps.integrations.delius.person.entity.PersonAddressRepository - -@Service -class AddressService( - auditedInteractionService: AuditedInteractionService, - private val personAddressRepository: PersonAddressRepository -) : AuditableService(auditedInteractionService) { - - @Transactional - fun insertAddress(address: PersonAddress): PersonAddress = audit(BusinessInteractionCode.INSERT_ADDRESS) { audit -> - val savedAddress = personAddressRepository.save(address) - audit["offenderId"] = address.personId - savedAddress - } -} \ No newline at end of file diff --git a/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/PersonService.kt b/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/PersonService.kt index 7455ef7e18..7bb1900a02 100644 --- a/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/PersonService.kt +++ b/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/PersonService.kt @@ -1,7 +1,6 @@ package uk.gov.justice.digital.hmpps.service import org.springframework.jdbc.core.JdbcTemplate -import org.springframework.jdbc.core.SqlOutParameter import org.springframework.jdbc.core.simple.SimpleJdbcCall import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional @@ -9,8 +8,12 @@ import uk.gov.justice.digital.hmpps.audit.service.AuditableService import uk.gov.justice.digital.hmpps.audit.service.AuditedInteractionService import uk.gov.justice.digital.hmpps.integrations.delius.audit.BusinessInteractionCode import uk.gov.justice.digital.hmpps.integrations.delius.entity.* +import uk.gov.justice.digital.hmpps.integrations.delius.person.entity.PersonAddress +import uk.gov.justice.digital.hmpps.integrations.delius.person.entity.PersonAddressRepository +import uk.gov.justice.digital.hmpps.messaging.Address +import uk.gov.justice.digital.hmpps.messaging.Defendant import uk.gov.justice.digital.hmpps.messaging.Notifier -import java.sql.Types +import java.time.LocalDate import java.time.LocalDateTime @Service @@ -24,24 +27,21 @@ class PersonService( private val personManagerRepository: PersonManagerRepository, private val teamRepository: TeamRepository, private val staffRepository: StaffRepository, - private val referenceDataRepository: ReferenceDataRepository + private val referenceDataRepository: ReferenceDataRepository, + private val personAddressRepository: PersonAddressRepository ) : AuditableService(auditedInteractionService) { private val generateCrn = SimpleJdbcCall(jdbcTemplate) .withCatalogName("offender_support_api") - .withProcedureName("getNextCRN") - .withoutProcedureColumnMetaDataAccess() - .declareParameters( - SqlOutParameter("CRN", Types.VARCHAR) - ) + .withFunctionName("getNextCRN") @Transactional - fun insertPerson(person: Person, courtCode: String): Person = + fun insertPerson(defendant: Defendant, courtCode: String): Person = audit(BusinessInteractionCode.INSERT_PERSON) { audit -> // Person record - val savedPerson = personRepository.save(person) + val savedPerson = personRepository.save(defendant.toPerson()) - val courtLinkedProvider = courtRepository.findByNationalCourtCode(courtCode).probationArea + val courtLinkedProvider = courtRepository.getByOuCode(courtCode).provider val initialAllocation = referenceDataRepository.initialAllocationReason() val unallocatedTeam = teamRepository.findByCode(courtLinkedProvider.code + "UAT") val unallocatedStaff = staffRepository.findByCode(unallocatedTeam.code + "U") @@ -73,11 +73,76 @@ class PersonService( equalityRepository.save(equality) + val address = defendant.personDefendant?.personDetails?.address + if (address.containsInformation()) { + insertAddress( + PersonAddress( + id = null, + start = LocalDate.now(), + status = referenceDataRepository.mainAddressStatus(), + personId = savedPerson.id, + notes = address?.buildNotes(), + postcode = address?.postcode, + type = referenceDataRepository.awaitingAssessmentAddressType() + ) + ) + } audit["offenderId"] = savedPerson.id savedPerson } + @Transactional + fun insertAddress(address: PersonAddress): PersonAddress = audit(BusinessInteractionCode.INSERT_ADDRESS) { audit -> + val savedAddress = personAddressRepository.save(address) + audit["addressId"] = address.id!! + savedAddress + } + fun generateCrn(): String { - return generateCrn.execute()["CRN"] as String + return generateCrn.executeFunction(String::class.java) + } + + fun String.toDeliusGender() = ReferenceData.GenderCode.entries.find { it.commonPlatformValue == this }?.deliusValue + ?: throw IllegalStateException("Gender not found: $this") + + fun Defendant.toPerson(): Person { + val personDetails = personDefendant?.personDetails ?: throw IllegalArgumentException("No person found") + val genderCode = personDetails.gender.toDeliusGender() + + return Person( + id = null, + crn = generateCrn(), + croNumber = this.croNumber, + pncNumber = this.pncId, + forename = personDetails.firstName, + secondName = personDetails.middleName, + telephoneNumber = personDetails.contact?.home, + mobileNumber = personDetails.contact?.mobile, + surname = personDetails.lastName, + dateOfBirth = personDetails.dateOfBirth, + gender = referenceDataRepository.findByCodeAndDatasetCode(genderCode, DatasetCode.GENDER)!!, + softDeleted = false, + surnameSoundex = personRepository.getSoundex(personDetails.lastName), + middleNameSoundex = personDetails.middleName?.let { personRepository.getSoundex(it) }, + firstNameSoundex = personRepository.getSoundex(personDetails.firstName), + ) + } + + fun Address?.containsInformation(): Boolean { + return this != null && listOf( + this.address1, this.address2, this.address3, + this.address4, this.address5, this.postcode + ).any { !it.isNullOrBlank() } + } + + fun Address.buildNotes(): String { + return listOf( + "Address record automatically created by common-platform-delius-service with the following information:", + "Address1: ${this.address1 ?: "N/A"}", + "Address2: ${this.address2 ?: "N/A"}", + "Address3: ${this.address3 ?: "N/A"}", + "Address4: ${this.address4 ?: "N/A"}", + "Postcode: ${this.postcode ?: "N/A"}" + ).joinToString("\n") } } \ No newline at end of file diff --git a/projects/common-platform-and-delius/src/main/resources/application.yml b/projects/common-platform-and-delius/src/main/resources/application.yml index 52522fea63..d3c0873bb6 100644 --- a/projects/common-platform-and-delius/src/main/resources/application.yml +++ b/projects/common-platform-and-delius/src/main/resources/application.yml @@ -75,10 +75,6 @@ logging.level: spring.config.activate.on-profile: integration-test spring.datasource.url: jdbc:h2:mem:./test;MODE=Oracle;DEFAULT_NULL_ORDERING=HIGH ---- -spring.config.activate.on-profile: oracle -spring.datasource.url: 'jdbc:tc:oracle:slim-faststart:///XEPDB1' - --- spring.config.activate.on-profile: delius-db spring: diff --git a/projects/common-platform-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/messaging/HandlerTest.kt b/projects/common-platform-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/messaging/HandlerTest.kt index be7b3df781..abbc0d86fd 100644 --- a/projects/common-platform-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/messaging/HandlerTest.kt +++ b/projects/common-platform-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/messaging/HandlerTest.kt @@ -12,14 +12,9 @@ import org.mockito.kotlin.whenever import uk.gov.justice.digital.hmpps.converter.NotificationConverter import uk.gov.justice.digital.hmpps.data.generator.MessageGenerator import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator -import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator import uk.gov.justice.digital.hmpps.integrations.client.ProbationMatchResponse import uk.gov.justice.digital.hmpps.integrations.client.ProbationSearchClient -import uk.gov.justice.digital.hmpps.integrations.delius.entity.DatasetCode -import uk.gov.justice.digital.hmpps.integrations.delius.entity.ReferenceData -import uk.gov.justice.digital.hmpps.integrations.delius.entity.ReferenceDataRepository import uk.gov.justice.digital.hmpps.message.Notification -import uk.gov.justice.digital.hmpps.service.AddressService 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 @@ -35,12 +30,6 @@ internal class HandlerTest { @Mock lateinit var personService: PersonService - @Mock - lateinit var addressService: AddressService - - @Mock - lateinit var referenceDataRepository: ReferenceDataRepository - @Mock lateinit var probationSearchClient: ProbationSearchClient @@ -55,26 +44,7 @@ internal class HandlerTest { matchedBy = "NONE" ) ) - whenever(personService.generateCrn()).thenReturn("A111111") whenever(personService.insertPerson(any(), any())).thenReturn(PersonGenerator.DEFAULT) - whenever( - referenceDataRepository.findByCodeAndDatasetCode( - ReferenceData.GenderCode.MALE.deliusValue, - DatasetCode.GENDER - ) - ).thenReturn(ReferenceDataGenerator.GENDER_MALE) - whenever( - referenceDataRepository.findByCodeAndDatasetCode( - ReferenceData.StandardRefDataCode.ADDRESS_MAIN_STATUS.code, - DatasetCode.ADDRESS_STATUS - ) - ).thenReturn(ReferenceDataGenerator.MAIN_ADDRESS_STATUS) - whenever( - referenceDataRepository.findByCodeAndDatasetCode( - ReferenceData.StandardRefDataCode.AWAITING_ASSESSMENT.code, - DatasetCode.ADDRESS_TYPE - ) - ).thenReturn(ReferenceDataGenerator.AWAITING_ASSESSMENT) val notification = Notification(message = MessageGenerator.COMMON_PLATFORM_EVENT) handler.handle(notification) diff --git a/projects/common-platform-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/AddressServiceTest.kt b/projects/common-platform-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/AddressServiceTest.kt deleted file mode 100644 index c3ce313ce3..0000000000 --- a/projects/common-platform-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/AddressServiceTest.kt +++ /dev/null @@ -1,42 +0,0 @@ -package uk.gov.justice.digital.hmpps.service - -import org.hamcrest.MatcherAssert.assertThat -import org.hamcrest.Matchers.equalTo -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -import org.mockito.InjectMocks -import org.mockito.Mock -import org.mockito.Mockito.verify -import org.mockito.junit.jupiter.MockitoExtension -import org.mockito.kotlin.check -import org.mockito.kotlin.whenever -import uk.gov.justice.digital.hmpps.audit.service.AuditedInteractionService -import uk.gov.justice.digital.hmpps.data.generator.AddressGenerator -import uk.gov.justice.digital.hmpps.integrations.delius.person.entity.PersonAddressRepository - -@ExtendWith(MockitoExtension::class) -class AddressServiceTest { - @Mock - lateinit var auditedInteractionService: AuditedInteractionService - - @Mock - private lateinit var addressRepository: PersonAddressRepository - - @InjectMocks - private lateinit var addressService: AddressService - - @Test - fun `successfully inserts address record`() { - val mainAddress = AddressGenerator.MAIN_ADDRESS - whenever(addressRepository.save(mainAddress)).thenReturn(mainAddress) - - addressService.insertAddress(mainAddress) - - verify(addressRepository).save(check { - assertThat(it.personId, equalTo(mainAddress.personId)) - assertThat(it.start, equalTo(mainAddress.start)) - assertThat(it.status, equalTo(mainAddress.status)) - assertThat(it.type, equalTo(mainAddress.type)) - }) - } -} diff --git a/projects/common-platform-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/PersonServiceTest.kt b/projects/common-platform-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/PersonServiceTest.kt deleted file mode 100644 index 4bb05c1c2a..0000000000 --- a/projects/common-platform-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/PersonServiceTest.kt +++ /dev/null @@ -1,105 +0,0 @@ -package uk.gov.justice.digital.hmpps.service - -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Assertions.assertFalse -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -import org.mockito.InjectMocks -import org.mockito.Mock -import org.mockito.Mockito.anyString -import org.mockito.Mockito.verify -import org.mockito.junit.jupiter.MockitoExtension -import org.mockito.kotlin.any -import org.mockito.kotlin.argumentCaptor -import org.mockito.kotlin.whenever -import org.springframework.jdbc.core.JdbcTemplate -import uk.gov.justice.digital.hmpps.audit.service.AuditedInteractionService -import uk.gov.justice.digital.hmpps.data.generator.* -import uk.gov.justice.digital.hmpps.integrations.delius.entity.* -import uk.gov.justice.digital.hmpps.messaging.Notifier -import java.time.LocalDateTime - -@ExtendWith(MockitoExtension::class) -class PersonServiceTest { - @Mock - lateinit var auditedInteractionService: AuditedInteractionService - - @Mock - private lateinit var personRepository: PersonRepository - - @Mock - private lateinit var courtRepository: CourtRepository - - @Mock - private lateinit var equalityRepository: EqualityRepository - - @Mock - private lateinit var personManagerRepository: PersonManagerRepository - - @Mock - private lateinit var teamRepository: TeamRepository - - @Mock - private lateinit var staffRepository: StaffRepository - - @Mock - private lateinit var referenceDataRepository: ReferenceDataRepository - - @Mock - lateinit var notifier: Notifier - - @Mock - private lateinit var jdbcTemplate: JdbcTemplate - - @InjectMocks - private lateinit var personService: PersonService - - @Test - fun `insert person successfully inserts person, person manager and equality records`() { - val person = PersonGenerator.DEFAULT - val savedPerson = PersonGenerator.generate("A000002") - val court = CourtGenerator.UNKNOWN_COURT_N07_PROVIDER - val unallocatedTeam = TeamGenerator.UNALLOCATED - val unallocatedStaff = StaffGenerator.UNALLOCATED - val initialAllocation = ReferenceDataGenerator.INITIAL_ALLOCATION - - whenever(personRepository.save(person)).thenReturn(savedPerson) - whenever(courtRepository.findByNationalCourtCode(anyString())).thenReturn(court) - whenever( - referenceDataRepository.findByCodeAndDatasetCode( - ReferenceData.StandardRefDataCode.INITIAL_ALLOCATION.code, - DatasetCode.OM_ALLOCATION_REASON - ) - ).thenReturn(initialAllocation) - whenever(teamRepository.findByCode(anyString())).thenReturn(unallocatedTeam) - whenever(staffRepository.findByCode(anyString())).thenReturn(unallocatedStaff) - - personService.insertPerson(person, court.code) - verify(notifier).caseCreated(any()) - verify(personRepository).save(person) - verify(personManagerRepository).save(any()) - verify(equalityRepository).save(any()) - - // Verify person record is saved successfully - val personCaptor = argumentCaptor() - verify(personRepository).save(personCaptor.capture()) - assertEquals(person.forename, personCaptor.firstValue.forename) - assertEquals(person.surname, personCaptor.firstValue.surname) - assertEquals(person.gender, personCaptor.firstValue.gender) - - // Verify manager record is saved successfully - val managerCaptor = argumentCaptor() - verify(personManagerRepository).save(managerCaptor.capture()) - assertEquals(savedPerson, managerCaptor.firstValue.person) - assertEquals(unallocatedStaff, managerCaptor.firstValue.staff) - assertEquals(unallocatedTeam, managerCaptor.firstValue.team) - assertEquals(court.probationArea, managerCaptor.firstValue.provider) - assertEquals(LocalDateTime.of(1900, 1, 1, 0, 0), managerCaptor.firstValue.allocationDate) - - // Verify equality is created successfully - val equalityCaptor = argumentCaptor() - verify(equalityRepository).save(equalityCaptor.capture()) - assertEquals(savedPerson.id, equalityCaptor.firstValue.personId) - assertFalse(equalityCaptor.firstValue.softDeleted) - } -}