-
Notifications
You must be signed in to change notification settings - Fork 3
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
Cas2bail/main #2641
base: main
Are you sure you want to change the base?
Cas2bail/main #2641
Changes from all commits
c8de685
45474a5
0402efd
4291eef
387da56
6166492
0b40d88
f16a186
162c90d
3a2baaa
3ddd76b
a6964b1
c8d6247
e7c5f01
dc1abef
86ab963
4c784be
adacbf8
790d541
c11e561
c1afc7b
2048331
134b3a0
5f74c57
947158b
b1001e2
12d980c
06d1429
c5a64b0
459044e
4390bcf
d0691ea
dd232ae
cfc809a
50be8e3
b6b1b46
ee33a8e
64704fc
2c6b359
13e4eed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
package uk.gov.justice.digital.hmpps.approvedpremisesapi.controller.cas2bail | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper | ||
import jakarta.transaction.Transactional | ||
import org.springframework.http.ResponseEntity | ||
import org.springframework.stereotype.Service | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.cas2bail.ApplicationsCas2bailDelegate | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.Application | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.NewApplication | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.SortDirection | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.UpdateApplication | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.cas2bail.Cas2BailApplicationEntity | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.cas2bail.Cas2BailApplicationSummaryEntity | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.problem.BadRequestProblem | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.problem.ConflictProblem | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.problem.ForbiddenProblem | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.problem.NotFoundProblem | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.results.AuthorisableActionResult | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.results.ValidatableActionResult | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.NomisUserService | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.cas2.OffenderService | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.cas2bail.Cas2BailApplicationService | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.transformer.cas2bail.Cas2BailApplicationsTransformer | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.util.PageCriteria | ||
import java.net.URI | ||
import java.util.UUID | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.Cas2ApplicationSummary as ModelCas2ApplicationSummary | ||
|
||
@Service( | ||
"Cas2BailApplicationsController", | ||
) | ||
class Cas2BailApplicationController( | ||
private val cas2BailApplicationService: Cas2BailApplicationService, | ||
private val cas2BailApplicationsTransformer: Cas2BailApplicationsTransformer, | ||
private val objectMapper: ObjectMapper, | ||
private val offenderService: OffenderService, | ||
private val userService: NomisUserService, | ||
) : ApplicationsCas2bailDelegate { | ||
|
||
override fun applicationsGet( | ||
isSubmitted: Boolean?, | ||
page: Int?, | ||
prisonCode: String?, | ||
): ResponseEntity<List<ModelCas2ApplicationSummary>> { | ||
/*This gets a NomisUser. Toby and Gareth discussed creating a third user service | ||
* The third user service will return a Cas2BailUser. That user will have two nullable fields/properties | ||
* 1. DeliusUser | ||
* 2. NomisUser | ||
* We discussed using transformers if we need any specific data about the user eg their name. | ||
* | ||
* In the Cas2BailApplicationEntity the created_by field would be of type Cas2BailUser | ||
* */ | ||
val user = userService.getUserForRequest() | ||
|
||
prisonCode?.let { if (prisonCode != user.activeCaseloadId) throw ForbiddenProblem() } | ||
|
||
val pageCriteria = PageCriteria("createdAt", SortDirection.desc, page) | ||
|
||
val (applications, metadata) = cas2BailApplicationService.getCas2BailApplications(prisonCode, isSubmitted, user, pageCriteria) | ||
|
||
return ResponseEntity.ok().headers( | ||
metadata?.toHeaders(), | ||
).body(getPersonNamesAndTransformToSummaries(applications)) | ||
} | ||
|
||
override fun applicationsApplicationIdGet(applicationId: UUID): ResponseEntity<Application> { | ||
val user = userService.getUserForRequest() | ||
|
||
val application = when ( | ||
val applicationResult = cas2BailApplicationService | ||
.getCas2BailApplicationForUser( | ||
applicationId, | ||
user, | ||
) | ||
|
||
) { | ||
is AuthorisableActionResult.NotFound -> null | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think there's an open question as to whether we should be adding more use of deprecated code (in this case using AuthorisableActionResult instead of CasResult). I'm not sure what the answer is, i'll get back to you. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. my position is we shouldn't use deprecated code, and use the latest pattern we have. please can we do this? |
||
is AuthorisableActionResult.Unauthorised -> throw ForbiddenProblem() | ||
is AuthorisableActionResult.Success -> applicationResult.entity | ||
} | ||
|
||
if (application != null) { | ||
return ResponseEntity.ok(getPersonDetailAndTransform(application)) | ||
} | ||
throw NotFoundProblem(applicationId, "Application") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I appreciate that you've copied this code, but this NotFoundProblem can be moved into line 70 |
||
} | ||
|
||
@Transactional | ||
override fun applicationsPost(body: NewApplication): ResponseEntity<Application> { | ||
val user = userService.getUserForRequest() | ||
|
||
val personInfo = offenderService.getFullInfoForPersonOrThrow(body.crn) | ||
|
||
val applicationResult = cas2BailApplicationService.createCas2BailApplication( | ||
body.crn, | ||
user, | ||
) | ||
|
||
val application = when (applicationResult) { | ||
is ValidatableActionResult.GeneralValidationError -> throw BadRequestProblem(errorDetail = applicationResult.message) | ||
is ValidatableActionResult.FieldValidationError -> throw BadRequestProblem(invalidParams = applicationResult.validationMessages) | ||
is ValidatableActionResult.ConflictError -> throw ConflictProblem(id = applicationResult.conflictingEntityId, conflictReason = applicationResult.message) | ||
is ValidatableActionResult.Success -> applicationResult.entity | ||
} | ||
|
||
return ResponseEntity | ||
.created(URI.create("/cas2/applications/${application.id}")) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this be /cas2bail? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed done |
||
.body(cas2BailApplicationsTransformer.transformJpaToApi(application, personInfo)) | ||
} | ||
|
||
@Transactional | ||
override fun applicationsApplicationIdPut( | ||
applicationId: UUID, | ||
body: UpdateApplication, | ||
): ResponseEntity<Application> { | ||
val user = userService.getUserForRequest() | ||
|
||
val serializedData = objectMapper.writeValueAsString(body.data) | ||
|
||
val applicationResult = cas2BailApplicationService.updateCas2BailApplication( | ||
applicationId = | ||
applicationId, | ||
data = serializedData, | ||
user, | ||
) | ||
|
||
val validationResult = when (applicationResult) { | ||
is AuthorisableActionResult.NotFound -> throw NotFoundProblem(applicationId, "Application") | ||
is AuthorisableActionResult.Unauthorised -> throw ForbiddenProblem() | ||
is AuthorisableActionResult.Success -> applicationResult.entity | ||
} | ||
|
||
val updatedApplication = when (validationResult) { | ||
is ValidatableActionResult.GeneralValidationError -> throw BadRequestProblem(errorDetail = validationResult.message) | ||
is ValidatableActionResult.FieldValidationError -> throw BadRequestProblem(invalidParams = validationResult.validationMessages) | ||
is ValidatableActionResult.ConflictError -> throw ConflictProblem(id = validationResult.conflictingEntityId, conflictReason = validationResult.message) | ||
is ValidatableActionResult.Success -> validationResult.entity | ||
} | ||
|
||
return ResponseEntity.ok(getPersonDetailAndTransform(updatedApplication)) | ||
} | ||
|
||
@Transactional | ||
override fun applicationsApplicationIdAbandonPut(applicationId: UUID): ResponseEntity<Unit> { | ||
val user = userService.getUserForRequest() | ||
|
||
val validationResult = when (val applicationResult = cas2BailApplicationService.abandonCas2BailApplication(applicationId, user)) { | ||
is AuthorisableActionResult.NotFound -> throw NotFoundProblem(applicationId, "Application") | ||
is AuthorisableActionResult.Unauthorised -> throw ForbiddenProblem() | ||
is AuthorisableActionResult.Success -> applicationResult.entity | ||
} | ||
|
||
when (validationResult) { | ||
is ValidatableActionResult.GeneralValidationError -> throw BadRequestProblem(errorDetail = validationResult.message) | ||
is ValidatableActionResult.FieldValidationError -> throw BadRequestProblem(invalidParams = validationResult.validationMessages) | ||
is ValidatableActionResult.ConflictError -> throw ConflictProblem(id = validationResult.conflictingEntityId, conflictReason = validationResult.message) | ||
is ValidatableActionResult.Success -> validationResult.entity | ||
} | ||
|
||
return ResponseEntity.ok(Unit) | ||
} | ||
|
||
private fun getPersonNamesAndTransformToSummaries( | ||
applicationSummaries: List<Cas2BailApplicationSummaryEntity>, | ||
): List<ModelCas2ApplicationSummary> { | ||
val crns = applicationSummaries.map { it.crn } | ||
|
||
val personNamesMap = offenderService.getMapOfPersonNamesAndCrns(crns) | ||
|
||
return applicationSummaries.map { application -> | ||
cas2BailApplicationsTransformer.transformJpaSummaryToSummary(application, personNamesMap[application.crn]!!) | ||
} | ||
} | ||
|
||
private fun getPersonDetailAndTransform( | ||
application: Cas2BailApplicationEntity, | ||
): Application { | ||
val personInfo = offenderService.getFullInfoForPersonOrThrow(application.crn) | ||
|
||
return cas2BailApplicationsTransformer.transformJpaToApi(application, personInfo) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
package uk.gov.justice.digital.hmpps.approvedpremisesapi.controller.cas2bail | ||
|
||
import org.springframework.http.HttpStatus | ||
import org.springframework.http.ResponseEntity | ||
import org.springframework.stereotype.Service | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.cas2bail.AssessmentsCas2bailDelegate | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.Cas2ApplicationNote | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.Cas2Assessment | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.Cas2AssessmentStatusUpdate | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.NewCas2ApplicationNote | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.UpdateCas2Assessment | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.Cas2ApplicationNoteEntity | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.problem.ConflictProblem | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.problem.ForbiddenProblem | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.problem.NotFoundProblem | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.results.CasResult | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.ExternalUserService | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.cas2bail.Cas2BailApplicationNoteService | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.cas2bail.Cas2BailAssessmentService | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.service.cas2bail.Cas2BailStatusUpdateService | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.transformer.cas2.ApplicationNotesTransformer | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.transformer.cas2bail.Cas2BailAssessmentsTransformer | ||
import uk.gov.justice.digital.hmpps.approvedpremisesapi.util.extractEntityFromCasResult | ||
import java.net.URI | ||
import java.util.UUID | ||
|
||
@Service("Cas2BailAssessmentsController") | ||
class Cas2BailAssessmentsController( | ||
private val cas2BailAssessmentService: Cas2BailAssessmentService, | ||
private val cas2BailApplicationNoteService: Cas2BailApplicationNoteService, | ||
private val cas2BailAssessmentsTransformer: Cas2BailAssessmentsTransformer, | ||
private val applicationNotesTransformer: ApplicationNotesTransformer, | ||
private val cas2BailStatusUpdateService: Cas2BailStatusUpdateService, | ||
private val externalUserService: ExternalUserService, | ||
) : AssessmentsCas2bailDelegate { | ||
|
||
override fun assessmentsAssessmentIdGet(assessmentId: UUID): ResponseEntity<Cas2Assessment> { | ||
val assessment = when ( | ||
val assessmentResult = cas2BailAssessmentService.getAssessment(assessmentId) | ||
) { | ||
is CasResult.NotFound -> throw NotFoundProblem(assessmentId, "Cas2BailAssessment") | ||
is CasResult.Unauthorised -> throw ForbiddenProblem() | ||
is CasResult.Success -> assessmentResult | ||
is CasResult.ConflictError<*> -> throw ConflictProblem(assessmentId, "Cas2BailAssessment conflict by assessmentId") | ||
is CasResult.FieldValidationError<*> -> CasResult.FieldValidationError(mapOf("$.reason" to "doesNotExist")) | ||
is CasResult.GeneralValidationError<*> -> CasResult.GeneralValidationError("General Validation Error") | ||
} | ||
|
||
val cas2BailAssessmentEntity = extractEntityFromCasResult(assessment) | ||
return ResponseEntity.ok(cas2BailAssessmentsTransformer.transformJpaToApiRepresentation(cas2BailAssessmentEntity)) | ||
} | ||
|
||
override fun assessmentsAssessmentIdPut( | ||
assessmentId: UUID, | ||
updateCas2Assessment: UpdateCas2Assessment, | ||
): ResponseEntity<Cas2Assessment> { | ||
val assessmentResult = cas2BailAssessmentService.updateAssessment(assessmentId, updateCas2Assessment) | ||
when (assessmentResult) { | ||
is CasResult.NotFound -> throw NotFoundProblem(assessmentId, "Assessment") | ||
is CasResult.Unauthorised -> throw ForbiddenProblem() | ||
is CasResult.Success -> assessmentResult | ||
is CasResult.ConflictError<*> -> throw ConflictProblem(assessmentId, "Cas2BailAssessment conflict by assessmentId") | ||
is CasResult.FieldValidationError<*> -> CasResult.FieldValidationError(mapOf("$.reason" to "doesNotExist")) | ||
is CasResult.GeneralValidationError<*> -> CasResult.GeneralValidationError("General Validation Error") | ||
} | ||
|
||
val cas2BailAssessmentEntity = extractEntityFromCasResult(assessmentResult) | ||
return ResponseEntity.ok( | ||
cas2BailAssessmentsTransformer.transformJpaToApiRepresentation(cas2BailAssessmentEntity), | ||
) | ||
} | ||
|
||
override fun assessmentsAssessmentIdStatusUpdatesPost( | ||
assessmentId: UUID, | ||
cas2AssessmentStatusUpdate: Cas2AssessmentStatusUpdate, | ||
): ResponseEntity<Unit> { | ||
val result = cas2BailStatusUpdateService.createForAssessment( | ||
assessmentId = assessmentId, | ||
statusUpdate = cas2AssessmentStatusUpdate, | ||
assessor = externalUserService.getUserForRequest(), | ||
) | ||
|
||
processAuthorisationFor(result) | ||
.run { processValidation(result) } | ||
|
||
return ResponseEntity(HttpStatus.CREATED) | ||
} | ||
|
||
override fun assessmentsAssessmentIdNotesPost( | ||
assessmentId: UUID, | ||
body: NewCas2ApplicationNote, | ||
): ResponseEntity<Cas2ApplicationNote> { | ||
val noteResult = cas2BailApplicationNoteService.createAssessmentNote(assessmentId, body) | ||
|
||
val validationResult = processAuthorisationFor(noteResult) as CasResult<Cas2ApplicationNote> | ||
|
||
val note = processValidation(validationResult) as Cas2ApplicationNoteEntity | ||
|
||
return ResponseEntity | ||
.created(URI.create("/cas2/assessments/$assessmentId/notes/${note.id}")) | ||
.body( | ||
applicationNotesTransformer.transformJpaToApi(note), | ||
) | ||
} | ||
|
||
private fun <EntityType> processAuthorisationFor( | ||
result: CasResult<EntityType>, | ||
): Any? { | ||
return extractEntityFromCasResult(result) | ||
} | ||
|
||
private fun <EntityType : Any> processValidation(casResult: CasResult<EntityType>): Any { | ||
return extractEntityFromCasResult(casResult) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because the class name is unique within the project, you shouldn't need to specify a value in the @service annotation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed done.