Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PI-1467 add new endpoints #2288

Merged
merged 2 commits into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ 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.datetime.EuropeLondon
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
Expand Down Expand Up @@ -48,14 +51,27 @@ class DataLoader(
ProviderGenerator.DEFAULT_STAFF,
ProviderGenerator.DEFAULT_STAFF_USER,
PersonGenerator.DEFAULT,
PersonGenerator.DEFAULT_MANAGER,
NSIGenerator.DEFAULT,
NSIManagerGenerator.DEFAULT,
AddressGenerator.DEFAULT,
AppointmentGenerator.ATTENDANCE_TYPE,
AppointmentGenerator.NON_ATTENDANCE_TYPE,
AppointmentGenerator.ATTENDED_OUTCOME,
AppointmentGenerator.NON_ATTENDED_OUTCOME,
AppointmentGenerator.DEFAULT_LOCATION
AppointmentGenerator.DEFAULT_LOCATION,
RegistrationGenerator.MAPPA_TYPE
)

RegistrationGenerator.CATEGORIES.values.forEach { em.persist(it) }
RegistrationGenerator.LEVELS.values.forEach { em.persist(it) }
em.persist(
RegistrationGenerator.generate(
date = LocalDate.now().minusDays(30),
category = RegistrationGenerator.CATEGORIES[Category.M1.name],
level = RegistrationGenerator.LEVELS[Level.M2.name],
reviewDate = LocalDate.now().plusDays(60)
)
)

createAppointments(PersonGenerator.DEFAULT)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,31 @@
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

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

fun generate(crn: String, noms: String? = null, softDeleted: Boolean = false, id: Long = IdGenerator.getAndIncrement()) =
fun generate(
crn: String,
noms: String? = null,
softDeleted: Boolean = false,
id: Long = IdGenerator.getAndIncrement()
) =
Person(
id,
crn,
noms,
softDeleted
)

fun generateManager(
person: Person = PersonGenerator.DEFAULT,
staff: Staff,
active: Boolean = true,
softDeleted: Boolean = false,
id: Long = IdGenerator.getAndIncrement()
) = PersonManager(person, staff, softDeleted, active, id)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package uk.gov.justice.digital.hmpps.data.generator

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.entity.ReferenceData
import uk.gov.justice.digital.hmpps.entity.RegisterType
import uk.gov.justice.digital.hmpps.entity.Registration
import java.time.LocalDate

