From e1d5e41c3fe0825642f5cb3f115e2bb6121ba698 Mon Sep 17 00:00:00 2001 From: stevomcallister Date: Tue, 10 Oct 2023 14:50:01 +0100 Subject: [PATCH] PI-1554 added get staff by username endpoint --- .../justice/digital/hmpps/data/DataLoader.kt | 9 +++++++- .../hmpps/data/generator/StaffGenerator.kt | 11 ++++++++++ .../hmpps/StaffControllerIntegrationTest.kt | 12 ++++++++++ .../hmpps/controller/StaffController.kt | 11 ++++++++++ .../hmpps/integrations/delius/staff/Staff.kt | 22 +++++++++++++++++++ .../delius/staff/StaffRepository.kt | 4 ++++ .../digital/hmpps/model/StaffResponse.kt | 6 +++++ .../digital/hmpps/service/StaffService.kt | 20 ++++++++++++++++- 8 files changed, 93 insertions(+), 2 deletions(-) diff --git a/projects/approved-premises-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt b/projects/approved-premises-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt index ea042e4ffa..fda87f796d 100644 --- a/projects/approved-premises-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt +++ b/projects/approved-premises-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt @@ -49,6 +49,7 @@ import uk.gov.justice.digital.hmpps.integrations.delius.probationarea.ProbationA import uk.gov.justice.digital.hmpps.integrations.delius.referencedata.Dataset import uk.gov.justice.digital.hmpps.integrations.delius.referencedata.ReferenceDataRepository import uk.gov.justice.digital.hmpps.integrations.delius.staff.StaffRepository +import uk.gov.justice.digital.hmpps.integrations.delius.staff.StaffUser import uk.gov.justice.digital.hmpps.integrations.delius.team.TeamRepository import uk.gov.justice.digital.hmpps.user.AuditUserRepository import java.time.LocalDate @@ -81,7 +82,8 @@ class DataLoader( private val registrationRepository: RegistrationRepository, private val referralRepository: ReferralRepository, private val probationCaseDataLoader: ProbationCaseDataLoader, - private val lduRepository: LduRepository + private val lduRepository: LduRepository, + private val staffUserRepository: StaffUserRepository ) : ApplicationListener { @PostConstruct @@ -147,6 +149,9 @@ class DataLoader( ) ) + staffRepository.save(StaffGenerator.DEFAULT_STAFF) + staffUserRepository.save(StaffGenerator.DEFAULT_STAFF_USER) + val personManagerStaff = StaffGenerator.generate(code = "N54A001") staffRepository.save(personManagerStaff) val person = PersonGenerator.DEFAULT @@ -193,3 +198,5 @@ interface DatasetRepository : JpaRepository interface ProbationAreaRepository : JpaRepository interface AddressRepository : JpaRepository interface RegisterTypeRepository : JpaRepository + +interface StaffUserRepository : JpaRepository diff --git a/projects/approved-premises-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/StaffGenerator.kt b/projects/approved-premises-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/StaffGenerator.kt index e5e1db8713..401e23e6e5 100644 --- a/projects/approved-premises-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/StaffGenerator.kt +++ b/projects/approved-premises-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/StaffGenerator.kt @@ -3,11 +3,16 @@ package uk.gov.justice.digital.hmpps.data.generator import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator.STAFF_GRADE import uk.gov.justice.digital.hmpps.integrations.delius.approvedpremises.entity.ApprovedPremises import uk.gov.justice.digital.hmpps.integrations.delius.staff.Staff +import uk.gov.justice.digital.hmpps.integrations.delius.staff.StaffUser import uk.gov.justice.digital.hmpps.integrations.delius.team.Team +import uk.gov.justice.digital.hmpps.set import java.util.concurrent.atomic.AtomicLong object StaffGenerator { private val staffCodeGenerator = AtomicLong(1) + val DEFAULT_STAFF = generate() + + val DEFAULT_STAFF_USER = generateStaffUser("john-smith", DEFAULT_STAFF) fun generate( name: String = "TEST", @@ -24,4 +29,10 @@ object StaffGenerator { teams = teams, approvedPremises = approvedPremises ) + + fun generateStaffUser( + username: String, + staff: Staff? = null, + id: Long = IdGenerator.getAndIncrement() + ) = StaffUser(staff, username, id).apply { staff?.set("user", this) } } diff --git a/projects/approved-premises-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/StaffControllerIntegrationTest.kt b/projects/approved-premises-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/StaffControllerIntegrationTest.kt index 3e41dab082..4c2b1a933c 100644 --- a/projects/approved-premises-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/StaffControllerIntegrationTest.kt +++ b/projects/approved-premises-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/StaffControllerIntegrationTest.kt @@ -12,6 +12,7 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status import uk.gov.justice.digital.hmpps.data.generator.ApprovedPremisesGenerator +import uk.gov.justice.digital.hmpps.data.generator.StaffGenerator import uk.gov.justice.digital.hmpps.security.withOAuth2Token @AutoConfigureMockMvc @@ -60,4 +61,15 @@ class StaffControllerIntegrationTest { .andExpect(jsonPath("$.content[*].name.surname", equalTo(listOf("Key-worker")))) .andExpect(jsonPath("$.content[*].keyWorker", equalTo(listOf(true)))) } + + @Test + fun `Get staff by username`() { + val username = StaffGenerator.DEFAULT_STAFF.user!!.username + mockMvc.perform(get("/staff/$username").withOAuth2Token(wireMockServer)) + .andExpect(status().isOk) + .andExpect(jsonPath("$.username", equalTo(username))) + .andExpect(jsonPath("$.name.surname", equalTo(StaffGenerator.DEFAULT_STAFF.surname))) + .andExpect(jsonPath("$.name.forename", equalTo(StaffGenerator.DEFAULT_STAFF.forename))) + .andExpect(jsonPath("$.code", equalTo(StaffGenerator.DEFAULT_STAFF.code))) + } } diff --git a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/controller/StaffController.kt b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/controller/StaffController.kt index e9e2b64edb..549275b35c 100644 --- a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/controller/StaffController.kt +++ b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/controller/StaffController.kt @@ -31,4 +31,15 @@ class StaffController( @RequestParam(required = false, defaultValue = "false") keyWorker: Boolean, @PageableDefault(value = 100) pageable: Pageable = Pageable.ofSize(100) ) = staffService.getStaffInApprovedPremises(code, keyWorker, pageable) + + @PreAuthorize("hasRole('ROLE_APPROVED_PREMISES_STAFF')") + @Operation( + summary = "Get the staff name by username", + description = """Returns the Staff name associated with the given username. + """ + ) + @GetMapping(value = ["/staff/{userName}"]) + fun getStaffByUsername( + @PathVariable userName: String + ) = staffService.getStaffByUsername(userName) } diff --git a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/staff/Staff.kt b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/staff/Staff.kt index 3cf5ab8283..ff46576484 100644 --- a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/staff/Staff.kt +++ b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/staff/Staff.kt @@ -7,6 +7,8 @@ import jakarta.persistence.JoinColumn import jakarta.persistence.JoinTable import jakarta.persistence.ManyToMany import jakarta.persistence.ManyToOne +import jakarta.persistence.OneToOne +import jakarta.persistence.Table import org.hibernate.annotations.Immutable import uk.gov.justice.digital.hmpps.integrations.delius.approvedpremises.entity.ApprovedPremises import uk.gov.justice.digital.hmpps.integrations.delius.referencedata.ReferenceData @@ -35,6 +37,9 @@ class Staff( @Column val surname: String, + @OneToOne(mappedBy = "staff") + val user: StaffUser? = null, + @ManyToMany @JoinTable( name = "staff_team", @@ -51,3 +56,20 @@ class Staff( ) val approvedPremises: List ) + +@Entity +@Immutable +@Table(name = "user_") +class StaffUser( + + @OneToOne + @JoinColumn(name = "staff_id") + val staff: Staff? = null, + + @Column(name = "distinguished_name") + val username: String, + + @Id + @Column(name = "user_id") + val id: Long +) diff --git a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/staff/StaffRepository.kt b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/staff/StaffRepository.kt index 57fe823d0f..58b1247980 100644 --- a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/staff/StaffRepository.kt +++ b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/delius/staff/StaffRepository.kt @@ -2,6 +2,7 @@ package uk.gov.justice.digital.hmpps.integrations.delius.staff import org.springframework.data.domain.Page import org.springframework.data.domain.Pageable +import org.springframework.data.jpa.repository.EntityGraph import org.springframework.data.jpa.repository.JpaRepository import org.springframework.data.jpa.repository.Query import uk.gov.justice.digital.hmpps.exception.NotFoundException @@ -33,6 +34,9 @@ interface StaffRepository : JpaRepository { ): Page fun findByCode(code: String): Staff? + + @EntityGraph(attributePaths = ["user"]) + fun findByUserUsername(username: String): Staff? } fun StaffRepository.getByCode(code: String): Staff = diff --git a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/model/StaffResponse.kt b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/model/StaffResponse.kt index 5674bdfc8a..3130b97b1e 100644 --- a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/model/StaffResponse.kt +++ b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/model/StaffResponse.kt @@ -17,3 +17,9 @@ data class StaffGrade( val code: String, val description: String ) + +data class StaffDetail( + val username: String, + val name: PersonName, + val code: String, +) diff --git a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/StaffService.kt b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/StaffService.kt index 814971d832..35e614a22d 100644 --- a/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/StaffService.kt +++ b/projects/approved-premises-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/StaffService.kt @@ -9,6 +9,7 @@ import uk.gov.justice.digital.hmpps.integrations.delius.approvedpremises.Approve import uk.gov.justice.digital.hmpps.integrations.delius.staff.Staff import uk.gov.justice.digital.hmpps.integrations.delius.staff.StaffRepository import uk.gov.justice.digital.hmpps.model.PersonName +import uk.gov.justice.digital.hmpps.model.StaffDetail import uk.gov.justice.digital.hmpps.model.StaffGrade import uk.gov.justice.digital.hmpps.model.StaffResponse @@ -18,7 +19,11 @@ class StaffService( private val staffRepository: StaffRepository ) { @Transactional - fun getStaffInApprovedPremises(approvedPremisesCode: String, keyWorkersOnly: Boolean, pageable: Pageable): Page { + fun getStaffInApprovedPremises( + approvedPremisesCode: String, + keyWorkersOnly: Boolean, + pageable: Pageable + ): Page { if (!approvedPremisesRepository.existsByCodeCode(approvedPremisesCode)) { throw NotFoundException("Approved Premises", "code", approvedPremisesCode) } @@ -34,10 +39,23 @@ class StaffService( } } + fun getStaffByUsername(username: String) = + staffRepository.findByUserUsername(username)?.toStaffDetail() ?: throw NotFoundException( + "Staff", + "username", + username + ) + fun Staff.toResponse(approvedPremisesCode: String) = StaffResponse( code = code, name = PersonName(forename, surname, middleName), grade = grade?.let { grade -> StaffGrade(grade.code, grade.description) }, keyWorker = approvedPremises.map { ap -> ap.code.code }.contains(approvedPremisesCode) ) + + fun Staff.toStaffDetail() = StaffDetail( + user!!.username, + PersonName(forename, surname, middleName), + code + ) }