diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_8_0/6587-enhance-vital-signs-narrative-generation-template.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_8_0/6587-enhance-vital-signs-narrative-generation-template.yaml
new file mode 100644
index 00000000000..41531e5d239
--- /dev/null
+++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_8_0/6587-enhance-vital-signs-narrative-generation-template.yaml
@@ -0,0 +1,5 @@
+---
+type: add
+issue: 6587
+title: "Enhanced the IPS vital signs narrative template to include code and value information for
+ all entries in the `Observation.component` property."
diff --git a/hapi-fhir-jpaserver-ips/src/main/resources/ca/uhn/fhir/jpa/ips/narrative/utility-fragments.html b/hapi-fhir-jpaserver-ips/src/main/resources/ca/uhn/fhir/jpa/ips/narrative/utility-fragments.html
index 3dea18d43a8..552e48b8753 100644
--- a/hapi-fhir-jpaserver-ips/src/main/resources/ca/uhn/fhir/jpa/ips/narrative/utility-fragments.html
+++ b/hapi-fhir-jpaserver-ips/src/main/resources/ca/uhn/fhir/jpa/ips/narrative/utility-fragments.html
@@ -247,3 +247,18 @@
+
+
+
+
+ Display
+ Code
+ Value
+ Value
+ Value
+
+
+
+
+
+
diff --git a/hapi-fhir-jpaserver-ips/src/main/resources/ca/uhn/fhir/jpa/ips/narrative/vitalsigns.html b/hapi-fhir-jpaserver-ips/src/main/resources/ca/uhn/fhir/jpa/ips/narrative/vitalsigns.html
index f890ad6c26e..55391cee2ed 100644
--- a/hapi-fhir-jpaserver-ips/src/main/resources/ca/uhn/fhir/jpa/ips/narrative/vitalsigns.html
+++ b/hapi-fhir-jpaserver-ips/src/main/resources/ca/uhn/fhir/jpa/ips/narrative/vitalsigns.html
@@ -4,6 +4,7 @@ Code: Observation.code.text || Observation.code.coding[x].display (separated by
Result: Observation.valueQuantity || Observation.valueDateTime || Observation.valueCodeableConcept.text || Observation.valueCodeableConcept.coding[x].display (separated by
) || Observation.valueString
Unit: Observation.valueQuantity.unit
Interpretation: Observation.interpretation[0].text || Observation.interpretation[0].coding[x].display (separated by
)
+Component(s): Observation.component[x].display || Observation.component[x].code + Observation.component[x].value (items separated by comma)
Comments: Observation.note[x].text (separated by
)
Date: Observation.effectiveDateTime || Observation.effectivePeriod.start
*/-->
@@ -16,6 +17,7 @@ Date: Observation.effectiveDateTime || Observation.effectivePeriod.start
Result |
Unit |
Interpretation |
+ Component(s) |
Comments |
Date |
@@ -23,12 +25,13 @@ Date: Observation.effectiveDateTime || Observation.effectivePeriod.start
-
-
+
+
Code |
Result |
Unit |
- Interpretation |
+ Interpretation |
+ Component(s) |
Comments |
Date |
diff --git a/hapi-fhir-jpaserver-ips/src/test/java/ca/uhn/fhir/jpa/ips/generator/IpsGeneratorSvcImplTest.java b/hapi-fhir-jpaserver-ips/src/test/java/ca/uhn/fhir/jpa/ips/generator/IpsGeneratorSvcImplTest.java
index 96464a82b4d..80018cb7ff1 100644
--- a/hapi-fhir-jpaserver-ips/src/test/java/ca/uhn/fhir/jpa/ips/generator/IpsGeneratorSvcImplTest.java
+++ b/hapi-fhir-jpaserver-ips/src/test/java/ca/uhn/fhir/jpa/ips/generator/IpsGeneratorSvcImplTest.java
@@ -25,6 +25,8 @@ import org.hl7.fhir.r4.model.AllergyIntolerance;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.CarePlan;
import org.hl7.fhir.r4.model.ClinicalImpression;
+import org.hl7.fhir.r4.model.CodeableConcept;
+import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.Composition;
import org.hl7.fhir.r4.model.Condition;
import org.hl7.fhir.r4.model.Consent;
@@ -45,6 +47,7 @@ import org.hl7.fhir.r4.model.Organization;
import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.PositiveIntType;
import org.hl7.fhir.r4.model.Procedure;
+import org.hl7.fhir.r4.model.Quantity;
import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.Resource;
import org.hl7.fhir.r4.model.StringType;
@@ -667,6 +670,59 @@ public class IpsGeneratorSvcImplTest {
assertSame(strategy2, svc.selectGenerationStrategy("http://2"));
}
+ @Test
+ public void testVitalSigns_withComponents() throws IOException {
+ // Setup Patient
+ initializeGenerationStrategy();
+ registerPatientDaoWithRead();
+
+ Observation observation1 = new Observation();
+ observation1.setId("Observation/1");
+ observation1.setStatus(Observation.ObservationStatus.FINAL);
+ observation1.setCode(
+ new CodeableConcept().addCoding(
+ new Coding("http://loinc.org", "85354-9", "Blood pressure panel with all children optional")
+ )
+ );
+ observation1.addComponent(
+ new Observation.ObservationComponentComponent(
+ new CodeableConcept(
+ new Coding("http://loinc.org", "8480-6", "Systolic blood pressure")
+ )
+ ).setValue(new Quantity().setValue(125).setUnit("mmHg").setSystem("http://unitsofmeasure.org").setCode("mm[Hg]"))
+ );
+ observation1.addComponent(
+ new Observation.ObservationComponentComponent(
+ new CodeableConcept(
+ new Coding("http://loinc.org", "8462-4", "Diastolic blood pressure")
+ )
+ ).setValue(new Quantity().setValue(75).setUnit("mmHg").setSystem("http://unitsofmeasure.org").setCode("mm[Hg]"))
+ );
+
+ ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.put(observation1, BundleEntrySearchModeEnum.MATCH);
+ IFhirResourceDao observationDao = registerResourceDaoWithNoData(Observation.class);
+ when(observationDao.search(any(), any())).thenReturn(new SimpleBundleProvider(Lists.newArrayList(observation1)));
+ registerRemainingResourceDaos();
+
+ // Test
+ Bundle outcome = (Bundle) mySvc.generateIps(new SystemRequestDetails(), new IdType(PATIENT_ID), null);
+
+ // Verify
+ Composition compositions = (Composition) outcome.getEntry().get(0).getResource();
+ Composition.SectionComponent section = findSection(compositions, DefaultJpaIpsGenerationStrategy.SECTION_CODE_VITAL_SIGNS);
+
+ HtmlPage narrativeHtml = HtmlUtil.parseAsHtml(section.getText().getDivAsString());
+ ourLog.info("Narrative:\n{}", narrativeHtml.asXml());
+
+ DomNodeList tables = narrativeHtml.getElementsByTagName("table");
+ assertThat(tables).hasSize(1);
+ HtmlTable table = (HtmlTable) tables.get(0);
+ assertEquals("Code", table.getHeader().getRows().get(0).getCell(0).asNormalizedText());
+ assertEquals("Blood pressure panel with all children optional", table.getBodies().get(0).getRows().get(0).getCell(0).asNormalizedText());
+ assertEquals("Component(s)", table.getHeader().getRows().get(0).getCell(4).asNormalizedText());
+ assertEquals("Systolic blood pressure 125 , Diastolic blood pressure 75", table.getBodies().get(0).getRows().get(0).getCell(4).asNormalizedText());
+ }
+
@Nonnull
private Composition.SectionComponent findSection(Composition compositions, String theSectionCode) {
return compositions