Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Remove CAS1 Unused Bed Search Logic #2767

Merged
merged 1 commit into from
Jan 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ package uk.gov.justice.digital.hmpps.approvedpremisesapi.controller
import org.springframework.http.ResponseEntity
import org.springframework.stereotype.Service
import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.BedsApiDelegate
import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ApprovedPremisesBedSearchParameters
import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.BedSearchParameters
import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.BedSearchResults
import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.TemporaryAccommodationBedSearchParameters
import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.BedSearchService
import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.UserService
import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.cas3.Cas3BedspaceSearchService
import uk.gov.justice.digital.hmpps.approvedpremisesapi.transformer.BedSearchResultTransformer
Expand All @@ -15,22 +13,13 @@ import uk.gov.justice.digital.hmpps.approvedpremisesapi.util.extractEntityFromCa
@Service
class BedSearchController(
private val userService: UserService,
private val bedSearchService: BedSearchService,
private val cas3BedspaceSearchService: Cas3BedspaceSearchService,
private val bedSearchResultTransformer: BedSearchResultTransformer,
) : BedsApiDelegate {
override fun bedsSearchPost(bedSearchParameters: BedSearchParameters): ResponseEntity<BedSearchResults> {
val user = userService.getUserForRequest()

val searchResult = when (bedSearchParameters) {
is ApprovedPremisesBedSearchParameters -> bedSearchService.findApprovedPremisesBeds(
user = user,
maxDistanceMiles = bedSearchParameters.maxDistanceMiles,
startDate = bedSearchParameters.startDate,
durationInDays = bedSearchParameters.durationDays,
requiredCharacteristics = bedSearchParameters.requiredCharacteristics,
postcodeDistrictOutcode = bedSearchParameters.postcodeDistrict,
)
is TemporaryAccommodationBedSearchParameters -> cas3BedspaceSearchService.findBedspaces(
user = user,
probationDeliveryUnits = bedSearchParameters.probationDeliveryUnits,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,160 +11,6 @@ import java.util.UUID

@Repository
class BedSearchRepository(private val namedParameterJdbcTemplate: NamedParameterJdbcTemplate) {
private val approvedPremisesSearchQuery =
"""
SELECT ST_Distance((SELECT point FROM postcode_districts pd WHERE pd.outcode = :outcode)::geography, ap.point::geography) * 0.000621371 as distance_miles,
p.id as premises_id,
p.name as premises_name,
p.address_line1 as premises_address_line1,
p.address_line2 as premises_address_line2,
p.town as premises_town,
p.postcode as premises_postcode,
c.property_name as premises_characteristic_property_name,
(SELECT count(1) FROM beds b2 WHERE b2.room_id IN (SELECT id FROM rooms r2 WHERE r2.premises_id = p.id)) as premises_bed_count,
c.name as premises_characteristic_name,
r.id as room_id,
r.name as room_name,
c2.property_name as room_characteristic_property_name,
c2.name as room_characteristic_name,
b.id as bed_id,
b.name as bed_name
FROM premises p
JOIN approved_premises ap ON p.id = ap.premises_id
LEFT JOIN premises_characteristics pc ON p.id = pc.premises_id
LEFT JOIN characteristics c ON pc.characteristic_id = c.id
LEFT JOIN rooms r ON r.premises_id = p.id
LEFT JOIN room_characteristics rc on rc.room_id = r.id
LEFT JOIN characteristics c2 ON rc.characteristic_id = c2.id
LEFT JOIN beds b ON b.room_id = r.id
WHERE
ST_DWithin((SELECT point FROM postcode_districts pd WHERE pd.outcode = :outcode)::geography, ap.point::geography, (:max_miles + 1) / 0.000621371) AND --miles to meters
#OPTIONAL_FILTERS
(SELECT COUNT(1) FROM bookings books
LEFT JOIN cancellations books_cancel ON books_cancel.booking_id = books.id
LEFT JOIN non_arrivals books_non_arrival ON books_non_arrival.booking_id = books.id
WHERE
books.bed_id = b.id AND
(books.arrival_date, books.departure_date) OVERLAPS (:start_date, :end_date) AND
books_cancel.id IS NULL
AND books_non_arrival.id IS NULL
) = 0 AND
(SELECT COUNT(1) FROM lost_beds lostbeds
LEFT JOIN lost_bed_cancellations lostbeds_cancel ON lostbeds_cancel.lost_bed_id = lostbeds.id
WHERE
lostbeds.bed_id = b.id AND
(lostbeds.start_date, lostbeds.end_date) OVERLAPS (:start_date, :end_date) AND
lostbeds_cancel.id IS NULL
) = 0 AND
p.status = 'active' AND
p.service = 'approved-premises'
ORDER BY distance_miles;
"""

private val premisesCharacteristicFilter = """
(SELECT COUNT(1) FROM premises_characteristics pc_filter WHERE pc_filter.characteristic_id IN (:premises_characteristic_ids) AND pc_filter.premises_id = p.id) = :premises_characteristic_ids_count
"""

private val roomCharacteristicFilter = """
(SELECT COUNT(1) FROM room_characteristics rc_filter WHERE rc_filter.characteristic_id IN (:room_characteristic_ids) AND rc_filter.room_id = r.id) = :room_characteristic_ids_count
"""

fun findApprovedPremisesBeds(
postcodeDistrictOutcode: String,
maxDistanceMiles: Int,
startDate: LocalDate,
durationInDays: Int,
requiredPremisesCharacteristics: List<UUID>,
requiredRoomCharacteristics: List<UUID>,
): List<ApprovedPremisesBedSearchResult> {
val params = MapSqlParameterSource().apply {
addValue("outcode", postcodeDistrictOutcode)
addValue("max_miles", maxDistanceMiles)
addValue("premises_characteristic_ids", requiredPremisesCharacteristics)
addValue("premises_characteristic_ids_count", requiredPremisesCharacteristics.size)
addValue("room_characteristic_ids", requiredRoomCharacteristics)
addValue("room_characteristic_ids_count", requiredRoomCharacteristics.size)
addValue("start_date", startDate)
addValue("end_date", startDate.plusDays(durationInDays.toLong()))
}

var optionalFilters = ""
if (requiredPremisesCharacteristics.any()) {
optionalFilters += "$premisesCharacteristicFilter AND\n"
}

if (requiredRoomCharacteristics.any()) {
optionalFilters += "$roomCharacteristicFilter AND\n"
}

val query = approvedPremisesSearchQuery.replace("#OPTIONAL_FILTERS", optionalFilters)

val result = namedParameterJdbcTemplate.query(
query,
params,
ResultSetExtractor { resultSet ->
val beds = mutableMapOf<UUID, ApprovedPremisesBedSearchResult>()

while (resultSet.next()) {
val distanceMiles = resultSet.getDouble("distance_miles")
val premisesId = UUID.fromString(resultSet.getString("premises_id"))
val premisesName = resultSet.getString("premises_name")
val premisesAddressLine1 = resultSet.getString("premises_address_line1")
val premisesAddressLine2 = resultSet.getString("premises_address_line2")
val premisesTown = resultSet.getString("premises_town")
val premisesPostcode = resultSet.getString("premises_postcode")
val premisesCharacteristicName = resultSet.getString("premises_characteristic_name")
val premisesCharacteristicPropertyName = resultSet.getString("premises_characteristic_property_name")
val premisesBedCount = resultSet.getInt("premises_bed_count")
val roomId = resultSet.getNullableUUID("room_id")
val roomName = resultSet.getString("room_name")
val roomCharacteristicName = resultSet.getString("room_characteristic_name")
val roomCharacteristicPropertyName = resultSet.getString("room_characteristic_property_name")
val bedId = resultSet.getNullableUUID("bed_id")
val bedName = resultSet.getString("bed_name")

if (bedId == null) continue

if (!beds.containsKey(bedId)) {
beds[bedId] = ApprovedPremisesBedSearchResult(
premisesId = premisesId,
premisesName = premisesName,
premisesAddressLine1 = premisesAddressLine1,
premisesAddressLine2 = premisesAddressLine2,
premisesTown = premisesTown,
premisesPostcode = premisesPostcode,
premisesCharacteristics = mutableListOf(),
premisesBedCount = premisesBedCount,
bedId = bedId,
bedName = bedName,
roomId = roomId!!,
roomName = roomName,
roomCharacteristics = mutableListOf(),
distance = distanceMiles,
)
}

beds[bedId]!!.apply {
if (premisesCharacteristicName != null) {
premisesCharacteristics.addIfNoneMatch(CharacteristicNames(premisesCharacteristicPropertyName, premisesCharacteristicName)) {
it.name == premisesCharacteristicName
}
}

if (roomCharacteristicName != null) {
roomCharacteristics.addIfNoneMatch(CharacteristicNames(roomCharacteristicPropertyName, roomCharacteristicName)) {
it.name == roomCharacteristicName
}
}
}
}

beds.values.toList()
},
)

return result ?: emptyList()
}

private val temporaryAccommodationSearchQuery =
"""
Expand Down Expand Up @@ -376,37 +222,6 @@ sealed class BedSearchResult(
val roomCharacteristics: MutableList<CharacteristicNames>,
)

class ApprovedPremisesBedSearchResult(
premisesId: UUID,
premisesName: String,
premisesAddressLine1: String,
premisesAddressLine2: String?,
premisesTown: String?,
premisesPostcode: String,
premisesCharacteristics: MutableList<CharacteristicNames>,
premisesBedCount: Int,
roomId: UUID,
roomName: String,
bedId: UUID,
bedName: String,
roomCharacteristics: MutableList<CharacteristicNames>,
val distance: Double,
) : BedSearchResult(
premisesId,
premisesName,
premisesAddressLine1,
premisesAddressLine2,
premisesTown,
premisesPostcode,
premisesCharacteristics,
premisesBedCount,
roomId,
roomName,
bedId,
bedName,
roomCharacteristics,
)

@SuppressWarnings("LongParameterList")
class TemporaryAccommodationBedSearchResult(
premisesId: UUID,
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import uk.gov.justice.digital.hmpps.approvedpremisesapi.repository.BedSearchRepo
import uk.gov.justice.digital.hmpps.approvedpremisesapi.repository.TemporaryAccommodationBedSearchResult
import uk.gov.justice.digital.hmpps.approvedpremisesapi.repository.TemporaryAccommodationBedSearchResultOverlap
import uk.gov.justice.digital.hmpps.approvedpremisesapi.results.CasResult
import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.BedSearchService.Constants.MAX_NUMBER_PDUS
import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.CharacteristicService
import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.OffenderService
import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.WorkingDayService
Expand All @@ -35,6 +34,10 @@ class Cas3BedspaceSearchService(
private val workingDayService: WorkingDayService,
private val offenderService: OffenderService,
) {
companion object {
const val MAX_NUMBER_PDUS = 5
}

@Suppress("detekt:CyclomaticComplexMethod")
fun findBedspaces(
user: UserEntity,
Expand Down
Loading
Loading