From 04321ae0b376b5d3593f45ec518c27e89d327cb0 Mon Sep 17 00:00:00 2001 From: Dani Burnley Date: Thu, 30 Jan 2025 17:02:52 +0000 Subject: [PATCH] CDPS-112: Fix pagination page and move to new class --- .../service/PrisonerHealthService.kt | 46 ++++++++----------- .../healthandmedication/utils/Pagination.kt | 45 ++++++++++++++++++ 2 files changed, 65 insertions(+), 26 deletions(-) create mode 100644 src/main/kotlin/uk/gov/justice/digital/hmpps/healthandmedication/utils/Pagination.kt diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/healthandmedication/service/PrisonerHealthService.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/healthandmedication/service/PrisonerHealthService.kt index fbddd78..a1e5545 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/healthandmedication/service/PrisonerHealthService.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/healthandmedication/service/PrisonerHealthService.kt @@ -18,6 +18,7 @@ import uk.gov.justice.digital.hmpps.healthandmedication.resource.requests.PageMe import uk.gov.justice.digital.hmpps.healthandmedication.resource.responses.HealthAndMedicationForPrisonDto import uk.gov.justice.digital.hmpps.healthandmedication.resource.responses.HealthAndMedicationForPrisonResponse import uk.gov.justice.digital.hmpps.healthandmedication.utils.AuthenticationFacade +import uk.gov.justice.digital.hmpps.healthandmedication.utils.Pagination import uk.gov.justice.digital.hmpps.healthandmedication.utils.toReferenceDataCode import uk.gov.justice.digital.hmpps.healthandmedication.utils.validatePrisonerNumber import java.time.Clock @@ -65,40 +66,33 @@ class PrisonerHealthService( ) // This maintains the order from the prisoner search API so that we're able to have sorting - val overlappingIds = prisonerNumbers.intersect(healthData.map { it.prisonerNumber }.toSet()).toList() - - // Pagination specific code to be moved out - val startIndex = (request.page - 1) * request.size - val lastIndex = (startIndex + request.size - 1).coerceAtMost(overlappingIds.size - 1) - val idsForPage = overlappingIds.slice(startIndex..lastIndex) - // End pagination specific code - - return HealthAndMedicationForPrisonResponse( - content = idsForPage.map { id -> - val health = healthData.find { it.prisonerNumber == id }!! - val prisoner = prisoners.find { prisoner -> prisoner.prisonerNumber == health.prisonerNumber }!! + val healthForPrison = + prisonerNumbers.intersect(healthData.map { it.prisonerNumber }.toSet()).toList().map { prisonerNumber -> + val health = healthData.find { it.prisonerNumber == prisonerNumber }!! + val prisoner = prisoners.find { prisoner -> prisoner.prisonerNumber == prisonerNumber }!! HealthAndMedicationForPrisonDto( firstName = prisoner.firstName, lastName = prisoner.lastName, location = prisoner.cellLocation, - prisonerNumber = health.prisonerNumber, + prisonerNumber = prisonerNumber, health = health.toHealthDto(), ) - }.toList(), + } + + val (content, metadata) = Pagination.paginateCollection(request.page, request.size, healthForPrison) + + return HealthAndMedicationForPrisonResponse( + content = content.toList(), // Pagination metadata, should be returned from the same class that returns the IDs calculated metadata = PageMeta( - first = startIndex == 0, - last = (lastIndex + 1) >= overlappingIds.size, - numberOfElements = idsForPage.size, - offset = startIndex, - pageNumber = if (idsForPage.isNotEmpty()) { - Math.ceilDiv(startIndex, idsForPage.size) + 1 - } else { - 1 - }, - size = request.size, - totalElements = overlappingIds.size, - totalPages = Math.ceilDiv(overlappingIds.size, request.size).coerceAtLeast(1), + first = metadata.first, + last = metadata.last, + numberOfElements = metadata.numberOfElements, + offset = metadata.offset, + pageNumber = metadata.pageNumber, + size = metadata.size, + totalElements = metadata.totalElements, + totalPages = metadata.totalPages, ), ) } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/healthandmedication/utils/Pagination.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/healthandmedication/utils/Pagination.kt new file mode 100644 index 0000000..c36d453 --- /dev/null +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/healthandmedication/utils/Pagination.kt @@ -0,0 +1,45 @@ +package uk.gov.justice.digital.hmpps.healthandmedication.utils + +class Pagination { + data class PaginationMetadata( + val first: Boolean, + val last: Boolean, + val numberOfElements: Int, + val offset: Int, + val pageNumber: Int, + val size: Int, + val totalElements: Int, + val totalPages: Int, + ) + + data class PaginatedCollection( + val content: List, + val metadata: PaginationMetadata, + ) + + companion object { + fun paginateCollection( + page: Int, + pageSize: Int, + collection: List, + ): PaginatedCollection { + val startIndex = (page - 1) * pageSize + val lastIndex = (startIndex + pageSize- 1).coerceAtMost(collection.size - 1) + val content = collection.slice(startIndex..lastIndex) + + return PaginatedCollection( + content, + PaginationMetadata( + first = startIndex == 0, + last = (lastIndex + 1) >= collection.size, + numberOfElements = content.size, + offset = startIndex, + pageNumber = page, + size = pageSize, + totalElements = collection.size, + totalPages = Math.ceilDiv(collection.size, pageSize).coerceAtLeast(1), + ), + ) + } + } +}