diff --git a/projects/court-case-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt b/projects/court-case-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt index 89c48ee538..4dc264c52b 100644 --- a/projects/court-case-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt +++ b/projects/court-case-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt @@ -8,21 +8,7 @@ import org.springframework.context.ApplicationListener import org.springframework.stereotype.Component import org.springframework.transaction.annotation.Transactional import uk.gov.justice.digital.hmpps.api.model.DocumentType -import uk.gov.justice.digital.hmpps.data.generator.BoroughGenerator -import uk.gov.justice.digital.hmpps.data.generator.BusinessInteractionGenerator -import uk.gov.justice.digital.hmpps.data.generator.ContactTypeGenerator -import uk.gov.justice.digital.hmpps.data.generator.CourtCaseNoteGenerator -import uk.gov.justice.digital.hmpps.data.generator.DistrictGenerator -import uk.gov.justice.digital.hmpps.data.generator.DocumentEntityGenerator -import uk.gov.justice.digital.hmpps.data.generator.IdGenerator -import uk.gov.justice.digital.hmpps.data.generator.LDUGenerator -import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator -import uk.gov.justice.digital.hmpps.data.generator.ProviderGenerator -import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator -import uk.gov.justice.digital.hmpps.data.generator.SentenceGenerator -import uk.gov.justice.digital.hmpps.data.generator.StaffGenerator -import uk.gov.justice.digital.hmpps.data.generator.TeamGenerator -import uk.gov.justice.digital.hmpps.data.generator.UserGenerator +import uk.gov.justice.digital.hmpps.data.generator.* import uk.gov.justice.digital.hmpps.integrations.delius.event.courtappearance.entity.Outcome import uk.gov.justice.digital.hmpps.user.AuditUserRepository import java.time.LocalDate @@ -58,10 +44,7 @@ class DataLoader( SentenceGenerator.ADDITIONAL_OFFENCE, BusinessInteractionGenerator.UPDATE_CONTACT, ContactTypeGenerator.CONTACT_TYPE, - PersonGenerator.NEW_TO_PROBATION, - PersonGenerator.CURRENTLY_MANAGED, - PersonGenerator.PREVIOUSLY_MANAGED, - PersonGenerator.NO_SENTENCE, + ReferenceDataGenerator.DISPOSAL_TYPE, ReferenceDataGenerator.LENGTH_UNITS, ReferenceDataGenerator.TERMINATION_REASON, @@ -76,7 +59,29 @@ class DataLoader( ReferenceDataGenerator.NSI_BREACH_OUTCOME, ReferenceDataGenerator.PSS_MAIN_CAT, ReferenceDataGenerator.PSS_SUB_CAT, - ReferenceDataGenerator.COURT_REPORT_TYPE + ReferenceDataGenerator.COURT_REPORT_TYPE, + ReferenceDataGenerator.GENDER_MALE, + ReferenceDataGenerator.PROVISION_TYPE_1, + ReferenceDataGenerator.PROVISION_CATEGORY_1, + ReferenceDataGenerator.DISABILITY_TYPE_1, + ReferenceDataGenerator.DISABILITY_CONDITION_1, + ReferenceDataGenerator.GENDER_IDENTITY, + ReferenceDataGenerator.ETHNICITY, + ReferenceDataGenerator.IMMIGRATION_STATUS, + ReferenceDataGenerator.NATIONALITY, + ReferenceDataGenerator.LANGUAGE_ENG, + ReferenceDataGenerator.RELIGION, + ReferenceDataGenerator.SECOND_NATIONALITY, + ReferenceDataGenerator.SEXUAL_ORIENTATION, + ReferenceDataGenerator.TITLE, + PersonGenerator.PARTITION_AREA, + PersonGenerator.NEW_TO_PROBATION, + PersonGenerator.CURRENTLY_MANAGED, + PersonGenerator.PREVIOUSLY_MANAGED, + PersonGenerator.NO_SENTENCE, + PersonGenerator.PROVISION_1, + PersonGenerator.DISABILITY_1, + PersonGenerator.PREVIOUS_CONVICTION_DOC ) em.saveAll(StaffGenerator.ALLOCATED, StaffGenerator.UNALLOCATED) diff --git a/projects/court-case-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/DocumentEntityGenerator.kt b/projects/court-case-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/DocumentEntityGenerator.kt index c433fb19f9..a2512d1d9c 100644 --- a/projects/court-case-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/DocumentEntityGenerator.kt +++ b/projects/court-case-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/DocumentEntityGenerator.kt @@ -22,7 +22,7 @@ object DocumentEntityGenerator { val R_INSTITUTION = Institution(IdGenerator.getAndIncrement(), "test", false) - fun generateDocument(personId: Long, primaryKeyId: Long, type: String, tableName: String) = + fun generateDocument(personId: Long, primaryKeyId: Long?, type: String, tableName: String?) = DocumentEntity( IdGenerator.getAndIncrement(), personId, @@ -31,6 +31,7 @@ object DocumentEntityGenerator { "filename.txt", type, tableName, - ZonedDateTime.now() + ZonedDateTime.now(), + lastUpdated = ZonedDateTime.now() ) } diff --git a/projects/court-case-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/PersonGenerator.kt b/projects/court-case-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/PersonGenerator.kt index 985c765060..a13fd18b41 100644 --- a/projects/court-case-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/PersonGenerator.kt +++ b/projects/court-case-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/PersonGenerator.kt @@ -1,17 +1,88 @@ package uk.gov.justice.digital.hmpps.data.generator -import uk.gov.justice.digital.hmpps.integrations.delius.person.entity.Person -import uk.gov.justice.digital.hmpps.integrations.delius.person.entity.PersonManager +import uk.gov.justice.digital.hmpps.api.model.DocumentType +import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator.DISABILITY_CONDITION_1 +import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator.DISABILITY_TYPE_1 +import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator.ETHNICITY +import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator.GENDER_IDENTITY +import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator.GENDER_MALE +import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator.IMMIGRATION_STATUS +import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator.LANGUAGE_ENG +import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator.NATIONALITY +import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator.PROVISION_CATEGORY_1 +import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator.PROVISION_TYPE_1 +import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator.RELIGION +import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator.SECOND_NATIONALITY +import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator.SEXUAL_ORIENTATION +import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator.TITLE +import uk.gov.justice.digital.hmpps.integrations.delius.person.entity.* +import java.time.LocalDate import java.time.ZonedDateTime object PersonGenerator { + val PARTITION_AREA = PartitionArea(IdGenerator.getAndIncrement(), "Partition Area") val NEW_TO_PROBATION = generate("N123456") - val CURRENTLY_MANAGED = generate("C123456") + val CURRENTLY_MANAGED = generate("C123456", currentDisposal = true) val PREVIOUSLY_MANAGED = generate("P123456") val NO_SENTENCE = generate("U123456") + val PROVISION_1 = generateProvision(CURRENTLY_MANAGED.id, null) + val DISABILITY_1 = generateDisability(CURRENTLY_MANAGED.id, null) - fun generate(crn: String, softDeleted: Boolean = false, id: Long = IdGenerator.getAndIncrement()) = - Person(crn, softDeleted, id) + val PREVIOUS_CONVICTION_DOC = DocumentEntityGenerator.generateDocument( + personId = CURRENTLY_MANAGED.id, + primaryKeyId = null, + DocumentType.PREVIOUS_CONVICTION.name, + null + ) + + fun generate( + crn: String, + softDeleted: Boolean = false, + id: Long = IdGenerator.getAndIncrement(), + currentDisposal: Boolean = false + ) = + Person( + id = id, + crn = crn, + softDeleted = softDeleted, + emailAddress = "test@test.none", + currentDisposal = currentDisposal, + currentExclusion = false, + currentRestriction = false, + currentHighestRiskColour = "RED", + dateOfBirth = LocalDate.of(1977, 8, 12), + partitionArea = PARTITION_AREA, + allowSms = true, + mobileNumber = "07876545678", + telephoneNumber = "0161786567", + forename = "TestForename", + secondName = "MiddleName", + thirdName = "OtherMiddleName", + gender = GENDER_MALE, + surname = "TestSurname", + preferredName = "Other name", + offenderDetails = "Some details", + genderIdentity = GENDER_IDENTITY, + genderIdentityDescription = "Some self described gender identity", + ethnicity = ETHNICITY, + immigrationStatus = IMMIGRATION_STATUS, + nationality = NATIONALITY, + language = LANGUAGE_ENG, + languageConcerns = "A concern", + requiresInterpreter = false, + currentRemandStatus = "Remand Status", + secondNationality = SECOND_NATIONALITY, + sexualOrientation = SEXUAL_ORIENTATION, + religion = RELIGION, + niNumber = "JK002213K", + pnc = "1234567890123", + nomsNumber = "NOMS123", + croNumber = "CRO123", + immigrationNumber = "IMA123", + mostRecentPrisonerNumber = "PRS123", + previousSurname = "Previous", + title = TITLE + ) fun generatePersonManager(person: Person) = PersonManager( @@ -22,4 +93,26 @@ object PersonGenerator { ProviderGenerator.DEFAULT, ZonedDateTime.now() ) + + fun generateProvision(personId: Long, end: LocalDate?) = Provision( + id = IdGenerator.getAndIncrement(), + personId = personId, + type = PROVISION_TYPE_1, + startDate = LocalDate.now().minusDays(1), + lastUpdated = LocalDate.now().minusDays(1), + category = PROVISION_CATEGORY_1, + notes = null, + finishDate = end, + ) + + fun generateDisability(personId: Long, end: LocalDate?) = Disability( + id = IdGenerator.getAndIncrement(), + personId = personId, + type = DISABILITY_TYPE_1, + startDate = LocalDate.now().minusDays(1), + lastUpdated = ZonedDateTime.now().minusDays(1), + condition = DISABILITY_CONDITION_1, + notes = null, + finishDate = end, + ) } diff --git a/projects/court-case-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ReferenceDataGenerator.kt b/projects/court-case-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ReferenceDataGenerator.kt index c99f5a8d06..0dbb4898f9 100644 --- a/projects/court-case-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ReferenceDataGenerator.kt +++ b/projects/court-case-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ReferenceDataGenerator.kt @@ -91,4 +91,88 @@ object ReferenceDataGenerator { "court report", IdGenerator.getAndIncrement() ) + + val GENDER_MALE = ReferenceData( + "MALE", + "Male", + IdGenerator.getAndIncrement() + ) + + val PROVISION_TYPE_1 = ReferenceData( + "PROV1", + "Provision type 1", + IdGenerator.getAndIncrement() + ) + + val PROVISION_CATEGORY_1 = ReferenceData( + "PROV1", + "Provision type 1", + IdGenerator.getAndIncrement() + ) + + val DISABILITY_TYPE_1 = ReferenceData( + "DIS1", + "Disability type 1", + IdGenerator.getAndIncrement() + ) + + val DISABILITY_CONDITION_1 = ReferenceData( + "DISCON1", + "Disability Condition 1", + IdGenerator.getAndIncrement() + ) + + val GENDER_IDENTITY = ReferenceData( + "GEN", + "Some gender identity", + IdGenerator.getAndIncrement() + ) + + val ETHNICITY = ReferenceData( + "ETH", + "Some ethnicity", + IdGenerator.getAndIncrement() + ) + + val IMMIGRATION_STATUS = ReferenceData( + "ETH", + "Some immigration status", + IdGenerator.getAndIncrement() + ) + + val NATIONALITY = ReferenceData( + "BRIT", + "British", + IdGenerator.getAndIncrement() + ) + + val LANGUAGE_ENG = ReferenceData( + "ENG", + "English", + IdGenerator.getAndIncrement() + ) + + val RELIGION = ReferenceData( + "REL", + "A Relgion", + IdGenerator.getAndIncrement() + ) + + val SECOND_NATIONALITY = ReferenceData( + "FRE", + "French", + IdGenerator.getAndIncrement() + ) + + val SEXUAL_ORIENTATION = ReferenceData( + "SO", + "A sexual orientation", + IdGenerator.getAndIncrement() + ) + + val TITLE = ReferenceData( + "MR", + "Mr", + IdGenerator.getAndIncrement() + ) } diff --git a/projects/court-case-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/OffenderIntegrationTest.kt b/projects/court-case-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/OffenderIntegrationTest.kt index 53add5487b..1e401d34c8 100644 --- a/projects/court-case-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/OffenderIntegrationTest.kt +++ b/projects/court-case-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/OffenderIntegrationTest.kt @@ -1,27 +1,26 @@ package uk.gov.justice.digital.hmpps -import com.fasterxml.jackson.databind.ObjectMapper -import com.github.tomakehurst.wiremock.WireMockServer -import org.assertj.core.api.Assertions +import org.hamcrest.MatcherAssert.assertThat +import org.hamcrest.Matchers.equalTo import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT -import org.springframework.boot.test.mock.mockito.MockBean import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status -import uk.gov.justice.digital.hmpps.api.model.DocumentType -import uk.gov.justice.digital.hmpps.api.model.ProbationRecord +import software.amazon.awssdk.utils.ImmutableMap +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.StaffGenerator -import uk.gov.justice.digital.hmpps.data.generator.TeamGenerator -import uk.gov.justice.digital.hmpps.telemetry.TelemetryService +import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator.PARTITION_AREA +import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator.PREVIOUS_CONVICTION_DOC +import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator.DISABILITY_TYPE_1 +import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator.PROVISION_TYPE_1 +import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator.RELIGION import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.contentAsJson import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withToken import java.time.LocalDate -import java.time.format.DateTimeFormatter @AutoConfigureMockMvc @SpringBootTest(webEnvironment = RANDOM_PORT) @@ -29,103 +28,108 @@ internal class OffenderIntegrationTest { @Autowired lateinit var mockMvc: MockMvc - @Autowired - lateinit var wireMockServer: WireMockServer - - @MockBean - lateinit var telemetryService: TelemetryService - - @Autowired - lateinit var objectMapper: ObjectMapper - @Test - fun `API call retuns probation record`() { + fun `API call retuns probation record with active sentence`() { val crn = PersonGenerator.CURRENTLY_MANAGED.crn val detailResponse = mockMvc .perform(get("/probation-case/$crn").withToken()) .andExpect(status().is2xxSuccessful) - .andReturn().response.contentAsJson() - - val todaysDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) - val futureDate = LocalDate.now().plusDays(5).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) - - Assertions.assertThat(detailResponse.crn).isEqualTo(crn) - Assertions.assertThat(detailResponse.offenderManagers[0].staff.forenames) - .isEqualTo(StaffGenerator.ALLOCATED.forename + " " + StaffGenerator.ALLOCATED.forename2) - Assertions.assertThat(detailResponse.offenderManagers[0].staff.surname) - .isEqualTo(StaffGenerator.ALLOCATED.surname) - Assertions.assertThat(detailResponse.offenderManagers[0].team.description) - .isEqualTo(TeamGenerator.DEFAULT.description) - - Assertions.assertThat(detailResponse.convictions[0].inBreach).isEqualTo(true) - Assertions.assertThat(detailResponse.convictions[0].active).isEqualTo(true) - Assertions.assertThat(detailResponse.convictions[0].awaitingPsr).isEqualTo(false) - Assertions.assertThat(detailResponse.convictions[0].convictionDate).isEqualTo(todaysDate) - - Assertions.assertThat(detailResponse.convictions[0].offences[0].description).isEqualTo("Main Offence") - Assertions.assertThat(detailResponse.convictions[0].offences[0].main).isEqualTo(true) - Assertions.assertThat(detailResponse.convictions[0].offences[0].offenceDate).isEqualTo(todaysDate) - Assertions.assertThat(detailResponse.convictions[0].offences[1].description).isEqualTo("Additional Offence") - Assertions.assertThat(detailResponse.convictions[0].offences[1].main).isEqualTo(false) - Assertions.assertThat(detailResponse.convictions[0].offences[1].offenceDate).isEqualTo(todaysDate) - Assertions.assertThat(detailResponse.convictions[0].sentence?.description).isEqualTo("Disposal type") - Assertions.assertThat(detailResponse.convictions[0].sentence?.length).isEqualTo(12) - Assertions.assertThat(detailResponse.convictions[0].sentence?.lengthUnits).isEqualTo("Days") - Assertions.assertThat(detailResponse.convictions[0].sentence?.lengthInDays).isEqualTo(99) - Assertions.assertThat(detailResponse.convictions[0].sentence?.startDate).isEqualTo(todaysDate) - - Assertions.assertThat(detailResponse.convictions[0].custodialType?.code).isEqualTo("C1") - Assertions.assertThat(detailResponse.convictions[0].custodialType?.description).isEqualTo("Custodial status") - - Assertions.assertThat(detailResponse.convictions[0].documents[0].documentName).isEqualTo("filename.txt") - Assertions.assertThat(detailResponse.convictions[0].documents[0].type) - .isEqualTo(DocumentType.CONVICTION_DOCUMENT) - Assertions.assertThat(detailResponse.convictions[0].documents[0].subType?.code).isEqualTo("EVENT") - Assertions.assertThat(detailResponse.convictions[0].documents[0].subType?.description) - .isEqualTo("Sentence related") - - Assertions.assertThat(detailResponse.convictions[0].breaches[0].description).isEqualTo("NSI Type desc") - Assertions.assertThat(detailResponse.convictions[0].breaches[0].status).isEqualTo("this NSI is in breach") - Assertions.assertThat(detailResponse.convictions[0].breaches[0].started).isEqualTo(todaysDate) - Assertions.assertThat(detailResponse.convictions[0].breaches[0].statusDate).isEqualTo(todaysDate) - - Assertions.assertThat(detailResponse.convictions[0].requirements[0].commencementDate).isEqualTo(todaysDate) - Assertions.assertThat(detailResponse.convictions[0].requirements[0].active).isEqualTo(true) - Assertions.assertThat(detailResponse.convictions[0].requirements[0].requirementTypeMainCategory?.description) - .isEqualTo("Main cat") - Assertions.assertThat(detailResponse.convictions[0].requirements[0].requirementTypeMainCategory?.code) - .isEqualTo("Main") - Assertions.assertThat(detailResponse.convictions[0].requirements[0].requirementTypeSubCategory?.description) - .isEqualTo("Sub cat") - Assertions.assertThat(detailResponse.convictions[0].requirements[0].requirementTypeSubCategory?.code) - .isEqualTo("Sub") - - Assertions.assertThat(detailResponse.convictions[0].requirements[0].adRequirementTypeMainCategory?.description) - .isEqualTo("AdMain cat") - Assertions.assertThat(detailResponse.convictions[0].requirements[0].adRequirementTypeMainCategory?.code) - .isEqualTo("AdMain") - Assertions.assertThat(detailResponse.convictions[0].requirements[0].adRequirementTypeSubCategory?.description) - .isEqualTo("AdSub cat") - Assertions.assertThat(detailResponse.convictions[0].requirements[0].adRequirementTypeSubCategory?.code) - .isEqualTo("AdSub") - - Assertions.assertThat(detailResponse.convictions[0].pssRequirements[0].description).isEqualTo("pss main") - Assertions.assertThat(detailResponse.convictions[0].pssRequirements[0].subTypeDescription).isEqualTo("pss sub") + .andReturn().response.contentAsJson() + assertThat(detailResponse.preferredName, equalTo("Other name")) + assertThat(detailResponse.softDeleted, equalTo(false)) + assertThat(detailResponse.activeProbationManagedSentence, equalTo(true)) + assertThat( + detailResponse.contactDetails.phoneNumbers, equalTo( + listOf( + PhoneNumber( + PersonGenerator.CURRENTLY_MANAGED.telephoneNumber, + PhoneTypes.TELEPHONE.name + ), PhoneNumber( + PersonGenerator.CURRENTLY_MANAGED.mobileNumber, + PhoneTypes.MOBILE.name + ) + ) + ) + ) + assertThat(detailResponse.contactDetails.allowSMS, equalTo(true)) + assertThat(detailResponse.contactDetails.emailAddresses, equalTo(listOf("test@test.none"))) + assertThat(detailResponse.currentDisposal, equalTo("1")) + assertThat(detailResponse.currentExclusion, equalTo(false)) + assertThat(detailResponse.currentRestriction, equalTo(false)) + assertThat(detailResponse.dateOfBirth, equalTo(LocalDate.of(1977, 8, 12))) + assertThat(detailResponse.firstName, equalTo("TestForename")) + assertThat(detailResponse.middleNames, equalTo(listOf("MiddleName", "OtherMiddleName"))) + assertThat(detailResponse.offenderId, equalTo(PersonGenerator.CURRENTLY_MANAGED.id)) + assertThat(detailResponse.offenderProfile.genderIdentity, equalTo("Some gender identity")) + assertThat( + detailResponse.offenderProfile.selfDescribedGenderIdentity, + equalTo("Some self described gender identity") + ) + assertThat( + detailResponse.offenderProfile.selfDescribedGenderIdentity, + equalTo("Some self described gender identity") + ) + assertThat( + detailResponse.offenderProfile.disabilities[0].disabilityType.description, + equalTo(DISABILITY_TYPE_1.description) + ) + assertThat(detailResponse.offenderProfile.ethnicity, equalTo("Some ethnicity")) + assertThat(detailResponse.offenderProfile.immigrationStatus, equalTo("Some immigration status")) + assertThat(detailResponse.offenderProfile.nationality, equalTo("British")) + assertThat(detailResponse.offenderProfile.offenderDetails, equalTo("Some details")) + assertThat( + detailResponse.offenderProfile.offenderLanguages, equalTo( + OffenderLanguages( + languageConcerns = "A concern", + primaryLanguage = "English", + requiresInterpreter = false + ) + ) + ) + assertThat( + detailResponse.offenderProfile.previousConviction, equalTo( + PreviousConviction( + convictionDate = PREVIOUS_CONVICTION_DOC.createdAt.toLocalDate(), + detail = ImmutableMap.of("documentName", PREVIOUS_CONVICTION_DOC.name) + ) + ) + ) + assertThat( + detailResponse.offenderProfile.provisions[0].provisionType.description, + equalTo(PROVISION_TYPE_1.description) + ) + assertThat(detailResponse.offenderProfile.religion, equalTo(RELIGION.description)) + assertThat(detailResponse.offenderProfile.remandStatus, equalTo("Remand Status")) + assertThat(detailResponse.offenderProfile.riskColour, equalTo("RED")) + assertThat(detailResponse.offenderProfile.secondaryNationality, equalTo("French")) + assertThat(detailResponse.offenderProfile.sexualOrientation, equalTo("A sexual orientation")) + assertThat(detailResponse.otherIds.crn, equalTo(crn)) + assertThat(detailResponse.otherIds.niNumber, equalTo("JK002213K")) + assertThat(detailResponse.otherIds.pncNumber, equalTo("1234567890123")) + assertThat(detailResponse.otherIds.nomsNumber, equalTo("NOMS123")) + assertThat(detailResponse.otherIds.croNumber, equalTo("CRO123")) + assertThat(detailResponse.otherIds.immigrationNumber, equalTo("IMA123")) + assertThat(detailResponse.otherIds.mostRecentPrisonerNumber, equalTo("PRS123")) + assertThat(detailResponse.partitionArea, equalTo(PARTITION_AREA.area)) + assertThat(detailResponse.previousSurname, equalTo("Previous")) + assertThat(detailResponse.surname, equalTo("TestSurname")) + } - Assertions.assertThat(detailResponse.convictions[0].licenceConditions[0].description).isEqualTo("lic cond main") - Assertions.assertThat(detailResponse.convictions[0].licenceConditions[0].subTypeDescription) - .isEqualTo("Lic Sub cat") - Assertions.assertThat(detailResponse.convictions[0].licenceConditions[0].startDate).isEqualTo(todaysDate) - Assertions.assertThat(detailResponse.convictions[0].licenceConditions[0].notes) - .isEqualTo("Licence Condition notes") + @Test + fun `API call probation record not found`() { + mockMvc + .perform(get("/probation-case/A123456").withToken()) + .andExpect(status().isNotFound) + } - Assertions.assertThat(detailResponse.convictions[0].courtReports[0].requestedDate).isEqualTo(todaysDate) - Assertions.assertThat(detailResponse.convictions[0].courtReports[0].requiredDate).isEqualTo(futureDate) - Assertions.assertThat(detailResponse.convictions[0].courtReports[0].courtReportType?.description) - .isEqualTo("court report") - Assertions.assertThat(detailResponse.convictions[0].courtReports[0].courtReportType?.code).isEqualTo("CR1") - Assertions.assertThat(detailResponse.convictions[0].courtReports[0].author?.forenames).isEqualTo("Bob Micheal") - Assertions.assertThat(detailResponse.convictions[0].courtReports[0].author?.surname).isEqualTo("Smith") - Assertions.assertThat(detailResponse.convictions[0].courtReports[0].author?.unallocated).isEqualTo(false) + @Test + fun `API call retuns probation record with no active sentence`() { + val crn = PersonGenerator.NO_SENTENCE.crn + val detailResponse = mockMvc + .perform(get("/probation-case/$crn").withToken()) + .andExpect(status().is2xxSuccessful) + .andReturn().response.contentAsJson() + assertThat(detailResponse.currentDisposal, equalTo("0")) + assertThat(detailResponse.activeProbationManagedSentence, equalTo(false)) } } diff --git a/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/OffenderDetailSummary.kt b/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/OffenderDetailSummary.kt new file mode 100644 index 0000000000..e491a933f7 --- /dev/null +++ b/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/OffenderDetailSummary.kt @@ -0,0 +1,103 @@ +package uk.gov.justice.digital.hmpps.api.model + +import java.time.LocalDate +import java.time.ZonedDateTime + +data class OffenderDetailSummary( + val preferredName: String?, + val activeProbationManagedSentence: Boolean, + val contactDetails: ContactDetails, + val currentDisposal: String, + val currentExclusion: Boolean, + val currentRestriction: Boolean, + val dateOfBirth: LocalDate, + val firstName: String, + val gender: String, + val middleNames: List, + val offenderId: Long, + val offenderProfile: OffenderProfile, + val otherIds: OtherIds, + val partitionArea: String, + val previousSurname: String?, + val softDeleted: Boolean, + val surname: String, + val title: String? +) + +data class ContactDetails( + val allowSMS: Boolean?, + val emailAddresses: List, + val phoneNumbers: List +) + +data class OtherIds( + val crn: String, + val croNumber: String?, + val immigrationNumber: String?, + val mostRecentPrisonerNumber: String?, + val niNumber: String?, + val nomsNumber: String?, + val pncNumber: String? +) + +data class Disability( + val lastUpdatedDateTime: ZonedDateTime, + val disabilityCondition: KeyValue, + val disabilityId: Long, + val disabilityType: KeyValue, + val endDate: LocalDate?, + val isActive: Boolean, + val notes: String?, + val provisions: List, + val startDate: LocalDate +) + +data class OffenderLanguages( + val languageConcerns: String?, + val otherLanguages: List = emptyList(), + val primaryLanguage: String?, + val requiresInterpreter: Boolean? +) + +data class OffenderProfile( + val genderIdentity: String?, + val selfDescribedGenderIdentity: String?, + val disabilities: List = emptyList(), + val ethnicity: String?, + val immigrationStatus: String?, + val nationality: String?, + val notes: String? = null, + val offenderDetails: String?, + val offenderLanguages: OffenderLanguages, + val previousConviction: PreviousConviction?, + val provisions: List = emptyList(), + val religion: String?, + val remandStatus: String?, + val riskColour: String?, + val secondaryNationality: String?, + val sexualOrientation: String? +) + +data class PhoneNumber( + val number: String?, + val type: String +) + +data class PreviousConviction( + val convictionDate: LocalDate, + val detail: Map +) + +data class Provision( + val category: KeyValue?, + val finishDate: LocalDate?, + val notes: String?, + val provisionId: Long, + val provisionType: KeyValue, + val startDate: LocalDate +) + +enum class PhoneTypes { + TELEPHONE, + MOBILE +} diff --git a/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/ProbationRecord.kt b/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/ProbationRecord.kt index 84099530ef..48f16a7e2c 100644 --- a/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/ProbationRecord.kt +++ b/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/ProbationRecord.kt @@ -127,7 +127,8 @@ enum class DocumentType(val description: String) { NSI_DOCUMENT("Non Statutory Intervention related document"), PERSONAL_CIRCUMSTANCE_DOCUMENT("Personal circumstance related document"), UPW_APPOINTMENT_DOCUMENT("Unpaid work appointment document"), - CONTACT_DOCUMENT("Contact related document") + CONTACT_DOCUMENT("Contact related document"), + PREVIOUS_CONVICTION("Previous conviction document") } class Breach( diff --git a/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/resource/ProbationRecordResource.kt b/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/resource/ProbationRecordResource.kt index c5e0a8b92b..0fa57e31f1 100644 --- a/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/resource/ProbationRecordResource.kt +++ b/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/resource/ProbationRecordResource.kt @@ -13,7 +13,7 @@ class ProbationRecordResource(private val offenderService: OffenderService) { @PreAuthorize("hasRole('PROBATION_API__COURT_CASE__CASE_DETAIL')") @GetMapping - fun probationRecord( + fun getOffenderDetailSummary( @PathVariable crn: String - ) = offenderService.getProbationRecord(crn) + ) = offenderService.getOffenderDetail(crn) } diff --git a/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/entity/Document.kt b/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/entity/Document.kt index d1852b2100..671f891169 100644 --- a/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/entity/Document.kt +++ b/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/entity/Document.kt @@ -7,6 +7,7 @@ import jakarta.persistence.Table import org.hibernate.annotations.Immutable import org.springframework.data.jpa.repository.JpaRepository import org.springframework.data.jpa.repository.Query +import uk.gov.justice.digital.hmpps.api.model.DocumentType import java.time.Instant import java.time.ZonedDateTime @@ -25,7 +26,7 @@ class DocumentEntity( val alfrescoId: String, @Column - val primaryKeyId: Long, + val primaryKeyId: Long?, @Column(name = "document_name") val name: String, @@ -34,7 +35,7 @@ class DocumentEntity( val type: String, @Column - val tableName: String, + val tableName: String?, @Column(name = "created_datetime") val createdAt: ZonedDateTime, @@ -45,6 +46,9 @@ class DocumentEntity( @Column val lastUpdatedUserId: Long = 0, + @Column(name = "last_saved") + val lastUpdated: ZonedDateTime, + @Column(columnDefinition = "number") val softDeleted: Boolean = false ) @@ -80,6 +84,18 @@ fun Document.typeDescription() = when (tableName) { } interface DocumentRepository : JpaRepository { + + @Query( + """ + select d from DocumentEntity d + where d.personId = :personId + and d.type = :type + and d.softDeleted = false + order by d.lastUpdated desc + """ + ) + fun findByPersonIdAndType(personId: Long, type: String): List + @Query( """ select document.alfresco_document_id as "alfrescoId", @@ -177,3 +193,6 @@ interface DocumentRepository : JpaRepository { @Query("select d.name from DocumentEntity d where d.alfrescoId = :alfrescoId") fun findNameByAlfrescoId(alfrescoId: String): String? } + +fun DocumentRepository.getPreviousConviction(personId: Long) = + findByPersonIdAndType(personId, DocumentType.PREVIOUS_CONVICTION.name).firstOrNull() diff --git a/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/person/entity/Disability.kt b/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/person/entity/Disability.kt new file mode 100644 index 0000000000..fd241c3607 --- /dev/null +++ b/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/person/entity/Disability.kt @@ -0,0 +1,47 @@ +package uk.gov.justice.digital.hmpps.integrations.delius.person.entity + +import jakarta.persistence.* +import org.hibernate.annotations.Fetch +import org.hibernate.annotations.FetchMode +import org.hibernate.annotations.Immutable +import org.hibernate.annotations.SQLRestriction +import uk.gov.justice.digital.hmpps.integrations.delius.entity.ReferenceData +import java.time.LocalDate +import java.time.ZonedDateTime + +@Immutable +@Entity +@Table(name = "disability") +@SQLRestriction("soft_deleted = 0 and (finish_date is null or finish_date > current_date)") +class Disability( + @Id + @Column(name = "disability_id") + val id: Long, + + @Column(name = "offender_id") + val personId: Long, + + @ManyToOne + @Fetch(FetchMode.JOIN) + @JoinColumn(name = "disability_type_id") + val type: ReferenceData, + + @ManyToOne + @Fetch(FetchMode.JOIN) + @JoinColumn(name = "disability_condition_id") + val condition: ReferenceData, + + val startDate: LocalDate, + + @Column(name = "last_updated_datetime") + val lastUpdated: ZonedDateTime, + + @Column(name = "notes", columnDefinition = "clob") + val notes: String? = null, + + val finishDate: LocalDate? = null, + + @Column(name = "soft_deleted", columnDefinition = "number") + val softDeleted: Boolean = false, + + ) diff --git a/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/person/entity/Person.kt b/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/person/entity/Person.kt index 9c5272f535..aabb6be07e 100644 --- a/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/person/entity/Person.kt +++ b/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/person/entity/Person.kt @@ -1,28 +1,173 @@ package uk.gov.justice.digital.hmpps.integrations.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.hibernate.type.YesNoConverter import org.springframework.data.jpa.repository.JpaRepository import org.springframework.data.jpa.repository.Query +import uk.gov.justice.digital.hmpps.exception.NotFoundException +import uk.gov.justice.digital.hmpps.integrations.delius.entity.ReferenceData import java.time.LocalDate @Immutable @Entity @Table(name = "offender") +@SQLRestriction("soft_deleted = 0") class Person( + @Id + @Column(name = "offender_id") + val id: Long, + @Column(columnDefinition = "char(7)") val crn: String, - @Column(updatable = false, columnDefinition = "number") - val softDeleted: Boolean = false, + @Column(name = "pnc_number", columnDefinition = "char(13)") + val pnc: String? = null, + + @Column(name = "cro_number") + val croNumber: String? = null, + + @Column(name = "noms_number") + val nomsNumber: String? = null, + + @Column(name = "immigration_number") + val immigrationNumber: String? = null, + + @Column(name = "ni_number") + val niNumber: String? = null, + + @Column(name = "most_recent_prisoner_number") + val mostRecentPrisonerNumber: String? = null, + + @ManyToOne + @JoinColumn(name = "title_id") + val title: ReferenceData? = null, + + @Column(name = "first_name", length = 35) + val forename: String, + + @Column(name = "second_name", length = 35) + val secondName: String? = null, + + @Column(name = "third_name", length = 35) + val thirdName: String? = null, + + @Column(name = "surname", length = 35) + val surname: String, + + @Column(name = "preferred_name", length = 35) + val preferredName: String? = null, + + @Column(name = "date_of_birth_date") + val dateOfBirth: LocalDate, + + @Column(name = "telephone_number") + val telephoneNumber: String? = null, + + @Column(name = "mobile_number") + val mobileNumber: String? = null, + + @Column(name = "e_mail_address") + val emailAddress: String? = null, + + @Column(name = "previous_surname") + val previousSurname: String? = null, + + @ManyToOne + @JoinColumn(name = "gender_id") + val gender: ReferenceData, + + @ManyToOne + @JoinColumn(name = "religion_id") + val religion: ReferenceData? = null, + + @ManyToOne + @JoinColumn(name = "language_id") + val language: ReferenceData? = null, + + @Column(name = "language_concerns") + val languageConcerns: String? = null, + + @ManyToOne + @JoinColumn(name = "sexual_orientation_id") + val sexualOrientation: ReferenceData? = null, + + @ManyToOne + @JoinColumn(name = "gender_identity_id") + val genderIdentity: ReferenceData? = null, + + @Column(name = "gender_identity_description") + val genderIdentityDescription: String? = null, + + @Column(name = "Interpreter_required") + @Convert(converter = YesNoConverter::class) + val requiresInterpreter: Boolean? = false, + @Column(name = "current_disposal", columnDefinition = "number") + val currentDisposal: Boolean, + + @Column(name = "current_remand_status") + val currentRemandStatus: String? = null, + + @OneToMany(mappedBy = "personId") + val disabilities: Set = emptySet(), + + @OneToMany(mappedBy = "personId") + val provisions: Set = emptySet(), + + @ManyToOne + @JoinColumn(name = "ethnicity_id") + val ethnicity: ReferenceData? = null, + + @ManyToOne + @JoinColumn(name = "nationality_id") + val nationality: ReferenceData? = null, + + @ManyToOne + @JoinColumn(name = "second_nationality_id") + val secondNationality: ReferenceData? = null, + + @ManyToOne + @JoinColumn(name = "immigration_status_id") + val immigrationStatus: ReferenceData? = null, + + @Column(name = "allow_sms") + @Convert(converter = YesNoConverter::class) + val allowSms: Boolean? = false, + + @Column(name = "current_exclusion", columnDefinition = "number") + val currentExclusion: Boolean = false, + + @Column(name = "current_restriction", columnDefinition = "number") + val currentRestriction: Boolean = false, + + @Column(name = "current_highest_risk_colour") + val currentHighestRiskColour: String? = null, + + @Column(name = "offender_details") + val offenderDetails: String? = null, + + @ManyToOne + @JoinColumn(name = "partition_area_id") + val partitionArea: PartitionArea, + + @Column(columnDefinition = "number") + val softDeleted: Boolean = false + +) + +@Immutable +@Entity +@Table(name = "partition_area") +class PartitionArea( @Id - @Column(name = "offender_id") - val id: Long + @Column(name = "partition_area_id") + val partitionAreaId: Long, + + @Column(name = "area") + val area: String, ) interface PersonRepository : JpaRepository { @@ -52,9 +197,37 @@ interface PersonRepository : JpaRepository { ) fun statusOf(crn: String): SentenceCounts? + @Query( + """ + select p from Person p + left join fetch p.ethnicity eth + left join fetch p.nationality nat + left join fetch p.gender gen + left join fetch p.language lang + left join fetch p.genderIdentity gi + left join fetch p.immigrationStatus is + left join fetch p.provisions prov + left join fetch p.disabilities dis + left join fetch p.secondNationality sn + left join fetch p.sexualOrientation so + left join fetch p.religion rel + left join fetch p.partitionArea pa + left join fetch p.title title + left join fetch prov.category pcat + left join fetch prov.type ptype + left join fetch dis.type dtype + left join fetch dis.condition dcond + where p.crn = :crn + and p.softDeleted = false + """ + ) + fun findByCrn(crn: String): Person? + fun findByCrnAndSoftDeletedIsFalse(crn: String): Person? } +fun PersonRepository.getPerson(crn: String) = findByCrn(crn) ?: throw NotFoundException("Person", "crn", crn) + interface SentenceCounts { val crn: String val currentCount: Int diff --git a/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/person/entity/Provision.kt b/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/person/entity/Provision.kt new file mode 100644 index 0000000000..7ed2436d89 --- /dev/null +++ b/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/person/entity/Provision.kt @@ -0,0 +1,51 @@ +package uk.gov.justice.digital.hmpps.integrations.delius.person.entity + +import jakarta.persistence.* +import org.hibernate.annotations.Fetch +import org.hibernate.annotations.FetchMode +import org.hibernate.annotations.Immutable +import org.hibernate.annotations.SQLRestriction +import org.springframework.data.jpa.repository.JpaRepository +import uk.gov.justice.digital.hmpps.integrations.delius.entity.ReferenceData +import java.time.LocalDate + +@Immutable +@Entity +@Table(name = "provision") +@SQLRestriction("soft_deleted = 0 and (finish_date is null or finish_date > current_date)") +class Provision( + @Id + @Column(name = "provision_id") + val id: Long, + + @Column(name = "offender_id") + val personId: Long, + + @ManyToOne + @Fetch(FetchMode.JOIN) + @JoinColumn(name = "provision_type_id") + val type: ReferenceData, + + val startDate: LocalDate, + + @Column(name = "last_updated_datetime") + val lastUpdated: LocalDate, + + @ManyToOne + @Fetch(FetchMode.JOIN) + @JoinColumn(name = "provision_category_id") + val category: ReferenceData? = null, + + @Column(name = "notes", columnDefinition = "clob") + val notes: String? = null, + + val finishDate: LocalDate? = null, + + @Column(name = "soft_deleted", columnDefinition = "number") + val softDeleted: Boolean = false, + + ) + +interface ProvisionRepository : JpaRepository { + fun findByPersonId(personId: Long): List +} \ No newline at end of file diff --git a/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/service/OffenderService.kt b/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/service/OffenderService.kt index 9000da7148..4d3d8c6ac7 100644 --- a/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/service/OffenderService.kt +++ b/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/service/OffenderService.kt @@ -1,39 +1,24 @@ package uk.gov.justice.digital.hmpps.integrations.delius.service import org.springframework.stereotype.Service -import uk.gov.justice.digital.hmpps.api.model.Breach -import uk.gov.justice.digital.hmpps.api.model.Conviction -import uk.gov.justice.digital.hmpps.api.model.CourtReport -import uk.gov.justice.digital.hmpps.api.model.DocumentType -import uk.gov.justice.digital.hmpps.api.model.KeyValue +import software.amazon.awssdk.utils.ImmutableMap +import uk.gov.justice.digital.hmpps.api.model.* import uk.gov.justice.digital.hmpps.api.model.LicenceCondition import uk.gov.justice.digital.hmpps.api.model.Offence -import uk.gov.justice.digital.hmpps.api.model.OffenderDocumentDetail -import uk.gov.justice.digital.hmpps.api.model.ProbationRecord -import uk.gov.justice.digital.hmpps.api.model.PssRequirement -import uk.gov.justice.digital.hmpps.api.model.ReportAuthor import uk.gov.justice.digital.hmpps.api.model.Requirement -import uk.gov.justice.digital.hmpps.api.model.Sentence -import uk.gov.justice.digital.hmpps.api.model.keyValueOf -import uk.gov.justice.digital.hmpps.api.model.toOffenderManager import uk.gov.justice.digital.hmpps.datetime.EuropeLondon -import uk.gov.justice.digital.hmpps.exception.NotFoundException -import uk.gov.justice.digital.hmpps.integrations.delius.entity.Document -import uk.gov.justice.digital.hmpps.integrations.delius.entity.DocumentRepository -import uk.gov.justice.digital.hmpps.integrations.delius.entity.typeDescription +import uk.gov.justice.digital.hmpps.integrations.delius.entity.* import uk.gov.justice.digital.hmpps.integrations.delius.event.courtappearance.entity.CourtReportRepository -import uk.gov.justice.digital.hmpps.integrations.delius.event.entity.AdditionalOffenceRepository -import uk.gov.justice.digital.hmpps.integrations.delius.event.entity.Event -import uk.gov.justice.digital.hmpps.integrations.delius.event.entity.EventRepository -import uk.gov.justice.digital.hmpps.integrations.delius.event.entity.LicenceConditionRepository -import uk.gov.justice.digital.hmpps.integrations.delius.event.entity.MainOffenceRepository -import uk.gov.justice.digital.hmpps.integrations.delius.event.entity.RequirementRepository +import uk.gov.justice.digital.hmpps.integrations.delius.event.entity.* import uk.gov.justice.digital.hmpps.integrations.delius.event.nsi.NsiRepository import uk.gov.justice.digital.hmpps.integrations.delius.event.sentence.entity.Disposal import uk.gov.justice.digital.hmpps.integrations.delius.event.sentence.entity.PssRequirementRepository import uk.gov.justice.digital.hmpps.integrations.delius.person.entity.Person import uk.gov.justice.digital.hmpps.integrations.delius.person.entity.PersonRepository +import uk.gov.justice.digital.hmpps.integrations.delius.person.entity.getPerson import uk.gov.justice.digital.hmpps.integrations.delius.repository.PersonManagerRepository +import java.time.LocalDate +import uk.gov.justice.digital.hmpps.integrations.delius.person.entity.Disability as DisabilityEntity @Service class OffenderService( @@ -49,14 +34,11 @@ class OffenderService( private val pssRequirementRepository: PssRequirementRepository, private val courtReportRepository: CourtReportRepository ) { - fun getProbationRecord(crn: String): ProbationRecord { - val person = - personRepository.findByCrnAndSoftDeletedIsFalse(crn) ?: throw NotFoundException("Person", "crn", crn) - val personManager = - personManagerRepository.findActiveManager(person.id) ?: throw NotFoundException("PersonManager", "crn", crn) - val documents = documentRepository.getPersonAndEventDocuments(person.id) - val convictions = getConvictions(person, documents) - return ProbationRecord(crn, listOf(personManager.toOffenderManager()), convictions) + + fun getOffenderDetail(crn: String): OffenderDetailSummary { + val person = personRepository.getPerson(crn) + val previousConviction = documentRepository.getPreviousConviction(person.id) + return person.toOffenderDetail(previousConviction) } private fun getOffences(event: Event): List { @@ -170,6 +152,99 @@ class OffenderService( } } +fun DisabilityEntity.isActive(): Boolean { + if (startDate.isAfter(LocalDate.now())) { + return false + } + return finishDate == null || finishDate.isAfter(LocalDate.now()) +} + +fun Person.toOffenderDetail(previousConviction: DocumentEntity?) = OffenderDetailSummary( + preferredName = preferredName, + activeProbationManagedSentence = currentDisposal, + contactDetails = ContactDetails( + allowSMS = allowSms, + emailAddresses = listOfNotNull(emailAddress), + phoneNumbers = listOf( + PhoneNumber(telephoneNumber, PhoneTypes.TELEPHONE.name), + PhoneNumber(mobileNumber, PhoneTypes.MOBILE.name) + ) + ), + currentDisposal = if (currentDisposal) "1" else "0", + currentExclusion = currentExclusion, + currentRestriction = currentRestriction, + dateOfBirth = dateOfBirth, + firstName = forename, + middleNames = listOfNotNull(secondName, thirdName), + surname = surname, + gender = gender.description, + offenderId = id, + offenderProfile = OffenderProfile( + genderIdentity = genderIdentity?.description, + selfDescribedGenderIdentity = genderIdentityDescription ?: genderIdentity?.description, + disabilities = disabilities.sortedByDescending { it.startDate }.map { + Disability( + lastUpdatedDateTime = it.lastUpdated, + disabilityCondition = KeyValue(it.condition.code, it.condition.description), + disabilityId = it.id, + disabilityType = KeyValue(it.type.code, it.type.description), + endDate = it.finishDate, + isActive = it.isActive(), + notes = it.notes, + provisions = emptyList(), + startDate = it.startDate + ) + }, + ethnicity = ethnicity?.description, + immigrationStatus = immigrationStatus?.description, + nationality = nationality?.description, + offenderDetails = offenderDetails, + offenderLanguages = OffenderLanguages( + languageConcerns = languageConcerns, + primaryLanguage = language?.description, + requiresInterpreter = requiresInterpreter, + otherLanguages = emptyList() + ), + previousConviction = previousConviction?.lastUpdated.let { + previousConviction?.createdAt?.toLocalDate() + ?.let { it1 -> + PreviousConviction( + convictionDate = it1, + detail = ImmutableMap.of("documentName", previousConviction.name) + ) + } + }, + provisions = provisions.sortedByDescending { it.startDate }.map { + Provision( + category = it.category?.let { cat -> KeyValue(cat.code, cat.description) }, + finishDate = it.finishDate, + notes = it.notes, + provisionId = it.id, + provisionType = KeyValue(it.type.code, it.type.description), + startDate = it.startDate + ) + }, + religion = religion?.description, + remandStatus = currentRemandStatus, + riskColour = currentHighestRiskColour, + sexualOrientation = sexualOrientation?.description, + secondaryNationality = secondNationality?.description + ), + otherIds = OtherIds( + crn = crn, + croNumber = croNumber, + immigrationNumber = immigrationNumber, + mostRecentPrisonerNumber = mostRecentPrisonerNumber, + niNumber = niNumber, + nomsNumber = nomsNumber, + pncNumber = pnc + ), + partitionArea = partitionArea.area, + previousSurname = previousSurname, + softDeleted = softDeleted, + title = title?.description +) + fun Disposal.sentenceOf() = Sentence( disposalType.description, entryLength,