diff --git a/projects/soc-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt b/projects/soc-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt index 888d6c968b..332775ca8c 100644 --- a/projects/soc-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt +++ b/projects/soc-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt @@ -44,9 +44,10 @@ class DataLoader( CourtAppearanceGenerator.DEFAULT_EVENT, CourtAppearanceGenerator.DEFAULT_CA, ConvictionEventGenerator.PERSON, - ConvictionEventGenerator.OFFENCE_OTHER, - ConvictionEventGenerator.OFFENCE_MAIN, + ConvictionEventGenerator.ADDITIONAL_OFFENCE_TYPE, + ConvictionEventGenerator.OFFENCE_MAIN_TYPE, ConvictionEventGenerator.DEFAULT_EVENT, + ConvictionEventGenerator.INACTIVE_EVENT, ConvictionEventGenerator.MAIN_OFFENCE, ConvictionEventGenerator.OTHER_OFFENCE, ConvictionEventGenerator.DISPOSAL_TYPE, diff --git a/projects/soc-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ConvictionEventGenerator.kt b/projects/soc-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ConvictionEventGenerator.kt index ae910be6f9..d3f7c654e1 100644 --- a/projects/soc-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ConvictionEventGenerator.kt +++ b/projects/soc-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ConvictionEventGenerator.kt @@ -15,12 +15,12 @@ object ConvictionEventGenerator { "X012772", "1231234" ) - val OFFENCE_MAIN = Offence( + val OFFENCE_MAIN_TYPE = Offence( IdGenerator.getAndIncrement(), "C01", "Murder" ) - val OFFENCE_OTHER = Offence( + val ADDITIONAL_OFFENCE_TYPE = Offence( IdGenerator.getAndIncrement(), "C02", "Stealing a kitten" @@ -30,15 +30,21 @@ object ConvictionEventGenerator { LocalDate.now(), PERSON ) + val INACTIVE_EVENT = ConvictionEventEntity( + IdGenerator.getAndIncrement(), + LocalDate.now(), + PERSON, + active = false + ) val MAIN_OFFENCE = MainOffence( IdGenerator.getAndIncrement(), DEFAULT_EVENT, - OFFENCE_MAIN + OFFENCE_MAIN_TYPE ) val OTHER_OFFENCE = AdditionalOffence( IdGenerator.getAndIncrement(), DEFAULT_EVENT, - OFFENCE_OTHER + ADDITIONAL_OFFENCE_TYPE ) val DISPOSAL_TYPE = DisposalType( IdGenerator.getAndIncrement(), @@ -64,12 +70,12 @@ object ConvictionEventGenerator { val MAIN_OFFENCE_2 = MainOffence( IdGenerator.getAndIncrement(), EVENT_2, - OFFENCE_MAIN + OFFENCE_MAIN_TYPE ) val OTHER_OFFENCE_2 = AdditionalOffence( IdGenerator.getAndIncrement(), EVENT_2, - OFFENCE_OTHER + ADDITIONAL_OFFENCE_TYPE ) val DISPOSAL_2 = Disposal( IdGenerator.getAndIncrement(), diff --git a/projects/soc-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/ConvictionsIntegrationTest.kt b/projects/soc-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/ConvictionsIntegrationTest.kt index 3c3791466a..2527ba0e52 100644 --- a/projects/soc-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/ConvictionsIntegrationTest.kt +++ b/projects/soc-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/ConvictionsIntegrationTest.kt @@ -47,7 +47,7 @@ internal class ConvictionsIntegrationTest { .andExpect(status().is2xxSuccessful).andReturn() val detailResponse = objectMapper.readValue(result.response.contentAsString, ConvictionsContainer::class.java) - Assertions.assertThat(detailResponse).isEqualTo(getConvictions()) + Assertions.assertThat(detailResponse).isEqualTo(getConvictions(true)) } @Test @@ -57,20 +57,52 @@ internal class ConvictionsIntegrationTest { .perform(get("/convictions/$crn?type=CRN").withOAuth2Token(wireMockServer)) .andExpect(status().is2xxSuccessful).andReturn() + val detailResponse = objectMapper.readValue(result.response.contentAsString, ConvictionsContainer::class.java) + Assertions.assertThat(detailResponse).isEqualTo(getConvictions(true)) + } + + @Test + fun `API call retuns only active convictions success response using CRN`() { + val crn = ConvictionEventGenerator.PERSON.crn + val result = mockMvc + .perform(get("/convictions/$crn?type=CRN&activeOnly=true").withOAuth2Token(wireMockServer)) + .andExpect(status().is2xxSuccessful).andReturn() + val detailResponse = objectMapper.readValue(result.response.contentAsString, ConvictionsContainer::class.java) Assertions.assertThat(detailResponse).isEqualTo(getConvictions()) } - private fun getConvictions(): ConvictionsContainer = ConvictionsContainer( - listOf( + @Test + fun `API call retuns only active convictions success response using NOMS`() { + val noms = ConvictionEventGenerator.PERSON.nomsNumber + val result = mockMvc + .perform(get("/convictions/$noms?type=NOMS&activeOnly=true").withOAuth2Token(wireMockServer)) + .andExpect(status().is2xxSuccessful).andReturn() + + val detailResponse = objectMapper.readValue(result.response.contentAsString, ConvictionsContainer::class.java) + Assertions.assertThat(detailResponse).isEqualTo(getConvictions()) + } + + private fun getConvictions(withInActive: Boolean = false): ConvictionsContainer { + val activeConviction = Conviction( + ConvictionEventGenerator.DEFAULT_EVENT.id, ConvictionEventGenerator.DEFAULT_EVENT.convictionDate, ConvictionEventGenerator.DISPOSAL_TYPE.description, listOf( - Offence(ConvictionEventGenerator.OFFENCE_MAIN.description, true), - Offence(ConvictionEventGenerator.OFFENCE_OTHER.description, false) + Offence( + ConvictionEventGenerator.MAIN_OFFENCE.id, + ConvictionEventGenerator.OFFENCE_MAIN_TYPE.description, + true + ), + Offence( + ConvictionEventGenerator.OTHER_OFFENCE.id, + ConvictionEventGenerator.ADDITIONAL_OFFENCE_TYPE.description, + false + ) ), Sentence( + ConvictionEventGenerator.DISPOSAL.id, ConvictionEventGenerator.DISPOSAL.startDate, null, Custody( @@ -88,6 +120,18 @@ internal class ConvictionsIntegrationTest { ) ) ) + + val inactiveConviction = Conviction( + ConvictionEventGenerator.INACTIVE_EVENT.id, + ConvictionEventGenerator.INACTIVE_EVENT.convictionDate, + "unknown", + listOf(), + null ) - ) + return if (withInActive) { + ConvictionsContainer(listOf(activeConviction, inactiveConviction)) + } else { + ConvictionsContainer(listOf(activeConviction)) + } + } } diff --git a/projects/soc-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/CourtAppearancesIntegrationTest.kt b/projects/soc-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/CourtAppearancesIntegrationTest.kt index 45c047c7b9..af42f791c8 100644 --- a/projects/soc-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/CourtAppearancesIntegrationTest.kt +++ b/projects/soc-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/CourtAppearancesIntegrationTest.kt @@ -63,7 +63,9 @@ internal class CourtAppearancesIntegrationTest { Type(CourtAppearanceGenerator.DEFAULT_CA_TYPE.code, CourtAppearanceGenerator.DEFAULT_CA_TYPE.description), CourtAppearanceGenerator.DEFAULT_COURT.code, CourtAppearanceGenerator.DEFAULT_COURT.name, - CourtAppearanceGenerator.DEFAULT_PERSON.crn + CourtAppearanceGenerator.DEFAULT_PERSON.crn, + CourtAppearanceGenerator.DEFAULT_CA.id, + CourtAppearanceGenerator.DEFAULT_PERSON.id ) ) ) diff --git a/projects/soc-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/DetailsIntegrationTest.kt b/projects/soc-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/DetailsIntegrationTest.kt index 559c30b9dc..c5076e1d36 100644 --- a/projects/soc-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/DetailsIntegrationTest.kt +++ b/projects/soc-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/DetailsIntegrationTest.kt @@ -69,7 +69,7 @@ internal class DetailsIntegrationTest { DetailsGenerator.DISTRICT.description, DetailsGenerator.DEFAULT_PA.description, Name(DetailsGenerator.STAFF.forename, DetailsGenerator.STAFF.middleName, DetailsGenerator.STAFF.surname), - ConvictionEventGenerator.OFFENCE_MAIN.description, + ConvictionEventGenerator.OFFENCE_MAIN_TYPE.description, DetailsGenerator.PERSON.religion?.description, listOf(KeyDate(KeyDateGenerator.SED_KEYDATE.code, KeyDateGenerator.SED_KEYDATE.description, KeyDateGenerator.KEYDATE.date)), DetailsGenerator.RELEASE.date, diff --git a/projects/soc-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/controller/ConvictionController.kt b/projects/soc-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/controller/ConvictionController.kt index f74e1a1d0d..5310e8b136 100644 --- a/projects/soc-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/controller/ConvictionController.kt +++ b/projects/soc-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/controller/ConvictionController.kt @@ -14,6 +14,7 @@ class ConvictionController(private val convictionService: ConvictionService) { @GetMapping(value = ["/convictions/{value}"]) fun convictions( @PathVariable value: String, - @RequestParam(required = false, defaultValue = "CRN") type: IdentifierType - ) = convictionService.getConvictions(value, type) + @RequestParam(required = false, defaultValue = "CRN") type: IdentifierType, + @RequestParam(required = false, defaultValue = "false") activeOnly: Boolean + ) = convictionService.getConvictions(value, type, activeOnly) } diff --git a/projects/soc-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/ConvictionEventEntity.kt b/projects/soc-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/ConvictionEventEntity.kt index ed1da9aea3..33cbe9082c 100644 --- a/projects/soc-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/ConvictionEventEntity.kt +++ b/projects/soc-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/ConvictionEventEntity.kt @@ -17,7 +17,7 @@ import java.time.LocalDate @Immutable @Table(name = "event") @Entity -@Where(clause = "soft_deleted = 0 and active_flag = 1") +@Where(clause = "soft_deleted = 0") class ConvictionEventEntity( @Id @Column(name = "event_id") @@ -172,7 +172,7 @@ interface ConvictionEventRepository : JpaRepository "disposal.type" ] ) - fun getAllByConvictionEventPersonCrn(crn: String): List + fun getAllByConvictionEventPersonIdOrderByConvictionDateDesc(personId: Long): List @EntityGraph( attributePaths = [ @@ -181,7 +181,7 @@ interface ConvictionEventRepository : JpaRepository "disposal.type" ] ) - fun getAllByConvictionEventPersonIdOrderByConvictionDateDesc(personId: Long): List + fun getAllByConvictionEventPersonCrn(crn: String): List @EntityGraph( attributePaths = [ @@ -191,6 +191,24 @@ interface ConvictionEventRepository : JpaRepository ] ) fun getAllByConvictionEventPersonNomsNumber(nomsNumber: String): List + + @EntityGraph( + attributePaths = [ + "mainOffence.offence", + "additionalOffences.offence", + "disposal.type" + ] + ) + fun getAllByConvictionEventPersonCrnAndActiveIsTrue(crn: String): List + + @EntityGraph( + attributePaths = [ + "mainOffence.offence", + "additionalOffences.offence", + "disposal.type" + ] + ) + fun getAllByConvictionEventPersonNomsNumberAndActiveIsTrue(nomsNumber: String): List } fun ConvictionEventRepository.getLatestConviction(personId: Long) = diff --git a/projects/soc-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/model/Conviction.kt b/projects/soc-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/model/Conviction.kt index bf72c98e04..ddd1c55e00 100644 --- a/projects/soc-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/model/Conviction.kt +++ b/projects/soc-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/model/Conviction.kt @@ -3,6 +3,7 @@ package uk.gov.justice.digital.hmpps.model import java.time.LocalDate data class Conviction( + val convictionId: Long, val convictionDate: LocalDate?, val outcome: String, val offences: List, @@ -10,6 +11,7 @@ data class Conviction( ) data class Offence( + val offenceId: Long, val description: String, val mainOffence: Boolean = false ) @@ -19,6 +21,7 @@ data class ConvictionsContainer( ) data class Sentence( + val sentenceId: Long, val startDate: LocalDate, val expectedEndDate: LocalDate?, val custody: Custody? diff --git a/projects/soc-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/model/CourtAppearance.kt b/projects/soc-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/model/CourtAppearance.kt index aa021fdcf0..9552a0b5b3 100644 --- a/projects/soc-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/model/CourtAppearance.kt +++ b/projects/soc-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/model/CourtAppearance.kt @@ -7,7 +7,9 @@ data class CourtAppearance( val type: Type, val courtCode: String, val courtName: String, - val crn: String + val crn: String, + val courtAppearanceId: Long, + val offenderId: Long ) data class Type( diff --git a/projects/soc-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/ConvictionService.kt b/projects/soc-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/ConvictionService.kt index 3991d91219..a4aa487415 100644 --- a/projects/soc-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/ConvictionService.kt +++ b/projects/soc-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/ConvictionService.kt @@ -19,19 +19,49 @@ class ConvictionService( private val convictionEventRepository: ConvictionEventRepository, private val custodyRepository: CustodyRepository ) { - fun getConvictions(value: String, type: IdentifierType): ConvictionsContainer { + fun getConvictions(value: String, type: IdentifierType, activeOnly: Boolean): ConvictionsContainer { val convictions = when (type) { - IdentifierType.CRN -> convictionEventRepository.getAllByConvictionEventPersonCrn(value) - IdentifierType.NOMS -> convictionEventRepository.getAllByConvictionEventPersonNomsNumber(value) + IdentifierType.CRN -> if (activeOnly) { + convictionEventRepository.getAllByConvictionEventPersonCrnAndActiveIsTrue( + value + ) + } else { + convictionEventRepository.getAllByConvictionEventPersonCrn(value) + } + + IdentifierType.NOMS -> if (activeOnly) { + convictionEventRepository.getAllByConvictionEventPersonNomsNumberAndActiveIsTrue( + value + ) + } else { + convictionEventRepository.getAllByConvictionEventPersonNomsNumber(value) + } } val convictionModels = mutableListOf() convictions.map { convictionEventEntity -> val custody = convictionEventEntity.disposal?.let { custodyRepository.getCustodyByDisposalId(it.id) } val offences = mutableListOf() - offences.add(Offence(convictionEventEntity.mainOffence!!.offence.description, true)) - convictionEventEntity.additionalOffences.forEach { offences.add(Offence(it.offence.description, false)) } + convictionEventEntity.mainOffence?.let { + offences.add( + Offence( + convictionEventEntity.mainOffence.id, + convictionEventEntity.mainOffence.offence.description, + true + ) + ) + } + offences.addAll( + convictionEventEntity.additionalOffences.map { + Offence( + it.id, + it.offence.description, + false + ) + } + ) convictionModels.add( Conviction( + convictionEventEntity.id, convictionEventEntity.convictionDate, convictionEventEntity.disposal?.type?.description ?: "unknown", offences, @@ -45,7 +75,7 @@ class ConvictionService( } private fun Disposal.asModel(custody: uk.gov.justice.digital.hmpps.entity.Custody?) = - Sentence(startDate, expectedEndDate, custody?.custodyModel()) + Sentence(id, startDate, expectedEndDate, custody?.custodyModel()) private fun ReferenceData.custodialStatus() = CustodyStatus(code, description) private fun uk.gov.justice.digital.hmpps.entity.Custody.custodyModel() = diff --git a/projects/soc-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/CourtAppearanceService.kt b/projects/soc-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/CourtAppearanceService.kt index 58c8562569..63c3f92e90 100644 --- a/projects/soc-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/CourtAppearanceService.kt +++ b/projects/soc-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/CourtAppearanceService.kt @@ -25,7 +25,9 @@ class CourtAppearanceService(private val courtAppearanceRepository: CourtAppeara Type(it.appearanceType.code, it.appearanceType.description), it.court.code, it.court.name, - it.courtAppearanceEventEntity.courtAppearancePerson.crn + it.courtAppearanceEventEntity.courtAppearancePerson.crn, + it.id, + it.courtAppearanceEventEntity.courtAppearancePerson.id ) ) }