mirror of
https://github.com/hapifhir/hapi-fhir.git
synced 2025-03-09 14:33:32 +00:00
Enhance vital signs narrative generation (#6590)
* add support for formatting observation.component entries in vital signs narrative generation * update
This commit is contained in:
parent
ee194f2a44
commit
37ab80e250
@ -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."
|
@ -247,3 +247,18 @@
|
||||
<th:block th:if="${!iter.last}" th:text="', '"/>
|
||||
</th:block>
|
||||
</th:block>
|
||||
|
||||
<!-- /* Component list */ -->
|
||||
<th:block th:if="${list}" th:fragment="renderComponent (list)">
|
||||
<th:block th:each="item,iter : ${list}" th:if="${!list.empty}">
|
||||
<th:block th:if="${item.getCode().getCodingFirstRep().hasDisplay()}" th:text="${item.getCode().getCodingFirstRep().getDisplay()}">Display</th:block>
|
||||
<th:block th:if="${!item.getCode().getCodingFirstRep().hasDisplay()}" th:text="${item.getCode().getCodingFirstRep().getCode()}">Code</th:block>
|
||||
<th:block th:if="${item.hasValueQuantity()}" th:text="${item.getValueQuantity().getValue().toPlainString()}">Value</th:block>
|
||||
<th:block th:if="${item.hasValueIntegerType()}" th:text="${item.getValueIntegerType().getValueAsString()}">Value</th:block>
|
||||
<th:block th:if="${item.hasValueStringType()}" th:text="${item.getValueStringType().getValueAsString()}">Value</th:block>
|
||||
<th:block th:if="${item.hasValueCodeableConcept()}">
|
||||
<th:block th:insert=":: codeableConcept (cc=${item.getValueCodeableConcept()}, attr='display')"/>
|
||||
</th:block>
|
||||
<th:block th:if="${!iter.last}" th:text="', '"/>
|
||||
</th:block>
|
||||
</th:block>
|
||||
|
@ -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 <br />) || Observation.valueString
|
||||
Unit: Observation.valueQuantity.unit
|
||||
Interpretation: Observation.interpretation[0].text || Observation.interpretation[0].coding[x].display (separated by <br />)
|
||||
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 <br />)
|
||||
Date: Observation.effectiveDateTime || Observation.effectivePeriod.start
|
||||
*/-->
|
||||
@ -16,6 +17,7 @@ Date: Observation.effectiveDateTime || Observation.effectivePeriod.start
|
||||
<th>Result</th>
|
||||
<th>Unit</th>
|
||||
<th>Interpretation</th>
|
||||
<th>Component(s)</th>
|
||||
<th>Comments</th>
|
||||
<th>Date</th>
|
||||
</tr>
|
||||
@ -23,12 +25,13 @@ Date: Observation.effectiveDateTime || Observation.effectivePeriod.start
|
||||
<tbody>
|
||||
<th:block th:each="entry : ${resource.entry}" th:object="${entry.getResource()}">
|
||||
<th:block th:unless='*{getResourceType().name() == "Composition"}'>
|
||||
<th:block th:with="extension=${entry.getResource().getExtensionByUrl('http://hl7.org/fhir/StructureDefinition/narrativeLink').getValue().getValue()}">
|
||||
<tr th:id="${#strings.arraySplit(extension, '#')[1]}">
|
||||
<th:block th:with="extension=${entry.getResource().getExtensionByUrl('http://hl7.org/fhir/StructureDefinition/narrativeLink')}">
|
||||
<tr th:id="${extension != null} ? ${#strings.arraySplit(extension.getValue().getValue(), '#')[1]} : ''">
|
||||
<td th:insert="~{IpsUtilityFragments :: codeableConcept (cc=*{getCode()},attr='display')}">Code</td>
|
||||
<td th:insert="~{IpsUtilityFragments :: renderValue (value=*{getValue()})}">Result</td>
|
||||
<td th:insert="~{IpsUtilityFragments :: renderValueUnit (value=*{getValue()})}">Unit</td>
|
||||
<td th:replace="~{IpsUtilityFragments :: firstFromCodeableConceptList (list=*{getInterpretation()})}">Interpretation</td>
|
||||
<td th:insert="~{IpsUtilityFragments :: firstFromCodeableConceptList (list=*{getInterpretation()})}">Interpretation</td>
|
||||
<td th:insert="~{IpsUtilityFragments :: renderComponent (list=*{getComponent()})}">Component(s)</td>
|
||||
<td th:insert="~{IpsUtilityFragments :: concat (list=*{getNote()},attr='text')}">Comments</td>
|
||||
<td th:insert="~{IpsUtilityFragments :: renderEffective (effective=*{getEffective()})}">Date</td>
|
||||
</tr>
|
||||
|
@ -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<Observation> 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<DomElement> 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user