From 2491a8912fd61371835a32f7a4eb3f325b3ed848 Mon Sep 17 00:00:00 2001 From: Amardeep Chimber Date: Thu, 14 Nov 2024 18:41:28 +0000 Subject: [PATCH 01/11] MAN-156 - add new api --- .../api/controller/AppointmentController.kt | 10 +++- .../hmpps/api/model/appointment/Outcome.kt | 10 ++++ .../delius/sentence/entity/Appointment.kt | 48 +++++++++++++++++++ .../service/AppointmentOutcomeService.kt | 24 ++++++++++ .../service/SentenceAppointmentService.kt | 1 - 5 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/appointment/Outcome.kt create mode 100644 projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/AppointmentController.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/AppointmentController.kt index 85c6066904..2d12075983 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/AppointmentController.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/AppointmentController.kt @@ -5,16 +5,24 @@ import org.springframework.http.HttpStatus import org.springframework.security.access.prepost.PreAuthorize import org.springframework.web.bind.annotation.* import uk.gov.justice.digital.hmpps.api.model.appointment.CreateAppointment +import uk.gov.justice.digital.hmpps.api.model.appointment.Outcome +import uk.gov.justice.digital.hmpps.service.AppointmentOutcomeService import uk.gov.justice.digital.hmpps.service.SentenceAppointmentService @RestController @Tag(name = "Sentence") @RequestMapping("/appointments/{crn}") @PreAuthorize("hasRole('PROBATION_API__MANAGE_A_SUPERVISION__CASE_DETAIL')") -class AppointmentController(private val appointmentService: SentenceAppointmentService) { +class AppointmentController( + private val appointmentService: SentenceAppointmentService, + private val appointmentOutcomeService: AppointmentOutcomeService) { @PostMapping @ResponseStatus(HttpStatus.CREATED) fun createAppointment(@PathVariable crn: String, @RequestBody createAppointment: CreateAppointment) = appointmentService.createAppointment(crn, createAppointment) + + @PatchMapping("/{id}") + @ResponseStatus(HttpStatus.OK) + fun recordOutcome(@RequestBody outcome: Outcome) = appointmentOutcomeService.recordOutcome(outcome) } \ No newline at end of file diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/appointment/Outcome.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/appointment/Outcome.kt new file mode 100644 index 0000000000..27d16f5ff3 --- /dev/null +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/appointment/Outcome.kt @@ -0,0 +1,10 @@ +package uk.gov.justice.digital.hmpps.api.model.appointment + +data class Outcome( + val id: Long, + val code: String, + val sensitive: Boolean, + val notes: String?, +) + + diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt index fe6b0b557d..2c76892bd5 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt @@ -2,6 +2,7 @@ package uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity import jakarta.persistence.* import org.hibernate.annotations.SQLRestriction +import org.hibernate.type.YesNoConverter import org.springframework.data.annotation.CreatedDate import org.springframework.data.annotation.LastModifiedBy import org.springframework.data.annotation.LastModifiedDate @@ -9,8 +10,10 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener import org.springframework.data.jpa.repository.JpaRepository import org.springframework.data.jpa.repository.Query import uk.gov.justice.digital.hmpps.exception.NotFoundException +import uk.gov.justice.digital.hmpps.integrations.delius.overview.entity.ContactOutcome import uk.gov.justice.digital.hmpps.integrations.delius.overview.entity.ContactType import uk.gov.justice.digital.hmpps.integrations.delius.overview.entity.Person +import java.io.Serializable import java.time.LocalDate import java.time.ZoneId import java.time.ZonedDateTime @@ -77,6 +80,17 @@ class Appointment( @Column(name = "office_location_id") val officeLocationId: Long? = null, + @ManyToOne + @JoinColumn(name = "contact_outcome_type_id") + val outcome: ContactOutcome? = null, + + @Lob + val notes: String? = null, + + @Column(name = "sensitive") + @Convert(converter = YesNoConverter::class) + val sensitive: Boolean? = null, + @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "contact_id_generator") @Column(name = "contact_id") @@ -113,6 +127,7 @@ interface AppointmentRepository : JpaRepository { startTime: String, endTime: String ): Int + } fun AppointmentRepository.appointmentClashes( @@ -133,3 +148,36 @@ interface AppointmentTypeRepository : JpaRepository { fun AppointmentTypeRepository.getByCode(code: String) = findByCode(code) ?: throw NotFoundException("AppointmentType", "code", code) + +@Entity +@Table(name = "r_contact_type_outcome") +class ContactTypeOutcome( + + @EmbeddedId + val id: ContactTypeOutcomeId +) + +interface ContactTypeOutcomeRepository : JpaRepository { + + @Query( + """ + SELECT DECODE(COUNT(1), 1, 'TRUE','FALSE') AS value + FROM ContactTypeOutcome c + JOIN c.id.outcome o + WHERE c.id = :contactTypeId + AND o.code = :code + """ + ) + fun existsById(contactTypeId: Long, code: String): Boolean + +} + +@Embeddable +class ContactTypeOutcomeId( + @Column(name = "contact_type_id") + val contactTypeId: Long, + + @ManyToOne + @JoinColumn(name = "r_contact_outcome_type") + val outcome: ContactOutcome, +) : Serializable diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt new file mode 100644 index 0000000000..de548ab60b --- /dev/null +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt @@ -0,0 +1,24 @@ +package uk.gov.justice.digital.hmpps.service + +import org.springframework.stereotype.Service +import uk.gov.justice.digital.hmpps.api.model.appointment.Outcome +import uk.gov.justice.digital.hmpps.exception.NotFoundException +import uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity.AppointmentRepository +import uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity.ContactTypeOutcomeRepository + +@Service +class AppointmentOutcomeService( + private val appointmentRepository: AppointmentRepository, + private val contactTypeOutcomeRepository: ContactTypeOutcomeRepository +) { + + fun recordOutcome(outcome: Outcome) { + val appointment = appointmentRepository.findById(outcome.id).orElseThrow { throw NotFoundException("Appointment", "id", outcome.id) } + + if (!contactTypeOutcomeRepository.existsById(appointment.type.id, outcome.code)) { + throw NotFoundException("ContactTypeOutcome", "ContactTypeOutcomeId with contact_type_id $appointment.type.id and ContactOutcome.code ", outcome.code) + } + + appointmentRepository.save(appointment) + } +} \ No newline at end of file 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 6f0e8db58f..043c8b13cf 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 @@ -17,7 +17,6 @@ import java.time.Duration import java.time.LocalDate import java.time.ZonedDateTime import java.util.* -import kotlin.math.ceil @Service class SentenceAppointmentService( From ed4b64b4c4c03971ecad1a38f2bb37f383107927 Mon Sep 17 00:00:00 2001 From: Amardeep Chimber Date: Fri, 15 Nov 2024 13:13:22 +0000 Subject: [PATCH 02/11] MAN-156 - add integration test --- .../AppointmentOutcomeIntegrationTest.kt | 87 +++++++++++++++++++ .../CreateAppointmentIntegrationTests.kt | 17 ++-- .../api/controller/AppointmentController.kt | 6 +- .../hmpps/api/model/appointment/Outcome.kt | 4 +- .../delius/sentence/entity/Appointment.kt | 37 ++++---- .../service/AppointmentOutcomeService.kt | 9 +- 6 files changed, 126 insertions(+), 34 deletions(-) create mode 100644 projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt diff --git a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt new file mode 100644 index 0000000000..2b5fa32f93 --- /dev/null +++ b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt @@ -0,0 +1,87 @@ +package uk.gov.justice.digital.hmpps + +import org.hamcrest.Matchers.equalTo +import org.junit.jupiter.api.Test +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.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post +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.Outcome +import uk.gov.justice.digital.hmpps.api.model.appointment.User +import uk.gov.justice.digital.hmpps.data.generator.OffenderManagerGenerator.STAFF_USER_1 +import uk.gov.justice.digital.hmpps.data.generator.OffenderManagerGenerator.TEAM +import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator +import uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity.AppointmentRepository +import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.contentAsJson +import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withJson +import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withToken +import java.time.ZonedDateTime +import java.util.* + +@AutoConfigureMockMvc +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +class AppointmentOutcomeIntegrationTest { + + @Autowired + internal lateinit var appointmentRepository: AppointmentRepository + + @Autowired + internal lateinit var mockMvc: MockMvc + + val outcome = Outcome(123, "ATTC") + + @Test + fun `unauthorized status returned`() { + mockMvc + .perform(MockMvcRequestBuilders.patch("/appointment") + .withJson(outcome) + ) + .andExpect(MockMvcResultMatchers.status().isUnauthorized) + } + + @Test + fun `when an appointment does not exist returns a 404 response`() { + mockMvc + .perform(MockMvcRequestBuilders.patch("/appointment") + .withToken() + .withJson(outcome) + ) + .andExpect(MockMvcResultMatchers.status().isNotFound) + .andExpect(jsonPath("$.message", equalTo("Appointment with id of 123 not found"))) + } + + @Test + fun `when an appointment outcome does not exist returns a 404 response`() { + val response = mockMvc.perform( + post("/appointment/${PersonGenerator.PERSON_1.crn}") + .withToken() + .withJson( + CreateAppointment( + User(STAFF_USER_1.username, TEAM.description), + CreateAppointment.Type.PlannedOfficeVisitNS, + ZonedDateTime.now().plusDays(1), + ZonedDateTime.now().plusDays(2), + eventId = PersonGenerator.EVENT_1.id, + uuid = UUID.randomUUID() + ) + ) + ).andReturn().response.contentAsJson() + + mockMvc + .perform(MockMvcRequestBuilders.patch("/appointment") + .withToken() + .withJson(Outcome(response.appointments[0].id, "ABC")) + ) + .andExpect(MockMvcResultMatchers.status().isNotFound) + .andExpect(jsonPath("$.message", equalTo("ContactTypeOutcome with contact_type_id 8 and outcome code of ABC not found"))) + + val appointment = appointmentRepository.findById(response.appointments[0].id).get() + appointmentRepository.delete(appointment) + } +} \ No newline at end of file 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 c7ec4eb563..d6943c367f 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 @@ -10,7 +10,6 @@ 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.test.web.servlet.MockMvc -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 @@ -48,14 +47,14 @@ class CreateAppointmentIntegrationTests { @Test fun `unauthorized status returned`() { mockMvc - .perform(MockMvcRequestBuilders.get("/appointments/D123456")) + .perform(post("/appointment/D123456")) .andExpect(MockMvcResultMatchers.status().isUnauthorized) } @Test - fun `when offender does not exist retuns a 404 response`() { + fun `when offender does not exist returns a 404 response`() { mockMvc.perform( - post("/appointments/D123456") + post("/appointment/D123456") .withToken() .withJson( CreateAppointment( @@ -75,7 +74,7 @@ class CreateAppointmentIntegrationTests { @Test fun `appointment end date before start returns bad request`() { mockMvc.perform( - post("/appointments/${PersonGenerator.PERSON_1.crn}") + post("/appointment/${PersonGenerator.PERSON_1.crn}") .withToken() .withJson( CreateAppointment( @@ -95,12 +94,12 @@ class CreateAppointmentIntegrationTests { } @ParameterizedTest - @MethodSource("createAppointments") + @MethodSource("createAppointment") fun `create a new appointment`(createAppointment: CreateAppointment) { val person = PersonGenerator.PERSON_1 val response = mockMvc.perform( - post("/appointments/${person.crn}") + post("/appointment/${person.crn}") .withToken() .withJson(createAppointment) ) @@ -128,7 +127,7 @@ class CreateAppointmentIntegrationTests { fun `create multiple appointments`(createAppointment: CreateAppointment) { val person = PersonGenerator.PERSON_1 val response = mockMvc.perform( - post("/appointments/${person.crn}") + post("/appointment/${person.crn}") .withToken() .withJson(createAppointment) ) @@ -163,7 +162,7 @@ class CreateAppointmentIntegrationTests { private val user = User(STAFF_USER_1.username, TEAM.description) @JvmStatic - fun createAppointments() = listOf( + fun createAppointment() = listOf( CreateAppointment( user, CreateAppointment.Type.PlannedOfficeVisitNS, diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/AppointmentController.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/AppointmentController.kt index 2d12075983..0a98811da1 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/AppointmentController.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/AppointmentController.kt @@ -11,18 +11,18 @@ import uk.gov.justice.digital.hmpps.service.SentenceAppointmentService @RestController @Tag(name = "Sentence") -@RequestMapping("/appointments/{crn}") +@RequestMapping("/appointment") @PreAuthorize("hasRole('PROBATION_API__MANAGE_A_SUPERVISION__CASE_DETAIL')") class AppointmentController( private val appointmentService: SentenceAppointmentService, private val appointmentOutcomeService: AppointmentOutcomeService) { - @PostMapping + @PostMapping("/{crn}") @ResponseStatus(HttpStatus.CREATED) fun createAppointment(@PathVariable crn: String, @RequestBody createAppointment: CreateAppointment) = appointmentService.createAppointment(crn, createAppointment) - @PatchMapping("/{id}") + @PatchMapping @ResponseStatus(HttpStatus.OK) fun recordOutcome(@RequestBody outcome: Outcome) = appointmentOutcomeService.recordOutcome(outcome) } \ No newline at end of file diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/appointment/Outcome.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/appointment/Outcome.kt index 27d16f5ff3..b1bc1f7c75 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/appointment/Outcome.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/appointment/Outcome.kt @@ -3,8 +3,8 @@ package uk.gov.justice.digital.hmpps.api.model.appointment data class Outcome( val id: Long, val code: String, - val sensitive: Boolean, - val notes: String?, + val sensitive: Boolean? = false, + val notes: String? = null, ) diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt index 2c76892bd5..c9f763db86 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt @@ -85,11 +85,11 @@ class Appointment( val outcome: ContactOutcome? = null, @Lob - val notes: String? = null, + var notes: String? = null, @Column(name = "sensitive") @Convert(converter = YesNoConverter::class) - val sensitive: Boolean? = null, + var sensitive: Boolean? = null, @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "contact_id_generator") @@ -154,30 +154,33 @@ fun AppointmentTypeRepository.getByCode(code: String) = class ContactTypeOutcome( @EmbeddedId - val id: ContactTypeOutcomeId + val id: ContactTypeOutcomeId, + + @ManyToOne + @JoinColumn(name = "contact_type_id", insertable = false, updatable = false) + val type: ContactType, + + @ManyToOne + @JoinColumn(name = "contact_outcome_type_id", insertable = false, updatable = false) + val outcome: ContactOutcome, ) interface ContactTypeOutcomeRepository : JpaRepository { + fun findByIdContactTypeIdAndOutcomeCode(contactTypeId: Long, code: String): ContactTypeOutcome? +} - @Query( - """ - SELECT DECODE(COUNT(1), 1, 'TRUE','FALSE') AS value - FROM ContactTypeOutcome c - JOIN c.id.outcome o - WHERE c.id = :contactTypeId - AND o.code = :code - """ - ) - fun existsById(contactTypeId: Long, code: String): Boolean +fun ContactTypeOutcomeRepository.getByTypeIdAndOutcomeCode(contactTypeId: Long, code: String) = + findByIdContactTypeIdAndOutcomeCode( + contactTypeId, code) ?: throw NotFoundException("ContactTypeOutcome", "contact_type_id $contactTypeId and outcome code", code) -} @Embeddable class ContactTypeOutcomeId( @Column(name = "contact_type_id") val contactTypeId: Long, - @ManyToOne - @JoinColumn(name = "r_contact_outcome_type") - val outcome: ContactOutcome, + @Column(name = "contact_outcome_type_id") + val contactOutcomeTypeId: Long, + ) : Serializable + diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt index de548ab60b..1a7f2e57b6 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt @@ -5,6 +5,7 @@ import uk.gov.justice.digital.hmpps.api.model.appointment.Outcome import uk.gov.justice.digital.hmpps.exception.NotFoundException import uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity.AppointmentRepository import uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity.ContactTypeOutcomeRepository +import uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity.getByTypeIdAndOutcomeCode @Service class AppointmentOutcomeService( @@ -15,10 +16,12 @@ class AppointmentOutcomeService( fun recordOutcome(outcome: Outcome) { val appointment = appointmentRepository.findById(outcome.id).orElseThrow { throw NotFoundException("Appointment", "id", outcome.id) } - if (!contactTypeOutcomeRepository.existsById(appointment.type.id, outcome.code)) { - throw NotFoundException("ContactTypeOutcome", "ContactTypeOutcomeId with contact_type_id $appointment.type.id and ContactOutcome.code ", outcome.code) - } + contactTypeOutcomeRepository.getByTypeIdAndOutcomeCode(appointment.type.id, outcome.code) + appointment.apply { + sensitive = appointment.sensitive + notes = outcome.notes + } appointmentRepository.save(appointment) } } \ No newline at end of file From a53171253d63f7620e56b014ddff23371ea2f6ec Mon Sep 17 00:00:00 2001 From: Amardeep Chimber Date: Fri, 15 Nov 2024 14:11:33 +0000 Subject: [PATCH 03/11] MAN-156 - update integration test --- .../justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt index 2b5fa32f93..c3581bcf23 100644 --- a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt +++ b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt @@ -81,7 +81,6 @@ class AppointmentOutcomeIntegrationTest { .andExpect(MockMvcResultMatchers.status().isNotFound) .andExpect(jsonPath("$.message", equalTo("ContactTypeOutcome with contact_type_id 8 and outcome code of ABC not found"))) - val appointment = appointmentRepository.findById(response.appointments[0].id).get() - appointmentRepository.delete(appointment) + appointmentRepository.deleteById(response.appointments[0].id) } } \ No newline at end of file From c497fd39b241bb861cbf21c7d37a7dbe4183afb3 Mon Sep 17 00:00:00 2001 From: Amardeep Chimber Date: Fri, 15 Nov 2024 15:08:24 +0000 Subject: [PATCH 04/11] MAN-156 - add test data --- .../justice/digital/hmpps/data/DataLoader.kt | 2 ++ .../data/generator/AppointmentGenerator.kt | 22 +++++++++++++++++++ .../hmpps/data/generator/ContactGenerator.kt | 2 +- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt b/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt index 596ae52c9f..7da807bc5b 100644 --- a/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt +++ b/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt @@ -34,7 +34,9 @@ class DataLoader( entityManager.persist(BusinessInteraction(IdGenerator.getAndIncrement(), it.code, ZonedDateTime.now())) } entityManager.persistAll( + AppointmentGenerator.ATTENDED_COMPLIED, *AppointmentGenerator.APPOINTMENT_TYPES.toTypedArray(), + *AppointmentGenerator.CONTACT_TYPE_OUTCOMES.toTypedArray(), ContactGenerator.DEFAULT_PROVIDER, ContactGenerator.DEFAULT_BOROUGH, ContactGenerator.DEFAULT_DISTRICT, diff --git a/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/AppointmentGenerator.kt b/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/AppointmentGenerator.kt index 95d9d0839c..ae72e62825 100644 --- a/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/AppointmentGenerator.kt +++ b/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/AppointmentGenerator.kt @@ -1,7 +1,11 @@ package uk.gov.justice.digital.hmpps.data.generator import uk.gov.justice.digital.hmpps.api.model.appointment.CreateAppointment +import uk.gov.justice.digital.hmpps.data.generator.ContactGenerator.generateOutcome +import uk.gov.justice.digital.hmpps.integrations.delius.overview.entity.ContactOutcome import uk.gov.justice.digital.hmpps.integrations.delius.overview.entity.ContactType +import uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity.ContactTypeOutcome +import uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity.ContactTypeOutcomeId object AppointmentGenerator { @@ -13,4 +17,22 @@ object AppointmentGenerator { attendanceType: Boolean, id: Long = IdGenerator.getAndIncrement() ) = ContactType(IdGenerator.getAndIncrement(), code, true, description) + + + val ATTENDED_COMPLIED = generateOutcome("ATTC", "Attended - Complied", true, true) + + val CONTACT_TYPE_OUTCOMES = APPOINTMENT_TYPES.map { + generateContactTypeOutcome(it.id, ATTENDED_COMPLIED.id, it, ATTENDED_COMPLIED) + } + + fun generateContactTypeOutcome( + contactTypeId: Long, + contactOutcomeTypeId: Long, + contactType: ContactType, + outcome: ContactOutcome + ) = ContactTypeOutcome ( + ContactTypeOutcomeId(contactTypeId, contactOutcomeTypeId), + contactType, + outcome + ) } diff --git a/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ContactGenerator.kt b/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ContactGenerator.kt index 8bf5b72db3..44bc3978a9 100644 --- a/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ContactGenerator.kt +++ b/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/ContactGenerator.kt @@ -179,7 +179,7 @@ object ContactGenerator { outcome = outcome ) - private fun generateOutcome(code: String, description: String, attendance: Boolean, acceptable: Boolean) = + fun generateOutcome(code: String, description: String, attendance: Boolean, acceptable: Boolean) = ContactOutcome(IdGenerator.getAndIncrement(), code, description, attendance, acceptable) private fun generateContactType( From 3c3e9a434ef475b2c24bcd1a5b9f1efd0f8d2c80 Mon Sep 17 00:00:00 2001 From: Amardeep Chimber Date: Fri, 15 Nov 2024 16:32:45 +0000 Subject: [PATCH 05/11] MAN-156 - update api and test --- .../AppointmentOutcomeIntegrationTest.kt | 59 ++++++++++++++----- .../delius/sentence/entity/Appointment.kt | 3 + .../service/AppointmentOutcomeService.kt | 6 +- 3 files changed, 52 insertions(+), 16 deletions(-) diff --git a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt index c3581bcf23..47fedf817c 100644 --- a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt +++ b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt @@ -1,6 +1,9 @@ package uk.gov.justice.digital.hmpps +import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.equalTo +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc @@ -14,10 +17,15 @@ 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.Outcome import uk.gov.justice.digital.hmpps.api.model.appointment.User +import uk.gov.justice.digital.hmpps.data.generator.AppointmentGenerator.ATTENDED_COMPLIED +import uk.gov.justice.digital.hmpps.data.generator.ContactGenerator.DEFAULT_PROVIDER +import uk.gov.justice.digital.hmpps.data.generator.OffenderManagerGenerator.DEFAULT_LOCATION +import uk.gov.justice.digital.hmpps.data.generator.OffenderManagerGenerator.STAFF_1 import uk.gov.justice.digital.hmpps.data.generator.OffenderManagerGenerator.STAFF_USER_1 import uk.gov.justice.digital.hmpps.data.generator.OffenderManagerGenerator.TEAM import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator import uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity.AppointmentRepository +import uk.gov.justice.digital.hmpps.test.CustomMatchers.isCloseTo import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.contentAsJson import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withJson import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withToken @@ -58,20 +66,7 @@ class AppointmentOutcomeIntegrationTest { @Test fun `when an appointment outcome does not exist returns a 404 response`() { - val response = mockMvc.perform( - post("/appointment/${PersonGenerator.PERSON_1.crn}") - .withToken() - .withJson( - CreateAppointment( - User(STAFF_USER_1.username, TEAM.description), - CreateAppointment.Type.PlannedOfficeVisitNS, - ZonedDateTime.now().plusDays(1), - ZonedDateTime.now().plusDays(2), - eventId = PersonGenerator.EVENT_1.id, - uuid = UUID.randomUUID() - ) - ) - ).andReturn().response.contentAsJson() + val response = createAppointment() mockMvc .perform(MockMvcRequestBuilders.patch("/appointment") @@ -83,4 +78,40 @@ class AppointmentOutcomeIntegrationTest { appointmentRepository.deleteById(response.appointments[0].id) } + + @Test + fun `outcome updated`() { + val response = createAppointment() + val request = Outcome(response.appointments[0].id, "ATTC", false, "my notes") + + mockMvc + .perform(MockMvcRequestBuilders.patch("/appointment") + .withToken() + .withJson(request) + ) + .andExpect(MockMvcResultMatchers.status().isOk) + + val appointment = appointmentRepository.findById(response.appointments[0].id).get() + assertEquals("Y", appointment.attended) + assertEquals(request.notes, appointment.notes) + assertFalse(appointment.sensitive!!) + + + appointmentRepository.delete(appointment) + } + + private fun createAppointment() = mockMvc.perform( + post("/appointment/${PersonGenerator.PERSON_1.crn}") + .withToken() + .withJson( + CreateAppointment( + User(STAFF_USER_1.username, TEAM.description), + CreateAppointment.Type.PlannedOfficeVisitNS, + ZonedDateTime.now().plusDays(1), + ZonedDateTime.now().plusDays(2), + eventId = PersonGenerator.EVENT_1.id, + uuid = UUID.randomUUID() + ) + ) + ).andReturn().response.contentAsJson() } \ No newline at end of file diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt index c9f763db86..1731f4fac7 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt @@ -80,6 +80,9 @@ class Appointment( @Column(name = "office_location_id") val officeLocationId: Long? = null, + @Column(name = "attended", columnDefinition = "char(1)") + var attended: String? = null, + @ManyToOne @JoinColumn(name = "contact_outcome_type_id") val outcome: ContactOutcome? = null, diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt index 1a7f2e57b6..823fc930ab 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt @@ -16,12 +16,14 @@ class AppointmentOutcomeService( fun recordOutcome(outcome: Outcome) { val appointment = appointmentRepository.findById(outcome.id).orElseThrow { throw NotFoundException("Appointment", "id", outcome.id) } - contactTypeOutcomeRepository.getByTypeIdAndOutcomeCode(appointment.type.id, outcome.code) + val contactTypeOutcome = contactTypeOutcomeRepository.getByTypeIdAndOutcomeCode(appointment.type.id, outcome.code) appointment.apply { - sensitive = appointment.sensitive + attended = if (contactTypeOutcome.type.attendanceContact) "Y" else "N" notes = outcome.notes + sensitive = outcome.sensitive } + appointmentRepository.save(appointment) } } \ No newline at end of file From b28658de98dbf50f4da61b1bf1f627e7b8c8cdd1 Mon Sep 17 00:00:00 2001 From: Amardeep Chimber Date: Fri, 15 Nov 2024 17:30:58 +0000 Subject: [PATCH 06/11] MAN-156 - update api and test --- .../digital/hmpps/AppointmentOutcomeIntegrationTest.kt | 6 +----- .../integrations/delius/sentence/entity/Appointment.kt | 5 ++--- .../digital/hmpps/service/AppointmentOutcomeService.kt | 1 + 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt index 47fedf817c..df3c6e4494 100644 --- a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt +++ b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt @@ -1,6 +1,5 @@ package uk.gov.justice.digital.hmpps -import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.equalTo import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertFalse @@ -18,14 +17,10 @@ import uk.gov.justice.digital.hmpps.api.model.appointment.CreateAppointment import uk.gov.justice.digital.hmpps.api.model.appointment.Outcome import uk.gov.justice.digital.hmpps.api.model.appointment.User import uk.gov.justice.digital.hmpps.data.generator.AppointmentGenerator.ATTENDED_COMPLIED -import uk.gov.justice.digital.hmpps.data.generator.ContactGenerator.DEFAULT_PROVIDER -import uk.gov.justice.digital.hmpps.data.generator.OffenderManagerGenerator.DEFAULT_LOCATION -import uk.gov.justice.digital.hmpps.data.generator.OffenderManagerGenerator.STAFF_1 import uk.gov.justice.digital.hmpps.data.generator.OffenderManagerGenerator.STAFF_USER_1 import uk.gov.justice.digital.hmpps.data.generator.OffenderManagerGenerator.TEAM import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator import uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity.AppointmentRepository -import uk.gov.justice.digital.hmpps.test.CustomMatchers.isCloseTo import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.contentAsJson import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withJson import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withToken @@ -94,6 +89,7 @@ class AppointmentOutcomeIntegrationTest { val appointment = appointmentRepository.findById(response.appointments[0].id).get() assertEquals("Y", appointment.attended) assertEquals(request.notes, appointment.notes) + assertEquals(ATTENDED_COMPLIED.id, appointment.outcomeId) assertFalse(appointment.sensitive!!) diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt index 1731f4fac7..74e1197344 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt @@ -83,9 +83,8 @@ class Appointment( @Column(name = "attended", columnDefinition = "char(1)") var attended: String? = null, - @ManyToOne - @JoinColumn(name = "contact_outcome_type_id") - val outcome: ContactOutcome? = null, + @Column(name = "contact_outcome_type_id") + var outcomeId: Long? = null, @Lob var notes: String? = null, diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt index 823fc930ab..87d23ae913 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt @@ -21,6 +21,7 @@ class AppointmentOutcomeService( appointment.apply { attended = if (contactTypeOutcome.type.attendanceContact) "Y" else "N" notes = outcome.notes + outcomeId = contactTypeOutcome.outcome.id sensitive = outcome.sensitive } From 45ab325293654fcc45cd339eeb512ea4a6946133 Mon Sep 17 00:00:00 2001 From: "probation-integration-bot[bot]" <177347787+probation-integration-bot[bot]@users.noreply.github.com> Date: Fri, 15 Nov 2024 19:47:56 +0000 Subject: [PATCH 07/11] Formatting changes --- .../data/generator/AppointmentGenerator.kt | 11 +++---- .../AppointmentOutcomeIntegrationTest.kt | 33 ++++++++++++------- .../api/controller/AppointmentController.kt | 3 +- .../delius/sentence/entity/Appointment.kt | 7 ++-- .../service/AppointmentOutcomeService.kt | 6 ++-- 5 files changed, 35 insertions(+), 25 deletions(-) diff --git a/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/AppointmentGenerator.kt b/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/AppointmentGenerator.kt index ae72e62825..b77f10a1ce 100644 --- a/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/AppointmentGenerator.kt +++ b/projects/manage-supervision-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/AppointmentGenerator.kt @@ -18,7 +18,6 @@ object AppointmentGenerator { id: Long = IdGenerator.getAndIncrement() ) = ContactType(IdGenerator.getAndIncrement(), code, true, description) - val ATTENDED_COMPLIED = generateOutcome("ATTC", "Attended - Complied", true, true) val CONTACT_TYPE_OUTCOMES = APPOINTMENT_TYPES.map { @@ -30,9 +29,9 @@ object AppointmentGenerator { contactOutcomeTypeId: Long, contactType: ContactType, outcome: ContactOutcome - ) = ContactTypeOutcome ( - ContactTypeOutcomeId(contactTypeId, contactOutcomeTypeId), - contactType, - outcome - ) + ) = ContactTypeOutcome( + ContactTypeOutcomeId(contactTypeId, contactOutcomeTypeId), + contactType, + outcome + ) } diff --git a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt index df3c6e4494..0fa4610a85 100644 --- a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt +++ b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt @@ -42,8 +42,9 @@ class AppointmentOutcomeIntegrationTest { @Test fun `unauthorized status returned`() { mockMvc - .perform(MockMvcRequestBuilders.patch("/appointment") - .withJson(outcome) + .perform( + MockMvcRequestBuilders.patch("/appointment") + .withJson(outcome) ) .andExpect(MockMvcResultMatchers.status().isUnauthorized) } @@ -51,9 +52,10 @@ class AppointmentOutcomeIntegrationTest { @Test fun `when an appointment does not exist returns a 404 response`() { mockMvc - .perform(MockMvcRequestBuilders.patch("/appointment") - .withToken() - .withJson(outcome) + .perform( + MockMvcRequestBuilders.patch("/appointment") + .withToken() + .withJson(outcome) ) .andExpect(MockMvcResultMatchers.status().isNotFound) .andExpect(jsonPath("$.message", equalTo("Appointment with id of 123 not found"))) @@ -64,12 +66,18 @@ class AppointmentOutcomeIntegrationTest { val response = createAppointment() mockMvc - .perform(MockMvcRequestBuilders.patch("/appointment") - .withToken() - .withJson(Outcome(response.appointments[0].id, "ABC")) + .perform( + MockMvcRequestBuilders.patch("/appointment") + .withToken() + .withJson(Outcome(response.appointments[0].id, "ABC")) ) .andExpect(MockMvcResultMatchers.status().isNotFound) - .andExpect(jsonPath("$.message", equalTo("ContactTypeOutcome with contact_type_id 8 and outcome code of ABC not found"))) + .andExpect( + jsonPath( + "$.message", + equalTo("ContactTypeOutcome with contact_type_id 8 and outcome code of ABC not found") + ) + ) appointmentRepository.deleteById(response.appointments[0].id) } @@ -80,9 +88,10 @@ class AppointmentOutcomeIntegrationTest { val request = Outcome(response.appointments[0].id, "ATTC", false, "my notes") mockMvc - .perform(MockMvcRequestBuilders.patch("/appointment") - .withToken() - .withJson(request) + .perform( + MockMvcRequestBuilders.patch("/appointment") + .withToken() + .withJson(request) ) .andExpect(MockMvcResultMatchers.status().isOk) diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/AppointmentController.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/AppointmentController.kt index 0a98811da1..07e0a118d5 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/AppointmentController.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/controller/AppointmentController.kt @@ -15,7 +15,8 @@ import uk.gov.justice.digital.hmpps.service.SentenceAppointmentService @PreAuthorize("hasRole('PROBATION_API__MANAGE_A_SUPERVISION__CASE_DETAIL')") class AppointmentController( private val appointmentService: SentenceAppointmentService, - private val appointmentOutcomeService: AppointmentOutcomeService) { + private val appointmentOutcomeService: AppointmentOutcomeService +) { @PostMapping("/{crn}") @ResponseStatus(HttpStatus.CREATED) diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt index 74e1197344..7d9bb9eac3 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/sentence/entity/Appointment.kt @@ -129,7 +129,6 @@ interface AppointmentRepository : JpaRepository { startTime: String, endTime: String ): Int - } fun AppointmentRepository.appointmentClashes( @@ -173,8 +172,8 @@ interface ContactTypeOutcomeRepository : JpaRepository Date: Fri, 15 Nov 2024 23:26:50 +0000 Subject: [PATCH 08/11] MAN-156 - update test --- .../AppointmentOutcomeIntegrationTest.kt | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt index df3c6e4494..aba4f46e0a 100644 --- a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt +++ b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt @@ -1,8 +1,8 @@ package uk.gov.justice.digital.hmpps +import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.equalTo -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc @@ -21,6 +21,7 @@ import uk.gov.justice.digital.hmpps.data.generator.OffenderManagerGenerator.STAF import uk.gov.justice.digital.hmpps.data.generator.OffenderManagerGenerator.TEAM import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator import uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity.AppointmentRepository +import uk.gov.justice.digital.hmpps.test.CustomMatchers.isCloseTo import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.contentAsJson import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withJson import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withToken @@ -77,7 +78,14 @@ class AppointmentOutcomeIntegrationTest { @Test fun `outcome updated`() { val response = createAppointment() - val request = Outcome(response.appointments[0].id, "ATTC", false, "my notes") + val createdAppointment = appointmentRepository.findById(response.appointments[0].id).get() + + assertNull(createdAppointment.attended) + assertNull(createdAppointment.notes) + assertNull(createdAppointment.outcomeId) + assertNull(createdAppointment.sensitive) + + val request = Outcome(response.appointments[0].id, "ATTC", notes = "my notes") mockMvc .perform(MockMvcRequestBuilders.patch("/appointment") @@ -86,14 +94,24 @@ class AppointmentOutcomeIntegrationTest { ) .andExpect(MockMvcResultMatchers.status().isOk) - val appointment = appointmentRepository.findById(response.appointments[0].id).get() - assertEquals("Y", appointment.attended) - assertEquals(request.notes, appointment.notes) - assertEquals(ATTENDED_COMPLIED.id, appointment.outcomeId) - assertFalse(appointment.sensitive!!) + val updatedAppointment = appointmentRepository.findById(response.appointments[0].id).get() + assertEquals("Y", updatedAppointment.attended) + assertEquals(request.notes, updatedAppointment.notes) + assertEquals(ATTENDED_COMPLIED.id, updatedAppointment.outcomeId) + assertFalse(updatedAppointment.sensitive!!) + + assertThat(updatedAppointment.type.code, equalTo(createdAppointment.type.code)) + assertThat(updatedAppointment.date, equalTo(createdAppointment.date)) + assertThat(updatedAppointment.startTime, isCloseTo(createdAppointment.startTime)) + assertThat(updatedAppointment.externalReference, equalTo(createdAppointment.externalReference)) + assertThat(updatedAppointment.eventId, equalTo(createdAppointment.eventId)) + assertThat(updatedAppointment.createdByUserId, equalTo(createdAppointment.createdByUserId)) + assertThat(updatedAppointment.staffId, equalTo(createdAppointment.staffId)) + assertThat(updatedAppointment.probationAreaId, equalTo(createdAppointment.probationAreaId)) + assertThat(updatedAppointment.officeLocationId, equalTo(createdAppointment.officeLocationId)) - appointmentRepository.delete(appointment) + appointmentRepository.delete(updatedAppointment) } private fun createAppointment() = mockMvc.perform( From e78b49dc695768643deba0f752d5e8aeedb7ac2c Mon Sep 17 00:00:00 2001 From: "probation-integration-bot[bot]" <177347787+probation-integration-bot[bot]@users.noreply.github.com> Date: Fri, 15 Nov 2024 23:28:55 +0000 Subject: [PATCH 09/11] Formatting changes --- .../justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt index 61d1beb1bf..a44bc35f86 100644 --- a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt +++ b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt @@ -93,7 +93,7 @@ class AppointmentOutcomeIntegrationTest { assertNull(createdAppointment.outcomeId) assertNull(createdAppointment.sensitive) - val request = Outcome(response.appointments[0].id, "ATTC", notes = "my notes") + val request = Outcome(response.appointments[0].id, "ATTC", notes = "my notes") mockMvc .perform( From 691b2b4e5e7469538cb9520d6f8f1d91d8e72154 Mon Sep 17 00:00:00 2001 From: Amardeep Chimber Date: Fri, 15 Nov 2024 23:29:14 +0000 Subject: [PATCH 10/11] MAN-156 - update test --- .../justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt index 61d1beb1bf..2469d5a14a 100644 --- a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt +++ b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt @@ -104,6 +104,7 @@ class AppointmentOutcomeIntegrationTest { .andExpect(MockMvcResultMatchers.status().isOk) val updatedAppointment = appointmentRepository.findById(response.appointments[0].id).get() + assertEquals("Y", updatedAppointment.attended) assertEquals(request.notes, updatedAppointment.notes) assertEquals(ATTENDED_COMPLIED.id, updatedAppointment.outcomeId) @@ -119,7 +120,6 @@ class AppointmentOutcomeIntegrationTest { assertThat(updatedAppointment.probationAreaId, equalTo(createdAppointment.probationAreaId)) assertThat(updatedAppointment.officeLocationId, equalTo(createdAppointment.officeLocationId)) - appointmentRepository.delete(updatedAppointment) } From 843b2946f57b144354ba89f5cf35e8b396eada7d Mon Sep 17 00:00:00 2001 From: Amardeep Chimber Date: Mon, 18 Nov 2024 10:19:01 +0000 Subject: [PATCH 11/11] MAN-156 - add new attribute --- .../digital/hmpps/AppointmentOutcomeIntegrationTest.kt | 6 +++--- .../justice/digital/hmpps/api/model/appointment/Outcome.kt | 1 + .../digital/hmpps/service/AppointmentOutcomeService.kt | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt index 073aeb8e16..42aa7a3291 100644 --- a/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt +++ b/projects/manage-supervision-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/AppointmentOutcomeIntegrationTest.kt @@ -38,7 +38,7 @@ class AppointmentOutcomeIntegrationTest { @Autowired internal lateinit var mockMvc: MockMvc - val outcome = Outcome(123, "ATTC") + val outcome = Outcome(123, "ATTC", "N") @Test fun `unauthorized status returned`() { @@ -70,7 +70,7 @@ class AppointmentOutcomeIntegrationTest { .perform( MockMvcRequestBuilders.patch("/appointment") .withToken() - .withJson(Outcome(response.appointments[0].id, "ABC")) + .withJson(Outcome(response.appointments[0].id, "ABC", "Y")) ) .andExpect(MockMvcResultMatchers.status().isNotFound) .andExpect( @@ -93,7 +93,7 @@ class AppointmentOutcomeIntegrationTest { assertNull(createdAppointment.outcomeId) assertNull(createdAppointment.sensitive) - val request = Outcome(response.appointments[0].id, "ATTC", notes = "my notes") + val request = Outcome(response.appointments[0].id, "ATTC", "Y", notes = "my notes") mockMvc .perform( diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/appointment/Outcome.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/appointment/Outcome.kt index b1bc1f7c75..e410208248 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/appointment/Outcome.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/api/model/appointment/Outcome.kt @@ -3,6 +3,7 @@ package uk.gov.justice.digital.hmpps.api.model.appointment data class Outcome( val id: Long, val code: String, + val attended: String, val sensitive: Boolean? = false, val notes: String? = null, ) diff --git a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt index c40cff7860..589ed18335 100644 --- a/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt +++ b/projects/manage-supervision-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AppointmentOutcomeService.kt @@ -21,7 +21,7 @@ class AppointmentOutcomeService( contactTypeOutcomeRepository.getByTypeIdAndOutcomeCode(appointment.type.id, outcome.code) appointment.apply { - attended = if (contactTypeOutcome.type.attendanceContact) "Y" else "N" + attended = outcome.attended notes = outcome.notes outcomeId = contactTypeOutcome.outcome.id sensitive = outcome.sensitive