diff --git a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/CreateAppointmentIntegrationTests.kt b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/CreateAppointmentIntegrationTests.kt index 35edb81cd2..c7ec4eb563 100644 --- a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/CreateAppointmentIntegrationTests.kt +++ b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/CreateAppointmentIntegrationTests.kt @@ -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 @@ -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 @@ -194,7 +197,7 @@ 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() ), @@ -202,7 +205,7 @@ class CreateAppointmentIntegrationTests { 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() diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/SentenceAppointmentService.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/SentenceAppointmentService.kt index ba0d155322..6f0e8db58f 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/SentenceAppointmentService.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/SentenceAppointmentService.kt @@ -1,8 +1,6 @@ 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 @@ -10,15 +8,16 @@ 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( @@ -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) { @@ -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)) { @@ -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") } } diff --git a/projects/manage-supervision-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/SentenceAppointmentServiceTest.kt b/projects/manage-supervision-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/SentenceAppointmentServiceTest.kt index 1307d3a61c..0b253edf5b 100644 --- a/projects/manage-supervision-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/SentenceAppointmentServiceTest.kt +++ b/projects/manage-supervision-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/SentenceAppointmentServiceTest.kt @@ -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.* @@ -75,13 +75,13 @@ class SentenceAppointmentServiceTest { whenever(offenderManagerRepository.findByPersonCrnAndSoftDeletedIsFalseAndActiveIsTrue(PersonGenerator.PERSON_1.crn)).thenReturn( OffenderManagerGenerator.OFFENDER_MANAGER_ACTIVE ) - val exception = assertThrows { + val exception = assertThrows { 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) @@ -108,11 +108,11 @@ class SentenceAppointmentServiceTest { whenever(offenderManagerRepository.findByPersonCrnAndSoftDeletedIsFalseAndActiveIsTrue(PersonGenerator.PERSON_1.crn)).thenReturn( OffenderManagerGenerator.OFFENDER_MANAGER_ACTIVE ) - val exception = assertThrows { + val exception = assertThrows { 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) @@ -138,11 +138,11 @@ class SentenceAppointmentServiceTest { whenever(offenderManagerRepository.findByPersonCrnAndSoftDeletedIsFalseAndActiveIsTrue(PersonGenerator.PERSON_1.crn)).thenReturn( OffenderManagerGenerator.OFFENDER_MANAGER_ACTIVE ) - val exception = assertThrows { + val exception = assertThrows { 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)