Skip to content

Commit d60623c

Browse files
NIAD-3304: Add functionality for medication codeable concepts to include non-SNOMEDCT codes (#1134)
* NIAD-3304: Add functionality for medication codeable concepts to include non-SNOMEDCT codes * Update `fhir-bundle.json` to add `Medication` resources for non-snomed codes, and additionally for when no SNOMED code is present. * Add test to ensure that translations are added when a `Medication` contains a snomed code and non-snomed codes. * Add test to ensure that a `nullFlavor="UNK"` coding block is created when no snomed codes are present in a `Medication`. * Add test files for the above tests. * Remove unnecessary ifPresent check when populating parameters builder
1 parent 6d77f0c commit d60623c

File tree

7 files changed

+289
-23
lines changed

7 files changed

+289
-23
lines changed

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

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -81,35 +81,31 @@ public String mapCodeableConceptToCd(CodeableConcept codeableConcept) {
8181
// we have agreed to use the Concept ID rather than Description Id for medications which will avoided the degradation.
8282
public String mapCodeableConceptForMedication(CodeableConcept codeableConcept) {
8383
var builder = CodeableConceptCdTemplateParameters.builder();
84-
var mainCode = getSnomedCodeCoding(codeableConcept);
84+
var snomedCodeCoding = getSnomedCodeCoding(codeableConcept);
8585

86-
builder.nullFlavor(mainCode.isEmpty());
86+
if (snomedCodeCoding.isEmpty()) {
87+
return buildNullFlavourCodeableConceptCd(codeableConcept, snomedCodeCoding);
88+
}
8789

88-
if (mainCode.isPresent()) {
89-
var extension = retrieveDescriptionExtension(mainCode.get())
90-
.map(Extension::getExtension)
91-
.orElse(Collections.emptyList());
90+
var extension = retrieveDescriptionExtension(snomedCodeCoding.get())
91+
.map(Extension::getExtension)
92+
.orElse(Collections.emptyList());
9293

93-
builder.mainCodeSystem(SNOMED_SYSTEM_CODE);
94+
builder.mainCodeSystem(SNOMED_SYSTEM_CODE);
9495

95-
Optional<String> code = Optional.ofNullable(mainCode.get().getCode());
96-
code.ifPresent(builder::mainCode);
96+
Optional<String> code = Optional.ofNullable(snomedCodeCoding.get().getCode());
97+
code.ifPresent(builder::mainCode);
9798

98-
Optional<String> displayName = extension.stream()
99-
.filter(displayExtension -> DESCRIPTION_DISPLAY.equals(displayExtension.getUrl()))
100-
.map(description -> description.getValue().toString())
101-
.findFirst()
102-
.or(() -> Optional.ofNullable(mainCode.get().getDisplay()));
103-
displayName.ifPresent(builder::mainDisplayName);
99+
Optional<String> displayName = extension.stream()
100+
.filter(displayExtension -> DESCRIPTION_DISPLAY.equals(displayExtension.getUrl()))
101+
.map(description -> description.getValue().toString())
102+
.findFirst()
103+
.or(() -> Optional.ofNullable(snomedCodeCoding.get().getDisplay()));
104+
displayName.ifPresent(builder::mainDisplayName);
104105

105-
if (codeableConcept.hasText()) {
106-
builder.mainOriginalText(codeableConcept.getText());
107-
}
108-
} else {
109-
var originalText = findOriginalText(codeableConcept, mainCode);
110-
originalText.ifPresent(builder::mainOriginalText);
111-
}
106+
builder.mainOriginalText(codeableConcept.getText());
112107

108+
builder.translations(getNonSnomedCodeCodings(codeableConcept));
113109
return TemplateUtils.fillTemplate(CODEABLE_CONCEPT_CD_TEMPLATE, builder.build());
114110
}
115111

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,9 @@ private static Stream<Arguments> resourceFileParams() {
131131
Arguments.of("mr-with-extension-status-reason-with-text.json", "medication-statement-with-status-reason-text.xml"),
132132
Arguments.of("mr-with-no-recorder-reference.json", "medication-statement-with-no-participant.xml"),
133133
Arguments.of("mr-with-invalid-recorder-resource-type.json", "medication-statement-with-no-participant.xml"),
134-
Arguments.of("medication-request-special-character-in-code.json", "medication-statement-with-xml-escaped-text-values.xml")
134+
Arguments.of("medication-request-special-character-in-code.json", "medication-statement-with-xml-escaped-text-values.xml"),
135+
Arguments.of("mr-referencing-medication-with-non-snomed-codes.json", "ms-with-material-coding-containing-translations.xml"),
136+
Arguments.of("mr-referencing-medication-with-no-snomed-code.json", "ms-with-material-coding-containing-null-flavor-code.xml")
135137
);
136138
}
137139

service/src/test/resources/ehr/mapper/medication_request/fhir-bundle.json

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,51 @@
2222
}
2323
}
2424
},
25+
{
26+
"resource": {
27+
"resourceType": "Medication",
28+
"id": "21",
29+
"code": {
30+
"coding": [
31+
{
32+
"system": "http://snomed.info/sct",
33+
"code": "430127000",
34+
"display": "Oral Form Oxycodone (product)"
35+
},
36+
{
37+
"system": "http://read.info/readv2",
38+
"code": "READ0",
39+
"display": "Display for Read V2"
40+
},
41+
{
42+
"system": "http://read.info/ctv3",
43+
"code": "READ1",
44+
"display": "Display for Read CTV3"
45+
}
46+
]
47+
}
48+
}
49+
},
50+
{
51+
"resource": {
52+
"resourceType": "Medication",
53+
"id": "22",
54+
"code": {
55+
"coding": [
56+
{
57+
"system": "http://read.info/readv2",
58+
"code": "READ0",
59+
"display": "Display for Read V2"
60+
},
61+
{
62+
"system": "http://read.info/ctv3",
63+
"code": "READ1",
64+
"display": "Display for Read CTV3"
65+
}
66+
]
67+
}
68+
}
69+
},
2570
{
2671
"resource": {
2772
"resourceType":"MedicationRequest",
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{
2+
"resourceType":"MedicationRequest",
3+
"id":"3377543D-5B1B-4C4F-BFF6-9F7BC3A1C3B8",
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-MedicationRepeatInformation-1",
12+
"extension": [
13+
{
14+
"url": "numberOfRepeatPrescriptionsAllowed",
15+
"valuePositiveInt": 12
16+
},
17+
{
18+
"url": "numberOfRepeatPrescriptionsIssued",
19+
"valuePositiveInt": 11
20+
}
21+
]
22+
}
23+
],
24+
"identifier":[
25+
{
26+
"system":"https://fhir.nhs.uk/Id/cross-care-setting-identifier",
27+
"value":"f2489066-7082-11eb-bb13-00505692d4aa"
28+
}
29+
],
30+
"status":"active",
31+
"intent":"order",
32+
"medicationReference":{
33+
"reference":"Medication/22"
34+
},
35+
"subject":{
36+
"reference":"Patient/2"
37+
},
38+
"authoredOn":"2017-11-10T00:00:00+00:00",
39+
"recorder":{
40+
"reference":"Practitioner/1"
41+
},
42+
"dosageInstruction":[
43+
{
44+
"text":"1 tablet once a day",
45+
"patientInstruction":"Take in morning"
46+
}
47+
],
48+
"dispenseRequest":{
49+
"validityPeriod":{
50+
"start":"2017-11-10T00:00:00+00:00",
51+
"end":"2018-08-15T00:00:00+01:00"
52+
}
53+
},
54+
"basedOn": [
55+
{
56+
"reference": "MedicationRequest/D66D84C9-C073-4EDF-8C2C-F309A83C3DC7"
57+
}
58+
]
59+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{
2+
"resourceType":"MedicationRequest",
3+
"id":"3377543D-5B1B-4C4F-BFF6-9F7BC3A1C3B8",
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-MedicationRepeatInformation-1",
12+
"extension": [
13+
{
14+
"url": "numberOfRepeatPrescriptionsAllowed",
15+
"valuePositiveInt": 12
16+
},
17+
{
18+
"url": "numberOfRepeatPrescriptionsIssued",
19+
"valuePositiveInt": 11
20+
}
21+
]
22+
}
23+
],
24+
"identifier":[
25+
{
26+
"system":"https://fhir.nhs.uk/Id/cross-care-setting-identifier",
27+
"value":"f2489066-7082-11eb-bb13-00505692d4aa"
28+
}
29+
],
30+
"status":"active",
31+
"intent":"order",
32+
"medicationReference":{
33+
"reference":"Medication/21"
34+
},
35+
"subject":{
36+
"reference":"Patient/2"
37+
},
38+
"authoredOn":"2017-11-10T00:00:00+00:00",
39+
"recorder":{
40+
"reference":"Practitioner/1"
41+
},
42+
"dosageInstruction":[
43+
{
44+
"text":"1 tablet once a day",
45+
"patientInstruction":"Take in morning"
46+
}
47+
],
48+
"dispenseRequest":{
49+
"validityPeriod":{
50+
"start":"2017-11-10T00:00:00+00:00",
51+
"end":"2018-08-15T00:00:00+01:00"
52+
}
53+
},
54+
"basedOn": [
55+
{
56+
"reference": "MedicationRequest/D66D84C9-C073-4EDF-8C2C-F309A83C3DC7"
57+
}
58+
]
59+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<component typeCode="COMP">
2+
<MedicationStatement classCode="SBADM" moodCode="ORD">
3+
<id root="394559384658936"/>
4+
<statusCode code="ACTIVE"/>
5+
<effectiveTime>
6+
<low value="20171110000000"/><high value="20180815000000"/>
7+
</effectiveTime>
8+
<availabilityTime value="20171110000000"/>
9+
<consumable typeCode="CSM">
10+
<manufacturedProduct classCode="MANU">
11+
<manufacturedMaterial determinerCode="KIND" classCode="MMAT">
12+
<code nullFlavor="UNK">
13+
<originalText>Display for Read V2</originalText>
14+
</code>
15+
</manufacturedMaterial>
16+
</manufacturedProduct>
17+
</consumable>
18+
<component typeCode="COMP">
19+
<ehrSupplyPrescribe>
20+
<id root="394559384658936"/>
21+
<code code="394823007" displayName="NHS Prescription" codeSystem="2.16.840.1.113883.2.1.3.2.4.15"/>
22+
<statusCode code="ACTIVE"/>
23+
<availabilityTime value="20171110000000"/>
24+
<quantity value="1" unit="1">
25+
<translation value="1">
26+
<originalText>Unk UoM</originalText>
27+
</translation>
28+
</quantity>
29+
<inFulfillmentOf typeCode="FLFS">
30+
<priorMedicationRef moodCode="INT">
31+
<id root="394559384658936"/>
32+
</priorMedicationRef>
33+
</inFulfillmentOf>
34+
<pertinentInformation typeCode="PERT">
35+
<pertinentSupplyAnnotation>
36+
<text>Patient Instruction: Take in morning</text>
37+
</pertinentSupplyAnnotation>
38+
</pertinentInformation>
39+
</ehrSupplyPrescribe>
40+
</component>
41+
<pertinentInformation typeCode="PERT">
42+
<pertinentMedicationDosage classCode="SBADM" moodCode="RMD">
43+
<text>1 tablet once a day</text>
44+
</pertinentMedicationDosage>
45+
</pertinentInformation>
46+
<Participant typeCode="AUT" contextControlCode="OP">
47+
<agentRef classCode="AGNT">
48+
<id root="394559384658936"/>
49+
</agentRef>
50+
</Participant>
51+
</MedicationStatement>
52+
</component>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<component typeCode="COMP">
2+
<MedicationStatement classCode="SBADM" moodCode="ORD">
3+
<id root="394559384658936"/>
4+
<statusCode code="ACTIVE"/>
5+
<effectiveTime>
6+
<low value="20171110000000"/><high value="20180815000000"/>
7+
</effectiveTime>
8+
<availabilityTime value="20171110000000"/>
9+
<consumable typeCode="CSM">
10+
<manufacturedProduct classCode="MANU">
11+
<manufacturedMaterial determinerCode="KIND" classCode="MMAT">
12+
<code code="430127000" codeSystem="2.16.840.1.113883.2.1.3.2.4.15" displayName="Oral Form Oxycodone (product)">
13+
<translation code="READ0" codeSystem="2.16.840.1.113883.2.1.6.2" displayName="Display for Read V2" />
14+
<translation code="READ1" codeSystem="2.16.840.1.113883.2.1.3.2.4.14" displayName="Display for Read CTV3" />
15+
</code>
16+
</manufacturedMaterial>
17+
</manufacturedProduct>
18+
</consumable>
19+
<component typeCode="COMP">
20+
<ehrSupplyPrescribe>
21+
<id root="394559384658936"/>
22+
<code code="394823007" displayName="NHS Prescription" codeSystem="2.16.840.1.113883.2.1.3.2.4.15"/>
23+
<statusCode code="ACTIVE"/>
24+
<availabilityTime value="20171110000000"/>
25+
<quantity value="1" unit="1">
26+
<translation value="1">
27+
<originalText>Unk UoM</originalText>
28+
</translation>
29+
</quantity>
30+
<inFulfillmentOf typeCode="FLFS">
31+
<priorMedicationRef moodCode="INT">
32+
<id root="394559384658936"/>
33+
</priorMedicationRef>
34+
</inFulfillmentOf>
35+
<pertinentInformation typeCode="PERT">
36+
<pertinentSupplyAnnotation>
37+
<text>Patient Instruction: Take in morning</text>
38+
</pertinentSupplyAnnotation>
39+
</pertinentInformation>
40+
</ehrSupplyPrescribe>
41+
</component>
42+
<pertinentInformation typeCode="PERT">
43+
<pertinentMedicationDosage classCode="SBADM" moodCode="RMD">
44+
<text>1 tablet once a day</text>
45+
</pertinentMedicationDosage>
46+
</pertinentInformation>
47+
<Participant typeCode="AUT" contextControlCode="OP">
48+
<agentRef classCode="AGNT">
49+
<id root="394559384658936"/>
50+
</agentRef>
51+
</Participant>
52+
</MedicationStatement>
53+
</component>

0 commit comments

Comments
 (0)