@imranq2/fhirpatientsummary 1.0.30 → 1.0.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +129 -112
- package/dist/index.js +129 -112
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -938,6 +938,12 @@ var TemplateUtilities = class {
|
|
|
938
938
|
const escapedText = text.replace(/</g, "<").replace(/>/g, ">");
|
|
939
939
|
return escapedText.replace(/\n/g, "<br />");
|
|
940
940
|
}
|
|
941
|
+
capitalizeFirstLetter(text) {
|
|
942
|
+
if (!text || text.length === 0) {
|
|
943
|
+
return "";
|
|
944
|
+
}
|
|
945
|
+
return text.charAt(0).toUpperCase() + text.slice(1);
|
|
946
|
+
}
|
|
941
947
|
/**
|
|
942
948
|
* Renders note elements from a FHIR resource in a standardized format
|
|
943
949
|
* Can render as simple comma-separated text or as styled HTML with timestamps
|
|
@@ -1435,7 +1441,8 @@ var PatientTemplate = class _PatientTemplate {
|
|
|
1435
1441
|
static generateStaticNarrative(resources, timezone) {
|
|
1436
1442
|
const templateUtilities = new TemplateUtilities(resources);
|
|
1437
1443
|
const combinedPatient = this.combinePatients(resources);
|
|
1438
|
-
|
|
1444
|
+
let html = `<p>This section merges all Patient resources into a single combined patient record, preferring non-empty values for each field.</p>`;
|
|
1445
|
+
html += `<div>
|
|
1439
1446
|
<ul>
|
|
1440
1447
|
<li><strong>Name(s):</strong>${this.renderNames(combinedPatient)}</li>
|
|
1441
1448
|
<li><strong>Gender:</strong>${combinedPatient.gender ? this.capitalize(combinedPatient.gender) : ""}</li>
|
|
@@ -1447,6 +1454,7 @@ var PatientTemplate = class _PatientTemplate {
|
|
|
1447
1454
|
<li><strong>Language(s):</strong>${this.renderCommunication(templateUtilities, combinedPatient)}</li>
|
|
1448
1455
|
</ul>
|
|
1449
1456
|
</div>`;
|
|
1457
|
+
return html;
|
|
1450
1458
|
}
|
|
1451
1459
|
/**
|
|
1452
1460
|
* Combines multiple patient resources into a single patient object
|
|
@@ -1771,7 +1779,9 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
|
|
|
1771
1779
|
generateSummaryNarrative(resources, timezone) {
|
|
1772
1780
|
const templateUtilities = new TemplateUtilities(resources);
|
|
1773
1781
|
let isSummaryCreated = false;
|
|
1774
|
-
let html =
|
|
1782
|
+
let html = `<p>This list includes all AllergyIntolerance resources, with no additional filtering, sorted as provided.</p>
|
|
1783
|
+
`;
|
|
1784
|
+
html += `
|
|
1775
1785
|
<div>
|
|
1776
1786
|
<table>
|
|
1777
1787
|
<thead>
|
|
@@ -1810,7 +1820,7 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
|
|
|
1810
1820
|
isSummaryCreated = true;
|
|
1811
1821
|
html += `
|
|
1812
1822
|
<tr>
|
|
1813
|
-
<td>${data["allergen"] ?? ""}</td>
|
|
1823
|
+
<td>${templateUtilities.capitalizeFirstLetter(data["allergen"] ?? "")}</td>
|
|
1814
1824
|
<td>${data["codeSystem"] ?? ""}</td>
|
|
1815
1825
|
<td>${data["criticality"] ?? ""}</td>
|
|
1816
1826
|
<td>${templateUtilities.renderTime(data["recordedDate"], timezone) ?? ""}</td>
|
|
@@ -1853,7 +1863,8 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
|
|
|
1853
1863
|
const dateB = b.onsetDateTime;
|
|
1854
1864
|
return dateA && dateB ? new Date(dateB).getTime() - new Date(dateA).getTime() : 0;
|
|
1855
1865
|
});
|
|
1856
|
-
let html =
|
|
1866
|
+
let html = `<p>This list includes all AllergyIntolerance resources, with no additional filtering, sorted as provided.</p>
|
|
1867
|
+
`;
|
|
1857
1868
|
html += `
|
|
1858
1869
|
<div class="ActiveAllergies">
|
|
1859
1870
|
<h3>Active</h3>
|
|
@@ -1927,8 +1938,8 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
|
|
|
1927
1938
|
let html = "";
|
|
1928
1939
|
for (const allergy of allergies) {
|
|
1929
1940
|
html += `
|
|
1930
|
-
<tr
|
|
1931
|
-
<td class="Name"><span class="AllergenName">${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(allergy.code))}</span></td>
|
|
1941
|
+
<tr>
|
|
1942
|
+
<td class="Name"><span class="AllergenName">${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(allergy.code)))}</span></td>
|
|
1932
1943
|
<td class="Status">${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(allergy.clinicalStatus)) || ""}</td>
|
|
1933
1944
|
<td class="CodeSystem">${templateUtilities.codeableConceptCoding(allergy.code)}</td>
|
|
1934
1945
|
<td class="Category">${templateUtilities.renderTextAsHtml(templateUtilities.safeConcat(allergy.category)) || ""}</td>
|
|
@@ -1979,7 +1990,8 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
|
|
|
1979
1990
|
let isSummaryCreated = false;
|
|
1980
1991
|
const currentDate = now || /* @__PURE__ */ new Date();
|
|
1981
1992
|
const twoYearsAgo = new Date(currentDate.getFullYear(), currentDate.getMonth() - 24, currentDate.getDate());
|
|
1982
|
-
let html =
|
|
1993
|
+
let html = "<p>This list includes all the medications that were ordered for the patient, the medications they filled from the pharmacy and the medications they reported, filtered to past 2 years and sorted by start date.</p>";
|
|
1994
|
+
html += `
|
|
1983
1995
|
<div>
|
|
1984
1996
|
<table>
|
|
1985
1997
|
<thead>
|
|
@@ -2044,7 +2056,7 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
|
|
|
2044
2056
|
isSummaryCreated = true;
|
|
2045
2057
|
html += `
|
|
2046
2058
|
<tr>
|
|
2047
|
-
<td>${templateUtilities.renderTextAsHtml(data["medication"])}</td>
|
|
2059
|
+
<td>${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(data["medication"]))}</td>
|
|
2048
2060
|
<td>${templateUtilities.codeableConceptCoding(sectionCodeableConcept)}</td>
|
|
2049
2061
|
<td>${templateUtilities.renderTextAsHtml(data["status"])}</td>
|
|
2050
2062
|
<td>${templateUtilities.renderTextAsHtml(data["sig-prescriber"] || data["sig-pharmacy"])}</td>
|
|
@@ -2091,8 +2103,8 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
|
|
|
2091
2103
|
static generateStaticNarrative(resources, timezone, now) {
|
|
2092
2104
|
const templateUtilities = new TemplateUtilities(resources);
|
|
2093
2105
|
let html = "";
|
|
2094
|
-
const medicationRequests =
|
|
2095
|
-
const medicationStatements =
|
|
2106
|
+
const medicationRequests = resources.filter((entry) => entry.resourceType === "MedicationRequest");
|
|
2107
|
+
const medicationStatements = resources.filter((entry) => entry.resourceType === "MedicationStatement");
|
|
2096
2108
|
const allActiveMedications = [];
|
|
2097
2109
|
const currentDate = now || /* @__PURE__ */ new Date();
|
|
2098
2110
|
const twoYearsAgo = new Date(currentDate);
|
|
@@ -2100,10 +2112,10 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
|
|
|
2100
2112
|
let skippedMedications = 0;
|
|
2101
2113
|
const allMedications = [];
|
|
2102
2114
|
medicationRequests.forEach((mr) => {
|
|
2103
|
-
allMedications.push({ type: "request", resource: mr
|
|
2115
|
+
allMedications.push({ type: "request", resource: mr });
|
|
2104
2116
|
});
|
|
2105
2117
|
medicationStatements.forEach((ms) => {
|
|
2106
|
-
allMedications.push({ type: "statement", resource: ms
|
|
2118
|
+
allMedications.push({ type: "statement", resource: ms });
|
|
2107
2119
|
});
|
|
2108
2120
|
for (const med of allMedications) {
|
|
2109
2121
|
let dateString;
|
|
@@ -2160,36 +2172,6 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
|
|
|
2160
2172
|
}
|
|
2161
2173
|
return "";
|
|
2162
2174
|
}
|
|
2163
|
-
/**
|
|
2164
|
-
* Extract MedicationRequest resources
|
|
2165
|
-
* @param templateUtilities - Instance of TemplateUtilities for utility functions
|
|
2166
|
-
* @param resources - FHIR Medication resources
|
|
2167
|
-
* @returns Array of MedicationRequest resources
|
|
2168
|
-
*/
|
|
2169
|
-
static getMedicationRequests(templateUtilities, resources) {
|
|
2170
|
-
if (resources.length === 0) {
|
|
2171
|
-
return [];
|
|
2172
|
-
}
|
|
2173
|
-
return resources.filter((entry) => entry.resourceType === "MedicationRequest").map((entry) => ({
|
|
2174
|
-
resource: entry,
|
|
2175
|
-
extension: templateUtilities.narrativeLinkExtension(entry)
|
|
2176
|
-
}));
|
|
2177
|
-
}
|
|
2178
|
-
/**
|
|
2179
|
-
* Extract MedicationStatement resources
|
|
2180
|
-
* @param templateUtilities - Instance of TemplateUtilities for utility functions
|
|
2181
|
-
* @param resources - FHIR Medication resources
|
|
2182
|
-
* @returns Array of MedicationStatement resources
|
|
2183
|
-
*/
|
|
2184
|
-
static getMedicationStatements(templateUtilities, resources) {
|
|
2185
|
-
if (resources.length === 0) {
|
|
2186
|
-
return [];
|
|
2187
|
-
}
|
|
2188
|
-
return resources.filter((entry) => entry.resourceType === "MedicationStatement").map((entry) => ({
|
|
2189
|
-
resource: entry,
|
|
2190
|
-
extension: templateUtilities.narrativeLinkExtension(entry)
|
|
2191
|
-
}));
|
|
2192
|
-
}
|
|
2193
2175
|
/**
|
|
2194
2176
|
* Render HTML table for combined MedicationRequest and MedicationStatement resources
|
|
2195
2177
|
* @param templateUtilities - Instance of TemplateUtilities for utility functions
|
|
@@ -2213,7 +2195,6 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
|
|
|
2213
2195
|
</thead>
|
|
2214
2196
|
<tbody>`;
|
|
2215
2197
|
for (const medication of medications) {
|
|
2216
|
-
const narrativeLinkId = templateUtilities.narrativeLinkId(medication.extension);
|
|
2217
2198
|
let type;
|
|
2218
2199
|
let medicationName;
|
|
2219
2200
|
let sig;
|
|
@@ -2260,9 +2241,9 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
|
|
|
2260
2241
|
}
|
|
2261
2242
|
}
|
|
2262
2243
|
html += `
|
|
2263
|
-
<tr
|
|
2244
|
+
<tr>
|
|
2264
2245
|
<td>${type}</td>
|
|
2265
|
-
<td>${medicationName}
|
|
2246
|
+
<td>${templateUtilities.capitalizeFirstLetter(medicationName)}</td>
|
|
2266
2247
|
<td>${codeSystemDisplay}</td>
|
|
2267
2248
|
<td>${sig}</td>
|
|
2268
2249
|
<td>${dispenseQuantity}</td>
|
|
@@ -2305,6 +2286,7 @@ var ImmunizationsTemplate = class _ImmunizationsTemplate {
|
|
|
2305
2286
|
let isSummaryCreated = false;
|
|
2306
2287
|
let html = `
|
|
2307
2288
|
<div>
|
|
2289
|
+
<p>This list includes all vaccinations, sorted by occurrence date (most recent first).</p>
|
|
2308
2290
|
<table>
|
|
2309
2291
|
<thead>
|
|
2310
2292
|
<tr>
|
|
@@ -2343,7 +2325,7 @@ var ImmunizationsTemplate = class _ImmunizationsTemplate {
|
|
|
2343
2325
|
isSummaryCreated = true;
|
|
2344
2326
|
html += `
|
|
2345
2327
|
<tr>
|
|
2346
|
-
<td>${data["immunization"] ?? ""}</td>
|
|
2328
|
+
<td>${templateUtilities.capitalizeFirstLetter(data["immunization"] ?? "")}</td>
|
|
2347
2329
|
<td>${data["codeSystem"] ?? ""}</td>
|
|
2348
2330
|
<td>${data["status"] ?? ""}</td>
|
|
2349
2331
|
<td>${templateUtilities.renderTime(data["occurrenceDateTime"], timezone) ?? ""}</td>
|
|
@@ -2387,8 +2369,8 @@ var ImmunizationsTemplate = class _ImmunizationsTemplate {
|
|
|
2387
2369
|
for (const resourceItem of immunizations) {
|
|
2388
2370
|
const imm = resourceItem;
|
|
2389
2371
|
html += `
|
|
2390
|
-
<tr
|
|
2391
|
-
<td>${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(imm.vaccineCode))}</td>
|
|
2372
|
+
<tr>
|
|
2373
|
+
<td>${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(imm.vaccineCode)))}</td>
|
|
2392
2374
|
<td>${templateUtilities.codeableConceptCoding(imm.vaccineCode)}</td>
|
|
2393
2375
|
<td>${imm.status || ""}</td>
|
|
2394
2376
|
<td>${templateUtilities.concatDoseNumber(imm.protocolApplied)}</td>
|
|
@@ -2427,7 +2409,8 @@ var ProblemListTemplate = class _ProblemListTemplate {
|
|
|
2427
2409
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2428
2410
|
static generateStaticNarrative(resources, timezone) {
|
|
2429
2411
|
const templateUtilities = new TemplateUtilities(resources);
|
|
2430
|
-
let html =
|
|
2412
|
+
let html = `<p>This list includes patient problems, sorted by recorded date (most recent first)</p>
|
|
2413
|
+
`;
|
|
2431
2414
|
const activeConditions = resources.map((entry) => entry) || [];
|
|
2432
2415
|
activeConditions.sort((a, b) => {
|
|
2433
2416
|
if (!a.recordedDate && b.recordedDate) return -1;
|
|
@@ -2457,8 +2440,8 @@ var ProblemListTemplate = class _ProblemListTemplate {
|
|
|
2457
2440
|
continue;
|
|
2458
2441
|
}
|
|
2459
2442
|
seenCodeAndSystems.add(codeAndSystem);
|
|
2460
|
-
html += `<tr
|
|
2461
|
-
<td class="Name">${conditionDisplay}</td>
|
|
2443
|
+
html += `<tr>
|
|
2444
|
+
<td class="Name">${templateUtilities.capitalizeFirstLetter(conditionDisplay)}</td>
|
|
2462
2445
|
<td class="CodeSystem">${codeAndSystem}</td>
|
|
2463
2446
|
<td class="OnsetDate">${templateUtilities.renderDate(cond.onsetDateTime)}</td>
|
|
2464
2447
|
<td class="RecordedDate">${templateUtilities.renderDate(cond.recordedDate)}</td>
|
|
@@ -2491,7 +2474,9 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
|
|
|
2491
2474
|
generateSummaryNarrative(resources, timezone) {
|
|
2492
2475
|
const templateUtilities = new TemplateUtilities(resources);
|
|
2493
2476
|
let isSummaryCreated = false;
|
|
2494
|
-
let html =
|
|
2477
|
+
let html = `<p>This list includes the latest vital signs, sorted by effective date (most recent first).</p>
|
|
2478
|
+
`;
|
|
2479
|
+
html += `
|
|
2495
2480
|
<div>
|
|
2496
2481
|
<table>
|
|
2497
2482
|
<thead>
|
|
@@ -2536,7 +2521,7 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
|
|
|
2536
2521
|
isSummaryCreated = true;
|
|
2537
2522
|
html += `
|
|
2538
2523
|
<tr>
|
|
2539
|
-
<td>${data["Vital Name"] ?? ""}</td>
|
|
2524
|
+
<td>${templateUtilities.capitalizeFirstLetter(data["Vital Name"] ?? "")}</td>
|
|
2540
2525
|
<td>${data["codeSystem"] ?? ""}</td>
|
|
2541
2526
|
<td>${templateUtilities.extractObservationSummaryValue(data, timezone) ?? ""}</td>
|
|
2542
2527
|
<td>${templateUtilities.extractObservationSummaryEffectiveTime(data, timezone) ?? ""}</td>
|
|
@@ -2564,7 +2549,9 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
|
|
|
2564
2549
|
const dateB = b.effectiveDateTime || b.effectivePeriod?.start;
|
|
2565
2550
|
return dateA && dateB ? new Date(dateB).getTime() - new Date(dateA).getTime() : 0;
|
|
2566
2551
|
});
|
|
2567
|
-
let html =
|
|
2552
|
+
let html = `<p>This list includes the latest vital signs, sorted by effective date (most recent first).</p>
|
|
2553
|
+
`;
|
|
2554
|
+
html += `
|
|
2568
2555
|
<table>
|
|
2569
2556
|
<thead>
|
|
2570
2557
|
<tr>
|
|
@@ -2582,8 +2569,8 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
|
|
|
2582
2569
|
<tbody>`;
|
|
2583
2570
|
for (const obs of observations) {
|
|
2584
2571
|
html += `
|
|
2585
|
-
<tr
|
|
2586
|
-
<td>${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(obs.code, "display"))}</td>
|
|
2572
|
+
<tr>
|
|
2573
|
+
<td>${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(obs.code, "display")))}</td>
|
|
2587
2574
|
<td>${templateUtilities.codeableConceptCoding(obs.code)}</td>
|
|
2588
2575
|
<td>${templateUtilities.extractObservationValue(obs)}</td>
|
|
2589
2576
|
<td>${templateUtilities.extractObservationValueUnit(obs)}</td>
|
|
@@ -2620,7 +2607,7 @@ var MedicalDevicesTemplate = class _MedicalDevicesTemplate {
|
|
|
2620
2607
|
*/
|
|
2621
2608
|
static generateStaticNarrative(resources, timezone) {
|
|
2622
2609
|
const templateUtilities = new TemplateUtilities(resources);
|
|
2623
|
-
let html =
|
|
2610
|
+
let html = `<p>This list includes all DeviceUseStatement resources, sorted by recorded date (most recent first).</p>
|
|
2624
2611
|
<table>
|
|
2625
2612
|
<thead>
|
|
2626
2613
|
<tr>
|
|
@@ -2636,10 +2623,12 @@ var MedicalDevicesTemplate = class _MedicalDevicesTemplate {
|
|
|
2636
2623
|
const dateB = b.recordedOn;
|
|
2637
2624
|
return typeof dateA === "string" && typeof dateB === "string" ? new Date(dateB).getTime() - new Date(dateA).getTime() : 0;
|
|
2638
2625
|
});
|
|
2626
|
+
let isDeviceAdded = false;
|
|
2639
2627
|
for (const dus of deviceStatements) {
|
|
2628
|
+
isDeviceAdded = true;
|
|
2640
2629
|
html += `
|
|
2641
|
-
<tr
|
|
2642
|
-
<td>${templateUtilities.renderTextAsHtml(templateUtilities.renderDevice(dus.device))}</td>
|
|
2630
|
+
<tr>
|
|
2631
|
+
<td>${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(templateUtilities.renderDevice(dus.device)))}</td>
|
|
2643
2632
|
<td>${templateUtilities.renderTextAsHtml(dus.status || "")}</td>
|
|
2644
2633
|
<td>${templateUtilities.renderNotes(dus.note, timezone)}</td>
|
|
2645
2634
|
<td>${templateUtilities.renderTextAsHtml(templateUtilities.renderRecorded(dus.recordedOn, timezone))}</td>
|
|
@@ -2648,7 +2637,7 @@ var MedicalDevicesTemplate = class _MedicalDevicesTemplate {
|
|
|
2648
2637
|
html += `
|
|
2649
2638
|
</tbody>
|
|
2650
2639
|
</table>`;
|
|
2651
|
-
return html;
|
|
2640
|
+
return isDeviceAdded ? html : void 0;
|
|
2652
2641
|
}
|
|
2653
2642
|
};
|
|
2654
2643
|
|
|
@@ -2999,11 +2988,12 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2999
2988
|
}
|
|
3000
2989
|
}
|
|
3001
2990
|
}
|
|
3002
|
-
let html =
|
|
3003
|
-
|
|
2991
|
+
let html = `<p>This section includes Observations from the last 2 years (one per lab name, using code mapping) and DiagnosticReports with status 'final' issued in the last 2 years. Both are sorted by date (most recent first). Older results are counted and noted below the tables.</p>
|
|
2992
|
+
`;
|
|
3004
2993
|
let observationhtml = `
|
|
3005
2994
|
<div>
|
|
3006
2995
|
<h3>Observations</h3>
|
|
2996
|
+
${html}
|
|
3007
2997
|
<table>
|
|
3008
2998
|
<thead>
|
|
3009
2999
|
<tr>
|
|
@@ -3019,6 +3009,7 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
3019
3009
|
let diagnosticReporthtml = `
|
|
3020
3010
|
<div>
|
|
3021
3011
|
<h3>Diagnostic Reports</h3>
|
|
3012
|
+
${html}
|
|
3022
3013
|
<table>
|
|
3023
3014
|
<thead>
|
|
3024
3015
|
<tr>
|
|
@@ -3103,7 +3094,7 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
3103
3094
|
this.formatSummaryObservationData(component);
|
|
3104
3095
|
observationhtml += `
|
|
3105
3096
|
<tr>
|
|
3106
|
-
<td>${componentCode}</td>
|
|
3097
|
+
<td>${templateUtilities.capitalizeFirstLetter(componentCode)}</td>
|
|
3107
3098
|
<td></td>
|
|
3108
3099
|
<td>${templateUtilities.renderTextAsHtml(component["formattedValue"]) ?? ""}</td>
|
|
3109
3100
|
<td>${templateUtilities.renderTextAsHtml(component["referenceRange"])?.trim() ?? ""}</td>
|
|
@@ -3120,7 +3111,7 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
3120
3111
|
this.formatSummaryObservationData(data);
|
|
3121
3112
|
observationhtml += `
|
|
3122
3113
|
<tr>
|
|
3123
|
-
<td>${data["code"] ?? ""}</td>
|
|
3114
|
+
<td>${templateUtilities.capitalizeFirstLetter(data["code"] ?? "")}</td>
|
|
3124
3115
|
<td>${templateUtilities.codeableConceptCoding(sectionCodeableConcept)}</td>
|
|
3125
3116
|
<td>${templateUtilities.renderTextAsHtml(data["formattedValue"]) ?? ""}</td>
|
|
3126
3117
|
<td>${templateUtilities.renderTextAsHtml(data["referenceRange"])?.trim() ?? ""}</td>
|
|
@@ -3141,7 +3132,7 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
3141
3132
|
diagnosticReportAdded.add(reportName);
|
|
3142
3133
|
diagnosticReporthtml += `
|
|
3143
3134
|
<tr>
|
|
3144
|
-
<td>${data["report"] ?? ""}</td>
|
|
3135
|
+
<td>${templateUtilities.capitalizeFirstLetter(data["report"] ?? "")}</td>
|
|
3145
3136
|
<td>${data["performer"] ?? ""}</td>
|
|
3146
3137
|
<td>${templateUtilities.renderTime(data["issued"], timezone) ?? ""}</td>
|
|
3147
3138
|
<td>${data["source"] ?? ""}</td>
|
|
@@ -3189,7 +3180,8 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
3189
3180
|
const currentDate = now || /* @__PURE__ */ new Date();
|
|
3190
3181
|
const twoYearsAgo = new Date(currentDate);
|
|
3191
3182
|
twoYearsAgo.setFullYear(currentDate.getFullYear() - 2);
|
|
3192
|
-
let html =
|
|
3183
|
+
let html = `<p>This section includes Observations from the last 2 years (one per lab name, using code mapping) and DiagnosticReports with status 'final' issued in the last 2 years. Both are sorted by date (most recent first). Older results are counted and noted below the tables.</p>
|
|
3184
|
+
`;
|
|
3193
3185
|
let skippedObservations = 0;
|
|
3194
3186
|
let skippedDiagnosticReports = 0;
|
|
3195
3187
|
for (const resourceItem of resources) {
|
|
@@ -3340,8 +3332,8 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
3340
3332
|
observationAdded.add(obsCodeDisplay);
|
|
3341
3333
|
observationAdded.add(obsCodeAndSystem);
|
|
3342
3334
|
html += `
|
|
3343
|
-
<tr
|
|
3344
|
-
<td>${obsCodeDisplay}</td>
|
|
3335
|
+
<tr>
|
|
3336
|
+
<td>${templateUtilities.capitalizeFirstLetter(obsCodeDisplay)}</td>
|
|
3345
3337
|
<td>${templateUtilities.codeableConceptCoding(obs.code)}</td>
|
|
3346
3338
|
<td>${templateUtilities.extractObservationValue(obs)}</td>
|
|
3347
3339
|
<td>${templateUtilities.concatReferenceRange(obs.referenceRange)}</td>
|
|
@@ -3389,8 +3381,8 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
3389
3381
|
resultCount = `${report.result.length} result${report.result.length !== 1 ? "s" : ""}`;
|
|
3390
3382
|
}
|
|
3391
3383
|
html += `
|
|
3392
|
-
<tr
|
|
3393
|
-
<td>${reportName}</td>
|
|
3384
|
+
<tr>
|
|
3385
|
+
<td>${templateUtilities.capitalizeFirstLetter(reportName)}</td>
|
|
3394
3386
|
<td>${codeAndSystem}</td>
|
|
3395
3387
|
<td>${templateUtilities.firstFromCodeableConceptList(report.category)}</td>
|
|
3396
3388
|
<td>${resultCount}</td>
|
|
@@ -3451,7 +3443,9 @@ var HistoryOfProceduresTemplate = class _HistoryOfProceduresTemplate {
|
|
|
3451
3443
|
generateSummaryNarrative(resources, timezone) {
|
|
3452
3444
|
const templateUtilities = new TemplateUtilities(resources);
|
|
3453
3445
|
let isSummaryCreated = false;
|
|
3454
|
-
let html =
|
|
3446
|
+
let html = `<p>This list includes all Procedure resources, sorted by performed date (most recent first).</p>
|
|
3447
|
+
`;
|
|
3448
|
+
html += `
|
|
3455
3449
|
<div>
|
|
3456
3450
|
<table>
|
|
3457
3451
|
<thead>
|
|
@@ -3490,7 +3484,7 @@ var HistoryOfProceduresTemplate = class _HistoryOfProceduresTemplate {
|
|
|
3490
3484
|
isSummaryCreated = true;
|
|
3491
3485
|
html += `
|
|
3492
3486
|
<tr>
|
|
3493
|
-
<td>${data["procedure"] ?? ""}</td>
|
|
3487
|
+
<td>${templateUtilities.capitalizeFirstLetter(data["procedure"] ?? "")}</td>
|
|
3494
3488
|
<td>${data["codeSystem"] ?? ""}</td>
|
|
3495
3489
|
<td>${data["performer"] ?? ""}</td>
|
|
3496
3490
|
<td>${templateUtilities.renderTime(data["date"], timezone) ?? ""}</td>
|
|
@@ -3512,7 +3506,9 @@ var HistoryOfProceduresTemplate = class _HistoryOfProceduresTemplate {
|
|
|
3512
3506
|
*/
|
|
3513
3507
|
static generateStaticNarrative(resources, timezone) {
|
|
3514
3508
|
const templateUtilities = new TemplateUtilities(resources);
|
|
3515
|
-
let html =
|
|
3509
|
+
let html = `<p>This list includes all Procedure resources, sorted by performed date (most recent first).</p>
|
|
3510
|
+
`;
|
|
3511
|
+
html += `
|
|
3516
3512
|
<table>
|
|
3517
3513
|
<thead>
|
|
3518
3514
|
<tr>
|
|
@@ -3527,12 +3523,12 @@ var HistoryOfProceduresTemplate = class _HistoryOfProceduresTemplate {
|
|
|
3527
3523
|
for (const resourceItem of resources) {
|
|
3528
3524
|
const proc = resourceItem;
|
|
3529
3525
|
html += `
|
|
3530
|
-
<tr
|
|
3531
|
-
<td>${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(proc.code, "display"))}</td>
|
|
3532
|
-
|
|
3526
|
+
<tr>
|
|
3527
|
+
<td>${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(proc.code, "display")))}</td>
|
|
3528
|
+
<td>${templateUtilities.codeableConceptCoding(proc.code)}</td>
|
|
3533
3529
|
<td>${templateUtilities.renderNotes(proc.note, timezone)}</td>
|
|
3534
|
-
<td>${
|
|
3535
|
-
|
|
3530
|
+
<td>${templateUtilities.renderTime(proc.performedDateTime || proc.performedPeriod?.start, timezone)}</td>
|
|
3531
|
+
<td>${templateUtilities.getOwnerTag(proc)}</td>
|
|
3536
3532
|
</tr>`;
|
|
3537
3533
|
}
|
|
3538
3534
|
html += `
|
|
@@ -3567,7 +3563,9 @@ var SocialHistoryTemplate = class _SocialHistoryTemplate {
|
|
|
3567
3563
|
const dateB = b.effectiveDateTime || b.effectivePeriod?.start;
|
|
3568
3564
|
return dateA && dateB ? new Date(dateB).getTime() - new Date(dateA).getTime() : 0;
|
|
3569
3565
|
});
|
|
3570
|
-
let html =
|
|
3566
|
+
let html = `<p>This list includes all information about the patient's social history, sorted by effective date (most recent first).</p>
|
|
3567
|
+
`;
|
|
3568
|
+
html += `
|
|
3571
3569
|
<table>
|
|
3572
3570
|
<thead>
|
|
3573
3571
|
<tr>
|
|
@@ -3581,17 +3579,22 @@ var SocialHistoryTemplate = class _SocialHistoryTemplate {
|
|
|
3581
3579
|
</tr>
|
|
3582
3580
|
</thead>
|
|
3583
3581
|
<tbody>`;
|
|
3582
|
+
const addedObservations = /* @__PURE__ */ new Set();
|
|
3584
3583
|
for (const obs of observations) {
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
<
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3584
|
+
const obsName = templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(obs.code));
|
|
3585
|
+
if (!addedObservations.has(obsName)) {
|
|
3586
|
+
addedObservations.add(obsName);
|
|
3587
|
+
html += `
|
|
3588
|
+
<tr>
|
|
3589
|
+
<td>${templateUtilities.capitalizeFirstLetter(obsName)}</td>
|
|
3590
|
+
<td>${templateUtilities.codeableConceptCoding(obs.code)}</td>
|
|
3591
|
+
<td>${templateUtilities.extractObservationValue(obs)}</td>
|
|
3592
|
+
<td>${templateUtilities.extractObservationValueUnit(obs)}</td>
|
|
3593
|
+
<td>${templateUtilities.renderNotes(obs.note, timezone)}</td>
|
|
3594
|
+
<td>${obs.effectiveDateTime ? templateUtilities.renderTime(obs.effectiveDateTime, timezone) : obs.effectivePeriod ? templateUtilities.renderPeriod(obs.effectivePeriod, timezone) : ""}</td>
|
|
3595
|
+
<td>${templateUtilities.getOwnerTag(obs)}</td>
|
|
3596
|
+
</tr>`;
|
|
3597
|
+
}
|
|
3595
3598
|
}
|
|
3596
3599
|
html += `
|
|
3597
3600
|
</tbody>
|
|
@@ -3611,7 +3614,8 @@ var PastHistoryOfIllnessTemplate = class {
|
|
|
3611
3614
|
*/
|
|
3612
3615
|
generateNarrative(resources, timezone, now) {
|
|
3613
3616
|
const templateUtilities = new TemplateUtilities(resources);
|
|
3614
|
-
let html =
|
|
3617
|
+
let html = `<p>This list includes past problems for the patient with a recorded date within the last 5 years, sorted by recorded date (most recent first).</p>
|
|
3618
|
+
`;
|
|
3615
3619
|
const resolvedConditions = resources.map((entry) => entry) || [];
|
|
3616
3620
|
const currentDate = now || /* @__PURE__ */ new Date();
|
|
3617
3621
|
const fiveYearsAgo = new Date(currentDate);
|
|
@@ -3648,8 +3652,8 @@ var PastHistoryOfIllnessTemplate = class {
|
|
|
3648
3652
|
const conditionCode = templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(cond.code));
|
|
3649
3653
|
if (!addedConditionCodes.has(conditionCode)) {
|
|
3650
3654
|
addedConditionCodes.add(conditionCode);
|
|
3651
|
-
html += `<tr
|
|
3652
|
-
<td class="Name">${conditionCode}</td>
|
|
3655
|
+
html += `<tr>
|
|
3656
|
+
<td class="Name">${templateUtilities.capitalizeFirstLetter(conditionCode)}</td>
|
|
3653
3657
|
<td class="CodeSystem">${templateUtilities.codeableConceptCoding(cond.code)}</td>
|
|
3654
3658
|
<td class="OnsetDate">${templateUtilities.renderDate(cond.onsetDateTime)}</td>
|
|
3655
3659
|
<td class="RecordedDate">${templateUtilities.renderDate(cond.recordedDate)}</td>
|
|
@@ -3684,7 +3688,9 @@ var PlanOfCareTemplate = class {
|
|
|
3684
3688
|
const endB = b.period?.end ? new Date(b.period?.end).getTime() : 0;
|
|
3685
3689
|
return endB - endA;
|
|
3686
3690
|
});
|
|
3687
|
-
let html =
|
|
3691
|
+
let html = `<p>This list includes all CarePlan resources, sorted by planned end date (most recent first).</p>
|
|
3692
|
+
`;
|
|
3693
|
+
html += `
|
|
3688
3694
|
<table>
|
|
3689
3695
|
<thead>
|
|
3690
3696
|
<tr>
|
|
@@ -3699,8 +3705,8 @@ var PlanOfCareTemplate = class {
|
|
|
3699
3705
|
<tbody>`;
|
|
3700
3706
|
for (const cp of carePlans) {
|
|
3701
3707
|
html += `
|
|
3702
|
-
<tr
|
|
3703
|
-
<td>${cp.description || cp.title || ""}</td>
|
|
3708
|
+
<tr>
|
|
3709
|
+
<td>${templateUtilities.capitalizeFirstLetter(cp.description || cp.title || "")}</td>
|
|
3704
3710
|
<td>${cp.intent || ""}</td>
|
|
3705
3711
|
<td>${templateUtilities.concat(cp.note, "text")}</td>
|
|
3706
3712
|
<td>${cp.period?.start ? templateUtilities.renderTime(cp.period?.start, timezone) : ""}</td>
|
|
@@ -3722,7 +3728,9 @@ var PlanOfCareTemplate = class {
|
|
|
3722
3728
|
generateSummaryNarrative(resources, timezone) {
|
|
3723
3729
|
const templateUtilities = new TemplateUtilities(resources);
|
|
3724
3730
|
let isSummaryCreated = false;
|
|
3725
|
-
let html =
|
|
3731
|
+
let html = `<p>This list includes all CarePlan resources, sorted by planned end date (most recent first).</p>
|
|
3732
|
+
`;
|
|
3733
|
+
html += `
|
|
3726
3734
|
<div>
|
|
3727
3735
|
<table>
|
|
3728
3736
|
<thead>
|
|
@@ -3749,7 +3757,7 @@ var PlanOfCareTemplate = class {
|
|
|
3749
3757
|
isSummaryCreated = true;
|
|
3750
3758
|
html += `
|
|
3751
3759
|
<tr>
|
|
3752
|
-
<td>${data["CarePlan Name"] ?? ""}</td>
|
|
3760
|
+
<td>${templateUtilities.capitalizeFirstLetter(data["CarePlan Name"] ?? "")}</td>
|
|
3753
3761
|
<td>${templateUtilities.renderTime(data["created"], timezone) ?? ""}</td>
|
|
3754
3762
|
<td>${templateUtilities.renderTime(data["period.start"], timezone) ?? ""}</td>
|
|
3755
3763
|
<td>${templateUtilities.renderTime(data["period.end"], timezone) ?? ""}</td>
|
|
@@ -3784,7 +3792,7 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
|
|
|
3784
3792
|
*/
|
|
3785
3793
|
static generateStaticNarrative(resources, timezone) {
|
|
3786
3794
|
const templateUtilities = new TemplateUtilities(resources);
|
|
3787
|
-
let html =
|
|
3795
|
+
let html = `<p>This section summarizes key observations and assessments related to the person's functional status and ability to perform daily activities.</p>`;
|
|
3788
3796
|
let functionalObservations = resources.filter((r) => r.resourceType === "Observation").filter((r) => {
|
|
3789
3797
|
const hasFunctionalLoinc = r.code?.coding?.some(
|
|
3790
3798
|
(c) => c.system?.toLowerCase().includes("loinc") && c.code === "47420-5"
|
|
@@ -3814,8 +3822,8 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
|
|
|
3814
3822
|
const date = observation.effectiveDateTime ? templateUtilities.renderDate(observation.effectiveDateTime) : observation.issued ? templateUtilities.renderDate(observation.issued) : "";
|
|
3815
3823
|
const interpretation = observation.interpretation ? templateUtilities.codeableConceptDisplay(observation.interpretation[0]) : "";
|
|
3816
3824
|
const comments = observation.comment || observation.note?.map((n) => n.text).join("; ") || "";
|
|
3817
|
-
html += `<tr
|
|
3818
|
-
<td>${obsName}</td>
|
|
3825
|
+
html += `<tr>
|
|
3826
|
+
<td>${templateUtilities.capitalizeFirstLetter(obsName)}</td>
|
|
3819
3827
|
<td>${value ?? ""}</td>
|
|
3820
3828
|
<td>${date}</td>
|
|
3821
3829
|
<td>${interpretation}</td>
|
|
@@ -3845,7 +3853,7 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
|
|
|
3845
3853
|
}
|
|
3846
3854
|
findingsHtml += "</ul>";
|
|
3847
3855
|
}
|
|
3848
|
-
html += `<tr
|
|
3856
|
+
html += `<tr>
|
|
3849
3857
|
<td>${formattedDate}</td>
|
|
3850
3858
|
<td>${impression.status || ""}</td>
|
|
3851
3859
|
<td>${impression.description || ""}</td>
|
|
@@ -3908,7 +3916,8 @@ var PregnancyTemplate = class _PregnancyTemplate {
|
|
|
3908
3916
|
if (!pregnancyStatusObs && !eddObs && historyObs.length === 0 && conditions.length === 0) {
|
|
3909
3917
|
return `<p>No history of pregnancy found.</p>`;
|
|
3910
3918
|
}
|
|
3911
|
-
let html =
|
|
3919
|
+
let html = `<p>This list includes Observation and Condition resources relevant to pregnancy, sorted by date (most recent first).</p>`;
|
|
3920
|
+
html += `
|
|
3912
3921
|
<table>
|
|
3913
3922
|
<thead>
|
|
3914
3923
|
<tr>
|
|
@@ -3920,10 +3929,10 @@ var PregnancyTemplate = class _PregnancyTemplate {
|
|
|
3920
3929
|
</tr>
|
|
3921
3930
|
</thead>
|
|
3922
3931
|
<tbody>`;
|
|
3923
|
-
function renderRow({
|
|
3932
|
+
function renderRow({ result, comments, date, codeSystem, owner }) {
|
|
3924
3933
|
html += `
|
|
3925
|
-
<tr
|
|
3926
|
-
<td class="Result">${result}</td>
|
|
3934
|
+
<tr>
|
|
3935
|
+
<td class="Result">${templateUtilities.capitalizeFirstLetter(result)}</td>
|
|
3927
3936
|
<td class="CodeSystem">${codeSystem}</td>
|
|
3928
3937
|
<td class="Comments">${comments}</td>
|
|
3929
3938
|
<td class="Date">${date}</td>
|
|
@@ -3954,9 +3963,9 @@ var PregnancyTemplate = class _PregnancyTemplate {
|
|
|
3954
3963
|
if (!b.date) return -1;
|
|
3955
3964
|
return new Date(b.date).getTime() - new Date(a.date).getTime();
|
|
3956
3965
|
});
|
|
3966
|
+
const addedRows = /* @__PURE__ */ new Set();
|
|
3957
3967
|
for (const { resource, date, type } of rowResources) {
|
|
3958
3968
|
let result = "", comments = "", dateStr = "", codeSystem = "";
|
|
3959
|
-
const id = templateUtilities.narrativeLinkId(resource);
|
|
3960
3969
|
if (type === "status") {
|
|
3961
3970
|
result = templateUtilities.renderTextAsHtml(templateUtilities.extractPregnancyStatus(resource));
|
|
3962
3971
|
comments = templateUtilities.renderNotes(resource.note, timezone);
|
|
@@ -3978,8 +3987,12 @@ var PregnancyTemplate = class _PregnancyTemplate {
|
|
|
3978
3987
|
dateStr = date ? templateUtilities.renderTextAsHtml(templateUtilities.renderTime(date, timezone)) : "";
|
|
3979
3988
|
codeSystem = templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptCoding(resource.code));
|
|
3980
3989
|
}
|
|
3981
|
-
const
|
|
3982
|
-
|
|
3990
|
+
const rowKey = `${result}|${codeSystem}`;
|
|
3991
|
+
if (!addedRows.has(rowKey)) {
|
|
3992
|
+
addedRows.add(rowKey);
|
|
3993
|
+
const owner = templateUtilities.getOwnerTag(resource);
|
|
3994
|
+
renderRow({ result, comments, date: dateStr, codeSystem, owner });
|
|
3995
|
+
}
|
|
3983
3996
|
}
|
|
3984
3997
|
html += `
|
|
3985
3998
|
</tbody>
|
|
@@ -4013,8 +4026,9 @@ var AdvanceDirectivesTemplate = class _AdvanceDirectivesTemplate {
|
|
|
4013
4026
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
4014
4027
|
static generateStaticNarrative(resources, timezone) {
|
|
4015
4028
|
const templateUtilities = new TemplateUtilities(resources);
|
|
4016
|
-
let html =
|
|
4017
|
-
|
|
4029
|
+
let html = `<p>This list includes all Consent resources, sorted by date (most recent first).</p>
|
|
4030
|
+
`;
|
|
4031
|
+
html += `<table>
|
|
4018
4032
|
<thead>
|
|
4019
4033
|
<tr>
|
|
4020
4034
|
<th>Scope</th>
|
|
@@ -4027,8 +4041,8 @@ var AdvanceDirectivesTemplate = class _AdvanceDirectivesTemplate {
|
|
|
4027
4041
|
for (const resourceItem of resources) {
|
|
4028
4042
|
const consent = resourceItem;
|
|
4029
4043
|
html += `
|
|
4030
|
-
<tr
|
|
4031
|
-
<td>${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(consent.scope, "display"))}</td>
|
|
4044
|
+
<tr>
|
|
4045
|
+
<td>${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(consent.scope, "display")))}</td>
|
|
4032
4046
|
<td>${consent.status || ""}</td>
|
|
4033
4047
|
<td>${consent.provision?.action ? templateUtilities.concatCodeableConcept(consent.provision.action) : ""}</td>
|
|
4034
4048
|
<td>${consent.dateTime || ""}</td>
|
|
@@ -4343,14 +4357,17 @@ var ComprehensiveIPSCompositionBuilder = class {
|
|
|
4343
4357
|
const summaryIPSCompositionFilter = useSummaryCompositions ? IPSSectionResourceHelper.getSummaryIPSCompositionFilterForSection(sectionType) : void 0;
|
|
4344
4358
|
const sectionIPSSummary = summaryIPSCompositionFilter ? resources.filter((resource) => summaryIPSCompositionFilter(resource)) : [];
|
|
4345
4359
|
if (sectionIPSSummary.length > 0) {
|
|
4360
|
+
console.log(`Using IPS summary composition for section: ${sectionType}`);
|
|
4346
4361
|
await this.makeSectionFromSummaryAsync(sectionType, sectionIPSSummary, resources, timezone);
|
|
4347
4362
|
continue;
|
|
4348
4363
|
}
|
|
4349
4364
|
const summaryCompositionFilter = useSummaryCompositions ? IPSSectionResourceHelper.getSummaryCompositionFilterForSection(sectionType) : void 0;
|
|
4350
4365
|
const sectionSummary = summaryCompositionFilter ? resources.filter((resource) => summaryCompositionFilter(resource)) : [];
|
|
4351
4366
|
if (sectionSummary.length > 0) {
|
|
4367
|
+
console.log(`Using summary composition for section: ${sectionType}`);
|
|
4352
4368
|
await this.makeSectionFromSummaryAsync(sectionType, sectionSummary, resources, timezone);
|
|
4353
4369
|
} else {
|
|
4370
|
+
console.log(`Using individual resources for section: ${sectionType}`);
|
|
4354
4371
|
const sectionFilter = IPSSectionResourceHelper.getResourceFilterForSection(sectionType);
|
|
4355
4372
|
const sectionResources = resources.filter((resource) => sectionFilter(resource));
|
|
4356
4373
|
await this.makeSectionAsync(sectionType, sectionResources, timezone);
|
package/dist/index.js
CHANGED
|
@@ -910,6 +910,12 @@ var TemplateUtilities = class {
|
|
|
910
910
|
const escapedText = text.replace(/</g, "<").replace(/>/g, ">");
|
|
911
911
|
return escapedText.replace(/\n/g, "<br />");
|
|
912
912
|
}
|
|
913
|
+
capitalizeFirstLetter(text) {
|
|
914
|
+
if (!text || text.length === 0) {
|
|
915
|
+
return "";
|
|
916
|
+
}
|
|
917
|
+
return text.charAt(0).toUpperCase() + text.slice(1);
|
|
918
|
+
}
|
|
913
919
|
/**
|
|
914
920
|
* Renders note elements from a FHIR resource in a standardized format
|
|
915
921
|
* Can render as simple comma-separated text or as styled HTML with timestamps
|
|
@@ -1407,7 +1413,8 @@ var PatientTemplate = class _PatientTemplate {
|
|
|
1407
1413
|
static generateStaticNarrative(resources, timezone) {
|
|
1408
1414
|
const templateUtilities = new TemplateUtilities(resources);
|
|
1409
1415
|
const combinedPatient = this.combinePatients(resources);
|
|
1410
|
-
|
|
1416
|
+
let html = `<p>This section merges all Patient resources into a single combined patient record, preferring non-empty values for each field.</p>`;
|
|
1417
|
+
html += `<div>
|
|
1411
1418
|
<ul>
|
|
1412
1419
|
<li><strong>Name(s):</strong>${this.renderNames(combinedPatient)}</li>
|
|
1413
1420
|
<li><strong>Gender:</strong>${combinedPatient.gender ? this.capitalize(combinedPatient.gender) : ""}</li>
|
|
@@ -1419,6 +1426,7 @@ var PatientTemplate = class _PatientTemplate {
|
|
|
1419
1426
|
<li><strong>Language(s):</strong>${this.renderCommunication(templateUtilities, combinedPatient)}</li>
|
|
1420
1427
|
</ul>
|
|
1421
1428
|
</div>`;
|
|
1429
|
+
return html;
|
|
1422
1430
|
}
|
|
1423
1431
|
/**
|
|
1424
1432
|
* Combines multiple patient resources into a single patient object
|
|
@@ -1743,7 +1751,9 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
|
|
|
1743
1751
|
generateSummaryNarrative(resources, timezone) {
|
|
1744
1752
|
const templateUtilities = new TemplateUtilities(resources);
|
|
1745
1753
|
let isSummaryCreated = false;
|
|
1746
|
-
let html =
|
|
1754
|
+
let html = `<p>This list includes all AllergyIntolerance resources, with no additional filtering, sorted as provided.</p>
|
|
1755
|
+
`;
|
|
1756
|
+
html += `
|
|
1747
1757
|
<div>
|
|
1748
1758
|
<table>
|
|
1749
1759
|
<thead>
|
|
@@ -1782,7 +1792,7 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
|
|
|
1782
1792
|
isSummaryCreated = true;
|
|
1783
1793
|
html += `
|
|
1784
1794
|
<tr>
|
|
1785
|
-
<td>${data["allergen"] ?? ""}</td>
|
|
1795
|
+
<td>${templateUtilities.capitalizeFirstLetter(data["allergen"] ?? "")}</td>
|
|
1786
1796
|
<td>${data["codeSystem"] ?? ""}</td>
|
|
1787
1797
|
<td>${data["criticality"] ?? ""}</td>
|
|
1788
1798
|
<td>${templateUtilities.renderTime(data["recordedDate"], timezone) ?? ""}</td>
|
|
@@ -1825,7 +1835,8 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
|
|
|
1825
1835
|
const dateB = b.onsetDateTime;
|
|
1826
1836
|
return dateA && dateB ? new Date(dateB).getTime() - new Date(dateA).getTime() : 0;
|
|
1827
1837
|
});
|
|
1828
|
-
let html =
|
|
1838
|
+
let html = `<p>This list includes all AllergyIntolerance resources, with no additional filtering, sorted as provided.</p>
|
|
1839
|
+
`;
|
|
1829
1840
|
html += `
|
|
1830
1841
|
<div class="ActiveAllergies">
|
|
1831
1842
|
<h3>Active</h3>
|
|
@@ -1899,8 +1910,8 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
|
|
|
1899
1910
|
let html = "";
|
|
1900
1911
|
for (const allergy of allergies) {
|
|
1901
1912
|
html += `
|
|
1902
|
-
<tr
|
|
1903
|
-
<td class="Name"><span class="AllergenName">${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(allergy.code))}</span></td>
|
|
1913
|
+
<tr>
|
|
1914
|
+
<td class="Name"><span class="AllergenName">${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(allergy.code)))}</span></td>
|
|
1904
1915
|
<td class="Status">${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(allergy.clinicalStatus)) || ""}</td>
|
|
1905
1916
|
<td class="CodeSystem">${templateUtilities.codeableConceptCoding(allergy.code)}</td>
|
|
1906
1917
|
<td class="Category">${templateUtilities.renderTextAsHtml(templateUtilities.safeConcat(allergy.category)) || ""}</td>
|
|
@@ -1951,7 +1962,8 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
|
|
|
1951
1962
|
let isSummaryCreated = false;
|
|
1952
1963
|
const currentDate = now || /* @__PURE__ */ new Date();
|
|
1953
1964
|
const twoYearsAgo = new Date(currentDate.getFullYear(), currentDate.getMonth() - 24, currentDate.getDate());
|
|
1954
|
-
let html =
|
|
1965
|
+
let html = "<p>This list includes all the medications that were ordered for the patient, the medications they filled from the pharmacy and the medications they reported, filtered to past 2 years and sorted by start date.</p>";
|
|
1966
|
+
html += `
|
|
1955
1967
|
<div>
|
|
1956
1968
|
<table>
|
|
1957
1969
|
<thead>
|
|
@@ -2016,7 +2028,7 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
|
|
|
2016
2028
|
isSummaryCreated = true;
|
|
2017
2029
|
html += `
|
|
2018
2030
|
<tr>
|
|
2019
|
-
<td>${templateUtilities.renderTextAsHtml(data["medication"])}</td>
|
|
2031
|
+
<td>${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(data["medication"]))}</td>
|
|
2020
2032
|
<td>${templateUtilities.codeableConceptCoding(sectionCodeableConcept)}</td>
|
|
2021
2033
|
<td>${templateUtilities.renderTextAsHtml(data["status"])}</td>
|
|
2022
2034
|
<td>${templateUtilities.renderTextAsHtml(data["sig-prescriber"] || data["sig-pharmacy"])}</td>
|
|
@@ -2063,8 +2075,8 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
|
|
|
2063
2075
|
static generateStaticNarrative(resources, timezone, now) {
|
|
2064
2076
|
const templateUtilities = new TemplateUtilities(resources);
|
|
2065
2077
|
let html = "";
|
|
2066
|
-
const medicationRequests =
|
|
2067
|
-
const medicationStatements =
|
|
2078
|
+
const medicationRequests = resources.filter((entry) => entry.resourceType === "MedicationRequest");
|
|
2079
|
+
const medicationStatements = resources.filter((entry) => entry.resourceType === "MedicationStatement");
|
|
2068
2080
|
const allActiveMedications = [];
|
|
2069
2081
|
const currentDate = now || /* @__PURE__ */ new Date();
|
|
2070
2082
|
const twoYearsAgo = new Date(currentDate);
|
|
@@ -2072,10 +2084,10 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
|
|
|
2072
2084
|
let skippedMedications = 0;
|
|
2073
2085
|
const allMedications = [];
|
|
2074
2086
|
medicationRequests.forEach((mr) => {
|
|
2075
|
-
allMedications.push({ type: "request", resource: mr
|
|
2087
|
+
allMedications.push({ type: "request", resource: mr });
|
|
2076
2088
|
});
|
|
2077
2089
|
medicationStatements.forEach((ms) => {
|
|
2078
|
-
allMedications.push({ type: "statement", resource: ms
|
|
2090
|
+
allMedications.push({ type: "statement", resource: ms });
|
|
2079
2091
|
});
|
|
2080
2092
|
for (const med of allMedications) {
|
|
2081
2093
|
let dateString;
|
|
@@ -2132,36 +2144,6 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
|
|
|
2132
2144
|
}
|
|
2133
2145
|
return "";
|
|
2134
2146
|
}
|
|
2135
|
-
/**
|
|
2136
|
-
* Extract MedicationRequest resources
|
|
2137
|
-
* @param templateUtilities - Instance of TemplateUtilities for utility functions
|
|
2138
|
-
* @param resources - FHIR Medication resources
|
|
2139
|
-
* @returns Array of MedicationRequest resources
|
|
2140
|
-
*/
|
|
2141
|
-
static getMedicationRequests(templateUtilities, resources) {
|
|
2142
|
-
if (resources.length === 0) {
|
|
2143
|
-
return [];
|
|
2144
|
-
}
|
|
2145
|
-
return resources.filter((entry) => entry.resourceType === "MedicationRequest").map((entry) => ({
|
|
2146
|
-
resource: entry,
|
|
2147
|
-
extension: templateUtilities.narrativeLinkExtension(entry)
|
|
2148
|
-
}));
|
|
2149
|
-
}
|
|
2150
|
-
/**
|
|
2151
|
-
* Extract MedicationStatement resources
|
|
2152
|
-
* @param templateUtilities - Instance of TemplateUtilities for utility functions
|
|
2153
|
-
* @param resources - FHIR Medication resources
|
|
2154
|
-
* @returns Array of MedicationStatement resources
|
|
2155
|
-
*/
|
|
2156
|
-
static getMedicationStatements(templateUtilities, resources) {
|
|
2157
|
-
if (resources.length === 0) {
|
|
2158
|
-
return [];
|
|
2159
|
-
}
|
|
2160
|
-
return resources.filter((entry) => entry.resourceType === "MedicationStatement").map((entry) => ({
|
|
2161
|
-
resource: entry,
|
|
2162
|
-
extension: templateUtilities.narrativeLinkExtension(entry)
|
|
2163
|
-
}));
|
|
2164
|
-
}
|
|
2165
2147
|
/**
|
|
2166
2148
|
* Render HTML table for combined MedicationRequest and MedicationStatement resources
|
|
2167
2149
|
* @param templateUtilities - Instance of TemplateUtilities for utility functions
|
|
@@ -2185,7 +2167,6 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
|
|
|
2185
2167
|
</thead>
|
|
2186
2168
|
<tbody>`;
|
|
2187
2169
|
for (const medication of medications) {
|
|
2188
|
-
const narrativeLinkId = templateUtilities.narrativeLinkId(medication.extension);
|
|
2189
2170
|
let type;
|
|
2190
2171
|
let medicationName;
|
|
2191
2172
|
let sig;
|
|
@@ -2232,9 +2213,9 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
|
|
|
2232
2213
|
}
|
|
2233
2214
|
}
|
|
2234
2215
|
html += `
|
|
2235
|
-
<tr
|
|
2216
|
+
<tr>
|
|
2236
2217
|
<td>${type}</td>
|
|
2237
|
-
<td>${medicationName}
|
|
2218
|
+
<td>${templateUtilities.capitalizeFirstLetter(medicationName)}</td>
|
|
2238
2219
|
<td>${codeSystemDisplay}</td>
|
|
2239
2220
|
<td>${sig}</td>
|
|
2240
2221
|
<td>${dispenseQuantity}</td>
|
|
@@ -2277,6 +2258,7 @@ var ImmunizationsTemplate = class _ImmunizationsTemplate {
|
|
|
2277
2258
|
let isSummaryCreated = false;
|
|
2278
2259
|
let html = `
|
|
2279
2260
|
<div>
|
|
2261
|
+
<p>This list includes all vaccinations, sorted by occurrence date (most recent first).</p>
|
|
2280
2262
|
<table>
|
|
2281
2263
|
<thead>
|
|
2282
2264
|
<tr>
|
|
@@ -2315,7 +2297,7 @@ var ImmunizationsTemplate = class _ImmunizationsTemplate {
|
|
|
2315
2297
|
isSummaryCreated = true;
|
|
2316
2298
|
html += `
|
|
2317
2299
|
<tr>
|
|
2318
|
-
<td>${data["immunization"] ?? ""}</td>
|
|
2300
|
+
<td>${templateUtilities.capitalizeFirstLetter(data["immunization"] ?? "")}</td>
|
|
2319
2301
|
<td>${data["codeSystem"] ?? ""}</td>
|
|
2320
2302
|
<td>${data["status"] ?? ""}</td>
|
|
2321
2303
|
<td>${templateUtilities.renderTime(data["occurrenceDateTime"], timezone) ?? ""}</td>
|
|
@@ -2359,8 +2341,8 @@ var ImmunizationsTemplate = class _ImmunizationsTemplate {
|
|
|
2359
2341
|
for (const resourceItem of immunizations) {
|
|
2360
2342
|
const imm = resourceItem;
|
|
2361
2343
|
html += `
|
|
2362
|
-
<tr
|
|
2363
|
-
<td>${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(imm.vaccineCode))}</td>
|
|
2344
|
+
<tr>
|
|
2345
|
+
<td>${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(imm.vaccineCode)))}</td>
|
|
2364
2346
|
<td>${templateUtilities.codeableConceptCoding(imm.vaccineCode)}</td>
|
|
2365
2347
|
<td>${imm.status || ""}</td>
|
|
2366
2348
|
<td>${templateUtilities.concatDoseNumber(imm.protocolApplied)}</td>
|
|
@@ -2399,7 +2381,8 @@ var ProblemListTemplate = class _ProblemListTemplate {
|
|
|
2399
2381
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2400
2382
|
static generateStaticNarrative(resources, timezone) {
|
|
2401
2383
|
const templateUtilities = new TemplateUtilities(resources);
|
|
2402
|
-
let html =
|
|
2384
|
+
let html = `<p>This list includes patient problems, sorted by recorded date (most recent first)</p>
|
|
2385
|
+
`;
|
|
2403
2386
|
const activeConditions = resources.map((entry) => entry) || [];
|
|
2404
2387
|
activeConditions.sort((a, b) => {
|
|
2405
2388
|
if (!a.recordedDate && b.recordedDate) return -1;
|
|
@@ -2429,8 +2412,8 @@ var ProblemListTemplate = class _ProblemListTemplate {
|
|
|
2429
2412
|
continue;
|
|
2430
2413
|
}
|
|
2431
2414
|
seenCodeAndSystems.add(codeAndSystem);
|
|
2432
|
-
html += `<tr
|
|
2433
|
-
<td class="Name">${conditionDisplay}</td>
|
|
2415
|
+
html += `<tr>
|
|
2416
|
+
<td class="Name">${templateUtilities.capitalizeFirstLetter(conditionDisplay)}</td>
|
|
2434
2417
|
<td class="CodeSystem">${codeAndSystem}</td>
|
|
2435
2418
|
<td class="OnsetDate">${templateUtilities.renderDate(cond.onsetDateTime)}</td>
|
|
2436
2419
|
<td class="RecordedDate">${templateUtilities.renderDate(cond.recordedDate)}</td>
|
|
@@ -2463,7 +2446,9 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
|
|
|
2463
2446
|
generateSummaryNarrative(resources, timezone) {
|
|
2464
2447
|
const templateUtilities = new TemplateUtilities(resources);
|
|
2465
2448
|
let isSummaryCreated = false;
|
|
2466
|
-
let html =
|
|
2449
|
+
let html = `<p>This list includes the latest vital signs, sorted by effective date (most recent first).</p>
|
|
2450
|
+
`;
|
|
2451
|
+
html += `
|
|
2467
2452
|
<div>
|
|
2468
2453
|
<table>
|
|
2469
2454
|
<thead>
|
|
@@ -2508,7 +2493,7 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
|
|
|
2508
2493
|
isSummaryCreated = true;
|
|
2509
2494
|
html += `
|
|
2510
2495
|
<tr>
|
|
2511
|
-
<td>${data["Vital Name"] ?? ""}</td>
|
|
2496
|
+
<td>${templateUtilities.capitalizeFirstLetter(data["Vital Name"] ?? "")}</td>
|
|
2512
2497
|
<td>${data["codeSystem"] ?? ""}</td>
|
|
2513
2498
|
<td>${templateUtilities.extractObservationSummaryValue(data, timezone) ?? ""}</td>
|
|
2514
2499
|
<td>${templateUtilities.extractObservationSummaryEffectiveTime(data, timezone) ?? ""}</td>
|
|
@@ -2536,7 +2521,9 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
|
|
|
2536
2521
|
const dateB = b.effectiveDateTime || b.effectivePeriod?.start;
|
|
2537
2522
|
return dateA && dateB ? new Date(dateB).getTime() - new Date(dateA).getTime() : 0;
|
|
2538
2523
|
});
|
|
2539
|
-
let html =
|
|
2524
|
+
let html = `<p>This list includes the latest vital signs, sorted by effective date (most recent first).</p>
|
|
2525
|
+
`;
|
|
2526
|
+
html += `
|
|
2540
2527
|
<table>
|
|
2541
2528
|
<thead>
|
|
2542
2529
|
<tr>
|
|
@@ -2554,8 +2541,8 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
|
|
|
2554
2541
|
<tbody>`;
|
|
2555
2542
|
for (const obs of observations) {
|
|
2556
2543
|
html += `
|
|
2557
|
-
<tr
|
|
2558
|
-
<td>${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(obs.code, "display"))}</td>
|
|
2544
|
+
<tr>
|
|
2545
|
+
<td>${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(obs.code, "display")))}</td>
|
|
2559
2546
|
<td>${templateUtilities.codeableConceptCoding(obs.code)}</td>
|
|
2560
2547
|
<td>${templateUtilities.extractObservationValue(obs)}</td>
|
|
2561
2548
|
<td>${templateUtilities.extractObservationValueUnit(obs)}</td>
|
|
@@ -2592,7 +2579,7 @@ var MedicalDevicesTemplate = class _MedicalDevicesTemplate {
|
|
|
2592
2579
|
*/
|
|
2593
2580
|
static generateStaticNarrative(resources, timezone) {
|
|
2594
2581
|
const templateUtilities = new TemplateUtilities(resources);
|
|
2595
|
-
let html =
|
|
2582
|
+
let html = `<p>This list includes all DeviceUseStatement resources, sorted by recorded date (most recent first).</p>
|
|
2596
2583
|
<table>
|
|
2597
2584
|
<thead>
|
|
2598
2585
|
<tr>
|
|
@@ -2608,10 +2595,12 @@ var MedicalDevicesTemplate = class _MedicalDevicesTemplate {
|
|
|
2608
2595
|
const dateB = b.recordedOn;
|
|
2609
2596
|
return typeof dateA === "string" && typeof dateB === "string" ? new Date(dateB).getTime() - new Date(dateA).getTime() : 0;
|
|
2610
2597
|
});
|
|
2598
|
+
let isDeviceAdded = false;
|
|
2611
2599
|
for (const dus of deviceStatements) {
|
|
2600
|
+
isDeviceAdded = true;
|
|
2612
2601
|
html += `
|
|
2613
|
-
<tr
|
|
2614
|
-
<td>${templateUtilities.renderTextAsHtml(templateUtilities.renderDevice(dus.device))}</td>
|
|
2602
|
+
<tr>
|
|
2603
|
+
<td>${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(templateUtilities.renderDevice(dus.device)))}</td>
|
|
2615
2604
|
<td>${templateUtilities.renderTextAsHtml(dus.status || "")}</td>
|
|
2616
2605
|
<td>${templateUtilities.renderNotes(dus.note, timezone)}</td>
|
|
2617
2606
|
<td>${templateUtilities.renderTextAsHtml(templateUtilities.renderRecorded(dus.recordedOn, timezone))}</td>
|
|
@@ -2620,7 +2609,7 @@ var MedicalDevicesTemplate = class _MedicalDevicesTemplate {
|
|
|
2620
2609
|
html += `
|
|
2621
2610
|
</tbody>
|
|
2622
2611
|
</table>`;
|
|
2623
|
-
return html;
|
|
2612
|
+
return isDeviceAdded ? html : void 0;
|
|
2624
2613
|
}
|
|
2625
2614
|
};
|
|
2626
2615
|
|
|
@@ -2971,11 +2960,12 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2971
2960
|
}
|
|
2972
2961
|
}
|
|
2973
2962
|
}
|
|
2974
|
-
let html =
|
|
2975
|
-
|
|
2963
|
+
let html = `<p>This section includes Observations from the last 2 years (one per lab name, using code mapping) and DiagnosticReports with status 'final' issued in the last 2 years. Both are sorted by date (most recent first). Older results are counted and noted below the tables.</p>
|
|
2964
|
+
`;
|
|
2976
2965
|
let observationhtml = `
|
|
2977
2966
|
<div>
|
|
2978
2967
|
<h3>Observations</h3>
|
|
2968
|
+
${html}
|
|
2979
2969
|
<table>
|
|
2980
2970
|
<thead>
|
|
2981
2971
|
<tr>
|
|
@@ -2991,6 +2981,7 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2991
2981
|
let diagnosticReporthtml = `
|
|
2992
2982
|
<div>
|
|
2993
2983
|
<h3>Diagnostic Reports</h3>
|
|
2984
|
+
${html}
|
|
2994
2985
|
<table>
|
|
2995
2986
|
<thead>
|
|
2996
2987
|
<tr>
|
|
@@ -3075,7 +3066,7 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
3075
3066
|
this.formatSummaryObservationData(component);
|
|
3076
3067
|
observationhtml += `
|
|
3077
3068
|
<tr>
|
|
3078
|
-
<td>${componentCode}</td>
|
|
3069
|
+
<td>${templateUtilities.capitalizeFirstLetter(componentCode)}</td>
|
|
3079
3070
|
<td></td>
|
|
3080
3071
|
<td>${templateUtilities.renderTextAsHtml(component["formattedValue"]) ?? ""}</td>
|
|
3081
3072
|
<td>${templateUtilities.renderTextAsHtml(component["referenceRange"])?.trim() ?? ""}</td>
|
|
@@ -3092,7 +3083,7 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
3092
3083
|
this.formatSummaryObservationData(data);
|
|
3093
3084
|
observationhtml += `
|
|
3094
3085
|
<tr>
|
|
3095
|
-
<td>${data["code"] ?? ""}</td>
|
|
3086
|
+
<td>${templateUtilities.capitalizeFirstLetter(data["code"] ?? "")}</td>
|
|
3096
3087
|
<td>${templateUtilities.codeableConceptCoding(sectionCodeableConcept)}</td>
|
|
3097
3088
|
<td>${templateUtilities.renderTextAsHtml(data["formattedValue"]) ?? ""}</td>
|
|
3098
3089
|
<td>${templateUtilities.renderTextAsHtml(data["referenceRange"])?.trim() ?? ""}</td>
|
|
@@ -3113,7 +3104,7 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
3113
3104
|
diagnosticReportAdded.add(reportName);
|
|
3114
3105
|
diagnosticReporthtml += `
|
|
3115
3106
|
<tr>
|
|
3116
|
-
<td>${data["report"] ?? ""}</td>
|
|
3107
|
+
<td>${templateUtilities.capitalizeFirstLetter(data["report"] ?? "")}</td>
|
|
3117
3108
|
<td>${data["performer"] ?? ""}</td>
|
|
3118
3109
|
<td>${templateUtilities.renderTime(data["issued"], timezone) ?? ""}</td>
|
|
3119
3110
|
<td>${data["source"] ?? ""}</td>
|
|
@@ -3161,7 +3152,8 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
3161
3152
|
const currentDate = now || /* @__PURE__ */ new Date();
|
|
3162
3153
|
const twoYearsAgo = new Date(currentDate);
|
|
3163
3154
|
twoYearsAgo.setFullYear(currentDate.getFullYear() - 2);
|
|
3164
|
-
let html =
|
|
3155
|
+
let html = `<p>This section includes Observations from the last 2 years (one per lab name, using code mapping) and DiagnosticReports with status 'final' issued in the last 2 years. Both are sorted by date (most recent first). Older results are counted and noted below the tables.</p>
|
|
3156
|
+
`;
|
|
3165
3157
|
let skippedObservations = 0;
|
|
3166
3158
|
let skippedDiagnosticReports = 0;
|
|
3167
3159
|
for (const resourceItem of resources) {
|
|
@@ -3312,8 +3304,8 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
3312
3304
|
observationAdded.add(obsCodeDisplay);
|
|
3313
3305
|
observationAdded.add(obsCodeAndSystem);
|
|
3314
3306
|
html += `
|
|
3315
|
-
<tr
|
|
3316
|
-
<td>${obsCodeDisplay}</td>
|
|
3307
|
+
<tr>
|
|
3308
|
+
<td>${templateUtilities.capitalizeFirstLetter(obsCodeDisplay)}</td>
|
|
3317
3309
|
<td>${templateUtilities.codeableConceptCoding(obs.code)}</td>
|
|
3318
3310
|
<td>${templateUtilities.extractObservationValue(obs)}</td>
|
|
3319
3311
|
<td>${templateUtilities.concatReferenceRange(obs.referenceRange)}</td>
|
|
@@ -3361,8 +3353,8 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
3361
3353
|
resultCount = `${report.result.length} result${report.result.length !== 1 ? "s" : ""}`;
|
|
3362
3354
|
}
|
|
3363
3355
|
html += `
|
|
3364
|
-
<tr
|
|
3365
|
-
<td>${reportName}</td>
|
|
3356
|
+
<tr>
|
|
3357
|
+
<td>${templateUtilities.capitalizeFirstLetter(reportName)}</td>
|
|
3366
3358
|
<td>${codeAndSystem}</td>
|
|
3367
3359
|
<td>${templateUtilities.firstFromCodeableConceptList(report.category)}</td>
|
|
3368
3360
|
<td>${resultCount}</td>
|
|
@@ -3423,7 +3415,9 @@ var HistoryOfProceduresTemplate = class _HistoryOfProceduresTemplate {
|
|
|
3423
3415
|
generateSummaryNarrative(resources, timezone) {
|
|
3424
3416
|
const templateUtilities = new TemplateUtilities(resources);
|
|
3425
3417
|
let isSummaryCreated = false;
|
|
3426
|
-
let html =
|
|
3418
|
+
let html = `<p>This list includes all Procedure resources, sorted by performed date (most recent first).</p>
|
|
3419
|
+
`;
|
|
3420
|
+
html += `
|
|
3427
3421
|
<div>
|
|
3428
3422
|
<table>
|
|
3429
3423
|
<thead>
|
|
@@ -3462,7 +3456,7 @@ var HistoryOfProceduresTemplate = class _HistoryOfProceduresTemplate {
|
|
|
3462
3456
|
isSummaryCreated = true;
|
|
3463
3457
|
html += `
|
|
3464
3458
|
<tr>
|
|
3465
|
-
<td>${data["procedure"] ?? ""}</td>
|
|
3459
|
+
<td>${templateUtilities.capitalizeFirstLetter(data["procedure"] ?? "")}</td>
|
|
3466
3460
|
<td>${data["codeSystem"] ?? ""}</td>
|
|
3467
3461
|
<td>${data["performer"] ?? ""}</td>
|
|
3468
3462
|
<td>${templateUtilities.renderTime(data["date"], timezone) ?? ""}</td>
|
|
@@ -3484,7 +3478,9 @@ var HistoryOfProceduresTemplate = class _HistoryOfProceduresTemplate {
|
|
|
3484
3478
|
*/
|
|
3485
3479
|
static generateStaticNarrative(resources, timezone) {
|
|
3486
3480
|
const templateUtilities = new TemplateUtilities(resources);
|
|
3487
|
-
let html =
|
|
3481
|
+
let html = `<p>This list includes all Procedure resources, sorted by performed date (most recent first).</p>
|
|
3482
|
+
`;
|
|
3483
|
+
html += `
|
|
3488
3484
|
<table>
|
|
3489
3485
|
<thead>
|
|
3490
3486
|
<tr>
|
|
@@ -3499,12 +3495,12 @@ var HistoryOfProceduresTemplate = class _HistoryOfProceduresTemplate {
|
|
|
3499
3495
|
for (const resourceItem of resources) {
|
|
3500
3496
|
const proc = resourceItem;
|
|
3501
3497
|
html += `
|
|
3502
|
-
<tr
|
|
3503
|
-
<td>${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(proc.code, "display"))}</td>
|
|
3504
|
-
|
|
3498
|
+
<tr>
|
|
3499
|
+
<td>${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(proc.code, "display")))}</td>
|
|
3500
|
+
<td>${templateUtilities.codeableConceptCoding(proc.code)}</td>
|
|
3505
3501
|
<td>${templateUtilities.renderNotes(proc.note, timezone)}</td>
|
|
3506
|
-
<td>${
|
|
3507
|
-
|
|
3502
|
+
<td>${templateUtilities.renderTime(proc.performedDateTime || proc.performedPeriod?.start, timezone)}</td>
|
|
3503
|
+
<td>${templateUtilities.getOwnerTag(proc)}</td>
|
|
3508
3504
|
</tr>`;
|
|
3509
3505
|
}
|
|
3510
3506
|
html += `
|
|
@@ -3539,7 +3535,9 @@ var SocialHistoryTemplate = class _SocialHistoryTemplate {
|
|
|
3539
3535
|
const dateB = b.effectiveDateTime || b.effectivePeriod?.start;
|
|
3540
3536
|
return dateA && dateB ? new Date(dateB).getTime() - new Date(dateA).getTime() : 0;
|
|
3541
3537
|
});
|
|
3542
|
-
let html =
|
|
3538
|
+
let html = `<p>This list includes all information about the patient's social history, sorted by effective date (most recent first).</p>
|
|
3539
|
+
`;
|
|
3540
|
+
html += `
|
|
3543
3541
|
<table>
|
|
3544
3542
|
<thead>
|
|
3545
3543
|
<tr>
|
|
@@ -3553,17 +3551,22 @@ var SocialHistoryTemplate = class _SocialHistoryTemplate {
|
|
|
3553
3551
|
</tr>
|
|
3554
3552
|
</thead>
|
|
3555
3553
|
<tbody>`;
|
|
3554
|
+
const addedObservations = /* @__PURE__ */ new Set();
|
|
3556
3555
|
for (const obs of observations) {
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
<
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3556
|
+
const obsName = templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(obs.code));
|
|
3557
|
+
if (!addedObservations.has(obsName)) {
|
|
3558
|
+
addedObservations.add(obsName);
|
|
3559
|
+
html += `
|
|
3560
|
+
<tr>
|
|
3561
|
+
<td>${templateUtilities.capitalizeFirstLetter(obsName)}</td>
|
|
3562
|
+
<td>${templateUtilities.codeableConceptCoding(obs.code)}</td>
|
|
3563
|
+
<td>${templateUtilities.extractObservationValue(obs)}</td>
|
|
3564
|
+
<td>${templateUtilities.extractObservationValueUnit(obs)}</td>
|
|
3565
|
+
<td>${templateUtilities.renderNotes(obs.note, timezone)}</td>
|
|
3566
|
+
<td>${obs.effectiveDateTime ? templateUtilities.renderTime(obs.effectiveDateTime, timezone) : obs.effectivePeriod ? templateUtilities.renderPeriod(obs.effectivePeriod, timezone) : ""}</td>
|
|
3567
|
+
<td>${templateUtilities.getOwnerTag(obs)}</td>
|
|
3568
|
+
</tr>`;
|
|
3569
|
+
}
|
|
3567
3570
|
}
|
|
3568
3571
|
html += `
|
|
3569
3572
|
</tbody>
|
|
@@ -3583,7 +3586,8 @@ var PastHistoryOfIllnessTemplate = class {
|
|
|
3583
3586
|
*/
|
|
3584
3587
|
generateNarrative(resources, timezone, now) {
|
|
3585
3588
|
const templateUtilities = new TemplateUtilities(resources);
|
|
3586
|
-
let html =
|
|
3589
|
+
let html = `<p>This list includes past problems for the patient with a recorded date within the last 5 years, sorted by recorded date (most recent first).</p>
|
|
3590
|
+
`;
|
|
3587
3591
|
const resolvedConditions = resources.map((entry) => entry) || [];
|
|
3588
3592
|
const currentDate = now || /* @__PURE__ */ new Date();
|
|
3589
3593
|
const fiveYearsAgo = new Date(currentDate);
|
|
@@ -3620,8 +3624,8 @@ var PastHistoryOfIllnessTemplate = class {
|
|
|
3620
3624
|
const conditionCode = templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(cond.code));
|
|
3621
3625
|
if (!addedConditionCodes.has(conditionCode)) {
|
|
3622
3626
|
addedConditionCodes.add(conditionCode);
|
|
3623
|
-
html += `<tr
|
|
3624
|
-
<td class="Name">${conditionCode}</td>
|
|
3627
|
+
html += `<tr>
|
|
3628
|
+
<td class="Name">${templateUtilities.capitalizeFirstLetter(conditionCode)}</td>
|
|
3625
3629
|
<td class="CodeSystem">${templateUtilities.codeableConceptCoding(cond.code)}</td>
|
|
3626
3630
|
<td class="OnsetDate">${templateUtilities.renderDate(cond.onsetDateTime)}</td>
|
|
3627
3631
|
<td class="RecordedDate">${templateUtilities.renderDate(cond.recordedDate)}</td>
|
|
@@ -3656,7 +3660,9 @@ var PlanOfCareTemplate = class {
|
|
|
3656
3660
|
const endB = b.period?.end ? new Date(b.period?.end).getTime() : 0;
|
|
3657
3661
|
return endB - endA;
|
|
3658
3662
|
});
|
|
3659
|
-
let html =
|
|
3663
|
+
let html = `<p>This list includes all CarePlan resources, sorted by planned end date (most recent first).</p>
|
|
3664
|
+
`;
|
|
3665
|
+
html += `
|
|
3660
3666
|
<table>
|
|
3661
3667
|
<thead>
|
|
3662
3668
|
<tr>
|
|
@@ -3671,8 +3677,8 @@ var PlanOfCareTemplate = class {
|
|
|
3671
3677
|
<tbody>`;
|
|
3672
3678
|
for (const cp of carePlans) {
|
|
3673
3679
|
html += `
|
|
3674
|
-
<tr
|
|
3675
|
-
<td>${cp.description || cp.title || ""}</td>
|
|
3680
|
+
<tr>
|
|
3681
|
+
<td>${templateUtilities.capitalizeFirstLetter(cp.description || cp.title || "")}</td>
|
|
3676
3682
|
<td>${cp.intent || ""}</td>
|
|
3677
3683
|
<td>${templateUtilities.concat(cp.note, "text")}</td>
|
|
3678
3684
|
<td>${cp.period?.start ? templateUtilities.renderTime(cp.period?.start, timezone) : ""}</td>
|
|
@@ -3694,7 +3700,9 @@ var PlanOfCareTemplate = class {
|
|
|
3694
3700
|
generateSummaryNarrative(resources, timezone) {
|
|
3695
3701
|
const templateUtilities = new TemplateUtilities(resources);
|
|
3696
3702
|
let isSummaryCreated = false;
|
|
3697
|
-
let html =
|
|
3703
|
+
let html = `<p>This list includes all CarePlan resources, sorted by planned end date (most recent first).</p>
|
|
3704
|
+
`;
|
|
3705
|
+
html += `
|
|
3698
3706
|
<div>
|
|
3699
3707
|
<table>
|
|
3700
3708
|
<thead>
|
|
@@ -3721,7 +3729,7 @@ var PlanOfCareTemplate = class {
|
|
|
3721
3729
|
isSummaryCreated = true;
|
|
3722
3730
|
html += `
|
|
3723
3731
|
<tr>
|
|
3724
|
-
<td>${data["CarePlan Name"] ?? ""}</td>
|
|
3732
|
+
<td>${templateUtilities.capitalizeFirstLetter(data["CarePlan Name"] ?? "")}</td>
|
|
3725
3733
|
<td>${templateUtilities.renderTime(data["created"], timezone) ?? ""}</td>
|
|
3726
3734
|
<td>${templateUtilities.renderTime(data["period.start"], timezone) ?? ""}</td>
|
|
3727
3735
|
<td>${templateUtilities.renderTime(data["period.end"], timezone) ?? ""}</td>
|
|
@@ -3756,7 +3764,7 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
|
|
|
3756
3764
|
*/
|
|
3757
3765
|
static generateStaticNarrative(resources, timezone) {
|
|
3758
3766
|
const templateUtilities = new TemplateUtilities(resources);
|
|
3759
|
-
let html =
|
|
3767
|
+
let html = `<p>This section summarizes key observations and assessments related to the person's functional status and ability to perform daily activities.</p>`;
|
|
3760
3768
|
let functionalObservations = resources.filter((r) => r.resourceType === "Observation").filter((r) => {
|
|
3761
3769
|
const hasFunctionalLoinc = r.code?.coding?.some(
|
|
3762
3770
|
(c) => c.system?.toLowerCase().includes("loinc") && c.code === "47420-5"
|
|
@@ -3786,8 +3794,8 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
|
|
|
3786
3794
|
const date = observation.effectiveDateTime ? templateUtilities.renderDate(observation.effectiveDateTime) : observation.issued ? templateUtilities.renderDate(observation.issued) : "";
|
|
3787
3795
|
const interpretation = observation.interpretation ? templateUtilities.codeableConceptDisplay(observation.interpretation[0]) : "";
|
|
3788
3796
|
const comments = observation.comment || observation.note?.map((n) => n.text).join("; ") || "";
|
|
3789
|
-
html += `<tr
|
|
3790
|
-
<td>${obsName}</td>
|
|
3797
|
+
html += `<tr>
|
|
3798
|
+
<td>${templateUtilities.capitalizeFirstLetter(obsName)}</td>
|
|
3791
3799
|
<td>${value ?? ""}</td>
|
|
3792
3800
|
<td>${date}</td>
|
|
3793
3801
|
<td>${interpretation}</td>
|
|
@@ -3817,7 +3825,7 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
|
|
|
3817
3825
|
}
|
|
3818
3826
|
findingsHtml += "</ul>";
|
|
3819
3827
|
}
|
|
3820
|
-
html += `<tr
|
|
3828
|
+
html += `<tr>
|
|
3821
3829
|
<td>${formattedDate}</td>
|
|
3822
3830
|
<td>${impression.status || ""}</td>
|
|
3823
3831
|
<td>${impression.description || ""}</td>
|
|
@@ -3880,7 +3888,8 @@ var PregnancyTemplate = class _PregnancyTemplate {
|
|
|
3880
3888
|
if (!pregnancyStatusObs && !eddObs && historyObs.length === 0 && conditions.length === 0) {
|
|
3881
3889
|
return `<p>No history of pregnancy found.</p>`;
|
|
3882
3890
|
}
|
|
3883
|
-
let html =
|
|
3891
|
+
let html = `<p>This list includes Observation and Condition resources relevant to pregnancy, sorted by date (most recent first).</p>`;
|
|
3892
|
+
html += `
|
|
3884
3893
|
<table>
|
|
3885
3894
|
<thead>
|
|
3886
3895
|
<tr>
|
|
@@ -3892,10 +3901,10 @@ var PregnancyTemplate = class _PregnancyTemplate {
|
|
|
3892
3901
|
</tr>
|
|
3893
3902
|
</thead>
|
|
3894
3903
|
<tbody>`;
|
|
3895
|
-
function renderRow({
|
|
3904
|
+
function renderRow({ result, comments, date, codeSystem, owner }) {
|
|
3896
3905
|
html += `
|
|
3897
|
-
<tr
|
|
3898
|
-
<td class="Result">${result}</td>
|
|
3906
|
+
<tr>
|
|
3907
|
+
<td class="Result">${templateUtilities.capitalizeFirstLetter(result)}</td>
|
|
3899
3908
|
<td class="CodeSystem">${codeSystem}</td>
|
|
3900
3909
|
<td class="Comments">${comments}</td>
|
|
3901
3910
|
<td class="Date">${date}</td>
|
|
@@ -3926,9 +3935,9 @@ var PregnancyTemplate = class _PregnancyTemplate {
|
|
|
3926
3935
|
if (!b.date) return -1;
|
|
3927
3936
|
return new Date(b.date).getTime() - new Date(a.date).getTime();
|
|
3928
3937
|
});
|
|
3938
|
+
const addedRows = /* @__PURE__ */ new Set();
|
|
3929
3939
|
for (const { resource, date, type } of rowResources) {
|
|
3930
3940
|
let result = "", comments = "", dateStr = "", codeSystem = "";
|
|
3931
|
-
const id = templateUtilities.narrativeLinkId(resource);
|
|
3932
3941
|
if (type === "status") {
|
|
3933
3942
|
result = templateUtilities.renderTextAsHtml(templateUtilities.extractPregnancyStatus(resource));
|
|
3934
3943
|
comments = templateUtilities.renderNotes(resource.note, timezone);
|
|
@@ -3950,8 +3959,12 @@ var PregnancyTemplate = class _PregnancyTemplate {
|
|
|
3950
3959
|
dateStr = date ? templateUtilities.renderTextAsHtml(templateUtilities.renderTime(date, timezone)) : "";
|
|
3951
3960
|
codeSystem = templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptCoding(resource.code));
|
|
3952
3961
|
}
|
|
3953
|
-
const
|
|
3954
|
-
|
|
3962
|
+
const rowKey = `${result}|${codeSystem}`;
|
|
3963
|
+
if (!addedRows.has(rowKey)) {
|
|
3964
|
+
addedRows.add(rowKey);
|
|
3965
|
+
const owner = templateUtilities.getOwnerTag(resource);
|
|
3966
|
+
renderRow({ result, comments, date: dateStr, codeSystem, owner });
|
|
3967
|
+
}
|
|
3955
3968
|
}
|
|
3956
3969
|
html += `
|
|
3957
3970
|
</tbody>
|
|
@@ -3985,8 +3998,9 @@ var AdvanceDirectivesTemplate = class _AdvanceDirectivesTemplate {
|
|
|
3985
3998
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3986
3999
|
static generateStaticNarrative(resources, timezone) {
|
|
3987
4000
|
const templateUtilities = new TemplateUtilities(resources);
|
|
3988
|
-
let html =
|
|
3989
|
-
|
|
4001
|
+
let html = `<p>This list includes all Consent resources, sorted by date (most recent first).</p>
|
|
4002
|
+
`;
|
|
4003
|
+
html += `<table>
|
|
3990
4004
|
<thead>
|
|
3991
4005
|
<tr>
|
|
3992
4006
|
<th>Scope</th>
|
|
@@ -3999,8 +4013,8 @@ var AdvanceDirectivesTemplate = class _AdvanceDirectivesTemplate {
|
|
|
3999
4013
|
for (const resourceItem of resources) {
|
|
4000
4014
|
const consent = resourceItem;
|
|
4001
4015
|
html += `
|
|
4002
|
-
<tr
|
|
4003
|
-
<td>${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(consent.scope, "display"))}</td>
|
|
4016
|
+
<tr>
|
|
4017
|
+
<td>${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(consent.scope, "display")))}</td>
|
|
4004
4018
|
<td>${consent.status || ""}</td>
|
|
4005
4019
|
<td>${consent.provision?.action ? templateUtilities.concatCodeableConcept(consent.provision.action) : ""}</td>
|
|
4006
4020
|
<td>${consent.dateTime || ""}</td>
|
|
@@ -4315,14 +4329,17 @@ var ComprehensiveIPSCompositionBuilder = class {
|
|
|
4315
4329
|
const summaryIPSCompositionFilter = useSummaryCompositions ? IPSSectionResourceHelper.getSummaryIPSCompositionFilterForSection(sectionType) : void 0;
|
|
4316
4330
|
const sectionIPSSummary = summaryIPSCompositionFilter ? resources.filter((resource) => summaryIPSCompositionFilter(resource)) : [];
|
|
4317
4331
|
if (sectionIPSSummary.length > 0) {
|
|
4332
|
+
console.log(`Using IPS summary composition for section: ${sectionType}`);
|
|
4318
4333
|
await this.makeSectionFromSummaryAsync(sectionType, sectionIPSSummary, resources, timezone);
|
|
4319
4334
|
continue;
|
|
4320
4335
|
}
|
|
4321
4336
|
const summaryCompositionFilter = useSummaryCompositions ? IPSSectionResourceHelper.getSummaryCompositionFilterForSection(sectionType) : void 0;
|
|
4322
4337
|
const sectionSummary = summaryCompositionFilter ? resources.filter((resource) => summaryCompositionFilter(resource)) : [];
|
|
4323
4338
|
if (sectionSummary.length > 0) {
|
|
4339
|
+
console.log(`Using summary composition for section: ${sectionType}`);
|
|
4324
4340
|
await this.makeSectionFromSummaryAsync(sectionType, sectionSummary, resources, timezone);
|
|
4325
4341
|
} else {
|
|
4342
|
+
console.log(`Using individual resources for section: ${sectionType}`);
|
|
4326
4343
|
const sectionFilter = IPSSectionResourceHelper.getResourceFilterForSection(sectionType);
|
|
4327
4344
|
const sectionResources = resources.filter((resource) => sectionFilter(resource));
|
|
4328
4345
|
await this.makeSectionAsync(sectionType, sectionResources, timezone);
|