Jr 20241217 refine ips templates (#6597)

* clean up procedures template

* immunization WIP

* complete conversion of immunization template

* medication template

* fix broken integration test

* template for history of illness

* problem list template
This commit is contained in:
JasonRoberts-smile 2025-01-08 12:15:24 -05:00 committed by GitHub
parent a23d77b174
commit 544f83279c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 54 additions and 73 deletions

View File

@ -66,6 +66,10 @@ public class CustomThymeleafNarrativeGenerator extends BaseThymeleafNarrativeGen
this(theNarrativePropertyFiles.toArray(new String[0])); this(theNarrativePropertyFiles.toArray(new String[0]));
} }
public CustomThymeleafNarrativeGenerator(CustomThymeleafNarrativeGenerator theNarrativeGenerator) {
setManifest(theNarrativeGenerator.getManifest());
}
@Override @Override
public NarrativeTemplateManifest getManifest() { public NarrativeTemplateManifest getManifest() {
NarrativeTemplateManifest retVal = myManifest; NarrativeTemplateManifest retVal = myManifest;

View File

@ -31,16 +31,7 @@ Comments: AllergyIntolerance.note[x].text (separated by <br />)
<td th:insert="~{IpsUtilityFragments :: concatReactionManifestation (list=*{getReaction()})}">Reaction</td> <td th:insert="~{IpsUtilityFragments :: concatReactionManifestation (list=*{getReaction()})}">Reaction</td>
<td th:insert="~{IpsUtilityFragments :: concat (list=*{getReaction()},attr='severity')}">Severity</td> <td th:insert="~{IpsUtilityFragments :: concat (list=*{getReaction()},attr='severity')}">Severity</td>
<td th:insert="~{IpsUtilityFragments :: concat (list=*{getNote()},attr='text')}">Comments</td> <td th:insert="~{IpsUtilityFragments :: concat (list=*{getNote()},attr='text')}">Comments</td>
<td th:insert="~{IpsUtilityFragments :: renderTime (time=*{getOnset()})}">Date</td>
<th:block th:if="*{hasOnsetDateTimeType()}">
<td th:text="*{getOnsetDateTimeType().getValueAsString()}">Onset</td>
</th:block>
<th:block th:if="*{hasOnsetStringType()}">
<td th:text="*{getOnsetStringType().getValue()}">Onset</td>
</th:block>
<th:block th:if="*{!hasOnsetDateTimeType() && !hasOnsetStringType()}">
<td></td>
</th:block>
</tr> </tr>
</th:block> </th:block>

View File

@ -17,11 +17,11 @@ Date: Procedure.performedDateTime || Procedure.performedPeriod.start && “-“
<tbody> <tbody>
<th:block th:each="entry : ${resource.entry}" th:object="${entry.getResource()}"> <th:block th:each="entry : ${resource.entry}" th:object="${entry.getResource()}">
<th:block th:unless='*{getResourceType().name() == "Composition"}'> <th:block th:unless='*{getResourceType().name() == "Composition"}'>
<th:block th:with="extension=${entry.getResource().getExtensionByUrl('http://hl7.org/fhir/StructureDefinition/narrativeLink').getValue().getValue()}"> <th:block th:with="extension=${entry.getResource().getExtensionByUrl('http://hl7.org/fhir/StructureDefinition/narrativeLink')}">
<tr th:id="${#strings.arraySplit(extension, '#')[1]}"> <tr th:id="${extension != null} ? ${#strings.arraySplit(extension.getValue().getValue(), '#')[1]} : ''">
<td th:insert="~{IpsUtilityFragments :: codeableConcept (cc=*{getCode()},attr='display')}">Procedure</td> <td th:insert="~{IpsUtilityFragments :: codeableConcept (cc=*{getCode()},attr='display')}">Procedure</td>
<td th:insert="~{IpsUtilityFragments :: concat (list=*{getNote()},attr='text')}">Comments</td> <td th:insert="~{IpsUtilityFragments :: concat (list=*{getNote()},attr='text')}">Comments</td>
<td th:insert="~{IpsUtilityFragments :: renderPerformed (performed=*{getPerformed()})}">Date</td> <td th:insert="~{IpsUtilityFragments :: renderTime (time=*{getPerformed()})}">Date</td>
</tr> </tr>
</th:block> </th:block>
</th:block> </th:block>

View File

@ -25,15 +25,15 @@ Date: Immunization.occurrenceDateTime || Immunization.occurrenceString
<tbody> <tbody>
<th:block th:each="entry : ${resource.entry}" th:object="${entry.getResource()}"> <th:block th:each="entry : ${resource.entry}" th:object="${entry.getResource()}">
<th:block th:if='*{getResourceType().name() == "Immunization"}'> <th:block th:if='*{getResourceType().name() == "Immunization"}'>
<th:block th:with="extension=${entry.getResource().getExtensionByUrl('http://hl7.org/fhir/StructureDefinition/narrativeLink').getValue().getValue()}"> <th:block th:with="extension=${entry.getResource().getExtensionByUrl('http://hl7.org/fhir/StructureDefinition/narrativeLink')}">
<tr th:id="${#strings.arraySplit(extension, '#')[1]}"> <tr th:id="${extension != null} ? ${#strings.arraySplit(extension.getValue().getValue(), '#')[1]} : ''">
<td th:insert="~{IpsUtilityFragments :: codeableConcept (cc=*{getVaccineCode()},attr='display')}">Immunization</td> <td th:insert="~{IpsUtilityFragments :: codeableConcept (cc=*{getVaccineCode()},attr='display')}">Immunization</td>
<td th:text="*{getStatusElement().value}">Status</td> <td th:text="*{getStatusElement().value}">Status</td>
<td th:insert="~{IpsUtilityFragments :: concatDoseNumber (list=*{getProtocolApplied()})}">Comments</td> <td th:insert="~{IpsUtilityFragments :: concatDoseNumber (list=*{getProtocolApplied()})}">Comments</td>
<td th:insert="~{IpsUtilityFragments :: renderOrganization (orgRef=*{getManufacturer()})}">Manufacturer</td> <td th:insert="~{IpsUtilityFragments :: renderVaccineManufacturer (immunization=${entry.getResource()})}">Manufacturer</td>
<td th:text="*{getLotNumber()}">Lot Number</td> <td th:text="*{getLotNumber()}">Lot Number</td>
<td th:insert="~{IpsUtilityFragments :: concat (list=*{getNote()},attr='text')}">Comments</td> <td th:insert="~{IpsUtilityFragments :: concat (list=*{getNote()},attr='text')}">Comments</td>
<td th:insert="~{IpsUtilityFragments :: renderOccurrence (occurrence=*{getOccurrence()})}">Date</td> <td th:insert="~{IpsUtilityFragments :: renderTime (time=*{getOccurrence()})}">Date</td>
</tr> </tr>
</th:block> </th:block>
</th:block> </th:block>

View File

@ -35,12 +35,12 @@ Date: MedicationStatement.effectiveDateTime || MedicationStatement.effectivePeri
<th:block th:if='*{getResourceType().name() == "MedicationRequest"}'> <th:block th:if='*{getResourceType().name() == "MedicationRequest"}'>
<th:block th:unless='*{getResourceType().name() == "Composition"}'> <th:block th:unless='*{getResourceType().name() == "Composition"}'>
<th:block <th:block
th:with="extension=${entry.getResource().getExtensionByUrl('http://hl7.org/fhir/StructureDefinition/narrativeLink').getValue().getValue()}"> th:with="extension=${entry.getResource().getExtensionByUrl('http://hl7.org/fhir/StructureDefinition/narrativeLink')}">
<tr th:id="${#strings.arraySplit(extension, '#')[1]}"> <tr th:id="${extension != null} ? ${#strings.arraySplit(extension.getValue().getValue(), '#')[1]} : ''">
<td th:insert="~{IpsUtilityFragments :: renderMedication (medicationType=*{getMedication()})}"> <td th:insert="~{IpsUtilityFragments :: renderMedication (medicationType=${entry.getResource()})}">
Medication Medication
</td> </td>
<td th:text="*{getStatus().getDisplay()}">Status</td> <td th:text="*{getStatus() != null} ? *{getStatus().getDisplay()} : ''">Status</td>
<td th:insert="~{IpsUtilityFragments :: concatDosageRoute (list=*{getDosageInstruction()})}"> <td th:insert="~{IpsUtilityFragments :: concatDosageRoute (list=*{getDosageInstruction()})}">
Route Route
</td> </td>
@ -48,7 +48,7 @@ Date: MedicationStatement.effectiveDateTime || MedicationStatement.effectivePeri
Sig Sig
</td> </td>
<td th:insert="~{IpsUtilityFragments :: concat (list=*{getNote()},attr='text')}">Comments</td> <td th:insert="~{IpsUtilityFragments :: concat (list=*{getNote()},attr='text')}">Comments</td>
<td th:text="*{getAuthoredOnElement().getValue()}">Authored Date</td> <td th:insert="~{IpsUtilityFragments :: renderTime (time=*{getAuthoredOnElement()})}">Authored Date</td>
</tr> </tr>
</th:block> </th:block>
</th:block> </th:block>
@ -74,15 +74,15 @@ Date: MedicationStatement.effectiveDateTime || MedicationStatement.effectivePeri
<th:block th:each="entry : ${resource.entry}" th:object="${entry.getResource()}"> <th:block th:each="entry : ${resource.entry}" th:object="${entry.getResource()}">
<th:block th:if='*{getResourceType().name() == "MedicationStatement"}'> <th:block th:if='*{getResourceType().name() == "MedicationStatement"}'>
<th:block <th:block
th:with="extension=${entry.getResource().getExtensionByUrl('http://hl7.org/fhir/StructureDefinition/narrativeLink').getValue().getValue()}"> th:with="extension=${entry.getResource().getExtensionByUrl('http://hl7.org/fhir/StructureDefinition/narrativeLink')}">
<tr th:id="${#strings.arraySplit(extension, '#')[1]}"> <tr th:id="${extension != null} ? ${#strings.arraySplit(extension.getValue().getValue(), '#')[1]} : ''">
<td th:insert="~{IpsUtilityFragments :: renderMedication (medicationType=*{getMedication()})}"> <td th:insert="~{IpsUtilityFragments :: renderMedication (medicationType=${entry.getResource()})}">
Medication Medication
</td> </td>
<td th:text="*{getStatus().getDisplay()}">Status</td> <td th:text="*{getStatus() != null} ? *{getStatus().getDisplay()} : ''">Status</td>
<td th:insert="~{IpsUtilityFragments :: concatDosageRoute (list=*{getDosage()})}">Route</td> <td th:insert="~{IpsUtilityFragments :: concatDosageRoute (list=*{getDosage()})}">Route</td>
<td th:insert="~{IpsUtilityFragments :: concat (list=*{getDosage()},attr='text')}">Sig</td> <td th:insert="~{IpsUtilityFragments :: concat (list=*{getDosage()},attr='text')}">Sig</td>
<td th:insert="~{IpsUtilityFragments :: renderEffective (effective=*{getEffective()})}">Date</td> <td th:insert="~{IpsUtilityFragments :: renderTime (time=*{getEffective()})}">Date</td>
</tr> </tr>
</th:block> </th:block>
</th:block> </th:block>

View File

@ -19,12 +19,12 @@ Onset Date: Condition.onsetDateTime || Condition.onsetPeriod.start && “-“ &&
<tbody> <tbody>
<th:block th:each="entry : ${resource.entry}" th:object="${entry.getResource()}"> <th:block th:each="entry : ${resource.entry}" th:object="${entry.getResource()}">
<th:block th:unless='*{getResourceType().name() == "Composition"}'> <th:block th:unless='*{getResourceType().name() == "Composition"}'>
<th:block th:with="extension=${entry.getResource().getExtensionByUrl('http://hl7.org/fhir/StructureDefinition/narrativeLink').getValue().getValue()}"> <th:block th:with="extension=${entry.getResource().getExtensionByUrl('http://hl7.org/fhir/StructureDefinition/narrativeLink')}">
<tr th:id="${#strings.arraySplit(extension, '#')[1]}"> <tr th:id="${extension != null} ? ${#strings.arraySplit(extension.getValue().getValue(), '#')[1]} : ''">
<td th:insert="~{IpsUtilityFragments :: codeableConcept (cc=*{getCode()},attr='display')}">Medical Problem</td> <td th:insert="~{IpsUtilityFragments :: codeableConcept (cc=*{getCode()},attr='display')}">Medical Problem</td>
<td th:insert="~{IpsUtilityFragments :: codeableConcept (cc=*{getClinicalStatus()},attr='code')}">Status</td> <td th:insert="~{IpsUtilityFragments :: codeableConcept (cc=*{getClinicalStatus()},attr='code')}">Status</td>
<td th:insert="~{IpsUtilityFragments :: concat (list=*{getNote()},attr='text')}">Comments</td> <td th:insert="~{IpsUtilityFragments :: concat (list=*{getNote()},attr='text')}">Comments</td>
<td th:insert="~{IpsUtilityFragments :: renderOnset (onset=*{getOnset()})}">Onset Date</td> <td th:insert="~{IpsUtilityFragments :: renderTime (time=*{getOnset()})}">Onset Date</td>
</tr> </tr>
</th:block> </th:block>
</th:block> </th:block>

View File

@ -19,12 +19,12 @@ Onset Date: Condition.onsetDateTime || Condition.onsetPeriod.start && “-“ &&
<tbody> <tbody>
<th:block th:each="entry : ${resource.entry}" th:object="${entry.getResource()}"> <th:block th:each="entry : ${resource.entry}" th:object="${entry.getResource()}">
<th:block th:unless='*{getResourceType().name() == "Composition"}'> <th:block th:unless='*{getResourceType().name() == "Composition"}'>
<th:block th:with="extension=${entry.getResource().getExtensionByUrl('http://hl7.org/fhir/StructureDefinition/narrativeLink').getValue().getValue()}"> <th:block th:with="extension=${entry.getResource().getExtensionByUrl('http://hl7.org/fhir/StructureDefinition/narrativeLink')}">
<tr th:id="${#strings.arraySplit(extension, '#')[1]}"> <tr th:id="${extension != null} ? ${#strings.arraySplit(extension.getValue().getValue(), '#')[1]} : ''">
<td th:insert="~{IpsUtilityFragments :: codeableConcept (cc=*{getCode()},attr='display')}">Medical Problems</td> <td th:insert="~{IpsUtilityFragments :: codeableConcept (cc=*{getCode()},attr='display')}">Medical Problems</td>
<td th:insert="~{IpsUtilityFragments :: codeableConcept (cc=*{getClinicalStatus()},attr='code')}">Status</td> <td th:insert="~{IpsUtilityFragments :: codeableConcept (cc=*{getClinicalStatus()},attr='code')}">Status</td>
<td th:insert="~{IpsUtilityFragments :: concat (list=*{getNote()},attr='text')}">Comments</td> <td th:insert="~{IpsUtilityFragments :: concat (list=*{getNote()},attr='text')}">Comments</td>
<td th:insert="~{IpsUtilityFragments :: renderOnset (onset=*{getOnset()})}">Onset Date</td> <td th:insert="~{IpsUtilityFragments :: renderTime (time=*{getOnset()})}">Onset Date</td>
</tr> </tr>
</th:block> </th:block>
</th:block> </th:block>

View File

@ -22,21 +22,33 @@
</th:block> </th:block>
</th:block> </th:block>
<th:block th:if="${immunization}" th:fragment="renderVaccineManufacturer (immunization)">
<th:block th:with="organization = ${#fhirpath.evaluateFirst(immunization, 'manufacturer.resolve()')}">
<th:block th:if="${organization != null}">
<th:block th:if='${organization.getResourceType().name() == "Organization"}'>
<th:block th:text="${organization.getName()}">Org Name</th:block>
</th:block>
</th:block>
</th:block>
</th:block>
<th:block th:fragment="renderMedication (medicationType)"> <th:block th:fragment="renderMedication (medicationType)">
<th:block th:if="${medicationType} != null" th:object="${medicationType}"> <th:block th:if="${medicationType} != null" th:object="${medicationType}">
<th:block th:switch="*{getClass().getSimpleName()}"> <th:block th:if="*{getMedication() != null}">
<th:block th:case="'CodeableConcept'"> <th:block th:switch="*{getMedication().getClass().getSimpleName()}">
<th:block th:replace=":: codeableConcept (cc=${medicationType}, attr='display')">Medication</th:block> <th:block th:case="'CodeableConcept'">
</th:block> <th:block th:replace=":: codeableConcept (cc=${medicationType.getMedication()}, attr='display')">Medication</th:block>
<th:block th:case="'Reference'"> </th:block>
<th:block th:replace=":: renderMedicationRef (medicationRef=${medicationType})">Medication</th:block> <th:block th:case="'Reference'">
</th:block> <th:block th:replace=":: renderMedicationRef (medicationRef=${medicationType})">Medication</th:block>
</th:block> </th:block>
</th:block>
</th:block>
</th:block> </th:block>
</th:block> </th:block>
<th:block th:if="${medicationRef}" th:fragment="renderMedicationRef (medicationRef)"> <th:block th:if="${medicationRef}" th:fragment="renderMedicationRef (medicationRef)">
<th:block th:with="medication = ${#fhirpath.evaluateFirst(medicationRef, 'resolve()')}"> <th:block th:with="medication = ${#fhirpath.evaluateFirst(medicationRef, 'medication.resolve()')}">
<th:block th:if="${medication != null}"> <th:block th:if="${medication != null}">
<th:block th:replace=":: renderMedicationCode (medication=${medication})">Medication</th:block> <th:block th:replace=":: renderMedicationCode (medication=${medication})">Medication</th:block>
</th:block> </th:block>
@ -94,49 +106,23 @@
</th:block> </th:block>
</th:block> </th:block>
<th:block th:if="${onset}" th:fragment="renderOnset (onset)"> <th:block th:if="${time}" th:fragment="renderTime (time)">
<th:block th:if="${onset} != null" th:object="${onset}"> <th:block th:if="${time} != null" th:object="${time}">
<th:block th:switch="*{getClass().getSimpleName()}"> <th:block th:switch="*{getClass().getSimpleName()}">
<th:block th:case="'DateTimeType'" th:text="*{getValue()}">Date</th:block> <th:block th:case="'DateTimeType'" th:text="*{getValueAsString()}">Date</th:block>
<th:block th:case="'Period'" <th:block th:case="'Period'"
th:text="*{#strings.concatReplaceNulls('', getStartElement().getValue(), '-', getEndElement().getValue() )}"> th:text="*{#strings.concatReplaceNulls('', getStartElement().getValueAsString(), ' - ', getEndElement().getValueAsString() )}">
Date Date
</th:block> </th:block>
<th:block th:case="'Age'" th:text="*{getValue()}">Date</th:block> <th:block th:case="'Age'" th:text="*{getValue()}">Date</th:block>
<th:block th:case="'Range'" <th:block th:case="'Range'"
th:text="*{#strings.concatReplaceNulls('', getLow().getValue(), '-', getHigh().getValue() )}">Date th:text="*{#strings.concatReplaceNulls('', getLow().getValueAsString(), ' - ', getHigh().getValueAsString() )}">Date
</th:block> </th:block>
<th:block th:case="'StringType'" th:text="*{getValue()}">Date</th:block> <th:block th:case="'StringType'" th:text="*{getValue()}">Date</th:block>
</th:block> </th:block>
</th:block> </th:block>
</th:block> </th:block>
<th:block th:if="${performed}" th:fragment="renderPerformed (performed)">
<th:block th:if="${performed} != null" th:object="${performed}">
<th:block th:switch="*{getClass().getSimpleName()}">
<th:block th:case="'DateTimeType'" th:text="*{getValue()}">Date</th:block>
<th:block th:case="'Period'"
th:text="*{#strings.concatReplaceNulls('', getStartElement().getValue(), '-', getEndElement().getValue() )}">
Date
</th:block>
<th:block th:case="'Age'" th:text="*{getValue()}">Date</th:block>
<th:block th:case="'Range'"
th:text="*{#strings.concatReplaceNulls('', getLow().getValue(), '-', getHigh().getValue() )}">Date
</th:block>
<th:block th:case="'StringType'" th:text="*{getValue()}">Date</th:block>
</th:block>
</th:block>
</th:block>
<th:block th:if="${occurrence}" th:fragment="renderOccurrence (occurrence)">
<th:block th:if="${occurrence} != null" th:object="${occurrence}">
<th:block th:switch="*{getClass().getSimpleName()}">
<th:block th:case="'DateTimeType'" th:text="*{getValue()}">Date</th:block>
<th:block th:case="'StringType'" th:text="*{getValue()}">Date</th:block>
</th:block>
</th:block>
</th:block>
<th:block th:if="${recorded}" th:fragment="renderRecorded (recorded)"> <th:block th:if="${recorded}" th:fragment="renderRecorded (recorded)">
<th:block th:if="${recorded} != null" th:object="${recorded}"> <th:block th:if="${recorded} != null" th:object="${recorded}">
<th:block th:switch="*{getClass().getSimpleName()}"> <th:block th:switch="*{getClass().getSimpleName()}">