From 22ec1d066e446cb1576714fe2b1a690f6a241eba Mon Sep 17 00:00:00 2001 From: davidatkinsuk Date: Wed, 25 Sep 2024 11:29:50 +0100 Subject: [PATCH 1/7] =?UTF-8?q?Remove=20=E2=80=98womens=E2=80=99=20qualifi?= =?UTF-8?q?cation=20from=20test=20user?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/db/seed/local+dev+test/3__user.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/db/seed/local+dev+test/3__user.csv b/src/main/resources/db/seed/local+dev+test/3__user.csv index 6ddd206411e..dfcb58befa7 100644 --- a/src/main/resources/db/seed/local+dev+test/3__user.csv +++ b/src/main/resources/db/seed/local+dev+test/3__user.csv @@ -1,2 +1,2 @@ deliusUsername,roles,qualifications -JIMSNOWLDAP,"CAS3_ASSESSOR,CAS3_REPORTER,CAS3_REFERRER,CAS1_ASSESSOR,CAS1_ADMIN,CAS1_APPLICANT,CAS1_ASSESSOR,CAS1_WORKFLOW_MANAGER,CAS1_APPEALS_MANAGER,CAS1_MATCHER,CAS1_REPORT_VIEWER,CAS1_CRU_MEMBER,CAS1_FUTURE_MANAGER","EMERGENCY,PIPE,WOMENS,LAO,ESAP" +JIMSNOWLDAP,"CAS3_ASSESSOR,CAS3_REPORTER,CAS3_REFERRER,CAS1_ASSESSOR,CAS1_ADMIN,CAS1_APPLICANT,CAS1_ASSESSOR,CAS1_WORKFLOW_MANAGER,CAS1_APPEALS_MANAGER,CAS1_MATCHER,CAS1_REPORT_VIEWER,CAS1_CRU_MEMBER,CAS1_FUTURE_MANAGER","EMERGENCY,PIPE,LAO,ESAP" From 2bf334802eda9eb18108e69fb6ff721274b948aa Mon Sep 17 00:00:00 2001 From: Rob Booth Date: Tue, 24 Sep 2024 16:44:25 +0100 Subject: [PATCH 2/7] Rollback change to only return conviction documents Removed feature flag CAS1-ONLY-LIST-CONVICTION-DOCUMENTS Agreed on call with Harry, Dan and David 24/9/24 Removed filtering of documents to return only conviction documents if the feature flag was set. --- helm_deploy/values-dev.yaml | 1 - helm_deploy/values-preprod.yaml | 1 - helm_deploy/values-prod.yaml | 1 - helm_deploy/values-test.yaml | 1 - .../controller/ApplicationsController.kt | 12 +--- .../transformer/DocumentTransformer.kt | 39 +++++++------ src/main/resources/application.yml | 1 - .../integration/ApplicationDocumentsTest.kt | 55 ++++++++----------- .../transformer/DocumentTransformerTest.kt | 53 ++---------------- src/test/resources/application-test.yml | 1 - 10 files changed, 49 insertions(+), 116 deletions(-) diff --git a/helm_deploy/values-dev.yaml b/helm_deploy/values-dev.yaml index b83e9b52f32..923aac1743d 100644 --- a/helm_deploy/values-dev.yaml +++ b/helm_deploy/values-dev.yaml @@ -112,7 +112,6 @@ generic-service: FEATURE-FLAGS_CAS1-APPEAL-MANAGER-CAN-ASSESS-APPLICATIONS: true FEATURE-FLAGS_CAS1-ONLY-LIST-ADJUDICATIONS-UP-TO-12-MONTHS: true - FEATURE-FLAGS_CAS1-ONLY-LIST-CONVICTION-DOCUMENTS: true FEATURE-FLAGS_CAS1-ONLY-LIST-SPECIFIC-PRISON-NOTE-TYPES: true FEATURE-FLAGS_CAS1-WOMENS-ESTATE-ENABLED: true FEATURE-FLAGS_USE-AP-AND-DELIUS-TO-UPDATE-USERS: true diff --git a/helm_deploy/values-preprod.yaml b/helm_deploy/values-preprod.yaml index d30cbb75f06..b53a0bc2c91 100644 --- a/helm_deploy/values-preprod.yaml +++ b/helm_deploy/values-preprod.yaml @@ -104,7 +104,6 @@ generic-service: FEATURE-FLAGS_CAS1-APPEAL-MANAGER-CAN-ASSESS-APPLICATIONS: true FEATURE-FLAGS_CAS1-ONLY-LIST-ADJUDICATIONS-UP-TO-12-MONTHS: true - FEATURE-FLAGS_CAS1-ONLY-LIST-CONVICTION-DOCUMENTS: true FEATURE-FLAGS_CAS1-ONLY-LIST-SPECIFIC-PRISON-NOTE-TYPES: true FEATURE-FLAGS_CAS1-WOMENS-ESTATE-ENABLED: false FEATURE-FLAGS_USE-AP-AND-DELIUS-TO-UPDATE-USERS: true diff --git a/helm_deploy/values-prod.yaml b/helm_deploy/values-prod.yaml index fa7d12f33d9..bb27548ef05 100644 --- a/helm_deploy/values-prod.yaml +++ b/helm_deploy/values-prod.yaml @@ -106,7 +106,6 @@ generic-service: FEATURE-FLAGS_CAS1-APPEAL-MANAGER-CAN-ASSESS-APPLICATIONS: true FEATURE-FLAGS_CAS1-ONLY-LIST-ADJUDICATIONS-UP-TO-12-MONTHS: false - FEATURE-FLAGS_CAS1-ONLY-LIST-CONVICTION-DOCUMENTS: false FEATURE-FLAGS_CAS1-ONLY-LIST-SPECIFIC-PRISON-NOTE-TYPES: false FEATURE-FLAGS_CAS1-WOMENS-ESTATE-ENABLED: false FEATURE-FLAGS_USE-AP-AND-DELIUS-TO-UPDATE-USERS: true diff --git a/helm_deploy/values-test.yaml b/helm_deploy/values-test.yaml index b4a633df4a9..30bfd647a1c 100644 --- a/helm_deploy/values-test.yaml +++ b/helm_deploy/values-test.yaml @@ -102,7 +102,6 @@ generic-service: FEATURE-FLAGS_CAS1-APPEAL-MANAGER-CAN-ASSESS-APPLICATIONS: true FEATURE-FLAGS_CAS1-ONLY-LIST-ADJUDICATIONS-UP-TO-12-MONTHS: true - FEATURE-FLAGS_CAS1-ONLY-LIST-CONVICTION-DOCUMENTS: true FEATURE-FLAGS_CAS1-ONLY-LIST-SPECIFIC-PRISON-NOTE-TYPES: true FEATURE-FLAGS_CAS1-WOMENS-ESTATE-ENABLED: true FEATURE-FLAGS_USE-AP-AND-DELIUS-TO-UPDATE-USERS: true diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/controller/ApplicationsController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/controller/ApplicationsController.kt index 44b04d559a6..bec5a4067fb 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/controller/ApplicationsController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/controller/ApplicationsController.kt @@ -51,7 +51,6 @@ import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.AssessmentServic import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.HttpAuthService import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.OffenderService import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.RequestForPlacementService -import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.SpringConfigFeatureFlagService import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.UserService import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.cas1.Cas1WithdrawableService import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.cas1.WithdrawableEntitiesWithNotes @@ -83,7 +82,6 @@ class ApplicationsController( private val appealTransformer: AppealTransformer, private val requestForPlacementService: RequestForPlacementService, private val withdrawableTransformer: WithdrawableTransformer, - private val featureFlagService: SpringConfigFeatureFlagService, ) : ApplicationsApiDelegate { override fun applicationsGet(xServiceName: ServiceName?): ResponseEntity> { @@ -453,14 +451,8 @@ class ApplicationsController( } val transformedDocuments = when (application) { - is ApprovedPremisesApplicationEntity -> documentTransformer.transformToApi( - groupedDocuments = documents, - onlyConvictionDocuments = featureFlagService.getBooleanFlag("cas1-only-list-conviction-documents"), - ) - is TemporaryAccommodationApplicationEntity -> documentTransformer.transformToApi( - groupedDocuments = documents, - convictionId = application.convictionId, - ) + is ApprovedPremisesApplicationEntity -> documentTransformer.transformToApiUnfiltered(documents) + is TemporaryAccommodationApplicationEntity -> documentTransformer.transformToApiFiltered(documents, application.convictionId) else -> throw RuntimeException("Unsupported Application type: ${application::class.qualifiedName}") } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/transformer/DocumentTransformer.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/transformer/DocumentTransformer.kt index 8e39e089a9f..b3876e11984 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/transformer/DocumentTransformer.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/transformer/DocumentTransformer.kt @@ -14,12 +14,27 @@ class DocumentTransformer { private val log = LoggerFactory.getLogger(this::class.java) + fun transformToApiFiltered(groupedDocuments: GroupedDocuments, convictionId: Long?) = + transformToApi(groupedDocuments) { it.convictionId == convictionId.toString() } + + fun transformToApiUnfiltered(groupedDocuments: GroupedDocuments) = + transformToApi(groupedDocuments) { true } + fun transformToApi( groupedDocuments: GroupedDocuments, - onlyConvictionDocuments: Boolean = false, - convictionId: Long? = null, + convictionDocFilter: (ConvictionDocuments) -> Boolean, ): List { - val convictionDocFilter: (ConvictionDocuments) -> Boolean = { document -> convictionId?.let { document.convictionId == convictionId.toString() } ?: true } + val offenderDocuments = documentsWithIdsAndNames(groupedDocuments.documents).map { + Document( + id = it.id!!, + level = DocumentLevel.offender, + fileName = it.documentName!!, + createdAt = it.createdAt.toInstant(ZoneOffset.UTC), + typeCode = it.type.code, + typeDescription = it.type.description, + description = it.extendedDescription, + ) + } val filteredConvictionDocuments = groupedDocuments .convictions @@ -38,23 +53,7 @@ class DocumentTransformer { ) } - when (onlyConvictionDocuments) { - true -> return convictionDocuments - false -> { - val offenderDocuments = documentsWithIdsAndNames(groupedDocuments.documents).map { - Document( - id = it.id!!, - level = DocumentLevel.offender, - fileName = it.documentName!!, - createdAt = it.createdAt.toInstant(ZoneOffset.UTC), - typeCode = it.type.code, - typeDescription = it.type.description, - description = it.extendedDescription, - ) - } - return offenderDocuments + convictionDocuments - } - } + return offenderDocuments + convictionDocuments } /** diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 08eebd090e4..1e8b58ec08c 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -300,7 +300,6 @@ reports: feature-flags: cas1-appeal-manager-can-assess-applications: false cas1-only-list-adjudications-up-to-12-months: false - cas1-only-list-conviction-documents: false cas1-only-list-specific-prison-note-types: false cas1-womens-estate-enabled: false use-ap-and-delius-to-update-users: true diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/ApplicationDocumentsTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/ApplicationDocumentsTest.kt index 630c9a058de..5967a5bc43b 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/ApplicationDocumentsTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/ApplicationDocumentsTest.kt @@ -11,8 +11,6 @@ import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Give import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Given an Offender` import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.httpmocks.CommunityAPI_mockSuccessfulDocumentDownloadCall import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.httpmocks.CommunityAPI_mockSuccessfulDocumentsCall -import uk.gov.justice.digital.hmpps.approvedpremisesapi.model.community.ConvictionDocuments -import uk.gov.justice.digital.hmpps.approvedpremisesapi.model.community.GroupedDocuments import uk.gov.justice.digital.hmpps.approvedpremisesapi.transformer.DocumentTransformer import java.time.LocalDateTime @@ -40,36 +38,31 @@ class ApplicationDocumentsTest : InitialiseDatabasePerClassTestBase() { withApplicationSchema(approvedPremisesApplicationJsonSchemaRepository.findAll().first()) } - val offenderDocument = - DocumentFactory() - .withId("b0df5ec4-5685-4b02-8a95-91b6da80156f") - .withDocumentName("offender_level_doc.pdf") - .withTypeCode("TYPE-1") - .withTypeDescription("Type 1 Description") - .withCreatedAt(LocalDateTime.parse("2022-12-07T11:40:00")) - .withExtendedDescription("Extended Description 1") - .produce() - - val convictionDocuments = - ConvictionDocuments( + val groupedDocuments = GroupedDocumentsFactory() + .withOffenderLevelDocument( + DocumentFactory() + .withId("b0df5ec4-5685-4b02-8a95-91b6da80156f") + .withDocumentName("offender_level_doc.pdf") + .withTypeCode("TYPE-1") + .withTypeDescription("Type 1 Description") + .withCreatedAt(LocalDateTime.parse("2022-12-07T11:40:00")) + .withExtendedDescription("Extended Description 1") + .produce(), + ) + .withConvictionLevelDocument( "12345", - listOf( - DocumentFactory() - .withId("457af8a5-82b1-449a-ad03-032b39435865") - .withDocumentName("conviction_level_doc.pdf") - .withTypeCode("TYPE-2") - .withTypeDescription("Type 2 Description") - .withCreatedAt(LocalDateTime.parse("2022-12-07T10:40:00")) - .withExtendedDescription("Extended Description 2") - .produce(), - ), + DocumentFactory() + .withId("457af8a5-82b1-449a-ad03-032b39435865") + .withDocumentName("conviction_level_doc.pdf") + .withTypeCode("TYPE-2") + .withTypeDescription("Type 2 Description") + .withCreatedAt(LocalDateTime.parse("2022-12-07T10:40:00")) + .withExtendedDescription("Extended Description 2") + .produce(), ) + .produce() - val offenderAndConvictionDocuments = GroupedDocuments(listOf(offenderDocument), listOf(convictionDocuments)) - - CommunityAPI_mockSuccessfulDocumentsCall(offenderDetails.otherIds.crn, offenderAndConvictionDocuments) - - val convictionOnlyDocuments = GroupedDocuments(emptyList(), listOf(convictionDocuments)) + CommunityAPI_mockSuccessfulDocumentsCall(offenderDetails.otherIds.crn, groupedDocuments) webTestClient.get() .uri("/applications/${application.id}/documents") @@ -80,7 +73,7 @@ class ApplicationDocumentsTest : InitialiseDatabasePerClassTestBase() { .expectBody() .json( objectMapper.writeValueAsString( - documentTransformer.transformToApi(convictionOnlyDocuments, onlyConvictionDocuments = true), + documentTransformer.transformToApiUnfiltered(groupedDocuments), ), ) } @@ -135,7 +128,7 @@ class ApplicationDocumentsTest : InitialiseDatabasePerClassTestBase() { .expectBody() .json( objectMapper.writeValueAsString( - documentTransformer.transformToApi(groupedDocuments, onlyConvictionDocuments = false), + documentTransformer.transformToApiUnfiltered(groupedDocuments), ), ) } diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/unit/transformer/DocumentTransformerTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/unit/transformer/DocumentTransformerTest.kt index 1952d411f23..450f2d447d2 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/unit/transformer/DocumentTransformerTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/unit/transformer/DocumentTransformerTest.kt @@ -41,7 +41,7 @@ class DocumentTransformerTest { ) .produce() - val result = documentTransformer.transformToApi(groupedDocuments, onlyConvictionDocuments = false) + val result = documentTransformer.transformToApiUnfiltered(groupedDocuments) assertThat(result).containsExactlyInAnyOrder( Document( @@ -103,7 +103,7 @@ class DocumentTransformerTest { ) .produce() - val result = documentTransformer.transformToApi(groupedDocuments, convictionId = 12345) + val result = documentTransformer.transformToApiFiltered(groupedDocuments, 12345) assertThat(result).hasSize(2) assertThat(result[0].fileName).isEqualTo("offender_level_doc.pdf") @@ -148,7 +148,7 @@ class DocumentTransformerTest { ) .produce() - val result = documentTransformer.transformToApi(groupedDocuments, onlyConvictionDocuments = false) + val result = documentTransformer.transformToApiUnfiltered(groupedDocuments) assertThat(result).hasSize(3) assertThat(result[0].fileName).isEqualTo("offender_level_doc.pdf") @@ -156,51 +156,6 @@ class DocumentTransformerTest { assertThat(result[2].fileName).isEqualTo("conviction_level_doc_2.pdf") } - @Test - fun `transformToApiUnfiltered returns only conviction documents when onlyConvictionDocuments is true`() { - val groupedDocuments = GroupedDocumentsFactory() - .withOffenderLevelDocument( - DocumentFactory() - .withId(UUID.fromString("b0df5ec4-5685-4b02-8a95-91b6da80156f").toString()) - .withDocumentName("offender_level_doc.pdf") - .withTypeCode("TYPE-1") - .withTypeDescription("Type 1 Description") - .withCreatedAt(LocalDateTime.parse("2022-12-07T11:40:00")) - .withExtendedDescription("Extended Description 1") - .produce(), - ) - .withConvictionLevelDocument( - "12345", - DocumentFactory() - .withId(UUID.fromString("457af8a5-82b1-449a-ad03-032b39435865").toString()) - .withDocumentName("conviction_level_doc.pdf") - .withoutAuthor() - .withTypeCode("TYPE-2") - .withTypeDescription("Type 2 Description") - .withCreatedAt(LocalDateTime.parse("2022-12-07T10:40:00")) - .withExtendedDescription("Extended Description 2") - .produce(), - ) - .withConvictionLevelDocument( - "6789", - DocumentFactory() - .withId(UUID.fromString("e20589b3-7f83-4502-a0df-c8dd645f3f44").toString()) - .withDocumentName("conviction_level_doc_2.pdf") - .withTypeCode("TYPE-2") - .withTypeDescription("Type 2 Description") - .withCreatedAt(LocalDateTime.parse("2022-12-07T10:40:00")) - .withExtendedDescription("Extended Description 2") - .produce(), - ) - .produce() - - val result = documentTransformer.transformToApi(groupedDocuments, onlyConvictionDocuments = true) - - assertThat(result).hasSize(2) - assertThat(result[0].fileName).isEqualTo("conviction_level_doc.pdf") - assertThat(result[1].fileName).isEqualTo("conviction_level_doc_2.pdf") - } - @Test fun `transformToApiUnfiltered filters out docs with no id`() { val groupedDocuments = GroupedDocumentsFactory() @@ -251,7 +206,7 @@ class DocumentTransformerTest { ) .produce() - val result = documentTransformer.transformToApi(groupedDocuments, onlyConvictionDocuments = false) + val result = documentTransformer.transformToApiUnfiltered(groupedDocuments) assertThat(result).hasSize(3) assertThat(result[0].fileName).isEqualTo("offender_level_doc.pdf") diff --git a/src/test/resources/application-test.yml b/src/test/resources/application-test.yml index 3e3017fa11d..16e33cbc407 100644 --- a/src/test/resources/application-test.yml +++ b/src/test/resources/application-test.yml @@ -219,5 +219,4 @@ logging.level.org.springframework.jdbc.core.JdbcTemplate: debug feature-flags: cas1-appeal-manager-can-assess-applications: true cas1-only-list-adjudications-up-to-12-months: true - cas1-only-list-conviction-documents: true cas1-only-list-specific-prison-note-types: true \ No newline at end of file From c010c95e7795f6d834fc7df76db392c4dd958b3a Mon Sep 17 00:00:00 2001 From: davidatkinsuk Date: Wed, 18 Sep 2024 07:35:38 +0100 Subject: [PATCH 3/7] Add gender to approved premise entity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This defaults to MALE and will be correctly set when seeding/updating Women’s Estate Premises. This commit also updates the seed job for Approved Premises to populate the gender field. --- .../jpa/entity/PremisesEntity.kt | 8 +++++ .../seed/cas1/ApprovedPremisesSeedJob.kt | 7 ++++- ...72511__add_gender_to_approved_premises.sql | 1 + .../local+dev+test/1__approved_premises.csv | 30 +++++++++---------- .../factory/ApprovedPremisesEntityFactory.kt | 3 ++ .../cas1/seed/SeedApprovedPremisesTest.kt | 3 ++ 6 files changed, 36 insertions(+), 16 deletions(-) create mode 100644 src/main/resources/db/migration/all/20240918072511__add_gender_to_approved_premises.sql diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/jpa/entity/PremisesEntity.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/jpa/entity/PremisesEntity.kt index ae209a9d61e..b56b9dd80a7 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/jpa/entity/PremisesEntity.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/jpa/entity/PremisesEntity.kt @@ -214,6 +214,7 @@ abstract class PremisesEntity( var status: PropertyStatus, ) +@SuppressWarnings("LongParameterList") @Entity @DiscriminatorValue("approved-premises") @Table(name = "approved_premises") @@ -239,6 +240,8 @@ class ApprovedPremisesEntity( characteristics: MutableList, status: PropertyStatus, var point: Point?, // TODO: Make not-null once Premises have had point added in all environments + @Enumerated(value = EnumType.STRING) + val gender: ApprovedPremisesGender, ) : PremisesEntity( id, name, @@ -259,6 +262,11 @@ class ApprovedPremisesEntity( status, ) +enum class ApprovedPremisesGender { + MALE, + FEMALE, +} + @Entity @DiscriminatorValue("temporary-accommodation") @Table(name = "temporary_accommodation_premises") diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/seed/cas1/ApprovedPremisesSeedJob.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/seed/cas1/ApprovedPremisesSeedJob.kt index a8f5dcc74e0..8ee32b80446 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/seed/cas1/ApprovedPremisesSeedJob.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/seed/cas1/ApprovedPremisesSeedJob.kt @@ -6,6 +6,7 @@ import org.locationtech.jts.geom.PrecisionModel import org.slf4j.LoggerFactory import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.PropertyStatus import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.ApprovedPremisesEntity +import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.ApprovedPremisesGender import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.CharacteristicEntity import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.CharacteristicRepository import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.LocalAuthorityAreaEntity @@ -58,6 +59,7 @@ class ApprovedPremisesSeedJob( "qCode", "latitude", "longitude", + "gender", ), ) { private val log = LoggerFactory.getLogger(this::class.java) @@ -97,6 +99,7 @@ class ApprovedPremisesSeedJob( qCode = columns["qCode"]!!, latitude = columns["latitude"]!!.toDoubleOrNull(), longitude = columns["longitude"]!!.toDoubleOrNull(), + gender = ApprovedPremisesGender.valueOf(columns["gender"]!!), ) override fun processRow(row: ApprovedPremisesSeedCsvRow) { @@ -111,7 +114,7 @@ class ApprovedPremisesSeedJob( val characteristics = characteristicsFromRow(row) if (existingPremises != null) { - updateExistingApprovedPremises(row, existingPremises as ApprovedPremisesEntity, probationRegion, localAuthorityArea, characteristics) + updateExistingApprovedPremises(row, existingPremises, probationRegion, localAuthorityArea, characteristics) } else { createNewApprovedPremises(row, probationRegion, localAuthorityArea, characteristics) } @@ -175,6 +178,7 @@ class ApprovedPremisesSeedJob( longitude = row.longitude, latitude = row.latitude, point = if (row.longitude != null && row.latitude != null) geometryFactory.createPoint(Coordinate(row.latitude, row.longitude)) else null, + gender = row.gender, ), ) @@ -270,4 +274,5 @@ data class ApprovedPremisesSeedCsvRow( val qCode: String, val latitude: Double?, val longitude: Double?, + val gender: ApprovedPremisesGender, ) diff --git a/src/main/resources/db/migration/all/20240918072511__add_gender_to_approved_premises.sql b/src/main/resources/db/migration/all/20240918072511__add_gender_to_approved_premises.sql new file mode 100644 index 00000000000..a9d3ffcb1bd --- /dev/null +++ b/src/main/resources/db/migration/all/20240918072511__add_gender_to_approved_premises.sql @@ -0,0 +1 @@ +ALTER TABLE approved_premises ADD gender TEXT NOT NULL DEFAULT 'MALE'; \ No newline at end of file diff --git a/src/main/resources/db/seed/local+dev+test/1__approved_premises.csv b/src/main/resources/db/seed/local+dev+test/1__approved_premises.csv index 55a08e945cc..7f4718403b6 100644 --- a/src/main/resources/db/seed/local+dev+test/1__approved_premises.csv +++ b/src/main/resources/db/seed/local+dev+test/1__approved_premises.csv @@ -1,16 +1,16 @@ name,addressLine1,addressLine2,town,postcode,latitude,longitude,notes,emailAddress,probationRegion,localAuthorityArea,characteristics,isIAP,isPIPE,isESAP,isSemiSpecialistMentalHealth,isRecoveryFocussed,isSuitableForVulnerable,acceptsSexOffenders,acceptsChildSexOffenders,acceptsNonSexualChildOffenders,acceptsHateCrimeOffenders,isCatered,hasWideStepFreeAccess,hasWideAccessToCommunalAreas,hasStepFreeAccessToCommunalAreas,hasWheelChairAccessibleBathrooms,hasLift,hasTactileFlooring,hasBrailleSignage,hasHearingLoop,status,apCode,qCode -Test AP 1,454 Nader Port,,Quitzonview,OX26 2EQ,51.904735,-1.1635,No,some@emailaddress.com,Greater Manchester,Malvern Hills,,YES,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,NO,YES,NO,NO,NO,NO,YES,active,TEST1,Q095 -Test AP 2,7525 Alba Trail,,Theronborough,WA6 9BQ,53.266459,-2.768905,,some@emailaddress.com,North East,Hambleton,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,NO,YES,YES,NO,NO,NO,YES,active,TEST2,Q100 -Test AP 3,8527 Bell Rapids,,South Myah,ML8 5EP,55.751711,-3.851103,restrictions on offences against sex workers due to location of the AP,some@emailaddress.com,Wales,Tamworth,,NO,YES,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,YES,YES,YES,NO,NO,NO,NO,active,TEST3,Q057 -Test AP 4,306 Destinee Union,,South Devinberg,KA4 8JG,55.599949,-4.376498,,some@emailaddress.com,South Central,Rochford,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,NO,YES,YES,NO,NO,YES,YES,active,TEST4,Q077 -Test AP 5,4023 Green Wells,,Port Carleton,N14 6QW,51.631685,-0.125257,"As an independent AP, cannot take Arsonists who post an imminent risk of further Arson. This is a local decision, I confirmed that there was no insurance issues regarding Arson. The manager just said if there was an Arsonist whose risk was seen as imminent, she would have to check with the Charity who funds the AP",some@emailaddress.com,East Midlands,Carmarthenshire,,YES,YES,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,NO,YES,YES,NO,NO,NO,NO,active,TEST5,Q705 -Test AP 6,42716 Dickens Route,,Bayerstead,WA11 8GJ,53.50205,-2.790471,,some@emailaddress.com,South Central,West Northamptonshire,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,NO,YES,YES,NO,NO,NO,YES,active,TEST6,Q706 -Test AP 7,704 Eleazar Rue,,Bergstromfort,SK11 6TG,53.254466,-2.124048,,some@emailaddress.com,Wales,Plymouth,,YES,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,YES,YES,YES,YES,NO,NO,YES,active,TEST7,Q707 -Test AP 8,069 Braun Flat,,Roobbury,SO15 8PN,50.913966,-1.442888,,some@emailaddress.com,Yorkshire & The Humber,Gravesham,,NO,YES,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,NO,YES,YES,NO,NO,YES,YES,active,TEST8,Q708 -Test AP 9,14063 Edyth Court,,North Hallie,LN13 9AT,53.254737,0.180603,No,some@emailaddress.com,East of England,Norwich,,YES,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,NO,NO,NO,NO,NO,NO,NO,active,TEST9,Q709 -Test AP 10,9317 Bauch Heights,,Mavisworth,TN33 9JN,50.886096,0.424608,No Child RSO's since 2006 - National instruction.,some@emailaddress.com,South West,Rossendale,,YES,NO,NO,NO,NO,YES,YES,NO,YES,YES,NO,NO,NO,NO,NO,NO,NO,NO,NO,active,TEST10,Q710 -Test AP 11,5510 Emmitt Street,,North Gregoryboro,SA13 1NN,51.593159,-3.781082,Rooms 9 to 16 are currently out of use - annexe that contains them is subsiding and is non accesssible - for last 6 months or so.,some@emailaddress.com,Wales,Torridge,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,NO,NO,NO,NO,NO,YES,YES,active,TEST11,Q711 -Test AP 12,307 Annabell Flats,,Zemlaktown,GU34 5EB,51.119205,-1.040455,,some@emailaddress.com,Greater Manchester,Lisburn and Castlereagh,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,YES,YES,NO,NO,NO,YES,NO,active,TEST12,Q712 -Test AP 13,110 Bailey Expressway,,Cordellburgh,GU3 3DZ,51.249544,-0.637553,,some@emailaddress.com,North East,Staffordshire,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,YES,YES,YES,NO,NO,YES,NO,active,TEST13,Q713 -Test AP 14,0300 Blick Camp,,North Moriahhaven,HU11 4XH,53.792705,-0.191504,Westgate notes,some@emailaddress.com,West Midlands,Harrow,,NO,NO,NO,NO,NO,YES,YES,NO,NO,YES,YES,NO,NO,YES,YES,NO,NO,YES,YES,active,TEST14,Q714 -Test AP 15,4169 Joana Branch,,Alfredohaven,IV30 1XX,57.644221,-3.295377,TEST notes,some@emailaddress.com,North East,Bromley,,NO,NO,NO,NO,NO,YES,YES,NO,NO,YES,YES,NO,NO,YES,YES,NO,NO,YES,YES,active,TEST15,Q715 \ No newline at end of file +Test AP 1,454 Nader Port,,Quitzonview,OX26 2EQ,51.904735,-1.1635,No,some@emailaddress.com,Greater Manchester,Malvern Hills,,YES,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,NO,YES,NO,NO,NO,NO,YES,active,TEST1,Q095,MALE +Test AP 2,7525 Alba Trail,,Theronborough,WA6 9BQ,53.266459,-2.768905,,some@emailaddress.com,North East,Hambleton,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,NO,YES,YES,NO,NO,NO,YES,active,TEST2,Q100,MALE +Test AP 3,8527 Bell Rapids,,South Myah,ML8 5EP,55.751711,-3.851103,restrictions on offences against sex workers due to location of the AP,some@emailaddress.com,Wales,Tamworth,,NO,YES,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,YES,YES,YES,NO,NO,NO,NO,active,TEST3,Q057,MALE +Test AP 4,306 Destinee Union,,South Devinberg,KA4 8JG,55.599949,-4.376498,,some@emailaddress.com,South Central,Rochford,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,NO,YES,YES,NO,NO,YES,YES,active,TEST4,Q077,MALE +Test AP 5,4023 Green Wells,,Port Carleton,N14 6QW,51.631685,-0.125257,"As an independent AP, cannot take Arsonists who post an imminent risk of further Arson. This is a local decision, I confirmed that there was no insurance issues regarding Arson. The manager just said if there was an Arsonist whose risk was seen as imminent, she would have to check with the Charity who funds the AP",some@emailaddress.com,East Midlands,Carmarthenshire,,YES,YES,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,NO,YES,YES,NO,NO,NO,NO,active,TEST5,Q705,MALE +Test AP 6,42716 Dickens Route,,Bayerstead,WA11 8GJ,53.50205,-2.790471,,some@emailaddress.com,South Central,West Northamptonshire,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,NO,YES,YES,NO,NO,NO,YES,active,TEST6,Q706,MALE +Test AP 7,704 Eleazar Rue,,Bergstromfort,SK11 6TG,53.254466,-2.124048,,some@emailaddress.com,Wales,Plymouth,,YES,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,YES,YES,YES,YES,NO,NO,YES,active,TEST7,Q707,MALE +Test AP 8,069 Braun Flat,,Roobbury,SO15 8PN,50.913966,-1.442888,,some@emailaddress.com,Yorkshire & The Humber,Gravesham,,NO,YES,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,NO,YES,YES,NO,NO,YES,YES,active,TEST8,Q708,MALE +Test AP 9,14063 Edyth Court,,North Hallie,LN13 9AT,53.254737,0.180603,No,some@emailaddress.com,East of England,Norwich,,YES,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,NO,NO,NO,NO,NO,NO,NO,active,TEST9,Q709,MALE +Test AP 10,9317 Bauch Heights,,Mavisworth,TN33 9JN,50.886096,0.424608,No Child RSO's since 2006 - National instruction.,some@emailaddress.com,South West,Rossendale,,YES,NO,NO,NO,NO,YES,YES,NO,YES,YES,NO,NO,NO,NO,NO,NO,NO,NO,NO,active,TEST10,Q710,MALE +Test AP 11,5510 Emmitt Street,,North Gregoryboro,SA13 1NN,51.593159,-3.781082,Rooms 9 to 16 are currently out of use - annexe that contains them is subsiding and is non accesssible - for last 6 months or so.,some@emailaddress.com,Wales,Torridge,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,NO,NO,NO,NO,NO,YES,YES,active,TEST11,Q711,MALE +Test AP 12,307 Annabell Flats,,Zemlaktown,GU34 5EB,51.119205,-1.040455,,some@emailaddress.com,Greater Manchester,Lisburn and Castlereagh,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,YES,YES,NO,NO,NO,YES,NO,active,TEST12,Q712,MALE +Test AP 13,110 Bailey Expressway,,Cordellburgh,GU3 3DZ,51.249544,-0.637553,,some@emailaddress.com,North East,Staffordshire,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,YES,YES,YES,NO,NO,YES,NO,active,TEST13,Q713,MALE +Test AP 14,0300 Blick Camp,,North Moriahhaven,HU11 4XH,53.792705,-0.191504,Westgate notes,some@emailaddress.com,West Midlands,Harrow,,NO,NO,NO,NO,NO,YES,YES,NO,NO,YES,YES,NO,NO,YES,YES,NO,NO,YES,YES,active,TEST14,Q714,MALE +Test AP 15,4169 Joana Branch,,Alfredohaven,IV30 1XX,57.644221,-3.295377,TEST notes,some@emailaddress.com,North East,Bromley,,NO,NO,NO,NO,NO,YES,YES,NO,NO,YES,YES,NO,NO,YES,YES,NO,NO,YES,YES,active,TEST15,Q715,MALE \ No newline at end of file diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/factory/ApprovedPremisesEntityFactory.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/factory/ApprovedPremisesEntityFactory.kt index 4a3fafc018a..7fd5cf5ccc2 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/factory/ApprovedPremisesEntityFactory.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/factory/ApprovedPremisesEntityFactory.kt @@ -8,6 +8,7 @@ import org.locationtech.jts.geom.Point import org.locationtech.jts.geom.PrecisionModel import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.PropertyStatus import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.ApprovedPremisesEntity +import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.ApprovedPremisesGender import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.CharacteristicEntity import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.LocalAuthorityAreaEntity import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.ProbationRegionEntity @@ -37,6 +38,7 @@ class ApprovedPremisesEntityFactory : Factory { private var characteristics: Yielded> = { mutableListOf() } private var status: Yielded = { randomOf(PropertyStatus.values().asList()) } private var point: Yielded? = null + private var gender: Yielded = { ApprovedPremisesGender.MALE } fun withDefaults() = apply { withDefaultProbationRegion() @@ -173,5 +175,6 @@ class ApprovedPremisesEntityFactory : Factory { status = this.status(), point = this.point?.invoke() ?: GeometryFactory(PrecisionModel(PrecisionModel.FLOATING), 4326) .createPoint(Coordinate(this.latitude(), this.longitude())), + gender = this.gender(), ) } diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/cas1/seed/SeedApprovedPremisesTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/cas1/seed/SeedApprovedPremisesTest.kt index fe673f9cd3a..9435d55708f 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/cas1/seed/SeedApprovedPremisesTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/cas1/seed/SeedApprovedPremisesTest.kt @@ -13,6 +13,7 @@ import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.PropertyStatus import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.SeedFileType import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Given a Probation Region` import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.seed.SeedTestBase +import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.ApprovedPremisesGender import uk.gov.justice.digital.hmpps.approvedpremisesapi.seed.CsvBuilder import uk.gov.justice.digital.hmpps.approvedpremisesapi.seed.cas1.ApprovedPremisesSeedCsvRow import uk.gov.justice.digital.hmpps.approvedpremisesapi.util.randomDouble @@ -440,6 +441,7 @@ class ApprovedPremisesSeedCsvRowFactory : Factory { private var status: Yielded = { PropertyStatus.active } private var apCode: Yielded = { randomStringMultiCaseWithNumbers(6) } private var qCode: Yielded = { randomStringMultiCaseWithNumbers(6) } + private var gender: Yielded = { ApprovedPremisesGender.MALE } fun withName(name: String) = apply { this.name = { name } @@ -530,5 +532,6 @@ class ApprovedPremisesSeedCsvRowFactory : Factory { status = this.status(), apCode = this.apCode(), qCode = this.qCode(), + gender = this.gender(), ) } From 4b163739e81ac62e996199f53cbe1b72ead7309a Mon Sep 17 00:00:00 2001 From: davidatkinsuk Date: Wed, 18 Sep 2024 08:26:35 +0100 Subject: [PATCH 4/7] Add API to retrieve CAS1 premise summaries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This endpoint is optionally filterable on gender, required to support women’s estate functionality. --- .../controller/cas1/Cas1PremisesController.kt | 19 +++ .../jpa/entity/PremisesEntity.kt | 9 ++ .../service/PremisesService.kt | 1 + .../service/cas1/Cas1PremisesService.kt | 9 +- .../cas1/Cas1PremisesTransformer.kt | 12 ++ src/main/resources/static/cas1-api.yml | 35 +++++ src/main/resources/static/cas1-schemas.yml | 21 ++- .../static/codegen/built-cas1-api-spec.yml | 56 +++++++- .../factory/ApprovedPremisesEntityFactory.kt | 4 + .../integration/cas1/Cas1PremisesTest.kt | 120 ++++++++++++++++++ .../cas1/seed/SeedApprovedPremisesTest.kt | 4 +- .../service/cas1/Cas1PremisesServiceTest.kt | 23 +--- .../cas1/Cas1PremisesTransformerTest.kt | 34 ++++- 13 files changed, 322 insertions(+), 25 deletions(-) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/controller/cas1/Cas1PremisesController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/controller/cas1/Cas1PremisesController.kt index 319a5c687fb..6489473aca9 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/controller/cas1/Cas1PremisesController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/controller/cas1/Cas1PremisesController.kt @@ -3,7 +3,10 @@ package uk.gov.justice.digital.hmpps.approvedpremisesapi.controller.cas1 import org.springframework.http.ResponseEntity import org.springframework.stereotype.Service import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.cas1.PremisesCas1Delegate +import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.Cas1ApprovedPremisesGender +import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.Cas1PremisesBasicSummary import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.Cas1PremisesSummary +import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.ApprovedPremisesGender import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.UserPermission import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.UserAccessService import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.cas1.Cas1PremisesService @@ -29,4 +32,20 @@ class Cas1PremisesController( ), ) } + + override fun getPremisesSummaries(gender: Cas1ApprovedPremisesGender?): ResponseEntity> { + return ResponseEntity + .ok() + .body( + cas1PremisesService.getPremises( + gender = when (gender) { + Cas1ApprovedPremisesGender.male -> ApprovedPremisesGender.MALE + Cas1ApprovedPremisesGender.female -> ApprovedPremisesGender.FEMALE + null -> null + }, + ).map { + cas1PremisesTransformer.toPremiseBasicSummary(it) + }, + ) + } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/jpa/entity/PremisesEntity.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/jpa/entity/PremisesEntity.kt index b56b9dd80a7..bfb62214abc 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/jpa/entity/PremisesEntity.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/jpa/entity/PremisesEntity.kt @@ -106,6 +106,7 @@ interface PremisesRepository : JpaRepository { ) fun findAllApprovedPremisesSummary(probationRegionId: UUID?, apAreaId: UUID?): List + @Deprecated("Use ApprovedPremisesRepository") @Query("SELECT p as premises FROM ApprovedPremisesEntity p WHERE p.id = :id") fun findApprovedPremisesByIdOrNull(id: UUID): ApprovedPremisesEntity? @@ -175,6 +176,14 @@ where fun getBookingSummariesForPremisesId(premisesId: UUID): List } +@Repository +interface ApprovedPremisesRepository : JpaRepository { + fun findByGender(gender: ApprovedPremisesGender): List + + @Query("SELECT p as premises FROM ApprovedPremisesEntity p WHERE :gender IS NULL OR p.gender = :gender") + fun findForSummaries(gender: ApprovedPremisesGender?): List +} + @Entity @Table(name = "premises") @DiscriminatorColumn(name = "service") diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/service/PremisesService.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/service/PremisesService.kt index 59308985437..0e41f53d757 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/service/PremisesService.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/service/PremisesService.kt @@ -80,6 +80,7 @@ class PremisesService( premisesRepository.findAllByProbationRegionAndType(probationRegionId, it) } ?: listOf() + @Deprecated("Callers should instead call Cas1PremisesSevice") fun getApprovedPremises(premisesId: UUID) = premisesRepository.findApprovedPremisesByIdOrNull(premisesId) fun getPremises(premisesId: UUID): PremisesEntity? = premisesRepository.findByIdOrNull(premisesId) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/service/cas1/Cas1PremisesService.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/service/cas1/Cas1PremisesService.kt index 208839b641a..f9032bbbcb5 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/service/cas1/Cas1PremisesService.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/service/cas1/Cas1PremisesService.kt @@ -3,20 +3,21 @@ package uk.gov.justice.digital.hmpps.approvedpremisesapi.service.cas1 import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Service import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.ApprovedPremisesEntity -import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.PremisesRepository +import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.ApprovedPremisesGender +import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.ApprovedPremisesRepository import uk.gov.justice.digital.hmpps.approvedpremisesapi.results.CasResult import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.PremisesService import java.util.UUID @Service class Cas1PremisesService( - val premisesRepository: PremisesRepository, + val premisesRepository: ApprovedPremisesRepository, val premisesService: PremisesService, val cas1OutOfServiceBedService: Cas1OutOfServiceBedService, ) { fun getPremisesSummary(premisesId: UUID): CasResult { val premise = premisesRepository.findByIdOrNull(premisesId) - if (premise !is ApprovedPremisesEntity) return CasResult.NotFound("premises", premisesId.toString()) + ?: return CasResult.NotFound("premises", premisesId.toString()) val bedCount = premisesService.getBedCount(premise) val outOfServiceBedsCount = cas1OutOfServiceBedService.getActiveOutOfServiceBedsCountForPremisesId(premisesId) @@ -31,6 +32,8 @@ class Cas1PremisesService( ) } + fun getPremises(gender: ApprovedPremisesGender?) = premisesRepository.findForSummaries(gender) + data class Cas1PremisesSummaryInfo( val entity: ApprovedPremisesEntity, val bedCount: Int, diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/transformer/cas1/Cas1PremisesTransformer.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/transformer/cas1/Cas1PremisesTransformer.kt index 36e6afd25a0..227c50e1143 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/transformer/cas1/Cas1PremisesTransformer.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/transformer/cas1/Cas1PremisesTransformer.kt @@ -1,7 +1,10 @@ package uk.gov.justice.digital.hmpps.approvedpremisesapi.transformer.cas1 import org.springframework.stereotype.Service +import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.Cas1PremisesBasicSummary import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.Cas1PremisesSummary +import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.NamedId +import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.PremisesEntity import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.cas1.Cas1PremisesService import uk.gov.justice.digital.hmpps.approvedpremisesapi.transformer.ApAreaTransformer @@ -22,4 +25,13 @@ class Cas1PremisesTransformer( apArea = apAreaTransformer.transformJpaToApi(entity.probationRegion.apArea!!), ) } + + fun toPremiseBasicSummary(entity: PremisesEntity): Cas1PremisesBasicSummary { + val apArea = entity.probationRegion.apArea!! + return Cas1PremisesBasicSummary( + id = entity.id, + name = entity.name, + apArea = NamedId(apArea.id, apArea.name), + ) + } } diff --git a/src/main/resources/static/cas1-api.yml b/src/main/resources/static/cas1-api.yml index f188439f0fd..892b87b1f0d 100644 --- a/src/main/resources/static/cas1-api.yml +++ b/src/main/resources/static/cas1-api.yml @@ -82,6 +82,41 @@ paths: $ref: '_shared.yml#/components/responses/500Response' x-codegen-request-body-name: body + /premises/summary: + get: + description: Provide a summary of all premises, with optional filtering + tags: + - premises + operationId: "getPremisesSummaries" + parameters: + - name: gender + in: query + required: false + description: If specified, only return premises for the corresponding gender + schema: + $ref: 'cas1-schemas.yml#/components/schemas/Cas1ApprovedPremisesGender' + responses: + 200: + description: successful operation + content: + 'application/json': + schema: + type: array + items: + $ref: 'cas1-schemas.yml#/components/schemas/Cas1PremisesBasicSummary' + 400: + description: invalid params + content: + 'application/problem+json': + schema: + $ref: '_shared.yml#/components/schemas/ValidationError' + 401: + $ref: '_shared.yml#/components/responses/401Response' + 403: + $ref: '_shared.yml#/components/responses/403Response' + 500: + $ref: '_shared.yml#/components/responses/500Response' + /premises/{premisesId}/lost-beds: post: deprecated: true diff --git a/src/main/resources/static/cas1-schemas.yml b/src/main/resources/static/cas1-schemas.yml index 75c36643037..7bb85610686 100644 --- a/src/main/resources/static/cas1-schemas.yml +++ b/src/main/resources/static/cas1-schemas.yml @@ -1,5 +1,20 @@ components: schemas: + Cas1PremisesBasicSummary: + type: object + properties: + id: + type: string + format: uuid + name: + type: string + example: Hope House + apArea: + $ref: '_shared.yml#/components/schemas/NamedId' + required: + - id + - name + - apArea Cas1PremisesSearchResultSummary: type: object properties: @@ -442,4 +457,8 @@ components: type: string required: - staffCode - + Cas1ApprovedPremisesGender: + type: string + enum: + - male + - female diff --git a/src/main/resources/static/codegen/built-cas1-api-spec.yml b/src/main/resources/static/codegen/built-cas1-api-spec.yml index 4ac856131ed..50ff7f3fe71 100644 --- a/src/main/resources/static/codegen/built-cas1-api-spec.yml +++ b/src/main/resources/static/codegen/built-cas1-api-spec.yml @@ -84,6 +84,41 @@ paths: $ref: '#/components/responses/500Response' x-codegen-request-body-name: body + /premises/summary: + get: + description: Provide a summary of all premises, with optional filtering + tags: + - premises + operationId: "getPremisesSummaries" + parameters: + - name: gender + in: query + required: false + description: If specified, only return premises for the corresponding gender + schema: + $ref: '#/components/schemas/Cas1ApprovedPremisesGender' + responses: + 200: + description: successful operation + content: + 'application/json': + schema: + type: array + items: + $ref: '#/components/schemas/Cas1PremisesBasicSummary' + 400: + description: invalid params + content: + 'application/problem+json': + schema: + $ref: '#/components/schemas/ValidationError' + 401: + $ref: '#/components/responses/401Response' + 403: + $ref: '#/components/responses/403Response' + 500: + $ref: '#/components/responses/500Response' + /premises/{premisesId}/lost-beds: post: deprecated: true @@ -6157,6 +6192,21 @@ components: enum: - sharedProperty - singleOccupancy + Cas1PremisesBasicSummary: + type: object + properties: + id: + type: string + format: uuid + name: + type: string + example: Hope House + apArea: + $ref: '#/components/schemas/NamedId' + required: + - id + - name + - apArea Cas1PremisesSearchResultSummary: type: object properties: @@ -6599,4 +6649,8 @@ components: type: string required: - staffCode - + Cas1ApprovedPremisesGender: + type: string + enum: + - male + - female diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/factory/ApprovedPremisesEntityFactory.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/factory/ApprovedPremisesEntityFactory.kt index 7fd5cf5ccc2..889301bf9bf 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/factory/ApprovedPremisesEntityFactory.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/factory/ApprovedPremisesEntityFactory.kt @@ -153,6 +153,10 @@ class ApprovedPremisesEntityFactory : Factory { this.emailAddress = { emailAddress } } + fun withGender(gender: ApprovedPremisesGender) = apply { + this.gender = { gender } + } + override fun produce(): ApprovedPremisesEntity = ApprovedPremisesEntity( id = this.id(), name = this.name(), diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/cas1/Cas1PremisesTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/cas1/Cas1PremisesTest.kt index 0bf72dd9389..ff4ac820825 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/cas1/Cas1PremisesTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/cas1/Cas1PremisesTest.kt @@ -4,14 +4,17 @@ import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test +import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.Cas1PremisesBasicSummary import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.Cas1PremisesSummary import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.InitialiseDatabasePerClassTestBase import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.IntegrationTestBase import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Given a User` import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Given an AP Area` import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.ApprovedPremisesEntity +import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.ApprovedPremisesGender import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.UserRole.CAS1_ASSESSOR import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.UserRole.CAS1_FUTURE_MANAGER +import uk.gov.justice.digital.hmpps.approvedpremisesapi.util.bodyAsListOfObjects import uk.gov.justice.digital.hmpps.approvedpremisesapi.util.roundNanosToMillisToAccountForLossOfPrecisionInPostgres import java.time.LocalDate import java.time.OffsetDateTime @@ -107,4 +110,121 @@ class Cas1PremisesTest : IntegrationTestBase() { assertThat(summary.apArea.name).isEqualTo("The ap area name") } } + + @Nested + inner class GetPremisesSummaries : InitialiseDatabasePerClassTestBase() { + + lateinit var premises1Male: ApprovedPremisesEntity + lateinit var premises2Female: ApprovedPremisesEntity + lateinit var premises3Male: ApprovedPremisesEntity + + @BeforeAll + fun setupTestData() { + val region1 = probationRegionEntityFactory.produceAndPersist { + withYieldedApArea { + apAreaEntityFactory.produceAndPersist { + withName("the ap area name 1") + } + } + } + + val region2 = probationRegionEntityFactory.produceAndPersist { + withYieldedApArea { + apAreaEntityFactory.produceAndPersist { + withName("the ap area name 2") + } + } + } + + premises1Male = approvedPremisesEntityFactory.produceAndPersist { + withName("the premises name 1") + withGender(ApprovedPremisesGender.MALE) + withYieldedProbationRegion { region1 } + withYieldedLocalAuthorityArea { localAuthorityEntityFactory.produceAndPersist() } + } + + premises2Female = approvedPremisesEntityFactory.produceAndPersist { + withName("the premises name 2") + withGender(ApprovedPremisesGender.FEMALE) + withYieldedProbationRegion { region2 } + withYieldedLocalAuthorityArea { localAuthorityEntityFactory.produceAndPersist() } + } + + premises3Male = approvedPremisesEntityFactory.produceAndPersist { + withName("the premises name 3") + withGender(ApprovedPremisesGender.MALE) + withYieldedProbationRegion { region2 } + withYieldedLocalAuthorityArea { localAuthorityEntityFactory.produceAndPersist() } + } + } + + @Test + fun `Returns premises summaries with no filters applied`() { + val (_, jwt) = `Given a User`() + + val summaries = webTestClient.get() + .uri("/cas1/premises/summary") + .header("Authorization", "Bearer $jwt") + .exchange() + .expectStatus() + .isOk + .bodyAsListOfObjects() + + assertThat(summaries).hasSize(3) + + assertThat(summaries[0].id).isEqualTo(premises1Male.id) + assertThat(summaries[0].name).isEqualTo("the premises name 1") + assertThat(summaries[0].apArea.name).isEqualTo("the ap area name 1") + + assertThat(summaries[1].id).isEqualTo(premises2Female.id) + assertThat(summaries[1].name).isEqualTo("the premises name 2") + assertThat(summaries[1].apArea.name).isEqualTo("the ap area name 2") + + assertThat(summaries[2].id).isEqualTo(premises3Male.id) + assertThat(summaries[2].name).isEqualTo("the premises name 3") + assertThat(summaries[2].apArea.name).isEqualTo("the ap area name 2") + } + + @Test + fun `Returns premises summaries where gender is male`() { + val (_, jwt) = `Given a User`() + + val summaries = webTestClient.get() + .uri("/cas1/premises/summary?gender=male") + .header("Authorization", "Bearer $jwt") + .exchange() + .expectStatus() + .isOk + .bodyAsListOfObjects() + + assertThat(summaries).hasSize(2) + + assertThat(summaries[0].id).isEqualTo(premises1Male.id) + assertThat(summaries[0].name).isEqualTo("the premises name 1") + assertThat(summaries[0].apArea.name).isEqualTo("the ap area name 1") + + assertThat(summaries[1].id).isEqualTo(premises3Male.id) + assertThat(summaries[1].name).isEqualTo("the premises name 3") + assertThat(summaries[1].apArea.name).isEqualTo("the ap area name 2") + } + + @Test + fun `Returns premises summaries where gender is female`() { + val (_, jwt) = `Given a User`() + + val summaries = webTestClient.get() + .uri("/cas1/premises/summary?gender=female") + .header("Authorization", "Bearer $jwt") + .exchange() + .expectStatus() + .isOk + .bodyAsListOfObjects() + + assertThat(summaries).hasSize(1) + + assertThat(summaries[0].id).isEqualTo(premises2Female.id) + assertThat(summaries[0].name).isEqualTo("the premises name 2") + assertThat(summaries[0].apArea.name).isEqualTo("the ap area name 2") + } + } } diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/cas1/seed/SeedApprovedPremisesTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/cas1/seed/SeedApprovedPremisesTest.kt index 9435d55708f..fc1f5e20e60 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/cas1/seed/SeedApprovedPremisesTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/cas1/seed/SeedApprovedPremisesTest.kt @@ -201,7 +201,7 @@ class SeedApprovedPremisesTest : SeedTestBase() { "isRecoveryFocussed, isSuitableForVulnerable, acceptsSexOffenders, acceptsChildSexOffenders, " + "acceptsNonSexualChildOffenders, acceptsHateCrimeOffenders, isCatered, hasWideStepFreeAccess, " + "hasWideAccessToCommunalAreas, hasStepFreeAccessToCommunalAreas, hasWheelChairAccessibleBathrooms, " + - "hasLift, hasTactileFlooring, hasBrailleSignage, hasHearingLoop, status, latitude, longitude]" + "hasLift, hasTactileFlooring, hasBrailleSignage, hasHearingLoop, status, latitude, longitude, gender]" assertThat(logEntries) .withFailMessage("-> logEntries actually contains: $logEntries") @@ -362,6 +362,7 @@ class SeedApprovedPremisesTest : SeedTestBase() { "status", "apCode", "qCode", + "gender", ) .newRow() @@ -400,6 +401,7 @@ class SeedApprovedPremisesTest : SeedTestBase() { .withQuotedField(it.status.value) .withQuotedField(it.apCode) .withQuotedField(it.qCode) + .withQuotedField(it.gender) .newRow() } diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/unit/service/cas1/Cas1PremisesServiceTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/unit/service/cas1/Cas1PremisesServiceTest.kt index b5c0fee25a4..38f69240ad3 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/unit/service/cas1/Cas1PremisesServiceTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/unit/service/cas1/Cas1PremisesServiceTest.kt @@ -10,8 +10,7 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith import org.springframework.data.repository.findByIdOrNull import uk.gov.justice.digital.hmpps.approvedpremisesapi.factory.ApprovedPremisesEntityFactory -import uk.gov.justice.digital.hmpps.approvedpremisesapi.factory.TemporaryAccommodationPremisesEntityFactory -import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.PremisesRepository +import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.ApprovedPremisesRepository import uk.gov.justice.digital.hmpps.approvedpremisesapi.results.CasResult import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.PremisesService import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.cas1.Cas1OutOfServiceBedService @@ -22,7 +21,7 @@ import java.util.UUID class Cas1PremisesServiceTest { @MockK - lateinit var premisesRepository: PremisesRepository + lateinit var approvedPremisesRepository: ApprovedPremisesRepository @MockK lateinit var premisesService: PremisesService @@ -34,7 +33,7 @@ class Cas1PremisesServiceTest { lateinit var service: Cas1PremisesService companion object CONSTANTS { - val PREMISES_ID = UUID.randomUUID() + val PREMISES_ID: UUID = UUID.randomUUID() } @Nested @@ -42,19 +41,7 @@ class Cas1PremisesServiceTest { @Test fun `premises not found return error`() { - every { premisesRepository.findByIdOrNull(PREMISES_ID) } returns null - - val result = service.getPremisesSummary(PREMISES_ID) - - assertThat(result).isInstanceOf(CasResult.NotFound::class.java) - } - - @Test - fun `premises not cas1 return error`() { - every { premisesRepository.findByIdOrNull(PREMISES_ID) } returns - TemporaryAccommodationPremisesEntityFactory() - .withDefaults() - .produce() + every { approvedPremisesRepository.findByIdOrNull(PREMISES_ID) } returns null val result = service.getPremisesSummary(PREMISES_ID) @@ -71,7 +58,7 @@ class Cas1PremisesServiceTest { .withPostcode("LE11 1PO") .produce() - every { premisesRepository.findByIdOrNull(PREMISES_ID) } returns premises + every { approvedPremisesRepository.findByIdOrNull(PREMISES_ID) } returns premises every { premisesService.getBedCount(premises) } returns 56 every { cas1OutOfServiceBedService.getActiveOutOfServiceBedsCountForPremisesId(PREMISES_ID) } returns 4 diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/unit/transformer/cas1/Cas1PremisesTransformerTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/unit/transformer/cas1/Cas1PremisesTransformerTest.kt index 8d5ea90c45b..14cd32fd389 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/unit/transformer/cas1/Cas1PremisesTransformerTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/unit/transformer/cas1/Cas1PremisesTransformerTest.kt @@ -28,6 +28,7 @@ class Cas1PremisesTransformerTest { lateinit var transformer: Cas1PremisesTransformer companion object CONSTANTS { + val AP_AREA_ID: UUID = UUID.randomUUID() val PREMISES_ID: UUID = UUID.randomUUID() } @@ -35,7 +36,7 @@ class Cas1PremisesTransformerTest { inner class ToPremisesSummary { @Test - fun `success`() { + fun success() { val apArea = ApAreaEntityFactory().produce() val probationRegion = ProbationRegionEntityFactory() @@ -74,4 +75,35 @@ class Cas1PremisesTransformerTest { assertThat(result.apArea).isEqualTo(expectedApArea) } } + + @Nested + inner class ToPremiseBasicSummary { + + @Test + fun success() { + val apArea = ApAreaEntityFactory() + .withId(AP_AREA_ID) + .withName("the ap area name") + .produce() + + val probationRegion = ProbationRegionEntityFactory() + .withDefaults() + .withApArea(apArea) + .produce() + + val premises = ApprovedPremisesEntityFactory() + .withDefaults() + .withId(PREMISES_ID) + .withName("the name") + .withProbationRegion(probationRegion) + .produce() + + val result = transformer.toPremiseBasicSummary(premises) + + assertThat(result.id).isEqualTo(premises.id) + assertThat(result.name).isEqualTo("the name") + assertThat(result.apArea.id).isEqualTo(AP_AREA_ID) + assertThat(result.apArea.name).isEqualTo("the ap area name") + } + } } From 52585557ac562aeaf7937b0bdcef24238a6b1765 Mon Sep 17 00:00:00 2001 From: davidatkinsuk Date: Wed, 18 Sep 2024 12:59:59 +0100 Subject: [PATCH 5/7] Use CAS1 specific repo to get Approved Premises --- .../jpa/entity/PremisesEntity.kt | 4 -- .../service/PremisesService.kt | 3 -- .../service/cas1/Cas1PremisesService.kt | 2 + .../service/cas1/Cas1SpaceBookingService.kt | 13 +++---- .../service/Cas1SpaceBookingServiceTest.kt | 38 +++++++++---------- 5 files changed, 27 insertions(+), 33 deletions(-) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/jpa/entity/PremisesEntity.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/jpa/entity/PremisesEntity.kt index bfb62214abc..fb083e351e2 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/jpa/entity/PremisesEntity.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/jpa/entity/PremisesEntity.kt @@ -106,10 +106,6 @@ interface PremisesRepository : JpaRepository { ) fun findAllApprovedPremisesSummary(probationRegionId: UUID?, apAreaId: UUID?): List - @Deprecated("Use ApprovedPremisesRepository") - @Query("SELECT p as premises FROM ApprovedPremisesEntity p WHERE p.id = :id") - fun findApprovedPremisesByIdOrNull(id: UUID): ApprovedPremisesEntity? - @Query("SELECT p as premises, $BED_COUNT_QUERY as bedCount FROM PremisesEntity p WHERE TYPE(p) = :type") fun findAllByType(type: Class): List diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/service/PremisesService.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/service/PremisesService.kt index 0e41f53d757..8f2f57b2d92 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/service/PremisesService.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/service/PremisesService.kt @@ -80,9 +80,6 @@ class PremisesService( premisesRepository.findAllByProbationRegionAndType(probationRegionId, it) } ?: listOf() - @Deprecated("Callers should instead call Cas1PremisesSevice") - fun getApprovedPremises(premisesId: UUID) = premisesRepository.findApprovedPremisesByIdOrNull(premisesId) - fun getPremises(premisesId: UUID): PremisesEntity? = premisesRepository.findByIdOrNull(premisesId) fun getPremisesSummary(premisesId: UUID): List = premisesRepository.getBookingSummariesForPremisesId(premisesId) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/service/cas1/Cas1PremisesService.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/service/cas1/Cas1PremisesService.kt index f9032bbbcb5..40a1827055a 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/service/cas1/Cas1PremisesService.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/service/cas1/Cas1PremisesService.kt @@ -34,6 +34,8 @@ class Cas1PremisesService( fun getPremises(gender: ApprovedPremisesGender?) = premisesRepository.findForSummaries(gender) + fun findPremiseById(id: UUID) = premisesRepository.findByIdOrNull(id) + data class Cas1PremisesSummaryInfo( val entity: ApprovedPremisesEntity, val bedCount: Int, diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/service/cas1/Cas1SpaceBookingService.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/service/cas1/Cas1SpaceBookingService.kt index 5ee4bde0f74..55634c5685e 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/service/cas1/Cas1SpaceBookingService.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/service/cas1/Cas1SpaceBookingService.kt @@ -22,7 +22,6 @@ import uk.gov.justice.digital.hmpps.approvedpremisesapi.model.PaginationMetadata import uk.gov.justice.digital.hmpps.approvedpremisesapi.model.validatedCasResult import uk.gov.justice.digital.hmpps.approvedpremisesapi.results.CasResult import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.PlacementRequestService -import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.PremisesService import uk.gov.justice.digital.hmpps.approvedpremisesapi.util.PageCriteria import uk.gov.justice.digital.hmpps.approvedpremisesapi.util.getMetadata import java.time.LocalDate @@ -32,7 +31,7 @@ import java.util.UUID @Service class Cas1SpaceBookingService( - private val premisesService: PremisesService, + private val cas1PremisesService: Cas1PremisesService, private val placementRequestService: PlacementRequestService, private val cas1SpaceBookingRepository: Cas1SpaceBookingRepository, private val cas1SpaceSearchRepository: Cas1SpaceSearchRepository, @@ -51,7 +50,7 @@ class Cas1SpaceBookingService( departureDate: LocalDate, createdBy: UserEntity, ): CasResult = validatedCasResult { - val premises = premisesService.getApprovedPremises(premisesId) + val premises = cas1PremisesService.findPremiseById(premisesId) if (premises == null) { "$.premisesId" hasValidationError "doesNotExist" } @@ -133,7 +132,7 @@ class Cas1SpaceBookingService( bookingId: UUID, cas1NewArrival: Cas1NewArrival, ): CasResult = validatedCasResult { - val premises = premisesService.getApprovedPremises(premisesId) + val premises = cas1PremisesService.findPremiseById(premisesId) if (premises == null) { "$.premisesId" hasValidationError "doesNotExist" } @@ -180,7 +179,7 @@ class Cas1SpaceBookingService( bookingId: UUID, cas1NewDeparture: Cas1NewDeparture, ): CasResult = validatedCasResult { - val premises = premisesService.getApprovedPremises(premisesId) + val premises = cas1PremisesService.findPremiseById(premisesId) if (premises == null) { "$.premisesId" hasValidationError "doesNotExist" } @@ -239,7 +238,7 @@ class Cas1SpaceBookingService( filterCriteria: SpaceBookingFilterCriteria, pageCriteria: PageCriteria, ): CasResult, PaginationMetadata?>> { - if (premisesService.getApprovedPremises(premisesId) == null) return CasResult.NotFound("premises", premisesId.toString()) + if (cas1PremisesService.findPremiseById(premisesId) == null) return CasResult.NotFound("premises", premisesId.toString()) val page = cas1SpaceBookingRepository.search( filterCriteria.residency?.name, @@ -265,7 +264,7 @@ class Cas1SpaceBookingService( } fun getBooking(premisesId: UUID, bookingId: UUID): CasResult { - if (premisesService.getApprovedPremises(premisesId) !is ApprovedPremisesEntity) return CasResult.NotFound("premises", premisesId.toString()) + if (cas1PremisesService.findPremiseById(premisesId) !is ApprovedPremisesEntity) return CasResult.NotFound("premises", premisesId.toString()) val booking = cas1SpaceBookingRepository.findByIdOrNull(bookingId) ?: return CasResult.NotFound("booking", bookingId.toString()) diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/unit/service/Cas1SpaceBookingServiceTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/unit/service/Cas1SpaceBookingServiceTest.kt index a2df4175046..93cefff60fe 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/unit/service/Cas1SpaceBookingServiceTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/unit/service/Cas1SpaceBookingServiceTest.kt @@ -40,11 +40,11 @@ import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.cas1.Cas1Spac import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.cas1.SpaceAvailability import uk.gov.justice.digital.hmpps.approvedpremisesapi.results.CasResult import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.PlacementRequestService -import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.PremisesService import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.cas1.BlockingReason import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.cas1.Cas1ApplicationStatusService import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.cas1.Cas1BookingDomainEventService import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.cas1.Cas1BookingEmailService +import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.cas1.Cas1PremisesService import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.cas1.Cas1SpaceBookingManagementDomainEventService import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.cas1.Cas1SpaceBookingService import uk.gov.justice.digital.hmpps.approvedpremisesapi.util.isWithinTheLastMinute @@ -58,7 +58,7 @@ import java.util.UUID @ExtendWith(MockKExtension::class) class Cas1SpaceBookingServiceTest { @MockK - private lateinit var premisesService: PremisesService + private lateinit var cas1PremisesService: Cas1PremisesService @MockK private lateinit var placementRequestService: PlacementRequestService @@ -106,7 +106,7 @@ class Cas1SpaceBookingServiceTest { .withDefaults() .produce() - every { premisesService.getApprovedPremises(any()) } returns null + every { cas1PremisesService.findPremiseById(any()) } returns null every { placementRequestService.getPlacementRequestOrNull(placementRequest.id) } returns placementRequest val result = service.createNewBooking( @@ -135,7 +135,7 @@ class Cas1SpaceBookingServiceTest { .withDefaults() .produce() - every { premisesService.getApprovedPremises(premises.id) } returns premises + every { cas1PremisesService.findPremiseById(premises.id) } returns premises every { placementRequestService.getPlacementRequestOrNull(any()) } returns null val result = service.createNewBooking( @@ -168,7 +168,7 @@ class Cas1SpaceBookingServiceTest { .withDefaults() .produce() - every { premisesService.getApprovedPremises(premises.id) } returns premises + every { cas1PremisesService.findPremiseById(premises.id) } returns premises every { placementRequestService.getPlacementRequestOrNull(placementRequest.id) } returns placementRequest val result = service.createNewBooking( @@ -206,7 +206,7 @@ class Cas1SpaceBookingServiceTest { .withPlacementRequest(placementRequest) .produce() - every { premisesService.getApprovedPremises(premises.id) } returns premises + every { cas1PremisesService.findPremiseById(premises.id) } returns premises every { placementRequestService.getPlacementRequestOrNull(placementRequest.id) } returns placementRequest every { spaceBookingRepository.findByPremisesIdAndPlacementRequestId(premises.id, placementRequest.id) } returns existingSpaceBooking @@ -249,7 +249,7 @@ class Cas1SpaceBookingServiceTest { premisesId = premises.id, ) - every { premisesService.getApprovedPremises(premises.id) } returns premises + every { cas1PremisesService.findPremiseById(premises.id) } returns premises every { placementRequestService.getPlacementRequestOrNull(placementRequest.id) } returns placementRequest every { spaceBookingRepository.findByPremisesIdAndPlacementRequestId(premises.id, placementRequest.id) } returns null @@ -315,7 +315,7 @@ class Cas1SpaceBookingServiceTest { @Test fun `approved premises not found return error`() { - every { premisesService.getApprovedPremises(PREMISES_ID) } returns null + every { cas1PremisesService.findPremiseById(PREMISES_ID) } returns null val result = service.search( PREMISES_ID, @@ -342,7 +342,7 @@ class Cas1SpaceBookingServiceTest { inputSortField: Cas1SpaceBookingSummarySortField, sqlSortField: String, ) { - every { premisesService.getApprovedPremises(PREMISES_ID) } returns ApprovedPremisesEntityFactory().withDefaults().produce() + every { cas1PremisesService.findPremiseById(PREMISES_ID) } returns ApprovedPremisesEntityFactory().withDefaults().produce() val results = PageImpl( listOf( @@ -384,7 +384,7 @@ class Cas1SpaceBookingServiceTest { @Test fun `Returns not found error if premises with the given ID doesn't exist`() { - every { premisesService.getApprovedPremises(any()) } returns null + every { cas1PremisesService.findPremiseById(any()) } returns null val result = service.getBooking(UUID.randomUUID(), UUID.randomUUID()) @@ -398,7 +398,7 @@ class Cas1SpaceBookingServiceTest { .withDefaults() .produce() - every { premisesService.getApprovedPremises(premises.id) } returns premises + every { cas1PremisesService.findPremiseById(premises.id) } returns premises every { spaceBookingRepository.findByIdOrNull(any()) } returns null val result = service.getBooking(premises.id, UUID.randomUUID()) @@ -416,7 +416,7 @@ class Cas1SpaceBookingServiceTest { val spaceBooking = Cas1SpaceBookingEntityFactory() .produce() - every { premisesService.getApprovedPremises(premises.id) } returns premises + every { cas1PremisesService.findPremiseById(premises.id) } returns premises every { spaceBookingRepository.findByIdOrNull(spaceBooking.id) } returns spaceBooking val result = service.getBooking(premises.id, spaceBooking.id) @@ -442,7 +442,7 @@ class Cas1SpaceBookingServiceTest { @Test fun `Returns validation error if no premises with the given premisesId exists`() { - every { premisesService.getApprovedPremises(any()) } returns null + every { cas1PremisesService.findPremiseById(any()) } returns null every { spaceBookingRepository.findByIdOrNull(any()) } returns existingSpaceBooking val result = service.recordArrivalForBooking( @@ -461,7 +461,7 @@ class Cas1SpaceBookingServiceTest { @Test fun `Returns validation error if no space booking with the given bookingId exists`() { - every { premisesService.getApprovedPremises(any()) } returns premises + every { cas1PremisesService.findPremiseById(any()) } returns premises every { spaceBookingRepository.findByIdOrNull(any()) } returns null val result = service.recordArrivalForBooking( @@ -482,7 +482,7 @@ class Cas1SpaceBookingServiceTest { fun `Returns conflict error if the space booking record already has an arrival date recorded`() { val existingSpaceBookingWithArrivalDate = existingSpaceBooking.copy(actualArrivalDateTime = originalArrivalDate) - every { premisesService.getApprovedPremises(any()) } returns premises + every { cas1PremisesService.findPremiseById(any()) } returns premises every { spaceBookingRepository.findByIdOrNull(any()) } returns existingSpaceBookingWithArrivalDate val result = service.recordArrivalForBooking( @@ -501,7 +501,7 @@ class Cas1SpaceBookingServiceTest { fun `Updates existing space booking with arrival information and raises domain event`() { val updatedSpaceBookingCaptor = slot() - every { premisesService.getApprovedPremises(any()) } returns premises + every { cas1PremisesService.findPremiseById(any()) } returns premises every { spaceBookingRepository.findByIdOrNull(any()) } returns existingSpaceBooking every { spaceBookingRepository.save(capture(updatedSpaceBookingCaptor)) } returnsArgument 0 every { cas1SpaceBookingManagementDomainEventService.arrivalRecorded(any(), any()) } returns Unit @@ -538,7 +538,7 @@ class Cas1SpaceBookingServiceTest { val updatedSpaceBookingCaptor = slot() val updatedExpectedDepartureDate = expectedDepartureDate.plusMonths(1) - every { premisesService.getApprovedPremises(any()) } returns premises + every { cas1PremisesService.findPremiseById(any()) } returns premises every { spaceBookingRepository.findByIdOrNull(any()) } returns existingSpaceBooking every { spaceBookingRepository.save(capture(updatedSpaceBookingCaptor)) } returnsArgument 0 every { cas1SpaceBookingManagementDomainEventService.arrivalRecorded(any(), any()) } returns Unit @@ -614,7 +614,7 @@ class Cas1SpaceBookingServiceTest { @BeforeEach fun setup() { - every { premisesService.getApprovedPremises(any()) } returns premises + every { cas1PremisesService.findPremiseById(any()) } returns premises every { spaceBookingRepository.findByIdOrNull(any()) } returns existingSpaceBooking every { departureReasonRepository.findByIdOrNull(any()) } returns departureReason every { moveOnCategoryRepository.findByIdOrNull(any()) } returns departureMoveOnCategory @@ -622,7 +622,7 @@ class Cas1SpaceBookingServiceTest { @Test fun `Returns validation error if no premises exist with the given premisesId`() { - every { premisesService.getApprovedPremises(any()) } returns null + every { cas1PremisesService.findPremiseById(any()) } returns null val result = service.recordDepartureForBooking( premisesId = UUID.randomUUID(), From 2449cd5d807e33d968c2e22400013d6fadfc009d Mon Sep 17 00:00:00 2001 From: davidatkinsuk Date: Thu, 19 Sep 2024 10:53:47 +0100 Subject: [PATCH 6/7] Update Approved Premises Gender Enumeration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit when referring to gender ‘man’/‘woman’ should be used instad of ‘male’/‘female’. --- .../controller/cas1/Cas1PremisesController.kt | 4 +- .../jpa/entity/PremisesEntity.kt | 6 +- ..._default_gender_value_approved_premise.sql | 2 + .../local+dev+test/1__approved_premises.csv | 30 ++++----- src/main/resources/static/cas1-schemas.yml | 4 +- .../static/codegen/built-cas1-api-spec.yml | 4 +- .../factory/ApprovedPremisesEntityFactory.kt | 2 +- .../integration/cas1/Cas1PremisesTest.kt | 65 +++++++++---------- .../cas1/seed/SeedApprovedPremisesTest.kt | 2 +- 9 files changed, 56 insertions(+), 63 deletions(-) create mode 100644 src/main/resources/db/migration/all/20240919103029__alter_default_gender_value_approved_premise.sql diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/controller/cas1/Cas1PremisesController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/controller/cas1/Cas1PremisesController.kt index 6489473aca9..99201c281bb 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/controller/cas1/Cas1PremisesController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/controller/cas1/Cas1PremisesController.kt @@ -39,8 +39,8 @@ class Cas1PremisesController( .body( cas1PremisesService.getPremises( gender = when (gender) { - Cas1ApprovedPremisesGender.male -> ApprovedPremisesGender.MALE - Cas1ApprovedPremisesGender.female -> ApprovedPremisesGender.FEMALE + Cas1ApprovedPremisesGender.man -> ApprovedPremisesGender.MAN + Cas1ApprovedPremisesGender.woman -> ApprovedPremisesGender.WOMAN null -> null }, ).map { diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/jpa/entity/PremisesEntity.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/jpa/entity/PremisesEntity.kt index fb083e351e2..75915affda3 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/jpa/entity/PremisesEntity.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/jpa/entity/PremisesEntity.kt @@ -174,8 +174,6 @@ where @Repository interface ApprovedPremisesRepository : JpaRepository { - fun findByGender(gender: ApprovedPremisesGender): List - @Query("SELECT p as premises FROM ApprovedPremisesEntity p WHERE :gender IS NULL OR p.gender = :gender") fun findForSummaries(gender: ApprovedPremisesGender?): List } @@ -268,8 +266,8 @@ class ApprovedPremisesEntity( ) enum class ApprovedPremisesGender { - MALE, - FEMALE, + MAN, + WOMAN, } @Entity diff --git a/src/main/resources/db/migration/all/20240919103029__alter_default_gender_value_approved_premise.sql b/src/main/resources/db/migration/all/20240919103029__alter_default_gender_value_approved_premise.sql new file mode 100644 index 00000000000..214c4de6d27 --- /dev/null +++ b/src/main/resources/db/migration/all/20240919103029__alter_default_gender_value_approved_premise.sql @@ -0,0 +1,2 @@ +ALTER TABLE approved_premises ALTER COLUMN gender SET DEFAULT 'MAN'::text; +UPDATE approved_premises SET gender = 'MAN'; \ No newline at end of file diff --git a/src/main/resources/db/seed/local+dev+test/1__approved_premises.csv b/src/main/resources/db/seed/local+dev+test/1__approved_premises.csv index 7f4718403b6..155aefece40 100644 --- a/src/main/resources/db/seed/local+dev+test/1__approved_premises.csv +++ b/src/main/resources/db/seed/local+dev+test/1__approved_premises.csv @@ -1,16 +1,16 @@ name,addressLine1,addressLine2,town,postcode,latitude,longitude,notes,emailAddress,probationRegion,localAuthorityArea,characteristics,isIAP,isPIPE,isESAP,isSemiSpecialistMentalHealth,isRecoveryFocussed,isSuitableForVulnerable,acceptsSexOffenders,acceptsChildSexOffenders,acceptsNonSexualChildOffenders,acceptsHateCrimeOffenders,isCatered,hasWideStepFreeAccess,hasWideAccessToCommunalAreas,hasStepFreeAccessToCommunalAreas,hasWheelChairAccessibleBathrooms,hasLift,hasTactileFlooring,hasBrailleSignage,hasHearingLoop,status,apCode,qCode -Test AP 1,454 Nader Port,,Quitzonview,OX26 2EQ,51.904735,-1.1635,No,some@emailaddress.com,Greater Manchester,Malvern Hills,,YES,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,NO,YES,NO,NO,NO,NO,YES,active,TEST1,Q095,MALE -Test AP 2,7525 Alba Trail,,Theronborough,WA6 9BQ,53.266459,-2.768905,,some@emailaddress.com,North East,Hambleton,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,NO,YES,YES,NO,NO,NO,YES,active,TEST2,Q100,MALE -Test AP 3,8527 Bell Rapids,,South Myah,ML8 5EP,55.751711,-3.851103,restrictions on offences against sex workers due to location of the AP,some@emailaddress.com,Wales,Tamworth,,NO,YES,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,YES,YES,YES,NO,NO,NO,NO,active,TEST3,Q057,MALE -Test AP 4,306 Destinee Union,,South Devinberg,KA4 8JG,55.599949,-4.376498,,some@emailaddress.com,South Central,Rochford,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,NO,YES,YES,NO,NO,YES,YES,active,TEST4,Q077,MALE -Test AP 5,4023 Green Wells,,Port Carleton,N14 6QW,51.631685,-0.125257,"As an independent AP, cannot take Arsonists who post an imminent risk of further Arson. This is a local decision, I confirmed that there was no insurance issues regarding Arson. The manager just said if there was an Arsonist whose risk was seen as imminent, she would have to check with the Charity who funds the AP",some@emailaddress.com,East Midlands,Carmarthenshire,,YES,YES,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,NO,YES,YES,NO,NO,NO,NO,active,TEST5,Q705,MALE -Test AP 6,42716 Dickens Route,,Bayerstead,WA11 8GJ,53.50205,-2.790471,,some@emailaddress.com,South Central,West Northamptonshire,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,NO,YES,YES,NO,NO,NO,YES,active,TEST6,Q706,MALE -Test AP 7,704 Eleazar Rue,,Bergstromfort,SK11 6TG,53.254466,-2.124048,,some@emailaddress.com,Wales,Plymouth,,YES,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,YES,YES,YES,YES,NO,NO,YES,active,TEST7,Q707,MALE -Test AP 8,069 Braun Flat,,Roobbury,SO15 8PN,50.913966,-1.442888,,some@emailaddress.com,Yorkshire & The Humber,Gravesham,,NO,YES,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,NO,YES,YES,NO,NO,YES,YES,active,TEST8,Q708,MALE -Test AP 9,14063 Edyth Court,,North Hallie,LN13 9AT,53.254737,0.180603,No,some@emailaddress.com,East of England,Norwich,,YES,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,NO,NO,NO,NO,NO,NO,NO,active,TEST9,Q709,MALE -Test AP 10,9317 Bauch Heights,,Mavisworth,TN33 9JN,50.886096,0.424608,No Child RSO's since 2006 - National instruction.,some@emailaddress.com,South West,Rossendale,,YES,NO,NO,NO,NO,YES,YES,NO,YES,YES,NO,NO,NO,NO,NO,NO,NO,NO,NO,active,TEST10,Q710,MALE -Test AP 11,5510 Emmitt Street,,North Gregoryboro,SA13 1NN,51.593159,-3.781082,Rooms 9 to 16 are currently out of use - annexe that contains them is subsiding and is non accesssible - for last 6 months or so.,some@emailaddress.com,Wales,Torridge,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,NO,NO,NO,NO,NO,YES,YES,active,TEST11,Q711,MALE -Test AP 12,307 Annabell Flats,,Zemlaktown,GU34 5EB,51.119205,-1.040455,,some@emailaddress.com,Greater Manchester,Lisburn and Castlereagh,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,YES,YES,NO,NO,NO,YES,NO,active,TEST12,Q712,MALE -Test AP 13,110 Bailey Expressway,,Cordellburgh,GU3 3DZ,51.249544,-0.637553,,some@emailaddress.com,North East,Staffordshire,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,YES,YES,YES,NO,NO,YES,NO,active,TEST13,Q713,MALE -Test AP 14,0300 Blick Camp,,North Moriahhaven,HU11 4XH,53.792705,-0.191504,Westgate notes,some@emailaddress.com,West Midlands,Harrow,,NO,NO,NO,NO,NO,YES,YES,NO,NO,YES,YES,NO,NO,YES,YES,NO,NO,YES,YES,active,TEST14,Q714,MALE -Test AP 15,4169 Joana Branch,,Alfredohaven,IV30 1XX,57.644221,-3.295377,TEST notes,some@emailaddress.com,North East,Bromley,,NO,NO,NO,NO,NO,YES,YES,NO,NO,YES,YES,NO,NO,YES,YES,NO,NO,YES,YES,active,TEST15,Q715,MALE \ No newline at end of file +Test AP 1,454 Nader Port,,Quitzonview,OX26 2EQ,51.904735,-1.1635,No,some@emailaddress.com,Greater Manchester,Malvern Hills,,YES,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,NO,YES,NO,NO,NO,NO,YES,active,TEST1,Q095,MAN +Test AP 2,7525 Alba Trail,,Theronborough,WA6 9BQ,53.266459,-2.768905,,some@emailaddress.com,North East,Hambleton,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,NO,YES,YES,NO,NO,NO,YES,active,TEST2,Q100,MAN +Test AP 3,8527 Bell Rapids,,South Myah,ML8 5EP,55.751711,-3.851103,restrictions on offences against sex workers due to location of the AP,some@emailaddress.com,Wales,Tamworth,,NO,YES,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,YES,YES,YES,NO,NO,NO,NO,active,TEST3,Q057,MAN +Test AP 4,306 Destinee Union,,South Devinberg,KA4 8JG,55.599949,-4.376498,,some@emailaddress.com,South Central,Rochford,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,NO,YES,YES,NO,NO,YES,YES,active,TEST4,Q077,MAN +Test AP 5,4023 Green Wells,,Port Carleton,N14 6QW,51.631685,-0.125257,"As an independent AP, cannot take Arsonists who post an imminent risk of further Arson. This is a local decision, I confirmed that there was no insurance issues regarding Arson. The manager just said if there was an Arsonist whose risk was seen as imminent, she would have to check with the Charity who funds the AP",some@emailaddress.com,East Midlands,Carmarthenshire,,YES,YES,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,NO,YES,YES,NO,NO,NO,NO,active,TEST5,Q705,MAN +Test AP 6,42716 Dickens Route,,Bayerstead,WA11 8GJ,53.50205,-2.790471,,some@emailaddress.com,South Central,West Northamptonshire,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,NO,YES,YES,NO,NO,NO,YES,active,TEST6,Q706,MAN +Test AP 7,704 Eleazar Rue,,Bergstromfort,SK11 6TG,53.254466,-2.124048,,some@emailaddress.com,Wales,Plymouth,,YES,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,YES,YES,YES,YES,NO,NO,YES,active,TEST7,Q707,MAN +Test AP 8,069 Braun Flat,,Roobbury,SO15 8PN,50.913966,-1.442888,,some@emailaddress.com,Yorkshire & The Humber,Gravesham,,NO,YES,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,NO,YES,YES,NO,NO,YES,YES,active,TEST8,Q708,MAN +Test AP 9,14063 Edyth Court,,North Hallie,LN13 9AT,53.254737,0.180603,No,some@emailaddress.com,East of England,Norwich,,YES,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,NO,NO,NO,NO,NO,NO,NO,active,TEST9,Q709,MAN +Test AP 10,9317 Bauch Heights,,Mavisworth,TN33 9JN,50.886096,0.424608,No Child RSO's since 2006 - National instruction.,some@emailaddress.com,South West,Rossendale,,YES,NO,NO,NO,NO,YES,YES,NO,YES,YES,NO,NO,NO,NO,NO,NO,NO,NO,NO,active,TEST10,Q710,MAN +Test AP 11,5510 Emmitt Street,,North Gregoryboro,SA13 1NN,51.593159,-3.781082,Rooms 9 to 16 are currently out of use - annexe that contains them is subsiding and is non accesssible - for last 6 months or so.,some@emailaddress.com,Wales,Torridge,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,NO,NO,NO,NO,NO,YES,YES,active,TEST11,Q711,MAN +Test AP 12,307 Annabell Flats,,Zemlaktown,GU34 5EB,51.119205,-1.040455,,some@emailaddress.com,Greater Manchester,Lisburn and Castlereagh,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,YES,YES,NO,NO,NO,YES,NO,active,TEST12,Q712,MAN +Test AP 13,110 Bailey Expressway,,Cordellburgh,GU3 3DZ,51.249544,-0.637553,,some@emailaddress.com,North East,Staffordshire,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,YES,YES,YES,NO,NO,YES,NO,active,TEST13,Q713,MAN +Test AP 14,0300 Blick Camp,,North Moriahhaven,HU11 4XH,53.792705,-0.191504,Westgate notes,some@emailaddress.com,West Midlands,Harrow,,NO,NO,NO,NO,NO,YES,YES,NO,NO,YES,YES,NO,NO,YES,YES,NO,NO,YES,YES,active,TEST14,Q714,MAN +Test AP 15,4169 Joana Branch,,Alfredohaven,IV30 1XX,57.644221,-3.295377,TEST notes,some@emailaddress.com,North East,Bromley,,NO,NO,NO,NO,NO,YES,YES,NO,NO,YES,YES,NO,NO,YES,YES,NO,NO,YES,YES,active,TEST15,Q715,MAN \ No newline at end of file diff --git a/src/main/resources/static/cas1-schemas.yml b/src/main/resources/static/cas1-schemas.yml index 7bb85610686..e8dedc6801f 100644 --- a/src/main/resources/static/cas1-schemas.yml +++ b/src/main/resources/static/cas1-schemas.yml @@ -460,5 +460,5 @@ components: Cas1ApprovedPremisesGender: type: string enum: - - male - - female + - man + - woman diff --git a/src/main/resources/static/codegen/built-cas1-api-spec.yml b/src/main/resources/static/codegen/built-cas1-api-spec.yml index 50ff7f3fe71..c8f76cffe18 100644 --- a/src/main/resources/static/codegen/built-cas1-api-spec.yml +++ b/src/main/resources/static/codegen/built-cas1-api-spec.yml @@ -6652,5 +6652,5 @@ components: Cas1ApprovedPremisesGender: type: string enum: - - male - - female + - man + - woman diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/factory/ApprovedPremisesEntityFactory.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/factory/ApprovedPremisesEntityFactory.kt index 889301bf9bf..556c2777d4f 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/factory/ApprovedPremisesEntityFactory.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/factory/ApprovedPremisesEntityFactory.kt @@ -38,7 +38,7 @@ class ApprovedPremisesEntityFactory : Factory { private var characteristics: Yielded> = { mutableListOf() } private var status: Yielded = { randomOf(PropertyStatus.values().asList()) } private var point: Yielded? = null - private var gender: Yielded = { ApprovedPremisesGender.MALE } + private var gender: Yielded = { ApprovedPremisesGender.MAN } fun withDefaults() = apply { withDefaultProbationRegion() diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/cas1/Cas1PremisesTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/cas1/Cas1PremisesTest.kt index ff4ac820825..7962bf3c89b 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/cas1/Cas1PremisesTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/cas1/Cas1PremisesTest.kt @@ -8,6 +8,7 @@ import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.Cas1PremisesBa import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.Cas1PremisesSummary import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.InitialiseDatabasePerClassTestBase import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.IntegrationTestBase +import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Given a Probation Region` import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Given a User` import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Given an AP Area` import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.ApprovedPremisesEntity @@ -29,9 +30,9 @@ class Cas1PremisesTest : IntegrationTestBase() { @BeforeAll fun setupTestData() { - val region = probationRegionEntityFactory.produceAndPersist { - withYieldedApArea { `Given an AP Area`(name = "The ap area name") } - } + val region = `Given a Probation Region`( + apArea = `Given an AP Area`(name = "The ap area name"), + ) premises = approvedPremisesEntityFactory.produceAndPersist { withName("the premises name") @@ -114,45 +115,37 @@ class Cas1PremisesTest : IntegrationTestBase() { @Nested inner class GetPremisesSummaries : InitialiseDatabasePerClassTestBase() { - lateinit var premises1Male: ApprovedPremisesEntity - lateinit var premises2Female: ApprovedPremisesEntity - lateinit var premises3Male: ApprovedPremisesEntity + lateinit var premises1Man: ApprovedPremisesEntity + lateinit var premises2Woman: ApprovedPremisesEntity + lateinit var premises3Man: ApprovedPremisesEntity @BeforeAll fun setupTestData() { - val region1 = probationRegionEntityFactory.produceAndPersist { - withYieldedApArea { - apAreaEntityFactory.produceAndPersist { - withName("the ap area name 1") - } - } - } + val region1 = `Given a Probation Region`( + apArea = `Given an AP Area`(name = "the ap area name 1"), + ) - val region2 = probationRegionEntityFactory.produceAndPersist { - withYieldedApArea { - apAreaEntityFactory.produceAndPersist { - withName("the ap area name 2") - } - } - } + val region2 = `Given a Probation Region`( + apArea = `Given an AP Area`(name = "the ap area name 2"), + ) - premises1Male = approvedPremisesEntityFactory.produceAndPersist { + premises1Man = approvedPremisesEntityFactory.produceAndPersist { withName("the premises name 1") - withGender(ApprovedPremisesGender.MALE) + withGender(ApprovedPremisesGender.MAN) withYieldedProbationRegion { region1 } withYieldedLocalAuthorityArea { localAuthorityEntityFactory.produceAndPersist() } } - premises2Female = approvedPremisesEntityFactory.produceAndPersist { + premises2Woman = approvedPremisesEntityFactory.produceAndPersist { withName("the premises name 2") - withGender(ApprovedPremisesGender.FEMALE) + withGender(ApprovedPremisesGender.WOMAN) withYieldedProbationRegion { region2 } withYieldedLocalAuthorityArea { localAuthorityEntityFactory.produceAndPersist() } } - premises3Male = approvedPremisesEntityFactory.produceAndPersist { + premises3Man = approvedPremisesEntityFactory.produceAndPersist { withName("the premises name 3") - withGender(ApprovedPremisesGender.MALE) + withGender(ApprovedPremisesGender.MAN) withYieldedProbationRegion { region2 } withYieldedLocalAuthorityArea { localAuthorityEntityFactory.produceAndPersist() } } @@ -172,25 +165,25 @@ class Cas1PremisesTest : IntegrationTestBase() { assertThat(summaries).hasSize(3) - assertThat(summaries[0].id).isEqualTo(premises1Male.id) + assertThat(summaries[0].id).isEqualTo(premises1Man.id) assertThat(summaries[0].name).isEqualTo("the premises name 1") assertThat(summaries[0].apArea.name).isEqualTo("the ap area name 1") - assertThat(summaries[1].id).isEqualTo(premises2Female.id) + assertThat(summaries[1].id).isEqualTo(premises2Woman.id) assertThat(summaries[1].name).isEqualTo("the premises name 2") assertThat(summaries[1].apArea.name).isEqualTo("the ap area name 2") - assertThat(summaries[2].id).isEqualTo(premises3Male.id) + assertThat(summaries[2].id).isEqualTo(premises3Man.id) assertThat(summaries[2].name).isEqualTo("the premises name 3") assertThat(summaries[2].apArea.name).isEqualTo("the ap area name 2") } @Test - fun `Returns premises summaries where gender is male`() { + fun `Returns premises summaries where gender is man`() { val (_, jwt) = `Given a User`() val summaries = webTestClient.get() - .uri("/cas1/premises/summary?gender=male") + .uri("/cas1/premises/summary?gender=man") .header("Authorization", "Bearer $jwt") .exchange() .expectStatus() @@ -199,21 +192,21 @@ class Cas1PremisesTest : IntegrationTestBase() { assertThat(summaries).hasSize(2) - assertThat(summaries[0].id).isEqualTo(premises1Male.id) + assertThat(summaries[0].id).isEqualTo(premises1Man.id) assertThat(summaries[0].name).isEqualTo("the premises name 1") assertThat(summaries[0].apArea.name).isEqualTo("the ap area name 1") - assertThat(summaries[1].id).isEqualTo(premises3Male.id) + assertThat(summaries[1].id).isEqualTo(premises3Man.id) assertThat(summaries[1].name).isEqualTo("the premises name 3") assertThat(summaries[1].apArea.name).isEqualTo("the ap area name 2") } @Test - fun `Returns premises summaries where gender is female`() { + fun `Returns premises summaries where gender is woman`() { val (_, jwt) = `Given a User`() val summaries = webTestClient.get() - .uri("/cas1/premises/summary?gender=female") + .uri("/cas1/premises/summary?gender=woman") .header("Authorization", "Bearer $jwt") .exchange() .expectStatus() @@ -222,7 +215,7 @@ class Cas1PremisesTest : IntegrationTestBase() { assertThat(summaries).hasSize(1) - assertThat(summaries[0].id).isEqualTo(premises2Female.id) + assertThat(summaries[0].id).isEqualTo(premises2Woman.id) assertThat(summaries[0].name).isEqualTo("the premises name 2") assertThat(summaries[0].apArea.name).isEqualTo("the ap area name 2") } diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/cas1/seed/SeedApprovedPremisesTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/cas1/seed/SeedApprovedPremisesTest.kt index fc1f5e20e60..272d948c0af 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/cas1/seed/SeedApprovedPremisesTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/cas1/seed/SeedApprovedPremisesTest.kt @@ -443,7 +443,7 @@ class ApprovedPremisesSeedCsvRowFactory : Factory { private var status: Yielded = { PropertyStatus.active } private var apCode: Yielded = { randomStringMultiCaseWithNumbers(6) } private var qCode: Yielded = { randomStringMultiCaseWithNumbers(6) } - private var gender: Yielded = { ApprovedPremisesGender.MALE } + private var gender: Yielded = { ApprovedPremisesGender.MAN } fun withName(name: String) = apply { this.name = { name } From 0383d5877acf9f81e3fdc9db36d6897f1cc44e82 Mon Sep 17 00:00:00 2001 From: davidatkinsuk Date: Thu, 26 Sep 2024 12:54:18 +0100 Subject: [PATCH 7/7] Fix premises seed This commit fixes the approved premises seed CSV file, adding a missing column name. --- .../resources/db/seed/local+dev+test/1__approved_premises.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/db/seed/local+dev+test/1__approved_premises.csv b/src/main/resources/db/seed/local+dev+test/1__approved_premises.csv index 155aefece40..500f3de8c84 100644 --- a/src/main/resources/db/seed/local+dev+test/1__approved_premises.csv +++ b/src/main/resources/db/seed/local+dev+test/1__approved_premises.csv @@ -1,4 +1,4 @@ -name,addressLine1,addressLine2,town,postcode,latitude,longitude,notes,emailAddress,probationRegion,localAuthorityArea,characteristics,isIAP,isPIPE,isESAP,isSemiSpecialistMentalHealth,isRecoveryFocussed,isSuitableForVulnerable,acceptsSexOffenders,acceptsChildSexOffenders,acceptsNonSexualChildOffenders,acceptsHateCrimeOffenders,isCatered,hasWideStepFreeAccess,hasWideAccessToCommunalAreas,hasStepFreeAccessToCommunalAreas,hasWheelChairAccessibleBathrooms,hasLift,hasTactileFlooring,hasBrailleSignage,hasHearingLoop,status,apCode,qCode +name,addressLine1,addressLine2,town,postcode,latitude,longitude,notes,emailAddress,probationRegion,localAuthorityArea,characteristics,isIAP,isPIPE,isESAP,isSemiSpecialistMentalHealth,isRecoveryFocussed,isSuitableForVulnerable,acceptsSexOffenders,acceptsChildSexOffenders,acceptsNonSexualChildOffenders,acceptsHateCrimeOffenders,isCatered,hasWideStepFreeAccess,hasWideAccessToCommunalAreas,hasStepFreeAccessToCommunalAreas,hasWheelChairAccessibleBathrooms,hasLift,hasTactileFlooring,hasBrailleSignage,hasHearingLoop,status,apCode,qCode,gender Test AP 1,454 Nader Port,,Quitzonview,OX26 2EQ,51.904735,-1.1635,No,some@emailaddress.com,Greater Manchester,Malvern Hills,,YES,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,NO,NO,YES,NO,NO,NO,NO,YES,active,TEST1,Q095,MAN Test AP 2,7525 Alba Trail,,Theronborough,WA6 9BQ,53.266459,-2.768905,,some@emailaddress.com,North East,Hambleton,,NO,NO,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,NO,YES,YES,NO,NO,NO,YES,active,TEST2,Q100,MAN Test AP 3,8527 Bell Rapids,,South Myah,ML8 5EP,55.751711,-3.851103,restrictions on offences against sex workers due to location of the AP,some@emailaddress.com,Wales,Tamworth,,NO,YES,NO,NO,NO,YES,YES,YES,YES,YES,YES,YES,YES,YES,YES,NO,NO,NO,NO,active,TEST3,Q057,MAN