Skip to content

Commit

Permalink
MAN-109 - Use Duration instead of Period when calculating number of a… (
Browse files Browse the repository at this point in the history
#4393)

* MAN-109 - Use Duration instead of Period when calculating number of appointments. Amend exception type so that message is returned via controller advice

* Formatting changes

* Update projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/SentenceAppointmentService.kt

Co-authored-by: Marcus Aspin <[email protected]>

---------

Co-authored-by: probation-integration-bot[bot] <177347787+probation-integration-bot[bot]@users.noreply.github.com>
Co-authored-by: Marcus Aspin <[email protected]>
  • Loading branch information
3 people authored Nov 5, 2024
1 parent a01831a commit aa655c6
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
import org.springframework.test.web.servlet.result.MockMvcResultHandlers.print
import org.springframework.test.web.servlet.result.MockMvcResultMatchers
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
import uk.gov.justice.digital.hmpps.api.model.appointment.AppointmentDetail
import uk.gov.justice.digital.hmpps.api.model.appointment.CreateAppointment
import uk.gov.justice.digital.hmpps.api.model.appointment.User
Expand Down Expand Up @@ -88,7 +89,9 @@ class CreateAppointmentIntegrationTests {
UUID.randomUUID()
)
)
).andExpect(MockMvcResultMatchers.status().isBadRequest)
)
.andExpect(MockMvcResultMatchers.status().isBadRequest)
.andExpect(jsonPath("$.message", equalTo("Appointment end time cannot be before start time")))
}

