Skip to content

Commit

Permalink
Pi 2099 court appearances (#4136)
Browse files Browse the repository at this point in the history
* PI-2099: Added court appearances
  • Loading branch information
pmcphee77 authored Aug 6, 2024
1 parent 941fa13 commit e80e2d2
Show file tree
Hide file tree
Showing 14 changed files with 140 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import uk.gov.justice.digital.hmpps.data.generator.*
import uk.gov.justice.digital.hmpps.datetime.EuropeLondon
import uk.gov.justice.digital.hmpps.user.AuditUserRepository
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.ZonedDateTime

Expand Down Expand Up @@ -135,7 +136,7 @@ class DataLoader(
ZonedDateTime.of(LocalDate.now().minusDays(1), LocalTime.NOON, EuropeLondon)
)
val outcome = SentenceGenerator.OUTCOME
val courtAppearance = SentenceGenerator.generateCourtAppearance(noSentenceEvent, outcome, ZonedDateTime.now())
val courtAppearance = SentenceGenerator.generateCourtAppearance(noSentenceEvent, outcome, LocalDateTime.now())
em.saveAll(noSentenceEvent, noSentenceManager, outcome, courtAppearance)

val newEvent = SentenceGenerator.generateEvent(PersonGenerator.NEW_TO_PROBATION, referralDate = LocalDate.now())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import uk.gov.justice.digital.hmpps.integrations.delius.provider.entity.Probatio
import uk.gov.justice.digital.hmpps.integrations.delius.provider.entity.Staff
import uk.gov.justice.digital.hmpps.integrations.delius.provider.entity.Team
import java.time.*
import java.time.temporal.ChronoUnit

object SentenceGenerator {

Expand Down Expand Up @@ -69,7 +70,7 @@ object SentenceGenerator {
val COURT_APPEARANCE = generateCourtAppearance(
CURRENTLY_MANAGED,
OUTCOME,
ZonedDateTime.of(LocalDate.now(), LocalTime.NOON, EuropeLondon)
LocalDateTime.now().truncatedTo(ChronoUnit.MICROS)
)

val CURRENT_ORDER_MANAGER = generateOrderManager(
Expand Down Expand Up @@ -182,7 +183,7 @@ object SentenceGenerator {
fun generateCourtAppearance(
event: Event,
outcome: Outcome,
appearanceDate: ZonedDateTime,
appearanceDate: LocalDateTime,
softDeleted: Boolean = false,
id: Long = IdGenerator.getAndIncrement()
) = CourtAppearance(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"courtAppearances": [
{
"courtAppearanceId": 90,
"appearanceDate": "2024-08-06T12:00:00",
"courtCode": "BRMNCC",
"courtName": "Birmingham Crown Court",
"appearanceType": {
"code": "CRN",
"description": "Crown Court"
},
"crn": "C123456"
}
]
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
{
"mappings": [
{
"request": {
"method": "GET",
"urlPathTemplate": "/secure/offenders/crn/{crn}/convictions/{convictionId}/courtAppearances"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "get_court_appearances_C123456.json"
}
},
{
"request": {
"method": "GET",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import uk.gov.justice.digital.hmpps.data.generator.SentenceGenerator.MAIN_OFFENC
import uk.gov.justice.digital.hmpps.data.generator.StaffGenerator.ALLOCATED
import uk.gov.justice.digital.hmpps.data.generator.UnpaidWorkGenerator.UNPAID_WORK_DETAILS_1
import uk.gov.justice.digital.hmpps.integrations.delius.service.toAttendance
import uk.gov.justice.digital.hmpps.integrations.delius.service.toCourtAppearance
import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.contentAsJson
import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withToken
import java.time.LocalDate
Expand Down Expand Up @@ -228,7 +229,7 @@ internal class ConvictionByCrnAndEventIdIntegrationTest {
),
CourtAppearanceBasic(
COURT_APPEARANCE.id,
COURT_APPEARANCE.appearanceDate.toLocalDateTime(),
COURT_APPEARANCE.appearanceDate,
COURT_APPEARANCE.court.code,
COURT_APPEARANCE.court.courtName,
KeyValue(COURT_APPEARANCE.appearanceType.code, COURT_APPEARANCE.appearanceType.description),
Expand Down Expand Up @@ -271,4 +272,17 @@ internal class ConvictionByCrnAndEventIdIntegrationTest {

assertThat(response.attendances[0], equalTo(ATTENDANCE_CONTACT_1.toAttendance()))
}

@Test
fun `call convictions by id and courtAppearances`() {
val crn = PersonGenerator.CURRENTLY_MANAGED.crn
val event = SentenceGenerator.CURRENTLY_MANAGED

val response = mockMvc
.perform(get("/probation-case/$crn/convictions/${event.id}/courtAppearances").withToken())
.andExpect(status().isOk)
.andReturn().response.contentAsJson<CourtAppearanceBasicWrapper>()

assertThat(response.courtAppearances[0], equalTo(COURT_APPEARANCE.toCourtAppearance()))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ internal class ConvictionByCrnIntegrationTest {
),
CourtAppearanceBasic(
COURT_APPEARANCE.id,
COURT_APPEARANCE.appearanceDate.toLocalDateTime(),
COURT_APPEARANCE.appearanceDate,
COURT_APPEARANCE.court.code,
COURT_APPEARANCE.court.courtName,
KeyValue(COURT_APPEARANCE.appearanceType.code, COURT_APPEARANCE.appearanceType.description),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,10 @@ internal class ProxyIntegrationTest {
},
"CONVICTION_BY_ID_PSS": {
"convictionId": "?"
},
"CONVICTION_BY_ID_COURT_APPEARANCES": {
"convictionId": "?",
"activeOnly": true
}
}
}
Expand All @@ -253,7 +257,7 @@ internal class ProxyIntegrationTest {
.withToken()
).andExpect(status().is2xxSuccessful).andReturn().response.contentAsJson<CompareAllReport>()

assertThat(res.totalNumberOfRequests, equalTo(10))
assertThat(res.totalNumberOfRequests, equalTo(11))
assertThat(res.totalNumberOfCrns, equalTo(2))
assertThat(res.currentPageNumber, equalTo(1))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ data class Court(
val courtType: KeyValue
)

data class CourtAppearanceBasicWrapper(
val courtAppearances: List<CourtAppearanceBasic> = emptyList()
)

data class CourtAppearanceBasic(
val courtAppearanceId: Long,
val appearanceDate: LocalDateTime,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ class CommunityApiController(
mapOf(
"crn" to crn,
"convictionId" to convictionId
), Uri.CONVICTION_BY_ID_NSIS, request
), Uri.CONVICTION_BY_ID_PSS, request
)

if (featureFlags.enabled("ccd-conviction-pss-enabled")) {
Expand All @@ -212,6 +212,26 @@ class CommunityApiController(
return proxy(request)
}

@GetMapping("/offenders/crn/{crn}/convictions/{convictionId}/courtAppearances")
fun convictionByIdCourtAppearances(
request: HttpServletRequest,
@PathVariable crn: String,
@PathVariable convictionId: Long,
): Any {

sendComparisonReport(
mapOf(
"crn" to crn,
"convictionId" to convictionId
), Uri.CONVICTION_BY_ID_COURT_APPEARANCES, request
)

if (featureFlags.enabled("ccd-conviction-by-id-court-appearances")) {
return convictionResource.getConvictionCourtAppearances(crn, convictionId)
}
return proxy(request)
}

@GetMapping("/**")
fun proxy(request: HttpServletRequest): ResponseEntity<String> {
val headers = request.headerNames.asSequence().associateWith { request.getHeader(it) }.toMutableMap()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ enum class Uri(
"getPssRequirementsByConvictionId",
listOf("crn", "convictionId"),
),

CONVICTION_BY_ID_COURT_APPEARANCES(
"/secure/offenders/crn/{crn}/convictions/{convictionId}/courtAppearances",
"convictionResource",
"getConvictionCourtAppearances",
listOf("crn", "convictionId"),
),
DUMMY("/dummy", "dummyResource", "getDummy", listOf("crn")),
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ import io.swagger.v3.oas.annotations.Parameter
import jakarta.validation.constraints.NotEmpty
import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.web.bind.annotation.*
import uk.gov.justice.digital.hmpps.integrations.delius.service.AttendanceService
import uk.gov.justice.digital.hmpps.integrations.delius.service.ConvictionService
import uk.gov.justice.digital.hmpps.integrations.delius.service.InterventionService
import uk.gov.justice.digital.hmpps.integrations.delius.service.RequirementService
import uk.gov.justice.digital.hmpps.integrations.delius.service.*

@RestController
@RequestMapping("probation-case/{crn}/convictions")
Expand All @@ -16,7 +13,8 @@ class ConvictionResource(
private val convictionService: ConvictionService,
private val requirementService: RequirementService,
private val interventionService: InterventionService,
private val attendanceService: AttendanceService
private val attendanceService: AttendanceService,
private val courtAppearanceService: CourtAppearanceService
) {

@GetMapping
Expand Down Expand Up @@ -90,4 +88,10 @@ class ConvictionResource(
@PathVariable crn: String,
@PathVariable convictionId: Long
) = attendanceService.getAttendancesFor(crn, convictionId)

@GetMapping("/{convictionId}/courtAppearances")
fun getConvictionCourtAppearances(
@PathVariable crn: String,
@PathVariable convictionId: Long
) = courtAppearanceService.getCourtAppearancesFor(crn, convictionId)
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import uk.gov.justice.digital.hmpps.integrations.delius.event.sentence.entity.Co
import uk.gov.justice.digital.hmpps.integrations.delius.person.entity.Person
import uk.gov.justice.digital.hmpps.integrations.delius.provider.entity.Staff
import java.time.LocalDate
import java.time.ZonedDateTime
import java.time.LocalDateTime

@Entity
@Immutable
Expand All @@ -26,7 +26,7 @@ class CourtAppearance(
@JoinColumn(name = "outcome_id")
val outcome: Outcome?,

val appearanceDate: ZonedDateTime,
val appearanceDate: LocalDateTime,

@Column(name = "soft_deleted", columnDefinition = "number")
val softDeleted: Boolean,
Expand All @@ -52,6 +52,11 @@ class CourtAppearance(
}
}

interface CourtAppearanceRepository : JpaRepository<CourtAppearance, Long> {

fun findByPersonIdAndEventId(personId: Long, eventId: Long): List<CourtAppearance>
}

interface CourtReportRepository : JpaRepository<CourtReport, Long> {

@Query(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class ConvictionService(
fun CourtAppearance.toCourtAppearanceBasic(): CourtAppearanceBasic =
CourtAppearanceBasic(
id,
appearanceDate.toLocalDateTime(),
appearanceDate,
court.code,
court.courtName,
KeyValue(appearanceType.code, appearanceType.description),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package uk.gov.justice.digital.hmpps.integrations.delius.service

import org.springframework.stereotype.Service
import uk.gov.justice.digital.hmpps.api.model.KeyValue
import uk.gov.justice.digital.hmpps.api.model.conviction.CourtAppearanceBasic
import uk.gov.justice.digital.hmpps.api.model.conviction.CourtAppearanceBasicWrapper
import uk.gov.justice.digital.hmpps.integrations.delius.event.courtappearance.entity.CourtAppearance
import uk.gov.justice.digital.hmpps.integrations.delius.event.courtappearance.entity.CourtAppearanceRepository
import uk.gov.justice.digital.hmpps.integrations.delius.event.entity.EventRepository
import uk.gov.justice.digital.hmpps.integrations.delius.event.entity.getByPersonAndEventNumber
import uk.gov.justice.digital.hmpps.integrations.delius.person.entity.PersonRepository
import uk.gov.justice.digital.hmpps.integrations.delius.person.entity.getPerson

@Service
class CourtAppearanceService(
private val personRepository: PersonRepository,
private val eventRepository: EventRepository,
private val courtAppearanceRepository: CourtAppearanceRepository
) {

fun getCourtAppearancesFor(crn: String, eventId: Long): CourtAppearanceBasicWrapper {
val person = personRepository.getPerson(crn)
val event = eventRepository.getByPersonAndEventNumber(person, eventId)
val courtAppearances = courtAppearanceRepository.findByPersonIdAndEventId(person.id, event.id)
.sortedByDescending { it.appearanceDate }
.map { it.toCourtAppearance() }
return CourtAppearanceBasicWrapper(courtAppearances)
}
}

fun CourtAppearance.toCourtAppearance() = CourtAppearanceBasic(
courtAppearanceId = id,
appearanceDate = appearanceDate,
courtCode = court.code,
courtName = court.courtName,
appearanceType = KeyValue(court.courtType.code, court.courtType.description),
crn = person.crn
)

0 comments on commit e80e2d2

Please sign in to comment.