Skip to content

Commit

Permalink
Pi 1744 office address search (#2973)
Browse files Browse the repository at this point in the history
* Introduced Office Address search
  • Loading branch information
pmcphee77 authored Jan 3, 2024
1 parent 392f087 commit bee439a
Show file tree
Hide file tree
Showing 9 changed files with 408 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import org.springframework.context.ApplicationListener
import org.springframework.stereotype.Component
import org.springframework.transaction.annotation.Transactional
import uk.gov.justice.digital.hmpps.data.generator.AddressGenerator
import uk.gov.justice.digital.hmpps.data.generator.OfficeLocationGenerator
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator
import uk.gov.justice.digital.hmpps.data.generator.ProviderGenerator
import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator
Expand Down Expand Up @@ -68,6 +69,7 @@ class DataLoader(
)

createForAddingLicenceConditions()
createOfficeLocationsAndDistricts()
}

private fun createForAddingLicenceConditions() {
Expand All @@ -87,6 +89,16 @@ class DataLoader(
entityManager.saveCvlMappings(ReferenceDataGenerator.CVL_MAPPINGS)
}

private fun createOfficeLocationsAndDistricts() {
entityManager.persistAll(
OfficeLocationGenerator.DISTRICT_BRK,
OfficeLocationGenerator.DISTRICT_MKY,
OfficeLocationGenerator.DISTRICT_OXF,
OfficeLocationGenerator.LOCATION_BRK_1,
OfficeLocationGenerator.LOCATION_BRK_2
)
}

private fun EntityManager.persistAll(vararg entities: Any) {
entities.forEach { persist(it) }
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package uk.gov.justice.digital.hmpps.data.generator

import uk.gov.justice.digital.hmpps.api.model.OfficeAddress
import uk.gov.justice.digital.hmpps.integrations.delius.provider.entity.Borough
import uk.gov.justice.digital.hmpps.integrations.delius.provider.entity.District
import uk.gov.justice.digital.hmpps.integrations.delius.provider.entity.OfficeLocation
import java.time.LocalDate

object OfficeLocationGenerator {
val DISTRICT_BRK = generateDistrict("TVP_BRK", "Berkshire")
val DISTRICT_OXF = generateDistrict("TVP_OXF", "Oxfordshire")
val DISTRICT_MKY = generateDistrict("TVP_MKY", "Milton Keynes")

val LOCATION_BRK_1 = generateLocation(
code = "TVP_BRK",
description = "Bracknell Office",
buildingNumber = "21",
streetName = "Some Place",
town = "Hearth",
postcode = "H34 7TH",
district = DISTRICT_BRK
)

val LOCATION_BRK_2 = generateLocation(
code = "TVP_RCC",
description = "Reading Office",
buildingNumber = "23",
buildingName = "The old hall",
streetName = "Another Place",
town = "Reading",
postcode = "RG1 3EH",
district = DISTRICT_BRK
)

fun generateDistrict(
code: String,
description: String,
borough: Borough = ProviderGenerator.DEFAULT_BOROUGH,
id: Long = IdGenerator.getAndIncrement()
) = District(code, description, borough, id)

fun generateOfficeAddress(
officeLocation: OfficeLocation,
officeDistrict: District
) = OfficeAddress(
officeLocation.description,
officeLocation.buildingName,
officeLocation.buildingNumber,
officeLocation.streetName,
officeDistrict.description,
officeLocation.townCity,
officeLocation.county,
officeLocation.postcode,
officeLocation.telephoneNumber,
officeLocation.startDate,
officeLocation.endDate
)

fun generateLocation(location: OfficeLocation, district: District) =
OfficeLocation(
location.code,
location.description,
location.buildingName,
location.buildingNumber,
location.streetName,
location.districtStr,
location.townCity,
location.county,
location.postcode,
location.telephoneNumber,
location.startDate,
location.endDate,
district,
location.id
)

fun generateLocation(
code: String,
description: String,
buildingName: String? = null,
buildingNumber: String,
streetName: String? = null,
districtStr: String? = null,
town: String? = null,
county: String? = null,
postcode: String? = null,
telephoneNumber: String? = null,
startDate: LocalDate = LocalDate.now(),
endDate: LocalDate? = null,
district: District,
id: Long = IdGenerator.getAndIncrement()
) = OfficeLocation(
code,
description,
buildingName,
buildingNumber,
streetName,
districtStr,
town,
county,
postcode,
telephoneNumber,
startDate,
endDate,
district,
id
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package uk.gov.justice.digital.hmpps

import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.equalTo
import org.junit.jupiter.api.Test
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.Arguments
import org.junit.jupiter.params.provider.MethodSource
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
import uk.gov.justice.digital.hmpps.api.model.OfficeAddress
import uk.gov.justice.digital.hmpps.api.resource.ResultSet
import uk.gov.justice.digital.hmpps.data.generator.OfficeLocationGenerator.DISTRICT_BRK
import uk.gov.justice.digital.hmpps.data.generator.OfficeLocationGenerator.LOCATION_BRK_1
import uk.gov.justice.digital.hmpps.data.generator.OfficeLocationGenerator.LOCATION_BRK_2
import uk.gov.justice.digital.hmpps.data.generator.OfficeLocationGenerator.generateOfficeAddress
import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.contentAsJson
import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withToken

@AutoConfigureMockMvc
@SpringBootTest(webEnvironment = RANDOM_PORT)
internal class OfficeAddressIntegrationTest {
@Autowired
lateinit var mockMvc: MockMvc

@Test
fun badRequest() {
mockMvc
.perform(get("/office/addresses").withToken())
.andExpect(status().isBadRequest)
}

@ParameterizedTest
@MethodSource("officeAddressArgs")
fun getOfficeAddress(url: String, pageSize: Int, resultSize: Int, pageNumber: Int, results: List<OfficeAddress>?) {
val res = mockMvc
.perform(get(url).withToken())
.andExpect(status().isOk)
.andReturn().response.contentAsJson<ResultSet<OfficeAddress>>()

assertThat(res.totalPages, equalTo(pageSize))
assertThat(res.results.size, equalTo(resultSize))
assertThat(res.page, equalTo(pageNumber))
assertThat(res.results, equalTo(results))
}

companion object {
@JvmStatic
fun officeAddressArgs(): List<Arguments> = listOf(
Arguments.of("/office/addresses?ldu=Berk&officeName=nothing", 0, 0, 0, listOf<OfficeAddress>()),
Arguments.of(
"/office/addresses?ldu=Berk&officeName=Office", 1, 2, 0,
listOf(
generateOfficeAddress(LOCATION_BRK_1, DISTRICT_BRK),
generateOfficeAddress(LOCATION_BRK_2, DISTRICT_BRK)
)
),
Arguments.of(
"/office/addresses?ldu=Berk&officeName=Reading", 1, 1, 0,
listOf(generateOfficeAddress(LOCATION_BRK_2, DISTRICT_BRK))
),
Arguments.of(
"/office/addresses?ldu=Berk&officeName=Brack", 1, 1, 0,
listOf(generateOfficeAddress(LOCATION_BRK_1, DISTRICT_BRK))
),
Arguments.of(
"/office/addresses?page=0&size=1&ldu=Berk&officeName=Office", 2, 1, 0,
listOf(generateOfficeAddress(LOCATION_BRK_1, DISTRICT_BRK))
),
Arguments.of(
"/office/addresses?page=1&size=1&ldu=Berk&officeName=Office", 2, 1, 1,
listOf(generateOfficeAddress(LOCATION_BRK_2, DISTRICT_BRK))
),
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package uk.gov.justice.digital.hmpps.api.model

import java.time.LocalDate

data class OfficeAddress(
val officeName: String,
val buildingName: String?,
val buildingNumber: String?,
val streetName: String?,
val district: String?,
val town: String?,
val county: String?,
val postcode: String?,
val telephoneNumber: String?,
val from: LocalDate,
val to: LocalDate?
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package uk.gov.justice.digital.hmpps.api.resource

import org.springframework.data.domain.PageRequest
import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
import uk.gov.justice.digital.hmpps.api.model.OfficeAddress
import uk.gov.justice.digital.hmpps.service.OfficeAddressService

@RestController
@RequestMapping("office")
class OfficeResource(
private val officeAddressService: OfficeAddressService
) {

@PreAuthorize("hasRole('CVL_CONTEXT')")
@GetMapping("addresses")
fun findAddresses(
@RequestParam(required = true) ldu: String,
@RequestParam(required = true) officeName: String,
@RequestParam(required = false, defaultValue = "0") page: Int,
@RequestParam(required = false, defaultValue = "50") size: Int,

): ResultSet<OfficeAddress> =
officeAddressService.findAddresses(ldu, officeName, PageRequest.of(page, size)).let {
ResultSet(it.content, it.totalElements, it.totalPages, page, size)
}
}

data class ResultSet<T>(
val results: List<T>,
val totalElements: Long,
val totalPages: Int,
val page: Int,
val size: Int
)
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import jakarta.persistence.ManyToOne
import jakarta.persistence.OneToOne
import jakarta.persistence.Table
import org.hibernate.annotations.Immutable
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query
import java.time.LocalDate
Expand Down Expand Up @@ -98,7 +100,7 @@ class Borough(
val provider: Provider
)

interface BoroughRepository : JpaRepository<Borough?, Long?> {
interface BoroughRepository : JpaRepository<Borough, Long> {
@Query(
"""
select b from Borough b
Expand All @@ -108,3 +110,47 @@ interface BoroughRepository : JpaRepository<Borough?, Long?> {
)
fun findActiveByCode(code: String): Borough?
}

@Immutable
@Entity
@Table(name = "office_location")
class OfficeLocation(

@Column(name = "code", columnDefinition = "char(7)")
val code: String,

val description: String,
val buildingName: String?,
val buildingNumber: String?,
val streetName: String?,

@Column(name = "district")
val districtStr: String?,

val townCity: String?,
val county: String?,
val postcode: String?,
val telephoneNumber: String?,
val startDate: LocalDate,
val endDate: LocalDate?,

@JoinColumn(name = "district_id")
@ManyToOne
val district: District,

@Id
@Column(name = "office_location_id")
val id: Long
)

interface OfficeLocationRepository : JpaRepository<OfficeLocation, Long> {
@Query(
"""
select ol from OfficeLocation ol
where ol.description like %:officeName% and ol.district.description like %:ldu%
and (ol.endDate is null or ol.endDate > current_date)
order by ol.description
"""
)
fun findByLduAndOfficeName(ldu: String, officeName: String, pageable: Pageable): Page<OfficeLocation>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package uk.gov.justice.digital.hmpps.service

import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.stereotype.Service
import uk.gov.justice.digital.hmpps.api.model.OfficeAddress
import uk.gov.justice.digital.hmpps.integrations.delius.provider.entity.OfficeLocationRepository

@Service
class OfficeAddressService(private val officeLocationRepository: OfficeLocationRepository) {
fun findAddresses(ldu: String, officeName: String, pageable: Pageable): Page<OfficeAddress> =
officeLocationRepository.findByLduAndOfficeName(ldu, officeName, pageable).map {
OfficeAddress(
it.description,
it.buildingName,
it.buildingNumber,
it.streetName,
it.district.description,
it.townCity,
it.county,
it.postcode,
it.telephoneNumber,
it.startDate,
it.endDate
)
}
}
Loading

0 comments on commit bee439a

Please sign in to comment.