From f2e28dba669550ece31645077a8b15d01d4200cd Mon Sep 17 00:00:00 2001 From: David Raeside Date: Thu, 9 Jan 2025 09:04:40 -0500 Subject: [PATCH] added new narrative generator utility method --- .../NarrativeGeneratorTemplateUtils.java | 34 ++++++++++++ .../NarrativeGeneratorTemplateUtilsTest.java | 55 +++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/narrative2/NarrativeGeneratorTemplateUtils.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/narrative2/NarrativeGeneratorTemplateUtils.java index adb173eb582f..23f6abd86ec4 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/narrative2/NarrativeGeneratorTemplateUtils.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/narrative2/NarrativeGeneratorTemplateUtils.java @@ -22,8 +22,12 @@ import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.util.BundleUtil; +import ca.uhn.fhir.util.TerserUtil; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; +import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBaseBundle; +import org.hl7.fhir.instance.model.api.IBaseCoding; import org.hl7.fhir.instance.model.api.IBaseResource; import java.util.List; @@ -52,4 +56,34 @@ public boolean bundleHasEntriesWithResourceType(IBaseBundle theBaseBundle, Strin .filter(Objects::nonNull) .anyMatch(t -> ctx.getResourceType(t).equals(theResourceType)); } + + /** + * Returns if the bundle contains a resource that has a `code` property that contains a matching code system and code. + * + * @param theBundle the bundle to inspect + * @param theResourceType the resource type to look for + * @param theCodeSystem the code system to find + * @param theCode the code to find + * @return returns true if bundle has a resource that with matching code/code system + */ + public boolean bundleHasEntriesWithCode( + IBaseBundle theBundle, String theResourceType, String theCodeSystem, String theCode) { + FhirVersionEnum fhirVersionEnum = theBundle.getStructureFhirVersionEnum(); + FhirContext ctx = FhirContext.forCached(fhirVersionEnum); + + List> entryResources = BundleUtil.getBundleEntryUrlsAndResources(ctx, theBundle); + + return entryResources.stream() + .map(Pair::getValue) + .filter(Objects::nonNull) + .filter(t -> ctx.getResourceType(t).equals(theResourceType)) + .anyMatch(t -> { + List codeList = TerserUtil.getFieldByFhirPath(ctx, "code.coding", t); + return codeList.stream().anyMatch(m -> { + IBaseCoding coding = (IBaseCoding) m; + return StringUtils.equals(coding.getSystem(), theCodeSystem) + && StringUtils.equals(coding.getCode(), theCode); + }); + }); + } } diff --git a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/narrative2/NarrativeGeneratorTemplateUtilsTest.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/narrative2/NarrativeGeneratorTemplateUtilsTest.java index ad71176a1f39..cf12f7828e43 100644 --- a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/narrative2/NarrativeGeneratorTemplateUtilsTest.java +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/narrative2/NarrativeGeneratorTemplateUtilsTest.java @@ -1,7 +1,10 @@ package ca.uhn.fhir.narrative2; import org.hl7.fhir.dstu3.model.Bundle; +import org.hl7.fhir.dstu3.model.CodeableConcept; +import org.hl7.fhir.dstu3.model.Coding; import org.hl7.fhir.dstu3.model.Medication; +import org.hl7.fhir.dstu3.model.Observation; import org.hl7.fhir.dstu3.model.Patient; import org.junit.jupiter.api.Test; @@ -24,5 +27,57 @@ public void testBundleHasEntriesWithResourceType_False() { assertFalse(NarrativeGeneratorTemplateUtils.INSTANCE.bundleHasEntriesWithResourceType(bundle, "Patient")); } + @Test + public void testResourcesHaveCodeValue_isTrue() { + Bundle bundle = new Bundle(); + bundle.addEntry().setResource(new Observation().setCode( + new CodeableConcept( + new Coding("http://loinc.org", "123", "")))); + bundle.addEntry().setResource(new Observation().setCode( + new CodeableConcept( + new Coding("http://loinc.org", "456", "")))); + + assertTrue(NarrativeGeneratorTemplateUtils.INSTANCE + .bundleHasEntriesWithCode(bundle, "Observation", "http://loinc.org", "123")); + } + + @Test + public void testResourcesHaveCodeValue_isTrueWhenOneCodeMatches() { + Bundle bundle = new Bundle(); + bundle.addEntry().setResource(new Observation().setCode( + new CodeableConcept() + .addCoding(new Coding("http://loinc.org", "abc", "")) + .addCoding(new Coding("http://loinc.org", "123", "")) + )); + bundle.addEntry().setResource(new Observation().setCode( + new CodeableConcept( + new Coding("http://loinc.org", "456", "")))); + + assertTrue(NarrativeGeneratorTemplateUtils.INSTANCE + .bundleHasEntriesWithCode(bundle, "Observation", "http://loinc.org", "123")); + } + + @Test + public void testResourcesHaveCodeValue_isFalse() { + Bundle bundle = new Bundle(); + bundle.addEntry().setResource(new Observation().setCode( + new CodeableConcept( + new Coding("http://loinc.org", "123", "")))); + bundle.addEntry().setResource(new Observation().setCode( + new CodeableConcept( + new Coding("http://loinc.org", "456", "")))); + + assertFalse(NarrativeGeneratorTemplateUtils.INSTANCE + .bundleHasEntriesWithCode(bundle, "Observation", "http://loinc.org", "789")); + } + + @Test + public void testResourcesHaveCodeValue_isFalseWhenNoResourcePresent() { + Bundle bundle = new Bundle(); + bundle.addEntry().setResource(new Patient().setActive(true)); + bundle.addEntry().setResource(new Medication().setIsBrand(true)); + assertFalse(NarrativeGeneratorTemplateUtils.INSTANCE + .bundleHasEntriesWithCode(bundle, "Observation", "http://loinc.org", "789")); + } }