From 69d4abb1605b28f600f45d3512a42698c66b1bc2 Mon Sep 17 00:00:00 2001 From: Marcus Aspin Date: Tue, 12 Nov 2024 18:56:23 +0000 Subject: [PATCH 01/26] PI-2543 Use East of England template for GOV.UK Notify (#4423) --- .../appointment-reminders-and-delius/deploy/values-prod.yml | 3 +-- .../kotlin/uk/gov/justice/digital/hmpps/IntegrationTest.kt | 2 +- .../digital/hmpps/service/UnpaidWorkAppointmentsService.kt | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/projects/appointment-reminders-and-delius/deploy/values-prod.yml b/projects/appointment-reminders-and-delius/deploy/values-prod.yml index 6c96f52410..60c56efbf9 100644 --- a/projects/appointment-reminders-and-delius/deploy/values-prod.yml +++ b/projects/appointment-reminders-and-delius/deploy/values-prod.yml @@ -1,5 +1,3 @@ -enabled: false # TODO set this to true when you're ready to deploy your service - generic-service: ingress: host: appointment-reminders-and-delius.hmpps.service.justice.gov.uk @@ -8,6 +6,7 @@ generic-service: SENTRY_ENVIRONMENT: prod SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI: https://sign-in.hmpps.service.justice.gov.uk/auth/.well-known/jwks.json SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI: https://sign-in.hmpps.service.justice.gov.uk/auth/issuer + GOVUK-NOTIFY_TEMPLATES_UPW-APPOINTMENT-REMINDER: 4895f1a9-50b7-481e-9fca-2ac0f8d200d2 jobs: unpaid-work-appointment-reminders: diff --git a/projects/appointment-reminders-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/IntegrationTest.kt b/projects/appointment-reminders-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/IntegrationTest.kt index 9886227bc5..3f8875a303 100644 --- a/projects/appointment-reminders-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/IntegrationTest.kt +++ b/projects/appointment-reminders-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/IntegrationTest.kt @@ -89,7 +89,7 @@ internal class IntegrationTest { verify(notificationClient).sendSms( "cd713c1b-1b27-45a0-b493-37a34666635a", "07000000000", - mapOf("firstName" to "Test", "date" to "01/01/2000"), + mapOf("FirstName" to "Test", "NextWorkSession" to "01/01/2000"), "123, 456" ) verify(telemetryService).trackEvent( diff --git a/projects/appointment-reminders-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/UnpaidWorkAppointmentsService.kt b/projects/appointment-reminders-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/UnpaidWorkAppointmentsService.kt index d22336a8e3..2b08245809 100644 --- a/projects/appointment-reminders-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/UnpaidWorkAppointmentsService.kt +++ b/projects/appointment-reminders-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/UnpaidWorkAppointmentsService.kt @@ -20,7 +20,7 @@ class UnpaidWorkAppointmentsService( notificationClient.sendSms( templateId, it.mobileNumber, - mapOf("firstName" to it.firstName, "date" to it.appointmentDate), + mapOf("FirstName" to it.firstName, "NextWorkSession" to it.appointmentDate), it.upwAppointmentIds ) telemetryService.trackEvent( From 3e11a2582e69bc012f4d983cafae16997fa1a562 Mon Sep 17 00:00:00 2001 From: "probation-integration-bot[bot]" <177347787+probation-integration-bot[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 16:04:40 +0000 Subject: [PATCH 02/26] Update Gradle Wrapper from 8.10.2 to 8.11 (#4422) * Bump Gradle Wrapper to the latest version * Enable parallel config cache + update deprecated usage for Jib * Formatting changes --------- Co-authored-by: probation-integration-bot[bot] <177347787+probation-integration-bot[bot]@users.noreply.github.com> Co-authored-by: Marcus Aspin --- .../digital/hmpps/plugins/JibConfigPlugin.kt | 2 +- gradle.properties | 1 + gradle/wrapper/gradle-wrapper.properties | 4 +-- .../hmpps/ldap/LdapTemplateExtensions.kt | 26 ++++++++++--------- .../hmpps/data/ProbationCaseDataLoader.kt | 11 ++++---- .../delius/service/DocumentService.kt | 3 ++- .../delius/service/OffenderService.kt | 3 ++- .../digital/hmpps/messaging/Handler.kt | 13 +++++----- .../hmpps/service/ComplianceService.kt | 3 ++- .../hmpps/service/PersonalDetailsService.kt | 3 ++- .../delius/allocations/ManagerService.kt | 4 +-- .../gradle/wrapper/gradle-wrapper.properties | 4 +-- 12 files changed, 43 insertions(+), 34 deletions(-) diff --git a/buildSrc/src/main/kotlin/uk/gov/justice/digital/hmpps/plugins/JibConfigPlugin.kt b/buildSrc/src/main/kotlin/uk/gov/justice/digital/hmpps/plugins/JibConfigPlugin.kt index 58182fc444..ee61f2f374 100644 --- a/buildSrc/src/main/kotlin/uk/gov/justice/digital/hmpps/plugins/JibConfigPlugin.kt +++ b/buildSrc/src/main/kotlin/uk/gov/justice/digital/hmpps/plugins/JibConfigPlugin.kt @@ -75,7 +75,7 @@ class JibConfigPlugin : Plugin { "$buildDir/classes", "$buildDir/generated", "$buildDir/resources", - project.configurations[jib!!.configurationName.get()].resolvedConfiguration.files + project.configurations[jib!!.configurationName.get()].resolvedConfiguration.resolvedArtifacts.map { it.file } ) outputs.file("$buildDir/jib-image.id") outputs.cacheIf { true } diff --git a/gradle.properties b/gradle.properties index 13c47f9710..1b387ffcbb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,7 @@ org.gradle.parallel=true org.gradle.caching=true org.gradle.configuration-cache=true +org.gradle.configuration-cache.parallel=true org.gradle.configuration-cache.problems=warn # Remove the above line once https://github.com/n0mer/gradle-git-properties/pull/235 is released org.gradle.jvmargs=-Xmx4g "-XX:MaxMetaspaceSize=1g" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index fb602ee2af..82dd18b204 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=31c55713e40233a8303827ceb42ca48a47267a0ad4bab9177123121e71524c26 -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip +distributionSha256Sum=57dafb5c2622c6cc08b993c85b7c06956a2f53536432a30ead46166dbca0f1e9 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/libs/commons/src/main/kotlin/uk/gov/justice/digital/hmpps/ldap/LdapTemplateExtensions.kt b/libs/commons/src/main/kotlin/uk/gov/justice/digital/hmpps/ldap/LdapTemplateExtensions.kt index 040bebd336..9ed652e09b 100644 --- a/libs/commons/src/main/kotlin/uk/gov/justice/digital/hmpps/ldap/LdapTemplateExtensions.kt +++ b/libs/commons/src/main/kotlin/uk/gov/justice/digital/hmpps/ldap/LdapTemplateExtensions.kt @@ -30,12 +30,13 @@ fun LdapTemplate.findEmailByUsername(@SpanAttribute username: String) = findAttr @WithSpan fun LdapTemplate.findAttributeByUsername(@SpanAttribute username: String, @SpanAttribute attribute: String) = try { - search(query() - .attributes(attribute) - .searchScope(SearchScope.ONELEVEL) - .where("objectclass").`is`("inetOrgPerson") - .and("objectclass").`is`("top") - .and("cn").`is`(username), + search( + query() + .attributes(attribute) + .searchScope(SearchScope.ONELEVEL) + .where("objectclass").`is`("inetOrgPerson") + .and("objectclass").`is`("top") + .and("cn").`is`(username), AttributesMapper { it[attribute]?.get()?.toString() } ).singleOrNull() } catch (_: NameNotFoundException) { @@ -44,12 +45,13 @@ fun LdapTemplate.findAttributeByUsername(@SpanAttribute username: String, @SpanA @WithSpan fun LdapTemplate.getRoles(@SpanAttribute username: String) = try { - search(query() - .attributes("cn") - .base(LdapNameBuilder.newInstance().add("cn", username).build()) - .searchScope(SearchScope.ONELEVEL) - .where("objectclass").`is`("NDRole") - .or("objectclass").`is`("NDRoleAssociation"), + search( + query() + .attributes("cn") + .base(LdapNameBuilder.newInstance().add("cn", username).build()) + .searchScope(SearchScope.ONELEVEL) + .where("objectclass").`is`("NDRole") + .or("objectclass").`is`("NDRoleAssociation"), AttributesMapper { it["cn"]?.get()?.toString() } ).filterNotNull() } catch (_: NameNotFoundException) { diff --git a/projects/approved-premises-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/ProbationCaseDataLoader.kt b/projects/approved-premises-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/ProbationCaseDataLoader.kt index 8e9d8f3615..56deb3a926 100644 --- a/projects/approved-premises-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/ProbationCaseDataLoader.kt +++ b/projects/approved-premises-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/ProbationCaseDataLoader.kt @@ -123,11 +123,12 @@ class ProbationCaseDataLoader( personalCircumstanceTypeRepository.saveAll(PersonalCircumstanceGenerator.PC_TYPES) personalCircumstanceSubTypeRepository.saveAll(PersonalCircumstanceGenerator.PC_SUB_TYPES) - personalCircumstanceRepository.save(PersonalCircumstanceGenerator.generate( - ProbationCaseGenerator.CASE_COMPLEX.id, - PersonalCircumstanceGenerator.PC_TYPES.first { it.code == PersonalCircumstanceType.Code.VETERAN.value }, - PersonalCircumstanceGenerator.PC_SUB_TYPES.first { it.description == PersonalCircumstanceType.Code.VETERAN.value + "SUB" } - )) + personalCircumstanceRepository.save( + PersonalCircumstanceGenerator.generate( + ProbationCaseGenerator.CASE_COMPLEX.id, + PersonalCircumstanceGenerator.PC_TYPES.first { it.code == PersonalCircumstanceType.Code.VETERAN.value }, + PersonalCircumstanceGenerator.PC_SUB_TYPES.first { it.description == PersonalCircumstanceType.Code.VETERAN.value + "SUB" } + )) mutableLimitedAccessPersonRepository.save(RESTRICTED_CASE) mutableLimitedAccessPersonRepository.save(EXCLUDED_CASE) diff --git a/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/service/DocumentService.kt b/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/service/DocumentService.kt index e474fbc362..a758f4f1c9 100644 --- a/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/service/DocumentService.kt +++ b/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/service/DocumentService.kt @@ -42,7 +42,8 @@ class DocumentService( val convictions = convictionDocuments .groupBy { it.eventId } .map { - ConvictionDocuments(it.key.toString(), + ConvictionDocuments( + it.key.toString(), it.value.map { d -> d.toOffenderDocumentDetail() } .filter { odd -> filter(odd, filterData) }) } diff --git a/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/service/OffenderService.kt b/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/service/OffenderService.kt index 533d399124..0b42b40fae 100644 --- a/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/service/OffenderService.kt +++ b/projects/court-case-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/service/OffenderService.kt @@ -217,7 +217,8 @@ fun DisabilityEntity.toDisability() = Disability( startDate = startDate ) -fun DocumentEntity?.toPreviousConviction() = PreviousConviction(convictionDate = this?.dateProduced?.toLocalDate(), +fun DocumentEntity?.toPreviousConviction() = PreviousConviction( + convictionDate = this?.dateProduced?.toLocalDate(), detail = this?.name?.let { ImmutableMap.of("documentName", it) }) fun Person.toProfile(previousConviction: DocumentEntity?) = OffenderProfile( diff --git a/projects/justice-email-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/Handler.kt b/projects/justice-email-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/Handler.kt index 3e37b122e5..7ccfd7cc97 100644 --- a/projects/justice-email-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/Handler.kt +++ b/projects/justice-email-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/Handler.kt @@ -84,12 +84,13 @@ class Handler( private fun findStaffIdForEmailAddress(emailAddress: String): Long? { val matchingStaffIds = try { ldapTemplate - .search(query() - .attributes("cn") - .searchScope(SearchScope.ONELEVEL) - .where("objectclass").`is`("inetOrgPerson") - .and("objectclass").`is`("top") - .and("mail").`is`(emailAddress), + .search( + query() + .attributes("cn") + .searchScope(SearchScope.ONELEVEL) + .where("objectclass").`is`("inetOrgPerson") + .and("objectclass").`is`("top") + .and("mail").`is`(emailAddress), AttributesMapper { it["cn"]?.get()?.toString() }) .filterNotNull() .mapNotNull { staffRepository.findByUserUsername(it)?.id } 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 b2436cff59..b0b1445471 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 @@ -76,7 +76,8 @@ class ComplianceService( return PersonCompliance( personSummary = summary.toPersonSummary(), currentSentences = currentSentences.mapNotNull { it.toSentenceCompliance() }, - previousOrders = PreviousOrders(breaches = previousOrders.map { breachesForSentence(it.id) }.count(), + previousOrders = PreviousOrders( + breaches = previousOrders.map { breachesForSentence(it.id) }.count(), count = previousOrders.size, orders = previousOrders.mapNotNull { it.disposal?.toOrder( diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/PersonalDetailsService.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/PersonalDetailsService.kt index c2d4c09bd2..3399049e22 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/PersonalDetailsService.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/PersonalDetailsService.kt @@ -58,7 +58,8 @@ class PersonalDetailsService( preferredName = person.preferredName, telephoneNumber = person.telephoneNumber, mobileNumber = person.mobileNumber, - circumstances = Circumstances(lastUpdated = personalCircumstances.maxOfOrNull { it.lastUpdated }, + circumstances = Circumstances( + lastUpdated = personalCircumstances.maxOfOrNull { it.lastUpdated }, circumstances = personalCircumstances.map { PersonalCircumstance( it.subType.description, diff --git a/projects/workforce-allocations-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/allocations/ManagerService.kt b/projects/workforce-allocations-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/allocations/ManagerService.kt index 659cb5699e..0ccaec092c 100644 --- a/projects/workforce-allocations-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/allocations/ManagerService.kt +++ b/projects/workforce-allocations-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/allocations/ManagerService.kt @@ -47,7 +47,7 @@ abstract class ManagerService( staffId = newManager.staff.id, providerId = newManager.provider.id, notes = - """ + """ |Transfer Reason: Internal Transfer |Transfer Date: ${newManager.startDate.format(DateTimeFormatter.ofPattern("dd/MM/yyyy"))} |From Trust: ${newManager.provider.description} @@ -55,7 +55,7 @@ abstract class ManagerService( |From Officer: ${oldManager.staff.displayName} |-------------------------------/${System.lineSeparator()} |""" - .trimMargin() + .trimMargin() ) } diff --git a/tools/ingress-testing/api-client/gradle/wrapper/gradle-wrapper.properties b/tools/ingress-testing/api-client/gradle/wrapper/gradle-wrapper.properties index fb602ee2af..82dd18b204 100644 --- a/tools/ingress-testing/api-client/gradle/wrapper/gradle-wrapper.properties +++ b/tools/ingress-testing/api-client/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=31c55713e40233a8303827ceb42ca48a47267a0ad4bab9177123121e71524c26 -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip +distributionSha256Sum=57dafb5c2622c6cc08b993c85b7c06956a2f53536432a30ead46166dbca0f1e9 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From b1fe5a1c4a65a81185a821dabc8c34a14db43207 Mon Sep 17 00:00:00 2001 From: Marcus Aspin Date: Wed, 13 Nov 2024 16:38:26 +0000 Subject: [PATCH 03/26] PI-2619 Reduce batch size for incremental logstash pipelines (#4425) * PI-2619 Reduce batch size for incremental logstash pipelines * Formatting changes --------- Co-authored-by: probation-integration-bot[bot] <177347787+probation-integration-bot[bot]@users.noreply.github.com> --- .../container/config/logstash.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/person-search-index-from-delius/container/config/logstash.yml b/projects/person-search-index-from-delius/container/config/logstash.yml index c9b7995845..a3f928816e 100644 --- a/projects/person-search-index-from-delius/container/config/logstash.yml +++ b/projects/person-search-index-from-delius/container/config/logstash.yml @@ -2,4 +2,4 @@ api.http.host: 0.0.0.0 config.reload.automatic: true config.support_escapes: true dead_letter_queue.enable: true -pipeline.batch.size: ${PIPELINE_BATCH_SIZE:100} \ No newline at end of file +pipeline.batch.size: ${PIPELINE_BATCH_SIZE:10} \ No newline at end of file From 2d90979446f5fbf6098c1bb94628da0a5ab9f3b5 Mon Sep 17 00:00:00 2001 From: Marcus Aspin Date: Wed, 13 Nov 2024 16:46:12 +0000 Subject: [PATCH 04/26] PI-2632 Add ids to the offence response (#4426) --- .../kotlin/uk/gov/justice/digital/hmpps/model/CaseDetail.kt | 2 ++ .../kotlin/uk/gov/justice/digital/hmpps/service/CaseService.kt | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/model/CaseDetail.kt b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/model/CaseDetail.kt index 24c1a2063c..b7359827c0 100644 --- a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/model/CaseDetail.kt +++ b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/model/CaseDetail.kt @@ -59,10 +59,12 @@ data class MappaDetail( ) data class Offence( + val id: Long, val code: String, val description: String, val date: LocalDate?, val main: Boolean, + val eventId: Long, val eventNumber: String ) diff --git a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/CaseService.kt b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/CaseService.kt index 72b66d3bb8..49cc6a0f32 100644 --- a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/CaseService.kt +++ b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/CaseService.kt @@ -87,7 +87,7 @@ fun CommunityManager.team() = Team( team.endDate ) -fun CaseOffence.asOffence() = Offence(code, description, date, main, eventNumber) +fun CaseOffence.asOffence() = Offence(id, code, description, date, main, eventId, eventNumber) fun Registration.asRegistration() = uk.gov.justice.digital.hmpps.model.Registration(type.code, type.description, date) fun Registration.asMappa() = MappaDetail( From 91cf66552b3fc23ae234347f16f3e5e0f7de6311 Mon Sep 17 00:00:00 2001 From: Marcus Aspin Date: Thu, 14 Nov 2024 09:53:34 +0000 Subject: [PATCH 05/26] PI-2619 Validate JDBC connections before use + delay dev startup (#4427) * PI-2619 Validate JDBC connections before use * Delay startup time in dev --- .../container/pipelines/contact/logstash-incremental.conf | 2 ++ .../container/pipelines/person/logstash-incremental.conf | 2 ++ projects/person-search-index-from-delius/deploy/values-dev.yml | 1 + 3 files changed, 5 insertions(+) diff --git a/projects/person-search-index-from-delius/container/pipelines/contact/logstash-incremental.conf b/projects/person-search-index-from-delius/container/pipelines/contact/logstash-incremental.conf index 3bca0ce575..27e5792e98 100644 --- a/projects/person-search-index-from-delius/container/pipelines/contact/logstash-incremental.conf +++ b/projects/person-search-index-from-delius/container/pipelines/contact/logstash-incremental.conf @@ -32,6 +32,8 @@ filter { jdbc_connection_string => "${JDBC_CONNECTION_STRING}" jdbc_user => "${JDBC_USER}" jdbc_password => "${JDBC_PASSWORD}" + jdbc_validate_connection => true + jdbc_validation_timeout => 120 statement => "${INCREMENTAL_STATEMENT_SQL}" use_prepared_statements => true prepared_statement_name => "search_indexer_contact_incremental" diff --git a/projects/person-search-index-from-delius/container/pipelines/person/logstash-incremental.conf b/projects/person-search-index-from-delius/container/pipelines/person/logstash-incremental.conf index d171b0c1c3..eda2612a49 100644 --- a/projects/person-search-index-from-delius/container/pipelines/person/logstash-incremental.conf +++ b/projects/person-search-index-from-delius/container/pipelines/person/logstash-incremental.conf @@ -19,6 +19,8 @@ filter { jdbc_connection_string => "${JDBC_CONNECTION_STRING}" jdbc_user => "${JDBC_USER}" jdbc_password => "${JDBC_PASSWORD}" + jdbc_validate_connection => true + jdbc_validation_timeout => 120 statement => "${INCREMENTAL_STATEMENT_SQL}" parameters => { "offender_id" => "%{offenderId}" } target => "db" diff --git a/projects/person-search-index-from-delius/deploy/values-dev.yml b/projects/person-search-index-from-delius/deploy/values-dev.yml index 945ac173f6..333a288c9c 100644 --- a/projects/person-search-index-from-delius/deploy/values-dev.yml +++ b/projects/person-search-index-from-delius/deploy/values-dev.yml @@ -4,6 +4,7 @@ generic-service: scheduledDowntime: enabled: true + startup: 0 8 * * 1-5 # delayed startup to match Delius DB startup time env: SENTRY_ENVIRONMENT: dev From 6405a62ab0ebc8a1f6319300511fa400c063d3f8 Mon Sep 17 00:00:00 2001 From: Marcus Aspin Date: Thu, 14 Nov 2024 14:04:55 +0000 Subject: [PATCH 06/26] PI-2543 Update UPW reminder schedule while testing (#4428) --- .../appointment-reminders-and-delius/deploy/values-prod.yml | 2 +- .../digital/hmpps/service/UnpaidWorkAppointmentsService.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/appointment-reminders-and-delius/deploy/values-prod.yml b/projects/appointment-reminders-and-delius/deploy/values-prod.yml index 60c56efbf9..3b5628ba8d 100644 --- a/projects/appointment-reminders-and-delius/deploy/values-prod.yml +++ b/projects/appointment-reminders-and-delius/deploy/values-prod.yml @@ -11,4 +11,4 @@ generic-service: jobs: unpaid-work-appointment-reminders: dry-run: true - schedule: '0 18 * * *' # 6:00pm UTC every day \ No newline at end of file + schedule: '30 18 * * *' # 6:30pm UTC every day \ No newline at end of file diff --git a/projects/appointment-reminders-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/UnpaidWorkAppointmentsService.kt b/projects/appointment-reminders-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/UnpaidWorkAppointmentsService.kt index 2b08245809..71481ec84c 100644 --- a/projects/appointment-reminders-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/UnpaidWorkAppointmentsService.kt +++ b/projects/appointment-reminders-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/UnpaidWorkAppointmentsService.kt @@ -15,7 +15,7 @@ class UnpaidWorkAppointmentsService( @Value("\${govuk-notify.templates.upw-appointment-reminder}") private val templateId: String, ) { fun sendUnpaidWorkAppointmentReminders(providerCode: String, dryRun: Boolean = false) { - upwAppointmentRepository.getUnpaidWorkAppointments(LocalDate.now().plusDays(2), providerCode) + upwAppointmentRepository.getUnpaidWorkAppointments(LocalDate.now().plusDays(3), providerCode) .forEach { notificationClient.sendSms( templateId, From 8439efe7c4eee809c9dea36eef5bf65d9ff3505d Mon Sep 17 00:00:00 2001 From: Matthew Ryall Date: Fri, 15 Nov 2024 09:19:01 +0000 Subject: [PATCH 07/26] PI-2634: Document 'Appointment Reminders and Delius' service (#4429) --- .../README.md | 36 +- .../diag/east-of-england-upw-reminders.d2 | 79 ++ .../img/east-of-england-upw-reminders.svg | 888 ++++++++++++++++++ 3 files changed, 1001 insertions(+), 2 deletions(-) create mode 100644 projects/appointment-reminders-and-delius/tech-docs/diag/east-of-england-upw-reminders.d2 create mode 100644 projects/appointment-reminders-and-delius/tech-docs/source/img/east-of-england-upw-reminders.svg diff --git a/projects/appointment-reminders-and-delius/README.md b/projects/appointment-reminders-and-delius/README.md index 4515740f75..a4550237e2 100644 --- a/projects/appointment-reminders-and-delius/README.md +++ b/projects/appointment-reminders-and-delius/README.md @@ -1,3 +1,35 @@ -# appointment-reminders-and-delius +# Appointment Reminders and Delius -// TODO Describe the service \ No newline at end of file +## Business Need + +- Sending appointment reminders to people on probation to help improve compliance with supervision activities +- Providing a method of automating the sending of SMS messages via GOV.UK Notify +- Standardising the process of sending SMS appointment reminders across regions + +## Workflows + +### Sending SMS Reminders Based on Delius Data + +The service will send appointment reminders to people on probation by combining the data in _Delius_ and the [GOV.UK Notify](https://www.notifications.service.gov.uk/) service. Data is gathered from Delius, validated and templated SMS messages are sent using the GOV.UK Notify API. + +![Workflow Map](./tech-docs/source/img/east-of-england-upw-reminders.svg) + +### Downloading CSV Data + +A CSV file of the appointment reminders that the service will send on a particular day can be accessed via an API endpoint + +## Interfaces + +### Scheduled Job + +- SMS messages are send via a scheduled job +- Telemetry is send to Application Insights for each SMS message sent + +### API Access Control + +API endpoints are secured by roles supplied by the HMPPS Auth client used in +the requests + +| API Endpoint | Required Role | +|-----------------------|--------------------------------------------------| +| /upw-appointments.csv | PROBATION\_API\_\_REMINDERS\_\_UPW\_APPOINTMENTS | diff --git a/projects/appointment-reminders-and-delius/tech-docs/diag/east-of-england-upw-reminders.d2 b/projects/appointment-reminders-and-delius/tech-docs/diag/east-of-england-upw-reminders.d2 new file mode 100644 index 0000000000..eae41899e9 --- /dev/null +++ b/projects/appointment-reminders-and-delius/tech-docs/diag/east-of-england-upw-reminders.d2 @@ -0,0 +1,79 @@ +# Appointment SMS Flow + +direction: down + +style { ...@../../../../script/style.style } +vars { ...@../../../../script/style.vars } +** { ...@../../../../script/style.all-style } + +data: Delius Data { + "" { + explanation: |md + Name, mobile number and appointment date + | + } +} + +deduplicate: Deduplication { + "" { + explanation: |md + Where there are multiple appointments for a mobile number\ + only send a single reminder + | + } +} + +validate: Validation { + validate_person: Person Validation { + explanation: |md + - The person is not in custody or on remand + - The person is not unlawfully at large + - The person is not Limited Access + | + } + + validate_comms: Communication Validation { + explanation: |md + - The mobile number is formatted correctly + - The person has not opted out of SMS contacts + | + } + + validate_activity: Activity Validation { + explanation: |md + - The person has an active unpaid work requirement + - The unpaid work requirement is not related to\ + Education, Training and Employment + - There is time remaining on the unpaid work requirement + - The appointment does not have an outcome + | + } +} + +ok: Validation OK +fail: Validation Fail + +send: Send SMS { + notify: GOV.UK Notify { + explanation: |md + Send SMS appointment reminder to person on probation + | + } +} + +end1: End { + shape: circle +} + +end2: End { + shape: circle +} + +data -> validate +validate -> ok: OK +validate -> fail: Fail + +ok -> deduplicate +deduplicate -> send +send -> end1 +fail -> end2 diff --git a/projects/appointment-reminders-and-delius/tech-docs/source/img/east-of-england-upw-reminders.svg b/projects/appointment-reminders-and-delius/tech-docs/source/img/east-of-england-upw-reminders.svg new file mode 100644 index 0000000000..77b7928bf6 --- /dev/null +++ b/projects/appointment-reminders-and-delius/tech-docs/source/img/east-of-england-upw-reminders.svg @@ -0,0 +1,888 @@ +Delius DataDeduplicationValidationValidation OKValidation FailSend SMSEndEndPerson ValidationCommunication ValidationActivity ValidationGOV.UK Notify

Name, mobile number and appointment date

+

Where there are multiple appointments for a mobile number
+only send a single reminder

+
    +
  • The person is not in custody or on remand
  • +
  • The person is not unlawfully at large
  • +
  • The person is not Limited Access
  • +
+
    +
  • The mobile number is formatted correctly
  • +
  • The person has not opted out of SMS contacts
  • +
+
    +
  • The person has an active unpaid work requirement
  • +
  • The unpaid work requirement is not related to
    +Education, Training and Employment
  • +
  • There is time remaining on the unpaid work requirement
  • +
  • The appointment does not have an outcome
  • +
+

Send SMS appointment reminder to person on probation

+
OKFail + + + + + + + + + + + + + + + + + + + + + +
From 2052628ce5c6070810ebfa1763e86d5aaf5b6f61 Mon Sep 17 00:00:00 2001 From: gregkhawkins <148795810+gregkhawkins@users.noreply.github.com> Date: Fri, 15 Nov 2024 10:35:32 +0000 Subject: [PATCH 08/26] APS-1482 - link offences data to probation cases (#4430) APS-1482 - add offences data to probation cases --- .../hmpps/data/ProbationCaseDataLoader.kt | 42 ++++++++++++------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/projects/approved-premises-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/ProbationCaseDataLoader.kt b/projects/approved-premises-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/ProbationCaseDataLoader.kt index 56deb3a926..2194d12f44 100644 --- a/projects/approved-premises-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/ProbationCaseDataLoader.kt +++ b/projects/approved-premises-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/ProbationCaseDataLoader.kt @@ -14,6 +14,7 @@ import uk.gov.justice.digital.hmpps.entity.LimitedAccessPerson import uk.gov.justice.digital.hmpps.entity.Restriction import uk.gov.justice.digital.hmpps.integrations.delius.approvedpremises.referral.entity.EventRepository import uk.gov.justice.digital.hmpps.integrations.delius.person.Ldu +import uk.gov.justice.digital.hmpps.integrations.delius.person.ProbationCase import uk.gov.justice.digital.hmpps.integrations.delius.person.ProbationCaseRepository import uk.gov.justice.digital.hmpps.integrations.delius.person.manager.probation.PersonManagerRepository import uk.gov.justice.digital.hmpps.integrations.delius.person.offence.entity.AdditionalOffence @@ -100,9 +101,34 @@ class ProbationCaseDataLoader( ) ) + listOf( + ProbationCaseGenerator.CASE_COMPLEX, + ProbationCaseGenerator.CASE_X320741, + ProbationCaseGenerator.CASE_LAO_RESTRICTED, + ProbationCaseGenerator.CASE_LAO_EXCLUSION, + ).forEach { + generateEventAndAddOffences(probationCase = it) + } + + personalCircumstanceTypeRepository.saveAll(PersonalCircumstanceGenerator.PC_TYPES) + personalCircumstanceSubTypeRepository.saveAll(PersonalCircumstanceGenerator.PC_SUB_TYPES) + personalCircumstanceRepository.save( + PersonalCircumstanceGenerator.generate( + ProbationCaseGenerator.CASE_COMPLEX.id, + PersonalCircumstanceGenerator.PC_TYPES.first { it.code == PersonalCircumstanceType.Code.VETERAN.value }, + PersonalCircumstanceGenerator.PC_SUB_TYPES.first { it.description == PersonalCircumstanceType.Code.VETERAN.value + "SUB" } + )) + + mutableLimitedAccessPersonRepository.save(RESTRICTED_CASE) + mutableLimitedAccessPersonRepository.save(EXCLUDED_CASE) + restrictionRepository.save(LimitedAccessGenerator.generateRestriction(RESTRICTED_CASE.toLimitedAccessPerson())) + exclusionRepository.save(LimitedAccessGenerator.generateExclusion(EXCLUDED_CASE.toLimitedAccessPerson())) + } + + private fun generateEventAndAddOffences(probationCase: ProbationCase) { val event = PersonGenerator.generateEvent( "1", - ProbationCaseGenerator.CASE_COMPLEX.id + probationCase.id ).apply(eventRepository::save) mainOffenceRepository.save( @@ -120,20 +146,6 @@ class ProbationCaseDataLoader( LocalDate.now().minusDays(5) ) ) - - personalCircumstanceTypeRepository.saveAll(PersonalCircumstanceGenerator.PC_TYPES) - personalCircumstanceSubTypeRepository.saveAll(PersonalCircumstanceGenerator.PC_SUB_TYPES) - personalCircumstanceRepository.save( - PersonalCircumstanceGenerator.generate( - ProbationCaseGenerator.CASE_COMPLEX.id, - PersonalCircumstanceGenerator.PC_TYPES.first { it.code == PersonalCircumstanceType.Code.VETERAN.value }, - PersonalCircumstanceGenerator.PC_SUB_TYPES.first { it.description == PersonalCircumstanceType.Code.VETERAN.value + "SUB" } - )) - - mutableLimitedAccessPersonRepository.save(RESTRICTED_CASE) - mutableLimitedAccessPersonRepository.save(EXCLUDED_CASE) - restrictionRepository.save(LimitedAccessGenerator.generateRestriction(RESTRICTED_CASE.toLimitedAccessPerson())) - exclusionRepository.save(LimitedAccessGenerator.generateExclusion(EXCLUDED_CASE.toLimitedAccessPerson())) } } From 62c52ee722f5a5d230486a4c39c52119ab74eef7 Mon Sep 17 00:00:00 2001 From: Marcus Aspin Date: Fri, 15 Nov 2024 15:46:53 +0000 Subject: [PATCH 09/26] PI-2635 Switch to Gradle for IntelliJ run configurations (#4431) --- .../render-project-template/action.yml | 2 +- .../accredited_programmes_and_oasys.run.xml | 29 +++++++++++++++ .../accredited_programmes_and_oasys.xml | 12 ------- .../appointment_reminders_and_delius.run.xml | 29 +++++++++++++++ .../appointment_reminders_and_delius.xml | 12 ------- .../approved_premises_and_delius.run.xml | 29 +++++++++++++++ .../approved_premises_and_delius.xml | 12 ------- .../approved_premises_and_oasys.run.xml | 29 +++++++++++++++ .../approved_premises_and_oasys.xml | 12 ------- .../runConfigurations/arns_and_delius.run.xml | 29 +++++++++++++++ .idea/runConfigurations/arns_and_delius.xml | 12 ------- .../assessment_summary_and_delius.run.xml | 29 +++++++++++++++ .../assessment_summary_and_delius.xml | 12 ------- .../runConfigurations/cas2_and_delius.run.xml | 29 +++++++++++++++ .idea/runConfigurations/cas2_and_delius.xml | 12 ------- .../runConfigurations/cas3_and_delius.run.xml | 29 +++++++++++++++ .idea/runConfigurations/cas3_and_delius.xml | 12 ------- .../common_platform_and_delius.run.xml | 29 +++++++++++++++ .../common_platform_and_delius.xml | 12 ------- .../core_person_record_and_delius.run.xml | 29 +++++++++++++++ .../core_person_record_and_delius.xml | 12 ------- .../court_case_and_delius.run.xml | 29 +++++++++++++++ .../court_case_and_delius.xml | 12 ------- ...eate_and_vary_a_licence_and_delius.run.xml | 29 +++++++++++++++ .../create_and_vary_a_licence_and_delius.xml | 12 ------- .../custody_key_dates_and_delius.run.xml | 29 +++++++++++++++ .../custody_key_dates_and_delius.xml | 12 ------- .../domain_events_and_delius.run.xml | 29 +++++++++++++++ .../domain_events_and_delius.xml | 12 ------- .../runConfigurations/dps_and_delius.run.xml | 29 +++++++++++++++ .idea/runConfigurations/dps_and_delius.xml | 12 ------- ...tive_proposal_framework_and_delius.run.xml | 29 +++++++++++++++ ...ffective_proposal_framework_and_delius.xml | 12 ------- .../external_api_and_delius.run.xml | 29 +++++++++++++++ .../external_api_and_delius.xml | 12 ------- .../hdc_licences_and_delius.run.xml | 29 +++++++++++++++ .../hdc_licences_and_delius.xml | 12 ------- .../hmpps_auth_and_delius.run.xml | 29 +++++++++++++++ .../hmpps_auth_and_delius.xml | 12 ------- .../runConfigurations/ims_and_delius.run.xml | 29 +++++++++++++++ .idea/runConfigurations/ims_and_delius.xml | 12 ------- .../justice_email_and_delius.run.xml | 29 +++++++++++++++ .../justice_email_and_delius.xml | 12 ------- .../make_recall_decisions_and_delius.run.xml | 29 +++++++++++++++ .../make_recall_decisions_and_delius.xml | 12 ------- .../manage_offences_and_delius.run.xml | 29 +++++++++++++++ .../manage_offences_and_delius.xml | 12 ------- .../manage_pom_cases_and_delius.run.xml | 29 +++++++++++++++ .../manage_pom_cases_and_delius.xml | 12 ------- .../manage_supervision_and_delius.run.xml | 29 +++++++++++++++ .../manage_supervision_and_delius.xml | 12 ------- .../manage_supervision_and_oasys.run.xml | 29 +++++++++++++++ .../manage_supervision_and_oasys.xml | 12 ------- .../oasys_and_delius.run.xml | 29 +++++++++++++++ .idea/runConfigurations/oasys_and_delius.xml | 12 ------- .../offender_events_and_delius.run.xml | 29 +++++++++++++++ .../offender_events_and_delius.xml | 27 -------------- .../runConfigurations/opd_and_delius.run.xml | 29 +++++++++++++++ .idea/runConfigurations/opd_and_delius.xml | 12 ------- .../pathfinder_and_delius.run.xml | 29 +++++++++++++++ .../pathfinder_and_delius.xml | 12 ------- .../pre_sentence_reports_to_delius.run.xml | 29 +++++++++++++++ .../pre_sentence_reports_to_delius.xml | 11 ------ .../prison_case_notes_to_probation.run.xml | 29 +++++++++++++++ .../prison_case_notes_to_probation.xml | 26 -------------- .../prison_custody_status_to_delius.run.xml | 29 +++++++++++++++ .../prison_custody_status_to_delius.xml | 12 ------- .../prison_education_and_delius.run.xml | 29 +++++++++++++++ .../prison_education_and_delius.xml | 12 ------- .../prison_identifier_and_delius.run.xml | 29 +++++++++++++++ .../prison_identifier_and_delius.xml | 12 ------- .../prisoner_profile_and_delius.run.xml | 29 +++++++++++++++ .../prisoner_profile_and_delius.xml | 12 ------- .../probation_search_and_delius.run.xml | 29 +++++++++++++++ .../probation_search_and_delius.xml | 12 ------- .../refer_and_monitor_and_delius.run.xml | 29 +++++++++++++++ .../refer_and_monitor_and_delius.xml | 12 ------- .../resettlement_passport_and_delius.run.xml | 29 +++++++++++++++ .../resettlement_passport_and_delius.xml | 12 ------- .../risk_assessment_scores_to_delius.run.xml | 29 +++++++++++++++ .../risk_assessment_scores_to_delius.xml | 12 ------- .../sentence_plan_and_delius.run.xml | 29 +++++++++++++++ .../sentence_plan_and_delius.xml | 12 ------- .../sentence_plan_and_oasys.run.xml | 29 +++++++++++++++ .../sentence_plan_and_oasys.xml | 12 ------- .../runConfigurations/soc_and_delius.run.xml | 29 +++++++++++++++ .idea/runConfigurations/soc_and_delius.xml | 12 ------- ...subject_access_requests_and_delius.run.xml | 29 +++++++++++++++ .../subject_access_requests_and_delius.xml | 12 ------- .../runConfigurations/tier_to_delius.run.xml | 29 +++++++++++++++ .idea/runConfigurations/tier_to_delius.xml | 15 -------- .../unpaid_work_and_delius.run.xml | 29 +++++++++++++++ .../unpaid_work_and_delius.xml | 12 ------- .../workforce_allocations_to_delius.run.xml | 29 +++++++++++++++ .../workforce_allocations_to_delius.xml | 26 -------------- templates/runConfiguration.xml | 35 ++++++++++++++----- 96 files changed, 1390 insertions(+), 619 deletions(-) create mode 100644 .idea/runConfigurations/accredited_programmes_and_oasys.run.xml delete mode 100644 .idea/runConfigurations/accredited_programmes_and_oasys.xml create mode 100644 .idea/runConfigurations/appointment_reminders_and_delius.run.xml delete mode 100644 .idea/runConfigurations/appointment_reminders_and_delius.xml create mode 100644 .idea/runConfigurations/approved_premises_and_delius.run.xml delete mode 100644 .idea/runConfigurations/approved_premises_and_delius.xml create mode 100644 .idea/runConfigurations/approved_premises_and_oasys.run.xml delete mode 100644 .idea/runConfigurations/approved_premises_and_oasys.xml create mode 100644 .idea/runConfigurations/arns_and_delius.run.xml delete mode 100644 .idea/runConfigurations/arns_and_delius.xml create mode 100644 .idea/runConfigurations/assessment_summary_and_delius.run.xml delete mode 100644 .idea/runConfigurations/assessment_summary_and_delius.xml create mode 100644 .idea/runConfigurations/cas2_and_delius.run.xml delete mode 100644 .idea/runConfigurations/cas2_and_delius.xml create mode 100644 .idea/runConfigurations/cas3_and_delius.run.xml delete mode 100644 .idea/runConfigurations/cas3_and_delius.xml create mode 100644 .idea/runConfigurations/common_platform_and_delius.run.xml delete mode 100644 .idea/runConfigurations/common_platform_and_delius.xml create mode 100644 .idea/runConfigurations/core_person_record_and_delius.run.xml delete mode 100644 .idea/runConfigurations/core_person_record_and_delius.xml create mode 100644 .idea/runConfigurations/court_case_and_delius.run.xml delete mode 100644 .idea/runConfigurations/court_case_and_delius.xml create mode 100644 .idea/runConfigurations/create_and_vary_a_licence_and_delius.run.xml delete mode 100644 .idea/runConfigurations/create_and_vary_a_licence_and_delius.xml create mode 100644 .idea/runConfigurations/custody_key_dates_and_delius.run.xml delete mode 100644 .idea/runConfigurations/custody_key_dates_and_delius.xml create mode 100644 .idea/runConfigurations/domain_events_and_delius.run.xml delete mode 100644 .idea/runConfigurations/domain_events_and_delius.xml create mode 100644 .idea/runConfigurations/dps_and_delius.run.xml delete mode 100644 .idea/runConfigurations/dps_and_delius.xml create mode 100644 .idea/runConfigurations/effective_proposal_framework_and_delius.run.xml delete mode 100644 .idea/runConfigurations/effective_proposal_framework_and_delius.xml create mode 100644 .idea/runConfigurations/external_api_and_delius.run.xml delete mode 100644 .idea/runConfigurations/external_api_and_delius.xml create mode 100644 .idea/runConfigurations/hdc_licences_and_delius.run.xml delete mode 100644 .idea/runConfigurations/hdc_licences_and_delius.xml create mode 100644 .idea/runConfigurations/hmpps_auth_and_delius.run.xml delete mode 100644 .idea/runConfigurations/hmpps_auth_and_delius.xml create mode 100644 .idea/runConfigurations/ims_and_delius.run.xml delete mode 100644 .idea/runConfigurations/ims_and_delius.xml create mode 100644 .idea/runConfigurations/justice_email_and_delius.run.xml delete mode 100644 .idea/runConfigurations/justice_email_and_delius.xml create mode 100644 .idea/runConfigurations/make_recall_decisions_and_delius.run.xml delete mode 100644 .idea/runConfigurations/make_recall_decisions_and_delius.xml create mode 100644 .idea/runConfigurations/manage_offences_and_delius.run.xml delete mode 100644 .idea/runConfigurations/manage_offences_and_delius.xml create mode 100644 .idea/runConfigurations/manage_pom_cases_and_delius.run.xml delete mode 100644 .idea/runConfigurations/manage_pom_cases_and_delius.xml create mode 100644 .idea/runConfigurations/manage_supervision_and_delius.run.xml delete mode 100644 .idea/runConfigurations/manage_supervision_and_delius.xml create mode 100644 .idea/runConfigurations/manage_supervision_and_oasys.run.xml delete mode 100644 .idea/runConfigurations/manage_supervision_and_oasys.xml create mode 100644 .idea/runConfigurations/oasys_and_delius.run.xml delete mode 100644 .idea/runConfigurations/oasys_and_delius.xml create mode 100644 .idea/runConfigurations/offender_events_and_delius.run.xml delete mode 100644 .idea/runConfigurations/offender_events_and_delius.xml create mode 100644 .idea/runConfigurations/opd_and_delius.run.xml delete mode 100644 .idea/runConfigurations/opd_and_delius.xml create mode 100644 .idea/runConfigurations/pathfinder_and_delius.run.xml delete mode 100644 .idea/runConfigurations/pathfinder_and_delius.xml create mode 100644 .idea/runConfigurations/pre_sentence_reports_to_delius.run.xml delete mode 100644 .idea/runConfigurations/pre_sentence_reports_to_delius.xml create mode 100644 .idea/runConfigurations/prison_case_notes_to_probation.run.xml delete mode 100644 .idea/runConfigurations/prison_case_notes_to_probation.xml create mode 100644 .idea/runConfigurations/prison_custody_status_to_delius.run.xml delete mode 100644 .idea/runConfigurations/prison_custody_status_to_delius.xml create mode 100644 .idea/runConfigurations/prison_education_and_delius.run.xml delete mode 100644 .idea/runConfigurations/prison_education_and_delius.xml create mode 100644 .idea/runConfigurations/prison_identifier_and_delius.run.xml delete mode 100644 .idea/runConfigurations/prison_identifier_and_delius.xml create mode 100644 .idea/runConfigurations/prisoner_profile_and_delius.run.xml delete mode 100644 .idea/runConfigurations/prisoner_profile_and_delius.xml create mode 100644 .idea/runConfigurations/probation_search_and_delius.run.xml delete mode 100644 .idea/runConfigurations/probation_search_and_delius.xml create mode 100644 .idea/runConfigurations/refer_and_monitor_and_delius.run.xml delete mode 100644 .idea/runConfigurations/refer_and_monitor_and_delius.xml create mode 100644 .idea/runConfigurations/resettlement_passport_and_delius.run.xml delete mode 100644 .idea/runConfigurations/resettlement_passport_and_delius.xml create mode 100644 .idea/runConfigurations/risk_assessment_scores_to_delius.run.xml delete mode 100644 .idea/runConfigurations/risk_assessment_scores_to_delius.xml create mode 100644 .idea/runConfigurations/sentence_plan_and_delius.run.xml delete mode 100644 .idea/runConfigurations/sentence_plan_and_delius.xml create mode 100644 .idea/runConfigurations/sentence_plan_and_oasys.run.xml delete mode 100644 .idea/runConfigurations/sentence_plan_and_oasys.xml create mode 100644 .idea/runConfigurations/soc_and_delius.run.xml delete mode 100644 .idea/runConfigurations/soc_and_delius.xml create mode 100644 .idea/runConfigurations/subject_access_requests_and_delius.run.xml delete mode 100644 .idea/runConfigurations/subject_access_requests_and_delius.xml create mode 100644 .idea/runConfigurations/tier_to_delius.run.xml delete mode 100644 .idea/runConfigurations/tier_to_delius.xml create mode 100644 .idea/runConfigurations/unpaid_work_and_delius.run.xml delete mode 100644 .idea/runConfigurations/unpaid_work_and_delius.xml create mode 100644 .idea/runConfigurations/workforce_allocations_to_delius.run.xml delete mode 100644 .idea/runConfigurations/workforce_allocations_to_delius.xml diff --git a/.github/actions/render-project-template/action.yml b/.github/actions/render-project-template/action.yml index 7e1a48fa06..3ee45fa262 100644 --- a/.github/actions/render-project-template/action.yml +++ b/.github/actions/render-project-template/action.yml @@ -33,7 +33,7 @@ runs: sed -i '/add new projects here/i \ - '"'"'["${{ inputs.project_name }}"]'"'"'' .github/workflows/service-catalogue.yml sed -i '/add new projects here/i \ - ${{ inputs.project_name }}' .github/workflows/build.yml sed -i '/add new projects here/i \* [${{ steps.project_name.outputs.title_case }}](https://ministryofjustice.github.io/hmpps-probation-integration-services/tech-docs/projects/${{ inputs.project_name }})' doc/tech-docs/source/services.html.md.erb - sed 's/$SERVICE_NAME/${{ inputs.project_name }}/g' templates/runConfiguration.xml > '.idea/runConfigurations/${{ steps.project_name.outputs.underscore }}.xml' + sed 's/$SERVICE_NAME/${{ inputs.project_name }}/g' templates/runConfiguration.xml > '.idea/runConfigurations/${{ inputs.project_name }}.run.xml' - name: Render queue-specific files if: startsWith(inputs.project_template, 'message-listener') diff --git a/.idea/runConfigurations/accredited_programmes_and_oasys.run.xml b/.idea/runConfigurations/accredited_programmes_and_oasys.run.xml new file mode 100644 index 0000000000..bf7bbc1897 --- /dev/null +++ b/.idea/runConfigurations/accredited_programmes_and_oasys.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/accredited_programmes_and_oasys.xml b/.idea/runConfigurations/accredited_programmes_and_oasys.xml deleted file mode 100644 index c9a87cb328..0000000000 --- a/.idea/runConfigurations/accredited_programmes_and_oasys.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/appointment_reminders_and_delius.run.xml b/.idea/runConfigurations/appointment_reminders_and_delius.run.xml new file mode 100644 index 0000000000..e2cfe07e16 --- /dev/null +++ b/.idea/runConfigurations/appointment_reminders_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/appointment_reminders_and_delius.xml b/.idea/runConfigurations/appointment_reminders_and_delius.xml deleted file mode 100644 index ee51450f75..0000000000 --- a/.idea/runConfigurations/appointment_reminders_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/approved_premises_and_delius.run.xml b/.idea/runConfigurations/approved_premises_and_delius.run.xml new file mode 100644 index 0000000000..a87527aa98 --- /dev/null +++ b/.idea/runConfigurations/approved_premises_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/approved_premises_and_delius.xml b/.idea/runConfigurations/approved_premises_and_delius.xml deleted file mode 100644 index fae215c088..0000000000 --- a/.idea/runConfigurations/approved_premises_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/approved_premises_and_oasys.run.xml b/.idea/runConfigurations/approved_premises_and_oasys.run.xml new file mode 100644 index 0000000000..e3b0fe3af6 --- /dev/null +++ b/.idea/runConfigurations/approved_premises_and_oasys.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/approved_premises_and_oasys.xml b/.idea/runConfigurations/approved_premises_and_oasys.xml deleted file mode 100644 index 91a8e91aef..0000000000 --- a/.idea/runConfigurations/approved_premises_and_oasys.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/arns_and_delius.run.xml b/.idea/runConfigurations/arns_and_delius.run.xml new file mode 100644 index 0000000000..a579830fe2 --- /dev/null +++ b/.idea/runConfigurations/arns_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/arns_and_delius.xml b/.idea/runConfigurations/arns_and_delius.xml deleted file mode 100644 index 3d0ceb87c3..0000000000 --- a/.idea/runConfigurations/arns_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/assessment_summary_and_delius.run.xml b/.idea/runConfigurations/assessment_summary_and_delius.run.xml new file mode 100644 index 0000000000..810393bf40 --- /dev/null +++ b/.idea/runConfigurations/assessment_summary_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/assessment_summary_and_delius.xml b/.idea/runConfigurations/assessment_summary_and_delius.xml deleted file mode 100644 index b53e740649..0000000000 --- a/.idea/runConfigurations/assessment_summary_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/cas2_and_delius.run.xml b/.idea/runConfigurations/cas2_and_delius.run.xml new file mode 100644 index 0000000000..e1c9faec50 --- /dev/null +++ b/.idea/runConfigurations/cas2_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/cas2_and_delius.xml b/.idea/runConfigurations/cas2_and_delius.xml deleted file mode 100644 index 375b91d251..0000000000 --- a/.idea/runConfigurations/cas2_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/cas3_and_delius.run.xml b/.idea/runConfigurations/cas3_and_delius.run.xml new file mode 100644 index 0000000000..6d4e5dabb6 --- /dev/null +++ b/.idea/runConfigurations/cas3_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/cas3_and_delius.xml b/.idea/runConfigurations/cas3_and_delius.xml deleted file mode 100644 index baafdc0076..0000000000 --- a/.idea/runConfigurations/cas3_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/common_platform_and_delius.run.xml b/.idea/runConfigurations/common_platform_and_delius.run.xml new file mode 100644 index 0000000000..4274fea1ee --- /dev/null +++ b/.idea/runConfigurations/common_platform_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/common_platform_and_delius.xml b/.idea/runConfigurations/common_platform_and_delius.xml deleted file mode 100644 index 6e921d526d..0000000000 --- a/.idea/runConfigurations/common_platform_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/core_person_record_and_delius.run.xml b/.idea/runConfigurations/core_person_record_and_delius.run.xml new file mode 100644 index 0000000000..3ddceaed5c --- /dev/null +++ b/.idea/runConfigurations/core_person_record_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/core_person_record_and_delius.xml b/.idea/runConfigurations/core_person_record_and_delius.xml deleted file mode 100644 index 01246708d0..0000000000 --- a/.idea/runConfigurations/core_person_record_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/court_case_and_delius.run.xml b/.idea/runConfigurations/court_case_and_delius.run.xml new file mode 100644 index 0000000000..e2e705ea25 --- /dev/null +++ b/.idea/runConfigurations/court_case_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/court_case_and_delius.xml b/.idea/runConfigurations/court_case_and_delius.xml deleted file mode 100644 index 1dcf3a960b..0000000000 --- a/.idea/runConfigurations/court_case_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/create_and_vary_a_licence_and_delius.run.xml b/.idea/runConfigurations/create_and_vary_a_licence_and_delius.run.xml new file mode 100644 index 0000000000..27ac3418f9 --- /dev/null +++ b/.idea/runConfigurations/create_and_vary_a_licence_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/create_and_vary_a_licence_and_delius.xml b/.idea/runConfigurations/create_and_vary_a_licence_and_delius.xml deleted file mode 100644 index 50a13ae459..0000000000 --- a/.idea/runConfigurations/create_and_vary_a_licence_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/custody_key_dates_and_delius.run.xml b/.idea/runConfigurations/custody_key_dates_and_delius.run.xml new file mode 100644 index 0000000000..302d699cce --- /dev/null +++ b/.idea/runConfigurations/custody_key_dates_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/custody_key_dates_and_delius.xml b/.idea/runConfigurations/custody_key_dates_and_delius.xml deleted file mode 100644 index af9cc084c5..0000000000 --- a/.idea/runConfigurations/custody_key_dates_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/domain_events_and_delius.run.xml b/.idea/runConfigurations/domain_events_and_delius.run.xml new file mode 100644 index 0000000000..8a6ea5dd09 --- /dev/null +++ b/.idea/runConfigurations/domain_events_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/domain_events_and_delius.xml b/.idea/runConfigurations/domain_events_and_delius.xml deleted file mode 100644 index ac99a2e69c..0000000000 --- a/.idea/runConfigurations/domain_events_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/dps_and_delius.run.xml b/.idea/runConfigurations/dps_and_delius.run.xml new file mode 100644 index 0000000000..a28166adf1 --- /dev/null +++ b/.idea/runConfigurations/dps_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/dps_and_delius.xml b/.idea/runConfigurations/dps_and_delius.xml deleted file mode 100644 index b78127db75..0000000000 --- a/.idea/runConfigurations/dps_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/effective_proposal_framework_and_delius.run.xml b/.idea/runConfigurations/effective_proposal_framework_and_delius.run.xml new file mode 100644 index 0000000000..67d920489c --- /dev/null +++ b/.idea/runConfigurations/effective_proposal_framework_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/effective_proposal_framework_and_delius.xml b/.idea/runConfigurations/effective_proposal_framework_and_delius.xml deleted file mode 100644 index 110a3e8f2e..0000000000 --- a/.idea/runConfigurations/effective_proposal_framework_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/external_api_and_delius.run.xml b/.idea/runConfigurations/external_api_and_delius.run.xml new file mode 100644 index 0000000000..0262a01409 --- /dev/null +++ b/.idea/runConfigurations/external_api_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/external_api_and_delius.xml b/.idea/runConfigurations/external_api_and_delius.xml deleted file mode 100644 index ce953a4bbf..0000000000 --- a/.idea/runConfigurations/external_api_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/hdc_licences_and_delius.run.xml b/.idea/runConfigurations/hdc_licences_and_delius.run.xml new file mode 100644 index 0000000000..781e2dfec1 --- /dev/null +++ b/.idea/runConfigurations/hdc_licences_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/hdc_licences_and_delius.xml b/.idea/runConfigurations/hdc_licences_and_delius.xml deleted file mode 100644 index 04e46d0a6d..0000000000 --- a/.idea/runConfigurations/hdc_licences_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/hmpps_auth_and_delius.run.xml b/.idea/runConfigurations/hmpps_auth_and_delius.run.xml new file mode 100644 index 0000000000..150b08fc88 --- /dev/null +++ b/.idea/runConfigurations/hmpps_auth_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/hmpps_auth_and_delius.xml b/.idea/runConfigurations/hmpps_auth_and_delius.xml deleted file mode 100644 index dc8faa965d..0000000000 --- a/.idea/runConfigurations/hmpps_auth_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/ims_and_delius.run.xml b/.idea/runConfigurations/ims_and_delius.run.xml new file mode 100644 index 0000000000..88c0fdb739 --- /dev/null +++ b/.idea/runConfigurations/ims_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/ims_and_delius.xml b/.idea/runConfigurations/ims_and_delius.xml deleted file mode 100644 index 0e247d4d43..0000000000 --- a/.idea/runConfigurations/ims_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/justice_email_and_delius.run.xml b/.idea/runConfigurations/justice_email_and_delius.run.xml new file mode 100644 index 0000000000..c8608046b1 --- /dev/null +++ b/.idea/runConfigurations/justice_email_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/justice_email_and_delius.xml b/.idea/runConfigurations/justice_email_and_delius.xml deleted file mode 100644 index 7d547a24f7..0000000000 --- a/.idea/runConfigurations/justice_email_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/make_recall_decisions_and_delius.run.xml b/.idea/runConfigurations/make_recall_decisions_and_delius.run.xml new file mode 100644 index 0000000000..3206d17862 --- /dev/null +++ b/.idea/runConfigurations/make_recall_decisions_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/make_recall_decisions_and_delius.xml b/.idea/runConfigurations/make_recall_decisions_and_delius.xml deleted file mode 100644 index 25239cbce5..0000000000 --- a/.idea/runConfigurations/make_recall_decisions_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/manage_offences_and_delius.run.xml b/.idea/runConfigurations/manage_offences_and_delius.run.xml new file mode 100644 index 0000000000..f1a72cee3f --- /dev/null +++ b/.idea/runConfigurations/manage_offences_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/manage_offences_and_delius.xml b/.idea/runConfigurations/manage_offences_and_delius.xml deleted file mode 100644 index 1264ce0186..0000000000 --- a/.idea/runConfigurations/manage_offences_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/manage_pom_cases_and_delius.run.xml b/.idea/runConfigurations/manage_pom_cases_and_delius.run.xml new file mode 100644 index 0000000000..c935693fc3 --- /dev/null +++ b/.idea/runConfigurations/manage_pom_cases_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/manage_pom_cases_and_delius.xml b/.idea/runConfigurations/manage_pom_cases_and_delius.xml deleted file mode 100644 index a4c33a9371..0000000000 --- a/.idea/runConfigurations/manage_pom_cases_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/manage_supervision_and_delius.run.xml b/.idea/runConfigurations/manage_supervision_and_delius.run.xml new file mode 100644 index 0000000000..a7c2d1a87f --- /dev/null +++ b/.idea/runConfigurations/manage_supervision_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/manage_supervision_and_delius.xml b/.idea/runConfigurations/manage_supervision_and_delius.xml deleted file mode 100644 index 4432a13836..0000000000 --- a/.idea/runConfigurations/manage_supervision_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/manage_supervision_and_oasys.run.xml b/.idea/runConfigurations/manage_supervision_and_oasys.run.xml new file mode 100644 index 0000000000..7381628cde --- /dev/null +++ b/.idea/runConfigurations/manage_supervision_and_oasys.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/manage_supervision_and_oasys.xml b/.idea/runConfigurations/manage_supervision_and_oasys.xml deleted file mode 100644 index 9f3f6a83fb..0000000000 --- a/.idea/runConfigurations/manage_supervision_and_oasys.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/oasys_and_delius.run.xml b/.idea/runConfigurations/oasys_and_delius.run.xml new file mode 100644 index 0000000000..ad218f51ec --- /dev/null +++ b/.idea/runConfigurations/oasys_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/oasys_and_delius.xml b/.idea/runConfigurations/oasys_and_delius.xml deleted file mode 100644 index 650b0cf744..0000000000 --- a/.idea/runConfigurations/oasys_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/offender_events_and_delius.run.xml b/.idea/runConfigurations/offender_events_and_delius.run.xml new file mode 100644 index 0000000000..2cdefe3240 --- /dev/null +++ b/.idea/runConfigurations/offender_events_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/offender_events_and_delius.xml b/.idea/runConfigurations/offender_events_and_delius.xml deleted file mode 100644 index 04f4ac1e37..0000000000 --- a/.idea/runConfigurations/offender_events_and_delius.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/opd_and_delius.run.xml b/.idea/runConfigurations/opd_and_delius.run.xml new file mode 100644 index 0000000000..d639900072 --- /dev/null +++ b/.idea/runConfigurations/opd_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/opd_and_delius.xml b/.idea/runConfigurations/opd_and_delius.xml deleted file mode 100644 index 18bd3e7bd0..0000000000 --- a/.idea/runConfigurations/opd_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/pathfinder_and_delius.run.xml b/.idea/runConfigurations/pathfinder_and_delius.run.xml new file mode 100644 index 0000000000..258ed1a5da --- /dev/null +++ b/.idea/runConfigurations/pathfinder_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/pathfinder_and_delius.xml b/.idea/runConfigurations/pathfinder_and_delius.xml deleted file mode 100644 index 7f8983bf72..0000000000 --- a/.idea/runConfigurations/pathfinder_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/pre_sentence_reports_to_delius.run.xml b/.idea/runConfigurations/pre_sentence_reports_to_delius.run.xml new file mode 100644 index 0000000000..6baba08dd5 --- /dev/null +++ b/.idea/runConfigurations/pre_sentence_reports_to_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/pre_sentence_reports_to_delius.xml b/.idea/runConfigurations/pre_sentence_reports_to_delius.xml deleted file mode 100644 index b5cdaeacfb..0000000000 --- a/.idea/runConfigurations/pre_sentence_reports_to_delius.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/prison_case_notes_to_probation.run.xml b/.idea/runConfigurations/prison_case_notes_to_probation.run.xml new file mode 100644 index 0000000000..64d2461698 --- /dev/null +++ b/.idea/runConfigurations/prison_case_notes_to_probation.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/prison_case_notes_to_probation.xml b/.idea/runConfigurations/prison_case_notes_to_probation.xml deleted file mode 100644 index f20d4dcb53..0000000000 --- a/.idea/runConfigurations/prison_case_notes_to_probation.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/prison_custody_status_to_delius.run.xml b/.idea/runConfigurations/prison_custody_status_to_delius.run.xml new file mode 100644 index 0000000000..c2ccf609ee --- /dev/null +++ b/.idea/runConfigurations/prison_custody_status_to_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/prison_custody_status_to_delius.xml b/.idea/runConfigurations/prison_custody_status_to_delius.xml deleted file mode 100644 index 279835144a..0000000000 --- a/.idea/runConfigurations/prison_custody_status_to_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/prison_education_and_delius.run.xml b/.idea/runConfigurations/prison_education_and_delius.run.xml new file mode 100644 index 0000000000..98f006e1cd --- /dev/null +++ b/.idea/runConfigurations/prison_education_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/prison_education_and_delius.xml b/.idea/runConfigurations/prison_education_and_delius.xml deleted file mode 100644 index fed7f3ee02..0000000000 --- a/.idea/runConfigurations/prison_education_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/prison_identifier_and_delius.run.xml b/.idea/runConfigurations/prison_identifier_and_delius.run.xml new file mode 100644 index 0000000000..14bf2279a0 --- /dev/null +++ b/.idea/runConfigurations/prison_identifier_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/prison_identifier_and_delius.xml b/.idea/runConfigurations/prison_identifier_and_delius.xml deleted file mode 100644 index e9a1d4a47c..0000000000 --- a/.idea/runConfigurations/prison_identifier_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - diff --git a/.idea/runConfigurations/prisoner_profile_and_delius.run.xml b/.idea/runConfigurations/prisoner_profile_and_delius.run.xml new file mode 100644 index 0000000000..64e4dd5721 --- /dev/null +++ b/.idea/runConfigurations/prisoner_profile_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/prisoner_profile_and_delius.xml b/.idea/runConfigurations/prisoner_profile_and_delius.xml deleted file mode 100644 index 89dbef33ac..0000000000 --- a/.idea/runConfigurations/prisoner_profile_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/probation_search_and_delius.run.xml b/.idea/runConfigurations/probation_search_and_delius.run.xml new file mode 100644 index 0000000000..cec87429f9 --- /dev/null +++ b/.idea/runConfigurations/probation_search_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/probation_search_and_delius.xml b/.idea/runConfigurations/probation_search_and_delius.xml deleted file mode 100644 index 40c7012df7..0000000000 --- a/.idea/runConfigurations/probation_search_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/refer_and_monitor_and_delius.run.xml b/.idea/runConfigurations/refer_and_monitor_and_delius.run.xml new file mode 100644 index 0000000000..92b961f7aa --- /dev/null +++ b/.idea/runConfigurations/refer_and_monitor_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/refer_and_monitor_and_delius.xml b/.idea/runConfigurations/refer_and_monitor_and_delius.xml deleted file mode 100644 index 772e36dba9..0000000000 --- a/.idea/runConfigurations/refer_and_monitor_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/resettlement_passport_and_delius.run.xml b/.idea/runConfigurations/resettlement_passport_and_delius.run.xml new file mode 100644 index 0000000000..5b5ea06437 --- /dev/null +++ b/.idea/runConfigurations/resettlement_passport_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/resettlement_passport_and_delius.xml b/.idea/runConfigurations/resettlement_passport_and_delius.xml deleted file mode 100644 index 8d17d90b84..0000000000 --- a/.idea/runConfigurations/resettlement_passport_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/risk_assessment_scores_to_delius.run.xml b/.idea/runConfigurations/risk_assessment_scores_to_delius.run.xml new file mode 100644 index 0000000000..58728c3325 --- /dev/null +++ b/.idea/runConfigurations/risk_assessment_scores_to_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/risk_assessment_scores_to_delius.xml b/.idea/runConfigurations/risk_assessment_scores_to_delius.xml deleted file mode 100644 index 0b42735976..0000000000 --- a/.idea/runConfigurations/risk_assessment_scores_to_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/sentence_plan_and_delius.run.xml b/.idea/runConfigurations/sentence_plan_and_delius.run.xml new file mode 100644 index 0000000000..48d60bb7ad --- /dev/null +++ b/.idea/runConfigurations/sentence_plan_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/sentence_plan_and_delius.xml b/.idea/runConfigurations/sentence_plan_and_delius.xml deleted file mode 100644 index c1629b5f9b..0000000000 --- a/.idea/runConfigurations/sentence_plan_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/sentence_plan_and_oasys.run.xml b/.idea/runConfigurations/sentence_plan_and_oasys.run.xml new file mode 100644 index 0000000000..c7e58f08d5 --- /dev/null +++ b/.idea/runConfigurations/sentence_plan_and_oasys.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/sentence_plan_and_oasys.xml b/.idea/runConfigurations/sentence_plan_and_oasys.xml deleted file mode 100644 index e38500dd25..0000000000 --- a/.idea/runConfigurations/sentence_plan_and_oasys.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/soc_and_delius.run.xml b/.idea/runConfigurations/soc_and_delius.run.xml new file mode 100644 index 0000000000..b6d911b0a1 --- /dev/null +++ b/.idea/runConfigurations/soc_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/soc_and_delius.xml b/.idea/runConfigurations/soc_and_delius.xml deleted file mode 100644 index 0a7556eb6e..0000000000 --- a/.idea/runConfigurations/soc_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/subject_access_requests_and_delius.run.xml b/.idea/runConfigurations/subject_access_requests_and_delius.run.xml new file mode 100644 index 0000000000..1136ecbc65 --- /dev/null +++ b/.idea/runConfigurations/subject_access_requests_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/subject_access_requests_and_delius.xml b/.idea/runConfigurations/subject_access_requests_and_delius.xml deleted file mode 100644 index 5f2829d727..0000000000 --- a/.idea/runConfigurations/subject_access_requests_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/tier_to_delius.run.xml b/.idea/runConfigurations/tier_to_delius.run.xml new file mode 100644 index 0000000000..d9b97282d3 --- /dev/null +++ b/.idea/runConfigurations/tier_to_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/tier_to_delius.xml b/.idea/runConfigurations/tier_to_delius.xml deleted file mode 100644 index 0a1157475d..0000000000 --- a/.idea/runConfigurations/tier_to_delius.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/unpaid_work_and_delius.run.xml b/.idea/runConfigurations/unpaid_work_and_delius.run.xml new file mode 100644 index 0000000000..20fbe345a8 --- /dev/null +++ b/.idea/runConfigurations/unpaid_work_and_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/unpaid_work_and_delius.xml b/.idea/runConfigurations/unpaid_work_and_delius.xml deleted file mode 100644 index 16b361cf2e..0000000000 --- a/.idea/runConfigurations/unpaid_work_and_delius.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/workforce_allocations_to_delius.run.xml b/.idea/runConfigurations/workforce_allocations_to_delius.run.xml new file mode 100644 index 0000000000..b627aac06c --- /dev/null +++ b/.idea/runConfigurations/workforce_allocations_to_delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/workforce_allocations_to_delius.xml b/.idea/runConfigurations/workforce_allocations_to_delius.xml deleted file mode 100644 index 8b01a2480e..0000000000 --- a/.idea/runConfigurations/workforce_allocations_to_delius.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - \ No newline at end of file diff --git a/templates/runConfiguration.xml b/templates/runConfiguration.xml index 7ac101736d..75a9d1e251 100644 --- a/templates/runConfiguration.xml +++ b/templates/runConfiguration.xml @@ -1,12 +1,29 @@ - - \ No newline at end of file From 9dc811e9c4907d41f3d1cf97d6a7ae165011303a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 16:10:39 +0000 Subject: [PATCH 10/26] Bump logstash from 8.15.3 to 8.16.0 in /projects/person-search-index-from-delius/container (#4435) Bump logstash in /projects/person-search-index-from-delius/container Bumps logstash from 8.15.3 to 8.16.0. --- updated-dependencies: - dependency-name: logstash dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- projects/person-search-index-from-delius/container/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/person-search-index-from-delius/container/Dockerfile b/projects/person-search-index-from-delius/container/Dockerfile index 8656be0be3..cd0003c72f 100644 --- a/projects/person-search-index-from-delius/container/Dockerfile +++ b/projects/person-search-index-from-delius/container/Dockerfile @@ -4,7 +4,7 @@ COPY --chown=yq /pipelines /pipelines RUN find /pipelines -type f -name "*.yml" -exec sh -c 'for f; do yq -o=json "$f" > "${f%.yml}.json"; done' sh {} + -FROM logstash:8.15.3 +FROM logstash:8.16.0 USER root SHELL ["/bin/bash", "-o", "pipefail", "-c"] From 3e0f123c0003b3e28045dcc06e222056914c9c72 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 16:12:05 +0000 Subject: [PATCH 11/26] Bump mikepenz/action-junit-report from 5.0.0.pre.rc01 to 5 in /.github/actions/analyse (#4434) Bump mikepenz/action-junit-report in /.github/actions/analyse Bumps [mikepenz/action-junit-report](https://github.com/mikepenz/action-junit-report) from 5.0.0.pre.rc01 to 5. - [Release notes](https://github.com/mikepenz/action-junit-report/releases) - [Commits](https://github.com/mikepenz/action-junit-report/compare/ec3a351c13e080dc4fa94c49ab7ad5bf778a9668...a427a90771729d8f85b6ab0cdaa1a5929cab985d) --- updated-dependencies: - dependency-name: mikepenz/action-junit-report dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/analyse/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/analyse/action.yml b/.github/actions/analyse/action.yml index 0681d2f29c..a6ab05950a 100644 --- a/.github/actions/analyse/action.yml +++ b/.github/actions/analyse/action.yml @@ -26,7 +26,7 @@ runs: shell: bash - name: Publish test reports - uses: mikepenz/action-junit-report@ec3a351c13e080dc4fa94c49ab7ad5bf778a9668 # v5 + uses: mikepenz/action-junit-report@a427a90771729d8f85b6ab0cdaa1a5929cab985d # v5 if: always() && github.actor != 'dependabot[bot]' with: check_name: |- From 38dfa7a80aab15540f06edad8646f9f8d6da3b55 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 16:15:29 +0000 Subject: [PATCH 12/26] Bump the minor group with 6 updates (#4437) Bumps the minor group with 6 updates: | Package | From | To | | --- | --- | --- | | software.amazon.awssdk:aws-query-protocol | `2.29.9` | `2.29.15` | | software.amazon.awssdk:sts | `2.29.9` | `2.29.15` | | [com.azure:azure-identity](https://github.com/Azure/azure-sdk-for-java) | `1.14.1` | `1.14.2` | | [io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations](https://github.com/open-telemetry/opentelemetry-java-instrumentation) | `2.9.0` | `2.10.0` | | [io.sentry:sentry-spring-boot-starter-jakarta](https://github.com/getsentry/sentry-java) | `7.16.0` | `7.18.0` | | com.gradle.develocity | `3.18.1` | `3.18.2` | Updates `software.amazon.awssdk:aws-query-protocol` from 2.29.9 to 2.29.15 Updates `software.amazon.awssdk:sts` from 2.29.9 to 2.29.15 Updates `com.azure:azure-identity` from 1.14.1 to 1.14.2 - [Release notes](https://github.com/Azure/azure-sdk-for-java/releases) - [Commits](https://github.com/Azure/azure-sdk-for-java/compare/azure-core_1.14.1...azure-identity_1.14.2) Updates `io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations` from 2.9.0 to 2.10.0 - [Release notes](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-java-instrumentation/compare/v2.9.0...v2.10.0) Updates `io.sentry:sentry-spring-boot-starter-jakarta` from 7.16.0 to 7.18.0 - [Release notes](https://github.com/getsentry/sentry-java/releases) - [Changelog](https://github.com/getsentry/sentry-java/blob/main/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-java/compare/7.16.0...7.18.0) Updates `com.gradle.develocity` from 3.18.1 to 3.18.2 --- updated-dependencies: - dependency-name: software.amazon.awssdk:aws-query-protocol dependency-type: direct:production update-type: version-update:semver-patch dependency-group: minor - dependency-name: software.amazon.awssdk:sts dependency-type: direct:production update-type: version-update:semver-patch dependency-group: minor - dependency-name: com.azure:azure-identity dependency-type: direct:production update-type: version-update:semver-patch dependency-group: minor - dependency-name: io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations dependency-type: direct:production update-type: version-update:semver-minor dependency-group: minor - dependency-name: io.sentry:sentry-spring-boot-starter-jakarta dependency-type: direct:production update-type: version-update:semver-minor dependency-group: minor - dependency-name: com.gradle.develocity dependency-type: direct:production update-type: version-update:semver-patch dependency-group: minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- settings.gradle.kts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index d9f10df384..e897a719f8 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -73,13 +73,13 @@ dependencyResolutionManagement { create("libs") { library("asyncapi", "org.openfolder:kotlin-asyncapi-spring-web:3.0.3") library("aws-autoconfigure", "io.awspring.cloud:spring-cloud-aws-autoconfigure:3.2.1") - library("aws-query-protocol", "software.amazon.awssdk:aws-query-protocol:2.29.9") + library("aws-query-protocol", "software.amazon.awssdk:aws-query-protocol:2.29.15") library("aws-sns", "io.awspring.cloud:spring-cloud-aws-starter-sns:3.2.1") library("aws-sqs", "io.awspring.cloud:spring-cloud-aws-starter-sqs:3.2.1") library("aws-starter", "io.awspring.cloud:spring-cloud-aws-starter:3.2.1") - library("aws-sts", "software.amazon.awssdk:sts:2.29.9") + library("aws-sts", "software.amazon.awssdk:sts:2.29.15") library("azure-app-insights", "com.microsoft.azure:applicationinsights-web:3.6.2") - library("azure-identity", "com.azure:azure-identity:1.14.1") + library("azure-identity", "com.azure:azure-identity:1.14.2") library("flipt", "io.flipt:flipt-java:1.1.1") library("html2md", "com.vladsch.flexmark:flexmark-html2md-converter:0.64.8") library("microsoft-graph", "com.microsoft.graph:microsoft-graph:6.20.0") @@ -88,9 +88,9 @@ dependencyResolutionManagement { library("notify", "uk.gov.service.notify:notifications-java-client:5.2.1-RELEASE") library( "opentelemetry-annotations", - "io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations:2.9.0" + "io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations:2.10.0" ) - library("sentry", "io.sentry:sentry-spring-boot-starter-jakarta:7.16.0") + library("sentry", "io.sentry:sentry-spring-boot-starter-jakarta:7.18.0") library("springdoc", "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0") library("wiremock", "org.wiremock:wiremock-standalone:3.9.2") @@ -104,7 +104,7 @@ dependencyResolutionManagement { } } -plugins { id("com.gradle.develocity") version "3.18.1" } +plugins { id("com.gradle.develocity") version "3.18.2" } develocity { buildScan { publishing.onlyIf { !System.getenv("CI").isNullOrEmpty() } From 6bb9647e9698c8ed2527f0978ad4197b7f273cba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 16:29:44 +0000 Subject: [PATCH 13/26] Bump aws-cli/aws-cli from 2.19.4 to 2.21.3 in /projects/redrive-dead-letter-queues/container (#4438) Bump aws-cli/aws-cli in /projects/redrive-dead-letter-queues/container Bumps aws-cli/aws-cli from 2.19.4 to 2.21.3. --- updated-dependencies: - dependency-name: aws-cli/aws-cli dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- projects/redrive-dead-letter-queues/container/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/redrive-dead-letter-queues/container/Dockerfile b/projects/redrive-dead-letter-queues/container/Dockerfile index 7317d83aae..bd7bb774f4 100644 --- a/projects/redrive-dead-letter-queues/container/Dockerfile +++ b/projects/redrive-dead-letter-queues/container/Dockerfile @@ -1,4 +1,4 @@ -FROM public.ecr.aws/aws-cli/aws-cli:2.19.4 +FROM public.ecr.aws/aws-cli/aws-cli:2.21.3 USER root SHELL ["/bin/bash", "-o", "pipefail", "-c"] From 39338c5929e8db7e2328b4ae331f1da666727aac Mon Sep 17 00:00:00 2001 From: Marcus Aspin Date: Tue, 19 Nov 2024 09:33:05 +0000 Subject: [PATCH 14/26] PI-2639 Handle "DEIRC" movement reason code (#4440) --- .../gov/justice/digital/hmpps/messaging/MovementReasonCodes.kt | 1 + .../uk/gov/justice/digital/hmpps/messaging/PrisonerMovement.kt | 1 + .../src/main/resources/application-prisoner-movement.yml | 1 + 3 files changed, 3 insertions(+) diff --git a/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/MovementReasonCodes.kt b/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/MovementReasonCodes.kt index 4f9acc99b9..d0b456e0c2 100644 --- a/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/MovementReasonCodes.kt +++ b/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/MovementReasonCodes.kt @@ -4,6 +4,7 @@ object MovementReasonCodes { const val DISCHARGED_OR_DEPORTED = "DD" const val DEPORTED_NO_SENTENCE = "DE" const val DEPORTED_LICENCE = "DL" + const val DEPORTED_IRC = "DEIRC" const val EARLY_REMOVAL_SCHEME = "ETR" const val END_CUSTODY_TO_IMMIGRATION_RELEASE_CENTRE = "ECSLIRC" const val DETAINED_MENTAL_HEALTH = "HO" diff --git a/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/PrisonerMovement.kt b/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/PrisonerMovement.kt index 208bef6bfc..1c2a684e8a 100644 --- a/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/PrisonerMovement.kt +++ b/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/PrisonerMovement.kt @@ -55,6 +55,7 @@ sealed interface PrisonerMovement { MovementReasonCodes.DISCHARGED_OR_DEPORTED, MovementReasonCodes.DEPORTED_NO_SENTENCE, MovementReasonCodes.DEPORTED_LICENCE, + MovementReasonCodes.DEPORTED_IRC, MovementReasonCodes.EARLY_REMOVAL_SCHEME, MovementReasonCodes.END_CUSTODY_TO_IMMIGRATION_RELEASE_CENTRE ) diff --git a/projects/prison-custody-status-to-delius/src/main/resources/application-prisoner-movement.yml b/projects/prison-custody-status-to-delius/src/main/resources/application-prisoner-movement.yml index 7229999120..4006e56e9e 100644 --- a/projects/prison-custody-status-to-delius/src/main/resources/application-prisoner-movement.yml +++ b/projects/prison-custody-status-to-delius/src/main/resources/application-prisoner-movement.yml @@ -33,6 +33,7 @@ prisoner.movement.configs: - DD - DE - DL + - DEIRC - ECSLIRC # Early removal scheme - ETR From fae75d275ae1d2c9643bb1b51c1aec755f322c76 Mon Sep 17 00:00:00 2001 From: achimber-moj <161360519+achimber-moj@users.noreply.github.com> Date: Tue, 19 Nov 2024 09:45:14 +0000 Subject: [PATCH 15/26] MAN-108 manage appointments record an outcome (#4433) * MAN-156 - add new api * MAN-156 - add integration test * MAN-156 - update integration test * MAN-156 - add test data * MAN-156 - update api and test * MAN-156 - update api and test * Formatting changes * MAN-156 - update test * Formatting changes * MAN-156 - update test * MAN-156 - add new attribute --------- Co-authored-by: probation-integration-bot[bot] <177347787+probation-integration-bot[bot]@users.noreply.github.com> --- .../justice/digital/hmpps/data/DataLoader.kt | 2 + .../data/generator/AppointmentGenerator.kt | 21 +++ .../hmpps/data/generator/ContactGenerator.kt | 2 +- .../AppointmentOutcomeIntegrationTest.kt | 140 ++++++++++++++++++ .../CreateAppointmentIntegrationTests.kt | 17 +-- .../api/controller/AppointmentController.kt | 15 +- .../hmpps/api/model/appointment/Outcome.kt | 11 ++ .../delius/sentence/entity/Appointment.kt | 52 +++++++ .../service/AppointmentOutcomeService.kt | 32 ++++ .../service/SentenceAppointmentService.kt | 1 - 10 files changed, 279 insertions(+), 14 deletions(-) create mode 100644 projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt create mode 100644 projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/appointment/Outcome.kt create mode 100644 projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt 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 596ae52c9f..7da807bc5b 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 @@ -34,7 +34,9 @@ class DataLoader( entityManager.persist(BusinessInteraction(IdGenerator.getAndIncrement(), it.code, ZonedDateTime.now())) } entityManager.persistAll( + AppointmentGenerator.ATTENDED_COMPLIED, *AppointmentGenerator.APPOINTMENT_TYPES.toTypedArray(), + *AppointmentGenerator.CONTACT_TYPE_OUTCOMES.toTypedArray(), ContactGenerator.DEFAULT_PROVIDER, ContactGenerator.DEFAULT_BOROUGH, ContactGenerator.DEFAULT_DISTRICT, diff --git a/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/AppointmentGenerator.kt b/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/AppointmentGenerator.kt index 95d9d0839c..b77f10a1ce 100644 --- a/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/AppointmentGenerator.kt +++ b/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/AppointmentGenerator.kt @@ -1,7 +1,11 @@ package uk.gov.justice.digital.hmpps.data.generator import uk.gov.justice.digital.hmpps.api.model.appointment.CreateAppointment +import uk.gov.justice.digital.hmpps.data.generator.ContactGenerator.generateOutcome +import uk.gov.justice.digital.hmpps.integrations.delius.overview.entity.ContactOutcome import uk.gov.justice.digital.hmpps.integrations.delius.overview.entity.ContactType +import uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity.ContactTypeOutcome +import uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity.ContactTypeOutcomeId object AppointmentGenerator { @@ -13,4 +17,21 @@ object AppointmentGenerator { attendanceType: Boolean, id: Long = IdGenerator.getAndIncrement() ) = ContactType(IdGenerator.getAndIncrement(), code, true, description) + + val ATTENDED_COMPLIED = generateOutcome("ATTC", "Attended - Complied", true, true) + + val CONTACT_TYPE_OUTCOMES = APPOINTMENT_TYPES.map { + generateContactTypeOutcome(it.id, ATTENDED_COMPLIED.id, it, ATTENDED_COMPLIED) + } + + fun generateContactTypeOutcome( + contactTypeId: Long, + contactOutcomeTypeId: Long, + contactType: ContactType, + outcome: ContactOutcome + ) = ContactTypeOutcome( + ContactTypeOutcomeId(contactTypeId, contactOutcomeTypeId), + contactType, + outcome + ) } 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 8bf5b72db3..44bc3978a9 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 @@ -179,7 +179,7 @@ object ContactGenerator { outcome = outcome ) - private fun generateOutcome(code: String, description: String, attendance: Boolean, acceptable: Boolean) = + fun generateOutcome(code: String, description: String, attendance: Boolean, acceptable: Boolean) = ContactOutcome(IdGenerator.getAndIncrement(), code, description, attendance, acceptable) private fun generateContactType( diff --git a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt new file mode 100644 index 0000000000..42aa7a3291 --- /dev/null +++ b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt @@ -0,0 +1,140 @@ +package uk.gov.justice.digital.hmpps + +import org.hamcrest.MatcherAssert.assertThat +import org.hamcrest.Matchers.equalTo +import org.junit.jupiter.api.Assertions.* +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.request.MockMvcRequestBuilders.post +import org.springframework.test.web.servlet.result.MockMvcResultMatchers +import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath +import uk.gov.justice.digital.hmpps.api.model.appointment.AppointmentDetail +import uk.gov.justice.digital.hmpps.api.model.appointment.CreateAppointment +import uk.gov.justice.digital.hmpps.api.model.appointment.Outcome +import uk.gov.justice.digital.hmpps.api.model.appointment.User +import uk.gov.justice.digital.hmpps.data.generator.AppointmentGenerator.ATTENDED_COMPLIED +import uk.gov.justice.digital.hmpps.data.generator.OffenderManagerGenerator.STAFF_USER_1 +import uk.gov.justice.digital.hmpps.data.generator.OffenderManagerGenerator.TEAM +import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator +import uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity.AppointmentRepository +import uk.gov.justice.digital.hmpps.test.CustomMatchers.isCloseTo +import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.contentAsJson +import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withJson +import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withToken +import java.time.ZonedDateTime +import java.util.* + +@AutoConfigureMockMvc +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +class AppointmentOutcomeIntegrationTest { + + @Autowired + internal lateinit var appointmentRepository: AppointmentRepository + + @Autowired + internal lateinit var mockMvc: MockMvc + + val outcome = Outcome(123, "ATTC", "N") + + @Test + fun `unauthorized status returned`() { + mockMvc + .perform( + MockMvcRequestBuilders.patch("/appointment") + .withJson(outcome) + ) + .andExpect(MockMvcResultMatchers.status().isUnauthorized) + } + + @Test + fun `when an appointment does not exist returns a 404 response`() { + mockMvc + .perform( + MockMvcRequestBuilders.patch("/appointment") + .withToken() + .withJson(outcome) + ) + .andExpect(MockMvcResultMatchers.status().isNotFound) + .andExpect(jsonPath("$.message", equalTo("Appointment with id of 123 not found"))) + } + + @Test + fun `when an appointment outcome does not exist returns a 404 response`() { + val response = createAppointment() + + mockMvc + .perform( + MockMvcRequestBuilders.patch("/appointment") + .withToken() + .withJson(Outcome(response.appointments[0].id, "ABC", "Y")) + ) + .andExpect(MockMvcResultMatchers.status().isNotFound) + .andExpect( + jsonPath( + "$.message", + equalTo("ContactTypeOutcome with contact_type_id 8 and outcome code of ABC not found") + ) + ) + + appointmentRepository.deleteById(response.appointments[0].id) + } + + @Test + fun `outcome updated`() { + val response = createAppointment() + val createdAppointment = appointmentRepository.findById(response.appointments[0].id).get() + + assertNull(createdAppointment.attended) + assertNull(createdAppointment.notes) + assertNull(createdAppointment.outcomeId) + assertNull(createdAppointment.sensitive) + + val request = Outcome(response.appointments[0].id, "ATTC", "Y", notes = "my notes") + + mockMvc + .perform( + MockMvcRequestBuilders.patch("/appointment") + .withToken() + .withJson(request) + ) + .andExpect(MockMvcResultMatchers.status().isOk) + + val updatedAppointment = appointmentRepository.findById(response.appointments[0].id).get() + + assertEquals("Y", updatedAppointment.attended) + assertEquals(request.notes, updatedAppointment.notes) + assertEquals(ATTENDED_COMPLIED.id, updatedAppointment.outcomeId) + assertFalse(updatedAppointment.sensitive!!) + + assertThat(updatedAppointment.type.code, equalTo(createdAppointment.type.code)) + assertThat(updatedAppointment.date, equalTo(createdAppointment.date)) + assertThat(updatedAppointment.startTime, isCloseTo(createdAppointment.startTime)) + assertThat(updatedAppointment.externalReference, equalTo(createdAppointment.externalReference)) + assertThat(updatedAppointment.eventId, equalTo(createdAppointment.eventId)) + assertThat(updatedAppointment.createdByUserId, equalTo(createdAppointment.createdByUserId)) + assertThat(updatedAppointment.staffId, equalTo(createdAppointment.staffId)) + assertThat(updatedAppointment.probationAreaId, equalTo(createdAppointment.probationAreaId)) + assertThat(updatedAppointment.officeLocationId, equalTo(createdAppointment.officeLocationId)) + + appointmentRepository.delete(updatedAppointment) + } + + private fun createAppointment() = mockMvc.perform( + post("/appointment/${PersonGenerator.PERSON_1.crn}") + .withToken() + .withJson( + CreateAppointment( + User(STAFF_USER_1.username, TEAM.description), + CreateAppointment.Type.PlannedOfficeVisitNS, + ZonedDateTime.now().plusDays(1), + ZonedDateTime.now().plusDays(2), + eventId = PersonGenerator.EVENT_1.id, + uuid = UUID.randomUUID() + ) + ) + ).andReturn().response.contentAsJson() +} \ No newline at end of file diff --git a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/CreateAppointmentIntegrationTests.kt b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/CreateAppointmentIntegrationTests.kt index c7ec4eb563..d6943c367f 100644 --- a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/CreateAppointmentIntegrationTests.kt +++ b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/CreateAppointmentIntegrationTests.kt @@ -10,7 +10,6 @@ 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.request.MockMvcRequestBuilders.post import org.springframework.test.web.servlet.result.MockMvcResultHandlers.print import org.springframework.test.web.servlet.result.MockMvcResultMatchers @@ -48,14 +47,14 @@ class CreateAppointmentIntegrationTests { @Test fun `unauthorized status returned`() { mockMvc - .perform(MockMvcRequestBuilders.get("/appointments/D123456")) + .perform(post("/appointment/D123456")) .andExpect(MockMvcResultMatchers.status().isUnauthorized) } @Test - fun `when offender does not exist retuns a 404 response`() { + fun `when offender does not exist returns a 404 response`() { mockMvc.perform( - post("/appointments/D123456") + post("/appointment/D123456") .withToken() .withJson( CreateAppointment( @@ -75,7 +74,7 @@ class CreateAppointmentIntegrationTests { @Test fun `appointment end date before start returns bad request`() { mockMvc.perform( - post("/appointments/${PersonGenerator.PERSON_1.crn}") + post("/appointment/${PersonGenerator.PERSON_1.crn}") .withToken() .withJson( CreateAppointment( @@ -95,12 +94,12 @@ class CreateAppointmentIntegrationTests { } @ParameterizedTest - @MethodSource("createAppointments") + @MethodSource("createAppointment") fun `create a new appointment`(createAppointment: CreateAppointment) { val person = PersonGenerator.PERSON_1 val response = mockMvc.perform( - post("/appointments/${person.crn}") + post("/appointment/${person.crn}") .withToken() .withJson(createAppointment) ) @@ -128,7 +127,7 @@ class CreateAppointmentIntegrationTests { fun `create multiple appointments`(createAppointment: CreateAppointment) { val person = PersonGenerator.PERSON_1 val response = mockMvc.perform( - post("/appointments/${person.crn}") + post("/appointment/${person.crn}") .withToken() .withJson(createAppointment) ) @@ -163,7 +162,7 @@ class CreateAppointmentIntegrationTests { private val user = User(STAFF_USER_1.username, TEAM.description) @JvmStatic - fun createAppointments() = listOf( + fun createAppointment() = listOf( CreateAppointment( user, CreateAppointment.Type.PlannedOfficeVisitNS, diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/AppointmentController.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/AppointmentController.kt index 85c6066904..07e0a118d5 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/AppointmentController.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/AppointmentController.kt @@ -5,16 +5,25 @@ import org.springframework.http.HttpStatus import org.springframework.security.access.prepost.PreAuthorize import org.springframework.web.bind.annotation.* import uk.gov.justice.digital.hmpps.api.model.appointment.CreateAppointment +import uk.gov.justice.digital.hmpps.api.model.appointment.Outcome +import uk.gov.justice.digital.hmpps.service.AppointmentOutcomeService import uk.gov.justice.digital.hmpps.service.SentenceAppointmentService @RestController @Tag(name = "Sentence") -@RequestMapping("/appointments/{crn}") +@RequestMapping("/appointment") @PreAuthorize("hasRole('PROBATION_API__MANAGE_A_SUPERVISION__CASE_DETAIL')") -class AppointmentController(private val appointmentService: SentenceAppointmentService) { +class AppointmentController( + private val appointmentService: SentenceAppointmentService, + private val appointmentOutcomeService: AppointmentOutcomeService +) { - @PostMapping + @PostMapping("/{crn}") @ResponseStatus(HttpStatus.CREATED) fun createAppointment(@PathVariable crn: String, @RequestBody createAppointment: CreateAppointment) = appointmentService.createAppointment(crn, createAppointment) + + @PatchMapping + @ResponseStatus(HttpStatus.OK) + fun recordOutcome(@RequestBody outcome: Outcome) = appointmentOutcomeService.recordOutcome(outcome) } \ No newline at end of file diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/appointment/Outcome.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/appointment/Outcome.kt new file mode 100644 index 0000000000..e410208248 --- /dev/null +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/appointment/Outcome.kt @@ -0,0 +1,11 @@ +package uk.gov.justice.digital.hmpps.api.model.appointment + +data class Outcome( + val id: Long, + val code: String, + val attended: String, + val sensitive: Boolean? = false, + val notes: String? = null, +) + + diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt index fe6b0b557d..7d9bb9eac3 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt @@ -2,6 +2,7 @@ package uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity import jakarta.persistence.* import org.hibernate.annotations.SQLRestriction +import org.hibernate.type.YesNoConverter import org.springframework.data.annotation.CreatedDate import org.springframework.data.annotation.LastModifiedBy import org.springframework.data.annotation.LastModifiedDate @@ -9,8 +10,10 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener import org.springframework.data.jpa.repository.JpaRepository import org.springframework.data.jpa.repository.Query import uk.gov.justice.digital.hmpps.exception.NotFoundException +import uk.gov.justice.digital.hmpps.integrations.delius.overview.entity.ContactOutcome import uk.gov.justice.digital.hmpps.integrations.delius.overview.entity.ContactType import uk.gov.justice.digital.hmpps.integrations.delius.overview.entity.Person +import java.io.Serializable import java.time.LocalDate import java.time.ZoneId import java.time.ZonedDateTime @@ -77,6 +80,19 @@ class Appointment( @Column(name = "office_location_id") val officeLocationId: Long? = null, + @Column(name = "attended", columnDefinition = "char(1)") + var attended: String? = null, + + @Column(name = "contact_outcome_type_id") + var outcomeId: Long? = null, + + @Lob + var notes: String? = null, + + @Column(name = "sensitive") + @Convert(converter = YesNoConverter::class) + var sensitive: Boolean? = null, + @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "contact_id_generator") @Column(name = "contact_id") @@ -133,3 +149,39 @@ interface AppointmentTypeRepository : JpaRepository { fun AppointmentTypeRepository.getByCode(code: String) = findByCode(code) ?: throw NotFoundException("AppointmentType", "code", code) + +@Entity +@Table(name = "r_contact_type_outcome") +class ContactTypeOutcome( + + @EmbeddedId + val id: ContactTypeOutcomeId, + + @ManyToOne + @JoinColumn(name = "contact_type_id", insertable = false, updatable = false) + val type: ContactType, + + @ManyToOne + @JoinColumn(name = "contact_outcome_type_id", insertable = false, updatable = false) + val outcome: ContactOutcome, +) + +interface ContactTypeOutcomeRepository : JpaRepository { + fun findByIdContactTypeIdAndOutcomeCode(contactTypeId: Long, code: String): ContactTypeOutcome? +} + +fun ContactTypeOutcomeRepository.getByTypeIdAndOutcomeCode(contactTypeId: Long, code: String) = + findByIdContactTypeIdAndOutcomeCode( + contactTypeId, code + ) ?: throw NotFoundException("ContactTypeOutcome", "contact_type_id $contactTypeId and outcome code", code) + +@Embeddable +class ContactTypeOutcomeId( + @Column(name = "contact_type_id") + val contactTypeId: Long, + + @Column(name = "contact_outcome_type_id") + val contactOutcomeTypeId: Long, + + ) : Serializable + diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt new file mode 100644 index 0000000000..589ed18335 --- /dev/null +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt @@ -0,0 +1,32 @@ +package uk.gov.justice.digital.hmpps.service + +import org.springframework.stereotype.Service +import uk.gov.justice.digital.hmpps.api.model.appointment.Outcome +import uk.gov.justice.digital.hmpps.exception.NotFoundException +import uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity.AppointmentRepository +import uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity.ContactTypeOutcomeRepository +import uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity.getByTypeIdAndOutcomeCode + +@Service +class AppointmentOutcomeService( + private val appointmentRepository: AppointmentRepository, + private val contactTypeOutcomeRepository: ContactTypeOutcomeRepository +) { + + fun recordOutcome(outcome: Outcome) { + val appointment = appointmentRepository.findById(outcome.id) + .orElseThrow { throw NotFoundException("Appointment", "id", outcome.id) } + + val contactTypeOutcome = + contactTypeOutcomeRepository.getByTypeIdAndOutcomeCode(appointment.type.id, outcome.code) + + appointment.apply { + attended = outcome.attended + notes = outcome.notes + outcomeId = contactTypeOutcome.outcome.id + sensitive = outcome.sensitive + } + + appointmentRepository.save(appointment) + } +} \ No newline at end of file diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/SentenceAppointmentService.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/SentenceAppointmentService.kt index 6f0e8db58f..043c8b13cf 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/SentenceAppointmentService.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/SentenceAppointmentService.kt @@ -17,7 +17,6 @@ import java.time.Duration import java.time.LocalDate import java.time.ZonedDateTime import java.util.* -import kotlin.math.ceil @Service class SentenceAppointmentService( From e0dc35c325678fc5699cf55f93569b88c03a61aa Mon Sep 17 00:00:00 2001 From: Marcus Aspin Date: Tue, 19 Nov 2024 12:24:16 +0000 Subject: [PATCH 16/26] PI-2641 Add users endpoint for SAR service (#4441) Also remove some `andDo(print())` lines from various tests --- ...onvictionByCrnAndEventIdIntegrationTest.kt | 2 -- .../RequirementsByEventIdIntegrationTest.kt | 3 -- .../CreateAppointmentIntegrationTests.kt | 2 -- .../justice/digital/hmpps/data/DataLoader.kt | 19 ++++++----- .../hmpps/data/generator/PersonGenerator.kt | 2 +- .../hmpps/data/generator/UserGenerator.kt | 9 +++-- .../hmpps/GetPersonByCRNIntegrationTest.kt | 2 -- .../digital/hmpps/UserIntegrationTest.kt | 34 +++++++++++++++++++ .../api/controller/ProbationCaseController.kt | 20 +++++++++++ .../SubjectAccessRequestsController.kt | 17 ---------- .../hmpps/api/controller/UserController.kt | 14 ++++++++ .../justice/digital/hmpps/api/model/User.kt | 6 ++++ .../delius/person => }/entity/Person.kt | 2 +- .../gov/justice/digital/hmpps/entity/User.kt | 31 +++++++++++++++++ .../service/SubjectAccessRequestsService.kt | 27 --------------- .../ProbationCaseControllerTest.kt} | 14 ++++---- 16 files changed, 130 insertions(+), 74 deletions(-) create mode 100644 projects/subject-access-requests-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/UserIntegrationTest.kt create mode 100644 projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/ProbationCaseController.kt delete mode 100644 projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/SubjectAccessRequestsController.kt create mode 100644 projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/UserController.kt create mode 100644 projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/User.kt rename projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/{integration/delius/person => }/entity/Person.kt (94%) create mode 100644 projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/User.kt delete mode 100644 projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/SubjectAccessRequestsService.kt rename projects/subject-access-requests-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/{service/SubjectAccessRequestsServiceTest.kt => api/controller/ProbationCaseControllerTest.kt} (78%) diff --git a/projects/court-case-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/ConvictionByCrnAndEventIdIntegrationTest.kt b/projects/court-case-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/ConvictionByCrnAndEventIdIntegrationTest.kt index 1fade86124..6b9cff0a7d 100644 --- a/projects/court-case-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/ConvictionByCrnAndEventIdIntegrationTest.kt +++ b/projects/court-case-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/ConvictionByCrnAndEventIdIntegrationTest.kt @@ -10,7 +10,6 @@ import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get -import org.springframework.test.web.servlet.result.MockMvcResultHandlers.print import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status import uk.gov.justice.digital.hmpps.api.model.Attendances @@ -256,7 +255,6 @@ internal class ConvictionByCrnAndEventIdIntegrationTest { val response = mockMvc .perform(get("/probation-case/$crn/convictions/${event.id}").withToken()) .andExpect(status().is2xxSuccessful) - .andDo(print()) .andReturn().response.contentAsJson() assertEquals(expectedResponse.convictionId, response.convictionId) diff --git a/projects/court-case-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/RequirementsByEventIdIntegrationTest.kt b/projects/court-case-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/RequirementsByEventIdIntegrationTest.kt index 8e35c2d223..4613303342 100644 --- a/projects/court-case-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/RequirementsByEventIdIntegrationTest.kt +++ b/projects/court-case-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/RequirementsByEventIdIntegrationTest.kt @@ -10,7 +10,6 @@ import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get -import org.springframework.test.web.servlet.result.MockMvcResultHandlers.print import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status import uk.gov.justice.digital.hmpps.api.model.KeyValue @@ -89,7 +88,6 @@ internal class RequirementsByEventIdIntegrationTest { val response = mockMvc .perform(get("/probation-case/$crn/convictions/${event.id}/requirements").withToken()) .andExpect(status().isOk) - .andDo(print()) .andReturn().response.contentAsJson() assertEquals(expectedResponse, response) @@ -119,7 +117,6 @@ internal class RequirementsByEventIdIntegrationTest { mockMvc .perform(get("/probation-case/$crn/convictions/${event.id}/requirements?$requestParams").withToken()) .andExpect(status().isOk) - .andDo(print()) .andExpect(jsonPath("$.requirements.length()").value(1)) .andExpect(jsonPath("$.requirements[0].active").value(active)) .andExpect(jsonPath("$.requirements[0].softDeleted").value(deleted)) diff --git a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/CreateAppointmentIntegrationTests.kt b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/CreateAppointmentIntegrationTests.kt index d6943c367f..4a4e2f2020 100644 --- a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/CreateAppointmentIntegrationTests.kt +++ b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/CreateAppointmentIntegrationTests.kt @@ -11,7 +11,6 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMock import org.springframework.boot.test.context.SpringBootTest import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post -import org.springframework.test.web.servlet.result.MockMvcResultHandlers.print import org.springframework.test.web.servlet.result.MockMvcResultMatchers import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath import uk.gov.justice.digital.hmpps.api.model.appointment.AppointmentDetail @@ -131,7 +130,6 @@ class CreateAppointmentIntegrationTests { .withToken() .withJson(createAppointment) ) - .andDo(print()) .andExpect(MockMvcResultMatchers.status().isCreated) .andReturn().response.contentAsJson() diff --git a/projects/subject-access-requests-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt b/projects/subject-access-requests-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt index 6480ea934f..5d38ef190a 100644 --- a/projects/subject-access-requests-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt +++ b/projects/subject-access-requests-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt @@ -9,26 +9,27 @@ import org.springframework.stereotype.Component import org.springframework.transaction.annotation.Transactional import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator import uk.gov.justice.digital.hmpps.data.generator.UserGenerator -import uk.gov.justice.digital.hmpps.user.AuditUserRepository +import uk.gov.justice.digital.hmpps.entity.UserRepository @Component @ConditionalOnProperty("seed.database") class DataLoader( - private val auditUserRepository: AuditUserRepository, - private val em: EntityManager + private val userRepository: UserRepository, + private val entityManager: EntityManager ) : ApplicationListener { @PostConstruct fun saveAuditUser() { - auditUserRepository.save(UserGenerator.AUDIT_USER) + userRepository.save(UserGenerator.AUDIT_USER) } @Transactional override fun onApplicationEvent(are: ApplicationReadyEvent) { - em.persistAll(PersonGenerator.PERSON1) - } - - private fun EntityManager.persistAll(vararg entities: Any) { - entities.forEach { persist(it) } + listOf( + PersonGenerator.PERSON1, + UserGenerator.USER1, + UserGenerator.USER2, + UserGenerator.INACTIVE_USER, + ).forEach { entityManager.persist(it) } } } diff --git a/projects/subject-access-requests-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/PersonGenerator.kt b/projects/subject-access-requests-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/PersonGenerator.kt index 7f83c4fbe0..8a047f1a59 100644 --- a/projects/subject-access-requests-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/PersonGenerator.kt +++ b/projects/subject-access-requests-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/PersonGenerator.kt @@ -1,6 +1,6 @@ package uk.gov.justice.digital.hmpps.data.generator -import uk.gov.justice.digital.hmpps.integration.delius.person.entity.Person +import uk.gov.justice.digital.hmpps.entity.Person object PersonGenerator { diff --git a/projects/subject-access-requests-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/UserGenerator.kt b/projects/subject-access-requests-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/UserGenerator.kt index 3722486f4f..d128875464 100644 --- a/projects/subject-access-requests-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/UserGenerator.kt +++ b/projects/subject-access-requests-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/UserGenerator.kt @@ -1,7 +1,12 @@ package uk.gov.justice.digital.hmpps.data.generator -import uk.gov.justice.digital.hmpps.user.AuditUser +import uk.gov.justice.digital.hmpps.entity.User +import java.time.LocalDate object UserGenerator { - val AUDIT_USER = AuditUser(IdGenerator.getAndIncrement(), "SubjectAccessRequestsAndDelius") + val AUDIT_USER = User(IdGenerator.getAndIncrement(), "SubjectAccessRequestsAndDelius", "Service") + + val USER1 = User(IdGenerator.getAndIncrement(), "username1", "surname1") + val USER2 = User(IdGenerator.getAndIncrement(), "username2", "surname2") + val INACTIVE_USER = User(IdGenerator.getAndIncrement(), "inactive", "inactive", LocalDate.now().minusDays(1)) } diff --git a/projects/subject-access-requests-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/GetPersonByCRNIntegrationTest.kt b/projects/subject-access-requests-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/GetPersonByCRNIntegrationTest.kt index 464c4fa154..fca93c1815 100644 --- a/projects/subject-access-requests-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/GetPersonByCRNIntegrationTest.kt +++ b/projects/subject-access-requests-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/GetPersonByCRNIntegrationTest.kt @@ -9,7 +9,6 @@ import org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDO import org.springframework.boot.test.mock.mockito.MockBean import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get -import org.springframework.test.web.servlet.result.MockMvcResultHandlers.print import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status import uk.gov.justice.digital.hmpps.api.model.Name @@ -52,7 +51,6 @@ internal class GetPersonByCRNIntegrationTest { val response = mockMvc .perform(get("/probation-case/$crn").withToken()) .andExpect(status().isOk) - .andDo(print()) .andReturn().response.contentAsJson() assertEquals(expectedResponse, response) diff --git a/projects/subject-access-requests-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/UserIntegrationTest.kt b/projects/subject-access-requests-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/UserIntegrationTest.kt new file mode 100644 index 0000000000..b796306e8f --- /dev/null +++ b/projects/subject-access-requests-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/UserIntegrationTest.kt @@ -0,0 +1,34 @@ +package uk.gov.justice.digital.hmpps + +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.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get +import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status +import uk.gov.justice.digital.hmpps.api.model.User +import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.andExpectJson +import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withToken + +@AutoConfigureMockMvc +@SpringBootTest(webEnvironment = RANDOM_PORT) +internal class UserIntegrationTest { + @Autowired + lateinit var mockMvc: MockMvc + + @Test + fun `returns data`() { + mockMvc + .perform(get("/user").withToken()) + .andExpect(status().isOk) + .andExpectJson( + listOf( + User("SubjectAccessRequestsAndDelius", "Service"), + User("username1", "surname1"), + User("username2", "surname2") + ), strict = true + ) + } +} diff --git a/projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/ProbationCaseController.kt b/projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/ProbationCaseController.kt new file mode 100644 index 0000000000..ea6e25bac9 --- /dev/null +++ b/projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/ProbationCaseController.kt @@ -0,0 +1,20 @@ +package uk.gov.justice.digital.hmpps.api.controller + +import org.springframework.security.access.prepost.PreAuthorize +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RestController +import uk.gov.justice.digital.hmpps.api.model.Name +import uk.gov.justice.digital.hmpps.api.model.Person +import uk.gov.justice.digital.hmpps.entity.PersonRepository +import uk.gov.justice.digital.hmpps.entity.getPerson + +@RestController +@PreAuthorize("hasRole('PROBATION_API__SUBJECT_ACCESS_REQUEST__DETAIL')") +class ProbationCaseController(private val personRepository: PersonRepository) { + @GetMapping("/probation-case/{crn}") + fun getPersonalDetails(@PathVariable crn: String) = with(personRepository.getPerson(crn)) { + val middleName = listOfNotNull(secondName, thirdName).takeIf { it.isNotEmpty() }?.joinToString(" ") + Person(Name(forename, middleName, surname)) + } +} diff --git a/projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/SubjectAccessRequestsController.kt b/projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/SubjectAccessRequestsController.kt deleted file mode 100644 index 60b2ebb4c6..0000000000 --- a/projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/SubjectAccessRequestsController.kt +++ /dev/null @@ -1,17 +0,0 @@ -package uk.gov.justice.digital.hmpps.api.controller - -import org.springframework.security.access.prepost.PreAuthorize -import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.bind.annotation.PathVariable -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RestController -import uk.gov.justice.digital.hmpps.service.SubjectAccessRequestsService - -@RestController -@RequestMapping("probation-case/{crn}") -@PreAuthorize("hasRole('PROBATION_API__SUBJECT_ACCESS_REQUEST__DETAIL')") -class SubjectAccessRequestsController(private val subjectAccessRequestsService: SubjectAccessRequestsService) { - - @GetMapping - fun getPersonalDetails(@PathVariable crn: String) = subjectAccessRequestsService.getPersonDetailsByCrn(crn) -} diff --git a/projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/UserController.kt b/projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/UserController.kt new file mode 100644 index 0000000000..8a308f6971 --- /dev/null +++ b/projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/UserController.kt @@ -0,0 +1,14 @@ +package uk.gov.justice.digital.hmpps.api.controller + +import org.springframework.security.access.prepost.PreAuthorize +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.RestController +import uk.gov.justice.digital.hmpps.api.model.User +import uk.gov.justice.digital.hmpps.entity.UserRepository + +@RestController +@PreAuthorize("hasRole('PROBATION_API__SUBJECT_ACCESS_REQUEST__DETAIL')") +class UserController(private val userRepository: UserRepository) { + @GetMapping("/user") + fun getUsers() = userRepository.findAll().map { User(it.username, it.surname) } +} diff --git a/projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/User.kt b/projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/User.kt new file mode 100644 index 0000000000..d9dc7a71fa --- /dev/null +++ b/projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/User.kt @@ -0,0 +1,6 @@ +package uk.gov.justice.digital.hmpps.api.model + +data class User( + val username: String, + val lastName: String +) \ No newline at end of file diff --git a/projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integration/delius/person/entity/Person.kt b/projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/Person.kt similarity index 94% rename from projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integration/delius/person/entity/Person.kt rename to projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/Person.kt index af42c1a859..b61669bec3 100644 --- a/projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integration/delius/person/entity/Person.kt +++ b/projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/Person.kt @@ -1,4 +1,4 @@ -package uk.gov.justice.digital.hmpps.integration.delius.person.entity +package uk.gov.justice.digital.hmpps.entity import jakarta.persistence.Column import jakarta.persistence.Entity diff --git a/projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/User.kt b/projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/User.kt new file mode 100644 index 0000000000..a11d9bb967 --- /dev/null +++ b/projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/User.kt @@ -0,0 +1,31 @@ +package uk.gov.justice.digital.hmpps.entity + +import jakarta.persistence.Column +import jakarta.persistence.Entity +import jakarta.persistence.Id +import jakarta.persistence.Table +import org.hibernate.annotations.Immutable +import org.hibernate.annotations.SQLRestriction +import org.springframework.data.jpa.repository.JpaRepository +import java.time.LocalDate + +@Entity +@Immutable +@Table(name = "user_") +@SQLRestriction("end_date is null or end_date > current_date") +class User( + @Id + @Column(name = "user_id") + val id: Long, + + @Column(name = "distinguished_name") + val username: String, + + @Column(name = "surname") + val surname: String, + + @Column + val endDate: LocalDate? = null +) + +interface UserRepository : JpaRepository diff --git a/projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/SubjectAccessRequestsService.kt b/projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/SubjectAccessRequestsService.kt deleted file mode 100644 index 5771f2094e..0000000000 --- a/projects/subject-access-requests-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/SubjectAccessRequestsService.kt +++ /dev/null @@ -1,27 +0,0 @@ -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.integration.delius.person.entity.PersonRepository -import uk.gov.justice.digital.hmpps.integration.delius.person.entity.getPerson -import uk.gov.justice.digital.hmpps.integration.delius.person.entity.Person as PersonEntity -import uk.gov.justice.digital.hmpps.api.model.Person - -@Service -class SubjectAccessRequestsService(private val personRepository: PersonRepository) { - - fun getPersonDetailsByCrn(crn: String): Person { - return personRepository.getPerson(crn).toPerson() - } -} - -fun PersonEntity.toPerson(): Person { - val middleName = listOfNotNull(secondName, thirdName).let { - when (it.size) { - 0 -> null - else -> it.joinToString(" ") - } - } - - return Person(Name(forename, middleName, surname)) -} diff --git a/projects/subject-access-requests-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/SubjectAccessRequestsServiceTest.kt b/projects/subject-access-requests-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/api/controller/ProbationCaseControllerTest.kt similarity index 78% rename from projects/subject-access-requests-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/SubjectAccessRequestsServiceTest.kt rename to projects/subject-access-requests-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/api/controller/ProbationCaseControllerTest.kt index 622b9c63d8..f588b6a395 100644 --- a/projects/subject-access-requests-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/SubjectAccessRequestsServiceTest.kt +++ b/projects/subject-access-requests-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/api/controller/ProbationCaseControllerTest.kt @@ -1,4 +1,4 @@ -package uk.gov.justice.digital.hmpps.service +package uk.gov.justice.digital.hmpps.api.controller import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.extension.ExtendWith @@ -11,19 +11,17 @@ import org.mockito.kotlin.whenever import uk.gov.justice.digital.hmpps.api.model.Name import uk.gov.justice.digital.hmpps.api.model.Person import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator -import uk.gov.justice.digital.hmpps.integration.delius.person.entity.Person as PersonEntity -import uk.gov.justice.digital.hmpps.integration.delius.person.entity.PersonRepository +import uk.gov.justice.digital.hmpps.entity.PersonRepository +import uk.gov.justice.digital.hmpps.entity.Person as PersonEntity @ExtendWith(MockitoExtension::class) -class SubjectAccessRequestsServiceTest { +class ProbationCaseControllerTest { @Mock lateinit var personRepository: PersonRepository @InjectMocks - lateinit var subjectAccessRequestsService: SubjectAccessRequestsService - - val person1 = PersonGenerator.PERSON1 + lateinit var probationCaseController: ProbationCaseController @ParameterizedTest @CsvSource( @@ -36,7 +34,7 @@ class SubjectAccessRequestsServiceTest { whenever(personRepository.findByCrn(crn)).thenReturn(getPerson(person)) - val response = subjectAccessRequestsService.getPersonDetailsByCrn(crn) + val response = probationCaseController.getPersonalDetails(crn) val expectedResponse = Person(getName(fullName)) From b08717d82a0192a0cbde8f1cc5753495e4108a87 Mon Sep 17 00:00:00 2001 From: Marcus Aspin Date: Tue, 19 Nov 2024 16:07:09 +0000 Subject: [PATCH 17/26] PI-2625 Ignore historic custodial status and location updates (#4416) --- .../hmpps/data/generator/EventGenerator.kt | 6 +- .../data/generator/NotificationGenerator.kt | 1 + .../messages/prisoner-released-historic.json | 17 +++ .../digital/hmpps/PcstdIntegrationTest.kt | 20 ++++ .../delius/custody/entity/Custody.kt | 6 +- .../hmpps/messaging/PrisonerMovement.kt | 6 + .../messaging/actions/UpdateLocationAction.kt | 3 +- .../messaging/actions/UpdateStatusAction.kt | 105 +++++++++--------- .../actions/UpdateStatusActionTest.kt | 11 +- 9 files changed, 110 insertions(+), 65 deletions(-) create mode 100644 projects/prison-custody-status-to-delius/src/dev/resources/messages/prisoner-released-historic.json diff --git a/projects/prison-custody-status-to-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/EventGenerator.kt b/projects/prison-custody-status-to-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/EventGenerator.kt index 6c7f2d9c53..38367b30c9 100644 --- a/projects/prison-custody-status-to-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/EventGenerator.kt +++ b/projects/prison-custody-status-to-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/EventGenerator.kt @@ -44,6 +44,8 @@ object EventGenerator { institution: Institution?, custodialStatusCode: CustodialStatusCode = CustodialStatusCode.IN_CUSTODY, disposalDate: ZonedDateTime = ZonedDateTime.of(2022, 5, 1, 0, 0, 0, 0, EuropeLondon), + statusChangeDate: LocalDate = LocalDate.of(2020, 1, 1), + locationChangeDate: LocalDate = LocalDate.of(2020, 1, 1), lengthInDays: Long = 365, disposalCode: String = "DEF" ): Event { @@ -54,8 +56,8 @@ object EventGenerator { status = ReferenceDataGenerator.CUSTODIAL_STATUS[custodialStatusCode]!!, institution = institution, disposal = disposal, - statusChangeDate = LocalDate.now().minusDays(1), - locationChangeDate = LocalDate.now().minusDays(1) + statusChangeDate = statusChangeDate, + locationChangeDate = locationChangeDate ) disposal.custody = custody return event diff --git a/projects/prison-custody-status-to-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/NotificationGenerator.kt b/projects/prison-custody-status-to-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/NotificationGenerator.kt index dfbcc1a3e6..fde0fc64ba 100644 --- a/projects/prison-custody-status-to-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/NotificationGenerator.kt +++ b/projects/prison-custody-status-to-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/NotificationGenerator.kt @@ -25,4 +25,5 @@ object NotificationGenerator { val PRISONER_ETR_IN_CUSTODY = ResourceLoader.notification("prisoner-received-etr-custody") val PRISONER_ECSLIRC_IN_CUSTODY = ResourceLoader.notification("prisoner-received-ecslirc-custody") val PRISONER_ADMIN_MERGE = ResourceLoader.notification("prisoner-released-admin-merge") + val PRISONER_RELEASED_HISTORIC = ResourceLoader.notification("prisoner-released-historic") } diff --git a/projects/prison-custody-status-to-delius/src/dev/resources/messages/prisoner-released-historic.json b/projects/prison-custody-status-to-delius/src/dev/resources/messages/prisoner-released-historic.json new file mode 100644 index 0000000000..b9c3d8c394 --- /dev/null +++ b/projects/prison-custody-status-to-delius/src/dev/resources/messages/prisoner-released-historic.json @@ -0,0 +1,17 @@ +{ + "Type": "Notification", + "MessageId": "682dd2a4-c193-461c-a8e9-cc976a961aa5", + "TopicArn": "", + "Message": "{\"eventType\":\"prison-offender-events.prisoner.released\",\"additionalInformation\":{\"nomsNumber\":\"A0001AA\",\"reason\":\"RELEASED\",\"details\":\"Movement reason code NCS\",\"nomisMovementReasonCode\":\"NCS\",\"currentLocation\":\"OUTSIDE_PRISON\",\"prisonId\":\"WSI\",\"currentPrisonStatus\":\"NOT_UNDER_PRISON_CARE\"},\"version\":1,\"occurredAt\":\"2010-01-01T07:03:50.912169+01:00\",\"publishedAt\":\"2010-01-01T08:00:33.477735848+01:00\",\"description\":\"A prisoner has been released from prison\",\"personReference\":{\"identifiers\":[{\"type\":\"NOMS\",\"value\":\"A0001AA\"}]}}", + "Timestamp": "2022-05-04T07:00:33.487Z", + "SignatureVersion": "1", + "Signature": "", + "SigningCertURL": "", + "UnsubscribeURL": "", + "MessageAttributes": { + "eventType": { + "Type": "String", + "Value": "prison-offender-events.prisoner.released" + } + } +} \ No newline at end of file diff --git a/projects/prison-custody-status-to-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/PcstdIntegrationTest.kt b/projects/prison-custody-status-to-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/PcstdIntegrationTest.kt index 1ccf2041f5..10774b826f 100644 --- a/projects/prison-custody-status-to-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/PcstdIntegrationTest.kt +++ b/projects/prison-custody-status-to-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/PcstdIntegrationTest.kt @@ -691,4 +691,24 @@ class PcstdIntegrationTest : PcstdIntegrationTestBase() { ) } } + + @Test + fun `status and location updates are ignored if the values have been updated more recently in Delius`() { + val notification = NotificationGenerator.PRISONER_RELEASED_HISTORIC + withBooking(BookingGenerator.RELEASED, BookingGenerator.RELEASED.lastMovement(notification.message.occurredAt)) + + channelManager.getChannel(queueName).publishAndWait(notification) + + verifyTelemetry("PrisonerLocationCorrect", "PrisonerStatusCorrect") { + mapOf( + "occurredAt" to notification.message.occurredAt.toString(), + "nomsNumber" to "A0001AA", + "previousInstitution" to "WSI", + "institution" to "OUT", + "reason" to "RELEASED", + "movementReason" to "NCS", + "movementType" to "Released" + ) + } + } } diff --git a/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/custody/entity/Custody.kt b/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/custody/entity/Custody.kt index e4b9787ed0..a3ab72bd8c 100644 --- a/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/custody/entity/Custody.kt +++ b/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/custody/entity/Custody.kt @@ -105,12 +105,10 @@ class Custody( dateTime: ZonedDateTime, detail: String, historyType: () -> ReferenceData - ): CustodyHistory? = if (this.status.code == status.code) { - null - } else { + ): CustodyHistory { this.status = status this.statusChangeDate = dateTime.toLocalDate() - CustodyHistory( + return CustodyHistory( date = dateTime, type = historyType(), detail = detail, diff --git a/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/PrisonerMovement.kt b/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/PrisonerMovement.kt index 1c2a684e8a..0c28ebfcbd 100644 --- a/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/PrisonerMovement.kt +++ b/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/PrisonerMovement.kt @@ -74,3 +74,9 @@ fun PrisonerMovement.releaseDateValid(custody: Custody): Boolean { fun PrisonerMovement.receivedDateValid(custody: Custody): Boolean = !occurredAt.isAfter(ZonedDateTime.now()) && (custody.mostRecentRelease()?.date?.let { !occurredAt.isBefore(it) } ?: true) + +fun PrisonerMovement.statusDateValid(custody: Custody): Boolean = + occurredAt <= ZonedDateTime.now() && occurredAt.toLocalDate() >= custody.statusChangeDate + +fun PrisonerMovement.locationDateValid(custody: Custody): Boolean = + occurredAt <= ZonedDateTime.now() && occurredAt.toLocalDate() >= custody.locationChangeDate diff --git a/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/actions/UpdateLocationAction.kt b/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/actions/UpdateLocationAction.kt index 4bbabc328e..fa823b69ec 100644 --- a/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/actions/UpdateLocationAction.kt +++ b/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/actions/UpdateLocationAction.kt @@ -119,7 +119,8 @@ class UpdateLocationAction( private fun checkPreconditions(prisonerMovement: PrisonerMovement, custody: Custody): ActionResult? { if ((prisonerMovement is PrisonerMovement.Received && custody.institution?.nomisCdeCode == prisonerMovement.toPrisonId) || (prisonerMovement is PrisonerMovement.Received && !prisonerMovement.receivedDateValid(custody)) || - (prisonerMovement is PrisonerMovement.Released && !prisonerMovement.releaseDateValid(custody)) + (prisonerMovement is PrisonerMovement.Released && !prisonerMovement.releaseDateValid(custody)) || + !prisonerMovement.locationDateValid(custody) ) { return ActionResult.Ignored("PrisonerLocationCorrect", prisonerMovement.telemetryProperties()) } diff --git a/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/actions/UpdateStatusAction.kt b/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/actions/UpdateStatusAction.kt index d64e21e23c..88ce12b46f 100644 --- a/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/actions/UpdateStatusAction.kt +++ b/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/actions/UpdateStatusAction.kt @@ -19,78 +19,83 @@ class UpdateStatusAction( private val custodyHistoryRepository: CustodyHistoryRepository ) : PrisonerMovementAction { override val name: String = "UpdateStatus" - override fun accept(context: PrisonerMovementContext): ActionResult = - when (context.prisonerMovement) { - is PrisonerMovement.Received -> { - inboundStatusChange(context) - } + override fun accept(context: PrisonerMovementContext): ActionResult { + val (prisonerMovement, custody) = context + + val result = checkPreconditions(prisonerMovement, custody) + if (result != null) return result - is PrisonerMovement.Released -> { - outboundStatusChange(context) - } + return when (context.prisonerMovement) { + is PrisonerMovement.Received -> inboundStatusChange(context) + is PrisonerMovement.Released -> outboundStatusChange(context) } + } private fun inboundStatusChange(context: PrisonerMovementContext): ActionResult { val (prisonerMovement, custody) = context - return if (custody.status.canChange() && prisonerMovement.receivedDateValid(custody)) { - val detail = if (custody.canBeRecalled()) "Recall added in custody " else "In custody " - updateStatus( - custody, - CustodialStatusCode.IN_CUSTODY, - prisonerMovement, - detail - ) - } else { - ActionResult.Ignored("PrisonerStatusCorrect", prisonerMovement.telemetryProperties()) - } + val detail = if (custody.canBeRecalled()) "Recall added in custody " else "In custody " + return updateStatus(custody, CustodialStatusCode.IN_CUSTODY, prisonerMovement, detail) } private fun outboundStatusChange(context: PrisonerMovementContext): ActionResult { val (prisonerMovement, custody) = context val statusCode = when { prisonerMovement.isHospitalRelease() || prisonerMovement.isIrcRelease() || prisonerMovement.isAbsconded() -> custody.nextStatus() - else -> if (custody.canBeReleased() && prisonerMovement.releaseDateValid(custody)) { - CustodialStatusCode.RELEASED_ON_LICENCE - } else { - throw IgnorableMessageException("PrisonerStatusCorrect") - } + else -> CustodialStatusCode.RELEASED_ON_LICENCE } - return updateStatus( - custody, - statusCode, - prisonerMovement, - when { - prisonerMovement.isHospitalRelease() -> "Transfer to/from Hospital" - prisonerMovement.isIrcRelease() -> "Transfer to Immigration Removal Centre" - prisonerMovement.isAbsconded() -> "Recall added unlawfully at large " - else -> "Released on Licence" - } - ) + val detail = when { + prisonerMovement.isHospitalRelease() -> "Transfer to/from Hospital" + prisonerMovement.isIrcRelease() -> "Transfer to Immigration Removal Centre" + prisonerMovement.isAbsconded() -> "Recall added unlawfully at large " + else -> "Released on Licence" + } + return updateStatus(custody, statusCode, prisonerMovement, detail) } - private fun Custody.nextStatus() = - when { - canBeRecalled() -> CustodialStatusCode.RECALLED - status.canChange() -> CustodialStatusCode.IN_CUSTODY - else -> throw IgnorableMessageException("PrisonerStatusCorrect") - } + private fun Custody.nextStatus() = when { + canBeRecalled() -> CustodialStatusCode.RECALLED + status.canChange() -> CustodialStatusCode.IN_CUSTODY + else -> throw IgnorableMessageException("PrisonerStatusCorrect") + } private fun updateStatus( custody: Custody, status: CustodialStatusCode, prisonerMovement: PrisonerMovement, detail: String - ): ActionResult = custody.updateStatusAt( - referenceDataRepository.getCustodialStatus(status.code), - prisonerMovement.occurredAt, - detail - ) { - referenceDataRepository.getCustodyEventType(CustodyEventTypeCode.STATUS_CHANGE.code) - }?.let { history -> + ): ActionResult = if (status.code == custody.status.code) { + ActionResult.Ignored("PrisonerStatusCorrect", prisonerMovement.telemetryProperties()) + } else { + val history = custody.updateStatusAt( + referenceDataRepository.getCustodialStatus(status.code), + prisonerMovement.occurredAt, + detail + ) { referenceDataRepository.getCustodyEventType(CustodyEventTypeCode.STATUS_CHANGE.code) } custodyRepository.save(custody) custodyHistoryRepository.save(history) - return ActionResult.Success(ActionResult.Type.StatusUpdated, prisonerMovement.telemetryProperties()) - } ?: ActionResult.Ignored("PrisonerStatusCorrect", prisonerMovement.telemetryProperties()) + ActionResult.Success(ActionResult.Type.StatusUpdated, prisonerMovement.telemetryProperties()) + } + + private fun checkPreconditions(prisonerMovement: PrisonerMovement, custody: Custody): ActionResult? { + if (prisonerMovement is PrisonerMovement.Received && + !(custody.status.canChange() && prisonerMovement.receivedDateValid(custody)) + ) { + return ActionResult.Ignored("PrisonerStatusCorrect", prisonerMovement.telemetryProperties()) + } + + if (prisonerMovement is PrisonerMovement.Released && + !(prisonerMovement.isHospitalRelease() || prisonerMovement.isIrcRelease() || prisonerMovement.isAbsconded()) && + !(custody.canBeReleased() && prisonerMovement.releaseDateValid(custody)) + ) { + return ActionResult.Ignored("PrisonerStatusCorrect", prisonerMovement.telemetryProperties()) + } + + if (!prisonerMovement.statusDateValid(custody)) { + return ActionResult.Ignored("PrisonerStatusCorrect", prisonerMovement.telemetryProperties()) + } + + return null + } } private fun ReferenceData.canChange() = !NO_CHANGE_STATUSES.map { it.code }.contains(code) diff --git a/projects/prison-custody-status-to-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/messaging/actions/UpdateStatusActionTest.kt b/projects/prison-custody-status-to-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/messaging/actions/UpdateStatusActionTest.kt index 52ee949fc8..4f628e7bae 100644 --- a/projects/prison-custody-status-to-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/messaging/actions/UpdateStatusActionTest.kt +++ b/projects/prison-custody-status-to-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/messaging/actions/UpdateStatusActionTest.kt @@ -15,12 +15,8 @@ import org.mockito.junit.jupiter.MockitoExtension import org.mockito.kotlin.any import org.mockito.kotlin.verify import org.mockito.kotlin.whenever -import uk.gov.justice.digital.hmpps.data.generator.CustodyGenerator -import uk.gov.justice.digital.hmpps.data.generator.EventGenerator +import uk.gov.justice.digital.hmpps.data.generator.* import uk.gov.justice.digital.hmpps.data.generator.EventGenerator.previouslyReleasedEvent -import uk.gov.justice.digital.hmpps.data.generator.InstitutionGenerator -import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator -import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator import uk.gov.justice.digital.hmpps.exception.IgnorableMessageException import uk.gov.justice.digital.hmpps.integrations.delius.custody.entity.Custody import uk.gov.justice.digital.hmpps.integrations.delius.custody.entity.CustodyHistoryRepository @@ -121,9 +117,8 @@ internal class UpdateStatusActionTest { ZonedDateTime.now().minusDays(1) ) - assertThrows { - action.accept(PrisonerMovementContext(prisonerMovement, custody)) - } + val result = action.accept(PrisonerMovementContext(prisonerMovement, custody)) + assertThat(result, instanceOf(ActionResult.Ignored::class.java)) } @ParameterizedTest From d9d185c2e00767bfeac6a4a60c31dfdf1ffcafc3 Mon Sep 17 00:00:00 2001 From: Marcus Aspin Date: Tue, 19 Nov 2024 17:55:44 +0000 Subject: [PATCH 18/26] PI-2625 Handle null location change date (#4443) --- .../uk/gov/justice/digital/hmpps/messaging/PrisonerMovement.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/PrisonerMovement.kt b/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/PrisonerMovement.kt index 0c28ebfcbd..2e610986db 100644 --- a/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/PrisonerMovement.kt +++ b/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/PrisonerMovement.kt @@ -79,4 +79,4 @@ fun PrisonerMovement.statusDateValid(custody: Custody): Boolean = occurredAt <= ZonedDateTime.now() && occurredAt.toLocalDate() >= custody.statusChangeDate fun PrisonerMovement.locationDateValid(custody: Custody): Boolean = - occurredAt <= ZonedDateTime.now() && occurredAt.toLocalDate() >= custody.locationChangeDate + occurredAt <= ZonedDateTime.now() && (custody.locationChangeDate == null || occurredAt.toLocalDate() >= custody.locationChangeDate) From be7e55467ad545f991d54e1d8239b2680b9a4a9f Mon Sep 17 00:00:00 2001 From: achimber-moj <161360519+achimber-moj@users.noreply.github.com> Date: Tue, 19 Nov 2024 18:27:00 +0000 Subject: [PATCH 19/26] Man 108 record if complied (#4445) * MAN-156 - update complied column * MAN-156 - update note to add created by * Formatting changes * MAN-108 - append note when updating contact * Formatting changes --------- Co-authored-by: probation-integration-bot[bot] <177347787+probation-integration-bot[bot]@users.noreply.github.com> --- .../justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt | 2 ++ .../hmpps/integrations/delius/sentence/entity/Appointment.kt | 3 +++ .../justice/digital/hmpps/service/AppointmentOutcomeService.kt | 3 ++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt index 42aa7a3291..91bcdb0ac1 100644 --- a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt +++ b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt @@ -89,6 +89,7 @@ class AppointmentOutcomeIntegrationTest { val createdAppointment = appointmentRepository.findById(response.appointments[0].id).get() assertNull(createdAppointment.attended) + assertNull(createdAppointment.complied) assertNull(createdAppointment.notes) assertNull(createdAppointment.outcomeId) assertNull(createdAppointment.sensitive) @@ -106,6 +107,7 @@ class AppointmentOutcomeIntegrationTest { val updatedAppointment = appointmentRepository.findById(response.appointments[0].id).get() assertEquals("Y", updatedAppointment.attended) + assertEquals("Y", updatedAppointment.complied) assertEquals(request.notes, updatedAppointment.notes) assertEquals(ATTENDED_COMPLIED.id, updatedAppointment.outcomeId) assertFalse(updatedAppointment.sensitive!!) diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt index 7d9bb9eac3..18e67ba657 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt @@ -83,6 +83,9 @@ class Appointment( @Column(name = "attended", columnDefinition = "char(1)") var attended: String? = null, + @Column(name = "complied", columnDefinition = "char(1") + var complied: String? = null, + @Column(name = "contact_outcome_type_id") var outcomeId: Long? = null, diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt index 589ed18335..eb76525b5d 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt @@ -22,7 +22,8 @@ class AppointmentOutcomeService( appointment.apply { attended = outcome.attended - notes = outcome.notes + complied = if (contactTypeOutcome.outcome.outcomeCompliantAcceptable!!) "Y" else "N" + notes = listOfNotNull(notes, outcome.notes).joinToString(System.lineSeparator()) outcomeId = contactTypeOutcome.outcome.id sensitive = outcome.sensitive } From 30ab577805bf990bbaa229358f57fbc0166a9b64 Mon Sep 17 00:00:00 2001 From: gregkhawkins <148795810+gregkhawkins@users.noreply.github.com> Date: Wed, 20 Nov 2024 11:53:42 +0000 Subject: [PATCH 20/26] APS-1482 - changes to offence id generation and offences data setup (#4444) --- .../hmpps/data/ProbationCaseDataLoader.kt | 40 +++++++++++++++---- .../hmpps/ProbationCaseIntegrationTest.kt | 6 +++ .../delius/person/offence/entity/Offence.kt | 4 +- .../justice/digital/hmpps/model/CaseDetail.kt | 2 +- .../digital/hmpps/service/CaseService.kt | 3 +- 5 files changed, 43 insertions(+), 12 deletions(-) diff --git a/projects/approved-premises-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/ProbationCaseDataLoader.kt b/projects/approved-premises-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/ProbationCaseDataLoader.kt index 2194d12f44..e3fedcc622 100644 --- a/projects/approved-premises-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/ProbationCaseDataLoader.kt +++ b/projects/approved-premises-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/ProbationCaseDataLoader.kt @@ -101,14 +101,30 @@ class ProbationCaseDataLoader( ) ) - listOf( + generateEventAndAddOffences( ProbationCaseGenerator.CASE_COMPLEX, + eventId = 100001L, + mainOffence = Pair(200001L, LocalDate.parse("2024-10-11")), + additionalOffence = Pair(300001L, LocalDate.parse("2024-10-21")) + ) + generateEventAndAddOffences( ProbationCaseGenerator.CASE_X320741, + eventId = 100002L, + mainOffence = Pair(200002L, LocalDate.parse("2024-10-12")), + additionalOffence = Pair(300002L, LocalDate.parse("2024-10-22")) + ) + generateEventAndAddOffences( ProbationCaseGenerator.CASE_LAO_RESTRICTED, + eventId = 100003L, + mainOffence = Pair(200003L, LocalDate.parse("2024-10-13")), + additionalOffence = Pair(300003L, LocalDate.parse("2024-10-23")) + ) + generateEventAndAddOffences( ProbationCaseGenerator.CASE_LAO_EXCLUSION, - ).forEach { - generateEventAndAddOffences(probationCase = it) - } + eventId = 100004L, + mainOffence = Pair(200004L, LocalDate.parse("2024-10-14")), + additionalOffence = Pair(300004L, LocalDate.parse("2024-10-24")) + ) personalCircumstanceTypeRepository.saveAll(PersonalCircumstanceGenerator.PC_TYPES) personalCircumstanceSubTypeRepository.saveAll(PersonalCircumstanceGenerator.PC_SUB_TYPES) @@ -125,17 +141,24 @@ class ProbationCaseDataLoader( exclusionRepository.save(LimitedAccessGenerator.generateExclusion(EXCLUDED_CASE.toLimitedAccessPerson())) } - private fun generateEventAndAddOffences(probationCase: ProbationCase) { + private fun generateEventAndAddOffences( + probationCase: ProbationCase, + eventId: Long, + mainOffence: Pair, + additionalOffence: Pair, + ) { val event = PersonGenerator.generateEvent( "1", - probationCase.id + probationCase.id, + id = eventId ).apply(eventRepository::save) mainOffenceRepository.save( OffenceGenerator.generateMainOffence( event, OffenceGenerator.OFFENCE_ONE, - LocalDate.now().minusDays(7) + id = mainOffence.first, + date = mainOffence.second ) ) @@ -143,7 +166,8 @@ class ProbationCaseDataLoader( OffenceGenerator.generateAdditionalOffence( event, OffenceGenerator.OFFENCE_TWO, - LocalDate.now().minusDays(5) + id = additionalOffence.first, + date = additionalOffence.second ) ) } diff --git a/projects/approved-premises-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/ProbationCaseIntegrationTest.kt b/projects/approved-premises-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/ProbationCaseIntegrationTest.kt index ffa54129ac..23e75f272f 100644 --- a/projects/approved-premises-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/ProbationCaseIntegrationTest.kt +++ b/projects/approved-premises-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/ProbationCaseIntegrationTest.kt @@ -70,9 +70,15 @@ class ProbationCaseIntegrationTest { assertThat(detail.mappaDetail?.level, equalTo(2)) assertThat(detail.registrations.map { it.description }, equalTo(listOf("Description of ARSO"))) val mainOffence = detail.offences.first { it.main } + assertThat(mainOffence.id, equalTo("M200001")) assertThat(mainOffence.description, equalTo("Offence One")) + assertThat(mainOffence.date, equalTo(LocalDate.parse("2024-10-11"))) + assertThat(mainOffence.eventId, equalTo(100001L)) val otherOffence = detail.offences.first { !it.main } + assertThat(otherOffence.id, equalTo("A300001")) assertThat(otherOffence.description, equalTo("Offence Two")) + assertThat(otherOffence.date, equalTo(LocalDate.parse("2024-10-21"))) + assertThat(otherOffence.eventId, equalTo(100001L)) assertThat(detail.careLeaver, equalTo(false)) assertThat(detail.veteran, equalTo(true)) } diff --git a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/person/offence/entity/Offence.kt b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/person/offence/entity/Offence.kt index 951cdae8f7..97d91a0220 100644 --- a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/person/offence/entity/Offence.kt +++ b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/person/offence/entity/Offence.kt @@ -88,7 +88,7 @@ interface MainOffenceRepository : JpaRepository { @Query( """ select - mo.offence.id as id, + mo.id as id, mo.offence.code as code, mo.offence.description as description, mo.date as date, @@ -99,7 +99,7 @@ interface MainOffenceRepository : JpaRepository { where mo.event.personId = :personId and mo.event.active = true union all select - ao.offence.id, + ao.id, ao.offence.code, ao.offence.description, ao.date, diff --git a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/model/CaseDetail.kt b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/model/CaseDetail.kt index b7359827c0..0cf9687caa 100644 --- a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/model/CaseDetail.kt +++ b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/model/CaseDetail.kt @@ -59,7 +59,7 @@ data class MappaDetail( ) data class Offence( - val id: Long, + val id: String, val code: String, val description: String, val date: LocalDate?, diff --git a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/CaseService.kt b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/CaseService.kt index 49cc6a0f32..8585a9cd9c 100644 --- a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/CaseService.kt +++ b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/CaseService.kt @@ -87,7 +87,8 @@ fun CommunityManager.team() = Team( team.endDate ) -fun CaseOffence.asOffence() = Offence(id, code, description, date, main, eventId, eventNumber) +fun CaseOffence.asOffence() = + Offence(id = if (main) "M$id" else "A$id", code, description, date, main, eventId, eventNumber) fun Registration.asRegistration() = uk.gov.justice.digital.hmpps.model.Registration(type.code, type.description, date) fun Registration.asMappa() = MappaDetail( From 85aacfeed26a66e7799d42e1229c7f8d16ec0e3c Mon Sep 17 00:00:00 2001 From: Marcus Aspin Date: Wed, 20 Nov 2024 14:21:07 +0000 Subject: [PATCH 21/26] PI-2653 Ignore temporary absence movements with no toAgency/fromAgency (#4446) --- .../kotlin/uk/gov/justice/digital/hmpps/messaging/Handler.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/Handler.kt b/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/Handler.kt index 2ccba192f4..eff2585ee6 100644 --- a/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/Handler.kt +++ b/projects/prison-custody-status-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/Handler.kt @@ -168,7 +168,7 @@ fun Booking.prisonerMovement(movement: Movement): PrisonerMovement { Booking.InOutStatus.IN -> PrisonerMovement.Received( personReference, movement.fromAgency, - movement.toAgency!!, + movement.toAgency ?: throw IgnorableMessageException("TemporaryAbsenceNoAgency"), PrisonerMovement.Type.valueOf(reason), movement.movementReason, dateTime @@ -176,7 +176,7 @@ fun Booking.prisonerMovement(movement: Movement): PrisonerMovement { Booking.InOutStatus.OUT -> PrisonerMovement.Released( personReference, - movement.fromAgency!!, + movement.fromAgency ?: throw IgnorableMessageException("TemporaryAbsenceNoAgency"), movement.toAgency, PrisonerMovement.Type.valueOf(reason), movement.movementReason, From da84e3fd8474bafbe769adabe45192cef0b390f4 Mon Sep 17 00:00:00 2001 From: "probation-integration-bot[bot]" <177347787+probation-integration-bot[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 14:52:55 +0000 Subject: [PATCH 22/26] PI-2564 Create initial project for assess-for-early-release-and-delius (#4447) * PI-2564 Create initial project for assess-for-early-release-and-delius * Update access.yml --------- Co-authored-by: probation-integration-bot[bot] <177347787+probation-integration-bot[bot]@users.noreply.github.com> Co-authored-by: Marcus Aspin --- .github/workflows/access.yml | 1 + .github/workflows/build.yml | 1 + .github/workflows/deploy.yml | 1 + .github/workflows/service-catalogue.yml | 1 + ...ssess-for-early-release-and-delius.run.xml | 29 +++ doc/tech-docs/source/services.html.md.erb | 1 + .../.trivyignore | 0 .../README.md | 3 + .../applicationinsights.json | 62 ++++++ .../build.gradle.kts | 36 ++++ .../deploy/Chart.yaml | 13 ++ .../deploy/database/access.yml | 9 + .../deploy/values-dev.yml | 17 ++ .../deploy/values-preprod.yml | 16 ++ .../deploy/values-prod.yml | 10 + .../deploy/values.yaml | 23 +++ .../settings.gradle.kts | 1 + .../justice/digital/hmpps/data/DataLoader.kt | 25 +++ .../hmpps/data/generator/UserGenerator.kt | 7 + .../justice/digital/hmpps/IntegrationTest.kt | 30 +++ .../uk/gov/justice/digital/hmpps/App.kt | 11 ++ .../digital/hmpps/controller/ApiController.kt | 17 ++ .../src/main/resources/application.yml | 73 ++++++++ .../tech-docs/.gitignore | 20 ++ .../tech-docs/.template_version | 3 + .../tech-docs/Gemfile | 12 ++ .../tech-docs/Gemfile.lock | 177 ++++++++++++++++++ .../tech-docs/config.rb | 8 + .../tech-docs/config/tech-docs.yml | 44 +++++ .../source/api-reference.html.md.erb | 19 ++ .../tech-docs/source/index.html.md.erb | 7 + .../source/javascripts/application.js | 1 + .../source/stylesheets/print.css.scss | 3 + .../source/stylesheets/screen-old-ie.css.scss | 4 + .../source/stylesheets/screen.css.scss | 1 + settings.gradle.kts | 1 + 36 files changed, 687 insertions(+) create mode 100644 .idea/runConfigurations/assess-for-early-release-and-delius.run.xml create mode 100644 projects/assess-for-early-release-and-delius/.trivyignore create mode 100644 projects/assess-for-early-release-and-delius/README.md create mode 100644 projects/assess-for-early-release-and-delius/applicationinsights.json create mode 100644 projects/assess-for-early-release-and-delius/build.gradle.kts create mode 100644 projects/assess-for-early-release-and-delius/deploy/Chart.yaml create mode 100644 projects/assess-for-early-release-and-delius/deploy/database/access.yml create mode 100644 projects/assess-for-early-release-and-delius/deploy/values-dev.yml create mode 100644 projects/assess-for-early-release-and-delius/deploy/values-preprod.yml create mode 100644 projects/assess-for-early-release-and-delius/deploy/values-prod.yml create mode 100644 projects/assess-for-early-release-and-delius/deploy/values.yaml create mode 100644 projects/assess-for-early-release-and-delius/settings.gradle.kts create mode 100644 projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt create mode 100644 projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/UserGenerator.kt create mode 100644 projects/assess-for-early-release-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/IntegrationTest.kt create mode 100644 projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/App.kt create mode 100644 projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/controller/ApiController.kt create mode 100644 projects/assess-for-early-release-and-delius/src/main/resources/application.yml create mode 100644 projects/assess-for-early-release-and-delius/tech-docs/.gitignore create mode 100644 projects/assess-for-early-release-and-delius/tech-docs/.template_version create mode 100644 projects/assess-for-early-release-and-delius/tech-docs/Gemfile create mode 100644 projects/assess-for-early-release-and-delius/tech-docs/Gemfile.lock create mode 100644 projects/assess-for-early-release-and-delius/tech-docs/config.rb create mode 100644 projects/assess-for-early-release-and-delius/tech-docs/config/tech-docs.yml create mode 100644 projects/assess-for-early-release-and-delius/tech-docs/source/api-reference.html.md.erb create mode 100644 projects/assess-for-early-release-and-delius/tech-docs/source/index.html.md.erb create mode 100644 projects/assess-for-early-release-and-delius/tech-docs/source/javascripts/application.js create mode 100644 projects/assess-for-early-release-and-delius/tech-docs/source/stylesheets/print.css.scss create mode 100644 projects/assess-for-early-release-and-delius/tech-docs/source/stylesheets/screen-old-ie.css.scss create mode 100644 projects/assess-for-early-release-and-delius/tech-docs/source/stylesheets/screen.css.scss diff --git a/.github/workflows/access.yml b/.github/workflows/access.yml index 6f53002e2c..6e6b41dcd4 100644 --- a/.github/workflows/access.yml +++ b/.github/workflows/access.yml @@ -58,6 +58,7 @@ on: - '["ims-and-delius"]' - '["appointment-reminders-and-delius"]' - '["justice-email-and-delius"]' + - '["assess-for-early-release-and-delius"]' # ^ add new projects here # GitHub Actions doesn't support dynamic choices, we must add each project here to enable manual deployments # See https://github.com/community/community/discussions/11795 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7afa312374..91ab71ace3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -85,6 +85,7 @@ jobs: - ims-and-delius - appointment-reminders-and-delius - justice-email-and-delius + - assess-for-early-release-and-delius # ^ add new projects here # GitHub Actions doesn't support dynamic choices, we must add each project here to enable manual deployments # See https://github.com/community/community/discussions/11795 diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index b857195496..d05a39a339 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -73,6 +73,7 @@ on: - '["ims-and-delius"]' - '["appointment-reminders-and-delius"]' - '["justice-email-and-delius"]' + - '["assess-for-early-release-and-delius"]' # ^ add new projects here # GitHub Actions doesn't support dynamic choices, we must add each project here to enable manual deployments # See https://github.com/community/community/discussions/11795 diff --git a/.github/workflows/service-catalogue.yml b/.github/workflows/service-catalogue.yml index 8250e66ce2..f99dd0b0d5 100644 --- a/.github/workflows/service-catalogue.yml +++ b/.github/workflows/service-catalogue.yml @@ -58,6 +58,7 @@ on: - '["ims-and-delius"]' - '["appointment-reminders-and-delius"]' - '["justice-email-and-delius"]' + - '["assess-for-early-release-and-delius"]' # ^ add new projects here # GitHub Actions doesn't support dynamic choices, we must add each project here to enable manual deployments # See https://github.com/community/community/discussions/11795 diff --git a/.idea/runConfigurations/assess-for-early-release-and-delius.run.xml b/.idea/runConfigurations/assess-for-early-release-and-delius.run.xml new file mode 100644 index 0000000000..80e0aa569f --- /dev/null +++ b/.idea/runConfigurations/assess-for-early-release-and-delius.run.xml @@ -0,0 +1,29 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/doc/tech-docs/source/services.html.md.erb b/doc/tech-docs/source/services.html.md.erb index 8225b8c9e8..cfee61c3ff 100644 --- a/doc/tech-docs/source/services.html.md.erb +++ b/doc/tech-docs/source/services.html.md.erb @@ -85,4 +85,5 @@ weight: 20 * [Ims And Delius](https://ministryofjustice.github.io/hmpps-probation-integration-services/tech-docs/projects/ims-and-delius) * [Appointment Reminders And Delius](https://ministryofjustice.github.io/hmpps-probation-integration-services/tech-docs/projects/appointment-reminders-and-delius) * [Justice Email And Delius](https://ministryofjustice.github.io/hmpps-probation-integration-services/tech-docs/projects/justice-email-and-delius) +* [Assess For Early Release And Delius](https://ministryofjustice.github.io/hmpps-probation-integration-services/tech-docs/projects/assess-for-early-release-and-delius)
  • ^ add new projects here
  • diff --git a/projects/assess-for-early-release-and-delius/.trivyignore b/projects/assess-for-early-release-and-delius/.trivyignore new file mode 100644 index 0000000000..e69de29bb2 diff --git a/projects/assess-for-early-release-and-delius/README.md b/projects/assess-for-early-release-and-delius/README.md new file mode 100644 index 0000000000..e91a03d980 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/README.md @@ -0,0 +1,3 @@ +# assess-for-early-release-and-delius + +// TODO Describe the service \ No newline at end of file diff --git a/projects/assess-for-early-release-and-delius/applicationinsights.json b/projects/assess-for-early-release-and-delius/applicationinsights.json new file mode 100644 index 0000000000..012edad194 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/applicationinsights.json @@ -0,0 +1,62 @@ +{ + "role": { + "name": "assess-for-early-release-and-delius" + }, + "customDimensions": { + "service.version": "${VERSION}", + "service.team": "probation-integration" + }, + "instrumentation": { + "logging": { + "level": "DEBUG" + }, + "springScheduling": { + "enabled": false + } + }, + "selfDiagnostics": { + "destination": "console" + }, + "sampling": { + "percentage": 100 + }, + "preview": { + "sampling": { + "overrides": [ + { + "telemetryType": "request", + "attributes": [ + { + "key": "http.url", + "value": "https?://[^/]+/health/?.*", + "matchType": "regexp" + } + ], + "percentage": 0 + }, + { + "telemetryType": "request", + "attributes": [ + { + "key": "http.url", + "value": "https?://[^/]+/info/?.*", + "matchType": "regexp" + } + ], + "percentage": 0 + }, + { + "telemetryType": "dependency", + "attributes": [ + { + "key": "db.operation", + "value": "SELECT", + "matchType": "strict" + } + ], + "percentage": 10 + } + ] + } + } +} \ No newline at end of file diff --git a/projects/assess-for-early-release-and-delius/build.gradle.kts b/projects/assess-for-early-release-and-delius/build.gradle.kts new file mode 100644 index 0000000000..a089a2f210 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/build.gradle.kts @@ -0,0 +1,36 @@ +import uk.gov.justice.digital.hmpps.extensions.ClassPathExtension + +apply(plugin = "com.google.cloud.tools.jib") + +dependencies { + implementation(project(":libs:audit")) + implementation(project(":libs:commons")) + implementation(project(":libs:oauth-server")) + + implementation("org.springframework.boot:spring-boot-starter-actuator") + implementation("org.springframework.boot:spring-boot-starter-data-jpa") + implementation("org.springframework.boot:spring-boot-starter-security") + implementation("org.springframework.boot:spring-boot-starter-validation") + implementation("org.springframework.boot:spring-boot-starter-web") + implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") + implementation("com.fasterxml.jackson.module:jackson-module-kotlin") + implementation(libs.springdoc) + + dev(project(":libs:dev-tools")) + dev("com.h2database:h2") + dev("org.testcontainers:oracle-xe") + + runtimeOnly("com.oracle.database.jdbc:ojdbc11") + + testImplementation("org.springframework.boot:spring-boot-starter-test") + testImplementation(libs.bundles.mockito) +} + +configure { + jacocoExclusions = listOf( + "**/config/**", + "**/entity/**", + "**/AppKt.class" + ) +} diff --git a/projects/assess-for-early-release-and-delius/deploy/Chart.yaml b/projects/assess-for-early-release-and-delius/deploy/Chart.yaml new file mode 100644 index 0000000000..1c5c964515 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/deploy/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v2 +appVersion: '1.0' +description: A Helm chart for Kubernetes +name: assess-for-early-release-and-delius +version: 1.0.0 + +dependencies: + - name: generic-service + version: "3.2" + repository: https://ministryofjustice.github.io/hmpps-helm-charts + - name: generic-prometheus-alerts + version: "1.4" + repository: https://ministryofjustice.github.io/hmpps-helm-charts \ No newline at end of file diff --git a/projects/assess-for-early-release-and-delius/deploy/database/access.yml b/projects/assess-for-early-release-and-delius/deploy/database/access.yml new file mode 100644 index 0000000000..e8bd4437b7 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/deploy/database/access.yml @@ -0,0 +1,9 @@ +database: + access: + username_key: /assess-for-early-release-and-delius/db-username + password_key: /assess-for-early-release-and-delius/db-password + + audit: + username: AssessForEarlyReleaseAndDelius + forename: Assess for Early Release + surname: Service diff --git a/projects/assess-for-early-release-and-delius/deploy/values-dev.yml b/projects/assess-for-early-release-and-delius/deploy/values-dev.yml new file mode 100644 index 0000000000..41baa373a1 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/deploy/values-dev.yml @@ -0,0 +1,17 @@ +enabled: false # TODO set this to true when you're ready to deploy your service + +generic-service: + ingress: + host: assess-for-early-release-and-delius-dev.hmpps.service.justice.gov.uk + + scheduledDowntime: + enabled: true + + env: + SENTRY_ENVIRONMENT: dev + LOGGING_LEVEL_UK_GOV_DIGITAL_JUSTICE_HMPPS: DEBUG + SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI: https://sign-in-dev.hmpps.service.justice.gov.uk/auth/.well-known/jwks.json + SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI: https://sign-in-dev.hmpps.service.justice.gov.uk/auth/issuer + +generic-prometheus-alerts: + businessHoursOnly: true diff --git a/projects/assess-for-early-release-and-delius/deploy/values-preprod.yml b/projects/assess-for-early-release-and-delius/deploy/values-preprod.yml new file mode 100644 index 0000000000..23a555dccd --- /dev/null +++ b/projects/assess-for-early-release-and-delius/deploy/values-preprod.yml @@ -0,0 +1,16 @@ +enabled: false # TODO set this to true when you're ready to deploy your service + +generic-service: + ingress: + host: assess-for-early-release-and-delius-preprod.hmpps.service.justice.gov.uk + + scheduledDowntime: + enabled: true + + env: + SENTRY_ENVIRONMENT: preprod + SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI: https://sign-in-preprod.hmpps.service.justice.gov.uk/auth/.well-known/jwks.json + SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI: https://sign-in-preprod.hmpps.service.justice.gov.uk/auth/issuer + +generic-prometheus-alerts: + businessHoursOnly: true \ No newline at end of file diff --git a/projects/assess-for-early-release-and-delius/deploy/values-prod.yml b/projects/assess-for-early-release-and-delius/deploy/values-prod.yml new file mode 100644 index 0000000000..a26f2ca45b --- /dev/null +++ b/projects/assess-for-early-release-and-delius/deploy/values-prod.yml @@ -0,0 +1,10 @@ +enabled: false # TODO set this to true when you're ready to deploy your service + +generic-service: + ingress: + host: assess-for-early-release-and-delius.hmpps.service.justice.gov.uk + + env: + SENTRY_ENVIRONMENT: prod + SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI: https://sign-in.hmpps.service.justice.gov.uk/auth/.well-known/jwks.json + SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI: https://sign-in.hmpps.service.justice.gov.uk/auth/issuer diff --git a/projects/assess-for-early-release-and-delius/deploy/values.yaml b/projects/assess-for-early-release-and-delius/deploy/values.yaml new file mode 100644 index 0000000000..9170a7faa4 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/deploy/values.yaml @@ -0,0 +1,23 @@ +# Common values +generic-service: + productId: HMPPS518 + nameOverride: assess-for-early-release-and-delius + + image: + repository: ghcr.io/ministryofjustice/hmpps-probation-integration-services/assess-for-early-release-and-delius + + ingress: + tlsSecretName: assess-for-early-release-and-delius-cert + + namespace_secrets: + common: + SPRING_DATASOURCE_URL: DB_URL + assess-for-early-release-and-delius-database: + SPRING_DATASOURCE_USERNAME: DB_USERNAME + SPRING_DATASOURCE_PASSWORD: DB_PASSWORD + assess-for-early-release-and-delius-sentry: + SENTRY_DSN: SENTRY_DSN + +generic-prometheus-alerts: + targetApplication: assess-for-early-release-and-delius + diff --git a/projects/assess-for-early-release-and-delius/settings.gradle.kts b/projects/assess-for-early-release-and-delius/settings.gradle.kts new file mode 100644 index 0000000000..54c13653a1 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "assess-for-early-release-and-delius" diff --git a/projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt b/projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt new file mode 100644 index 0000000000..f6ea94c9a7 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt @@ -0,0 +1,25 @@ +package uk.gov.justice.digital.hmpps.data + +import jakarta.annotation.PostConstruct +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.context.event.ApplicationReadyEvent +import org.springframework.context.ApplicationListener +import org.springframework.stereotype.Component +import uk.gov.justice.digital.hmpps.data.generator.UserGenerator +import uk.gov.justice.digital.hmpps.user.AuditUserRepository + +@Component +@ConditionalOnProperty("seed.database") +class DataLoader( + private val auditUserRepository: AuditUserRepository +) : ApplicationListener { + + @PostConstruct + fun saveAuditUser() { + auditUserRepository.save(UserGenerator.AUDIT_USER) + } + + override fun onApplicationEvent(are: ApplicationReadyEvent) { + // Perform dev/test database setup here, using JPA repositories and generator classes... + } +} diff --git a/projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/UserGenerator.kt b/projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/UserGenerator.kt new file mode 100644 index 0000000000..63e88c7b6c --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/UserGenerator.kt @@ -0,0 +1,7 @@ +package uk.gov.justice.digital.hmpps.data.generator + +import uk.gov.justice.digital.hmpps.user.AuditUser + +object UserGenerator { + val AUDIT_USER = AuditUser(IdGenerator.getAndIncrement(), "AssessForEarlyReleaseAndDelius") +} diff --git a/projects/assess-for-early-release-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/IntegrationTest.kt b/projects/assess-for-early-release-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/IntegrationTest.kt new file mode 100644 index 0000000000..d9006c74c5 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/IntegrationTest.kt @@ -0,0 +1,30 @@ +package uk.gov.justice.digital.hmpps + +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.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT +import org.springframework.boot.test.mock.mockito.MockBean +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get +import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status +import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withToken +import uk.gov.justice.digital.hmpps.telemetry.TelemetryService + +@AutoConfigureMockMvc +@SpringBootTest(webEnvironment = RANDOM_PORT) +internal class IntegrationTest { + @Autowired + lateinit var mockMvc: MockMvc + + @MockBean + lateinit var telemetryService: TelemetryService + + @Test + fun `API call retuns a success response`() { + mockMvc + .perform(get("/example/123").withToken()) + .andExpect(status().is2xxSuccessful) + } +} diff --git a/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/App.kt b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/App.kt new file mode 100644 index 0000000000..c7faac5b26 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/App.kt @@ -0,0 +1,11 @@ +package uk.gov.justice.digital.hmpps + +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.boot.runApplication + +@SpringBootApplication +class App + +fun main(args: Array) { + runApplication(*args) +} diff --git a/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/controller/ApiController.kt b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/controller/ApiController.kt new file mode 100644 index 0000000000..6e4f24c46f --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/controller/ApiController.kt @@ -0,0 +1,17 @@ +package uk.gov.justice.digital.hmpps.controller + +import org.springframework.security.access.prepost.PreAuthorize +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RestController + +@RestController +class ApiController { + @PreAuthorize("hasRole('EXAMPLE')") + @GetMapping(value = ["/example/{inputId}"]) + fun handle( + @PathVariable("inputId") inputId: String + ) { + // TODO Not yet implemented + } +} diff --git a/projects/assess-for-early-release-and-delius/src/main/resources/application.yml b/projects/assess-for-early-release-and-delius/src/main/resources/application.yml new file mode 100644 index 0000000000..18f07d6fe3 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/main/resources/application.yml @@ -0,0 +1,73 @@ +# Default config +server.shutdown: graceful +spring: + jackson: + default-property-inclusion: non_null + jpa: + hibernate.ddl-auto: validate + database-platform: org.hibernate.dialect.OracleDialect + properties: + hibernate: + timezone.default_storage: NORMALIZE + query.mutation_strategy: org.hibernate.query.sqm.mutation.internal.inline.InlineMutationStrategy + query.mutation_strategy.persistent: + create_tables: false + drop_tables: false + query.mutation_strategy.global_temporary: + create_tables: false + drop_tables: false + threads.virtual.enabled: true + +oauth2.roles: + - EXAMPLE + +springdoc.default-produces-media-type: application/json + +delius.db.username: AssessForEarlyReleaseAndDelius # Should match value in [deploy/database/access.yml]. + +management: + endpoints.web: + base-path: / + exposure.include: [ "health", "info" ] + endpoint.health.show-details: always + +info.productId: HMPPS518 # https://developer-portal.hmpps.service.justice.gov.uk/products/185 + +--- +# Shared dev/test config +spring.config.activate.on-profile: [ "dev", "integration-test" ] +server.shutdown: immediate + +spring: + datasource.url: jdbc:h2:file:./dev;MODE=Oracle;DEFAULT_NULL_ORDERING=HIGH;AUTO_SERVER=true;AUTO_SERVER_PORT=9092 + jpa.hibernate.ddl-auto: create-drop + +seed.database: true +wiremock.enabled: true +context.initializer.classes: uk.gov.justice.digital.hmpps.wiremock.WireMockInitialiser + +logging.level: + uk.gov.justice.digital.hmpps: DEBUG + org.hibernate.tool.schema: ERROR + org.apache.activemq: WARN + +--- +spring.config.activate.on-profile: integration-test +spring.datasource.url: jdbc:h2:mem:./test;MODE=Oracle;DEFAULT_NULL_ORDERING=HIGH + +--- +spring.config.activate.on-profile: oracle +spring: + datasource.url: 'jdbc:tc:oracle:slim-faststart:///XEPDB1' + jpa.hibernate.ddl-auto: create + +--- +spring.config.activate.on-profile: delius-db +spring: + datasource: + url: 'jdbc:oracle:thin:@//localhost:1521/XEPDB1' + username: delius_pool + password: NDelius1 + jpa.hibernate.ddl-auto: validate +seed.database: false +delius.db.username: NationalUser diff --git a/projects/assess-for-early-release-and-delius/tech-docs/.gitignore b/projects/assess-for-early-release-and-delius/tech-docs/.gitignore new file mode 100644 index 0000000000..80d5de85a7 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/tech-docs/.gitignore @@ -0,0 +1,20 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. +# +# If you find yourself ignoring temporary files generated by your text editor +# or operating system, you probably want to add a global ignore instead: +# git config --global core.excludesfile ~/.gitignore_global + +# Ignore bundler config +/.bundle + +# Ignore the build directory +/build + +# Ignore cache +/.sass-cache +/.cache + +# Ignore .DS_store file +.DS_Store + +Staticfile.auth diff --git a/projects/assess-for-early-release-and-delius/tech-docs/.template_version b/projects/assess-for-early-release-and-delius/tech-docs/.template_version new file mode 100644 index 0000000000..57ff8862e1 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/tech-docs/.template_version @@ -0,0 +1,3 @@ +--- +:remote: https://github.com/alphagov/tech-docs-template.git +:revision: b37e894 \ No newline at end of file diff --git a/projects/assess-for-early-release-and-delius/tech-docs/Gemfile b/projects/assess-for-early-release-and-delius/tech-docs/Gemfile new file mode 100644 index 0000000000..afef363c09 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/tech-docs/Gemfile @@ -0,0 +1,12 @@ +# If you do not have OpenSSL installed, change +# the following line to use 'http://' +source 'https://rubygems.org' + +# For faster file watcher updates on Windows: +gem 'wdm', '~> 0.1.0', platforms: [:mswin, :mingw, :x64_mingw] + +# Windows does not come with time zone data +gem 'tzinfo-data', platforms: [:mswin, :mingw, :x64_mingw, :jruby] + +# Include the tech docs gem +gem 'govuk_tech_docs' diff --git a/projects/assess-for-early-release-and-delius/tech-docs/Gemfile.lock b/projects/assess-for-early-release-and-delius/tech-docs/Gemfile.lock new file mode 100644 index 0000000000..9fdb19f88e --- /dev/null +++ b/projects/assess-for-early-release-and-delius/tech-docs/Gemfile.lock @@ -0,0 +1,177 @@ +GEM + remote: https://rubygems.org/ + specs: + activesupport (7.0.7.2) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 1.6, < 2) + minitest (>= 5.1) + tzinfo (~> 2.0) + addressable (2.8.4) + public_suffix (>= 2.0.2, < 6.0) + autoprefixer-rails (10.4.13.0) + execjs (~> 2) + backports (3.24.1) + chronic (0.10.2) + chunky_png (1.4.0) + coffee-script (2.4.1) + coffee-script-source + execjs + coffee-script-source (1.12.2) + commonmarker (0.23.10) + compass (1.0.3) + chunky_png (~> 1.2) + compass-core (~> 1.0.2) + compass-import-once (~> 1.0.5) + rb-fsevent (>= 0.9.3) + rb-inotify (>= 0.9) + sass (>= 3.3.13, < 3.5) + compass-core (1.0.3) + multi_json (~> 1.0) + sass (>= 3.3.0, < 3.5) + compass-import-once (1.0.5) + sass (>= 3.2, < 3.5) + concurrent-ruby (1.2.2) + contracts (0.17) + dotenv (2.8.1) + em-websocket (0.5.3) + eventmachine (>= 0.12.9) + http_parser.rb (~> 0) + erubis (2.7.0) + eventmachine (1.2.7) + execjs (2.8.1) + fast_blank (1.0.1) + fastimage (2.2.6) + ffi (1.15.5) + govuk_tech_docs (3.3.1) + autoprefixer-rails (~> 10.2) + chronic (~> 0.10.2) + middleman (~> 4.0) + middleman-autoprefixer (~> 2.10.0) + middleman-compass (>= 4.0.0) + middleman-livereload + middleman-search-gds + middleman-sprockets (~> 4.0.0) + middleman-syntax (~> 3.2.0) + nokogiri + openapi3_parser (~> 0.9.0) + redcarpet (~> 3.5.1) + haml (5.2.2) + temple (>= 0.8.0) + tilt + hamster (3.0.0) + concurrent-ruby (~> 1.0) + hashie (3.6.0) + http_parser.rb (0.8.0) + i18n (1.6.0) + concurrent-ruby (~> 1.0) + kramdown (2.4.0) + rexml + listen (3.8.0) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + memoist (0.16.2) + middleman (4.4.3) + coffee-script (~> 2.2) + haml (>= 4.0.5, < 6.0) + kramdown (>= 2.3.0) + middleman-cli (= 4.4.3) + middleman-core (= 4.4.3) + middleman-autoprefixer (2.10.0) + autoprefixer-rails (>= 9.1.4) + middleman-core (>= 3.3.3) + middleman-cli (4.4.3) + thor (>= 0.17.0, < 2.0) + middleman-compass (4.0.1) + compass (>= 1.0.0, < 2.0.0) + middleman-core (>= 4.0.0) + middleman-core (4.4.3) + activesupport (>= 6.1, < 7.1) + addressable (~> 2.4) + backports (~> 3.6) + bundler (~> 2.0) + contracts (~> 0.13) + dotenv + erubis + execjs (~> 2.0) + fast_blank + fastimage (~> 2.0) + hamster (~> 3.0) + hashie (~> 3.4) + i18n (~> 1.6.0) + listen (~> 3.0) + memoist (~> 0.14) + padrino-helpers (~> 0.15.0) + parallel + rack (>= 1.4.5, < 3) + sassc (~> 2.0) + servolux + tilt (~> 2.0.9) + toml + uglifier (~> 3.0) + webrick + middleman-livereload (3.4.7) + em-websocket (~> 0.5.1) + middleman-core (>= 3.3) + rack-livereload (~> 0.3.15) + middleman-search-gds (0.11.2) + execjs (~> 2.6) + middleman-core (>= 3.2) + nokogiri (~> 1.6) + middleman-sprockets (4.0.0) + middleman-core (~> 4.0) + sprockets (>= 3.0) + middleman-syntax (3.2.0) + middleman-core (>= 3.2) + rouge (~> 3.2) + minitest (5.18.0) + multi_json (1.15.0) + nokogiri (1.16.5-x86_64-linux) + racc (~> 1.4) + openapi3_parser (0.9.2) + commonmarker (~> 0.17) + padrino-helpers (0.15.3) + i18n (>= 0.6.7, < 2) + padrino-support (= 0.15.3) + tilt (>= 1.4.1, < 3) + padrino-support (0.15.3) + parallel (1.22.1) + parslet (2.0.0) + public_suffix (5.0.1) + racc (1.7.3) + rack (2.2.8.1) + rack-livereload (0.3.17) + rack + rb-fsevent (0.11.2) + rb-inotify (0.10.1) + ffi (~> 1.0) + redcarpet (3.5.1) + rexml (3.3.9) + rouge (3.30.0) + sass (3.4.25) + sassc (2.4.0) + ffi (~> 1.9) + servolux (0.13.0) + sprockets (4.2.0) + concurrent-ruby (~> 1.0) + rack (>= 2.2.4, < 4) + temple (0.10.0) + thor (1.2.1) + tilt (2.0.11) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + uglifier (3.2.0) + execjs (>= 0.3.0, < 3) + webrick (1.8.2) + +PLATFORMS + x86_64-linux + +DEPENDENCIES + govuk_tech_docs + tzinfo-data + wdm (~> 0.1.0) + +BUNDLED WITH + 2.3.26 diff --git a/projects/assess-for-early-release-and-delius/tech-docs/config.rb b/projects/assess-for-early-release-and-delius/tech-docs/config.rb new file mode 100644 index 0000000000..76c77d53dd --- /dev/null +++ b/projects/assess-for-early-release-and-delius/tech-docs/config.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +require "govuk_tech_docs" + +GovukTechDocs.configure(self) + +activate :relative_assets +set :relative_links, true diff --git a/projects/assess-for-early-release-and-delius/tech-docs/config/tech-docs.yml b/projects/assess-for-early-release-and-delius/tech-docs/config/tech-docs.yml new file mode 100644 index 0000000000..646e660be3 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/tech-docs/config/tech-docs.yml @@ -0,0 +1,44 @@ +# Host to use for canonical URL generation (without trailing slash) +host: https://ministryofjustice.github.io/hmpps-probation-integration-services/tech-docs/projects/assess-for-early-release-and-delius + +# Header-related options +service_name: HMPPS Assess For Early Release And Delius +service_link: https://ministryofjustice.github.io/hmpps-probation-integration-services/tech-docs/projects/assess-for-early-release-and-delius + +# Links to show on right-hand-side of header +header_links: + Home: https://ministryofjustice.github.io/hmpps-probation-integration-services/tech-docs + GitHub: https://github.com/ministryofjustice/hmpps-probation-integration-services#readme + Slack: https://mojdt.slack.com/archives/C02HQ4M2YQN # #probation-integration-tech channel + +# Enables search functionality. This indexes pages only and is not recommended for single-page sites. +enable_search: true + +# Tracking ID from Google Analytics (e.g. UA-XXXX-Y) +ga_tracking_id: + +# Enable multipage navigation in the sidebar +multipage_nav: true + +# Enable collapsible navigation in the sidebar +collapsible_nav: true + +# Table of contents depth – how many levels to include in the table of contents. +# If your ToC is too long, reduce this number and we'll only show higher-level +# headings. +max_toc_heading_level: 2 + +# Prevent robots from indexing (e.g. whilst in development) +prevent_indexing: false + +# Contribution +show_contribution_banner: true +github_repo: ministryofjustice/hmpps-probation-integration-services +github_branch: main + +# Slack +owner_slack_workspace: mojdt +default_owner_slack: '#probation-integration-tech' + +# OpenAPI +api_path: https://assess-for-early-release-and-delius-dev.hmpps.service.justice.gov.uk/v3/api-docs.yaml diff --git a/projects/assess-for-early-release-and-delius/tech-docs/source/api-reference.html.md.erb b/projects/assess-for-early-release-and-delius/tech-docs/source/api-reference.html.md.erb new file mode 100644 index 0000000000..a21752cfae --- /dev/null +++ b/projects/assess-for-early-release-and-delius/tech-docs/source/api-reference.html.md.erb @@ -0,0 +1,19 @@ +--- +title: API Reference +source_url: 'https://github.com/ministryofjustice/hmpps-probation-integration-services/blob/main/projects/assess-for-early-release-and-delius/tech-docs/source/api-reference.html.md.erb' +weight: 20 +--- + +
    + + API Reference +
    + + +The following documentation is also available in these formats: + +* [OpenAPI JSON](https://ministryofjustice.github.io/hmpps-probation-integration-services/tech-docs/projects/assess-for-early-release-and-delius/api-docs.json) +* [OpenAPI YAML](https://ministryofjustice.github.io/hmpps-probation-integration-services/tech-docs/projects/assess-for-early-release-and-delius/api-docs.yaml) +* [Swagger UI](https://assess-for-early-release-and-delius-dev.hmpps.service.justice.gov.uk/swagger-ui/index.html) + +api> diff --git a/projects/assess-for-early-release-and-delius/tech-docs/source/index.html.md.erb b/projects/assess-for-early-release-and-delius/tech-docs/source/index.html.md.erb new file mode 100644 index 0000000000..52d19debb8 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/tech-docs/source/index.html.md.erb @@ -0,0 +1,7 @@ +--- +title: About +source_url: 'https://github.com/ministryofjustice/hmpps-probation-integration-services/blob/main/projects/assess-for-early-release-and-delius/tech-docs/source/index.html.md.erb' +weight: 10 +--- + +<%= URI.open('https://raw.githubusercontent.com/ministryofjustice/hmpps-probation-integration-services/main/projects/assess-for-early-release-and-delius/README.md').read.gsub(/tech-docs\/source\//, "./") %> \ No newline at end of file diff --git a/projects/assess-for-early-release-and-delius/tech-docs/source/javascripts/application.js b/projects/assess-for-early-release-and-delius/tech-docs/source/javascripts/application.js new file mode 100644 index 0000000000..8a5d80b842 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/tech-docs/source/javascripts/application.js @@ -0,0 +1 @@ +//= require govuk_tech_docs diff --git a/projects/assess-for-early-release-and-delius/tech-docs/source/stylesheets/print.css.scss b/projects/assess-for-early-release-and-delius/tech-docs/source/stylesheets/print.css.scss new file mode 100644 index 0000000000..82b181c017 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/tech-docs/source/stylesheets/print.css.scss @@ -0,0 +1,3 @@ +$is-print: true; + +@import "govuk_tech_docs"; diff --git a/projects/assess-for-early-release-and-delius/tech-docs/source/stylesheets/screen-old-ie.css.scss b/projects/assess-for-early-release-and-delius/tech-docs/source/stylesheets/screen-old-ie.css.scss new file mode 100644 index 0000000000..da90cca5b0 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/tech-docs/source/stylesheets/screen-old-ie.css.scss @@ -0,0 +1,4 @@ +$is-ie: true; +$ie-version: 8; + +@import "govuk_tech_docs"; diff --git a/projects/assess-for-early-release-and-delius/tech-docs/source/stylesheets/screen.css.scss b/projects/assess-for-early-release-and-delius/tech-docs/source/stylesheets/screen.css.scss new file mode 100644 index 0000000000..f0456338fd --- /dev/null +++ b/projects/assess-for-early-release-and-delius/tech-docs/source/stylesheets/screen.css.scss @@ -0,0 +1 @@ +@import "govuk_tech_docs"; diff --git a/settings.gradle.kts b/settings.gradle.kts index e897a719f8..c73ea07547 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,6 +1,7 @@ rootProject.name = "probation-integration-services" include( // ⌄ add new projects here + "assess-for-early-release-and-delius", "justice-email-and-delius", "appointment-reminders-and-delius", "ims-and-delius", From 2f253ac81a13ae6086cdc1a36beabd9289f19e3f Mon Sep 17 00:00:00 2001 From: Marcus Aspin Date: Wed, 20 Nov 2024 15:47:00 +0000 Subject: [PATCH 23/26] Added note about imports to code formatting section (#4450) also moved code formatting to development section --- README.md | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index a1b558b2d9..88852a0e6c 100644 --- a/README.md +++ b/README.md @@ -61,9 +61,24 @@ Docker or remote dependencies. To set up your development environment: 1. Open the project in [IntelliJ IDEA](https://www.jetbrains.com/idea/). Select "Import project from external model", then "Gradle". -2. To run the tests for a service, right-click the `src/test` folder in the project view and select "Run tests" (See [Test](#test)). +2. To run the tests for a service, right-click the `src/test` or `src/integrationTest` folder in the project view and + select "Run tests" (See [Test](#test)). 3. To start the service, use the pre-defined run configuration in `.idea/runConfigurations` (See [Run](#run)). +## Code formatting + +Kotlin code is formatted using IntelliJ IDEA's code formatter, +which follows the [Kotlin Coding Conventions](https://kotlinlang.org/docs/coding-conventions.html). + +GitHub Actions will automatically fix any formatting issues when you open a pull request. +You can also use ⌘⌥**L** (macOS), +or **Ctrl+Alt+L** (Windows/Linux) to manually reformat your code in IntelliJ IDEA. +See [Reformat code](https://www.jetbrains.com/help/idea/reformat-and-rearrange-code.html). + +Note: The code formatter does not remove unused imports by default. You should +enable [Optimise on save](https://www.jetbrains.com/help/idea/creating-and-optimizing-imports.html#optimize-on-save) in +your IntelliJ IDEA settings to ensure you do not commit unused imports. + # Build IntelliJ will automatically build your code as needed. To build using Gradle, follow the instructions below. @@ -97,15 +112,6 @@ To build Docker images locally, run: ./gradlew jibDockerBuild ``` -## Code formatting -Kotlin code is formatted using IntelliJ IDEA's code formatter, -which follows the [Kotlin Coding Conventions](https://kotlinlang.org/docs/coding-conventions.html). - -GitHub Actions will automatically fix any formatting issues when you open a pull request. -You can also use ⌘⌥**L** (macOS), -or **Ctrl+Alt+L** (Windows/Linux) to manually reformat your code in IntelliJ IDEA. -See [Reformat file](https://www.jetbrains.com/guide/java/tips/reformat-file/). - # Run ## IntelliJ In IntelliJ IDEA, a Spring Boot [run configuration](https://www.jetbrains.com/help/idea/run-debug-configuration.html) is From bc559ecc9f551f130cd07ec7aec3e1265b747fb9 Mon Sep 17 00:00:00 2001 From: Marcus Aspin Date: Wed, 20 Nov 2024 15:47:15 +0000 Subject: [PATCH 24/26] PI-2564 Copy API endpoints from CVL (#4452) --- .../build.gradle.kts | 3 + .../deploy/values-dev.yml | 2 - .../deploy/values-preprod.yml | 2 - .../deploy/values.yaml | 3 + .../justice/digital/hmpps/data/DataLoader.kt | 73 +++++++- .../hmpps/data/generator/CaseloadGenerator.kt | 111 +++++++++++ .../hmpps/data/generator/PersonGenerator.kt | 31 +++ .../hmpps/data/generator/ProviderGenerator.kt | 141 ++++++++++++++ .../hmpps/data/generator/StaffGenerator.kt | 30 +++ .../src/dev/resources/schema.ldif | 25 +++ .../digital/hmpps/CaseloadIntegrationTest.kt | 70 +++++++ .../justice/digital/hmpps/IntegrationTest.kt | 176 +++++++++++++++++- .../uk/gov/justice/digital/hmpps/App.kt | 3 +- .../hmpps/api/model/ManagedOffender.kt | 11 ++ .../digital/hmpps/api/model/Manager.kt | 30 +++ .../digital/hmpps/api/model/OfficeAddress.kt | 56 ++++++ .../justice/digital/hmpps/api/model/Staff.kt | 30 +++ .../api/resource/ProbationCaseResource.kt | 19 ++ .../hmpps/api/resource/StaffResource.kt | 33 ++++ .../hmpps/api/resource/TeamResource.kt | 18 ++ .../digital/hmpps/controller/ApiController.kt | 17 -- .../justice/digital/hmpps/entity/Caseload.kt | 47 +++++ .../justice/digital/hmpps/entity/LdapUser.kt | 23 +++ .../justice/digital/hmpps/entity/Person.kt | 25 +++ .../digital/hmpps/entity/PersonManager.kt | 52 ++++++ .../justice/digital/hmpps/entity/Provider.kt | 160 ++++++++++++++++ .../gov/justice/digital/hmpps/entity/Staff.kt | 80 ++++++++ .../digital/hmpps/service/ManagerService.kt | 86 +++++++++ .../digital/hmpps/service/StaffService.kt | 81 ++++++++ .../digital/hmpps/service/TeamService.kt | 19 ++ .../src/main/resources/application.yml | 9 +- .../hmpps/api/resource/StaffResourceTest.kt | 31 +++ .../hmpps/api/resource/TeamResourceTest.kt | 33 ++++ .../service/ResponsibleManagerServiceTest.kt | 44 +++++ .../digital/hmpps/service/StaffServiceTest.kt | 43 +++++ .../digital/hmpps/service/TeamServiceTest.kt | 31 +++ 36 files changed, 1615 insertions(+), 33 deletions(-) create mode 100644 projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/CaseloadGenerator.kt create mode 100644 projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/PersonGenerator.kt create mode 100644 projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ProviderGenerator.kt create mode 100644 projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/StaffGenerator.kt create mode 100644 projects/assess-for-early-release-and-delius/src/dev/resources/schema.ldif create mode 100644 projects/assess-for-early-release-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/CaseloadIntegrationTest.kt create mode 100644 projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/ManagedOffender.kt create mode 100644 projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/Manager.kt create mode 100644 projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/OfficeAddress.kt create mode 100644 projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/Staff.kt create mode 100644 projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/resource/ProbationCaseResource.kt create mode 100644 projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/resource/StaffResource.kt create mode 100644 projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/resource/TeamResource.kt delete mode 100644 projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/controller/ApiController.kt create mode 100644 projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/Caseload.kt create mode 100644 projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/LdapUser.kt create mode 100644 projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/Person.kt create mode 100644 projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/PersonManager.kt create mode 100644 projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/Provider.kt create mode 100644 projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/Staff.kt create mode 100644 projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/ManagerService.kt create mode 100644 projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/StaffService.kt create mode 100644 projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/TeamService.kt create mode 100644 projects/assess-for-early-release-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/api/resource/StaffResourceTest.kt create mode 100644 projects/assess-for-early-release-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/api/resource/TeamResourceTest.kt create mode 100644 projects/assess-for-early-release-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/ResponsibleManagerServiceTest.kt create mode 100644 projects/assess-for-early-release-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/StaffServiceTest.kt create mode 100644 projects/assess-for-early-release-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/TeamServiceTest.kt diff --git a/projects/assess-for-early-release-and-delius/build.gradle.kts b/projects/assess-for-early-release-and-delius/build.gradle.kts index a089a2f210..b7a0ac1c3d 100644 --- a/projects/assess-for-early-release-and-delius/build.gradle.kts +++ b/projects/assess-for-early-release-and-delius/build.gradle.kts @@ -12,12 +12,14 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-security") implementation("org.springframework.boot:spring-boot-starter-validation") implementation("org.springframework.boot:spring-boot-starter-web") + implementation("org.springframework.boot:spring-boot-starter-data-ldap") implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") implementation("com.fasterxml.jackson.module:jackson-module-kotlin") implementation(libs.springdoc) dev(project(":libs:dev-tools")) + dev("com.unboundid:unboundid-ldapsdk") dev("com.h2database:h2") dev("org.testcontainers:oracle-xe") @@ -31,6 +33,7 @@ configure { jacocoExclusions = listOf( "**/config/**", "**/entity/**", + "**/ldap/**", "**/AppKt.class" ) } diff --git a/projects/assess-for-early-release-and-delius/deploy/values-dev.yml b/projects/assess-for-early-release-and-delius/deploy/values-dev.yml index 41baa373a1..1996330d35 100644 --- a/projects/assess-for-early-release-and-delius/deploy/values-dev.yml +++ b/projects/assess-for-early-release-and-delius/deploy/values-dev.yml @@ -1,5 +1,3 @@ -enabled: false # TODO set this to true when you're ready to deploy your service - generic-service: ingress: host: assess-for-early-release-and-delius-dev.hmpps.service.justice.gov.uk diff --git a/projects/assess-for-early-release-and-delius/deploy/values-preprod.yml b/projects/assess-for-early-release-and-delius/deploy/values-preprod.yml index 23a555dccd..aa341f8d1c 100644 --- a/projects/assess-for-early-release-and-delius/deploy/values-preprod.yml +++ b/projects/assess-for-early-release-and-delius/deploy/values-preprod.yml @@ -1,5 +1,3 @@ -enabled: false # TODO set this to true when you're ready to deploy your service - generic-service: ingress: host: assess-for-early-release-and-delius-preprod.hmpps.service.justice.gov.uk diff --git a/projects/assess-for-early-release-and-delius/deploy/values.yaml b/projects/assess-for-early-release-and-delius/deploy/values.yaml index 9170a7faa4..a47d12cc30 100644 --- a/projects/assess-for-early-release-and-delius/deploy/values.yaml +++ b/projects/assess-for-early-release-and-delius/deploy/values.yaml @@ -12,6 +12,9 @@ generic-service: namespace_secrets: common: SPRING_DATASOURCE_URL: DB_URL + SPRING_LDAP_URLS: LDAP_URL + SPRING_LDAP_USERNAME: LDAP_USERNAME + SPRING_LDAP_PASSWORD: LDAP_PASSWORD assess-for-early-release-and-delius-database: SPRING_DATASOURCE_USERNAME: DB_USERNAME SPRING_DATASOURCE_PASSWORD: DB_PASSWORD diff --git a/projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt b/projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt index f6ea94c9a7..df093edc47 100644 --- a/projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt +++ b/projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt @@ -1,17 +1,20 @@ package uk.gov.justice.digital.hmpps.data import jakarta.annotation.PostConstruct +import jakarta.persistence.EntityManager import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty import org.springframework.boot.context.event.ApplicationReadyEvent import org.springframework.context.ApplicationListener import org.springframework.stereotype.Component -import uk.gov.justice.digital.hmpps.data.generator.UserGenerator +import org.springframework.transaction.annotation.Transactional +import uk.gov.justice.digital.hmpps.data.generator.* import uk.gov.justice.digital.hmpps.user.AuditUserRepository @Component @ConditionalOnProperty("seed.database") class DataLoader( - private val auditUserRepository: AuditUserRepository + private val auditUserRepository: AuditUserRepository, + private val entityManager: EntityManager ) : ApplicationListener { @PostConstruct @@ -19,7 +22,71 @@ class DataLoader( auditUserRepository.save(UserGenerator.AUDIT_USER) } + @Transactional override fun onApplicationEvent(are: ApplicationReadyEvent) { - // Perform dev/test database setup here, using JPA repositories and generator classes... + entityManager.persist(ProviderGenerator.DEFAULT_PROVIDER) + entityManager.persist(StaffGenerator.PDUHEAD) + entityManager.persist(StaffGenerator.DEFAULT_PDUSTAFF_USER) + entityManager.persist(ProviderGenerator.DEFAULT_BOROUGH) + entityManager.persist(ProviderGenerator.DEFAULT_DISTRICT) + + createOfficeLocationsAndDistricts() + + entityManager.persist(ProviderGenerator.DEFAULT_TEAM) + entityManager.persist(ProviderGenerator.TEAM_ENDED_OR_NULL_LOCATIONS) + + StaffGenerator.DEFAULT = StaffGenerator.generateStaff( + StaffGenerator.DEFAULT.code, + StaffGenerator.DEFAULT.forename, + StaffGenerator.DEFAULT.surname, + listOf(ProviderGenerator.DEFAULT_TEAM), + ProviderGenerator.DEFAULT_PROVIDER, + StaffGenerator.DEFAULT.middleName, + StaffGenerator.DEFAULT.user, + StaffGenerator.DEFAULT.id + ) + entityManager.persist(StaffGenerator.DEFAULT) + + entityManager.persist(StaffGenerator.DEFAULT_STAFF_USER) + entityManager.flush() + + entityManager.persist(PersonGenerator.DEFAULT_PERSON) + entityManager.persist(PersonGenerator.PERSON_ENDED_TEAM_LOCATION) + entityManager.persist(PersonGenerator.DEFAULT_CM) + entityManager.persist(PersonGenerator.CM_ENDED_TEAM_LOCATION) + + val person = PersonGenerator.generatePerson("N123456").also(entityManager::persist) + PersonGenerator.generateManager(person).also(entityManager::persist) + + createCaseloadData() + } + + private fun createOfficeLocationsAndDistricts() { + entityManager.persistAll( + ProviderGenerator.DISTRICT_BRK, + ProviderGenerator.DISTRICT_MKY, + ProviderGenerator.DISTRICT_OXF, + ProviderGenerator.LOCATION_BRK_1, + ProviderGenerator.LOCATION_BRK_2, + ProviderGenerator.LOCATION_ENDED, + ProviderGenerator.LOCATION_NULL + ) + } + + private fun createCaseloadData() { + entityManager.persistAll( + CaseloadGenerator.TEAM1, + CaseloadGenerator.STAFF1, + CaseloadGenerator.STAFF2, + CaseloadGenerator.CASELOAD_ROLE_OM_1, + CaseloadGenerator.CASELOAD_ROLE_OM_2, + CaseloadGenerator.CASELOAD_ROLE_OM_3, + CaseloadGenerator.CASELOAD_ROLE_OM_4, + CaseloadGenerator.CASELOAD_ROLE_OS_1 + ) + } + + private fun EntityManager.persistAll(vararg entities: Any) { + entities.forEach { persist(it) } } } diff --git a/projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/CaseloadGenerator.kt b/projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/CaseloadGenerator.kt new file mode 100644 index 0000000000..7fcf7c9bce --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/CaseloadGenerator.kt @@ -0,0 +1,111 @@ +package uk.gov.justice.digital.hmpps.data.generator + +import uk.gov.justice.digital.hmpps.api.model.ManagedOffender +import uk.gov.justice.digital.hmpps.api.model.Name +import uk.gov.justice.digital.hmpps.data.generator.ProviderGenerator.DEFAULT_TEAM +import uk.gov.justice.digital.hmpps.entity.Caseload +import uk.gov.justice.digital.hmpps.entity.Staff +import uk.gov.justice.digital.hmpps.entity.Team +import uk.gov.justice.digital.hmpps.service.asStaff +import uk.gov.justice.digital.hmpps.service.asTeam +import java.time.LocalDate + +object CaseloadGenerator { + + val STAFF1 = StaffGenerator.generateStaff("STCDE01", "Bob", "Smith") + val STAFF2 = StaffGenerator.generateStaff("STCDE02", "Joe", "Bloggs") + + val TEAM1 = ProviderGenerator.generateTeam("N02BDT") + + val CASELOAD_ROLE_OM_1 = generateCaseload( + staff = STAFF1, + team = DEFAULT_TEAM, + crn = "crn0001", + firstName = "John", + secondName = "x", + surname = "Brown", + allocationDate = LocalDate.of(2024, 1, 8), + roleCode = Caseload.CaseloadRole.OFFENDER_MANAGER.value + ) + + val CASELOAD_ROLE_OM_2 = generateCaseload( + staff = STAFF1, + team = DEFAULT_TEAM, + crn = "crn0022", + firstName = "Jane", + secondName = "y", + surname = "Doe", + allocationDate = LocalDate.of(2024, 1, 9), + roleCode = Caseload.CaseloadRole.OFFENDER_MANAGER.value + ) + + val CASELOAD_ROLE_OM_3 = generateCaseload( + staff = STAFF2, + team = DEFAULT_TEAM, + crn = "crn0077", + firstName = "Ano", + secondName = "no", + surname = "mys", + allocationDate = LocalDate.of(2024, 1, 10), + roleCode = Caseload.CaseloadRole.OFFENDER_MANAGER.value + ) + + val CASELOAD_ROLE_OM_4 = generateCaseload( + staff = STAFF2, + team = TEAM1, + crn = "crn0078", + firstName = "Joe", + secondName = "Denis", + surname = "Doe", + allocationDate = LocalDate.of(2024, 1, 10), + roleCode = Caseload.CaseloadRole.OFFENDER_MANAGER.value + ) + + val CASELOAD_ROLE_OS_1 = generateCaseload( + staff = STAFF2, + team = DEFAULT_TEAM, + crn = "crn0088", + firstName = "Robert", + secondName = "Alan", + surname = "Brown", + roleCode = Caseload.CaseloadRole.ORDER_SUPERVISOR.value + ) + + val MANAGED_OFFENDER = generateManagedOffender(CASELOAD_ROLE_OM_1, STAFF1, DEFAULT_TEAM) + + fun generateCaseload( + staff: Staff, + team: Team, + allocationDate: LocalDate? = LocalDate.now(), + roleCode: String, + crn: String, + firstName: String, + secondName: String?, + surname: String, + startDate: LocalDate? = LocalDate.now(), + id: Long = IdGenerator.getAndIncrement() + ) = Caseload( + staff, + team, + allocationDate, + roleCode, + crn, + firstName, + secondName, + surname, + startDate, + id + ) + + fun generateManagedOffender( + caseload: Caseload, + staff: Staff, + team: Team + ) = ManagedOffender( + caseload.crn, + Name(caseload.firstName, caseload.secondName, caseload.surname), + caseload.allocationDate, + staff.asStaff(), + team.asTeam() + ) +} diff --git a/projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/PersonGenerator.kt b/projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/PersonGenerator.kt new file mode 100644 index 0000000000..c0f8fb2405 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/PersonGenerator.kt @@ -0,0 +1,31 @@ +package uk.gov.justice.digital.hmpps.data.generator + +import uk.gov.justice.digital.hmpps.entity.* + +object PersonGenerator { + val DEFAULT_PERSON = generatePerson("T123456") + val PERSON_ENDED_TEAM_LOCATION = generatePerson("T123457") + val DEFAULT_CM = generateManager(DEFAULT_PERSON) + val CM_ENDED_TEAM_LOCATION = + generateManager(person = PERSON_ENDED_TEAM_LOCATION, team = ProviderGenerator.TEAM_ENDED_OR_NULL_LOCATIONS) + + fun generatePerson( + crn: String, + softDeleted: Boolean = false, + id: Long = IdGenerator.getAndIncrement() + ) = Person( + crn, + softDeleted, + id + ) + + fun generateManager( + person: Person, + provider: Provider = ProviderGenerator.DEFAULT_PROVIDER, + team: Team = ProviderGenerator.DEFAULT_TEAM, + staff: Staff = StaffGenerator.DEFAULT, + softDeleted: Boolean = false, + active: Boolean = true, + id: Long = IdGenerator.getAndIncrement() + ) = PersonManager(person, provider, team, staff, softDeleted, active, id) +} diff --git a/projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ProviderGenerator.kt b/projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ProviderGenerator.kt new file mode 100644 index 0000000000..a0e2885da0 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ProviderGenerator.kt @@ -0,0 +1,141 @@ +package uk.gov.justice.digital.hmpps.data.generator + +import java.time.LocalDate + +object ProviderGenerator { + val DEFAULT_PROVIDER = generateProvider("N01") + val DEFAULT_BOROUGH = generateBorough("N01B") + val DEFAULT_DISTRICT = generateDistrict("N01D") + val DISTRICT_BRK = generateDistrict("TVP_BRK", "Berkshire") + val DISTRICT_OXF = generateDistrict("TVP_OXF", "Oxfordshire") + val DISTRICT_MKY = generateDistrict("TVP_MKY", "Milton Keynes") + + val LOCATION_BRK_1 = generateLocation( + code = "TVP_BRK", + description = "Bracknell Office", + buildingNumber = "21", + streetName = "Some Place", + district = "District 1", + town = "Hearth", + postcode = "H34 7TH", + ldu = DISTRICT_BRK + ) + + val LOCATION_BRK_2 = generateLocation( + code = "TVP_RCC", + description = "Reading Office", + buildingNumber = "23", + buildingName = "The old hall", + streetName = "Another Place", + district = "District 2", + town = "Reading", + postcode = "RG1 3EH", + ldu = DISTRICT_BRK + ) + val LOCATION_ENDED = generateLocation( + code = "TVP_RCC", + description = "Reading Office", + buildingNumber = "23", + buildingName = "The old hall", + streetName = "Another Place", + district = "District 2", + town = "Reading", + postcode = "RG1 3EH", + endDate = LocalDate.now().minusDays(1), + ldu = DISTRICT_BRK + ) + + val LOCATION_NULL = generateLocation( + code = "TVP_RCC", + description = "Null office", + ldu = DEFAULT_DISTRICT + ) + + val DEFAULT_TEAM = generateTeam("N01BDT") + + val TEAM_ENDED_OR_NULL_LOCATIONS = generateTeam( + addresses = listOf( + LOCATION_BRK_1, + LOCATION_BRK_2, + LOCATION_ENDED, + LOCATION_NULL + ), code = "N01BDT" + ) + + fun generateProvider( + code: String, + description: String = "Description of $code", + id: Long = IdGenerator.getAndIncrement(), + endDate: LocalDate? = null + ) = uk.gov.justice.digital.hmpps.entity.Provider(code, description, id, endDate) + + fun generateBorough( + code: String, + description: String = "Description of $code", + id: Long = IdGenerator.getAndIncrement(), + ) = uk.gov.justice.digital.hmpps.entity.Borough(code, description, id, listOf(), DEFAULT_PROVIDER) + + fun generateDistrict( + code: String, + description: String = "Description of $code", + borough: uk.gov.justice.digital.hmpps.entity.Borough = DEFAULT_BOROUGH, + id: Long = IdGenerator.getAndIncrement() + ) = uk.gov.justice.digital.hmpps.entity.District(code, description, borough, id) + + fun generateTeam( + code: String, + description: String = "Description of $code", + telephone: String? = "12345", + emailAddress: String? = "testemail", + district: uk.gov.justice.digital.hmpps.entity.District = DEFAULT_DISTRICT, + addresses: List = listOf( + LOCATION_BRK_1, + LOCATION_BRK_2 + ), + startDate: LocalDate = LocalDate.now(), + endDate: LocalDate? = null, + id: Long = IdGenerator.getAndIncrement() + ) = uk.gov.justice.digital.hmpps.entity.Team( + code, + description, + telephone, + emailAddress, + district, + addresses, + startDate, + endDate, + id + ) + + fun generateLocation( + code: String, + description: String, + buildingName: String? = null, + buildingNumber: String? = null, + streetName: String? = null, + district: String? = null, + town: String? = null, + county: String? = null, + postcode: String? = null, + telephoneNumber: String? = null, + startDate: LocalDate = LocalDate.now(), + endDate: LocalDate? = null, + ldu: uk.gov.justice.digital.hmpps.entity.District, + id: Long = IdGenerator.getAndIncrement() + ) = uk.gov.justice.digital.hmpps.entity.OfficeLocation( + code, + description, + buildingName, + buildingNumber, + streetName, + district, + town, + county, + postcode, + telephoneNumber, + startDate, + endDate, + ldu, + id + ) +} diff --git a/projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/StaffGenerator.kt b/projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/StaffGenerator.kt new file mode 100644 index 0000000000..5f0a533eb3 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/StaffGenerator.kt @@ -0,0 +1,30 @@ +package uk.gov.justice.digital.hmpps.data.generator + +import uk.gov.justice.digital.hmpps.data.generator.ProviderGenerator.DEFAULT_BOROUGH +import uk.gov.justice.digital.hmpps.data.generator.ProviderGenerator.DEFAULT_PROVIDER +import uk.gov.justice.digital.hmpps.entity.* +import uk.gov.justice.digital.hmpps.set + +object StaffGenerator { + val PDUHEAD = generateStaff("N01BDT2", "Bob", "Smith").also { DEFAULT_BOROUGH.set(Borough::pduHeads, listOf(it)) } + val DEFAULT_PDUSTAFF_USER = generateStaffUser("bob-smith", PDUHEAD) + var DEFAULT = generateStaff("N01BDT1", "John", "Smith", teams = listOf(ProviderGenerator.DEFAULT_TEAM)) + val DEFAULT_STAFF_USER = generateStaffUser("john-smith", DEFAULT) + + fun generateStaff( + code: String, + forename: String, + surname: String, + teams: List = listOf(), + provider: Provider = DEFAULT_PROVIDER, + middleName: String? = null, + user: StaffUser? = null, + id: Long = IdGenerator.getAndIncrement() + ) = Staff(code, forename, surname, middleName, user, id, teams, provider).apply { user?.set("staff", this) } + + fun generateStaffUser( + username: String, + staff: Staff? = null, + id: Long = IdGenerator.getAndIncrement() + ) = StaffUser(staff, username, id).apply { staff?.set("user", this) } +} diff --git a/projects/assess-for-early-release-and-delius/src/dev/resources/schema.ldif b/projects/assess-for-early-release-and-delius/src/dev/resources/schema.ldif new file mode 100644 index 0000000000..9528a41c52 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/dev/resources/schema.ldif @@ -0,0 +1,25 @@ +dn: ou=Users,dc=moj,dc=com +objectclass: top +objectclass: organizationalUnit +ou: Users + +dn: cn=john-smith,ou=Users,dc=moj,dc=com +objectclass: top +objectclass: inetOrgPerson +cn: john-smith +sn: Staff +mail: john.smith@moj.gov.uk +telephoneNumber: 10101010101 + +dn: cn=bob-smith,ou=Users,dc=moj,dc=com +objectclass: top +objectclass: inetOrgPerson +cn: bob-smith +sn: Staff +mail: bob.smith@moj.gov.uk +telephoneNumber: 20202020202 + +dn: cn=ndRoleCatalogue,ou=Users,dc=moj,dc=com +description: Role Catalogue +objectclass: top +cn: ndRoleCatalogue \ No newline at end of file diff --git a/projects/assess-for-early-release-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/CaseloadIntegrationTest.kt b/projects/assess-for-early-release-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/CaseloadIntegrationTest.kt new file mode 100644 index 0000000000..b8623570ac --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/CaseloadIntegrationTest.kt @@ -0,0 +1,70 @@ +package uk.gov.justice.digital.hmpps + +import org.hamcrest.MatcherAssert.assertThat +import org.hamcrest.Matchers.equalTo +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.Arguments +import org.junit.jupiter.params.provider.MethodSource +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.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get +import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status +import uk.gov.justice.digital.hmpps.api.model.ManagedOffender +import uk.gov.justice.digital.hmpps.data.generator.CaseloadGenerator.CASELOAD_ROLE_OM_1 +import uk.gov.justice.digital.hmpps.data.generator.CaseloadGenerator.CASELOAD_ROLE_OM_2 +import uk.gov.justice.digital.hmpps.data.generator.CaseloadGenerator.CASELOAD_ROLE_OM_3 +import uk.gov.justice.digital.hmpps.data.generator.CaseloadGenerator.CASELOAD_ROLE_OM_4 +import uk.gov.justice.digital.hmpps.data.generator.CaseloadGenerator.STAFF1 +import uk.gov.justice.digital.hmpps.data.generator.CaseloadGenerator.STAFF2 +import uk.gov.justice.digital.hmpps.data.generator.CaseloadGenerator.TEAM1 +import uk.gov.justice.digital.hmpps.data.generator.CaseloadGenerator.generateManagedOffender +import uk.gov.justice.digital.hmpps.data.generator.ProviderGenerator.DEFAULT_TEAM +import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.contentAsJson +import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withToken + +@AutoConfigureMockMvc +@SpringBootTest(webEnvironment = RANDOM_PORT) +internal class CaseloadIntegrationTest { + @Autowired + lateinit var mockMvc: MockMvc + + @ParameterizedTest + @MethodSource("caseloadArgs") + fun getManagedOffenders(url: String, expected: List?) { + val res = mockMvc.perform(get(url).withToken()).andExpect(status().isOk) + .andReturn().response.contentAsJson>() + assertThat(res, equalTo(expected)) + } + + companion object { + @JvmStatic + fun caseloadArgs(): List = listOf( + Arguments.of("/staff/STCDEXX/caseload/managed-offenders", listOf()), Arguments.of( + "/staff/STCDE01/caseload/managed-offenders", listOf( + generateManagedOffender(CASELOAD_ROLE_OM_1, STAFF1, DEFAULT_TEAM), + generateManagedOffender(CASELOAD_ROLE_OM_2, STAFF1, DEFAULT_TEAM) + ) + ), Arguments.of( + "/staff/STCDE02/caseload/managed-offenders", listOf( + generateManagedOffender(CASELOAD_ROLE_OM_3, STAFF2, DEFAULT_TEAM), + generateManagedOffender(CASELOAD_ROLE_OM_4, STAFF2, TEAM1) + ) + ), Arguments.of( + "/team/N01BDT/caseload/managed-offenders", listOf( + generateManagedOffender(CASELOAD_ROLE_OM_3, STAFF2, DEFAULT_TEAM), + generateManagedOffender(CASELOAD_ROLE_OM_2, STAFF1, DEFAULT_TEAM), + generateManagedOffender(CASELOAD_ROLE_OM_1, STAFF1, DEFAULT_TEAM) + ) + ), Arguments.of( + "/team/N02BDT/caseload/managed-offenders", listOf( + generateManagedOffender(CASELOAD_ROLE_OM_4, STAFF2, TEAM1) + ) + ), Arguments.of( + "/team/N03BDT/caseload/managed-offenders", listOf() + ) + ) + } +} diff --git a/projects/assess-for-early-release-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/IntegrationTest.kt b/projects/assess-for-early-release-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/IntegrationTest.kt index d9006c74c5..e7110210d7 100644 --- a/projects/assess-for-early-release-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/IntegrationTest.kt +++ b/projects/assess-for-early-release-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/IntegrationTest.kt @@ -1,16 +1,32 @@ package uk.gov.justice.digital.hmpps +import org.hamcrest.MatcherAssert.assertThat +import org.hamcrest.Matchers.equalTo 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.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT -import org.springframework.boot.test.mock.mockito.MockBean import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post +import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status +import uk.gov.justice.digital.hmpps.api.model.Manager +import uk.gov.justice.digital.hmpps.api.model.OfficeAddress +import uk.gov.justice.digital.hmpps.api.model.PDUHead +import uk.gov.justice.digital.hmpps.api.model.StaffName +import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator +import uk.gov.justice.digital.hmpps.data.generator.ProviderGenerator +import uk.gov.justice.digital.hmpps.data.generator.StaffGenerator +import uk.gov.justice.digital.hmpps.entity.asAddress +import uk.gov.justice.digital.hmpps.service.asManager +import uk.gov.justice.digital.hmpps.service.asPDUHead +import uk.gov.justice.digital.hmpps.service.asStaffName +import uk.gov.justice.digital.hmpps.service.asTeam +import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.contentAsJson +import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withJson import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withToken -import uk.gov.justice.digital.hmpps.telemetry.TelemetryService @AutoConfigureMockMvc @SpringBootTest(webEnvironment = RANDOM_PORT) @@ -18,13 +34,159 @@ internal class IntegrationTest { @Autowired lateinit var mockMvc: MockMvc - @MockBean - lateinit var telemetryService: TelemetryService + @Test + fun `returns responsible officer details`() { + val crn = PersonGenerator.DEFAULT_PERSON.crn + + val manager = mockMvc + .perform(get("/probation-case/$crn/responsible-community-manager").withToken()) + .andExpect(status().isOk) + .andReturn().response.contentAsJson() + + + assertThat( + manager, + equalTo( + PersonGenerator.DEFAULT_CM.asManager().copy( + username = "john-smith", email = "john.smith@moj.gov.uk" + ) + ) + ) + } + + @Test + fun `returns responsible officer details for a list of CRNs`() { + val crn = PersonGenerator.DEFAULT_PERSON.crn + mockMvc + .perform(post("/probation-case/responsible-community-manager").withToken().withJson(listOf(crn))) + .andExpect(status().isOk) + .andExpect(jsonPath("size()", equalTo(1))) + .andExpect(jsonPath("$[0].code", equalTo("N01BDT1"))) + .andExpect(jsonPath("$[0].email", equalTo("john.smith@moj.gov.uk"))) + } + + @Test + fun `returns only active and non null team office locations`() { + val crn = PersonGenerator.PERSON_ENDED_TEAM_LOCATION.crn + val expectedAddresses: List = listOf( + ProviderGenerator.LOCATION_BRK_1.asAddress(), + ProviderGenerator.LOCATION_BRK_2.asAddress() + ) + val manager = mockMvc + .perform(get("/probation-case/$crn/responsible-community-manager").withToken()) + .andExpect(status().isOk) + .andReturn().response.contentAsJson() + assertThat( + manager, + equalTo( + PersonGenerator.CM_ENDED_TEAM_LOCATION.asManager().copy( + username = "john-smith", email = "john.smith@moj.gov.uk", + team = ProviderGenerator.TEAM_ENDED_OR_NULL_LOCATIONS.asTeam().copy(addresses = expectedAddresses) + ) + ) + ) + } + + @Test + fun `returns 404 if no crn or community officer`() { + mockMvc.perform( + get("/probation-case/Z123456/responsible-community-manager") + .withToken() + ).andExpect(status().isNotFound) + } + + @Test + fun `returns staff details`() { + val username = StaffGenerator.DEFAULT_STAFF_USER.username + mockMvc + .perform(get("/staff/$username").withToken()) + .andExpect(status().isOk) + .andExpect(jsonPath("$.username", equalTo("john-smith"))) + .andExpect(jsonPath("$.email", equalTo("john.smith@moj.gov.uk"))) + .andExpect(jsonPath("$.telephoneNumber", equalTo("10101010101"))) + } + + @Test + fun `username is case-insensitive`() { + val username = StaffGenerator.DEFAULT_STAFF_USER.username.uppercase() + mockMvc + .perform(get("/staff/$username").withToken()) + .andExpect(status().isOk) + .andExpect(jsonPath("$.username", equalTo("john-smith"))) + .andExpect(jsonPath("$.email", equalTo("john.smith@moj.gov.uk"))) + .andExpect(jsonPath("$.telephoneNumber", equalTo("10101010101"))) + } + + @Test + fun `returns pdu heads`() { + val boroughCode = ProviderGenerator.DEFAULT_BOROUGH.code + + val pduHeads = mockMvc + .perform(get("/staff/$boroughCode/pdu-head").withToken()) + .andExpect(status().isOk) + .andReturn().response.contentAsJson>() + + assertThat( + pduHeads, + equalTo( + listOf( + StaffGenerator.PDUHEAD.asPDUHead().copy(email = "bob.smith@moj.gov.uk") + ) + ) + ) + } + + @Test + fun `returns staff names for usernames`() { + val usernames = + listOf(StaffGenerator.DEFAULT_PDUSTAFF_USER.username, StaffGenerator.DEFAULT_STAFF_USER.username) + + val staffNames = mockMvc + .perform(post("/staff").withToken().withJson(usernames)) + .andExpect(status().isOk) + .andReturn().response.contentAsJson>() + + assertThat( + staffNames, + equalTo( + listOf( + StaffGenerator.PDUHEAD.asStaffName(), + StaffGenerator.DEFAULT.asStaffName() + ) + ) + ) + } + + @Test + fun `usernames are case-insensitive`() { + val usernames = listOf( + StaffGenerator.DEFAULT_PDUSTAFF_USER.username.uppercase(), + StaffGenerator.DEFAULT_STAFF_USER.username.uppercase() + ) + + val staffNames = mockMvc + .perform(post("/staff").withToken().withJson(usernames)) + .andExpect(status().isOk) + .andReturn().response.contentAsJson>() + + assertThat( + staffNames, + equalTo( + listOf( + StaffGenerator.PDUHEAD.asStaffName(), + StaffGenerator.DEFAULT.asStaffName() + ) + ) + ) + } @Test - fun `API call retuns a success response`() { + fun `returns staff by code`() { mockMvc - .perform(get("/example/123").withToken()) - .andExpect(status().is2xxSuccessful) + .perform(get("/staff/bycode/${StaffGenerator.DEFAULT.code}").withToken()) + .andExpect(status().isOk) + .andExpect(jsonPath("$.username", equalTo("john-smith"))) + .andExpect(jsonPath("$.email", equalTo("john.smith@moj.gov.uk"))) + .andExpect(jsonPath("$.telephoneNumber", equalTo("10101010101"))) } } diff --git a/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/App.kt b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/App.kt index c7faac5b26..2c6b3789ed 100644 --- a/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/App.kt +++ b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/App.kt @@ -1,9 +1,10 @@ package uk.gov.justice.digital.hmpps import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration import org.springframework.boot.runApplication -@SpringBootApplication +@SpringBootApplication(exclude = [LdapRepositoriesAutoConfiguration::class]) class App fun main(args: Array) { diff --git a/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/ManagedOffender.kt b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/ManagedOffender.kt new file mode 100644 index 0000000000..f3f02c708b --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/ManagedOffender.kt @@ -0,0 +1,11 @@ +package uk.gov.justice.digital.hmpps.api.model + +import java.time.LocalDate + +data class ManagedOffender( + val crn: String, + val name: Name, + val allocationDate: LocalDate?, + val staff: Staff, + val team: Team? +) diff --git a/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/Manager.kt b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/Manager.kt new file mode 100644 index 0000000000..ce92154082 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/Manager.kt @@ -0,0 +1,30 @@ +package uk.gov.justice.digital.hmpps.api.model + +import java.time.LocalDate + +data class Manager( + val id: Long, + val code: String, + val name: Name, + val provider: Provider, + val team: Team, + val username: String?, + val email: String?, + val unallocated: Boolean +) + +data class Name(val forename: String, val middleName: String?, val surname: String) +data class Provider(val code: String, val description: String) +data class Team( + val code: String, val description: String, + val telephone: String?, + val emailAddress: String?, + val addresses: List?, + val district: District, + val borough: Borough, + val startDate: LocalDate, + val endDate: LocalDate? +) + +data class District(val code: String, val description: String, val borough: Borough) +data class Borough(val code: String, val description: String) diff --git a/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/OfficeAddress.kt b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/OfficeAddress.kt new file mode 100644 index 0000000000..ad1bd42347 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/OfficeAddress.kt @@ -0,0 +1,56 @@ +package uk.gov.justice.digital.hmpps.api.model + +import java.time.LocalDate + +data class OfficeAddress( + val officeName: String, + val buildingName: String?, + val buildingNumber: String?, + val streetName: String?, + val district: String?, + val town: String?, + val county: String?, + val postcode: String?, + val ldu: String, + val telephoneNumber: String?, + val from: LocalDate, + val to: LocalDate? +) { + companion object { + fun from( + officeName: String, + buildingName: String?, + buildingNumber: String?, + streetName: String?, + district: String?, + town: String?, + county: String?, + postcode: String?, + ldu: String, + telephoneNumber: String?, + from: LocalDate, + to: LocalDate? + ): OfficeAddress? = + if ( + buildingName == null && buildingNumber == null && streetName == null && + district == null && town == null && county == null && postcode == null + ) { + null + } else { + OfficeAddress( + officeName, + buildingName, + buildingNumber, + streetName, + district, + town, + county, + postcode, + ldu, + telephoneNumber, + from, + to + ) + } + } +} diff --git a/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/Staff.kt b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/Staff.kt new file mode 100644 index 0000000000..686fa9f596 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/Staff.kt @@ -0,0 +1,30 @@ +package uk.gov.justice.digital.hmpps.api.model + +data class Staff( + val id: Long, + val code: String, + val name: Name, + val teams: List, + val provider: Provider, + val username: String?, + val email: String?, + val telephoneNumber: String?, + val unallocated: Boolean, +) + +data class PDUHead( + val name: Name, + val email: String? +) + +data class StaffName( + val id: Long, + val name: Name, + val code: String, + val username: String? +) + +data class StaffEmail( + val code: String, + val email: String? +) diff --git a/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/resource/ProbationCaseResource.kt b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/resource/ProbationCaseResource.kt new file mode 100644 index 0000000000..ae30bb218d --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/resource/ProbationCaseResource.kt @@ -0,0 +1,19 @@ +package uk.gov.justice.digital.hmpps.api.resource + +import org.springframework.security.access.prepost.PreAuthorize +import org.springframework.web.bind.annotation.* +import uk.gov.justice.digital.hmpps.api.model.Manager +import uk.gov.justice.digital.hmpps.api.model.StaffEmail +import uk.gov.justice.digital.hmpps.service.ManagerService + +@RestController +@RequestMapping("probation-case") +@PreAuthorize("hasRole('PROBATION_API__ASSESS_FOR_EARLY_RELEASE__CASE_DETAIL')") +class ProbationCaseResource(private val responsibleManagerService: ManagerService) { + @GetMapping("{crn}/responsible-community-manager") + fun findCommunityManager(@PathVariable crn: String): Manager = responsibleManagerService.findCommunityManager(crn) + + @PostMapping("/responsible-community-manager") + fun findCommunityManagerEmails(@RequestBody crns: List): List = + responsibleManagerService.findCommunityManagerEmails(crns) +} diff --git a/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/resource/StaffResource.kt b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/resource/StaffResource.kt new file mode 100644 index 0000000000..f46fdaaea5 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/resource/StaffResource.kt @@ -0,0 +1,33 @@ +package uk.gov.justice.digital.hmpps.api.resource + +import org.springframework.security.access.prepost.PreAuthorize +import org.springframework.web.bind.annotation.* +import uk.gov.justice.digital.hmpps.api.model.ManagedOffender +import uk.gov.justice.digital.hmpps.api.model.PDUHead +import uk.gov.justice.digital.hmpps.api.model.Staff +import uk.gov.justice.digital.hmpps.api.model.StaffName +import uk.gov.justice.digital.hmpps.service.StaffService + +@RestController +@RequestMapping("staff") +@PreAuthorize("hasRole('PROBATION_API__ASSESS_FOR_EARLY_RELEASE__CASE_DETAIL')") +class StaffResource( + private val staffService: StaffService +) { + @GetMapping("/{username}") + fun findStaff(@PathVariable username: String): Staff = staffService.findStaff(username) + + @GetMapping("/bycode/{code}") + fun findStaffByCode(@PathVariable code: String): Staff = staffService.findStaffByCode(code) + + @GetMapping("/{boroughCode}/pdu-head") + fun findPDUHead(@PathVariable boroughCode: String): List = staffService.findPDUHeads(boroughCode) + + @PostMapping + fun findStaffForUsernames(@RequestBody usernames: List): List = + staffService.findStaffForUsernames(usernames) + + @GetMapping("/{staffCode}/caseload/managed-offenders") + fun getManagedOffenders(@PathVariable staffCode: String): List = + staffService.getManagedOffenders(staffCode) +} diff --git a/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/resource/TeamResource.kt b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/resource/TeamResource.kt new file mode 100644 index 0000000000..bd43321bd3 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/resource/TeamResource.kt @@ -0,0 +1,18 @@ +package uk.gov.justice.digital.hmpps.api.resource + +import org.springframework.security.access.prepost.PreAuthorize +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController +import uk.gov.justice.digital.hmpps.api.model.ManagedOffender +import uk.gov.justice.digital.hmpps.service.TeamService + +@RestController +@RequestMapping("team") +@PreAuthorize("hasRole('PROBATION_API__ASSESS_FOR_EARLY_RELEASE__CASE_DETAIL')") +class TeamResource(private val teamService: TeamService) { + @GetMapping("/{teamCode}/caseload/managed-offenders") + fun getManagedOffendersByTeam(@PathVariable teamCode: String): List = + teamService.getManagedOffendersByTeam(teamCode) +} diff --git a/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/controller/ApiController.kt b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/controller/ApiController.kt deleted file mode 100644 index 6e4f24c46f..0000000000 --- a/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/controller/ApiController.kt +++ /dev/null @@ -1,17 +0,0 @@ -package uk.gov.justice.digital.hmpps.controller - -import org.springframework.security.access.prepost.PreAuthorize -import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.bind.annotation.PathVariable -import org.springframework.web.bind.annotation.RestController - -@RestController -class ApiController { - @PreAuthorize("hasRole('EXAMPLE')") - @GetMapping(value = ["/example/{inputId}"]) - fun handle( - @PathVariable("inputId") inputId: String - ) { - // TODO Not yet implemented - } -} diff --git a/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/Caseload.kt b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/Caseload.kt new file mode 100644 index 0000000000..09c38f951c --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/Caseload.kt @@ -0,0 +1,47 @@ +package uk.gov.justice.digital.hmpps.entity + +import jakarta.persistence.* +import org.hibernate.annotations.Immutable +import org.springframework.data.jpa.domain.support.AuditingEntityListener +import org.springframework.data.jpa.repository.JpaRepository +import java.time.LocalDate + +interface CaseloadRepository : JpaRepository { + fun findByStaffCodeAndRoleCode(staffCode: String, role: String): List + fun findByTeamCodeAndRoleCodeOrderByAllocationDateDesc(staffCode: String, role: String): List +} + +@Immutable +@EntityListeners(AuditingEntityListener::class) +@Entity +@Table(name = "caseload") +class Caseload( + + @ManyToOne + @JoinColumn(name = "staff_employee_id") + val staff: Staff, + + @ManyToOne + @JoinColumn(name = "trust_provider_team_id") + val team: Team, + + val allocationDate: LocalDate?, + val roleCode: String, + + @Column(columnDefinition = "char(7)") + val crn: String, + + val firstName: String, + val secondName: String?, + val surname: String, + val startDate: LocalDate?, + + @Id + val caseloadId: Long +) { + enum class CaseloadRole(val value: String) { + OFFENDER_MANAGER("OM"), + ORDER_SUPERVISOR("OS") + } +} + diff --git a/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/LdapUser.kt b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/LdapUser.kt new file mode 100644 index 0000000000..f19a3064b4 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/LdapUser.kt @@ -0,0 +1,23 @@ +package uk.gov.justice.digital.hmpps.entity + +import org.springframework.ldap.odm.annotations.Attribute +import org.springframework.ldap.odm.annotations.DnAttribute +import org.springframework.ldap.odm.annotations.Entry +import org.springframework.ldap.odm.annotations.Id +import javax.naming.Name + +@Entry(objectClasses = ["inetOrgPerson", "top"]) +class LdapUser( + @Id + val dn: Name, + + @Attribute(name = "cn") + @DnAttribute(value = "cn", index = 0) + val username: String, + + @Attribute(name = "mail") + val email: String?, + + @Attribute(name = "telephoneNumber") + val telephoneNumber: String? +) \ No newline at end of file diff --git a/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/Person.kt b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/Person.kt new file mode 100644 index 0000000000..e1cd658bc8 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/Person.kt @@ -0,0 +1,25 @@ +package uk.gov.justice.digital.hmpps.entity + +import jakarta.persistence.Column +import jakarta.persistence.Entity +import jakarta.persistence.Id +import jakarta.persistence.Table +import org.hibernate.annotations.Immutable +import org.hibernate.annotations.SQLRestriction + +@Immutable +@Entity +@Table(name = "offender") +@SQLRestriction("soft_deleted = 0") +class Person( + + @Column(columnDefinition = "char(7)") + val crn: String, + + @Column(name = "soft_deleted", columnDefinition = "number") + val softDeleted: Boolean = false, + + @Id + @Column(name = "offender_id") + val id: Long +) diff --git a/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/PersonManager.kt b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/PersonManager.kt new file mode 100644 index 0000000000..6b6ec03fa3 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/PersonManager.kt @@ -0,0 +1,52 @@ +package uk.gov.justice.digital.hmpps.entity + +import jakarta.persistence.* +import org.hibernate.annotations.Immutable +import org.hibernate.annotations.SQLRestriction +import org.springframework.data.jpa.repository.EntityGraph +import org.springframework.data.jpa.repository.JpaRepository +import uk.gov.justice.digital.hmpps.exception.NotFoundException + +@Immutable +@Entity +@Table(name = "offender_manager") +@SQLRestriction("soft_deleted = 0 and active_flag = 1") +class PersonManager( + + @ManyToOne + @JoinColumn(name = "offender_id") + val person: Person, + + @ManyToOne + @JoinColumn(name = "probation_area_id") + val provider: Provider, + + @ManyToOne + @JoinColumn(name = "team_id") + val team: Team, + + @ManyToOne + @JoinColumn(name = "allocation_staff_id") + val staff: Staff, + + @Column(name = "soft_deleted", columnDefinition = "number") + val softDeleted: Boolean = false, + + @Column(name = "active_flag", columnDefinition = "number") + val active: Boolean = true, + + @Id + @Column(name = "offender_manager_id") + val id: Long +) + +interface PersonManagerRepository : JpaRepository { + @EntityGraph(attributePaths = ["person", "provider", "team", "staff.user"]) + fun findByPersonCrn(crn: String): PersonManager? + + @EntityGraph(attributePaths = ["person", "staff.user"]) + fun findByPersonCrnIn(crn: List): List +} + +fun PersonManagerRepository.getByCrn(crn: String) = + findByPersonCrn(crn) ?: throw NotFoundException("Person", "crn", crn) diff --git a/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/Provider.kt b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/Provider.kt new file mode 100644 index 0000000000..898fed3843 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/Provider.kt @@ -0,0 +1,160 @@ +package uk.gov.justice.digital.hmpps.entity + +import jakarta.persistence.* +import org.hibernate.annotations.Immutable +import org.hibernate.annotations.SQLRestriction +import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.data.jpa.repository.Query +import uk.gov.justice.digital.hmpps.api.model.OfficeAddress +import java.time.LocalDate + +@Immutable +@Entity +@Table(name = "probation_area") +class Provider( + @Column(name = "code", columnDefinition = "char(3)") + val code: String, + + val description: String, + + @Id + @Column(name = "probation_area_id") + val id: Long, + + @Column(name = "end_date") + var endDate: LocalDate? = null +) + +@Immutable +@Entity +@Table(name = "team") +class Team( + + @Column(name = "code", columnDefinition = "char(6)") + val code: String, + + val description: String, + val telephone: String?, + val emailAddress: String?, + + @ManyToOne + @JoinColumn(name = "district_id") + val district: District, + + @ManyToMany + @JoinTable( + name = "team_office_location", + joinColumns = [JoinColumn(name = "team_id")], + inverseJoinColumns = [JoinColumn(name = "office_location_id")] + ) + @SQLRestriction("end_date is null or end_date > current_date") + val addresses: List, + + val startDate: LocalDate, + val endDate: LocalDate?, + + @Id + @Column(name = "team_id") + val id: Long +) + +@Immutable +@Entity +@Table(name = "district") +class District( + + @Column(name = "code") + val code: String, + + val description: String, + + @ManyToOne + @JoinColumn(name = "borough_id") + val borough: Borough, + + @Id + @Column(name = "district_id") + val id: Long +) + +@Immutable +@Entity +@Table(name = "borough") +class Borough( + + @Column(name = "code") + val code: String, + + val description: String, + + @Id + @Column(name = "borough_id") + val id: Long, + + @ManyToMany + @JoinTable( + name = "r_level_2_head_of_level_2", + joinColumns = [JoinColumn(name = "borough_id")], + inverseJoinColumns = [JoinColumn(name = "staff_id")] + ) + val pduHeads: List, + + @JoinColumn(name = "PROBATION_AREA_ID") + @OneToOne + val provider: Provider +) + +interface BoroughRepository : JpaRepository { + @Query( + """ + select b from Borough b + where b.code = :code + and (b.provider.endDate is null or b.provider.endDate > current_date) + """ + ) + fun findActiveByCode(code: String): Borough? +} + +@Immutable +@Entity +@Table(name = "office_location") +class OfficeLocation( + + @Column(name = "code", columnDefinition = "char(7)") + val code: String, + + val description: String, + val buildingName: String?, + val buildingNumber: String?, + val streetName: String?, + val district: String?, + val townCity: String?, + val county: String?, + val postcode: String?, + val telephoneNumber: String?, + val startDate: LocalDate, + val endDate: LocalDate?, + + @JoinColumn(name = "district_id") + @ManyToOne + val ldu: District, + + @Id + @Column(name = "office_location_id") + val id: Long +) + +fun OfficeLocation.asAddress() = OfficeAddress( + description, + buildingName, + buildingNumber, + streetName, + district, + townCity, + county, + postcode, + ldu.description, + telephoneNumber, + startDate, + endDate +) \ No newline at end of file diff --git a/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/Staff.kt b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/Staff.kt new file mode 100644 index 0000000000..397d6e5af8 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/entity/Staff.kt @@ -0,0 +1,80 @@ +package uk.gov.justice.digital.hmpps.entity + +import jakarta.persistence.* +import org.hibernate.annotations.Immutable +import org.springframework.data.jpa.repository.EntityGraph +import org.springframework.data.jpa.repository.JpaRepository +import java.util.* + +@Immutable +@Entity +@Table(name = "staff") +class Staff( + + @Column(name = "officer_code", columnDefinition = "char(7)") + val code: String, + + val forename: String, + val surname: String, + + @Column(name = "forename2") + val middleName: String? = null, + + @OneToOne(mappedBy = "staff") + val user: StaffUser? = null, + + @Id + @Column(name = "staff_id") + val id: Long, + + @ManyToMany + @JoinTable( + name = "staff_team", + joinColumns = [JoinColumn(name = "staff_id")], + inverseJoinColumns = [JoinColumn(name = "team_id")] + ) + val teams: List?, + + @ManyToOne + @JoinColumn(name = "probation_area_id") // Note: this column should not be used in general, because it can change whenever a user's teams changes. It's only used here for backward compatibility with Community API. + val provider: Provider, +) { + fun isUnallocated() = code.endsWith("U") +} + +@Entity +@Immutable +@Table(name = "user_") +class StaffUser( + + @OneToOne + @JoinColumn(name = "staff_id") + val staff: Staff? = null, + + @Column(name = "distinguished_name") + val username: String, + + @Id + @Column(name = "user_id") + val id: Long +) { + @Transient + var email: String? = null + + @Transient + var telephoneNumber: String? = null +} + +interface StaffRepository : JpaRepository { + @EntityGraph(attributePaths = ["user", "teams"]) + fun findByUserUsernameIgnoreCase(username: String): Staff? + + @EntityGraph(attributePaths = ["user", "teams"]) + fun findByCode(code: String): Staff? + + @EntityGraph(attributePaths = ["user", "teams"]) + override fun findById(id: Long): Optional + + @EntityGraph(attributePaths = ["user"]) + fun findByUserUsernameInIgnoreCase(usernames: List): List +} diff --git a/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/ManagerService.kt b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/ManagerService.kt new file mode 100644 index 0000000000..bd0080fab4 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/ManagerService.kt @@ -0,0 +1,86 @@ +package uk.gov.justice.digital.hmpps.service + +import org.springframework.ldap.core.LdapTemplate +import org.springframework.stereotype.Service +import uk.gov.justice.digital.hmpps.api.model.* +import uk.gov.justice.digital.hmpps.entity.Caseload +import uk.gov.justice.digital.hmpps.entity.PersonManager +import uk.gov.justice.digital.hmpps.entity.PersonManagerRepository +import uk.gov.justice.digital.hmpps.entity.Staff +import uk.gov.justice.digital.hmpps.exception.NotFoundException +import uk.gov.justice.digital.hmpps.ldap.findEmailByUsername + +@Service +class ManagerService( + private val ldapTemplate: LdapTemplate, + private val personManagerRepository: PersonManagerRepository +) { + fun findCommunityManager(crn: String): Manager = + personManagerRepository.findByPersonCrn(crn)?.let { ro -> + ro.staff.user?.apply { + email = ldapTemplate.findEmailByUsername(username) + } + ro.asManager() + } ?: throw NotFoundException("CommunityManager", "crn", crn) + + fun findCommunityManagerEmails(crns: List): List = + personManagerRepository.findByPersonCrnIn(crns).map { + StaffEmail(it.staff.code, it.staff.user?.username?.let { ldapTemplate.findEmailByUsername(it) }) + } +} + +fun PersonManager.asManager() = Manager( + staff.id, + staff.code, + staff.name(), + provider.asProvider(), + team.asTeam(), + staff.user?.username, + staff.user?.email, + staff.isUnallocated() +) + +fun Staff.name() = Name(forename, middleName, surname) +fun uk.gov.justice.digital.hmpps.entity.Provider.asProvider() = + uk.gov.justice.digital.hmpps.api.model.Provider(code, description) + +fun uk.gov.justice.digital.hmpps.entity.Team.asTeam() = uk.gov.justice.digital.hmpps.api.model.Team( + code, + description, + telephone, + emailAddress, + addresses.mapNotNull(uk.gov.justice.digital.hmpps.entity.OfficeLocation::asTeamAddress), + district.asDistrict(), + district.borough.asBorough(), + startDate, + endDate +) + +fun uk.gov.justice.digital.hmpps.entity.OfficeLocation.asTeamAddress() = OfficeAddress.from( + description, + buildingName, + buildingNumber, + streetName, + district, + townCity, + county, + postcode, + ldu.description, + telephoneNumber, + startDate, + endDate +) + +fun Caseload.asManagedOffender() = ManagedOffender( + crn, + Name(firstName, secondName, surname), + allocationDate, + staff.asStaff(), + team.asTeam() +) + +fun uk.gov.justice.digital.hmpps.entity.District.asDistrict() = + uk.gov.justice.digital.hmpps.api.model.District(code, description, borough.asBorough()) + +fun uk.gov.justice.digital.hmpps.entity.Borough.asBorough() = + uk.gov.justice.digital.hmpps.api.model.Borough(code, description) diff --git a/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/StaffService.kt b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/StaffService.kt new file mode 100644 index 0000000000..ff81f505da --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/StaffService.kt @@ -0,0 +1,81 @@ +package uk.gov.justice.digital.hmpps.service + +import org.springframework.ldap.core.LdapTemplate +import org.springframework.stereotype.Service +import uk.gov.justice.digital.hmpps.api.model.ManagedOffender +import uk.gov.justice.digital.hmpps.api.model.PDUHead +import uk.gov.justice.digital.hmpps.api.model.Staff +import uk.gov.justice.digital.hmpps.api.model.StaffName +import uk.gov.justice.digital.hmpps.entity.BoroughRepository +import uk.gov.justice.digital.hmpps.entity.Caseload.CaseloadRole +import uk.gov.justice.digital.hmpps.entity.CaseloadRepository +import uk.gov.justice.digital.hmpps.entity.LdapUser +import uk.gov.justice.digital.hmpps.entity.StaffRepository +import uk.gov.justice.digital.hmpps.exception.NotFoundException +import uk.gov.justice.digital.hmpps.ldap.findByUsername + +@Service +class StaffService( + private val ldapTemplate: LdapTemplate, + private val staffRepository: StaffRepository, + private val boroughRepository: BoroughRepository, + private val caseloadRepository: CaseloadRepository, +) { + fun findStaff(username: String): Staff = staffRepository.findByUserUsernameIgnoreCase(username) + ?.let { ldapTemplate.populateUserDetails(it).asStaff() } + ?: throw NotFoundException("Staff", "username", username) + + fun findStaffByCode(code: String): Staff = staffRepository.findByCode(code) + ?.let { ldapTemplate.populateUserDetails(it).asStaff() } + ?: throw NotFoundException("Staff", "code", code) + + fun findPDUHeads(boroughCode: String): List = boroughRepository.findActiveByCode(boroughCode)?.pduHeads + ?.map { ldapTemplate.populateUserDetails(it).asPDUHead() } + ?: listOf() + + fun findStaffForUsernames(usernames: List): List = + staffRepository.findByUserUsernameInIgnoreCase(usernames).map { it.asStaffName() } + + fun getManagedOffenders(staffCode: String): List = + caseloadRepository.findByStaffCodeAndRoleCode( + staffCode, + CaseloadRole.OFFENDER_MANAGER.value + ).map { + it.asManagedOffender() + } + + private fun LdapTemplate.populateUserDetails(staff: uk.gov.justice.digital.hmpps.entity.Staff) = + staff.apply { + user?.apply { + ldapTemplate.findByUsername(username)?.let { + email = it.email + telephoneNumber = it.telephoneNumber + } + } + } +} + +fun uk.gov.justice.digital.hmpps.entity.Staff.asStaff() = Staff( + id, + code, + name(), + teams?.map { it.asTeam() } ?: listOf(), + provider.asProvider(), + user?.username, + user?.email, + user?.telephoneNumber, + isUnallocated() +) + +fun uk.gov.justice.digital.hmpps.entity.Staff.asPDUHead() = PDUHead( + name(), + user?.email +) + +fun uk.gov.justice.digital.hmpps.entity.Staff.asStaffName() = StaffName( + id, + name(), + code, + user?.username +) + diff --git a/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/TeamService.kt b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/TeamService.kt new file mode 100644 index 0000000000..4ae1983679 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/TeamService.kt @@ -0,0 +1,19 @@ +package uk.gov.justice.digital.hmpps.service + +import org.springframework.stereotype.Service +import uk.gov.justice.digital.hmpps.api.model.ManagedOffender +import uk.gov.justice.digital.hmpps.entity.Caseload.CaseloadRole +import uk.gov.justice.digital.hmpps.entity.CaseloadRepository + +@Service +class TeamService( + private val caseloadRepository: CaseloadRepository, +) { + fun getManagedOffendersByTeam(teamCode: String): List = + caseloadRepository.findByTeamCodeAndRoleCodeOrderByAllocationDateDesc( + teamCode, + CaseloadRole.OFFENDER_MANAGER.value + ).map { + it.asManagedOffender() + } +} diff --git a/projects/assess-for-early-release-and-delius/src/main/resources/application.yml b/projects/assess-for-early-release-and-delius/src/main/resources/application.yml index 18f07d6fe3..0a4dd92c9e 100644 --- a/projects/assess-for-early-release-and-delius/src/main/resources/application.yml +++ b/projects/assess-for-early-release-and-delius/src/main/resources/application.yml @@ -16,10 +16,14 @@ spring: query.mutation_strategy.global_temporary: create_tables: false drop_tables: false + ldap: + base: ou=Users,dc=moj,dc=com + base-environment: + java.naming.ldap.derefAliases: never threads.virtual.enabled: true oauth2.roles: - - EXAMPLE + - PROBATION_API__ASSESS_FOR_EARLY_RELEASE__CASE_DETAIL springdoc.default-produces-media-type: application/json @@ -41,6 +45,9 @@ server.shutdown: immediate spring: datasource.url: jdbc:h2:file:./dev;MODE=Oracle;DEFAULT_NULL_ORDERING=HIGH;AUTO_SERVER=true;AUTO_SERVER_PORT=9092 jpa.hibernate.ddl-auto: create-drop + ldap.embedded: + validation.enabled: false + base-dn: ${spring.ldap.base} seed.database: true wiremock.enabled: true diff --git a/projects/assess-for-early-release-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/api/resource/StaffResourceTest.kt b/projects/assess-for-early-release-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/api/resource/StaffResourceTest.kt new file mode 100644 index 0000000000..f69de1ccf1 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/api/resource/StaffResourceTest.kt @@ -0,0 +1,31 @@ +package uk.gov.justice.digital.hmpps.api.resource + +import org.hamcrest.MatcherAssert.assertThat +import org.hamcrest.Matchers.equalTo +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import org.mockito.InjectMocks +import org.mockito.Mock +import org.mockito.junit.jupiter.MockitoExtension +import org.mockito.kotlin.whenever +import uk.gov.justice.digital.hmpps.data.generator.CaseloadGenerator.MANAGED_OFFENDER +import uk.gov.justice.digital.hmpps.service.StaffService + +@ExtendWith(MockitoExtension::class) +internal class StaffResourceTest { + + @Mock + lateinit var staffService: StaffService + + @InjectMocks + lateinit var resource: StaffResource + + @Test + fun `calls managed offenders endpoint`() { + whenever(staffService.getManagedOffenders("STCDE01")).thenReturn( + listOf(MANAGED_OFFENDER) + ) + val res = resource.getManagedOffenders("STCDE01") + assertThat(res[0].crn, equalTo("crn0001")) + } +} diff --git a/projects/assess-for-early-release-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/api/resource/TeamResourceTest.kt b/projects/assess-for-early-release-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/api/resource/TeamResourceTest.kt new file mode 100644 index 0000000000..17b93d64ad --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/api/resource/TeamResourceTest.kt @@ -0,0 +1,33 @@ +package uk.gov.justice.digital.hmpps.api.resource + +import org.hamcrest.MatcherAssert.assertThat +import org.hamcrest.Matchers.equalTo +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import org.mockito.InjectMocks +import org.mockito.Mock +import org.mockito.junit.jupiter.MockitoExtension +import org.mockito.kotlin.whenever +import uk.gov.justice.digital.hmpps.data.generator.CaseloadGenerator +import uk.gov.justice.digital.hmpps.service.TeamService + +@ExtendWith(MockitoExtension::class) +internal class TeamResourceTest { + + @Mock + lateinit var teamService: TeamService + + @InjectMocks + lateinit var resource: TeamResource + + @Test + fun `calls managed offenders endpoint`() { + whenever(teamService.getManagedOffendersByTeam("N01BDT")).thenReturn( + listOf( + CaseloadGenerator.MANAGED_OFFENDER + ) + ) + val res = resource.getManagedOffendersByTeam("N01BDT") + assertThat(res[0].crn, equalTo("crn0001")) + } +} diff --git a/projects/assess-for-early-release-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/ResponsibleManagerServiceTest.kt b/projects/assess-for-early-release-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/ResponsibleManagerServiceTest.kt new file mode 100644 index 0000000000..b71c91ee74 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/ResponsibleManagerServiceTest.kt @@ -0,0 +1,44 @@ +package uk.gov.justice.digital.hmpps.service + +import org.hamcrest.MatcherAssert.assertThat +import org.hamcrest.Matchers.equalTo +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import org.mockito.ArgumentMatchers.any +import org.mockito.InjectMocks +import org.mockito.Mock +import org.mockito.junit.jupiter.MockitoExtension +import org.mockito.kotlin.never +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever +import org.springframework.ldap.core.AttributesMapper +import org.springframework.ldap.core.LdapTemplate +import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator +import uk.gov.justice.digital.hmpps.data.generator.StaffGenerator +import uk.gov.justice.digital.hmpps.entity.PersonManagerRepository + +@ExtendWith(MockitoExtension::class) +internal class ResponsibleManagerServiceTest { + + @Mock + lateinit var personManagerRepository: PersonManagerRepository + + @Mock + lateinit var ldapTemplate: LdapTemplate + + @InjectMocks + lateinit var service: ManagerService + + @Test + fun `does not call ldap when no staff user`() { + val person = PersonGenerator.generatePerson("L123456") + val staff = StaffGenerator.generateStaff("NoLdap", "No", "User") + val cm = PersonGenerator.generateManager(person, staff = staff) + + whenever(personManagerRepository.findByPersonCrn(person.crn)).thenReturn(cm) + + val res = service.findCommunityManager(person.crn) + assertThat(res, equalTo(cm.asManager())) + verify(ldapTemplate, never()).search(any(), any>()) + } +} diff --git a/projects/assess-for-early-release-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/StaffServiceTest.kt b/projects/assess-for-early-release-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/StaffServiceTest.kt new file mode 100644 index 0000000000..873d007057 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/StaffServiceTest.kt @@ -0,0 +1,43 @@ +package uk.gov.justice.digital.hmpps.service + +import org.hamcrest.MatcherAssert.assertThat +import org.hamcrest.Matchers.equalTo +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import org.mockito.InjectMocks +import org.mockito.Mock +import org.mockito.junit.jupiter.MockitoExtension +import org.mockito.kotlin.whenever +import org.springframework.ldap.core.LdapTemplate +import uk.gov.justice.digital.hmpps.data.generator.CaseloadGenerator +import uk.gov.justice.digital.hmpps.entity.BoroughRepository +import uk.gov.justice.digital.hmpps.entity.CaseloadRepository +import uk.gov.justice.digital.hmpps.entity.StaffRepository + +@ExtendWith(MockitoExtension::class) +internal class StaffServiceTest { + + @Mock + lateinit var ldapTemplate: LdapTemplate + + @Mock + lateinit var staffRepository: StaffRepository + + @Mock + lateinit var boroughRepository: BoroughRepository + + @Mock + lateinit var caseloadRepository: CaseloadRepository + + @InjectMocks + lateinit var service: StaffService + + @Test + fun `calls caseload repository`() { + whenever(caseloadRepository.findByStaffCodeAndRoleCode("STCDE01", "OM")).thenReturn( + listOf(CaseloadGenerator.CASELOAD_ROLE_OM_1) + ) + val res = service.getManagedOffenders(staffCode = "STCDE01") + assertThat(res[0].crn, equalTo("crn0001")) + } +} diff --git a/projects/assess-for-early-release-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/TeamServiceTest.kt b/projects/assess-for-early-release-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/TeamServiceTest.kt new file mode 100644 index 0000000000..b7dfb80144 --- /dev/null +++ b/projects/assess-for-early-release-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/TeamServiceTest.kt @@ -0,0 +1,31 @@ +package uk.gov.justice.digital.hmpps.service + +import org.hamcrest.MatcherAssert.assertThat +import org.hamcrest.Matchers.equalTo +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import org.mockito.InjectMocks +import org.mockito.Mock +import org.mockito.junit.jupiter.MockitoExtension +import org.mockito.kotlin.whenever +import uk.gov.justice.digital.hmpps.data.generator.CaseloadGenerator +import uk.gov.justice.digital.hmpps.entity.CaseloadRepository + +@ExtendWith(MockitoExtension::class) +internal class TeamServiceTest { + + @Mock + lateinit var caseloadRepository: CaseloadRepository + + @InjectMocks + lateinit var service: TeamService + + @Test + fun `calls caseload repository`() { + whenever(caseloadRepository.findByTeamCodeAndRoleCodeOrderByAllocationDateDesc("N01BDT", "OM")).thenReturn( + listOf(CaseloadGenerator.CASELOAD_ROLE_OM_2) + ) + val res = service.getManagedOffendersByTeam("N01BDT") + assertThat(res[0].crn, equalTo("crn0022")) + } +} From 8b87ca6499df775652ba2b283db56d8888c9b320 Mon Sep 17 00:00:00 2001 From: "probation-integration-bot[bot]" <177347787+probation-integration-bot[bot]@users.noreply.github.com> Date: Thu, 21 Nov 2024 09:06:27 +0000 Subject: [PATCH 25/26] Update Gradle Wrapper from 8.11 to 8.11.1 (#4453) Bump Gradle Wrapper to the latest version Co-authored-by: probation-integration-bot[bot] <177347787+probation-integration-bot[bot]@users.noreply.github.com> --- gradle/wrapper/gradle-wrapper.properties | 4 ++-- .../api-client/gradle/wrapper/gradle-wrapper.properties | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 82dd18b204..eb1a55be0e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=57dafb5c2622c6cc08b993c85b7c06956a2f53536432a30ead46166dbca0f1e9 -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip +distributionSha256Sum=f397b287023acdba1e9f6fc5ea72d22dd63669d59ed4a289a29b1a76eee151c6 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/tools/ingress-testing/api-client/gradle/wrapper/gradle-wrapper.properties b/tools/ingress-testing/api-client/gradle/wrapper/gradle-wrapper.properties index 82dd18b204..eb1a55be0e 100644 --- a/tools/ingress-testing/api-client/gradle/wrapper/gradle-wrapper.properties +++ b/tools/ingress-testing/api-client/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=57dafb5c2622c6cc08b993c85b7c06956a2f53536432a30ead46166dbca0f1e9 -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip +distributionSha256Sum=f397b287023acdba1e9f6fc5ea72d22dd63669d59ed4a289a29b1a76eee151c6 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 0a3fbd72cf270eb33b2b1c08ec8a514124bc96e3 Mon Sep 17 00:00:00 2001 From: gregkhawkins <148795810+gregkhawkins@users.noreply.github.com> Date: Thu, 21 Nov 2024 15:31:36 +0000 Subject: [PATCH 26/26] APS-1482 - Refactor GET case-detail endpoint to include offence categories (#4455) --- .../hmpps/data/generator/OffenceGenerator.kt | 19 +++++++++++++++---- .../hmpps/ProbationCaseIntegrationTest.kt | 11 +++++++++-- .../delius/person/offence/entity/Offence.kt | 12 ++++++++++++ .../justice/digital/hmpps/model/CaseDetail.kt | 2 ++ .../digital/hmpps/service/CaseService.kt | 12 +++++++++++- 5 files changed, 49 insertions(+), 7 deletions(-) diff --git a/projects/approved-premises-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/OffenceGenerator.kt b/projects/approved-premises-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/OffenceGenerator.kt index 173f67158f..062a19aaa4 100644 --- a/projects/approved-premises-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/OffenceGenerator.kt +++ b/projects/approved-premises-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/OffenceGenerator.kt @@ -7,11 +7,22 @@ import uk.gov.justice.digital.hmpps.integrations.delius.person.offence.entity.Of import java.time.LocalDate object OffenceGenerator { - val OFFENCE_ONE = generate("OFF1", "Offence One") - val OFFENCE_TWO = generate("OFF2", "Offence Two") + val OFFENCE_ONE = generate("OFF1", "Murder - OFF1", "Murder", "Murder of spouse") + val OFFENCE_TWO = generate( + "OFF2", + "Burglary in a dwelling - OFF2", + "Burglary in a dwelling", + "Burglary (dwelling) with intent to commit, or the commission of, an offence triable only on indictment" + ) - fun generate(code: String, description: String, id: Long = IdGenerator.getAndIncrement()) = - Offence(code, description, id) + fun generate( + code: String, + description: String, + mainCategoryDescription: String, + subCategoryDescription: String, + id: Long = IdGenerator.getAndIncrement() + ) = + Offence(code, description, mainCategoryDescription, subCategoryDescription, id) fun generateMainOffence( event: Event, diff --git a/projects/approved-premises-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/ProbationCaseIntegrationTest.kt b/projects/approved-premises-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/ProbationCaseIntegrationTest.kt index 23e75f272f..c2c49e7d42 100644 --- a/projects/approved-premises-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/ProbationCaseIntegrationTest.kt +++ b/projects/approved-premises-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/ProbationCaseIntegrationTest.kt @@ -71,12 +71,19 @@ class ProbationCaseIntegrationTest { assertThat(detail.registrations.map { it.description }, equalTo(listOf("Description of ARSO"))) val mainOffence = detail.offences.first { it.main } assertThat(mainOffence.id, equalTo("M200001")) - assertThat(mainOffence.description, equalTo("Offence One")) + assertThat(mainOffence.description, equalTo("Murder - OFF1")) + assertThat(mainOffence.mainCategoryDescription, equalTo("Murder")) + assertThat(mainOffence.subCategoryDescription, equalTo("Murder of spouse")) assertThat(mainOffence.date, equalTo(LocalDate.parse("2024-10-11"))) assertThat(mainOffence.eventId, equalTo(100001L)) val otherOffence = detail.offences.first { !it.main } assertThat(otherOffence.id, equalTo("A300001")) - assertThat(otherOffence.description, equalTo("Offence Two")) + assertThat(otherOffence.description, equalTo("Burglary in a dwelling - OFF2")) + assertThat(otherOffence.mainCategoryDescription, equalTo("Burglary in a dwelling")) + assertThat( + otherOffence.subCategoryDescription, + equalTo("Burglary (dwelling) with intent to commit, or the commission of, an offence triable only on indictment") + ) assertThat(otherOffence.date, equalTo(LocalDate.parse("2024-10-21"))) assertThat(otherOffence.eventId, equalTo(100001L)) assertThat(detail.careLeaver, equalTo(false)) diff --git a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/person/offence/entity/Offence.kt b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/person/offence/entity/Offence.kt index 97d91a0220..7861f9def7 100644 --- a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/person/offence/entity/Offence.kt +++ b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/person/offence/entity/Offence.kt @@ -12,6 +12,8 @@ interface CaseOffence { val id: Long val code: String val description: String + val mainCategoryDescription: String + val subCategoryDescription: String val date: LocalDate? val main: Boolean val eventNumber: String @@ -79,6 +81,12 @@ class Offence( @Column val description: String, + @Column(name = "main_category_description") + private var mainCategoryDescription: String, + + @Column(name = "sub_category_description") + private val subCategoryDescription: String, + @Id @Column(name = "offence_id") val id: Long @@ -91,6 +99,8 @@ interface MainOffenceRepository : JpaRepository { mo.id as id, mo.offence.code as code, mo.offence.description as description, + mo.offence.mainCategoryDescription as mainCategoryDescription, + mo.offence.subCategoryDescription as subCategoryDescription, mo.date as date, true as main, mo.event.number as eventNumber, @@ -102,6 +112,8 @@ interface MainOffenceRepository : JpaRepository { ao.id, ao.offence.code, ao.offence.description, + ao.offence.mainCategoryDescription as mainCategoryDescription, + ao.offence.subCategoryDescription as subCategoryDescription, ao.date, false, ao.event.number, diff --git a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/model/CaseDetail.kt b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/model/CaseDetail.kt index 0cf9687caa..ba7f8716c6 100644 --- a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/model/CaseDetail.kt +++ b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/model/CaseDetail.kt @@ -62,6 +62,8 @@ data class Offence( val id: String, val code: String, val description: String, + val mainCategoryDescription: String, + val subCategoryDescription: String, val date: LocalDate?, val main: Boolean, val eventId: Long, diff --git a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/CaseService.kt b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/CaseService.kt index 8585a9cd9c..827a367950 100644 --- a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/CaseService.kt +++ b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/CaseService.kt @@ -88,7 +88,17 @@ fun CommunityManager.team() = Team( ) fun CaseOffence.asOffence() = - Offence(id = if (main) "M$id" else "A$id", code, description, date, main, eventId, eventNumber) + Offence( + id = if (main) "M$id" else "A$id", + code, + description, + mainCategoryDescription, + subCategoryDescription, + date, + main, + eventId, + eventNumber + ) fun Registration.asRegistration() = uk.gov.justice.digital.hmpps.model.Registration(type.code, type.description, date) fun Registration.asMappa() = MappaDetail(