Skip to content

Commit fa72896

Browse files
Add exception for unrecognised and uncoded prescription types (#1111)
* Add exception for the case where prescription type is unrecognised (the text value is present but is not "No information available"). * Add unit test and test file for the above change. * Remove now unused methods and constants from `MedicationStatementExtractor`.
1 parent 7b89644 commit fa72896

File tree

4 files changed

+112
-34
lines changed

4 files changed

+112
-34
lines changed

service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/MedicationStatementExtractor.java

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import org.apache.commons.lang3.StringUtils;
1010
import org.hl7.fhir.dstu3.model.BaseExtension;
1111
import org.hl7.fhir.dstu3.model.CodeableConcept;
12-
import org.hl7.fhir.dstu3.model.Coding;
1312
import org.hl7.fhir.dstu3.model.DateTimeType;
1413
import org.hl7.fhir.dstu3.model.Extension;
1514
import org.hl7.fhir.dstu3.model.MedicationRequest;
@@ -34,7 +33,6 @@ public class MedicationStatementExtractor {
3433
TemplateUtils.loadTemplate("in_fulfilment_of_template.mustache");
3534

3635
private static final String MEDICATION_QUANTITY_TEXT_URL = "https://fhir.nhs.uk/STU3/StructureDefinition/Extension-CareConnect-GPC-MedicationQuantityText-1";
37-
private static final String PRESCRIPTION_TYPE_URL = "https://fhir.nhs.uk/STU3/StructureDefinition/Extension-CareConnect-GPC-PrescriptionType-1";
3836
private static final String REPEAT_INFORMATION_URL = "https://fhir.nhs.uk/STU3/StructureDefinition/Extension-CareConnect-GPC-MedicationRepeatInformation-1";
3937
private static final String NUM_OF_REPEAT_PRESCRIPTIONS_ALLOWED_URL = "numberOfRepeatPrescriptionsAllowed";
4038
private static final String DEFAULT_REPEAT_VALUE = "1";
@@ -43,7 +41,7 @@ public class MedicationStatementExtractor {
4341
private static final String STATUS_CHANGE_URL = "statusChangeDate";
4442
private static final String AVAILABILITY_TIME_VALUE_TEMPLATE = "<availabilityTime value=\"%s\"/>";
4543
private static final String DEFAULT_QUANTITY_TEXT = "Unk UoM";
46-
private static final String NO_INFO_AVAILABLE = "No information available";
44+
4745
private static final String PRESCRIBING_AGENCY_EXTENSION_URL = "https://fhir.nhs.uk/STU3/StructureDefinition/Extension-CareConnect-GPC-PrescribingAgency-1";
4846

4947
public static String extractDispenseRequestQuantityText(MedicationRequest medicationRequest) {
@@ -68,25 +66,6 @@ public static String extractDispenseRequestQuantityTextFromQuantity(MedicationRe
6866
.orElse(DEFAULT_QUANTITY_TEXT);
6967
}
7068

71-
public static String extractPrescriptionTypeCode(MedicationRequest medicationRequest) {
72-
return filterExtensionByUrl(medicationRequest, PRESCRIPTION_TYPE_URL)
73-
.map(Extension::getValue)
74-
.map(CodeableConcept.class::cast)
75-
.map(CodeableConcept::getCodingFirstRep)
76-
.map(Coding::getCode)
77-
.orElse(StringUtils.EMPTY);
78-
}
79-
80-
public static boolean prescriptionTypeTextIsNoInfoAvailable(MedicationRequest medicationRequest) {
81-
var prescriptionTypeText = filterExtensionByUrl(medicationRequest, PRESCRIPTION_TYPE_URL)
82-
.map(Extension::getValue)
83-
.map(CodeableConcept.class::cast)
84-
.map(CodeableConcept::getText)
85-
.orElse(StringUtils.EMPTY);
86-
87-
return NO_INFO_AVAILABLE.equals(prescriptionTypeText);
88-
}
89-
9069
public static String extractRepeatValue(MedicationRequest medicationRequest) {
9170
var repeatInformation = filterExtensionByUrl(medicationRequest, REPEAT_INFORMATION_URL);
9271

service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/MedicationStatementMapper.java

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@
44
import static uk.nhs.adaptors.gp2gp.ehr.mapper.MedicationStatementExtractor.extractDispenseRequestQuantityTextFromQuantity;
55
import static uk.nhs.adaptors.gp2gp.ehr.mapper.MedicationStatementExtractor.extractEhrSupplyTypeCodeableConcept;
66
import static uk.nhs.adaptors.gp2gp.ehr.mapper.MedicationStatementExtractor.extractIdFromPlanMedicationRequestReference;
7-
import static uk.nhs.adaptors.gp2gp.ehr.mapper.MedicationStatementExtractor.extractPrescriptionTypeCode;
87
import static uk.nhs.adaptors.gp2gp.ehr.mapper.MedicationStatementExtractor.extractRepeatValue;
98
import static uk.nhs.adaptors.gp2gp.ehr.mapper.MedicationStatementExtractor.extractStatusReasonStoppedAvailabilityTime;
109
import static uk.nhs.adaptors.gp2gp.ehr.mapper.MedicationStatementExtractor.extractStatusReasonStoppedCode;
1110
import static uk.nhs.adaptors.gp2gp.ehr.mapper.MedicationStatementExtractor.extractStatusReasonStoppedText;
1211
import static uk.nhs.adaptors.gp2gp.ehr.mapper.MedicationStatementExtractor.hasStatusReasonStopped;
13-
import static uk.nhs.adaptors.gp2gp.ehr.mapper.MedicationStatementExtractor.prescriptionTypeTextIsNoInfoAvailable;
12+
import static uk.nhs.adaptors.gp2gp.ehr.utils.ExtensionMappingUtils.filterExtensionByUrl;
1413

1514
import java.util.Arrays;
1615
import java.util.List;
@@ -22,6 +21,9 @@
2221

2322
import org.apache.commons.lang3.StringUtils;
2423
import org.hl7.fhir.dstu3.model.Annotation;
24+
import org.hl7.fhir.dstu3.model.CodeableConcept;
25+
import org.hl7.fhir.dstu3.model.Coding;
26+
import org.hl7.fhir.dstu3.model.Extension;
2527
import org.hl7.fhir.dstu3.model.Medication;
2628
import org.hl7.fhir.dstu3.model.MedicationRequest;
2729
import org.hl7.fhir.dstu3.model.Reference;
@@ -72,6 +74,10 @@ public class MedicationStatementMapper {
7274
Arrays.asList("delayed-prescribing", "repeat", "repeat-dispensing");
7375
private static final String ACUTE_REPEAT_VALUE = "0";
7476
private static final String INVALID_PRESCRIPTION_TYPE_MESSAGE = "Could not resolve Prescription Type of `%s` in %s";
77+
private static final String PRESCRIPTION_TYPE_UNRECOGNISED = "Could not resolve Prescription Type with text of `%s` in %s";
78+
private static final String NO_INFO_AVAILABLE = "No information available";
79+
private static final String PRESCRIPTION_TYPE_URL =
80+
"https://fhir.nhs.uk/STU3/StructureDefinition/Extension-CareConnect-GPC-PrescriptionType-1";
7581

7682
private final MessageContext messageContext;
7783
private final CodeableConceptCdMapper codeableConceptCdMapper;
@@ -246,20 +252,45 @@ private String buildStatusReasonStoppedAvailabilityTime(MedicationRequest medica
246252

247253
private String buildRepeatNumber(MedicationRequest medicationRequest) {
248254
if (MedicationRequestIntent.PLAN.getDisplay().equals(medicationRequest.getIntent().getDisplay())) {
249-
var prescriptionTypeCode = extractPrescriptionTypeCode(medicationRequest);
250-
251-
if (ACUTE_PRESCRIPTION_TYPE_CODES.contains(prescriptionTypeCode)) {
252-
return ACUTE_REPEAT_VALUE;
253-
} else if (REPEAT_PRESCRIPTION_TYPE_CODES.contains(prescriptionTypeCode)) {
254-
return extractRepeatValue(medicationRequest);
255-
} else if (prescriptionTypeCode.isBlank() && prescriptionTypeTextIsNoInfoAvailable(medicationRequest)) {
256-
return extractRepeatValue(medicationRequest);
257-
}
258-
throw new EhrMapperException(INVALID_PRESCRIPTION_TYPE_MESSAGE.formatted(prescriptionTypeCode, medicationRequest.getId()));
255+
Optional<CodeableConcept> prescriptionType = filterExtensionByUrl(medicationRequest, PRESCRIPTION_TYPE_URL)
256+
.map(Extension::getValue)
257+
.map(CodeableConcept.class::cast);
258+
259+
var prescriptionTypeCode = prescriptionType
260+
.map(CodeableConcept::getCodingFirstRep)
261+
.map(Coding::getCode);
262+
263+
return prescriptionTypeCode.isEmpty()
264+
? buildRepeatNumberFromPrescriptionTypeText(medicationRequest, prescriptionType)
265+
: buildRepeatNumberFromPrescriptionTypeCode(medicationRequest, prescriptionTypeCode.get());
259266
}
260267
return StringUtils.EMPTY;
261268
}
262269

270+
private static String buildRepeatNumberFromPrescriptionTypeCode(MedicationRequest medicationRequest, String prescriptionTypeCode) {
271+
if (ACUTE_PRESCRIPTION_TYPE_CODES.contains(prescriptionTypeCode)) {
272+
return ACUTE_REPEAT_VALUE;
273+
} else if (REPEAT_PRESCRIPTION_TYPE_CODES.contains(prescriptionTypeCode)) {
274+
return extractRepeatValue(medicationRequest);
275+
}
276+
throw new EhrMapperException(INVALID_PRESCRIPTION_TYPE_MESSAGE.formatted(prescriptionTypeCode, medicationRequest.getId()));
277+
}
278+
279+
private static String buildRepeatNumberFromPrescriptionTypeText(
280+
MedicationRequest medicationRequest,
281+
Optional<CodeableConcept> prescriptionType
282+
) {
283+
var prescriptionTypeText = prescriptionType
284+
.map(CodeableConcept::getText)
285+
.orElse(StringUtils.EMPTY);
286+
287+
if (NO_INFO_AVAILABLE.equals(prescriptionTypeText)) {
288+
return extractRepeatValue(medicationRequest);
289+
} else {
290+
throw new EhrMapperException(PRESCRIPTION_TYPE_UNRECOGNISED.formatted(prescriptionTypeText, medicationRequest.getId()));
291+
}
292+
}
293+
263294
private String buildBasedOn(MedicationRequest medicationRequest) {
264295
if (MedicationRequestIntent.ORDER.getDisplay().equals(medicationRequest.getIntent().getDisplay())) {
265296
if (medicationRequest.hasBasedOn()) {

service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/MedicationStatementMapperTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,23 @@ void When_MedicationRequestPlanHasInvalidPrescriptionType_Expect_EhrMapperExcept
386386
assertThat(exception.getMessage()).isEqualTo("Could not resolve Prescription Type of `invalid-type` in MedicationRequest/789");
387387
}
388388

389+
@Test
390+
void When_MedicationRequestPlanHasUnrecognisedUncodedPrescriptionType_Expect_EhrMapperExceptionThrown() {
391+
final var jsonInput = ResourceTestFileUtils.getFileContent(
392+
TEST_FILE_DIRECTORY + "mr-plan-with-unrecognised-uncoded-prescription-type.json"
393+
);
394+
final var parsedMedicationRequest = new FhirParseService()
395+
.parseResource(jsonInput, MedicationRequest.class);
396+
397+
var exception = assertThrows(
398+
EhrMapperException.class,
399+
() -> medicationStatementMapper.mapMedicationRequestToMedicationStatement(parsedMedicationRequest));
400+
401+
assertThat(exception.getMessage())
402+
.isEqualTo("Could not resolve Prescription Type with text of `Some medical information` in MedicationRequest/789");
403+
404+
}
405+
389406
private void assertXmlIsEqual(String outputString, String expected) {
390407

391408
Diff diff = DiffBuilder.compare(outputString).withTest(expected)
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{
2+
"resourceType": "MedicationRequest",
3+
"id": "789",
4+
"meta": {
5+
"profile": [
6+
"https://fhir.nhs.uk/STU3/StructureDefinition/CareConnect-GPC-MedicationRequest-1"
7+
]
8+
},
9+
"extension": [
10+
{
11+
"url": "https://fhir.nhs.uk/STU3/StructureDefinition/Extension-CareConnect-GPC-PrescriptionType-1",
12+
"valueCodeableConcept": {
13+
"text": "Some medical information"
14+
}
15+
}
16+
],
17+
"status": "completed",
18+
"intent": "plan",
19+
"medicationReference": {
20+
"reference": "Medication/20"
21+
},
22+
"authoredOn": "2022-10-04",
23+
"recorder": {
24+
"reference": "Practitioner/1332aa9c-28d6-11eb-adc1-0242ac120002"
25+
},
26+
"requester": {
27+
"agent": {
28+
"reference": "Organization/F85003"
29+
}
30+
},
31+
"dosageInstruction": [
32+
{
33+
"text": "One puff as needed. Max 10 doses per day"
34+
}
35+
],
36+
"dispenseRequest": {
37+
"validityPeriod": {
38+
"start": "2022-10-04",
39+
"end": "2022-11-01"
40+
},
41+
"quantity": {
42+
"value": 1,
43+
"unit": "dose"
44+
},
45+
"expectedSupplyDuration": {
46+
"value": 28,
47+
"system": "http://unitsofmeasure.org",
48+
"code": "d"
49+
}
50+
}
51+
}

0 commit comments

Comments
 (0)