From aeb48b2c6e370e1528fe9c7576883e61bcf74f02 Mon Sep 17 00:00:00 2001 From: Anthony Britton <105213050+anthony-britton-moj@users.noreply.github.com> Date: Thu, 18 Apr 2024 16:31:36 +0100 Subject: [PATCH] PI-2110 (#3647) * PI-2110 * PI-2110 updated tests * PI-2110 added main address details * Formatting changes * Updated entity graph * PI-2110 * PI-2110 updated tests * PI-2110 added main address details * Formatting changes * Updated entity graph --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../justice/digital/hmpps/epf/entity/Event.kt | 2 + projects/oasys-and-delius/build.gradle.kts | 5 + .../justice/digital/hmpps/data/DataLoader.kt | 30 +++-- .../hmpps/data/generator/PersonGenerator.kt | 123 +++++++++++++++++- .../hmpps/data/generator/SentenceGenerator.kt | 4 +- .../justice/digital/hmpps/IntegrationTest.kt | 76 ++++++++++- .../hmpps/api/ProbationCaseResource.kt | 14 ++ .../digital/hmpps/api/model/CaseDetails.kt | 86 ++++++++++++ .../delius/person/entity/Person.kt | 79 ++++++++++- .../delius/person/entity/PersonAddress.kt | 61 +++++++++ .../hmpps/service/ProbationCaseService.kt | 28 ++++ .../hmpps/service/SentenceServiceTest.kt | 2 +- 12 files changed, 486 insertions(+), 24 deletions(-) create mode 100644 projects/oasys-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/ProbationCaseResource.kt create mode 100644 projects/oasys-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/CaseDetails.kt create mode 100644 projects/oasys-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integration/delius/person/entity/PersonAddress.kt create mode 100644 projects/oasys-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/ProbationCaseService.kt diff --git a/projects/effective-proposal-framework-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/epf/entity/Event.kt b/projects/effective-proposal-framework-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/epf/entity/Event.kt index 82193f0504..ca779e5b2a 100644 --- a/projects/effective-proposal-framework-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/epf/entity/Event.kt +++ b/projects/effective-proposal-framework-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/epf/entity/Event.kt @@ -3,6 +3,7 @@ package uk.gov.justice.digital.hmpps.epf.entity import jakarta.persistence.* import org.hibernate.annotations.Immutable import org.hibernate.annotations.SQLRestriction +import org.springframework.data.jpa.repository.EntityGraph import org.springframework.data.jpa.repository.JpaRepository import org.springframework.data.jpa.repository.Query import uk.gov.justice.digital.hmpps.exception.NotFoundException @@ -124,6 +125,7 @@ fun EventRepository.getEvent(crn: String, number: String) = findEventByCrnAndEventNumber(crn, number) ?: throw NotFoundException("Event", "crn", crn) interface KeyDateRepository : JpaRepository { + @EntityGraph(attributePaths = ["type"]) fun findByCustodyIdAndTypeCode(custodyId: Long, typeCode: String): KeyDate? } diff --git a/projects/oasys-and-delius/build.gradle.kts b/projects/oasys-and-delius/build.gradle.kts index a089a2f210..156e54efa8 100644 --- a/projects/oasys-and-delius/build.gradle.kts +++ b/projects/oasys-and-delius/build.gradle.kts @@ -30,7 +30,12 @@ dependencies { configure { jacocoExclusions = listOf( "**/config/**", + "**/model/**", "**/entity/**", "**/AppKt.class" ) + sonarExclusions = listOf( + "**/entity/**", + "**/model/**" + ) } diff --git a/projects/oasys-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt b/projects/oasys-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt index 4d4b4a8ee2..08bb73b0ff 100644 --- a/projects/oasys-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt +++ b/projects/oasys-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt @@ -7,20 +7,20 @@ import org.springframework.boot.context.event.ApplicationReadyEvent import org.springframework.context.ApplicationListener import org.springframework.stereotype.Component import org.springframework.transaction.annotation.Transactional -import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator +import uk.gov.justice.digital.hmpps.data.generator.* +import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator.CUSTODY_PERSON +import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator.DETAILED_PERSON import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator.REGISTERED_PERSON +import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator.RELEASED_PERSON import uk.gov.justice.digital.hmpps.data.generator.ProviderGenerator.DEFAULT_PROVIDER import uk.gov.justice.digital.hmpps.data.generator.ProviderGenerator.DEFAULT_TEAM import uk.gov.justice.digital.hmpps.data.generator.ProviderGenerator.JOHN_SMITH import uk.gov.justice.digital.hmpps.data.generator.ProviderGenerator.UNALLOCATED_STAFF -import uk.gov.justice.digital.hmpps.data.generator.RegistrationGenerator import uk.gov.justice.digital.hmpps.data.generator.RegistrationGenerator.ANOTHER_TYPE import uk.gov.justice.digital.hmpps.data.generator.RegistrationGenerator.CATEGORY import uk.gov.justice.digital.hmpps.data.generator.RegistrationGenerator.DEFAULT_TYPE import uk.gov.justice.digital.hmpps.data.generator.RegistrationGenerator.FLAG import uk.gov.justice.digital.hmpps.data.generator.RegistrationGenerator.LEVEL -import uk.gov.justice.digital.hmpps.data.generator.SentenceGenerator -import uk.gov.justice.digital.hmpps.data.generator.UserGenerator import uk.gov.justice.digital.hmpps.integration.delius.sentence.entity.Custody import uk.gov.justice.digital.hmpps.user.AuditUserRepository import java.time.ZonedDateTime @@ -41,6 +41,7 @@ class DataLoader( override fun onApplicationEvent(are: ApplicationReadyEvent) { referenceData() providerData() + personData() registrationData() custodialData() } @@ -51,7 +52,12 @@ class DataLoader( LEVEL, CATEGORY, DEFAULT_TYPE, - ANOTHER_TYPE + ANOTHER_TYPE, + PersonGenerator.GENDER, + PersonGenerator.ETHNICITY, + PersonGenerator.LANGUAGE, + PersonGenerator.RELIGION, + PersonGenerator.MAIN_ADDRESS_STATUS ) } @@ -64,8 +70,14 @@ class DataLoader( ) } + fun personData() { + entityManager.saveAll(REGISTERED_PERSON, RELEASED_PERSON, CUSTODY_PERSON, DETAILED_PERSON) + entityManager.flush() + entityManager.persist(PersonGenerator.DETAIL_ADDRESS) + } + fun registrationData() { - val person = REGISTERED_PERSON + val person = REGISTERED_PERSON.asPerson() val registration1 = RegistrationGenerator.generate(person) val review1 = RegistrationGenerator.generateReview(registration1) val registration2 = RegistrationGenerator.generate( @@ -77,7 +89,7 @@ class DataLoader( createdDateTime = ZonedDateTime.now().minusHours(1) ) val review2 = RegistrationGenerator.generateReview(registration2) - entityManager.saveAll(person, registration1, review1, registration2, review2) + entityManager.saveAll(registration1, review1, registration2, review2) } fun custodialData() { @@ -86,9 +98,7 @@ class DataLoader( SentenceGenerator.DEFAULT_INSTITUTION, SentenceGenerator.CUSTODY_STATUS, SentenceGenerator.RELEASE_TYPE, - SentenceGenerator.RECALL_REASON, - PersonGenerator.CUSTODY_PERSON, - PersonGenerator.RELEASED_PERSON + SentenceGenerator.RECALL_REASON ) persistCustody(SentenceGenerator.CUSTODIAL_SENTENCE) persistCustody(SentenceGenerator.RELEASED_SENTENCE) diff --git a/projects/oasys-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/PersonGenerator.kt b/projects/oasys-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/PersonGenerator.kt index 89457bfbae..79a74743ec 100644 --- a/projects/oasys-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/PersonGenerator.kt +++ b/projects/oasys-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/PersonGenerator.kt @@ -1,15 +1,130 @@ package uk.gov.justice.digital.hmpps.data.generator import uk.gov.justice.digital.hmpps.integration.delius.person.entity.Person +import uk.gov.justice.digital.hmpps.integration.delius.person.entity.PersonAddress +import uk.gov.justice.digital.hmpps.integration.delius.person.entity.PersonDetail +import uk.gov.justice.digital.hmpps.integration.delius.reference.entity.ReferenceData +import java.time.LocalDate object PersonGenerator { - val REGISTERED_PERSON = generate("R123456") - val RELEASED_PERSON = generate("B123456") - val CUSTODY_PERSON = generate("C123456") + val REGISTERED_PERSON = + generate("R123456", firstName = "Reginald", surname = "Regency", dob = LocalDate.now().minusYears(27)) + val RELEASED_PERSON = + generate("B123456", firstName = "Barry", surname = "Brown", dob = LocalDate.now().minusYears(39)) + val CUSTODY_PERSON = + generate("C123456", firstName = "Charles", surname = "Chaplin", dob = LocalDate.now().minusYears(42)) + + val GENDER = ReferenceDataGenerator.generate("GEN", "Gender") + val ETHNICITY = ReferenceDataGenerator.generate("ETH", "Ethnicity") + val LANGUAGE = ReferenceDataGenerator.generate("LAN", "Language") + val RELIGION = ReferenceDataGenerator.generate("REL", "Religion") + + val MAIN_ADDRESS_STATUS = ReferenceDataGenerator.generate(PersonAddress.MAIN_STATUS_CODE, "Main Address") + + val DETAILED_PERSON = + generate( + crn = "D123456", + firstName = "Daniel", + secondName = "David", + surname = "Danube", + dob = LocalDate.now().minusYears(36), + noms = "D1234YZ", + pnc = "2011/0593710D", + cro = "89861/11W", + gender = GENDER, + ethnicity = ETHNICITY, + language = LANGUAGE, + religion = RELIGION, + emailAddress = "dan@gmail.com", + telephoneNumber = "0191 256 7234", + mobileNumber = "07345617263" + ) + + val DETAIL_ADDRESS = generateAddress( + DETAILED_PERSON.id, + MAIN_ADDRESS_STATUS, + addressNumber = "23", + streetName = "Mantle Place", + postcode = "H34 7TH" + ) fun generate( + crn: String, + noms: String? = null, + pnc: String? = null, + cro: String? = null, + firstName: String, + secondName: String? = null, + thirdName: String? = null, + surname: String, + dob: LocalDate, + telephoneNumber: String? = null, + mobileNumber: String? = null, + emailAddress: String? = null, + gender: ReferenceData? = null, + ethnicity: ReferenceData? = null, + language: ReferenceData? = null, + religion: ReferenceData? = null, + softDeleted: Boolean = false, + id: Long = IdGenerator.getAndIncrement() + ) = PersonDetail( + crn, + noms, + pnc, + cro, + firstName, + secondName, + thirdName, + surname, + dob, + telephoneNumber, + mobileNumber, + emailAddress, + gender, + ethnicity, + language, + religion, + softDeleted, + id + ) + + fun generatePerson( crn: String, softDeleted: Boolean = false, id: Long = IdGenerator.getAndIncrement() ) = Person(crn, softDeleted, id) -} \ No newline at end of file + + fun generateAddress( + personId: Long, + status: ReferenceData, + noFixedAbode: Boolean = false, + buildingName: String? = null, + addressNumber: String? = null, + streetName: String? = null, + district: String? = null, + town: String? = null, + county: String? = null, + postcode: String? = null, + startDate: LocalDate = LocalDate.now().minusDays(1), + endDate: LocalDate? = null, + softDeleted: Boolean = false, + id: Long = IdGenerator.getAndIncrement() + ) = PersonAddress( + personId, + status, + buildingName, + addressNumber, + streetName, + district, + town, + county, + postcode, + noFixedAbode, + startDate, + endDate, + softDeleted, + id + ) +} + +fun PersonDetail.asPerson() = Person(crn, softDeleted, id) \ No newline at end of file diff --git a/projects/oasys-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/SentenceGenerator.kt b/projects/oasys-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/SentenceGenerator.kt index 9db498f852..a457ea0a6a 100644 --- a/projects/oasys-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/SentenceGenerator.kt +++ b/projects/oasys-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/SentenceGenerator.kt @@ -12,8 +12,8 @@ object SentenceGenerator { val CUSTODY_STATUS = ReferenceDataGenerator.generate("C") val RELEASE_TYPE = ReferenceDataGenerator.generate("REL") val RECALL_REASON = generateRecallReason("REC") - val CUSTODIAL_SENTENCE = generateCustodialSentence(PersonGenerator.CUSTODY_PERSON) - val RELEASED_SENTENCE = generateCustodialSentence(PersonGenerator.RELEASED_PERSON) + val CUSTODIAL_SENTENCE = generateCustodialSentence(PersonGenerator.CUSTODY_PERSON.asPerson()) + val RELEASED_SENTENCE = generateCustodialSentence(PersonGenerator.RELEASED_PERSON.asPerson()) val RELEASE = generateRelease(RELEASED_SENTENCE, date = ZonedDateTime.now().minusDays(1), institution = DEFAULT_INSTITUTION) val RECALL = generateRecall(RELEASE) diff --git a/projects/oasys-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/IntegrationTest.kt b/projects/oasys-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/IntegrationTest.kt index 5cf94716d0..fb4fcc85e2 100644 --- a/projects/oasys-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/IntegrationTest.kt +++ b/projects/oasys-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/IntegrationTest.kt @@ -19,7 +19,8 @@ import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status import uk.gov.justice.digital.hmpps.api.model.* import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator import uk.gov.justice.digital.hmpps.data.generator.SentenceGenerator -import uk.gov.justice.digital.hmpps.integration.delius.person.entity.Person +import uk.gov.justice.digital.hmpps.integration.delius.person.entity.PersonDetail +import uk.gov.justice.digital.hmpps.service.codeDescription import uk.gov.justice.digital.hmpps.telemetry.TelemetryService import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.contentAsJson import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withToken @@ -74,7 +75,7 @@ internal class IntegrationTest { @ParameterizedTest @MethodSource("custodialSentences") - fun `releases are correctly returned`(person: Person, releaseRecall: ReleaseRecall) { + fun `releases are correctly returned`(person: PersonDetail, releaseRecall: ReleaseRecall) { val res = mockMvc .perform(get("/probation-cases/${person.crn}/release").withToken()) .andExpect(status().is2xxSuccessful) @@ -83,6 +84,77 @@ internal class IntegrationTest { assertThat(res, equalTo(releaseRecall)) } + @Test + fun `should retrieve case details`() { + val person = PersonGenerator.DETAILED_PERSON + val address = PersonGenerator.DETAIL_ADDRESS + val res = mockMvc + .perform(get("/probation-cases/${person.crn}").withToken()) + .andExpect(status().is2xxSuccessful) + .andReturn().response.contentAsJson() + + assertThat( + res, equalTo( + CaseDetails( + Identifiers(person.crn, person.noms, person.pnc, person.cro), + Person( + Name( + person.surname, + person.firstName, + listOf(person.secondName!!) + ), + person.dob, + PersonGenerator.GENDER.codeDescription() + ), + Profile( + PersonGenerator.LANGUAGE.codeDescription(), + PersonGenerator.ETHNICITY.codeDescription(), + PersonGenerator.RELIGION.codeDescription() + ), + ContactDetails( + Address.from( + noFixedAbode = address.noFixedAbode, + buildingNumber = address.addressNumber, + streetName = address.streetName, + postcode = address.postcode + ), + person.emailAddress, + person.telephoneNumber, + person.mobileNumber + ) + ) + ) + ) + } + + @Test + fun `should retrieve minimal case details`() { + val person = PersonGenerator.REGISTERED_PERSON + val res = mockMvc + .perform(get("/probation-cases/${person.crn}").withToken()) + .andExpect(status().is2xxSuccessful) + .andReturn().response.contentAsJson() + + assertThat( + res, equalTo( + CaseDetails( + Identifiers(person.crn, person.noms, person.pnc, person.cro), + Person( + Name( + person.surname, + person.firstName, + listOf() + ), + person.dob, + null + ), + Profile.from(null, null, null), + ContactDetails.from(null, null, null) + ) + ) + ) + } + companion object { private val institution = SentenceGenerator.DEFAULT_INSTITUTION diff --git a/projects/oasys-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/ProbationCaseResource.kt b/projects/oasys-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/ProbationCaseResource.kt new file mode 100644 index 0000000000..9405358275 --- /dev/null +++ b/projects/oasys-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/ProbationCaseResource.kt @@ -0,0 +1,14 @@ +package uk.gov.justice.digital.hmpps.api + +import org.springframework.security.access.prepost.PreAuthorize +import org.springframework.web.bind.annotation.* +import uk.gov.justice.digital.hmpps.service.ProbationCaseService + +@RestController +@RequestMapping("probation-cases/{crn}") +class ProbationCaseResource(private val probationCaseService: ProbationCaseService) { + @PreAuthorize("hasRole('PROBATION_API__OASYS__CASE_DETAIL')") + @GetMapping + fun getCaseDetails(@PathVariable("crn") crn: String) = + probationCaseService.findCase(crn) +} \ No newline at end of file diff --git a/projects/oasys-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/CaseDetails.kt b/projects/oasys-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/CaseDetails.kt new file mode 100644 index 0000000000..bfec8a6aca --- /dev/null +++ b/projects/oasys-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/CaseDetails.kt @@ -0,0 +1,86 @@ +package uk.gov.justice.digital.hmpps.api.model + +import java.time.LocalDate + +data class CaseDetails( + val identifiers: Identifiers, + val person: Person, + val profile: Profile?, + val contactDetails: ContactDetails? +) + +data class Identifiers(val crn: String, val noms: String?, val pnc: String?, val cro: String?) +data class Person(val name: Name, val dateOfBirth: LocalDate, val gender: CodeDescription?) +data class Name(val surname: String, val forename: String, val middleNames: List) +data class Profile( + val language: CodeDescription?, + val ethnicity: CodeDescription?, + val religion: CodeDescription? +) { + companion object { + fun from( + language: CodeDescription?, + ethnicity: CodeDescription?, + religion: CodeDescription? + ): Profile? = + if (language == null && ethnicity == null && religion == null) { + null + } else { + Profile(language, ethnicity, religion) + } + } +} + +data class ContactDetails( + val mainAddress: Address?, + val emailAddress: String?, + val telephoneNumber: String?, + val mobileNumber: String? +) { + companion object { + fun from( + mainAddress: Address? = null, + emailAddress: String? = null, + telephoneNumber: String? = null, + mobileNumber: String? = null + ): ContactDetails? { + return if (mainAddress == null && emailAddress.isNullOrBlank() && telephoneNumber.isNullOrBlank() && mobileNumber.isNullOrBlank()) { + null + } else { + ContactDetails(mainAddress, emailAddress, telephoneNumber, mobileNumber) + } + } + } +} + +data class Address( + val noFixedAbode: Boolean, + val buildingName: String?, + val buildingNumber: String?, + val streetName: String?, + val district: String?, + val town: String?, + val county: String?, + val postcode: String? +) { + companion object { + fun from( + noFixedAbode: Boolean = false, + buildingName: String? = null, + buildingNumber: String? = null, + streetName: String? = null, + district: String? = null, + town: String? = null, + county: String? = null, + postcode: String? = null + ): Address? = + if ( + listOf(buildingName, buildingNumber, streetName, district, town, county, postcode) + .all(String?::isNullOrBlank) && !noFixedAbode + ) { + null + } else { + Address(noFixedAbode, buildingName, buildingNumber, streetName, district, town, county, postcode) + } + } +} \ No newline at end of file diff --git a/projects/oasys-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integration/delius/person/entity/Person.kt b/projects/oasys-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integration/delius/person/entity/Person.kt index d05fa4e995..d714072d72 100644 --- a/projects/oasys-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integration/delius/person/entity/Person.kt +++ b/projects/oasys-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integration/delius/person/entity/Person.kt @@ -1,11 +1,13 @@ package uk.gov.justice.digital.hmpps.integration.delius.person.entity -import jakarta.persistence.Column -import jakarta.persistence.Entity -import jakarta.persistence.Id -import jakarta.persistence.Table +import jakarta.persistence.* import org.hibernate.annotations.Immutable import org.hibernate.annotations.SQLRestriction +import org.springframework.data.jpa.repository.EntityGraph +import org.springframework.data.jpa.repository.JpaRepository +import uk.gov.justice.digital.hmpps.exception.NotFoundException +import uk.gov.justice.digital.hmpps.integration.delius.reference.entity.ReferenceData +import java.time.LocalDate @Entity @Immutable @@ -22,4 +24,71 @@ class Person( @Id @Column(name = "offender_id") val id: Long -) \ No newline at end of file +) + +@Immutable +@Entity +@Table(name = "offender") +@SQLRestriction("soft_deleted = 0") +class PersonDetail( + + @Column(columnDefinition = "char(7)") + val crn: String, + + @Column(name = "noms_number", columnDefinition = "char(7)") + val noms: String?, + + @Column(name = "pnc_number", columnDefinition = "char(13)") + val pnc: String?, + + @Column(name = "cro_number", columnDefinition = "char(12)") + val cro: String?, + + val firstName: String, + val secondName: String?, + val thirdName: String?, + val surname: String, + + @Column(name = "date_of_birth_date") + val dob: LocalDate, + + @Column(name = "telephone_number") + val telephoneNumber: String?, + + @Column(name = "mobile_number") + val mobileNumber: String?, + + @Column(name = "e_mail_address") + val emailAddress: String?, + + @ManyToOne + @JoinColumn(name = "gender_id") + val gender: ReferenceData?, + + @ManyToOne + @JoinColumn(name = "ethnicity_id") + val ethnicity: ReferenceData?, + + @ManyToOne + @JoinColumn(name = "language_id") + val language: ReferenceData?, + + @ManyToOne + @JoinColumn(name = "religion_id") + val religion: ReferenceData?, + + @Column(columnDefinition = "number") + val softDeleted: Boolean, + + @Id + @Column(name = "offender_id") + val id: Long +) + +interface PersonDetailRepository : JpaRepository { + @EntityGraph(attributePaths = ["gender", "ethnicity", "language", "religion"]) + fun findByCrn(crn: String): PersonDetail? +} + +fun PersonDetailRepository.getPersonDetail(crn: String): PersonDetail = + findByCrn(crn) ?: throw NotFoundException("Person", "crn", crn) \ No newline at end of file diff --git a/projects/oasys-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integration/delius/person/entity/PersonAddress.kt b/projects/oasys-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integration/delius/person/entity/PersonAddress.kt new file mode 100644 index 0000000000..4ce1066f8c --- /dev/null +++ b/projects/oasys-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integration/delius/person/entity/PersonAddress.kt @@ -0,0 +1,61 @@ +package uk.gov.justice.digital.hmpps.integration.delius.person.entity + +import jakarta.persistence.* +import org.hibernate.annotations.Immutable +import org.hibernate.annotations.SQLRestriction +import org.hibernate.type.YesNoConverter +import org.springframework.data.jpa.repository.EntityGraph +import org.springframework.data.jpa.repository.JpaRepository +import uk.gov.justice.digital.hmpps.integration.delius.person.entity.PersonAddress.Companion.MAIN_STATUS_CODE +import uk.gov.justice.digital.hmpps.integration.delius.reference.entity.ReferenceData +import java.time.LocalDate + +@Immutable +@Entity +@Table(name = "offender_address") +@SQLRestriction("soft_deleted = 0 and end_date is null") +class PersonAddress( + + @Column(name = "offender_id") + val personId: Long, + + @ManyToOne + @JoinColumn(name = "address_status_id") + val status: ReferenceData, + + @Column(name = "building_name") + val buildingName: String?, + @Column(name = "address_number") + val addressNumber: String?, + @Column(name = "street_name") + val streetName: String?, + val district: String?, + @Column(name = "town_city") + val town: String?, + val county: String?, + val postcode: String?, + + @Convert(converter = YesNoConverter::class) + val noFixedAbode: Boolean, + val startDate: LocalDate, + val endDate: LocalDate?, + + @Column(columnDefinition = "number") + val softDeleted: Boolean, + + @Id + @Column(name = "offender_address_id") + val id: Long +) { + companion object { + const val MAIN_STATUS_CODE = "M" + } +} + +interface PersonAddressRepository : JpaRepository { + @EntityGraph(attributePaths = ["status"]) + fun findByPersonIdAndStatusCodeOrderByStartDateDesc(personId: Long, statusCode: String): List +} + +fun PersonAddressRepository.mainAddress(personId: Long) = + findByPersonIdAndStatusCodeOrderByStartDateDesc(personId, MAIN_STATUS_CODE).firstOrNull() \ No newline at end of file diff --git a/projects/oasys-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/ProbationCaseService.kt b/projects/oasys-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/ProbationCaseService.kt new file mode 100644 index 0000000000..239ec47857 --- /dev/null +++ b/projects/oasys-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/ProbationCaseService.kt @@ -0,0 +1,28 @@ +package uk.gov.justice.digital.hmpps.service + +import org.springframework.stereotype.Service +import uk.gov.justice.digital.hmpps.api.model.* +import uk.gov.justice.digital.hmpps.api.model.Person +import uk.gov.justice.digital.hmpps.integration.delius.person.entity.* + +@Service +class ProbationCaseService( + private val personDetailRepository: PersonDetailRepository, + private val personAddressRepository: PersonAddressRepository +) { + fun findCase(crn: String): CaseDetails = + personDetailRepository.getPersonDetail(crn).asCaseDetail() + + fun PersonDetail.asCaseDetail(): CaseDetails { + val mainAddress = personAddressRepository.mainAddress(id)?.asAddress() + return CaseDetails( + Identifiers(crn, noms?.trim(), pnc?.trim(), cro?.trim()), + Person(Name(surname, firstName, listOfNotNull(secondName, thirdName)), dob, gender?.codeDescription()), + Profile.from(language?.codeDescription(), ethnicity?.codeDescription(), religion?.codeDescription()), + ContactDetails.from(mainAddress, emailAddress, telephoneNumber, mobileNumber) + ) + } + + fun PersonAddress.asAddress() = + Address(noFixedAbode, buildingName, addressNumber, streetName, district, town, county, postcode) +} \ No newline at end of file diff --git a/projects/oasys-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/SentenceServiceTest.kt b/projects/oasys-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/SentenceServiceTest.kt index be82c7158f..8773b511b0 100644 --- a/projects/oasys-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/SentenceServiceTest.kt +++ b/projects/oasys-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/SentenceServiceTest.kt @@ -35,7 +35,7 @@ internal class SentenceServiceTest { @Test fun `multiple custodial sentences throws exception`() { - val person = PersonGenerator.generate("M123456") + val person = PersonGenerator.generatePerson("M123456") val sentences = listOf( SentenceGenerator.generateCustodialSentence(person), SentenceGenerator.generateCustodialSentence(person)