Skip to content

Commit 5aa981b

Browse files
authored
CDPS-1124 Add distinguishing marks endpoints (#28)
* Update incorrect package * CDPS-1124 Endpoints for distinguishing marks * Correct typo
1 parent 6631292 commit 5aa981b

16 files changed

+1674
-18
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,105 @@
11
package uk.gov.justice.digital.hmpps.personintegrationapi.common.client
22

3+
import org.springframework.http.MediaType.APPLICATION_JSON_VALUE
4+
import org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE
35
import org.springframework.http.ResponseEntity
6+
import org.springframework.web.bind.annotation.ModelAttribute
47
import org.springframework.web.bind.annotation.PathVariable
58
import org.springframework.web.bind.annotation.RequestBody
9+
import org.springframework.web.bind.annotation.RequestPart
10+
import org.springframework.web.multipart.MultipartFile
611
import org.springframework.web.service.annotation.GetExchange
712
import org.springframework.web.service.annotation.HttpExchange
813
import org.springframework.web.service.annotation.PostExchange
914
import org.springframework.web.service.annotation.PutExchange
10-
import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.dto.UpdateBirthCountry
15+
import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.request.DistinguishingMarkCreateRequest
16+
import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.request.DistinguishingMarkUpdateRequest
1117
import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.request.MilitaryRecordRequest
18+
import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.request.UpdateBirthCountry
1219
import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.request.UpdateBirthPlace
1320
import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.request.UpdateNationality
1421
import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.request.UpdateReligion
1522
import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.response.MilitaryRecordPrisonDto
23+
import uk.gov.justice.digital.hmpps.personintegrationapi.corepersonrecord.dto.response.DistinguishingMarkDto
1624

17-
@HttpExchange("/api/offenders")
25+
@HttpExchange("/api")
1826
interface PrisonApiClient {
19-
@PutExchange("/{offenderNo}/birth-place")
27+
@PutExchange("/offenders/{offenderNo}/birth-place")
2028
fun updateBirthPlaceForWorkingName(
2129
@PathVariable offenderNo: String,
2230
@RequestBody updateBirthPlace: UpdateBirthPlace,
2331
): ResponseEntity<Void>
2432

25-
@PutExchange("/{offenderNo}/birth-country")
33+
@PutExchange("/offenders/{offenderNo}/birth-country")
2634
fun updateBirthCountryForWorkingName(
2735
@PathVariable offenderNo: String,
2836
@RequestBody updateBirthCountry: UpdateBirthCountry,
2937
): ResponseEntity<Void>
3038

31-
@PutExchange("/{offenderNo}/nationality")
39+
@PutExchange("/offenders/{offenderNo}/nationality")
3240
fun updateNationalityForWorkingName(
3341
@PathVariable offenderNo: String,
3442
@RequestBody updateNationality: UpdateNationality,
3543
): ResponseEntity<Void>
3644

37-
@GetExchange("/{offenderNo}/military-records")
45+
@GetExchange("/offenders/{offenderNo}/military-records")
3846
fun getMilitaryRecords(
3947
@PathVariable offenderNo: String,
4048
): ResponseEntity<MilitaryRecordPrisonDto>
4149

42-
@PutExchange("/{offenderNo}/military-records/{militarySeq}")
50+
@PutExchange("/offenders/{offenderNo}/military-records/{militarySeq}")
4351
fun updateMilitaryRecord(
4452
@PathVariable offenderNo: String,
4553
@PathVariable militarySeq: Int,
4654
@RequestBody militaryRecordRequest: MilitaryRecordRequest,
4755
): ResponseEntity<Void>
4856

49-
@PostExchange("/{offenderNo}/military-records")
57+
@PostExchange("/offenders/{offenderNo}/military-records")
5058
fun createMilitaryRecord(
5159
@PathVariable offenderNo: String,
5260
@RequestBody militaryRecordRequest: MilitaryRecordRequest,
5361
): ResponseEntity<Void>
5462

55-
@PutExchange("/{offenderNo}/religion")
63+
@PutExchange("/offenders/{offenderNo}/religion")
5664
fun updateReligionForWorkingName(
5765
@PathVariable offenderNo: String,
5866
@RequestBody updateNationality: UpdateReligion,
5967
): ResponseEntity<Void>
68+
69+
@GetExchange("/person/{prisonerNumber}/distinguishing-marks")
70+
fun getDistinguishingMarks(
71+
@PathVariable prisonerNumber: String,
72+
): ResponseEntity<List<DistinguishingMarkDto>>
73+
74+
@GetExchange("/person/{prisonerNumber}/distinguishing-mark/{markId}")
75+
fun getDistinguishingMark(
76+
@PathVariable prisonerNumber: String,
77+
@PathVariable markId: Int,
78+
): ResponseEntity<DistinguishingMarkDto>
79+
80+
@PutExchange("/person/{prisonerNumber}/distinguishing-mark/{markId}")
81+
fun updateDistinguishingMark(
82+
@RequestBody request: DistinguishingMarkUpdateRequest,
83+
@PathVariable prisonerNumber: String,
84+
@PathVariable markId: Int,
85+
): ResponseEntity<DistinguishingMarkDto>
86+
87+
@PostExchange("/person/{prisonerNumber}/distinguishing-mark", accept = [APPLICATION_JSON_VALUE, MULTIPART_FORM_DATA_VALUE])
88+
fun createDistinguishingMark(
89+
@RequestPart(name = "file") file: MultipartFile?,
90+
@ModelAttribute request: DistinguishingMarkCreateRequest,
91+
@PathVariable prisonerNumber: String,
92+
): ResponseEntity<DistinguishingMarkDto>
93+
94+
@GetExchange("/person/photo/{imageId}")
95+
fun getDistinguishingMarkImage(
96+
@PathVariable imageId: Int,
97+
): ResponseEntity<ByteArray>
98+
99+
@PostExchange("/person/{prisonerNumber}/distinguishing-mark/{markId}/photo")
100+
fun addDistinguishingMarkImage(
101+
@RequestPart(name = "file") file: MultipartFile,
102+
@PathVariable prisonerNumber: String,
103+
@PathVariable markId: Int,
104+
): ResponseEntity<DistinguishingMarkDto>
60105
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package uk.gov.justice.digital.hmpps.personintegrationapi.common.client.request
2+
3+
import io.swagger.v3.oas.annotations.media.Schema
4+
5+
@Schema(description = "Distinguishing mark request object. Used to create a distinguishing mark.")
6+
data class DistinguishingMarkCreateRequest(
7+
8+
@Schema(
9+
description = "The body part that the mark is on",
10+
example = "TORSO",
11+
)
12+
val bodyPart: String? = null,
13+
14+
@Schema(
15+
description = "The type of distinguishing mark (e.g. scar, tattoo)",
16+
example = "SCAR",
17+
)
18+
val markType: String? = null,
19+
20+
@Schema(
21+
description = "The side of the body the mark is on",
22+
example = "L",
23+
)
24+
val side: String? = null,
25+
26+
@Schema(
27+
description = "The orientation of the mark on the body part (e.g. upper, lower)",
28+
example = "UPP",
29+
)
30+
val partOrientation: String? = null,
31+
32+
@Schema(description = "Comments about the distinguishing mark")
33+
val comment: String? = null,
34+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package uk.gov.justice.digital.hmpps.personintegrationapi.common.client.request
2+
3+
import io.swagger.v3.oas.annotations.media.Schema
4+
5+
@Schema(description = "Distinguishing mark request object. Used to update a distinguishing mark.")
6+
data class DistinguishingMarkUpdateRequest(
7+
8+
@Schema(
9+
description = "The body part that the mark is on",
10+
example = "TORSO",
11+
)
12+
val bodyPart: String? = null,
13+
14+
@Schema(
15+
description = "The type of distinguishing mark (e.g. scar, tattoo)",
16+
example = "SCAR",
17+
)
18+
val markType: String? = null,
19+
20+
@Schema(
21+
description = "The side of the body the mark is on",
22+
example = "L",
23+
)
24+
val side: String? = null,
25+
26+
@Schema(
27+
description = "The orientation of the mark on the body part (e.g. upper, lower)",
28+
example = "UPP",
29+
)
30+
val partOrientation: String? = null,
31+
32+
@Schema(description = "Comments about the distinguishing mark")
33+
val comment: String? = null,
34+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package uk.gov.justice.digital.hmpps.personintegrationapi.common.client.request
2+
3+
enum class SourceSystem {
4+
NOMIS,
5+
}
6+
7+
fun String.toSourceSystem() = SourceSystem.valueOf(this.trim().uppercase())

src/main/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/common/client/request/UpdateBirthCountry.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package uk.gov.justice.digital.hmpps.personintegrationapi.common.client.dto
1+
package uk.gov.justice.digital.hmpps.personintegrationapi.common.client.request
22

33
import io.swagger.v3.oas.annotations.media.Schema
44

src/main/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/common/config/WebClientConfiguration.kt

+4-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import org.springframework.web.service.invoker.HttpServiceProxyFactory
2222
import reactor.netty.http.client.HttpClient
2323
import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.PrisonApiClient
2424
import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.ReferenceDataClient
25+
import uk.gov.justice.digital.hmpps.personintegrationapi.common.resolver.DistinguishingMarkCreateRequestResolver
2526
import uk.gov.justice.digital.hmpps.personintegrationapi.config.UserEnhancedOAuth2ClientCredentialGrantRequestConverter
2627
import uk.gov.justice.hmpps.kotlin.auth.healthWebClient
2728
import java.time.Duration
@@ -58,7 +59,9 @@ class WebClientConfiguration(
5859
@DependsOn("prisonApiWebClient")
5960
fun prisonApiClient(prisonApiWebClient: WebClient): PrisonApiClient {
6061
val factory =
61-
HttpServiceProxyFactory.builderFor(WebClientAdapter.create(prisonApiWebClient)).build()
62+
HttpServiceProxyFactory.builderFor(WebClientAdapter.create(prisonApiWebClient))
63+
.customArgumentResolver(DistinguishingMarkCreateRequestResolver())
64+
.build()
6265
val client = factory.createClient(PrisonApiClient::class.java)
6366

6467
return client
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package uk.gov.justice.digital.hmpps.personintegrationapi.common.resolver
2+
3+
import org.springframework.core.MethodParameter
4+
import org.springframework.web.service.invoker.HttpMethodArgumentResolver
5+
import org.springframework.web.service.invoker.HttpRequestValues
6+
import org.springframework.web.service.invoker.HttpRequestValues.Builder
7+
import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.request.DistinguishingMarkCreateRequest
8+
9+
class DistinguishingMarkCreateRequestResolver : HttpMethodArgumentResolver() {
10+
11+
override fun resolve(argument: Any?, parameter: MethodParameter, requestValues: HttpRequestValues.Builder): Boolean {
12+
if (argument != null && argument is DistinguishingMarkCreateRequest) {
13+
addRequestPart(requestValues, "markType", argument.markType)
14+
addRequestPart(requestValues, "bodyPart", argument.bodyPart)
15+
addRequestPart(requestValues, "side", argument.side)
16+
addRequestPart(requestValues, "partOrientation", argument.partOrientation)
17+
addRequestPart(requestValues, "comment", argument.comment)
18+
return true
19+
}
20+
return false
21+
}
22+
23+
private fun addRequestPart(requestValues: Builder, parameter: String, value: Any?) {
24+
if (value != null) {
25+
requestValues.addRequestPart(parameter, value)
26+
}
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package uk.gov.justice.digital.hmpps.personintegrationapi.corepersonrecord.dto.response
2+
3+
import com.fasterxml.jackson.annotation.JsonInclude
4+
import com.fasterxml.jackson.annotation.JsonInclude.Include
5+
import io.swagger.v3.oas.annotations.media.Schema
6+
import java.time.LocalDateTime
7+
8+
@JsonInclude(Include.NON_NULL)
9+
@Schema(description = "DTO representing a distinguishing mark with details around body part, mark type etc.")
10+
data class DistinguishingMarkDto(
11+
@Schema(
12+
description = "The sequence number of the distinguishing mark within the booking.",
13+
example = "1",
14+
)
15+
val id: Int,
16+
17+
@Schema(
18+
description = "The id of the booking that the distinguishing mark is associated with.",
19+
example = "1",
20+
)
21+
val bookingId: Long,
22+
23+
@Schema(
24+
description = "Offender unique reference",
25+
example = "A1234AA",
26+
)
27+
val offenderNo: String? = null,
28+
29+
@Schema(
30+
description = "The body part that the mark is on",
31+
example = "TORSO",
32+
)
33+
val bodyPart: String? = null,
34+
35+
@Schema(
36+
description = "The type of distinguishign mark (e.g. scar, tattoo)",
37+
example = "SCAR",
38+
)
39+
val markType: String? = null,
40+
41+
@Schema(
42+
description = "The side of the body the mark is on",
43+
example = "L",
44+
)
45+
val side: String? = null,
46+
47+
@Schema(
48+
description = "The orientation of the mark on the body part (e.g. upper, lower)",
49+
example = "UPP",
50+
)
51+
val partOrientation: String? = null,
52+
53+
@Schema(description = "Comments about the distinguishing mark")
54+
val comment: String? = null,
55+
56+
@Schema(description = "The date and time the data was created")
57+
val createdAt: LocalDateTime? = null,
58+
59+
@Schema(
60+
description = "The username of the user that created this distinguishing mark.",
61+
example = "TORSO",
62+
)
63+
val createdBy: String? = null,
64+
65+
@Schema(description = "List of details of images associated with this distinguishing mark.")
66+
val photographUuids: List<DistinguishingMarkImageDetail> = listOf(),
67+
)
68+
69+
data class DistinguishingMarkImageDetail(
70+
@Schema(description = "The image id")
71+
val id: Long? = null,
72+
73+
@Schema(description = "True if this image is the latest one associated with a mark")
74+
val latest: Boolean = false,
75+
)

0 commit comments

Comments
 (0)