diff --git a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/SentencesIntegrationTest.kt b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/SentencesIntegrationTest.kt new file mode 100644 index 0000000000..c10a1e3221 --- /dev/null +++ b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/SentencesIntegrationTest.kt @@ -0,0 +1,85 @@ +package uk.gov.justice.digital.hmpps + +import org.junit.jupiter.api.Assertions.assertEquals +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.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders +import org.springframework.test.web.servlet.result.MockMvcResultMatchers +import uk.gov.justice.digital.hmpps.api.model.sentence.* +import uk.gov.justice.digital.hmpps.data.generator.LicenceConditionGenerator.LC_WITHOUT_NOTES +import uk.gov.justice.digital.hmpps.data.generator.LicenceConditionGenerator.LC_WITH_1500_CHAR_NOTE +import uk.gov.justice.digital.hmpps.data.generator.LicenceConditionGenerator.LC_WITH_NOTES +import uk.gov.justice.digital.hmpps.data.generator.LicenceConditionGenerator.LC_WITH_NOTES_WITHOUT_ADDED_BY +import uk.gov.justice.digital.hmpps.data.generator.LicenceConditionGenerator.LIC_COND_MAIN_CAT +import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator +import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator.ACTIVE_ORDER +import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator.EVENT_1 +import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator.EVENT_2 +import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator.REQUIREMENT +import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator.REQUIREMENT_UNPAID_WORK +import uk.gov.justice.digital.hmpps.data.generator.personalDetails.PersonDetailsGenerator +import uk.gov.justice.digital.hmpps.service.toSummary +import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.contentAsJson +import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withToken + +@AutoConfigureMockMvc +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +class SentencesIntegrationTest { + @Autowired + lateinit var mockMvc: MockMvc + + + @Test + fun `unauthorized status returned`() { + mockMvc + .perform(MockMvcRequestBuilders.get("/sentences/X123456")) + .andExpect(MockMvcResultMatchers.status().isUnauthorized) + } + + @Test + fun `no active sentences`() { + val response = mockMvc + .perform(MockMvcRequestBuilders.get("/sentences/${PersonDetailsGenerator.PERSONAL_DETAILS.crn}").withToken()) + .andExpect(MockMvcResultMatchers.status().isOk) + .andReturn().response.contentAsJson() + + val expected = MinimalSentenceOverview( + PersonDetailsGenerator.PERSONAL_DETAILS.toSummary() + ) + + assertEquals(expected, response) + } + + @Test + fun `get active sentences`() { + val response = mockMvc + .perform(MockMvcRequestBuilders.get("/sentences/${PersonGenerator.OVERVIEW.crn}").withToken()) + .andExpect(MockMvcResultMatchers.status().isOk) + .andReturn().response.contentAsJson() + + val expected = MinimalSentenceOverview( + PersonGenerator.OVERVIEW.toSummary(), + listOf( + MinimalSentence(EVENT_2.id), + MinimalSentence( + EVENT_1.id, + order = MinimalOrder(ACTIVE_ORDER.type.description, ACTIVE_ORDER.date), + licenceConditions = listOf( + MinimalLicenceCondition(LC_WITH_NOTES.id, LIC_COND_MAIN_CAT.description), + MinimalLicenceCondition(LC_WITHOUT_NOTES.id, LIC_COND_MAIN_CAT.description), + MinimalLicenceCondition(LC_WITH_NOTES_WITHOUT_ADDED_BY.id, LIC_COND_MAIN_CAT.description), + MinimalLicenceCondition(LC_WITH_1500_CHAR_NOTE.id, LIC_COND_MAIN_CAT.description) + ), + requirements = listOf( + MinimalRequirement(REQUIREMENT.id, "1 days RAR, 1 completed"), + MinimalRequirement(REQUIREMENT_UNPAID_WORK.id, "Unpaid Work - Intensive")) + ) + ) + ) + + assertEquals(expected, response) + } +} \ No newline at end of file diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/SentencesController.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/SentencesController.kt new file mode 100644 index 0000000000..192f1ca114 --- /dev/null +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/SentencesController.kt @@ -0,0 +1,21 @@ +package uk.gov.justice.digital.hmpps.api.controller + +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.tags.Tag +import org.springframework.security.access.prepost.PreAuthorize +import org.springframework.web.bind.annotation.* +import uk.gov.justice.digital.hmpps.service.SentenceService + +@RestController +@Tag(name = "Sentences") +@RequestMapping("/sentences/{crn}") +@PreAuthorize("hasRole('PROBATION_API__MANAGE_A_SUPERVISION__CASE_DETAIL')") +class SentencesController(private val sentenceService: SentenceService) { + + @GetMapping + @Operation(summary = "Display active events") + fun getOverview( + @PathVariable crn: String, + @RequestParam(required = false) number: String?, + ) = sentenceService.getActiveSentences(crn) +} \ No newline at end of file diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/overview/Order.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/overview/Order.kt index 1c702c2b59..eb27659fbc 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/overview/Order.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/overview/Order.kt @@ -4,7 +4,7 @@ import java.time.LocalDate data class Order( val description: String, - val length: Long?, + val length: Long? = null, val endDate: LocalDate?, val releaseDate: LocalDate? = null, val startDate: LocalDate, diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/sentence/LicenceCondition.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/sentence/LicenceCondition.kt index 895552790a..9a5cb3a6b8 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/sentence/LicenceCondition.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/sentence/LicenceCondition.kt @@ -24,4 +24,9 @@ data class LicenceConditionNote( data class LicenceConditionNoteDetail( val personSummary: PersonSummary, val licenceCondition: LicenceCondition? = null +) + +data class MinimalLicenceCondition( + val id: Long, + val mainDescription: String ) \ No newline at end of file diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/sentence/Requirement.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/sentence/Requirement.kt index 1c7cea0c53..554d87c6b5 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/sentence/Requirement.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/sentence/Requirement.kt @@ -16,3 +16,8 @@ data class Requirement( val notes: String?, val rar: Rar? = null ) + +data class MinimalRequirement( + val id: Long, + val description: String +) diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/sentence/Sentence.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/sentence/Sentence.kt index c4cae7c0b9..29a07260e5 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/sentence/Sentence.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/sentence/Sentence.kt @@ -1,6 +1,7 @@ package uk.gov.justice.digital.hmpps.api.model.sentence import uk.gov.justice.digital.hmpps.api.model.overview.Order +import java.time.LocalDate data class Sentence( val offenceDetails: OffenceDetails, @@ -8,6 +9,19 @@ data class Sentence( val order: Order? = null, val requirements: List = listOf(), val courtDocuments: List = listOf(), - val unpaidWorkProgress: String?, + val unpaidWorkProgress: String? = null, val licenceConditions: List = listOf() -) \ No newline at end of file +) + +data class MinimalSentence( + val id: Long, + val order: MinimalOrder? = null, + val licenceConditions: List = listOf(), + val requirements: List = listOf() +) + +data class MinimalOrder( + val description: String, + val startDate: LocalDate, + val endDate: LocalDate? = null, +) diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/sentence/SentenceOverview.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/sentence/SentenceOverview.kt index a4dfcbad94..3ad71574d5 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/sentence/SentenceOverview.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/sentence/SentenceOverview.kt @@ -12,3 +12,8 @@ data class SentenceSummary( val eventNumber: String, val description: String ) + +data class MinimalSentenceOverview( + val personSummary: PersonSummary, + val sentences: List = emptyList(), +) \ No newline at end of file diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/LicenceConditionService.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/LicenceConditionService.kt index 40de98578c..3b9777c6dd 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/LicenceConditionService.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/LicenceConditionService.kt @@ -4,6 +4,7 @@ import org.springframework.stereotype.Service import uk.gov.justice.digital.hmpps.api.model.sentence.LicenceCondition import uk.gov.justice.digital.hmpps.api.model.sentence.LicenceConditionNote import uk.gov.justice.digital.hmpps.api.model.sentence.LicenceConditionNoteDetail +import uk.gov.justice.digital.hmpps.api.model.sentence.MinimalLicenceCondition import uk.gov.justice.digital.hmpps.datetime.DeliusDateFormatter import uk.gov.justice.digital.hmpps.integrations.delius.overview.entity.PersonRepository import uk.gov.justice.digital.hmpps.integrations.delius.overview.entity.getPerson @@ -40,6 +41,8 @@ fun EntityLicenceCondition.toLicenceCondition() = toLicenceConditionNote(true) ) +fun EntityLicenceCondition.toMinimalLicenceCondition() = MinimalLicenceCondition(id, mainCategory.description) + fun EntityLicenceCondition.toLicenceConditionSingleNote(noteId: Int, truncateNote: Boolean) = LicenceCondition( id, diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/SentenceService.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/SentenceService.kt index b0682efe01..f862ca058c 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/SentenceService.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/SentenceService.kt @@ -46,6 +46,18 @@ class SentenceService( ) } + fun getActiveSentences(crn: String): MinimalSentenceOverview { + val person = personRepository.getPerson(crn) + val activeEvents = eventRepository.findSentencesByPersonId(person.id).filter { + it.active + } + + return MinimalSentenceOverview( + personSummary = person.toSummary(), + activeEvents.map { it.toMinimalSentence() } + ) + } + fun getProbationHistory(crn: String): History { val person = personRepository.getPerson(crn) val (activeEvents, inactiveEvents) = eventRepository.findSentencesByPersonId(person.id).partition { it.active } @@ -67,6 +79,19 @@ class SentenceService( disposal?.type?.description ?: "Pre-Sentence" ) + fun Event.toMinimalSentence(): MinimalSentence = + MinimalSentence( + id, + disposal?.toMinimalOrder(), + licenceConditions = disposal?.let { + licenceConditionRepository.findAllByDisposalId(disposal.id).map { + it.toMinimalLicenceCondition() + } + } ?: emptyList(), + requirements = requirementRepository.getRequirements(id, eventNumber) + .map { it.toMinimalRequirement() }, + ) + fun Event.toSentence(crn: String): Sentence { val courtAppearance = courtAppearanceRepository.getFirstCourtAppearanceByEventIdOrderByDate(id) val additionalSentences = additionalSentenceRepository.getAllByEventId(id) @@ -114,6 +139,8 @@ class SentenceService( ) } + fun Disposal.toMinimalOrder() = MinimalOrder(type.description, date, expectedEndDate()) + fun RequirementDetails.toRequirement(): Requirement { val rar = getRar(id, code) @@ -134,6 +161,11 @@ class SentenceService( return requirement } + fun RequirementDetails.toMinimalRequirement(): MinimalRequirement { + val rar = getRar(id, code) + return MinimalRequirement(id, populateRequirementDescription(description, codeDescription, rar)) + } + fun populateRequirementDescription(description: String, codeDescription: String?, rar: Rar?): String { rar?.let { return "" + it.totalDays + " days RAR, " + it.completed + " completed" }