Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/pi 1939 mas sentence card #3550

Merged
merged 14 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ class DataLoader(
PersonGenerator.REGISTER_TYPE_1,
PersonGenerator.REGISTER_TYPE_2,
PersonGenerator.REGISRATION_1,
PersonGenerator.REGISRATION_2
PersonGenerator.REGISRATION_2,
PersonGenerator.MAIN_CAT_F_TYPE
)

personalDetailsData()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ object PersonGenerator {
)

val DEFAULT_DISPOSAL_TYPE = generateDisposalType("DFS", "Default Sentence Type", "NP", 0)
val ACTIVE_ORDER = generateDisposal(EVENT_1)
val ACTIVE_ORDER = generateDisposal(EVENT_1, length = 12)

val INACTIVE_ORDER_1 = generateDisposal(INACTIVE_EVENT_1)
val INACTIVE_ORDER_2 = generateDisposal(INACTIVE_EVENT_2)
Expand All @@ -83,8 +83,10 @@ object PersonGenerator {
LocalDate.now()
)

val MAIN_CAT_F_SUB_ID = IdGenerator.getAndIncrement();
val MAIN_CAT_F_TYPE = ReferenceData(MAIN_CAT_F_SUB_ID, "G03", "High Intensity")
val MAIN_CAT_F = RequirementMainCategory(IdGenerator.getAndIncrement(), "F", "Main")
val REQUIREMENT = generateRequirement(ACTIVE_ORDER)
val REQUIREMENT = generateRequirement(ACTIVE_ORDER, MAIN_CAT_F_SUB_ID)
val REQUIREMENT_CONTACT_1 = ContactGenerator.generateContact(
OVERVIEW,
ContactGenerator.APPT_CT_1,
Expand Down Expand Up @@ -238,11 +240,14 @@ object PersonGenerator {

fun generateRequirement(
disposal: Disposal,
subCategoryId: Long,
length: Long = 12,
notes: String = "my notes",
mainCategory: RequirementMainCategory = MAIN_CAT_F,
active: Boolean = true,
softDeleted: Boolean = false,
id: Long = IdGenerator.getAndIncrement()
) = Requirement(id, disposal, mainCategory, active, softDeleted)
) = Requirement(id, length, notes, subCategoryId, disposal, mainCategory, active, softDeleted)

fun generateDisposalType(
code: String,
Expand All @@ -255,13 +260,14 @@ object PersonGenerator {
fun generateDisposal(
event: Event,
date: LocalDate = LocalDate.now().minusDays(14),
length: Long? = null,
type: DisposalType = DEFAULT_DISPOSAL_TYPE,
enteredEndDate: LocalDate? = null,
notionalEndDate: LocalDate? = null,
active: Boolean = true,
softDeleted: Boolean = false,
id: Long = IdGenerator.getAndIncrement()
) = Disposal(event, date, type, enteredEndDate, notionalEndDate, active, softDeleted, id)
) = Disposal(event, date, length, type, enteredEndDate, notionalEndDate, active, softDeleted, id)

fun generateOffence(
description: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ 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.Name
import uk.gov.justice.digital.hmpps.api.model.overview.Order
import uk.gov.justice.digital.hmpps.api.model.overview.Rar
import uk.gov.justice.digital.hmpps.api.model.sentence.*
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator
import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.contentAsJson
Expand Down Expand Up @@ -61,7 +63,9 @@ class SentenceIntegrationTest {
"Birmingham Court",
LocalDate.now(),
listOf(AdditionalSentence(3, null, null, "Disqualified from Driving"))
)
),
Order("Default Sentence Type", 12, null, LocalDate.now().minusDays(14)),
listOf(Requirement("Main", "High Intensity", 12, "my notes", Rar(1, 0, 1)))
),
Sentence(
OffenceDetails(
Expand All @@ -71,7 +75,9 @@ class SentenceIntegrationTest {
"overview",
emptyList()
),
Conviction(null, null, null, listOf())
Conviction(null, null, null, listOf()),
null,
listOf()
)
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import java.time.LocalDate

data class Order(
val description: String,
val length: Long?,
val endDate: LocalDate?,
val startDate: LocalDate
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package uk.gov.justice.digital.hmpps.api.model.sentence

import uk.gov.justice.digital.hmpps.api.model.overview.Rar

data class Requirement(
val description: String?,
val codeDescription: String?,
val length: Long?,
val notes: String?,
val rar: Rar? = null
)
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package uk.gov.justice.digital.hmpps.api.model.sentence

import uk.gov.justice.digital.hmpps.api.model.overview.Order

data class Sentence(
val offenceDetails: OffenceDetails,
val conviction: Conviction? = null,
val order: Order? = null,
val requirements: List<Requirement> = listOf(),
)
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ class Disposal(
@Column(name = "disposal_date")
val date: LocalDate,

@Column(name = "length")
val length: Long?,

@ManyToOne
@JoinColumn(name = "disposal_type_id")
val type: DisposalType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ class Requirement(
@Column(name = "rqmnt_id", nullable = false)
val id: Long,

val length: Long?,

@Column(name = "rqmnt_notes")
val notes: String?,

@Column(name = "rqmnt_type_sub_category_id")
val subCategoryId: Long?,

@ManyToOne
@JoinColumn(name = "disposal_id")
val disposal: Disposal? = null,
Expand All @@ -35,6 +43,14 @@ interface RarDays {
val type: String
}

interface RequirementDetails {
val id: Long
val description: String?
val codeDescription: String?
val length: Long?
val notes: String?
}

interface RequirementRepository : JpaRepository<Requirement, Long> {

@Query(
Expand All @@ -59,6 +75,51 @@ interface RequirementRepository : JpaRepository<Requirement, Long> {
""", nativeQuery = true
)
fun getRarDays(disposalId: Long): List<RarDays>

@Query(
"""
select count(r.rqmnt_id) as days, 'SCHEDULED' as type from contact c
join rqmnt r on r.rqmnt_id = c.rqmnt_id
join r_rqmnt_type_main_category mc on r.rqmnt_type_main_category_id = mc.rqmnt_type_main_category_id
where c.rar_activity = 'Y' and c.soft_deleted = 0
and (c.attended is null)
and (c.complied is null or c.complied = 'Y')
and mc.code = 'F' and r.active_flag = 1 and r.soft_deleted = 0
and r.disposal_id = :requirementId
union
select count(r.rqmnt_id) as days, 'COMPLETED' as type from contact c
join rqmnt r on r.rqmnt_id = c.rqmnt_id
join r_rqmnt_type_main_category mc on r.rqmnt_type_main_category_id = mc.rqmnt_type_main_category_id
where c.rar_activity = 'Y' and c.soft_deleted = 0
and (c.attended = 'Y')
and (c.complied is null or c.complied = 'Y')
and mc.code = 'F' and r.active_flag = 1 and r.soft_deleted = 0
and r.rqmnt_id = :requirementId
""", nativeQuery = true
)
fun getRarDaysByRequirementId(requirementId: Long): List<RarDays>

@Query(
"""
SELECT r.rqmnt_id as id, r."LENGTH", rrtmc.description, rsrl.code_description AS codeDescription, r.rqmnt_notes AS notes
FROM rqmnt r
JOIN r_rqmnt_type_main_category rrtmc
ON r.rqmnt_type_main_category_id = rrtmc.rqmnt_type_main_category_id
JOIN r_standard_reference_list rsrl
ON rsrl.standard_reference_list_id = r.rqmnt_type_sub_category_id
JOIN disposal d
ON r.disposal_id = d.disposal_id
JOIN event e
ON e.event_id = d.event_id
JOIN offender o
ON o.offender_id = e.offender_id
AND o.crn = :crn
AND e.event_number = :eventNumber
AND e.soft_deleted = 0
AND e.active_flag = 1
""", nativeQuery = true
)
fun getRequirements(crn: String, eventNumber: String): List<RequirementDetails>
}

@Immutable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import uk.gov.justice.digital.hmpps.integrations.delius.overview.entity.Event
interface EventSentenceRepository : JpaRepository<Event, Long> {
@Query(
"SELECT e FROM Event e " +
"LEFT JOIN FETCH e.disposal d " +
"LEFT JOIN FETCH d.type t " +
"LEFT JOIN FETCH e.court c " +
"LEFT JOIN FETCH e.mainOffence m " +
"LEFT JOIN FETCH e.additionalOffences ao " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ class OverviewService(
return Rar(completed = completedDays, scheduled = scheduledDays)
}

fun Disposal.toOrder() = Order(description = type.description, startDate = date, endDate = expectedEndDate())
fun Disposal.toOrder() =
Order(description = type.description, length = length, startDate = date, endDate = expectedEndDate())

fun Event.toSentence() = mainOffence?.offence?.let { offence ->
Sentence(
mainOffence = offence.toOffence(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package uk.gov.justice.digital.hmpps.service

import org.springframework.stereotype.Service
import uk.gov.justice.digital.hmpps.api.model.Name
import uk.gov.justice.digital.hmpps.api.model.overview.Order
import uk.gov.justice.digital.hmpps.api.model.overview.Rar
import uk.gov.justice.digital.hmpps.api.model.sentence.*
import uk.gov.justice.digital.hmpps.integrations.delius.overview.entity.Event
import uk.gov.justice.digital.hmpps.integrations.delius.overview.entity.PersonRepository
import uk.gov.justice.digital.hmpps.integrations.delius.overview.entity.PersonSummaryEntity
import uk.gov.justice.digital.hmpps.integrations.delius.overview.entity.getSummary
import uk.gov.justice.digital.hmpps.api.model.sentence.Offence
import uk.gov.justice.digital.hmpps.api.model.sentence.Requirement
import uk.gov.justice.digital.hmpps.integrations.delius.overview.entity.*
import uk.gov.justice.digital.hmpps.integrations.delius.overview.entity.RequirementDetails
import uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity.AdditionalSentenceRepository
import uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity.CourtAppearance
import uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity.CourtAppearanceRepository
Expand All @@ -18,7 +20,8 @@ class SentenceService(
private val eventRepository: EventSentenceRepository,
private val courtAppearanceRepository: CourtAppearanceRepository,
private val additionalSentenceRepository: AdditionalSentenceRepository,
private val personRepository: PersonRepository
private val personRepository: PersonRepository,
private val requirementRepository: RequirementRepository
) {
fun getMostRecentActiveEvent(crn: String): SentenceOverview {
val person = personRepository.getSummary(crn)
Expand All @@ -28,31 +31,54 @@ class SentenceService(
sentences = events.map {
val courtAppearance = courtAppearanceRepository.getFirstCourtAppearanceByEventIdOrderByDate(it.id)
val additionalSentences = additionalSentenceRepository.getAllByEventId(it.id)
it.toSentence(courtAppearance, additionalSentences)
it.toSentence(courtAppearance, additionalSentences, crn)
})
}

fun Event.toSentence(courtAppearance: CourtAppearance?, additionalSentences: List<ExtraSentence>) = Sentence(
OffenceDetails(
eventNumber = eventNumber,
offence = mainOffence?.let { Offence(it.offence.description, it.offenceCount) },
dateOfOffence = mainOffence?.date,
notes = notes,
additionalOffences = additionalOffences.map {
Offence(description = it.offence.description, count = it.offenceCount ?: 0)
}
),
Conviction(
sentencingCourt = courtAppearance?.court?.name,
responsibleCourt = court?.name,
convictionDate = convictionDate,
additionalSentences.map { it.toAdditionalSentence() }
fun Event.toSentence(courtAppearance: CourtAppearance?, additionalSentences: List<ExtraSentence>, crn: String) =
Sentence(
OffenceDetails(
eventNumber = eventNumber,
offence = mainOffence?.let { Offence(it.offence.description, it.offenceCount) },
dateOfOffence = mainOffence?.date,
notes = notes,
additionalOffences = additionalOffences.map {
Offence(description = it.offence.description, count = it.offenceCount ?: 0)
}
),
Conviction(
sentencingCourt = courtAppearance?.court?.name,
responsibleCourt = court?.name,
convictionDate = convictionDate,
additionalSentences.map { it.toAdditionalSentence() }
),
order = disposal?.toOrder(),
requirements = disposal.let {
requirementRepository.getRequirements(crn, eventNumber).map { it.toRequirement() }
},
)
)

fun ExtraSentence.toAdditionalSentence(): AdditionalSentence =
AdditionalSentence(length, amount, notes, type.description)

fun PersonSummaryEntity.toName() =
Name(forename, secondName, surname)

fun Disposal.toOrder() =
Order(description = type.description, length = length, startDate = date, endDate = expectedEndDate())

fun RequirementDetails.toRequirement() = Requirement(
description,
codeDescription,
length,
notes,
getRar(id)
)

private fun getRar(requirementId: Long): Rar {
val rarDays = requirementRepository.getRarDaysByRequirementId(requirementId)
val scheduledDays = rarDays.find { it.type == "SCHEDULED" }?.days ?: 0
val completedDays = rarDays.find { it.type == "COMPLETED" }?.days ?: 0
return Rar(completed = completedDays, scheduled = scheduledDays)
}
}
Loading