Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
* PI-1961 

* PI-1961 create alert and add audit
  • Loading branch information
anthony-britton-moj authored Mar 6, 2024
1 parent 825242e commit 22bd573
Show file tree
Hide file tree
Showing 14 changed files with 434 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ database:
access:
username_key: /resettlement-passport-and-delius/db-username
password_key: /resettlement-passport-and-delius/db-password
tables:
- audited_interaction
- contact

audit:
username: ResettlementPassportAndDelius
forename: Probation Integration # TODO change this to something meaningful for your service
forename: Resettlement Passport
surname: Service
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,19 @@ import org.springframework.boot.context.event.ApplicationReadyEvent
import org.springframework.context.ApplicationListener
import org.springframework.stereotype.Component
import org.springframework.transaction.annotation.Transactional
import uk.gov.justice.digital.hmpps.data.generator.AddressGenerator
import uk.gov.justice.digital.hmpps.data.generator.AppointmentGenerator
import uk.gov.justice.digital.hmpps.data.generator.NSIGenerator
import uk.gov.justice.digital.hmpps.data.generator.NSIManagerGenerator
import uk.gov.justice.digital.hmpps.data.generator.NSIStatusGenerator
import uk.gov.justice.digital.hmpps.data.generator.NSITypeGenerator
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator
import uk.gov.justice.digital.hmpps.data.generator.ProviderGenerator
import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator
import uk.gov.justice.digital.hmpps.data.generator.RegistrationGenerator
import uk.gov.justice.digital.hmpps.data.generator.UserGenerator
import uk.gov.justice.digital.hmpps.api.model.CreateAppointment
import uk.gov.justice.digital.hmpps.audit.BusinessInteraction
import uk.gov.justice.digital.hmpps.data.generator.*
import uk.gov.justice.digital.hmpps.datetime.EuropeLondon
import uk.gov.justice.digital.hmpps.entity.BusinessInteractionCode
import uk.gov.justice.digital.hmpps.entity.Category
import uk.gov.justice.digital.hmpps.entity.Level
import uk.gov.justice.digital.hmpps.entity.Person
import uk.gov.justice.digital.hmpps.user.AuditUserRepository
import java.time.LocalDate
import java.time.LocalTime
import java.time.ZonedDateTime
import java.util.*

