Skip to content

Commit

Permalink
PI-1467 add new endpoints (#2288)
Browse files Browse the repository at this point in the history
* PI-1467 add new endpoints
  • Loading branch information
anthony-britton-moj authored Sep 18, 2023
1 parent e842738 commit 3aae02a
Show file tree
Hide file tree
Showing 12 changed files with 489 additions and 3 deletions.
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

0 comments on commit 3aae02a

Please sign in to comment.