diff --git a/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt b/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt index e09b94c7e6..168522c0ea 100644 --- a/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt +++ b/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt @@ -86,6 +86,7 @@ class DataLoader( PersonGenerator.TERMINATION_REASON, PersonGenerator.INACTIVE_ORDER_1, PersonGenerator.INACTIVE_ORDER_2, + ContactGenerator.COMMUNICATION_CATEGORY_RD, ContactGenerator.BREACH_CONTACT_TYPE, ContactGenerator.BREACH_ENFORCEMENT_ACTION, ContactGenerator.APPT_CT_1, @@ -98,6 +99,8 @@ class DataLoader( ContactGenerator.FIRST_APPT_CONTACT, ContactGenerator.ACCEPTABLE_ABSENCE, ContactGenerator.PREVIOUS_APPT_CONTACT_ABSENT, + ContactGenerator.PREVIOUS_COMMUNICATION_CONTACT, + ContactGenerator.COMMUNICATION_CATEGORY, ContactGenerator.CONTACT_DOCUMENT_1, ContactGenerator.CONTACT_DOCUMENT_2, PersonGenerator.OFFENCE_1, diff --git a/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ContactGenerator.kt b/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ContactGenerator.kt index ff7d4c4fd4..1261aa4571 100644 --- a/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ContactGenerator.kt +++ b/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ContactGenerator.kt @@ -7,6 +7,7 @@ import uk.gov.justice.digital.hmpps.data.generator.UserGenerator.USER import uk.gov.justice.digital.hmpps.datetime.EuropeLondon import uk.gov.justice.digital.hmpps.integrations.delius.overview.entity.* import uk.gov.justice.digital.hmpps.integrations.delius.personalDetails.entity.ContactDocument +import uk.gov.justice.digital.hmpps.integrations.delius.referencedata.entity.ReferenceData import java.time.LocalDate import java.time.LocalDateTime import java.time.ZonedDateTime @@ -28,11 +29,13 @@ object ContactGenerator { ) val DEFAULT_STAFF = generateStaff("N01BDT1", "John", "Smith") + val COMMUNICATION_CATEGORY_RD = ReferenceData(IdGenerator.getAndIncrement(), "LT", "Communication") + val BREACH_CONTACT_TYPE = generateContactType("BRE02", false, "Breach Contact Type") val BREACH_ENFORCEMENT_ACTION = generateEnforcementAction("BRE02", "Breach Enforcement Action", BREACH_CONTACT_TYPE) val APPT_CT_1 = generateContactType("C089", true, "Alcohol Key Worker Session (NS)") - val OTHER_CT = generateContactType("XXXX", false, "Non attendance contact type") + val OTHER_CT = generateContactType("XXXX", false, "Non attendance contact type", systemGenerated = true) val APPT_CT_2 = generateContactType("CODI", true, "Initial Appointment on Doorstep (NS)") val APPT_CT_3 = generateContactType("CODC", true, "Planned Doorstep Contact (NS)") @@ -48,6 +51,7 @@ object ContactGenerator { outcome = ACCEPTABLE_ABSENCE ) + val PREVIOUS_APPT_CONTACT = generateContact( OVERVIEW, APPT_CT_1, @@ -69,6 +73,14 @@ object ContactGenerator { ZonedDateTime.of(LocalDateTime.now(EuropeLondon).plusHours(3), EuropeLondon) ) + val PREVIOUS_COMMUNICATION_CONTACT = generateContact( + OVERVIEW, + OTHER_CT, + ZonedDateTime.of(LocalDateTime.now(EuropeLondon).minusDays(10), EuropeLondon), + ) + + val COMMUNICATION_CATEGORY = generateContactCategory(OTHER_CT, COMMUNICATION_CATEGORY_RD) + val CONTACT_DOCUMENT_1 = generateContactDocument( OVERVIEW.id, "B001", @@ -126,7 +138,7 @@ object ContactGenerator { action: EnforcementAction? = null, startTime: ZonedDateTime? = ZonedDateTime.of(LocalDate.EPOCH, startDateTime.toLocalTime(), startDateTime.zone), event: Event = PersonGenerator.EVENT_1, - outcome: ContactOutcome? = null + outcome: ContactOutcome? = null, ) = Contact( id = IdGenerator.getAndIncrement(), personId = person.id, @@ -151,8 +163,16 @@ object ContactGenerator { private fun generateOutcome(code: String, description: String, attendance: Boolean, acceptable: Boolean) = ContactOutcome(IdGenerator.getAndIncrement(), code, description, attendance, acceptable) - private fun generateContactType(code: String, attendance: Boolean, description: String) = - ContactType(IdGenerator.getAndIncrement(), code, attendance, description) + private fun generateContactType( + code: String, + attendance: Boolean, + description: String, + systemGenerated: Boolean = false + ) = + ContactType(IdGenerator.getAndIncrement(), code, attendance, description, systemGenerated = systemGenerated) + + private fun generateContactCategory(contactType: ContactType, contactCategory: ReferenceData) = + ContactCategory(id = contactType.id, category = contactCategory) fun generateOfficeLocation( code: String, diff --git a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/ActivityIntegrationTest.kt b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/ActivityIntegrationTest.kt index e192af814c..940389a1d5 100644 --- a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/ActivityIntegrationTest.kt +++ b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/ActivityIntegrationTest.kt @@ -33,18 +33,20 @@ internal class ActivityIntegrationTest { .andReturn().response.contentAsJson() assertThat(res.personSummary.crn, equalTo(person.crn)) - assertThat(res.activities.size, equalTo(7)) - assertThat(res.activities[2].id, equalTo(ContactGenerator.FIRST_APPT_CONTACT.toActivity().id)) - assertThat(res.activities[2].type, equalTo(ContactGenerator.FIRST_APPT_CONTACT.toActivity().type)) + assertThat(res.activities.size, equalTo(8)) + assertThat(res.activities[0].isCommunication, equalTo(true)) + assertThat(res.activities[0].isSystemContact, equalTo(true)) + assertThat(res.activities[3].id, equalTo(ContactGenerator.FIRST_APPT_CONTACT.toActivity().id)) + assertThat(res.activities[3].type, equalTo(ContactGenerator.FIRST_APPT_CONTACT.toActivity().type)) assertThat( res.activities[2].location?.officeName, equalTo(ContactGenerator.FIRST_APPT_CONTACT.toActivity().location?.officeName) ) - assertThat(res.activities[2].location?.postcode, equalTo("H34 7TH")) - assertThat(res.activities[2].isAppointment, equalTo(true)) - assertThat(res.activities[1].documents.size, equalTo(2)) - assertThat(res.activities[3].isAppointment, equalTo(false)) - assertThat(res.activities[0].documents.size, equalTo(0)) - assertThat(res.activities[0].action, equalTo("Breach Enforcement Action")) + assertThat(res.activities[3].location?.postcode, equalTo("H34 7TH")) + assertThat(res.activities[3].isAppointment, equalTo(true)) + assertThat(res.activities[2].documents.size, equalTo(2)) + assertThat(res.activities[4].isAppointment, equalTo(false)) + assertThat(res.activities[1].documents.size, equalTo(0)) + assertThat(res.activities[1].action, equalTo("Breach Enforcement Action")) } } diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/activity/Activity.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/activity/Activity.kt index 31017c0ecf..bfcc0adc2a 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/activity/Activity.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/activity/Activity.kt @@ -35,6 +35,7 @@ data class Activity( val acceptableAbsence: Boolean?, val acceptableAbsenceReason: String?, val isAppointment: Boolean = false, + val isCommunication: Boolean = false, val action: String?, val isSystemContact: Boolean? = false, val isEmailOrTextFromPop: Boolean? = false, diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/overview/entity/Contact.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/overview/entity/Contact.kt index 25a6fa477f..d7cb8972dd 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/overview/entity/Contact.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/overview/entity/Contact.kt @@ -9,6 +9,7 @@ import org.springframework.data.jpa.repository.Query import uk.gov.justice.digital.hmpps.datetime.EuropeLondon import uk.gov.justice.digital.hmpps.exception.NotFoundException import uk.gov.justice.digital.hmpps.integrations.delius.personalDetails.entity.ContactDocument +import uk.gov.justice.digital.hmpps.integrations.delius.referencedata.entity.ReferenceData import uk.gov.justice.digital.hmpps.integrations.delius.user.entity.User import java.time.LocalDate import java.time.ZonedDateTime @@ -120,10 +121,12 @@ class Contact( ).contains(outcome?.code) fun rescheduled(): Boolean = rescheduledStaff() || rescheduledPop() - fun isEmailOrTextFromPop(): Boolean = type.code.equals(ContactTypeCode.EMAIL_OR_TEXT_FROM_POP.value) - fun isEmailOrTextToPop(): Boolean = type.code.equals(ContactTypeCode.EMAIL_OR_TEXT_TO_POP.value) - fun isPhoneCallFromPop(): Boolean = type.code.equals(ContactTypeCode.PHONE_CONTACT_FROM_POP.value) - fun isPhoneCallToPop(): Boolean = type.code.equals(ContactTypeCode.PHONE_CONTACT_TO_POP.value) + fun isEmailOrTextFromPop(): Boolean = type.code == ContactTypeCode.EMAIL_OR_TEXT_FROM_POP.value + fun isEmailOrTextToPop(): Boolean = type.code == ContactTypeCode.EMAIL_OR_TEXT_TO_POP.value + fun isPhoneCallFromPop(): Boolean = type.code == ContactTypeCode.PHONE_CONTACT_FROM_POP.value + fun isPhoneCallToPop(): Boolean = type.code == ContactTypeCode.PHONE_CONTACT_TO_POP.value + fun isCommunication(): Boolean = + type.category?.category?.code?.equals(ContactCategoryCode.COMMUNICATION_CONTACT.value) ?: false } @Immutable @@ -144,11 +147,34 @@ class ContactType( @Column val description: String, + @ManyToOne + @JoinTable( + name = "r_contact_typecontact_category", + inverseJoinColumns = [JoinColumn(name = "contact_type_id", insertable = false, updatable = false)], + ) + val category: ContactCategory? = null, + + @Column(name = "sgc_flag", columnDefinition = "number") + val systemGenerated: Boolean = false, + @Column(name = "national_standards_contact") @Convert(converter = YesNoConverter::class) val nationalStandardsContact: Boolean = false, ) +@Immutable +@Entity +@Table(name = "r_contact_typecontact_category") +class ContactCategory( + @Id + @Column(name = "contact_type_id") + val id: Long, + + @ManyToOne + @JoinColumn(name = "standard_reference_list_id") + val category: ReferenceData, +) + @Immutable @Entity @Table(name = "r_contact_outcome_type") @@ -203,6 +229,10 @@ enum class ContactTypeCode(val value: String) { PHONE_CONTACT_TO_POP("CTOB"), } +enum class ContactCategoryCode(val value: String) { + COMMUNICATION_CONTACT("LT") +} + interface ContactRepository : JpaRepository { @Query( diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/ComplianceService.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/ComplianceService.kt index bed319c901..83a93b7404 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/ComplianceService.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/ComplianceService.kt @@ -35,7 +35,7 @@ class ComplianceService( fun breachesForSentence(eventId: Long) = allBreaches.filter { (it.eventId == eventId) } fun activeBreachCountForSentence(eventId: Long) = - allBreaches.filter { it.eventId == eventId && it.active }.firstOrNull() + allBreaches.firstOrNull { it.eventId == eventId && it.active } fun sentenceActivity(eventNumber: String) = allActiveSentenceActivity.filter { it.eventNumber == eventNumber } diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/OverviewService.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/OverviewService.kt index c36c03a7d8..a12e17b0c4 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/OverviewService.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/OverviewService.kt @@ -42,7 +42,7 @@ class OverviewService( val sentences = activeEvents.map { it.toSentence() } val allBreaches = nsiRepository.getAllBreaches(person.id) val previousOrders = events.filter { !it.active && it.disposal != null } - val previousOrdersBreached = allBreaches.filter { it.eventId in previousOrders.map { it.id } }.size + val previousOrdersBreached = allBreaches.filter { it -> it.eventId in previousOrders.map { it.id } }.size val compliance = toSentenceCompliance(previousAppointments.map { it.toActivity() }, allBreaches) val registrations = registrationRepository.findByPersonId(person.id) diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/ScheduleService.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/ScheduleService.kt index 75e5345d35..9138c0b0f2 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/ScheduleService.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/ScheduleService.kt @@ -94,11 +94,12 @@ fun Contact.toActivity() = Activity( ) else null, isAppointment = type.attendanceContact, action = action?.description, - isSystemContact = false, //ToDo + isSystemContact = type.systemGenerated, isEmailOrTextFromPop = isEmailOrTextFromPop(), isEmailOrTextToPop = isEmailOrTextToPop(), isPhoneCallFromPop = isPhoneCallFromPop(), isPhoneCallToPop = isPhoneCallToPop(), + isCommunication = isCommunication(), eventNumber = event?.eventNumber )