From 8ed2720853367a9ef182284fbd25c4aba939880a Mon Sep 17 00:00:00 2001 From: Muhammad El Abdulla <> Date: Fri, 20 Dec 2024 11:00:39 +0000 Subject: [PATCH] Add system notes to rejection referral seed job --- .../seed/cas3/Cas3ReferralRejectionSeedJob.kt | 35 +++++++- .../cas3/Cas3ReferralRejectionSeedJobTest.kt | 5 +- .../cas3/Cas3ReferralRejectionSeedJobTest.kt | 81 +++++++++++++------ 3 files changed, 90 insertions(+), 31 deletions(-) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/seed/cas3/Cas3ReferralRejectionSeedJob.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/seed/cas3/Cas3ReferralRejectionSeedJob.kt index 5b30dec090..4beaae4391 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/seed/cas3/Cas3ReferralRejectionSeedJob.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/seed/cas3/Cas3ReferralRejectionSeedJob.kt @@ -5,9 +5,15 @@ import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Component import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ServiceName import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.AssessmentDecision +import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.AssessmentEntity +import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.AssessmentReferralHistoryNoteRepository +import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.AssessmentReferralHistorySystemNoteEntity import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.AssessmentRepository +import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.ReferralHistorySystemNoteType import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.ReferralRejectionReasonRepository import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.TemporaryAccommodationAssessmentEntity +import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.UserEntity +import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.UserRepository import uk.gov.justice.digital.hmpps.approvedpremisesapi.seed.SeedJob import java.time.OffsetDateTime import java.util.UUID @@ -16,12 +22,15 @@ import java.util.UUID class Cas3ReferralRejectionSeedJob( private val assessmentRepository: AssessmentRepository, private val referralRejectionReasonRepository: ReferralRejectionReasonRepository, + private val assessmentReferralHistoryNoteRepository: AssessmentReferralHistoryNoteRepository, + private val userRepository: UserRepository, ) : SeedJob( requiredHeaders = setOf( "assessment_id", "rejection_reason", "rejection_reason_detail", "is_withdrawn", + "delius_username", ), runInTransaction = false, ) { @@ -32,6 +41,7 @@ class Cas3ReferralRejectionSeedJob( rejectionReason = columns["rejection_reason"]!!.trim(), rejectionReasonDetail = columns["rejection_reason_detail"]!!.trim(), isWithdrawn = columns["is_withdrawn"]!!.trim().equals("true", ignoreCase = true), + deliusUsername = columns["delius_username"]!!.trim(), ) override fun processRow(row: Cas3ReferralRejectionSeedCsvRow) { @@ -40,6 +50,8 @@ class Cas3ReferralRejectionSeedJob( @SuppressWarnings("TooGenericExceptionCaught") private fun rejectAssessment(row: Cas3ReferralRejectionSeedCsvRow) { + val userRequest = userRepository.findByDeliusUsername(row.deliusUsername.uppercase()) ?: error("User with delius username ${row.deliusUsername} not found") + val assessment = assessmentRepository.findByIdOrNull(row.assessmentId) ?: error("Assessment with id ${row.assessmentId} not found") @@ -48,8 +60,10 @@ class Cas3ReferralRejectionSeedJob( } if (assessment is TemporaryAccommodationAssessmentEntity) { - val rejectionReason = referralRejectionReasonRepository.findByNameAndActive(row.rejectionReason, ServiceName.temporaryAccommodation.value) - ?: error("Rejection reason ${row.rejectionReason} not found") + val rejectionReason = referralRejectionReasonRepository.findByNameAndActive( + row.rejectionReason, + ServiceName.temporaryAccommodation.value, + ) ?: error("Rejection reason ${row.rejectionReason} not found") try { assessment.submittedAt = OffsetDateTime.now() @@ -59,7 +73,8 @@ class Cas3ReferralRejectionSeedJob( assessment.referralRejectionReasonDetail = row.rejectionReasonDetail assessment.isWithdrawn = row.isWithdrawn - assessmentRepository.save(assessment) + val savedAssessment = assessmentRepository.save(assessment) + savedAssessment.addSystemNote(userRequest, ReferralHistorySystemNoteType.REJECTED) } catch (e: Throwable) { log.error("Failed to update assessment with id ${row.assessmentId}", e) error("Failed to update assessment with id ${row.assessmentId}") @@ -70,6 +85,19 @@ class Cas3ReferralRejectionSeedJob( error("Assessment with id ${row.assessmentId} is not a temporary accommodation assessment") } } + + fun AssessmentEntity.addSystemNote(user: UserEntity, type: ReferralHistorySystemNoteType) { + this.referralHistoryNotes += assessmentReferralHistoryNoteRepository.save( + AssessmentReferralHistorySystemNoteEntity( + id = UUID.randomUUID(), + assessment = this, + createdAt = OffsetDateTime.now(), + message = "", + createdByUser = user, + type = type, + ), + ) + } } data class Cas3ReferralRejectionSeedCsvRow( @@ -77,4 +105,5 @@ data class Cas3ReferralRejectionSeedCsvRow( val rejectionReason: String, val rejectionReasonDetail: String?, val isWithdrawn: Boolean, + val deliusUsername: String, ) diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/seed/cas3/Cas3ReferralRejectionSeedJobTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/seed/cas3/Cas3ReferralRejectionSeedJobTest.kt index 81661f4c0c..a326d808a6 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/seed/cas3/Cas3ReferralRejectionSeedJobTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/seed/cas3/Cas3ReferralRejectionSeedJobTest.kt @@ -43,7 +43,7 @@ class Cas3ReferralRejectionSeedJobTest : SeedTestBase() { withCsv( "cas3-referral-rejection-csv", - rowsToCsv(listOf(Cas3ReferralRejectionSeedCsvRow(assessment.id, rejectedReason, rejectedReasonDetail, false))), + rowsToCsv(listOf(Cas3ReferralRejectionSeedCsvRow(assessment.id, rejectedReason, rejectedReasonDetail, false, user.deliusUsername))), ) seedService.seedData(SeedFileType.temporaryAccommodationReferralRejection, "cas3-referral-rejection-csv.csv") @@ -64,12 +64,13 @@ class Cas3ReferralRejectionSeedJobTest : SeedTestBase() { "rejection_reason", "rejection_reason_detail", "is_withdrawn", + "delius_username", ) .newRow() rows.forEach { builder - .withQuotedFields(it.assessmentId, it.rejectionReason, it.rejectionReasonDetail!!, it.isWithdrawn) + .withQuotedFields(it.assessmentId, it.rejectionReason, it.rejectionReasonDetail!!, it.isWithdrawn, it.deliusUsername) .newRow() } diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/unit/seed/cas3/Cas3ReferralRejectionSeedJobTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/unit/seed/cas3/Cas3ReferralRejectionSeedJobTest.kt index dba09cd5c1..afd08d6843 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/unit/seed/cas3/Cas3ReferralRejectionSeedJobTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/unit/seed/cas3/Cas3ReferralRejectionSeedJobTest.kt @@ -8,11 +8,15 @@ import org.springframework.data.repository.findByIdOrNull import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ServiceName import uk.gov.justice.digital.hmpps.approvedpremisesapi.factory.ApprovedPremisesApplicationEntityFactory import uk.gov.justice.digital.hmpps.approvedpremisesapi.factory.ApprovedPremisesAssessmentEntityFactory +import uk.gov.justice.digital.hmpps.approvedpremisesapi.factory.ProbationRegionEntityFactory import uk.gov.justice.digital.hmpps.approvedpremisesapi.factory.TemporaryAccommodationApplicationEntityFactory import uk.gov.justice.digital.hmpps.approvedpremisesapi.factory.TemporaryAccommodationAssessmentEntityFactory +import uk.gov.justice.digital.hmpps.approvedpremisesapi.factory.UserEntityFactory +import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.AssessmentReferralHistoryNoteRepository import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.AssessmentRepository import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.ReferralRejectionReasonEntity import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.ReferralRejectionReasonRepository +import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.UserRepository import uk.gov.justice.digital.hmpps.approvedpremisesapi.seed.cas3.Cas3ReferralRejectionSeedCsvRow import uk.gov.justice.digital.hmpps.approvedpremisesapi.seed.cas3.Cas3ReferralRejectionSeedJob import uk.gov.justice.digital.hmpps.approvedpremisesapi.util.randomStringLowerCase @@ -20,19 +24,42 @@ import java.time.OffsetDateTime import java.util.UUID class Cas3ReferralRejectionSeedJobTest { - private val assessmentRepository = mockk() - private val referralRejectionReasonRepository = mockk() + private val mockAssessmentRepository = mockk() + private val mockReferralRejectionReasonRepository = mockk() + private val mockAssertAssessmentHasSystemNoteRepository = mockk() + private val mockUserRepository = mockk() + + private val assessmentId = UUID.randomUUID() + private val deliusUsername = randomStringLowerCase(20).uppercase() + + private val userEntity = UserEntityFactory() + .withYieldedProbationRegion { + ProbationRegionEntityFactory() + .produce() + } + .produce() private val seedJob = Cas3ReferralRejectionSeedJob( - assessmentRepository = assessmentRepository, - referralRejectionReasonRepository = referralRejectionReasonRepository, + assessmentRepository = mockAssessmentRepository, + referralRejectionReasonRepository = mockReferralRejectionReasonRepository, + assessmentReferralHistoryNoteRepository = mockAssertAssessmentHasSystemNoteRepository, + userRepository = mockUserRepository, ) @Test - fun `When the assessment is not Temporary Accommodation assessment expect error`() { - val assessmentId = UUID.randomUUID() + fun `When the user doesn't exist expect an error`() { + every { mockUserRepository.findByDeliusUsername(deliusUsername) } returns null + + assertThatThrownBy { + seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, "rejection reason", null, false, deliusUsername)) + }.hasMessage("User with delius username $deliusUsername not found") + } + + @Test + fun `When the assessment is not Temporary Accommodation assessment expect an error`() { + every { mockUserRepository.findByDeliusUsername(deliusUsername) } returns userEntity - every { assessmentRepository.findByIdOrNull(assessmentId) } returns + every { mockAssessmentRepository.findByIdOrNull(assessmentId) } returns ApprovedPremisesAssessmentEntityFactory() .withApplication( ApprovedPremisesApplicationEntityFactory() @@ -42,26 +69,26 @@ class Cas3ReferralRejectionSeedJobTest { .produce() assertThatThrownBy { - seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, "rejection reason", null, false)) + seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, "rejection reason", null, false, deliusUsername)) }.hasMessage("Assessment with id $assessmentId is not a temporary accommodation assessment") } @Test - fun `When an assessment doesn't exist expect error`() { - val assessmentId = UUID.randomUUID() + fun `When an assessment doesn't exist expect an error`() { + every { mockUserRepository.findByDeliusUsername(deliusUsername) } returns userEntity - every { assessmentRepository.findByIdOrNull(assessmentId) } returns null + every { mockAssessmentRepository.findByIdOrNull(assessmentId) } returns null assertThatThrownBy { - seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, "rejection reason", randomStringLowerCase(20), false)) + seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, "rejection reason", randomStringLowerCase(20), false, deliusUsername)) }.hasMessage("Assessment with id $assessmentId not found") } @Test - fun `When the application has been allocated expect error`() { - val assessmentId = UUID.randomUUID() + fun `When the application has been allocated expect an error`() { + every { mockUserRepository.findByDeliusUsername(deliusUsername) } returns userEntity - every { assessmentRepository.findByIdOrNull(assessmentId) } returns + every { mockAssessmentRepository.findByIdOrNull(assessmentId) } returns TemporaryAccommodationAssessmentEntityFactory() .withApplication( TemporaryAccommodationApplicationEntityFactory() @@ -72,16 +99,17 @@ class Cas3ReferralRejectionSeedJobTest { .produce() assertThatThrownBy { - seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, "rejection reason", null, false)) + seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, "rejection reason", null, false, deliusUsername)) }.hasMessage("The application has been reallocated, this assessment is read only") } @Test - fun `When the rejection reason doesn't exist expect error`() { - val assessmentId = UUID.randomUUID() + fun `When the rejection reason doesn't exist expect an error`() { val notExistRejectionReason = "not exist rejection reason" - every { assessmentRepository.findByIdOrNull(assessmentId) } returns + every { mockUserRepository.findByDeliusUsername(deliusUsername) } returns userEntity + + every { mockAssessmentRepository.findByIdOrNull(assessmentId) } returns TemporaryAccommodationAssessmentEntityFactory() .withApplication( TemporaryAccommodationApplicationEntityFactory() @@ -90,16 +118,15 @@ class Cas3ReferralRejectionSeedJobTest { ) .produce() - every { referralRejectionReasonRepository.findByNameAndActive(notExistRejectionReason, ServiceName.temporaryAccommodation.value) } returns null + every { mockReferralRejectionReasonRepository.findByNameAndActive(notExistRejectionReason, ServiceName.temporaryAccommodation.value) } returns null assertThatThrownBy { - seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, notExistRejectionReason, null, false)) + seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, notExistRejectionReason, null, false, deliusUsername)) }.hasMessage("Rejection reason $notExistRejectionReason not found") } @Test fun `When save an assessment and an exception happened expect logging error`() { - val assessmentId = UUID.randomUUID() val assessment = TemporaryAccommodationAssessmentEntityFactory() .withApplication( TemporaryAccommodationApplicationEntityFactory() @@ -108,15 +135,17 @@ class Cas3ReferralRejectionSeedJobTest { ) .produce() - every { assessmentRepository.findByIdOrNull(assessmentId) } returns assessment + every { mockUserRepository.findByDeliusUsername(deliusUsername) } returns userEntity + + every { mockAssessmentRepository.findByIdOrNull(assessmentId) } returns assessment - every { referralRejectionReasonRepository.findByNameAndActive("rejection reason", ServiceName.temporaryAccommodation.value) } returns + every { mockReferralRejectionReasonRepository.findByNameAndActive("rejection reason", ServiceName.temporaryAccommodation.value) } returns ReferralRejectionReasonEntity(UUID.randomUUID(), "rejection reason", true, ServiceName.temporaryAccommodation.value, 1) - every { assessmentRepository.save(any()) } throws RuntimeException("Failed to update assessment with id $assessmentId") + every { mockAssessmentRepository.save(any()) } throws RuntimeException("Failed to update assessment with id $assessmentId") assertThatThrownBy { - seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, "rejection reason", null, false)) + seedJob.processRow(Cas3ReferralRejectionSeedCsvRow(assessmentId, "rejection reason", null, false, deliusUsername)) }.hasMessage("Failed to update assessment with id $assessmentId") } }