Skip to content

Commit 67c1fce

Browse files
committed
wip
1 parent 4c00546 commit 67c1fce

File tree

8 files changed

+628
-0
lines changed

8 files changed

+628
-0
lines changed

src/main/java/uk/gov/hmcts/reform/iacaseapi/domain/entities/AsylumCaseFieldDefinition.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2826,6 +2826,15 @@ public enum AsylumCaseFieldDefinition {
28262826
HEARING_DECISION_LIST(
28272827
"hearingDecisionList", new TypeReference<List<IdValue<HearingDecision>>>(){}),
28282828

2829+
DETENTION_BUILDING(
2830+
"detentionBuilding", new TypeReference<String>(){}
2831+
),
2832+
DETENTION_ADDRESS_LINES(
2833+
"detentionAddressLines", new TypeReference<String>(){}
2834+
),
2835+
DETENTION_POSTCODE(
2836+
"detentionPostcode", new TypeReference<String>(){}
2837+
)
28292838
;
28302839

28312840
private final String value;
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package uk.gov.hmcts.reform.iacaseapi.domain.handlers.presubmit;
2+
3+
import org.apache.logging.log4j.util.Strings;
4+
import org.springframework.stereotype.Component;
5+
import uk.gov.hmcts.reform.iacaseapi.domain.RequiredFieldMissingException;
6+
import uk.gov.hmcts.reform.iacaseapi.domain.entities.AsylumCase;
7+
import uk.gov.hmcts.reform.iacaseapi.domain.entities.AsylumCaseFieldDefinition;
8+
import uk.gov.hmcts.reform.iacaseapi.domain.entities.ccd.Event;
9+
import uk.gov.hmcts.reform.iacaseapi.domain.entities.ccd.callback.Callback;
10+
import uk.gov.hmcts.reform.iacaseapi.domain.entities.ccd.callback.PreSubmitCallbackResponse;
11+
import uk.gov.hmcts.reform.iacaseapi.domain.entities.ccd.callback.PreSubmitCallbackStage;
12+
import uk.gov.hmcts.reform.iacaseapi.domain.entities.ccd.field.AddressUk;
13+
import uk.gov.hmcts.reform.iacaseapi.domain.entities.ccd.field.YesOrNo;
14+
import uk.gov.hmcts.reform.iacaseapi.domain.handlers.PreSubmitCallbackHandler;
15+
import uk.gov.hmcts.reform.iacaseapi.domain.service.DetentionFacilityAddressProvider;
16+
import uk.gov.hmcts.reform.iacaseapi.domain.service.DetentionFacilityAddressProvider.DetentionAddress;
17+
18+
import java.util.EnumSet;
19+
import java.util.List;
20+
import java.util.Optional;
21+
import java.util.Set;
22+
import java.util.stream.Stream;
23+
24+
import static java.util.Objects.requireNonNull;
25+
import static java.util.stream.Collectors.toList;
26+
import static uk.gov.hmcts.reform.iacaseapi.domain.entities.AsylumCaseFieldDefinition.*;
27+
import static uk.gov.hmcts.reform.iacaseapi.domain.entities.DetentionFacility.*;
28+
import static uk.gov.hmcts.reform.iacaseapi.domain.entities.ccd.Event.*;
29+
import static uk.gov.hmcts.reform.iacaseapi.domain.entities.ccd.callback.PreSubmitCallbackStage.MID_EVENT;
30+
import static uk.gov.hmcts.reform.iacaseapi.domain.entities.ccd.field.YesOrNo.NO;
31+
import static uk.gov.hmcts.reform.iacaseapi.domain.entities.ccd.field.YesOrNo.YES;
32+
33+
@Component
34+
public class DetentionLocationAddressPopulator implements PreSubmitCallbackHandler<AsylumCase> {
35+
36+
private static final Set<String> DETENTION_FACILITY_PAGE_IDS = Set.of("ircName", "prisonName", "appellantAddress");
37+
private static final EnumSet<Event> SUPPORTED_EVENTS = EnumSet.of(
38+
START_APPEAL, EDIT_APPEAL, EDIT_APPEAL_AFTER_SUBMIT, UPDATE_DETENTION_LOCATION
39+
);
40+
41+
private final DetentionFacilityAddressProvider addressProvider;
42+
43+
public DetentionLocationAddressPopulator(DetentionFacilityAddressProvider addressProvider) {
44+
this.addressProvider = addressProvider;
45+
}
46+
47+
public boolean canHandle(
48+
PreSubmitCallbackStage callbackStage,
49+
Callback<AsylumCase> callback
50+
) {
51+
requireNonNull(callbackStage, "callbackStage must not be null");
52+
requireNonNull(callback, "callback must not be null");
53+
54+
YesOrNo appellantInDetention = callback.getCaseDetails()
55+
.getCaseData().read(APPELLANT_IN_DETENTION, YesOrNo.class).orElse(NO);
56+
57+
return callbackStage == MID_EVENT
58+
&& (SUPPORTED_EVENTS.contains(callback.getEvent()))
59+
&& (DETENTION_FACILITY_PAGE_IDS.contains(callback.getPageId()))
60+
&& appellantInDetention.equals(YES);
61+
}
62+
63+
public PreSubmitCallbackResponse<AsylumCase> handle(
64+
PreSubmitCallbackStage callbackStage,
65+
Callback<AsylumCase> callback
66+
) {
67+
if (!canHandle(callbackStage, callback)) {
68+
throw new IllegalStateException("Cannot handle callback");
69+
}
70+
71+
AsylumCase asylumCase = callback
72+
.getCaseDetails()
73+
.getCaseData();
74+
75+
String facilityType = asylumCase.read(DETENTION_FACILITY, String.class)
76+
.orElseThrow(() -> new IllegalArgumentException("not a valid Detention Facility"));
77+
78+
if (facilityType.equals(IRC.getValue()) || facilityType.equals(PRISON.getValue())) {
79+
AsylumCaseFieldDefinition nameField = facilityType.equals(IRC.getValue()) ? IRC_NAME : PRISON_NAME;
80+
81+
String facilityName = asylumCase.read(nameField, String.class)
82+
.orElseThrow(() -> new RequiredFieldMissingException(nameField.value()));
83+
84+
DetentionAddress facilityAddress = addressProvider.getAddressFor(facilityName)
85+
.orElseThrow(() -> new RuntimeException("Could not find address for facility: " + facilityName));
86+
87+
asylumCase.write(DETENTION_BUILDING, facilityAddress.building());
88+
asylumCase.write(DETENTION_ADDRESS_LINES, facilityAddress.addressLines());
89+
asylumCase.write(DETENTION_POSTCODE, facilityAddress.postcode());
90+
}
91+
92+
if (facilityType.equals(OTHER.getValue())) {
93+
buildDetentionAddressFromAppellantAddress(asylumCase);
94+
}
95+
96+
return new PreSubmitCallbackResponse<>(asylumCase);
97+
}
98+
99+
private void buildDetentionAddressFromAppellantAddress(AsylumCase asylumCase) {
100+
AddressUk appellantAddress = asylumCase.read(APPELLANT_ADDRESS, AddressUk.class)
101+
.orElseThrow(() -> new RequiredFieldMissingException("appellantAddress"));
102+
103+
asylumCase.write(DETENTION_BUILDING, appellantAddress.getAddressLine1().orElse(""));
104+
asylumCase.write(DETENTION_ADDRESS_LINES, buildAddressLines(appellantAddress));
105+
asylumCase.write(DETENTION_POSTCODE, appellantAddress.getPostCode().orElse(""));
106+
}
107+
108+
private String buildAddressLines(AddressUk appellantAddress) {
109+
List<String> addressParts = Stream.of(
110+
appellantAddress.getAddressLine2(),
111+
appellantAddress.getAddressLine3(),
112+
appellantAddress.getPostTown(),
113+
appellantAddress.getCounty(),
114+
appellantAddress.getCountry()
115+
)
116+
.filter(Optional::isPresent)
117+
.map(Optional::get)
118+
.filter(str -> !Strings.isBlank(str))
119+
.collect(toList());
120+
121+
return String.join(", ", addressParts);
122+
}
123+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package uk.gov.hmcts.reform.iacaseapi.domain.service;
2+
3+
import org.springframework.stereotype.Component;
4+
import uk.gov.hmcts.reform.iacaseapi.infrastructure.config.DetentionFacilityAddressLoader;
5+
6+
import java.util.HashMap;
7+
import java.util.List;
8+
import java.util.Map;
9+
import java.util.Optional;
10+
11+
12+
@Component
13+
public class DetentionFacilityAddressProvider {
14+
15+
private final Map<String, String> addresses = new HashMap<>();
16+
17+
public DetentionFacilityAddressProvider(DetentionFacilityAddressLoader addressLoader) {
18+
extractAddressesToMap(addressLoader);
19+
}
20+
21+
public Optional<DetentionAddress> getAddressFor(String detentionFacility) {
22+
String maybeDetentionAddress = this.addresses.get(detentionFacility);
23+
24+
if (maybeDetentionAddress == null) {
25+
return Optional.empty();
26+
}
27+
28+
String[] parts = maybeDetentionAddress.split(",");
29+
30+
if (parts.length < 2) {
31+
throw new IllegalStateException("Invalid address: " + maybeDetentionAddress);
32+
}
33+
34+
String name = parts[0].trim();
35+
String postcode = parts[parts.length - 1].trim();
36+
37+
StringBuilder addressLines = new StringBuilder();
38+
for (int i = 1; i < parts.length - 1; i++) {
39+
addressLines.append(parts[i].trim());
40+
if (i < parts.length - 2) {
41+
addressLines.append(", ");
42+
}
43+
}
44+
45+
return Optional.of(new DetentionAddress(name, addressLines.toString(), postcode));
46+
}
47+
48+
private void extractAddressesToMap(DetentionFacilityAddressLoader addressLoader) {
49+
List<String> addressLines = addressLoader.loadAddress();
50+
for (String line : addressLines) {
51+
String[] parts = line.split(",", 2);
52+
if (parts.length == 2) {
53+
String key = parts[0].trim();
54+
String value = parts[1].trim().replaceAll("^\"|\"$", ""); // remove surrounding quotes
55+
addresses.put(key, value);
56+
}
57+
}
58+
}
59+
60+
public record DetentionAddress(String building, String addressLines, String postcode) {
61+
}
62+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package uk.gov.hmcts.reform.iacaseapi.infrastructure.config;
2+
3+
import org.springframework.beans.factory.annotation.Value;
4+
import org.springframework.stereotype.Component;
5+
6+
import java.io.BufferedReader;
7+
import java.io.InputStream;
8+
import java.io.InputStreamReader;
9+
import java.util.List;
10+
11+
import static java.nio.charset.StandardCharsets.UTF_8;
12+
import static java.util.Objects.requireNonNull;
13+
import static java.util.stream.Collectors.toList;
14+
15+
16+
@Component
17+
public class DetentionFacilityAddressLoader {
18+
19+
private final String addressFile;
20+
21+
public DetentionFacilityAddressLoader(@Value("${files.detention-facilities-addresses}") String addressesFile) {
22+
this.addressFile = addressesFile;
23+
}
24+
25+
public List<String> loadAddress() {
26+
InputStream resourceAsStream = requireNonNull(getClass().getResourceAsStream(addressFile));
27+
try (BufferedReader reader = new BufferedReader(new InputStreamReader(resourceAsStream, UTF_8))) {
28+
return reader.lines().collect(toList());
29+
} catch (Exception e) {
30+
throw new RuntimeException("Failed to load prison addresses", e);
31+
}
32+
}
33+
}

src/main/resources/application.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ fees-register:
5656
jurisdiction2: immigration and asylum chamber
5757
keyword: HearingPaper
5858
service: other
59+
files:
60+
detention-facilities-addresses: "/detention-facilities.csv"
5961

6062
spring:
6163
config:

0 commit comments

Comments
 (0)