Skip to content

Commit 93bfb69

Browse files
NIAD-3304: Add non-snomed code mapping to translations when mapping CodeableConcepts
* Remove unnecessary non-snomed code systems from test files as the functionality has changed and are testing in a separate test * Update `CodeableConceptCdTemplateParameters` to include a property for translations. * Update `codeable_concept_cd_template.mustache` to handle translations. * Add test to ensure that non-snomed codes are populated as translations in the produced XML when a SNOMEDCT code is present. * Add functionality to `CodeableConceptCdMapper` to populate translations in the XML when non-SNOMEDCT codes have been provided alongside the SNOMEDCT Code.
1 parent c622cc3 commit 93bfb69

File tree

8 files changed

+94
-46
lines changed

8 files changed

+94
-46
lines changed

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

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import lombok.RequiredArgsConstructor;
1818
import lombok.extern.slf4j.Slf4j;
1919
import uk.nhs.adaptors.gp2gp.ehr.mapper.parameters.CodeableConceptCdTemplateParameters;
20+
import uk.nhs.adaptors.gp2gp.ehr.utils.CodeSystemsUtil;
2021
import uk.nhs.adaptors.gp2gp.ehr.utils.CodeableConceptMappingUtils;
2122
import uk.nhs.adaptors.gp2gp.ehr.utils.TemplateUtils;
2223

