From 47f0576de5ba219dea4e8506968ad01b7af06a93 Mon Sep 17 00:00:00 2001 From: MartinWheelerMT Date: Wed, 5 Mar 2025 13:55:35 +0000 Subject: [PATCH 1/6] Refactor `CodeableConceptCdMapper` * Refactor `mapCodeableConceptForMedication` and `mapCodeableConceptToCd` to reduce code duplication. * Refactor `mapCodeableConceptToCdForAllergy` for readability --- .../ehr/mapper/CodeableConceptCdMapper.java | 214 +++++++++--------- 1 file changed, 104 insertions(+), 110 deletions(-) diff --git a/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapper.java b/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapper.java index 4a9efea3a..89ba6a5ff 100644 --- a/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapper.java +++ b/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapper.java @@ -3,6 +3,7 @@ import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.function.BiFunction; import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.dstu3.model.AllergyIntolerance; @@ -51,10 +52,23 @@ public class CodeableConceptCdMapper { private static final String OTHER_CATEGORY_DESCRIPTION = "Other category"; public String mapCodeableConceptToCd(CodeableConcept codeableConcept) { + return mapCodeableConcept(codeableConcept, this::getMainCode); + } + + public String mapCodeableConceptForMedication(CodeableConcept codeableConcept) { + return mapCodeableConcept( + codeableConcept, + (descriptionExtensions, snomedCodeCoding) -> Optional.ofNullable(snomedCodeCoding.getCode())); + } + + private String mapCodeableConcept( + CodeableConcept codeableConcept, + BiFunction>, Coding, Optional> getMainCodeFunction + ) { Optional snomedCodeCoding = getSnomedCodeCoding(codeableConcept); if (snomedCodeCoding.isEmpty()) { - return buildNullFlavourCodeableConceptCd(codeableConcept, snomedCodeCoding); + return mapToNullFlavorCodeableConcept(codeableConcept); } var builder = CodeableConceptCdTemplateParameters.builder(); @@ -64,87 +78,60 @@ public String mapCodeableConceptToCd(CodeableConcept codeableConcept) { builder.mainCodeSystem(SNOMED_SYSTEM_CODE); - var mainCode = getMainCode(descriptionExtensions, snomedCodeCoding.get()); - mainCode.ifPresent(builder::mainCode); - var mainDisplayName = getMainDisplayName(descriptionExtensions, snomedCodeCoding.get()); mainDisplayName.ifPresent(builder::mainDisplayName); builder.mainOriginalText(codeableConcept.getText()); builder.translations(getNonSnomedCodeCodings(codeableConcept)); + var mainCode = getMainCodeFunction.apply(descriptionExtensions, snomedCodeCoding.get()); + mainCode.ifPresent(builder::mainCode); + return TemplateUtils.fillTemplate(CODEABLE_CONCEPT_CD_TEMPLATE, builder.build()); } - // Medications are currently using D&T Codes rather than snomed codes but are being passed through as SNOMED codes which is - // creating a degradation on the receiving side. Until the types are configured correctly and agreed to a specification - // we have agreed to use the Concept ID rather than Description Id for medications which will avoided the degradation. - public String mapCodeableConceptForMedication(CodeableConcept codeableConcept) { + public String mapCodeableConceptToCdForAllergy( + CodeableConcept codeableConcept, + AllergyIntolerance.AllergyIntoleranceClinicalStatus allergyIntoleranceClinicalStatus + ) { var builder = CodeableConceptCdTemplateParameters.builder(); - var snomedCodeCoding = getSnomedCodeCoding(codeableConcept); + Optional snomedCodeCoding = getSnomedCodeCoding(codeableConcept); if (snomedCodeCoding.isEmpty()) { - return buildNullFlavourCodeableConceptCd(codeableConcept, snomedCodeCoding); + builder.nullFlavor(true); + return TemplateUtils.fillTemplate(CODEABLE_CONCEPT_CD_TEMPLATE, builder.build()); } - var extension = retrieveDescriptionExtension(snomedCodeCoding.get()) - .map(Extension::getExtension) - .orElse(Collections.emptyList()); - - builder.mainCodeSystem(SNOMED_SYSTEM_CODE); - - Optional code = Optional.ofNullable(snomedCodeCoding.get().getCode()); - code.ifPresent(builder::mainCode); + if (ACTIVE_CLINICAL_STATUS.equals(allergyIntoleranceClinicalStatus.toCode())) { + builder.mainCodeSystem(SNOMED_SYSTEM_CODE); + } else { + builder.nullFlavor(true); + } - Optional displayName = extension.stream() - .filter(displayExtension -> DESCRIPTION_DISPLAY.equals(displayExtension.getUrl())) - .map(description -> description.getValue().toString()) - .findFirst() - .or(() -> Optional.ofNullable(snomedCodeCoding.get().getDisplay())); - displayName.ifPresent(builder::mainDisplayName); + getAllergyMainCode(snomedCodeCoding.get()).ifPresent(builder::mainCode); + getCodingDisplayName(snomedCodeCoding.get()).ifPresent(builder::mainDisplayName); - builder.mainOriginalText(codeableConcept.getText()); + if (codeableConcept.hasText()) { + builder.mainOriginalText(codeableConcept.getText()); + } else { + var originalText = findOriginalTextForAllergy(codeableConcept, snomedCodeCoding, allergyIntoleranceClinicalStatus); + originalText.ifPresent(builder::mainOriginalText); + } - builder.translations(getNonSnomedCodeCodings(codeableConcept)); return TemplateUtils.fillTemplate(CODEABLE_CONCEPT_CD_TEMPLATE, builder.build()); } - public String mapCodeableConceptToCdForAllergy(CodeableConcept codeableConcept, AllergyIntolerance.AllergyIntoleranceClinicalStatus - allergyIntoleranceClinicalStatus) { - var builder = CodeableConceptCdTemplateParameters.builder(); - var mainCode = getSnomedCodeCoding(codeableConcept); - - builder.nullFlavor(mainCode.isEmpty()); - - if (mainCode.isPresent()) { - var extension = retrieveDescriptionExtension(mainCode.get()) - .map(Extension::getExtension) - .orElse(Collections.emptyList()); - - if (ACTIVE_CLINICAL_STATUS.equals(allergyIntoleranceClinicalStatus.toCode())) { - builder.mainCodeSystem(SNOMED_SYSTEM_CODE); - } else { - builder.nullFlavor(true); - } + private static Optional getCodingDisplayName(Coding snomedCodeCoding) { + return Optional.ofNullable(snomedCodeCoding.getDisplay()); + } - Optional code = extension.stream() + private static Optional getAllergyMainCode(Coding snomedCodeCoding) { + return retrieveDescriptionExtension(snomedCodeCoding) + .flatMap(extension -> extension.getExtension().stream() .filter(descriptionExt -> DESCRIPTION_ID.equals(descriptionExt.getUrl())) - .map(description -> description.getValue().toString()) .findFirst() - .or(() -> Optional.ofNullable(mainCode.get().getCode())); - code.ifPresent(builder::mainCode); - - Optional displayName = Optional.ofNullable(mainCode.get().getDisplay()); - displayName.ifPresent(builder::mainDisplayName); - - if (codeableConcept.hasText()) { - builder.mainOriginalText(codeableConcept.getText()); - } else { - var originalText = findOriginalTextForAllergy(codeableConcept, mainCode, allergyIntoleranceClinicalStatus); - originalText.ifPresent(builder::mainOriginalText); - } - } - return TemplateUtils.fillTemplate(CODEABLE_CONCEPT_CD_TEMPLATE, builder.build()); + .map(description -> description.getValue().toString())) + .or(() -> Optional.ofNullable(snomedCodeCoding.getCode())); } public String mapCodeableConceptToCdForTransformedActualProblemHeader(CodeableConcept codeableConcept) { @@ -343,7 +330,7 @@ private Optional findOriginalText(CodeableConcept codeableConcept, Optio return Optional.ofNullable(codeableConcept.getText()); } else { if (coding.get().hasDisplay()) { - return Optional.ofNullable(coding.get().getDisplay()); + return getCodingDisplayName(coding.get()); } else { var extension = retrieveDescriptionExtension(coding.get()); return extension.stream() @@ -362,52 +349,69 @@ private Optional findOriginalTextForAllergy( Optional coding, AllergyIntolerance.AllergyIntoleranceClinicalStatus allergyIntoleranceClinicalStatus ) { + if (coding.isEmpty()) { + return Optional.empty(); + } + if (!allergyIntoleranceClinicalStatus.toCode().isEmpty()) { if (RESOLVED_CLINICAL_STATUS.equals(allergyIntoleranceClinicalStatus.toCode())) { - if (coding.isPresent()) { - if (codeableConcept.hasText()) { - return Optional.ofNullable(codeableConcept.getText()); - } else { - var extension = retrieveDescriptionExtension(coding.get()); - if (extension.isPresent()) { - Optional originalText = extension - .get() - .getExtension().stream() - .filter(displayExtension -> DESCRIPTION_DISPLAY.equals(displayExtension.getUrl())) - .map(extension1 -> extension1.getValue().toString()) - .findFirst(); - - if (originalText.isPresent()) { - return originalText; - } else if (coding.get().hasDisplay()) { - return Optional.ofNullable(coding.get().getDisplay()); - } - } else if (coding.get().hasDisplay()) { - return Optional.ofNullable(coding.get().getDisplay()); - } - } - } - } else if (ACTIVE_CLINICAL_STATUS.equals(allergyIntoleranceClinicalStatus.toCode())) { - Optional extension = retrieveDescriptionExtension(coding.get()); - if (extension.isPresent()) { - Optional originalText = extension - .get() - .getExtension().stream() - .filter(displayExtension -> DESCRIPTION_DISPLAY.equals(displayExtension.getUrl())) - .map(extension1 -> extension1.getValue().toString()) - .findFirst(); - if (originalText.isPresent() && StringUtils.isNotBlank(originalText.get())) { - return originalText; - } - } - - return Optional.empty(); + return getOriginalTextForResolvedAllergy(codeableConcept, coding.get()); + } + if (ACTIVE_CLINICAL_STATUS.equals(allergyIntoleranceClinicalStatus.toCode())) { + return getOriginalTextForActiveAllergy(coding.get()); } } return CodeableConceptMappingUtils.extractTextOrCoding(codeableConcept); } + private Optional getOriginalTextForActiveAllergy(Coding coding) { + Optional extension = retrieveDescriptionExtension(coding); + + if (extension.isPresent()) { + Optional originalText = extension + .get() + .getExtension().stream() + .filter(displayExtension -> DESCRIPTION_DISPLAY.equals(displayExtension.getUrl())) + .map(extension1 -> extension1.getValue().toString()) + .findFirst(); + if (originalText.isPresent()) { + return originalText; + } + } + + return Optional.empty(); + } + + private Optional getOriginalTextForResolvedAllergy(CodeableConcept codeableConcept, Coding coding) { + + if (codeableConcept.hasText()) { + return Optional.ofNullable(codeableConcept.getText()); + } + + var extension = retrieveDescriptionExtension(coding); + if (extension.isEmpty()) { + return coding.hasDisplay() + ? Optional.ofNullable(coding.getDisplay()) + : Optional.empty(); + } + + Optional originalText = extension + .get() + .getExtension().stream() + .filter(displayExtension -> DESCRIPTION_DISPLAY.equals(displayExtension.getUrl())) + .map(extension1 -> extension1.getValue().toString()) + .findFirst(); + + if (originalText.isPresent()) { + return originalText; + } else if (coding.hasDisplay()) { + return Optional.ofNullable(coding.getDisplay()); + } + + return Optional.empty(); + } + private Optional findDisplayText(Coding coding) { return Optional.ofNullable(coding.getDisplay()); } @@ -420,7 +424,7 @@ private boolean isPrescribingAgency(Coding coding) { return coding.hasSystem() && coding.getSystem().equals(CARE_CONNECT_PRESCRIBING_AGENCY_SYSTEM); } - private Optional retrieveDescriptionExtension(Coding coding) { + private static Optional retrieveDescriptionExtension(Coding coding) { return coding .getExtension() .stream() @@ -435,7 +439,6 @@ public String getDisplayFromCodeableConcept(CodeableConcept codeableConcept) { } public String mapToNullFlavorCodeableConcept(CodeableConcept codeableConcept) { - var builder = CodeableConceptCdTemplateParameters.builder().nullFlavor(true); var mainCode = getSnomedCodeCoding(codeableConcept); @@ -456,15 +459,6 @@ public String mapToNullFlavorCodeableConceptForAllergy( return TemplateUtils.fillTemplate(CODEABLE_CONCEPT_CD_TEMPLATE, builder.build()); } - private String buildNullFlavourCodeableConceptCd(CodeableConcept codeableConcept, Optional snomedCode) { - var builder = CodeableConceptCdTemplateParameters.builder(); - builder.nullFlavor(true); - var originalText = findOriginalText(codeableConcept, snomedCode); - originalText.ifPresent(builder::mainOriginalText); - - return TemplateUtils.fillTemplate(CODEABLE_CONCEPT_CD_TEMPLATE, builder.build()); - } - private Optional getMainCode(Optional> descriptionExtensions, Coding snomedCodeCoding) { if (descriptionExtensions.isPresent()) { var descriptionCode = descriptionExtensions.get().stream() @@ -494,4 +488,4 @@ private Optional getMainDisplayName(Optional> descriptio return Optional.ofNullable(snomedCodeCoding.getDisplay()); } -} +} \ No newline at end of file From 29a707261a78865c1bbb6949ce42201a2c2e86c3 Mon Sep 17 00:00:00 2001 From: MartinWheelerMT Date: Wed, 5 Mar 2025 14:49:43 +0000 Subject: [PATCH 2/6] * Add a test case when mapping to nullFlavor codeable concept for allergy when a snomed code is not present. --- .../mapper/CodeableConceptCdMapperTest.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapperTest.java b/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapperTest.java index e0ee74097..126e7659f 100644 --- a/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapperTest.java +++ b/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapperTest.java @@ -127,6 +127,46 @@ void When_MappingCodeableConceptWithNonSnomedCodeSystems_Expect_ManifestedXmlCon assertThat(outputMessageXml).isEqualToIgnoringWhitespace(expectedOutputXml); } + + @Test + void When_mapToNullFlavorCodeableConceptForAllergyWithoutSnomedCode_ExpectOriginalTextIsNotPresent() { + var inputJson = """ + { + "resourceType": "AllergyIntolerance", + "id": "0C1232CF-D34B-4C16-A5F4-0F6461C51A41", + "meta": { + "profile": [ + "https://fhir.nhs.uk/STU3/StructureDefinition/CareConnect-GPC-AllergyIntolerance-1" + ] + }, + "identifier": [ + { + "system": "https://EMISWeb/A82038", + "value": "55D2363D57A248F49A745B2E03F5E93D0C1232CFD34B4C16A5F40F6461C51A41" + } + ], + "code": { + "coding": [ + { + "system": "http://read.info/readv2", + "code": "TJ00800", + "display": "Adverse reaction to pivampicillin rt" + } + ], + "text": "Adverse reaction to pivampicillin" + } + }"""; + var expectedOutputXML = """ + + + """; + var codeableConcept = fhirParseService.parseResource(inputJson, AllergyIntolerance.class).getCode(); + + var outputXml = codeableConceptCdMapper.mapToNullFlavorCodeableConceptForAllergy(codeableConcept, AllergyIntolerance.AllergyIntoleranceClinicalStatus.ACTIVE); + + assertThat(outputXml).isEqualToIgnoringWhitespace(expectedOutputXML); + } + @ParameterizedTest @MethodSource("getTestArgumentsActualProblem") public void When_MappingStubbedCodeableConceptForActualProblemHeader_Expect_HL7CdObjectXml(String inputJson, String outputXml) @@ -271,4 +311,5 @@ public void When_MapToCdForMedication_With_RelatedProblemAndTitle_Expect_Concept assertThat(outputString).isEqualToIgnoringWhitespace(expectedOutput); } + } \ No newline at end of file From 44d8756b3c205322bdfb632c035f08416dba7880 Mon Sep 17 00:00:00 2001 From: MartinWheelerMT Date: Wed, 5 Mar 2025 15:21:45 +0000 Subject: [PATCH 3/6] * Add unit test to handle the case where an allergy intolerance is neither ACTIVE nor RESOLVED. * Remove unnecessary nesting in `findOriginalTextForAllergy` as the equals already handles case where it is not present. --- .../ehr/mapper/CodeableConceptCdMapper.java | 12 ++--- .../mapper/CodeableConceptCdMapperTest.java | 53 +++++++++++++++++-- 2 files changed, 55 insertions(+), 10 deletions(-) diff --git a/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapper.java b/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapper.java index 89ba6a5ff..cc787aec8 100644 --- a/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapper.java +++ b/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapper.java @@ -353,13 +353,11 @@ private Optional findOriginalTextForAllergy( return Optional.empty(); } - if (!allergyIntoleranceClinicalStatus.toCode().isEmpty()) { - if (RESOLVED_CLINICAL_STATUS.equals(allergyIntoleranceClinicalStatus.toCode())) { - return getOriginalTextForResolvedAllergy(codeableConcept, coding.get()); - } - if (ACTIVE_CLINICAL_STATUS.equals(allergyIntoleranceClinicalStatus.toCode())) { - return getOriginalTextForActiveAllergy(coding.get()); - } + if (RESOLVED_CLINICAL_STATUS.equals(allergyIntoleranceClinicalStatus.toCode())) { + return getOriginalTextForResolvedAllergy(codeableConcept, coding.get()); + } + if (ACTIVE_CLINICAL_STATUS.equals(allergyIntoleranceClinicalStatus.toCode())) { + return getOriginalTextForActiveAllergy(coding.get()); } return CodeableConceptMappingUtils.extractTextOrCoding(codeableConcept); diff --git a/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapperTest.java b/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapperTest.java index 126e7659f..a107a1e9a 100644 --- a/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapperTest.java +++ b/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapperTest.java @@ -127,9 +127,8 @@ void When_MappingCodeableConceptWithNonSnomedCodeSystems_Expect_ManifestedXmlCon assertThat(outputMessageXml).isEqualToIgnoringWhitespace(expectedOutputXml); } - @Test - void When_mapToNullFlavorCodeableConceptForAllergyWithoutSnomedCode_ExpectOriginalTextIsNotPresent() { + void When_MapToNullFlavorCodeableConceptForAllergyWithoutSnomedCode_Expect_OriginalTextIsNotPresent() { var inputJson = """ { "resourceType": "AllergyIntolerance", @@ -162,11 +161,59 @@ void When_mapToNullFlavorCodeableConceptForAllergyWithoutSnomedCode_ExpectOrigin """; var codeableConcept = fhirParseService.parseResource(inputJson, AllergyIntolerance.class).getCode(); - var outputXml = codeableConceptCdMapper.mapToNullFlavorCodeableConceptForAllergy(codeableConcept, AllergyIntolerance.AllergyIntoleranceClinicalStatus.ACTIVE); + var outputXml = codeableConceptCdMapper.mapToNullFlavorCodeableConceptForAllergy( + codeableConcept, + AllergyIntolerance.AllergyIntoleranceClinicalStatus.ACTIVE + ); assertThat(outputXml).isEqualToIgnoringWhitespace(expectedOutputXML); } + @Test + void When_MappingStubbedCodeableConceptAsInactiveAllergy_Expect_NullFlavourCodeableConceptWithOriginalTextAsDisplayName() { + var inputJson = """ + { + "resourceType": "AllergyIntolerance", + "id": "0C1232CF-D34B-4C16-A5F4-0F6461C51A41", + "meta": { + "profile": [ + "https://fhir.nhs.uk/STU3/StructureDefinition/CareConnect-GPC-AllergyIntolerance-1" + ] + }, + "identifier": [ + { + "system": "https://EMISWeb/A82038", + "value": "55D2363D57A248F49A745B2E03F5E93D0C1232CFD34B4C16A5F40F6461C51A41" + } + ], + "clinicalStatus": "inactive", + "code": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "292971006", + "display": "Pivampicillin adverse reaction pt" + } + ] + } + }"""; + + var expectedOutputXML = """ + + Pivampicillin adverse reaction pt + + """; + var codeableConcept = fhirParseService.parseResource(inputJson, AllergyIntolerance.class).getCode(); + + var outputXml = codeableConceptCdMapper.mapToNullFlavorCodeableConceptForAllergy( + codeableConcept, + AllergyIntolerance.AllergyIntoleranceClinicalStatus.INACTIVE + ); + + assertThat(outputXml).isEqualToIgnoringWhitespace(expectedOutputXML); + + } + @ParameterizedTest @MethodSource("getTestArgumentsActualProblem") public void When_MappingStubbedCodeableConceptForActualProblemHeader_Expect_HL7CdObjectXml(String inputJson, String outputXml) From f78bd685ff3fc7dcb99c9ebc1991216ece501053 Mon Sep 17 00:00:00 2001 From: MartinWheelerMT Date: Wed, 5 Mar 2025 15:40:29 +0000 Subject: [PATCH 4/6] * Remove check for `resolved` clinical status as call to method `getOriginalTextForActiveAllergy` yields as the fallback method contains the exact same functionality. --- .../ehr/mapper/CodeableConceptCdMapper.java | 33 ------------------- 1 file changed, 33 deletions(-) diff --git a/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapper.java b/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapper.java index cc787aec8..2e326ae8a 100644 --- a/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapper.java +++ b/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapper.java @@ -38,7 +38,6 @@ public class CodeableConceptCdMapper { private static final String FIXED_ACTUAL_PROBLEM_CODE = "55607006"; private static final String PROBLEM_DISPLAY_NAME = "Problem"; private static final String ACTIVE_CLINICAL_STATUS = "active"; - private static final String RESOLVED_CLINICAL_STATUS = "resolved"; private static final String PRESCRIBING_AGENCY_GP_PRACTICE_CODE = "prescribed-at-gp-practice"; private static final String PRESCRIBING_AGENCY_PREVIOUS_PRACTICE_CODE = "prescribed-by-previous-practice"; private static final String PRESCRIBING_AGENCY_ANOTHER_ORGANISATION_CODE = "prescribed-by-another-organisation"; @@ -353,9 +352,6 @@ private Optional findOriginalTextForAllergy( return Optional.empty(); } - if (RESOLVED_CLINICAL_STATUS.equals(allergyIntoleranceClinicalStatus.toCode())) { - return getOriginalTextForResolvedAllergy(codeableConcept, coding.get()); - } if (ACTIVE_CLINICAL_STATUS.equals(allergyIntoleranceClinicalStatus.toCode())) { return getOriginalTextForActiveAllergy(coding.get()); } @@ -381,35 +377,6 @@ private Optional getOriginalTextForActiveAllergy(Coding coding) { return Optional.empty(); } - private Optional getOriginalTextForResolvedAllergy(CodeableConcept codeableConcept, Coding coding) { - - if (codeableConcept.hasText()) { - return Optional.ofNullable(codeableConcept.getText()); - } - - var extension = retrieveDescriptionExtension(coding); - if (extension.isEmpty()) { - return coding.hasDisplay() - ? Optional.ofNullable(coding.getDisplay()) - : Optional.empty(); - } - - Optional originalText = extension - .get() - .getExtension().stream() - .filter(displayExtension -> DESCRIPTION_DISPLAY.equals(displayExtension.getUrl())) - .map(extension1 -> extension1.getValue().toString()) - .findFirst(); - - if (originalText.isPresent()) { - return originalText; - } else if (coding.hasDisplay()) { - return Optional.ofNullable(coding.getDisplay()); - } - - return Optional.empty(); - } - private Optional findDisplayText(Coding coding) { return Optional.ofNullable(coding.getDisplay()); } From e849cac3dcaa81c164fef600e760f20ce8fd0671 Mon Sep 17 00:00:00 2001 From: MartinWheelerMT Date: Wed, 5 Mar 2025 15:52:09 +0000 Subject: [PATCH 5/6] * Removed unnecessary `isEmpty` check as fallback was to return an Optional.empty() which so this is already implied. * Refactor method to functional style for code consistency --- .../ehr/mapper/CodeableConceptCdMapper.java | 16 ++++------------ .../ehr/mapper/CodeableConceptCdMapperTest.java | 1 - 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapper.java b/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapper.java index 2e326ae8a..c32ff637a 100644 --- a/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapper.java +++ b/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapper.java @@ -360,21 +360,13 @@ private Optional findOriginalTextForAllergy( } private Optional getOriginalTextForActiveAllergy(Coding coding) { - Optional extension = retrieveDescriptionExtension(coding); - - if (extension.isPresent()) { - Optional originalText = extension - .get() + return retrieveDescriptionExtension(coding) + .flatMap(value -> value .getExtension().stream() .filter(displayExtension -> DESCRIPTION_DISPLAY.equals(displayExtension.getUrl())) .map(extension1 -> extension1.getValue().toString()) - .findFirst(); - if (originalText.isPresent()) { - return originalText; - } - } - - return Optional.empty(); + .findFirst() + ); } private Optional findDisplayText(Coding coding) { diff --git a/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapperTest.java b/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapperTest.java index a107a1e9a..7265d2ae4 100644 --- a/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapperTest.java +++ b/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapperTest.java @@ -358,5 +358,4 @@ public void When_MapToCdForMedication_With_RelatedProblemAndTitle_Expect_Concept assertThat(outputString).isEqualToIgnoringWhitespace(expectedOutput); } - } \ No newline at end of file From b19f33a577815aac89a70491d8402a65c7724dc8 Mon Sep 17 00:00:00 2001 From: MartinWheelerMT Date: Wed, 5 Mar 2025 16:11:05 +0000 Subject: [PATCH 6/6] Remove now unnecessary test * Remove now unnecessary test --- .../mapper/CodeableConceptCdMapperTest.java | 45 ------------------- 1 file changed, 45 deletions(-) diff --git a/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapperTest.java b/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapperTest.java index 7265d2ae4..f6da40e6a 100644 --- a/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapperTest.java +++ b/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/CodeableConceptCdMapperTest.java @@ -169,51 +169,6 @@ void When_MapToNullFlavorCodeableConceptForAllergyWithoutSnomedCode_Expect_Origi assertThat(outputXml).isEqualToIgnoringWhitespace(expectedOutputXML); } - @Test - void When_MappingStubbedCodeableConceptAsInactiveAllergy_Expect_NullFlavourCodeableConceptWithOriginalTextAsDisplayName() { - var inputJson = """ - { - "resourceType": "AllergyIntolerance", - "id": "0C1232CF-D34B-4C16-A5F4-0F6461C51A41", - "meta": { - "profile": [ - "https://fhir.nhs.uk/STU3/StructureDefinition/CareConnect-GPC-AllergyIntolerance-1" - ] - }, - "identifier": [ - { - "system": "https://EMISWeb/A82038", - "value": "55D2363D57A248F49A745B2E03F5E93D0C1232CFD34B4C16A5F40F6461C51A41" - } - ], - "clinicalStatus": "inactive", - "code": { - "coding": [ - { - "system": "http://snomed.info/sct", - "code": "292971006", - "display": "Pivampicillin adverse reaction pt" - } - ] - } - }"""; - - var expectedOutputXML = """ - - Pivampicillin adverse reaction pt - - """; - var codeableConcept = fhirParseService.parseResource(inputJson, AllergyIntolerance.class).getCode(); - - var outputXml = codeableConceptCdMapper.mapToNullFlavorCodeableConceptForAllergy( - codeableConcept, - AllergyIntolerance.AllergyIntoleranceClinicalStatus.INACTIVE - ); - - assertThat(outputXml).isEqualToIgnoringWhitespace(expectedOutputXML); - - } - @ParameterizedTest @MethodSource("getTestArgumentsActualProblem") public void When_MappingStubbedCodeableConceptForActualProblemHeader_Expect_HL7CdObjectXml(String inputJson, String outputXml)