@Component
@ConditionalOnProperty("seed.database")
Expand All @@ -41,6 +35,9 @@ class DataLoader(

@Transactional
override fun onApplicationEvent(are: ApplicationReadyEvent) {
BusinessInteractionCode.entries.forEach {
em.persist(BusinessInteraction(IdGenerator.getAndIncrement(), it.code, ZonedDateTime.now()))
}
em.saveAll(
NSITypeGenerator.DTR,
NSIStatusGenerator.INITIATED,
Expand Down Expand Up @@ -75,6 +72,29 @@ class DataLoader(
)

createAppointments(PersonGenerator.DEFAULT)

createAppointmentData()
}

fun createAppointmentData() {
val conflictPerson = PersonGenerator.CREATE_APPOINTMENT
val conflictManager = PersonGenerator.generateManager(PersonGenerator.CREATE_APPOINTMENT)
em.saveAll(
*AppointmentGenerator.APPOINTMENT_TYPES.toTypedArray(),
conflictPerson,
conflictManager,
AppointmentGenerator.generate(
conflictPerson,
AppointmentGenerator.ATTENDANCE_TYPE,
LocalDate.now().plusDays(7),
ZonedDateTime.now().plusDays(7),
ZonedDateTime.now().plusDays(7).plusHours(1),
location = null,
probationAreaId = conflictManager.probationAreaId,
team = conflictManager.team,
staff = conflictManager.staff
)
)
}

fun EntityManager.saveAll(vararg any: Any) = any.forEach { persist(it) }
Expand All @@ -89,17 +109,19 @@ class DataLoader(
date,
start,
start.plusMinutes(30),
if (start.minute == 30) AppointmentGenerator.DEFAULT_LOCATION else null,
ProviderGenerator.DEFAULT_STAFF,
if (start.isAfter(ZonedDateTime.now())) {
null
} else {
AppointmentGenerator.ATTENDED_OUTCOME
},
if (start.minute == 0) {
probationAreaId = ProviderGenerator.DEFAULT_AREA.id,
team = ProviderGenerator.DEFAULT_TEAM,
staff = ProviderGenerator.DEFAULT_STAFF,
location = if (start.minute == 30) AppointmentGenerator.DEFAULT_LOCATION else null,
description = if (start.minute == 0) {
"On the hour"
} else {
null
},
outcome = if (start.isAfter(ZonedDateTime.now())) {
null
} else {
AppointmentGenerator.ATTENDED_OUTCOME
}
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
package uk.gov.justice.digital.hmpps.data.generator

import uk.gov.justice.digital.hmpps.entity.Appointment
import uk.gov.justice.digital.hmpps.entity.AppointmentOutcome
import uk.gov.justice.digital.hmpps.entity.AppointmentType
import uk.gov.justice.digital.hmpps.entity.Location
import uk.gov.justice.digital.hmpps.entity.Person
import uk.gov.justice.digital.hmpps.entity.Staff
import uk.gov.justice.digital.hmpps.api.model.CreateAppointment
import uk.gov.justice.digital.hmpps.entity.*
import java.time.LocalDate
import java.time.ZonedDateTime

Expand All @@ -21,6 +17,7 @@ object AppointmentGenerator {
townCity = "Heath",
postcode = "H34 7TH"
)
val APPOINTMENT_TYPES = CreateAppointment.Type.entries.map { generateType(it.code, attendanceType = true) }

fun generateType(
code: String,
Expand Down Expand Up @@ -67,11 +64,33 @@ object AppointmentGenerator {
date: LocalDate,
startTime: ZonedDateTime,
endTime: ZonedDateTime?,
externalReference: String? = null,
location: Location?,
notes: String? = null,
probationAreaId: Long,
team: Team,
staff: Staff,
outcome: AppointmentOutcome? = null,
description: String? = null,
softDeleted: Boolean = false,
version: Long = 0,
id: Long = IdGenerator.getAndIncrement()
) = Appointment(person, type, date, startTime, endTime, location, staff, description, outcome, softDeleted, id)
) = Appointment(
person,
type,
date,
startTime,
endTime,
notes,
probationAreaId,
team,
staff,
externalReference,
description,
location,
outcome,
softDeleted,
version,
id
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ package uk.gov.justice.digital.hmpps.data.generator
import uk.gov.justice.digital.hmpps.entity.Person
import uk.gov.justice.digital.hmpps.entity.PersonManager
import uk.gov.justice.digital.hmpps.entity.Staff
import uk.gov.justice.digital.hmpps.entity.Team

object PersonGenerator {
val DEFAULT = generate("X123123", "A1234YZ")
val DEFAULT_MANAGER = generateManager(staff = ProviderGenerator.DEFAULT_STAFF)
val DEFAULT_MANAGER = generateManager(DEFAULT)
val CREATE_APPOINTMENT = generate("C123456")

fun generate(
crn: String,
Expand All @@ -22,10 +24,12 @@ object PersonGenerator {
)

fun generateManager(
person: Person = PersonGenerator.DEFAULT,
staff: Staff,
person: Person,
team: Team = ProviderGenerator.DEFAULT_TEAM,
staff: Staff = ProviderGenerator.DEFAULT_STAFF,
probationAreaId: Long = ProviderGenerator.DEFAULT_AREA.id,
active: Boolean = true,
softDeleted: Boolean = false,
id: Long = IdGenerator.getAndIncrement()
) = PersonManager(person, staff, softDeleted, active, id)
) = PersonManager(person, team, staff, probationAreaId, softDeleted, active, id)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package uk.gov.justice.digital.hmpps

import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.equalTo
import org.junit.jupiter.api.Assertions.assertNotNull
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.data.domain.PageRequest
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
import org.springframework.test.web.servlet.result.MockMvcResultMatchers
import uk.gov.justice.digital.hmpps.api.model.CreateAppointment
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator
import uk.gov.justice.digital.hmpps.entity.AlertRepository
import uk.gov.justice.digital.hmpps.entity.AppointmentRepository
import uk.gov.justice.digital.hmpps.test.CustomMatchers.isCloseTo
import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withJson
import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withToken
import java.time.ZonedDateTime

@AutoConfigureMockMvc
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
internal class CreateAppointmentIntTests {
@Autowired
internal lateinit var mockMvc: MockMvc

@Autowired
internal lateinit var appointmentRepository: AppointmentRepository

@Autowired
internal lateinit var alertRepository: AlertRepository

@Test
fun `create appointment when offender does not exist retuns a 404 response`() {
mockMvc.perform(
post("/appointments/D123456")
.withToken()
.withJson(
CreateAppointment(
CreateAppointment.Type.Accommodation,
ZonedDateTime.now().plusDays(1),
ZonedDateTime.now().plusDays(1)
)
)
).andExpect(MockMvcResultMatchers.status().isNotFound)
}

@Test
fun `create appointment retuns a 409 when conflicting appointment`() {
val start = ZonedDateTime.now().plusDays(7).plusMinutes(10)
mockMvc.perform(
post("/appointments/${PersonGenerator.CREATE_APPOINTMENT.crn}")
.withToken()
.withJson(
CreateAppointment(CreateAppointment.Type.Health, start, start.plusMinutes(30))
)
).andExpect(MockMvcResultMatchers.status().isConflict)
}

@Test
fun `create appointment ending before start returns bad request`() {
val start = ZonedDateTime.now().plusDays(7).plusMinutes(10)
mockMvc.perform(
post("/appointments/${PersonGenerator.CREATE_APPOINTMENT.crn}")
.withToken()
.withJson(
CreateAppointment(CreateAppointment.Type.Finance, start, start.minusSeconds(1))
)
).andExpect(MockMvcResultMatchers.status().isBadRequest)
}

@Test
fun `create a new appointment`() {
val person = PersonGenerator.CREATE_APPOINTMENT
val start = ZonedDateTime.now().plusDays(1)
val notes = "Resettlement Passport Notes"
val create = CreateAppointment(CreateAppointment.Type.SkillsAndWork, start, start.plusHours(1), notes)

mockMvc.perform(
post("/appointments/${person.crn}")
.withToken()
.withJson(create)
).andExpect(MockMvcResultMatchers.status().isCreated)

val appointment = appointmentRepository.findAppointmentsFor(
person.crn,
start.toLocalDate(),
start.toLocalDate(),
PageRequest.of(0, 1)
).first()

assertThat(appointment.type.code, equalTo(create.type.code))
assertThat(appointment.date, equalTo(start.toLocalDate()))
assertThat(appointment.startTime, isCloseTo(start))
assertThat(appointment.notes, equalTo(notes))
assertThat(appointment.externalReference, equalTo(create.urn))

val alert = alertRepository.findAll().firstOrNull { it.contactId == appointment.id }
assertNotNull(alert)
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package uk.gov.justice.digital.hmpps.api.controller

import org.springframework.data.domain.PageRequest
import org.springframework.http.HttpStatus
import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.bind.annotation.*
import uk.gov.justice.digital.hmpps.api.model.Appointment
import uk.gov.justice.digital.hmpps.api.model.CreateAppointment
import uk.gov.justice.digital.hmpps.service.AppointmentService
import java.time.LocalDate

Expand All @@ -26,6 +24,12 @@ class AppointmentController(private val appointmentService: AppointmentService)
appointmentService.findAppointmentsFor(crn, startDate, endDate, PageRequest.of(page, size)).let {
ResultSet(it.content, it.totalElements, it.totalPages, page, size)
}

@PreAuthorize("hasRole('PROBATION_API__RESETTLEMENT_PASSPORT__APPOINTMENT_RW')")
@PostMapping("/{crn}")
@ResponseStatus(HttpStatus.CREATED)
fun createAppointment(@PathVariable crn: String, @RequestBody createAppointment: CreateAppointment) =
appointmentService.createAppointment(crn, createAppointment)
}

data class ResultSet<T>(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package uk.gov.justice.digital.hmpps.api.model

import java.time.ZonedDateTime
import java.util.*

data class CreateAppointment(
val type: Type,
val start: ZonedDateTime,
val end: ZonedDateTime,
val notes: String? = null,
val uuid: UUID = UUID.randomUUID()
) {
val urn = URN_PREFIX + uuid

enum class Type(val code: String) {
Accommodation("RP1"),
ThinkingAndBehaviour("RP2"),
FamilyAndCommunity("RP3"),
DrugsAndAlcohol("RP4"),
SkillsAndWork("RP5"),
Finance("RP6"),
Health("RP7"),
Benefits("RP8")
}

companion object {
const val URN_PREFIX = "urn:uk:gov:hmpps:resettlement-passport-service:appointment:"
}
}
Loading

0 comments on commit 22bd573

Please sign in to comment.