@@ -63,18 +64,17 @@ public String mapCodeableConceptToCd(CodeableConcept codeableConcept) {
6364

6465
builder.mainCodeSystem(SNOMED_SYSTEM_CODE);
6566

66-
if (descriptionExtensions.isPresent()) {
67-
var mainCode = getMainCode(descriptionExtensions.get(), snomedCodeCoding.get());
68-
mainCode.ifPresent(builder::mainCode);
67+
var mainCode = getMainCode(descriptionExtensions, snomedCodeCoding.get());
68+
mainCode.ifPresent(builder::mainCode);
6969

70-
var mainDisplayName = getMainDisplayName(descriptionExtensions.get(), snomedCodeCoding.get());
71-
mainDisplayName.ifPresent(builder::mainDisplayName);
70+
var mainDisplayName = getMainDisplayName(descriptionExtensions, snomedCodeCoding.get());
71+
mainDisplayName.ifPresent(builder::mainDisplayName);
7272

73-
if (codeableConcept.hasText()) {
74-
builder.mainOriginalText(codeableConcept.getText());
75-
}
73+
if (codeableConcept.hasText()) {
74+
builder.mainOriginalText(codeableConcept.getText());
7675
}
7776

77+
addNonSnomedCodeTranslationsToTemplateParametersBuilder(codeableConcept, builder);
7878
return TemplateUtils.fillTemplate(CODEABLE_CONCEPT_CD_TEMPLATE, builder.build());
7979
}
8080

@@ -329,6 +329,20 @@ private Optional<Coding> getSnomedCodeCoding(CodeableConcept codeableConcept) {
329329
.findFirst();
330330
}
331331

332+
private List<Coding> getNonSnomedCodeCodings(CodeableConcept codeableConcept) {
333+
var nonSnomedCodeCodings = codeableConcept.getCoding()
334+
.stream()
335+
.filter(coding -> !isSnomed(coding))
336+
.toList();
337+
338+
for (Coding coding : nonSnomedCodeCodings) {
339+
var hl7CodeSystem = CodeSystemsUtil.getHl7code(coding.getSystem());
340+
coding.setSystem(hl7CodeSystem);
341+
}
342+
343+
return nonSnomedCodeCodings;
344+
}
345+
332346
private Optional<String> findOriginalText(CodeableConcept codeableConcept, Optional<Coding> coding) {
333347
if (coding.isPresent()) {
334348
if (codeableConcept.hasText()) {
@@ -457,30 +471,43 @@ private String buildNullFlavourCodeableConceptCd(CodeableConcept codeableConcept
457471
return TemplateUtils.fillTemplate(CODEABLE_CONCEPT_CD_TEMPLATE, builder.build());
458472
}
459473

460-
private Optional<String> getMainCode(List<Extension> descriptionExtensions, Coding snomedCodeCoding) {
461-
var descriptionCode = descriptionExtensions.stream()
462-
.filter(descriptionExt -> DESCRIPTION_ID.equals(descriptionExt.getUrl()))
463-
.map(description -> description.getValue().toString())
464-
.findFirst();
474+
private Optional<String> getMainCode(Optional<List<Extension>> descriptionExtensions, Coding snomedCodeCoding) {
475+
if (descriptionExtensions.isPresent()) {
476+
var descriptionCode = descriptionExtensions.get().stream()
477+
.filter(descriptionExt -> DESCRIPTION_ID.equals(descriptionExt.getUrl()))
478+
.map(description -> description.getValue().toString())
479+
.findFirst();
465480

466-
if (descriptionCode.isPresent()) {
467-
return descriptionCode;
481+
if (descriptionCode.isPresent()) {
482+
return descriptionCode;
483+
}
468484
}
469485

470486
return Optional.ofNullable(snomedCodeCoding.getCode());
471487
}
472488

473-
private Optional<String> getMainDisplayName(List<Extension> descriptionExtensions, Coding snomedCodeCoding) {
474-
var descriptionDisplayName = descriptionExtensions.stream()
475-
.filter(descriptionExt -> DESCRIPTION_DISPLAY.equals(descriptionExt.getUrl()))
476-
.map(description -> description.getValue().toString())
477-
.findFirst();
489+
private Optional<String> getMainDisplayName(Optional<List<Extension>> descriptionExtensions, Coding snomedCodeCoding) {
490+
if (descriptionExtensions.isPresent()) {
491+
var descriptionDisplayName = descriptionExtensions.get().stream()
492+
.filter(descriptionExt -> DESCRIPTION_DISPLAY.equals(descriptionExt.getUrl()))
493+
.map(description -> description.getValue().toString())
494+
.findFirst();
478495

479-
if (descriptionDisplayName.isPresent()) {
480-
return descriptionDisplayName;
496+
if (descriptionDisplayName.isPresent()) {
497+
return descriptionDisplayName;
498+
}
481499
}
482500

483501
return Optional.ofNullable(snomedCodeCoding.getDisplay());
484502
}
485503

504+
private void addNonSnomedCodeTranslationsToTemplateParametersBuilder(
505+
CodeableConcept codeableConcept,
506+
CodeableConceptCdTemplateParameters.CodeableConceptCdTemplateParametersBuilder builder
507+
) {
508+
var nonSnomedCodeCodings = getNonSnomedCodeCodings(codeableConcept);
509+
if (!nonSnomedCodeCodings.isEmpty()) {
510+
builder.translations(nonSnomedCodeCodings);
511+
}
512+
}
486513
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
import lombok.Builder;
44
import lombok.Getter;
55
import lombok.Setter;
6+
import org.hl7.fhir.dstu3.model.Coding;
7+
8+
import java.util.List;
69

710
@Getter
811
@Setter
@@ -12,5 +15,6 @@ public class CodeableConceptCdTemplateParameters {
1215
private String mainCodeSystem;
1316
private String mainDisplayName;
1417
private String mainOriginalText;
18+
private List<Coding> translations;
1519
private boolean nullFlavor;
1620
}

service/src/main/resources/templates/codeable_concept_cd_template.mustache

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
<code{{#nullFlavor}} nullFlavor="UNK"{{/nullFlavor}}{{^nullFlavor}} code="{{mainCode}}" codeSystem="{{mainCodeSystem}}" displayName="{{mainDisplayName}}"{{/nullFlavor}}>
2+
{{#translations}}
3+
<translation code="{{code}}" codeSystem="{{system}}" displayName="{{display}}" />
4+
{{/translations}}
25
{{#mainOriginalText}}
36
<originalText>{{mainOriginalText}}</originalText>
47
{{/mainOriginalText}}

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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,43 @@ public void When_MappingStubbedCodeableConcept_Expect_HL7CdObjectXml(String inpu
8585
.isEqualToIgnoringWhitespace(expectedOutput);
8686
}
8787

88+
@Test
89+
void When_MappingCodeableConceptWithNonSnomedCodeSystems_Expect_ManifestedXmlContainsTranslationsForThoseCodes() {
90+
var inputJson = """
91+
{
92+
"resourceType" : "Observation",
93+
"code": {
94+
"coding": [
95+
{
96+
"system": "http://snomed.info/sct",
97+
"code": "123456",
98+
"display": "Endometriosis of uterus"
99+
},
100+
{
101+
"system": "http://read.info/readv2",
102+
"code": "READ0",
103+
"display": "Read V2 Code Display"
104+
},
105+
{
106+
"system": "http://read.info/ctv3",
107+
"code": "READ1",
108+
"display": "Read CTV3 Code Display"
109+
}
110+
]
111+
}
112+
}""";
113+
var expectedOutputXml = """
114+
<code code="123456" codeSystem="2.16.840.1.113883.2.1.3.2.4.15" displayName="Endometriosis of uterus">
115+
<translation code="READ0" codeSystem="2.16.840.1.113883.2.1.6.2" displayName="Read V2 Code Display" />
116+
<translation code="READ1" codeSystem="2.16.840.1.113883.2.1.3.2.4.14" displayName="Read CTV3 Code Display" />
117+
</code>""";
118+
var codeableConcept = fhirParseService.parseResource(inputJson, Observation.class).getCode();
119+
120+
var outputMessageXml = codeableConceptCdMapper.mapCodeableConceptToCd(codeableConcept);
121+
122+
assertThat(outputMessageXml).isEqualToIgnoringWhitespace(expectedOutputXml);
123+
}
124+
88125
@ParameterizedTest
89126
@MethodSource("getTestArgumentsActualProblem")
90127
public void When_MappingStubbedCodeableConceptForActualProblemHeader_Expect_HL7CdObjectXml(String inputJson, String outputXml)

service/src/test/resources/ehr/mapper/codeableconcept/codeable_concept_snomed_with_description.json

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,6 @@
22
"resourceType" : "Observation",
33
"code": {
44
"coding": [
5-
{
6-
"system": "http://blah.info/blahsomecodesystem",
7-
"code": "X%^^%",
8-
"display": "Display for invalid code/system",
9-
"userSelected": true
10-
},
115
{
126
"extension": [
137
{

service/src/test/resources/ehr/mapper/codeableconcept/codeable_concept_snomed_with_no_description.json

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,6 @@
22
"resourceType" : "Observation",
33
"code": {
44
"coding": [
5-
{
6-
"system": "http://blah.info/blahsomecodesystem",
7-
"code": "X%^^%",
8-
"display": "Display for invalid code/system",
9-
"userSelected": true
10-
},
115
{
126
"extension": [
137
{

service/src/test/resources/ehr/mapper/codeableconcept/codeable_concept_with_text.json

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,6 @@
22
"resourceType" : "Observation",
33
"code": {
44
"coding": [
5-
{
6-
"system": "http://blah.info/blahsomecodesystem",
7-
"code": "X%^^%",
8-
"display": "Display for invalid code/system",
9-
"userSelected": true
10-
},
115
{
126
"extension": [
137
{

service/src/test/resources/ehr/mapper/codeableconcept/codeable_concept_without_text.json

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,7 @@
22
"resourceType" : "Observation",
33
"code": {
44
"coding": [
5-
{
6-
"system": "http://blah.info/blahsomecodesystem",
7-
"code": "F%^^%",
8-
"display": "Happy puppet syndrome",
9-
"userSelected": true
10-
}, {
5+
{
116
"extension": [
127
{
138
"url": "https://fhir.nhs.uk/STU3/StructureDefinition/Extension-coding-sctdescid",

0 commit comments

Comments
 (0)