@ParameterizedTest
Expand Down Expand Up @@ -194,15 +197,15 @@ class CreateAppointmentIntegrationTests {
user,
CreateAppointment.Type.HomeVisitToCaseNS,
ZonedDateTime.now(),
until = ZonedDateTime.now().plusDays(3),
until = ZonedDateTime.now().plusDays(2),
eventId = PersonGenerator.EVENT_1.id,
uuid = UUID.randomUUID()
),
CreateAppointment(
user,
CreateAppointment.Type.HomeVisitToCaseNS,
start = ZonedDateTime.now(),
until = ZonedDateTime.now().plusDays(21),
until = ZonedDateTime.now().plusDays(14),
interval = CreateAppointment.Interval.WEEK,
eventId = PersonGenerator.EVENT_1.id,
uuid = UUID.randomUUID()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
package uk.gov.justice.digital.hmpps.service

import org.springframework.http.HttpStatus
import org.springframework.stereotype.Service
import org.springframework.web.server.ResponseStatusException
import uk.gov.justice.digital.hmpps.api.model.appointment.AppointmentDetail
import uk.gov.justice.digital.hmpps.api.model.appointment.CreateAppointment
import uk.gov.justice.digital.hmpps.api.model.appointment.CreatedAppointment
import uk.gov.justice.digital.hmpps.audit.service.AuditableService
import uk.gov.justice.digital.hmpps.audit.service.AuditedInteractionService
import uk.gov.justice.digital.hmpps.datetime.EuropeLondon
import uk.gov.justice.digital.hmpps.exception.ConflictException
import uk.gov.justice.digital.hmpps.exception.InvalidRequestException
import uk.gov.justice.digital.hmpps.exception.NotFoundException
import uk.gov.justice.digital.hmpps.integrations.delius.audit.BusinessInteractionCode
import uk.gov.justice.digital.hmpps.integrations.delius.overview.entity.RequirementRepository
import uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity.*
import java.time.Period
import java.time.Duration
import java.time.LocalDate
import java.time.ZonedDateTime
import java.util.*
import kotlin.collections.ArrayList
import kotlin.math.ceil

@Service
class SentenceAppointmentService(
Expand All @@ -45,10 +44,12 @@ class SentenceAppointmentService(

createAppointment.let {
val numberOfAppointments = createAppointment.until?.let {
Period.between(
createAppointment.start.toLocalDate(),
it.toLocalDate()
).days.div(createAppointment.interval.value)
val duration = Duration.between(
createAppointment.start.toLocalDateTime(),
it.toLocalDateTime()
).toDays()

(duration / createAppointment.interval.value).toInt() + 1
} ?: createAppointment.numberOfAppointments

for (i in 0 until numberOfAppointments) {
Expand Down Expand Up @@ -85,26 +86,17 @@ class SentenceAppointmentService(
createAppointment: CreateAppointment
) {
if (createAppointment.requirementId != null && createAppointment.licenceConditionId != null) {
throw ResponseStatusException(
HttpStatus.BAD_REQUEST,
"Either licence id or requirement id can be provided, not both"
)
throw InvalidRequestException("Either licence id or requirement id can be provided, not both")
}

createAppointment.end?.let {
if (it.isBefore(createAppointment.start))
throw ResponseStatusException(
HttpStatus.BAD_REQUEST,
"Appointment end time cannot be before start time"
)
throw InvalidRequestException("Appointment end time cannot be before start time")
}

createAppointment.until?.let {
if (it.isBefore(createAppointment.start))
throw ResponseStatusException(
HttpStatus.BAD_REQUEST,
"Until cannot be before start time"
)
throw InvalidRequestException("Until cannot be before start time")
}

if (!eventSentenceRepository.existsById(createAppointment.eventId)) {
Expand Down Expand Up @@ -132,10 +124,7 @@ class SentenceAppointmentService(
val licenceOrRequirement = listOfNotNull(createAppointment.licenceConditionId, createAppointment.requirementId)

if (licenceOrRequirement.size > 1) {
throw ResponseStatusException(
HttpStatus.BAD_REQUEST,
"Either licence id or requirement id can be provided, not both"
)
throw InvalidRequestException("Either licence id or requirement id can be provided, not both")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.kotlin.verifyNoInteractions
import org.mockito.kotlin.whenever
import org.springframework.web.server.ResponseStatusException
import uk.gov.justice.digital.hmpps.api.model.appointment.CreateAppointment
import uk.gov.justice.digital.hmpps.api.model.appointment.User
import uk.gov.justice.digital.hmpps.audit.service.AuditedInteractionService
import uk.gov.justice.digital.hmpps.data.generator.OffenderManagerGenerator
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator
import uk.gov.justice.digital.hmpps.exception.InvalidRequestException
import uk.gov.justice.digital.hmpps.exception.NotFoundException
import uk.gov.justice.digital.hmpps.integrations.delius.overview.entity.RequirementRepository
import uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity.*
Expand Down Expand Up @@ -75,13 +75,13 @@ class SentenceAppointmentServiceTest {
whenever(offenderManagerRepository.findByPersonCrnAndSoftDeletedIsFalseAndActiveIsTrue(PersonGenerator.PERSON_1.crn)).thenReturn(
OffenderManagerGenerator.OFFENDER_MANAGER_ACTIVE
)
val exception = assertThrows<ResponseStatusException> {
val exception = assertThrows<InvalidRequestException> {
service.createAppointment(PersonGenerator.PERSON_1.crn, appointment)
}

assertThat(
exception.message,
equalTo("400 BAD_REQUEST \"Either licence id or requirement id can be provided, not both\"")
equalTo("Either licence id or requirement id can be provided, not both")
)

verifyNoMoreInteractions(offenderManagerRepository)
Expand All @@ -108,11 +108,11 @@ class SentenceAppointmentServiceTest {
whenever(offenderManagerRepository.findByPersonCrnAndSoftDeletedIsFalseAndActiveIsTrue(PersonGenerator.PERSON_1.crn)).thenReturn(
OffenderManagerGenerator.OFFENDER_MANAGER_ACTIVE
)
val exception = assertThrows<ResponseStatusException> {
val exception = assertThrows<InvalidRequestException> {
service.createAppointment(PersonGenerator.PERSON_1.crn, appointment)
}

assertThat(exception.message, equalTo("400 BAD_REQUEST \"Appointment end time cannot be before start time\""))
assertThat(exception.message, equalTo("Appointment end time cannot be before start time"))

verifyNoMoreInteractions(offenderManagerRepository)
verifyNoInteractions(eventSentenceRepository)
Expand All @@ -138,11 +138,11 @@ class SentenceAppointmentServiceTest {
whenever(offenderManagerRepository.findByPersonCrnAndSoftDeletedIsFalseAndActiveIsTrue(PersonGenerator.PERSON_1.crn)).thenReturn(
OffenderManagerGenerator.OFFENDER_MANAGER_ACTIVE
)
val exception = assertThrows<ResponseStatusException> {
val exception = assertThrows<InvalidRequestException> {
service.createAppointment(PersonGenerator.PERSON_1.crn, appointment)
}

assertThat(exception.message, equalTo("400 BAD_REQUEST \"Until cannot be before start time\""))
assertThat(exception.message, equalTo("Until cannot be before start time"))

verifyNoMoreInteractions(offenderManagerRepository)
verifyNoInteractions(eventSentenceRepository)
Expand Down

0 comments on commit aa655c6

Please sign in to comment.