object RegistrationGenerator {
val MAPPA_TYPE = generateType("MAPP")
val CATEGORIES = Category.entries.map { ReferenceDataGenerator.generate(it.name) }.associateBy { it.code }
val LEVELS = Level.entries.map { ReferenceDataGenerator.generate(it.name) }.associateBy { it.code }

fun generateType(code: String, id: Long = IdGenerator.getAndIncrement()) = RegisterType(id, code)

fun generate(
type: RegisterType = MAPPA_TYPE,
category: ReferenceData? = null,
level: ReferenceData? = null,
date: LocalDate = LocalDate.now(),
reviewDate: LocalDate? = null,
person: Person = PersonGenerator.DEFAULT,
deRegistered: Boolean = false,
softDeleted: Boolean = false,
id: Long = IdGenerator.getAndIncrement()
) = Registration(person, type, category, level, date, reviewDate, deRegistered, softDeleted, id)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package uk.gov.justice.digital.hmpps

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import com.github.tomakehurst.wiremock.WireMockServer
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.equalTo
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
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.result.MockMvcResultMatchers
import uk.gov.justice.digital.hmpps.api.model.CaseIdentifiers
import uk.gov.justice.digital.hmpps.api.model.Manager
import uk.gov.justice.digital.hmpps.api.model.MappaDetail
import uk.gov.justice.digital.hmpps.api.model.Name
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator
import uk.gov.justice.digital.hmpps.data.generator.ProviderGenerator
import uk.gov.justice.digital.hmpps.security.withOAuth2Token
import java.time.LocalDate

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

@Autowired
lateinit var wireMockServer: WireMockServer

@Autowired
lateinit var objectMapper: ObjectMapper

@Test
fun `crn is correctly returned when noms id present in delius`() {
val result = mockMvc.perform(
MockMvcRequestBuilders.get("/probation-cases/${PersonGenerator.DEFAULT.noms}/crn")
.withOAuth2Token(wireMockServer)
).andExpect(MockMvcResultMatchers.status().is2xxSuccessful).andReturn().response

val identifiers = objectMapper.readValue<CaseIdentifiers>(result.contentAsString)
assertThat(identifiers.crn, equalTo(PersonGenerator.DEFAULT.crn))
}

@Test
fun `not found returned when noms id not present in delius`() {
mockMvc.perform(
MockMvcRequestBuilders.get("/probation-cases/N4567FD/crn")
.withOAuth2Token(wireMockServer)
).andExpect(MockMvcResultMatchers.status().isNotFound)
}

@Test
fun `mappa detail is returned when available`() {
val result = mockMvc.perform(
MockMvcRequestBuilders.get("/probation-cases/${PersonGenerator.DEFAULT.crn}/mappa")
.withOAuth2Token(wireMockServer)
).andExpect(MockMvcResultMatchers.status().is2xxSuccessful).andReturn().response

val mappa = objectMapper.readValue<MappaDetail>(result.contentAsString)
assertThat(mappa.category, equalTo(1))
assertThat(mappa.level, equalTo(2))
assertThat(mappa.startDate, equalTo(LocalDate.now().minusDays(30)))
assertThat(mappa.reviewDate, equalTo(LocalDate.now().plusDays(60)))
}

@Test
fun `community manager is returned`() {
val result = mockMvc.perform(
MockMvcRequestBuilders.get("/probation-cases/${PersonGenerator.DEFAULT.crn}/community-manager")
.withOAuth2Token(wireMockServer)
).andExpect(MockMvcResultMatchers.status().is2xxSuccessful).andReturn().response

val manager = objectMapper.readValue<Manager>(result.contentAsString)
assertThat(
manager.name,
equalTo(Name(ProviderGenerator.DEFAULT_STAFF.forename, ProviderGenerator.DEFAULT_STAFF.surname))
)
assertFalse(manager.unallocated)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package uk.gov.justice.digital.hmpps.api.controller

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.RestController
import uk.gov.justice.digital.hmpps.api.model.CaseIdentifiers
import uk.gov.justice.digital.hmpps.api.model.MappaDetail
import uk.gov.justice.digital.hmpps.service.CaseDetailService

@RestController
@RequestMapping("/probation-cases")
class CaseDetailController(private val caseDetailService: CaseDetailService) {

@PreAuthorize("hasRole('RESETTLEMENT_PASSPORT_SUPERVISION_ACCESS')")
@GetMapping("/{nomsId}/crn")
fun findCrn(@PathVariable nomsId: String): CaseIdentifiers = caseDetailService.findCrnByNomsId(nomsId)

@PreAuthorize("hasRole('RESETTLEMENT_PASSPORT_SUPERVISION_ACCESS')")
@GetMapping("/{crn}/mappa")
fun findMappaInfo(@PathVariable crn: String): MappaDetail = caseDetailService.findMappaDetail(crn)

@PreAuthorize("hasRole('RESETTLEMENT_PASSPORT_SUPERVISION_ACCESS')")
@GetMapping("/{crn}/community-manager")
fun getCommunityManager(@PathVariable crn: String) = caseDetailService.findCommunityManager(crn)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package uk.gov.justice.digital.hmpps.api.model

import java.time.LocalDate

data class CaseIdentifiers(
val crn: String
)

data class MappaDetail(
val level: Int?,
val levelDescription: String?,
val category: Int?,
val categoryDescription: String?,
val startDate: LocalDate,
val reviewDate: LocalDate?
)

data class Manager(
val name: Name?,
val unallocated: Boolean
)
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package uk.gov.justice.digital.hmpps.entity

import jakarta.persistence.Column
import jakarta.persistence.Convert
import jakarta.persistence.Entity
Expand Down Expand Up @@ -72,3 +73,8 @@ interface PersonAddressRepository : JpaRepository<PersonAddress, Long> {
)
fun getMainAddressByPersonId(personId: Long): PersonAddress?
}

interface PersonRepository : JpaRepository<Person, Long> {
@Query("select p.crn from Person p where p.noms = :nomsId")
fun findCrnByNomsId(nomsId: String): String?
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package uk.gov.justice.digital.hmpps.entity

import jakarta.persistence.Column
import jakarta.persistence.Entity
import jakarta.persistence.Id
import jakarta.persistence.JoinColumn
import jakarta.persistence.ManyToOne
import jakarta.persistence.Table
import org.hibernate.annotations.Immutable
import org.hibernate.annotations.Where
import org.springframework.data.jpa.repository.JpaRepository

@Immutable
@Table(name = "offender_manager")
@Entity
@Where(clause = "soft_deleted = 0 and active_flag = 1")
class PersonManager(

@ManyToOne
@JoinColumn(name = "offender_id")
val person: Person,

@ManyToOne
@JoinColumn(name = "allocation_staff_id")
val staff: Staff,

@Column(name = "soft_deleted", columnDefinition = "number")
val softDeleted: Boolean,

@Column(name = "active_flag", columnDefinition = "number")
val active: Boolean,

@Id
@Column(name = "offender_manager_id")
val id: Long
)

interface PersonManagerRepository : JpaRepository<PersonManager, Long> {
fun findByPersonCrn(crn: String): PersonManager?
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ class ReferenceData(
@Column(name = "standard_reference_list_id")
val id: Long
)

enum class Category(val number: Int) { X9(0), M1(1), M2(2), M3(3), M4(4) }
enum class Level(val number: Int) { M0(0), M1(1), M2(2), M3(3) }
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package uk.gov.justice.digital.hmpps.entity

import jakarta.persistence.Column
import jakarta.persistence.Entity
import jakarta.persistence.Id
import jakarta.persistence.JoinColumn
import jakarta.persistence.ManyToOne
import jakarta.persistence.Table
import org.hibernate.annotations.Immutable
import org.hibernate.annotations.Where
import org.springframework.data.jpa.repository.EntityGraph
import org.springframework.data.jpa.repository.JpaRepository
import java.time.LocalDate

@Immutable
@Entity
@Where(clause = "soft_deleted = 0 and deregistered = 0")
@Table(name = "registration")
class Registration(

@ManyToOne
@JoinColumn(name = "offender_id")
val person: Person,

@ManyToOne
@JoinColumn(name = "register_type_id")
val type: RegisterType,

@ManyToOne
@JoinColumn(name = "register_category_id")
val category: ReferenceData?,

@ManyToOne
@JoinColumn(name = "register_level_id")
val level: ReferenceData?,

@Column(name = "registration_date")
val date: LocalDate,

@Column(name = "next_review_date")
val reviewDate: LocalDate?,

@Column(name = "deregistered", columnDefinition = "number")
val deRegistered: Boolean,

@Column(name = "soft_deleted", columnDefinition = "number")
val softDeleted: Boolean,

@Id
@Column(name = "registration_id")
val id: Long
)

@Entity
@Immutable
@Table(name = "r_register_type")
class RegisterType(

@Id
@Column(name = "register_type_id")
val id: Long,

val code: String
) {
companion object {
const val MAPPA_CODE = "MAPP"
}
}

interface RegistrationRepository : JpaRepository<Registration, Long> {

@EntityGraph(attributePaths = ["type", "category", "level"])
fun findFirstByPersonCrnAndTypeCodeOrderByDateDesc(crn: String, typeCode: String): Registration?
}

fun RegistrationRepository.findMappa(crn: String) =
findFirstByPersonCrnAndTypeCodeOrderByDateDesc(crn, RegisterType.MAPPA_CODE)
Loading