@imranq2/fhirpatientsummary 1.0.24 → 1.0.26
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 +142 -91
- package/dist/index.js +142 -91
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -142,7 +142,7 @@ var IPSSectionResourceFilters = {
|
|
|
142
142
|
// Only include pregnancy history Observations
|
|
143
143
|
["HistoryOfPregnancySection" /* PREGNANCY_HISTORY */]: (resource) => resource.resourceType === "Observation" && (resource.code?.coding?.some((c) => Object.keys(PREGNANCY_LOINC_CODES.PREGNANCY_STATUS).includes(c.code)) || resource.valueCodeableConcept?.coding?.some((c) => Object.keys(PREGNANCY_LOINC_CODES.PREGNANCY_OUTCOME).includes(c.code))),
|
|
144
144
|
// Only include Conditions or completed ClinicalImpressions
|
|
145
|
-
["FunctionalStatusSection" /* FUNCTIONAL_STATUS */]: (resource) => resource.resourceType === "Condition" || resource.resourceType === "ClinicalImpression" && resource.status === "completed",
|
|
145
|
+
["FunctionalStatusSection" /* FUNCTIONAL_STATUS */]: (resource) => resource.resourceType === "Condition" && resource.clinicalStatus?.coding?.some((c) => !["inactive", "resolved"].includes(c.code)) || resource.resourceType === "ClinicalImpression" && resource.status === "completed",
|
|
146
146
|
// Only include resolved medical history Conditions
|
|
147
147
|
["HistoryOfPastIllnessSection" /* MEDICAL_HISTORY */]: (resource) => resource.resourceType === "Condition" && resource.clinicalStatus?.coding?.some((c) => ["inactive", "resolved"].includes(c.code)),
|
|
148
148
|
// Only include active care plans
|
|
@@ -1326,6 +1326,7 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
|
|
|
1326
1326
|
*/
|
|
1327
1327
|
generateSummaryNarrative(resources, timezone) {
|
|
1328
1328
|
const templateUtilities = new TemplateUtilities(resources);
|
|
1329
|
+
let isSummaryCreated = false;
|
|
1329
1330
|
let html = `
|
|
1330
1331
|
<div>
|
|
1331
1332
|
<table>
|
|
@@ -1355,6 +1356,7 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
|
|
|
1355
1356
|
break;
|
|
1356
1357
|
}
|
|
1357
1358
|
}
|
|
1359
|
+
isSummaryCreated = true;
|
|
1358
1360
|
html += `
|
|
1359
1361
|
<tr>
|
|
1360
1362
|
<td>${data["allergen"] ?? "-"}</td>
|
|
@@ -1367,7 +1369,7 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
|
|
|
1367
1369
|
</tbody>
|
|
1368
1370
|
</table>
|
|
1369
1371
|
</div>`;
|
|
1370
|
-
return html;
|
|
1372
|
+
return isSummaryCreated ? html : void 0;
|
|
1371
1373
|
}
|
|
1372
1374
|
/**
|
|
1373
1375
|
* Internal static implementation that actually generates the narrative
|
|
@@ -1513,6 +1515,7 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
|
|
|
1513
1515
|
*/
|
|
1514
1516
|
generateSummaryNarrative(resources, timezone) {
|
|
1515
1517
|
const templateUtilities = new TemplateUtilities(resources);
|
|
1518
|
+
let isSummaryCreated = false;
|
|
1516
1519
|
let html = `
|
|
1517
1520
|
<div>
|
|
1518
1521
|
<table>
|
|
@@ -1557,6 +1560,7 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
|
|
|
1557
1560
|
}
|
|
1558
1561
|
}
|
|
1559
1562
|
if (data["status"] === "active") {
|
|
1563
|
+
isSummaryCreated = true;
|
|
1560
1564
|
html += `
|
|
1561
1565
|
<tr>
|
|
1562
1566
|
<td>${data["medication"]}</td>
|
|
@@ -1572,7 +1576,7 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
|
|
|
1572
1576
|
</tbody>
|
|
1573
1577
|
</table>
|
|
1574
1578
|
</div>`;
|
|
1575
|
-
return html;
|
|
1579
|
+
return isSummaryCreated ? html : void 0;
|
|
1576
1580
|
}
|
|
1577
1581
|
/**
|
|
1578
1582
|
* Safely parse a date string and return a valid Date object or null
|
|
@@ -1768,6 +1772,7 @@ var ImmunizationsTemplate = class _ImmunizationsTemplate {
|
|
|
1768
1772
|
*/
|
|
1769
1773
|
generateSummaryNarrative(resources, timezone) {
|
|
1770
1774
|
const templateUtilities = new TemplateUtilities(resources);
|
|
1775
|
+
let isSummaryCreated = false;
|
|
1771
1776
|
let html = `
|
|
1772
1777
|
<div>
|
|
1773
1778
|
<table>
|
|
@@ -1798,6 +1803,7 @@ var ImmunizationsTemplate = class _ImmunizationsTemplate {
|
|
|
1798
1803
|
}
|
|
1799
1804
|
}
|
|
1800
1805
|
if (data["status"] === "completed") {
|
|
1806
|
+
isSummaryCreated = true;
|
|
1801
1807
|
html += `
|
|
1802
1808
|
<tr>
|
|
1803
1809
|
<td>${data["immunization"] ?? "-"}</td>
|
|
@@ -1811,7 +1817,7 @@ var ImmunizationsTemplate = class _ImmunizationsTemplate {
|
|
|
1811
1817
|
</tbody>
|
|
1812
1818
|
</table>
|
|
1813
1819
|
</div>`;
|
|
1814
|
-
return html;
|
|
1820
|
+
return isSummaryCreated ? html : void 0;
|
|
1815
1821
|
}
|
|
1816
1822
|
/**
|
|
1817
1823
|
* Internal static implementation that actually generates the narrative
|
|
@@ -1881,8 +1887,8 @@ var ProblemListTemplate = class _ProblemListTemplate {
|
|
|
1881
1887
|
let html = ``;
|
|
1882
1888
|
const activeConditions = resources.map((entry) => entry) || [];
|
|
1883
1889
|
activeConditions.sort((a, b) => {
|
|
1884
|
-
const dateA = a.
|
|
1885
|
-
const dateB = b.
|
|
1890
|
+
const dateA = a.recordedDate ? new Date(a.recordedDate).getTime() : 0;
|
|
1891
|
+
const dateB = b.recordedDate ? new Date(b.recordedDate).getTime() : 0;
|
|
1886
1892
|
return dateB - dateA;
|
|
1887
1893
|
});
|
|
1888
1894
|
html += `
|
|
@@ -1895,12 +1901,17 @@ var ProblemListTemplate = class _ProblemListTemplate {
|
|
|
1895
1901
|
</tr>
|
|
1896
1902
|
</thead>
|
|
1897
1903
|
<tbody>`;
|
|
1904
|
+
const addedConditionCodes = /* @__PURE__ */ new Set();
|
|
1898
1905
|
for (const cond of activeConditions) {
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1906
|
+
const conditionCode = templateUtilities.codeableConcept(cond.code);
|
|
1907
|
+
if (!addedConditionCodes.has(conditionCode)) {
|
|
1908
|
+
addedConditionCodes.add(conditionCode);
|
|
1909
|
+
html += `<tr id="${templateUtilities.narrativeLinkId(cond)}">
|
|
1910
|
+
<td class="Name">${conditionCode}</td>
|
|
1911
|
+
<td class="OnsetDate">${templateUtilities.renderDate(cond.onsetDateTime)}</td>
|
|
1912
|
+
<td class="RecordedDate">${templateUtilities.renderDate(cond.recordedDate)}</td>
|
|
1913
|
+
</tr>`;
|
|
1914
|
+
}
|
|
1904
1915
|
}
|
|
1905
1916
|
html += `</tbody>
|
|
1906
1917
|
</table>`;
|
|
@@ -1927,6 +1938,7 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
|
|
|
1927
1938
|
*/
|
|
1928
1939
|
generateSummaryNarrative(resources, timezone) {
|
|
1929
1940
|
const templateUtilities = new TemplateUtilities(resources);
|
|
1941
|
+
let isSummaryCreated = false;
|
|
1930
1942
|
let html = `
|
|
1931
1943
|
<div>
|
|
1932
1944
|
<table>
|
|
@@ -1966,6 +1978,7 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
|
|
|
1966
1978
|
data[columnTitle] = columnData.text?.div ?? "";
|
|
1967
1979
|
}
|
|
1968
1980
|
}
|
|
1981
|
+
isSummaryCreated = true;
|
|
1969
1982
|
html += `
|
|
1970
1983
|
<tr>
|
|
1971
1984
|
<td>${data["Vital Name"] ?? "-"}</td>
|
|
@@ -1979,7 +1992,7 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
|
|
|
1979
1992
|
</tbody>
|
|
1980
1993
|
</table>
|
|
1981
1994
|
</div>`;
|
|
1982
|
-
return html;
|
|
1995
|
+
return isSummaryCreated ? html : void 0;
|
|
1983
1996
|
}
|
|
1984
1997
|
/**
|
|
1985
1998
|
* Internal static implementation that actually generates the narrative
|
|
@@ -2382,8 +2395,8 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2382
2395
|
</tr>
|
|
2383
2396
|
</thead>
|
|
2384
2397
|
<tbody>`;
|
|
2385
|
-
|
|
2386
|
-
|
|
2398
|
+
const observationAdded = /* @__PURE__ */ new Set();
|
|
2399
|
+
const diagnosticReportAdded = /* @__PURE__ */ new Set();
|
|
2387
2400
|
for (const resourceItem of resources) {
|
|
2388
2401
|
for (const rowData of resourceItem.section ?? []) {
|
|
2389
2402
|
const data = {};
|
|
@@ -2423,7 +2436,6 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2423
2436
|
}
|
|
2424
2437
|
}
|
|
2425
2438
|
if (resourceItem.title === "Observation|Labs Summary Grouped by Lab Code") {
|
|
2426
|
-
observationExists = true;
|
|
2427
2439
|
let date = data["effectiveDateTime"] ? templateUtilities.renderTime(data["effectiveDateTime"], timezone) : "";
|
|
2428
2440
|
if (!date && data["effectivePeriodStart"]) {
|
|
2429
2441
|
date = templateUtilities.renderTime(data["effectivePeriodStart"], timezone);
|
|
@@ -2432,48 +2444,59 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2432
2444
|
}
|
|
2433
2445
|
}
|
|
2434
2446
|
if (components.length > 0) {
|
|
2435
|
-
const groupName = data["code"]
|
|
2447
|
+
const groupName = data["code"] ? `${data["code"]} - ` : "";
|
|
2436
2448
|
for (const component of components) {
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
<
|
|
2443
|
-
|
|
2444
|
-
|
|
2449
|
+
const componentCode = `${groupName}${component["code"] ?? ""}`;
|
|
2450
|
+
if (componentCode && !observationAdded.has(componentCode)) {
|
|
2451
|
+
observationAdded.add(componentCode);
|
|
2452
|
+
this.formatSummaryObservationData(component);
|
|
2453
|
+
observationhtml += `
|
|
2454
|
+
<tr>
|
|
2455
|
+
<td>${componentCode}</td>
|
|
2456
|
+
<td>${component["formattedValue"] ?? "-"}</td>
|
|
2457
|
+
<td>${component["referenceRange"]?.trim() ?? "-"}</td>
|
|
2458
|
+
<td>${date ?? "-"}</td>
|
|
2459
|
+
</tr>`;
|
|
2460
|
+
}
|
|
2445
2461
|
}
|
|
2446
2462
|
} else {
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
<
|
|
2453
|
-
|
|
2454
|
-
|
|
2463
|
+
const code = data["code"] ?? "";
|
|
2464
|
+
if (code && !observationAdded.has(code)) {
|
|
2465
|
+
observationAdded.add(code);
|
|
2466
|
+
this.formatSummaryObservationData(data);
|
|
2467
|
+
observationhtml += `
|
|
2468
|
+
<tr>
|
|
2469
|
+
<td>${data["code"] ?? "-"}</td>
|
|
2470
|
+
<td>${data["formattedValue"] ?? "-"}</td>
|
|
2471
|
+
<td>${data["referenceRange"]?.trim() ?? "-"}</td>
|
|
2472
|
+
<td>${date ?? "-"}</td>
|
|
2473
|
+
</tr>`;
|
|
2474
|
+
}
|
|
2455
2475
|
}
|
|
2456
2476
|
} else if (resourceItem.title === "DiagnosticReportLab Summary Grouped by DiagnosticReport|Lab Code") {
|
|
2457
2477
|
if (data["status"] === "final") {
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
<
|
|
2463
|
-
|
|
2464
|
-
|
|
2478
|
+
const reportName = data["report"] ?? "";
|
|
2479
|
+
if (reportName && !diagnosticReportAdded.has(reportName)) {
|
|
2480
|
+
diagnosticReportAdded.add(reportName);
|
|
2481
|
+
diagnosticReporthtml += `
|
|
2482
|
+
<tr>
|
|
2483
|
+
<td>${data["report"] ?? "-"}</td>
|
|
2484
|
+
<td>${data["performer"] ?? "-"}</td>
|
|
2485
|
+
<td>${templateUtilities.renderTime(data["issued"], timezone) ?? "-"}</td>
|
|
2486
|
+
</tr>`;
|
|
2487
|
+
}
|
|
2465
2488
|
}
|
|
2466
2489
|
}
|
|
2467
2490
|
}
|
|
2468
2491
|
}
|
|
2469
|
-
if (
|
|
2492
|
+
if (observationAdded.size > 0) {
|
|
2470
2493
|
html += observationhtml;
|
|
2471
2494
|
html += `
|
|
2472
2495
|
</tbody>
|
|
2473
2496
|
</table>
|
|
2474
2497
|
</div>`;
|
|
2475
2498
|
}
|
|
2476
|
-
if (
|
|
2499
|
+
if (diagnosticReportAdded.size > 0) {
|
|
2477
2500
|
html += diagnosticReporthtml;
|
|
2478
2501
|
html += `
|
|
2479
2502
|
</tbody>
|
|
@@ -2482,7 +2505,7 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2482
2505
|
}
|
|
2483
2506
|
html += `
|
|
2484
2507
|
</div>`;
|
|
2485
|
-
return html;
|
|
2508
|
+
return observationAdded.size > 0 || diagnosticReportAdded.size > 0 ? html : void 0;
|
|
2486
2509
|
}
|
|
2487
2510
|
/**
|
|
2488
2511
|
* Internal static implementation that actually generates the narrative
|
|
@@ -2496,8 +2519,8 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2496
2519
|
const observations = this.getObservations(resources);
|
|
2497
2520
|
if (observations.length > 0) {
|
|
2498
2521
|
observations.sort((a, b) => {
|
|
2499
|
-
const dateA = a.effectiveDateTime || a.effectivePeriod?.start;
|
|
2500
|
-
const dateB = b.effectiveDateTime || b.effectivePeriod?.start;
|
|
2522
|
+
const dateA = a.effectiveDateTime || a.effectivePeriod?.start || a.effectivePeriod?.end;
|
|
2523
|
+
const dateB = b.effectiveDateTime || b.effectivePeriod?.start || b.effectivePeriod?.end;
|
|
2501
2524
|
return dateA && dateB ? new Date(dateB).getTime() - new Date(dateA).getTime() : 0;
|
|
2502
2525
|
});
|
|
2503
2526
|
html += this.renderObservations(templateUtilities, observations, timezone);
|
|
@@ -2552,17 +2575,22 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2552
2575
|
</tr>
|
|
2553
2576
|
</thead>
|
|
2554
2577
|
<tbody>`;
|
|
2578
|
+
const observationAdded = /* @__PURE__ */ new Set();
|
|
2555
2579
|
for (const obs of observations) {
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
<
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2580
|
+
const obsCode = templateUtilities.codeableConcept(obs.code);
|
|
2581
|
+
if (!observationAdded.has(obsCode)) {
|
|
2582
|
+
observationAdded.add(obsCode);
|
|
2583
|
+
html += `
|
|
2584
|
+
<tr id="${templateUtilities.narrativeLinkId(obs)}">
|
|
2585
|
+
<td>${obsCode}</td>
|
|
2586
|
+
<td>${templateUtilities.extractObservationValue(obs)}</td>
|
|
2587
|
+
<td>${templateUtilities.extractObservationValueUnit(obs)}</td>
|
|
2588
|
+
<td>${templateUtilities.firstFromCodeableConceptList(obs.interpretation)}</td>
|
|
2589
|
+
<td>${templateUtilities.concatReferenceRange(obs.referenceRange)}</td>
|
|
2590
|
+
<td>${templateUtilities.renderNotes(obs.note, timezone)}</td>
|
|
2591
|
+
<td>${obs.effectiveDateTime ? templateUtilities.renderTime(obs.effectiveDateTime, timezone) : obs.effectivePeriod ? templateUtilities.renderPeriod(obs.effectivePeriod, timezone) : ""}</td>
|
|
2592
|
+
</tr>`;
|
|
2593
|
+
}
|
|
2566
2594
|
}
|
|
2567
2595
|
html += `
|
|
2568
2596
|
</tbody>
|
|
@@ -2589,18 +2617,23 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2589
2617
|
</tr>
|
|
2590
2618
|
</thead>
|
|
2591
2619
|
<tbody>`;
|
|
2620
|
+
const diagnosticReportAdded = /* @__PURE__ */ new Set();
|
|
2592
2621
|
for (const report of reports) {
|
|
2593
|
-
|
|
2594
|
-
if (
|
|
2595
|
-
|
|
2622
|
+
const reportName = templateUtilities.codeableConcept(report.code);
|
|
2623
|
+
if (!diagnosticReportAdded.has(reportName)) {
|
|
2624
|
+
diagnosticReportAdded.add(reportName);
|
|
2625
|
+
let resultCount = "";
|
|
2626
|
+
if (report.result && Array.isArray(report.result)) {
|
|
2627
|
+
resultCount = `${report.result.length} result${report.result.length !== 1 ? "s" : ""}`;
|
|
2628
|
+
}
|
|
2629
|
+
html += `
|
|
2630
|
+
<tr id="${templateUtilities.narrativeLinkId(report)}">
|
|
2631
|
+
<td>${reportName}</td>
|
|
2632
|
+
<td>${templateUtilities.firstFromCodeableConceptList(report.category)}</td>
|
|
2633
|
+
<td>${resultCount}</td>
|
|
2634
|
+
<td>${report.issued ? templateUtilities.renderTime(report.issued, timezone) : ""}</td>
|
|
2635
|
+
</tr>`;
|
|
2596
2636
|
}
|
|
2597
|
-
html += `
|
|
2598
|
-
<tr id="${templateUtilities.narrativeLinkId(report)}">
|
|
2599
|
-
<td>${templateUtilities.codeableConcept(report.code)}</td>
|
|
2600
|
-
<td>${templateUtilities.firstFromCodeableConceptList(report.category)}</td>
|
|
2601
|
-
<td>${resultCount}</td>
|
|
2602
|
-
<td>${report.issued ? templateUtilities.renderTime(report.issued, timezone) : ""}</td>
|
|
2603
|
-
</tr>`;
|
|
2604
2637
|
}
|
|
2605
2638
|
html += `
|
|
2606
2639
|
</tbody>
|
|
@@ -2633,6 +2666,7 @@ var HistoryOfProceduresTemplate = class _HistoryOfProceduresTemplate {
|
|
|
2633
2666
|
*/
|
|
2634
2667
|
generateSummaryNarrative(resources, timezone) {
|
|
2635
2668
|
const templateUtilities = new TemplateUtilities(resources);
|
|
2669
|
+
let isSummaryCreated = false;
|
|
2636
2670
|
let html = `
|
|
2637
2671
|
<div>
|
|
2638
2672
|
<table>
|
|
@@ -2662,6 +2696,7 @@ var HistoryOfProceduresTemplate = class _HistoryOfProceduresTemplate {
|
|
|
2662
2696
|
break;
|
|
2663
2697
|
}
|
|
2664
2698
|
}
|
|
2699
|
+
isSummaryCreated = true;
|
|
2665
2700
|
html += `
|
|
2666
2701
|
<tr>
|
|
2667
2702
|
<td>${data["procedure"] ?? "-"}</td>
|
|
@@ -2674,7 +2709,7 @@ var HistoryOfProceduresTemplate = class _HistoryOfProceduresTemplate {
|
|
|
2674
2709
|
</tbody>
|
|
2675
2710
|
</table>
|
|
2676
2711
|
</div>`;
|
|
2677
|
-
return html;
|
|
2712
|
+
return isSummaryCreated ? html : void 0;
|
|
2678
2713
|
}
|
|
2679
2714
|
/**
|
|
2680
2715
|
* Internal static implementation that actually generates the narrative
|
|
@@ -2778,8 +2813,8 @@ var PastHistoryOfIllnessTemplate = class {
|
|
|
2778
2813
|
let html = ``;
|
|
2779
2814
|
const resolvedConditions = resources.map((entry) => entry) || [];
|
|
2780
2815
|
resolvedConditions.sort((a, b) => {
|
|
2781
|
-
const dateA = a.
|
|
2782
|
-
const dateB = b.
|
|
2816
|
+
const dateA = a.recordedDate ? new Date(a.recordedDate).getTime() : 0;
|
|
2817
|
+
const dateB = b.recordedDate ? new Date(b.recordedDate).getTime() : 0;
|
|
2783
2818
|
return dateB - dateA;
|
|
2784
2819
|
});
|
|
2785
2820
|
html += `
|
|
@@ -2793,13 +2828,18 @@ var PastHistoryOfIllnessTemplate = class {
|
|
|
2793
2828
|
</tr>
|
|
2794
2829
|
</thead>
|
|
2795
2830
|
<tbody>`;
|
|
2831
|
+
const addedConditionCodes = /* @__PURE__ */ new Set();
|
|
2796
2832
|
for (const cond of resolvedConditions) {
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2833
|
+
const conditionCode = templateUtilities.codeableConcept(cond.code);
|
|
2834
|
+
if (!addedConditionCodes.has(conditionCode)) {
|
|
2835
|
+
addedConditionCodes.add(conditionCode);
|
|
2836
|
+
html += `<tr id="${templateUtilities.narrativeLinkId(cond)}">
|
|
2837
|
+
<td class="Name">${conditionCode}</td>
|
|
2838
|
+
<td class="OnsetDate">${templateUtilities.renderDate(cond.onsetDateTime)}</td>
|
|
2839
|
+
<td class="RecordedDate">${templateUtilities.renderDate(cond.recordedDate)}</td>
|
|
2840
|
+
<td class="ResolvedDate">${templateUtilities.renderDate(cond.abatementDateTime)}</td>
|
|
2841
|
+
</tr>`;
|
|
2842
|
+
}
|
|
2803
2843
|
}
|
|
2804
2844
|
html += `</tbody>
|
|
2805
2845
|
</table>`;
|
|
@@ -2858,6 +2898,7 @@ var PlanOfCareTemplate = class {
|
|
|
2858
2898
|
*/
|
|
2859
2899
|
generateSummaryNarrative(resources, timezone) {
|
|
2860
2900
|
const templateUtilities = new TemplateUtilities(resources);
|
|
2901
|
+
let isSummaryCreated = false;
|
|
2861
2902
|
let html = `
|
|
2862
2903
|
<div>
|
|
2863
2904
|
<table>
|
|
@@ -2881,6 +2922,7 @@ var PlanOfCareTemplate = class {
|
|
|
2881
2922
|
if (data["status"] !== "active") {
|
|
2882
2923
|
continue;
|
|
2883
2924
|
}
|
|
2925
|
+
isSummaryCreated = true;
|
|
2884
2926
|
html += `
|
|
2885
2927
|
<tr>
|
|
2886
2928
|
<td>${data["CarePlan Name"] ?? "-"}</td>
|
|
@@ -2894,7 +2936,7 @@ var PlanOfCareTemplate = class {
|
|
|
2894
2936
|
</tbody>
|
|
2895
2937
|
</table>
|
|
2896
2938
|
</div>`;
|
|
2897
|
-
return html;
|
|
2939
|
+
return isSummaryCreated ? html : void 0;
|
|
2898
2940
|
}
|
|
2899
2941
|
};
|
|
2900
2942
|
|
|
@@ -2922,20 +2964,14 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
|
|
|
2922
2964
|
const clinicalImpressions = [];
|
|
2923
2965
|
for (const resourceItem of resources) {
|
|
2924
2966
|
if (resourceItem.resourceType === "Condition") {
|
|
2925
|
-
|
|
2926
|
-
const isResolved = cond.clinicalStatus?.coding?.some(
|
|
2927
|
-
(c) => c.code === "resolved" || c.code === "inactive" || c.display?.toLowerCase().includes("resolved")
|
|
2928
|
-
);
|
|
2929
|
-
if (!isResolved) {
|
|
2930
|
-
activeConditions.push(cond);
|
|
2931
|
-
}
|
|
2967
|
+
activeConditions.push(resourceItem);
|
|
2932
2968
|
} else if (resourceItem.resourceType === "ClinicalImpression") {
|
|
2933
2969
|
clinicalImpressions.push(resourceItem);
|
|
2934
2970
|
}
|
|
2935
2971
|
}
|
|
2936
2972
|
activeConditions.sort((a, b) => {
|
|
2937
|
-
const dateA = a.
|
|
2938
|
-
const dateB = b.
|
|
2973
|
+
const dateA = a.recordedDate ? new Date(a.recordedDate).getTime() : 0;
|
|
2974
|
+
const dateB = b.recordedDate ? new Date(b.recordedDate).getTime() : 0;
|
|
2939
2975
|
return dateB - dateA;
|
|
2940
2976
|
});
|
|
2941
2977
|
clinicalImpressions.sort((a, b) => {
|
|
@@ -2954,12 +2990,17 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
|
|
|
2954
2990
|
</tr>
|
|
2955
2991
|
</thead>
|
|
2956
2992
|
<tbody>`;
|
|
2993
|
+
const addedConditionCodes = /* @__PURE__ */ new Set();
|
|
2957
2994
|
for (const cond of activeConditions) {
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2995
|
+
const conditionCode = templateUtilities.codeableConcept(cond.code);
|
|
2996
|
+
if (!addedConditionCodes.has(conditionCode)) {
|
|
2997
|
+
addedConditionCodes.add(conditionCode);
|
|
2998
|
+
html += `<tr id="${templateUtilities.narrativeLinkId(cond)}">
|
|
2999
|
+
<td class="Name">${conditionCode}</td>
|
|
3000
|
+
<td class="OnsetDate">${templateUtilities.renderDate(cond.onsetDateTime)}</td>
|
|
3001
|
+
<td class="RecordedDate">${templateUtilities.renderDate(cond.recordedDate)}</td>
|
|
3002
|
+
</tr>`;
|
|
3003
|
+
}
|
|
2963
3004
|
}
|
|
2964
3005
|
html += `</tbody>
|
|
2965
3006
|
</table>`;
|
|
@@ -3347,11 +3388,13 @@ var ComprehensiveIPSCompositionBuilder = class {
|
|
|
3347
3388
|
timezone,
|
|
3348
3389
|
true
|
|
3349
3390
|
);
|
|
3350
|
-
}
|
|
3391
|
+
}
|
|
3392
|
+
if (!narrative && sectionType in IPSMandatorySections) {
|
|
3351
3393
|
narrative = await NarrativeGenerator.createNarrativeAsync(
|
|
3352
3394
|
IPSMissingMandatorySectionContent[sectionType]
|
|
3353
3395
|
);
|
|
3354
|
-
}
|
|
3396
|
+
}
|
|
3397
|
+
if (!narrative) {
|
|
3355
3398
|
return this;
|
|
3356
3399
|
}
|
|
3357
3400
|
this.addSectionAsync(narrative, sectionType, validResources);
|
|
@@ -3369,13 +3412,21 @@ var ComprehensiveIPSCompositionBuilder = class {
|
|
|
3369
3412
|
}
|
|
3370
3413
|
});
|
|
3371
3414
|
}
|
|
3372
|
-
|
|
3415
|
+
let narrative = await NarrativeGenerator.generateNarrativeAsync(
|
|
3373
3416
|
sectionType,
|
|
3374
3417
|
summaryCompositions,
|
|
3375
3418
|
timezone,
|
|
3376
3419
|
true,
|
|
3377
3420
|
true
|
|
3378
3421
|
);
|
|
3422
|
+
if (!narrative && sectionType in IPSMandatorySections) {
|
|
3423
|
+
narrative = await NarrativeGenerator.createNarrativeAsync(
|
|
3424
|
+
IPSMissingMandatorySectionContent[sectionType]
|
|
3425
|
+
);
|
|
3426
|
+
}
|
|
3427
|
+
if (!narrative) {
|
|
3428
|
+
return this;
|
|
3429
|
+
}
|
|
3379
3430
|
this.addSectionAsync(narrative, sectionType, sectionResources);
|
|
3380
3431
|
return this;
|
|
3381
3432
|
}
|
package/dist/index.js
CHANGED
|
@@ -114,7 +114,7 @@ var IPSSectionResourceFilters = {
|
|
|
114
114
|
// Only include pregnancy history Observations
|
|
115
115
|
["HistoryOfPregnancySection" /* PREGNANCY_HISTORY */]: (resource) => resource.resourceType === "Observation" && (resource.code?.coding?.some((c) => Object.keys(PREGNANCY_LOINC_CODES.PREGNANCY_STATUS).includes(c.code)) || resource.valueCodeableConcept?.coding?.some((c) => Object.keys(PREGNANCY_LOINC_CODES.PREGNANCY_OUTCOME).includes(c.code))),
|
|
116
116
|
// Only include Conditions or completed ClinicalImpressions
|
|
117
|
-
["FunctionalStatusSection" /* FUNCTIONAL_STATUS */]: (resource) => resource.resourceType === "Condition" || resource.resourceType === "ClinicalImpression" && resource.status === "completed",
|
|
117
|
+
["FunctionalStatusSection" /* FUNCTIONAL_STATUS */]: (resource) => resource.resourceType === "Condition" && resource.clinicalStatus?.coding?.some((c) => !["inactive", "resolved"].includes(c.code)) || resource.resourceType === "ClinicalImpression" && resource.status === "completed",
|
|
118
118
|
// Only include resolved medical history Conditions
|
|
119
119
|
["HistoryOfPastIllnessSection" /* MEDICAL_HISTORY */]: (resource) => resource.resourceType === "Condition" && resource.clinicalStatus?.coding?.some((c) => ["inactive", "resolved"].includes(c.code)),
|
|
120
120
|
// Only include active care plans
|
|
@@ -1298,6 +1298,7 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
|
|
|
1298
1298
|
*/
|
|
1299
1299
|
generateSummaryNarrative(resources, timezone) {
|
|
1300
1300
|
const templateUtilities = new TemplateUtilities(resources);
|
|
1301
|
+
let isSummaryCreated = false;
|
|
1301
1302
|
let html = `
|
|
1302
1303
|
<div>
|
|
1303
1304
|
<table>
|
|
@@ -1327,6 +1328,7 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
|
|
|
1327
1328
|
break;
|
|
1328
1329
|
}
|
|
1329
1330
|
}
|
|
1331
|
+
isSummaryCreated = true;
|
|
1330
1332
|
html += `
|
|
1331
1333
|
<tr>
|
|
1332
1334
|
<td>${data["allergen"] ?? "-"}</td>
|
|
@@ -1339,7 +1341,7 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
|
|
|
1339
1341
|
</tbody>
|
|
1340
1342
|
</table>
|
|
1341
1343
|
</div>`;
|
|
1342
|
-
return html;
|
|
1344
|
+
return isSummaryCreated ? html : void 0;
|
|
1343
1345
|
}
|
|
1344
1346
|
/**
|
|
1345
1347
|
* Internal static implementation that actually generates the narrative
|
|
@@ -1485,6 +1487,7 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
|
|
|
1485
1487
|
*/
|
|
1486
1488
|
generateSummaryNarrative(resources, timezone) {
|
|
1487
1489
|
const templateUtilities = new TemplateUtilities(resources);
|
|
1490
|
+
let isSummaryCreated = false;
|
|
1488
1491
|
let html = `
|
|
1489
1492
|
<div>
|
|
1490
1493
|
<table>
|
|
@@ -1529,6 +1532,7 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
|
|
|
1529
1532
|
}
|
|
1530
1533
|
}
|
|
1531
1534
|
if (data["status"] === "active") {
|
|
1535
|
+
isSummaryCreated = true;
|
|
1532
1536
|
html += `
|
|
1533
1537
|
<tr>
|
|
1534
1538
|
<td>${data["medication"]}</td>
|
|
@@ -1544,7 +1548,7 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
|
|
|
1544
1548
|
</tbody>
|
|
1545
1549
|
</table>
|
|
1546
1550
|
</div>`;
|
|
1547
|
-
return html;
|
|
1551
|
+
return isSummaryCreated ? html : void 0;
|
|
1548
1552
|
}
|
|
1549
1553
|
/**
|
|
1550
1554
|
* Safely parse a date string and return a valid Date object or null
|
|
@@ -1740,6 +1744,7 @@ var ImmunizationsTemplate = class _ImmunizationsTemplate {
|
|
|
1740
1744
|
*/
|
|
1741
1745
|
generateSummaryNarrative(resources, timezone) {
|
|
1742
1746
|
const templateUtilities = new TemplateUtilities(resources);
|
|
1747
|
+
let isSummaryCreated = false;
|
|
1743
1748
|
let html = `
|
|
1744
1749
|
<div>
|
|
1745
1750
|
<table>
|
|
@@ -1770,6 +1775,7 @@ var ImmunizationsTemplate = class _ImmunizationsTemplate {
|
|
|
1770
1775
|
}
|
|
1771
1776
|
}
|
|
1772
1777
|
if (data["status"] === "completed") {
|
|
1778
|
+
isSummaryCreated = true;
|
|
1773
1779
|
html += `
|
|
1774
1780
|
<tr>
|
|
1775
1781
|
<td>${data["immunization"] ?? "-"}</td>
|
|
@@ -1783,7 +1789,7 @@ var ImmunizationsTemplate = class _ImmunizationsTemplate {
|
|
|
1783
1789
|
</tbody>
|
|
1784
1790
|
</table>
|
|
1785
1791
|
</div>`;
|
|
1786
|
-
return html;
|
|
1792
|
+
return isSummaryCreated ? html : void 0;
|
|
1787
1793
|
}
|
|
1788
1794
|
/**
|
|
1789
1795
|
* Internal static implementation that actually generates the narrative
|
|
@@ -1853,8 +1859,8 @@ var ProblemListTemplate = class _ProblemListTemplate {
|
|
|
1853
1859
|
let html = ``;
|
|
1854
1860
|
const activeConditions = resources.map((entry) => entry) || [];
|
|
1855
1861
|
activeConditions.sort((a, b) => {
|
|
1856
|
-
const dateA = a.
|
|
1857
|
-
const dateB = b.
|
|
1862
|
+
const dateA = a.recordedDate ? new Date(a.recordedDate).getTime() : 0;
|
|
1863
|
+
const dateB = b.recordedDate ? new Date(b.recordedDate).getTime() : 0;
|
|
1858
1864
|
return dateB - dateA;
|
|
1859
1865
|
});
|
|
1860
1866
|
html += `
|
|
@@ -1867,12 +1873,17 @@ var ProblemListTemplate = class _ProblemListTemplate {
|
|
|
1867
1873
|
</tr>
|
|
1868
1874
|
</thead>
|
|
1869
1875
|
<tbody>`;
|
|
1876
|
+
const addedConditionCodes = /* @__PURE__ */ new Set();
|
|
1870
1877
|
for (const cond of activeConditions) {
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1878
|
+
const conditionCode = templateUtilities.codeableConcept(cond.code);
|
|
1879
|
+
if (!addedConditionCodes.has(conditionCode)) {
|
|
1880
|
+
addedConditionCodes.add(conditionCode);
|
|
1881
|
+
html += `<tr id="${templateUtilities.narrativeLinkId(cond)}">
|
|
1882
|
+
<td class="Name">${conditionCode}</td>
|
|
1883
|
+
<td class="OnsetDate">${templateUtilities.renderDate(cond.onsetDateTime)}</td>
|
|
1884
|
+
<td class="RecordedDate">${templateUtilities.renderDate(cond.recordedDate)}</td>
|
|
1885
|
+
</tr>`;
|
|
1886
|
+
}
|
|
1876
1887
|
}
|
|
1877
1888
|
html += `</tbody>
|
|
1878
1889
|
</table>`;
|
|
@@ -1899,6 +1910,7 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
|
|
|
1899
1910
|
*/
|
|
1900
1911
|
generateSummaryNarrative(resources, timezone) {
|
|
1901
1912
|
const templateUtilities = new TemplateUtilities(resources);
|
|
1913
|
+
let isSummaryCreated = false;
|
|
1902
1914
|
let html = `
|
|
1903
1915
|
<div>
|
|
1904
1916
|
<table>
|
|
@@ -1938,6 +1950,7 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
|
|
|
1938
1950
|
data[columnTitle] = columnData.text?.div ?? "";
|
|
1939
1951
|
}
|
|
1940
1952
|
}
|
|
1953
|
+
isSummaryCreated = true;
|
|
1941
1954
|
html += `
|
|
1942
1955
|
<tr>
|
|
1943
1956
|
<td>${data["Vital Name"] ?? "-"}</td>
|
|
@@ -1951,7 +1964,7 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
|
|
|
1951
1964
|
</tbody>
|
|
1952
1965
|
</table>
|
|
1953
1966
|
</div>`;
|
|
1954
|
-
return html;
|
|
1967
|
+
return isSummaryCreated ? html : void 0;
|
|
1955
1968
|
}
|
|
1956
1969
|
/**
|
|
1957
1970
|
* Internal static implementation that actually generates the narrative
|
|
@@ -2354,8 +2367,8 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2354
2367
|
</tr>
|
|
2355
2368
|
</thead>
|
|
2356
2369
|
<tbody>`;
|
|
2357
|
-
|
|
2358
|
-
|
|
2370
|
+
const observationAdded = /* @__PURE__ */ new Set();
|
|
2371
|
+
const diagnosticReportAdded = /* @__PURE__ */ new Set();
|
|
2359
2372
|
for (const resourceItem of resources) {
|
|
2360
2373
|
for (const rowData of resourceItem.section ?? []) {
|
|
2361
2374
|
const data = {};
|
|
@@ -2395,7 +2408,6 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2395
2408
|
}
|
|
2396
2409
|
}
|
|
2397
2410
|
if (resourceItem.title === "Observation|Labs Summary Grouped by Lab Code") {
|
|
2398
|
-
observationExists = true;
|
|
2399
2411
|
let date = data["effectiveDateTime"] ? templateUtilities.renderTime(data["effectiveDateTime"], timezone) : "";
|
|
2400
2412
|
if (!date && data["effectivePeriodStart"]) {
|
|
2401
2413
|
date = templateUtilities.renderTime(data["effectivePeriodStart"], timezone);
|
|
@@ -2404,48 +2416,59 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2404
2416
|
}
|
|
2405
2417
|
}
|
|
2406
2418
|
if (components.length > 0) {
|
|
2407
|
-
const groupName = data["code"]
|
|
2419
|
+
const groupName = data["code"] ? `${data["code"]} - ` : "";
|
|
2408
2420
|
for (const component of components) {
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
<
|
|
2415
|
-
|
|
2416
|
-
|
|
2421
|
+
const componentCode = `${groupName}${component["code"] ?? ""}`;
|
|
2422
|
+
if (componentCode && !observationAdded.has(componentCode)) {
|
|
2423
|
+
observationAdded.add(componentCode);
|
|
2424
|
+
this.formatSummaryObservationData(component);
|
|
2425
|
+
observationhtml += `
|
|
2426
|
+
<tr>
|
|
2427
|
+
<td>${componentCode}</td>
|
|
2428
|
+
<td>${component["formattedValue"] ?? "-"}</td>
|
|
2429
|
+
<td>${component["referenceRange"]?.trim() ?? "-"}</td>
|
|
2430
|
+
<td>${date ?? "-"}</td>
|
|
2431
|
+
</tr>`;
|
|
2432
|
+
}
|
|
2417
2433
|
}
|
|
2418
2434
|
} else {
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
<
|
|
2425
|
-
|
|
2426
|
-
|
|
2435
|
+
const code = data["code"] ?? "";
|
|
2436
|
+
if (code && !observationAdded.has(code)) {
|
|
2437
|
+
observationAdded.add(code);
|
|
2438
|
+
this.formatSummaryObservationData(data);
|
|
2439
|
+
observationhtml += `
|
|
2440
|
+
<tr>
|
|
2441
|
+
<td>${data["code"] ?? "-"}</td>
|
|
2442
|
+
<td>${data["formattedValue"] ?? "-"}</td>
|
|
2443
|
+
<td>${data["referenceRange"]?.trim() ?? "-"}</td>
|
|
2444
|
+
<td>${date ?? "-"}</td>
|
|
2445
|
+
</tr>`;
|
|
2446
|
+
}
|
|
2427
2447
|
}
|
|
2428
2448
|
} else if (resourceItem.title === "DiagnosticReportLab Summary Grouped by DiagnosticReport|Lab Code") {
|
|
2429
2449
|
if (data["status"] === "final") {
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
<
|
|
2435
|
-
|
|
2436
|
-
|
|
2450
|
+
const reportName = data["report"] ?? "";
|
|
2451
|
+
if (reportName && !diagnosticReportAdded.has(reportName)) {
|
|
2452
|
+
diagnosticReportAdded.add(reportName);
|
|
2453
|
+
diagnosticReporthtml += `
|
|
2454
|
+
<tr>
|
|
2455
|
+
<td>${data["report"] ?? "-"}</td>
|
|
2456
|
+
<td>${data["performer"] ?? "-"}</td>
|
|
2457
|
+
<td>${templateUtilities.renderTime(data["issued"], timezone) ?? "-"}</td>
|
|
2458
|
+
</tr>`;
|
|
2459
|
+
}
|
|
2437
2460
|
}
|
|
2438
2461
|
}
|
|
2439
2462
|
}
|
|
2440
2463
|
}
|
|
2441
|
-
if (
|
|
2464
|
+
if (observationAdded.size > 0) {
|
|
2442
2465
|
html += observationhtml;
|
|
2443
2466
|
html += `
|
|
2444
2467
|
</tbody>
|
|
2445
2468
|
</table>
|
|
2446
2469
|
</div>`;
|
|
2447
2470
|
}
|
|
2448
|
-
if (
|
|
2471
|
+
if (diagnosticReportAdded.size > 0) {
|
|
2449
2472
|
html += diagnosticReporthtml;
|
|
2450
2473
|
html += `
|
|
2451
2474
|
</tbody>
|
|
@@ -2454,7 +2477,7 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2454
2477
|
}
|
|
2455
2478
|
html += `
|
|
2456
2479
|
</div>`;
|
|
2457
|
-
return html;
|
|
2480
|
+
return observationAdded.size > 0 || diagnosticReportAdded.size > 0 ? html : void 0;
|
|
2458
2481
|
}
|
|
2459
2482
|
/**
|
|
2460
2483
|
* Internal static implementation that actually generates the narrative
|
|
@@ -2468,8 +2491,8 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2468
2491
|
const observations = this.getObservations(resources);
|
|
2469
2492
|
if (observations.length > 0) {
|
|
2470
2493
|
observations.sort((a, b) => {
|
|
2471
|
-
const dateA = a.effectiveDateTime || a.effectivePeriod?.start;
|
|
2472
|
-
const dateB = b.effectiveDateTime || b.effectivePeriod?.start;
|
|
2494
|
+
const dateA = a.effectiveDateTime || a.effectivePeriod?.start || a.effectivePeriod?.end;
|
|
2495
|
+
const dateB = b.effectiveDateTime || b.effectivePeriod?.start || b.effectivePeriod?.end;
|
|
2473
2496
|
return dateA && dateB ? new Date(dateB).getTime() - new Date(dateA).getTime() : 0;
|
|
2474
2497
|
});
|
|
2475
2498
|
html += this.renderObservations(templateUtilities, observations, timezone);
|
|
@@ -2524,17 +2547,22 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2524
2547
|
</tr>
|
|
2525
2548
|
</thead>
|
|
2526
2549
|
<tbody>`;
|
|
2550
|
+
const observationAdded = /* @__PURE__ */ new Set();
|
|
2527
2551
|
for (const obs of observations) {
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
<
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2552
|
+
const obsCode = templateUtilities.codeableConcept(obs.code);
|
|
2553
|
+
if (!observationAdded.has(obsCode)) {
|
|
2554
|
+
observationAdded.add(obsCode);
|
|
2555
|
+
html += `
|
|
2556
|
+
<tr id="${templateUtilities.narrativeLinkId(obs)}">
|
|
2557
|
+
<td>${obsCode}</td>
|
|
2558
|
+
<td>${templateUtilities.extractObservationValue(obs)}</td>
|
|
2559
|
+
<td>${templateUtilities.extractObservationValueUnit(obs)}</td>
|
|
2560
|
+
<td>${templateUtilities.firstFromCodeableConceptList(obs.interpretation)}</td>
|
|
2561
|
+
<td>${templateUtilities.concatReferenceRange(obs.referenceRange)}</td>
|
|
2562
|
+
<td>${templateUtilities.renderNotes(obs.note, timezone)}</td>
|
|
2563
|
+
<td>${obs.effectiveDateTime ? templateUtilities.renderTime(obs.effectiveDateTime, timezone) : obs.effectivePeriod ? templateUtilities.renderPeriod(obs.effectivePeriod, timezone) : ""}</td>
|
|
2564
|
+
</tr>`;
|
|
2565
|
+
}
|
|
2538
2566
|
}
|
|
2539
2567
|
html += `
|
|
2540
2568
|
</tbody>
|
|
@@ -2561,18 +2589,23 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2561
2589
|
</tr>
|
|
2562
2590
|
</thead>
|
|
2563
2591
|
<tbody>`;
|
|
2592
|
+
const diagnosticReportAdded = /* @__PURE__ */ new Set();
|
|
2564
2593
|
for (const report of reports) {
|
|
2565
|
-
|
|
2566
|
-
if (
|
|
2567
|
-
|
|
2594
|
+
const reportName = templateUtilities.codeableConcept(report.code);
|
|
2595
|
+
if (!diagnosticReportAdded.has(reportName)) {
|
|
2596
|
+
diagnosticReportAdded.add(reportName);
|
|
2597
|
+
let resultCount = "";
|
|
2598
|
+
if (report.result && Array.isArray(report.result)) {
|
|
2599
|
+
resultCount = `${report.result.length} result${report.result.length !== 1 ? "s" : ""}`;
|
|
2600
|
+
}
|
|
2601
|
+
html += `
|
|
2602
|
+
<tr id="${templateUtilities.narrativeLinkId(report)}">
|
|
2603
|
+
<td>${reportName}</td>
|
|
2604
|
+
<td>${templateUtilities.firstFromCodeableConceptList(report.category)}</td>
|
|
2605
|
+
<td>${resultCount}</td>
|
|
2606
|
+
<td>${report.issued ? templateUtilities.renderTime(report.issued, timezone) : ""}</td>
|
|
2607
|
+
</tr>`;
|
|
2568
2608
|
}
|
|
2569
|
-
html += `
|
|
2570
|
-
<tr id="${templateUtilities.narrativeLinkId(report)}">
|
|
2571
|
-
<td>${templateUtilities.codeableConcept(report.code)}</td>
|
|
2572
|
-
<td>${templateUtilities.firstFromCodeableConceptList(report.category)}</td>
|
|
2573
|
-
<td>${resultCount}</td>
|
|
2574
|
-
<td>${report.issued ? templateUtilities.renderTime(report.issued, timezone) : ""}</td>
|
|
2575
|
-
</tr>`;
|
|
2576
2609
|
}
|
|
2577
2610
|
html += `
|
|
2578
2611
|
</tbody>
|
|
@@ -2605,6 +2638,7 @@ var HistoryOfProceduresTemplate = class _HistoryOfProceduresTemplate {
|
|
|
2605
2638
|
*/
|
|
2606
2639
|
generateSummaryNarrative(resources, timezone) {
|
|
2607
2640
|
const templateUtilities = new TemplateUtilities(resources);
|
|
2641
|
+
let isSummaryCreated = false;
|
|
2608
2642
|
let html = `
|
|
2609
2643
|
<div>
|
|
2610
2644
|
<table>
|
|
@@ -2634,6 +2668,7 @@ var HistoryOfProceduresTemplate = class _HistoryOfProceduresTemplate {
|
|
|
2634
2668
|
break;
|
|
2635
2669
|
}
|
|
2636
2670
|
}
|
|
2671
|
+
isSummaryCreated = true;
|
|
2637
2672
|
html += `
|
|
2638
2673
|
<tr>
|
|
2639
2674
|
<td>${data["procedure"] ?? "-"}</td>
|
|
@@ -2646,7 +2681,7 @@ var HistoryOfProceduresTemplate = class _HistoryOfProceduresTemplate {
|
|
|
2646
2681
|
</tbody>
|
|
2647
2682
|
</table>
|
|
2648
2683
|
</div>`;
|
|
2649
|
-
return html;
|
|
2684
|
+
return isSummaryCreated ? html : void 0;
|
|
2650
2685
|
}
|
|
2651
2686
|
/**
|
|
2652
2687
|
* Internal static implementation that actually generates the narrative
|
|
@@ -2750,8 +2785,8 @@ var PastHistoryOfIllnessTemplate = class {
|
|
|
2750
2785
|
let html = ``;
|
|
2751
2786
|
const resolvedConditions = resources.map((entry) => entry) || [];
|
|
2752
2787
|
resolvedConditions.sort((a, b) => {
|
|
2753
|
-
const dateA = a.
|
|
2754
|
-
const dateB = b.
|
|
2788
|
+
const dateA = a.recordedDate ? new Date(a.recordedDate).getTime() : 0;
|
|
2789
|
+
const dateB = b.recordedDate ? new Date(b.recordedDate).getTime() : 0;
|
|
2755
2790
|
return dateB - dateA;
|
|
2756
2791
|
});
|
|
2757
2792
|
html += `
|
|
@@ -2765,13 +2800,18 @@ var PastHistoryOfIllnessTemplate = class {
|
|
|
2765
2800
|
</tr>
|
|
2766
2801
|
</thead>
|
|
2767
2802
|
<tbody>`;
|
|
2803
|
+
const addedConditionCodes = /* @__PURE__ */ new Set();
|
|
2768
2804
|
for (const cond of resolvedConditions) {
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2805
|
+
const conditionCode = templateUtilities.codeableConcept(cond.code);
|
|
2806
|
+
if (!addedConditionCodes.has(conditionCode)) {
|
|
2807
|
+
addedConditionCodes.add(conditionCode);
|
|
2808
|
+
html += `<tr id="${templateUtilities.narrativeLinkId(cond)}">
|
|
2809
|
+
<td class="Name">${conditionCode}</td>
|
|
2810
|
+
<td class="OnsetDate">${templateUtilities.renderDate(cond.onsetDateTime)}</td>
|
|
2811
|
+
<td class="RecordedDate">${templateUtilities.renderDate(cond.recordedDate)}</td>
|
|
2812
|
+
<td class="ResolvedDate">${templateUtilities.renderDate(cond.abatementDateTime)}</td>
|
|
2813
|
+
</tr>`;
|
|
2814
|
+
}
|
|
2775
2815
|
}
|
|
2776
2816
|
html += `</tbody>
|
|
2777
2817
|
</table>`;
|
|
@@ -2830,6 +2870,7 @@ var PlanOfCareTemplate = class {
|
|
|
2830
2870
|
*/
|
|
2831
2871
|
generateSummaryNarrative(resources, timezone) {
|
|
2832
2872
|
const templateUtilities = new TemplateUtilities(resources);
|
|
2873
|
+
let isSummaryCreated = false;
|
|
2833
2874
|
let html = `
|
|
2834
2875
|
<div>
|
|
2835
2876
|
<table>
|
|
@@ -2853,6 +2894,7 @@ var PlanOfCareTemplate = class {
|
|
|
2853
2894
|
if (data["status"] !== "active") {
|
|
2854
2895
|
continue;
|
|
2855
2896
|
}
|
|
2897
|
+
isSummaryCreated = true;
|
|
2856
2898
|
html += `
|
|
2857
2899
|
<tr>
|
|
2858
2900
|
<td>${data["CarePlan Name"] ?? "-"}</td>
|
|
@@ -2866,7 +2908,7 @@ var PlanOfCareTemplate = class {
|
|
|
2866
2908
|
</tbody>
|
|
2867
2909
|
</table>
|
|
2868
2910
|
</div>`;
|
|
2869
|
-
return html;
|
|
2911
|
+
return isSummaryCreated ? html : void 0;
|
|
2870
2912
|
}
|
|
2871
2913
|
};
|
|
2872
2914
|
|
|
@@ -2894,20 +2936,14 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
|
|
|
2894
2936
|
const clinicalImpressions = [];
|
|
2895
2937
|
for (const resourceItem of resources) {
|
|
2896
2938
|
if (resourceItem.resourceType === "Condition") {
|
|
2897
|
-
|
|
2898
|
-
const isResolved = cond.clinicalStatus?.coding?.some(
|
|
2899
|
-
(c) => c.code === "resolved" || c.code === "inactive" || c.display?.toLowerCase().includes("resolved")
|
|
2900
|
-
);
|
|
2901
|
-
if (!isResolved) {
|
|
2902
|
-
activeConditions.push(cond);
|
|
2903
|
-
}
|
|
2939
|
+
activeConditions.push(resourceItem);
|
|
2904
2940
|
} else if (resourceItem.resourceType === "ClinicalImpression") {
|
|
2905
2941
|
clinicalImpressions.push(resourceItem);
|
|
2906
2942
|
}
|
|
2907
2943
|
}
|
|
2908
2944
|
activeConditions.sort((a, b) => {
|
|
2909
|
-
const dateA = a.
|
|
2910
|
-
const dateB = b.
|
|
2945
|
+
const dateA = a.recordedDate ? new Date(a.recordedDate).getTime() : 0;
|
|
2946
|
+
const dateB = b.recordedDate ? new Date(b.recordedDate).getTime() : 0;
|
|
2911
2947
|
return dateB - dateA;
|
|
2912
2948
|
});
|
|
2913
2949
|
clinicalImpressions.sort((a, b) => {
|
|
@@ -2926,12 +2962,17 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
|
|
|
2926
2962
|
</tr>
|
|
2927
2963
|
</thead>
|
|
2928
2964
|
<tbody>`;
|
|
2965
|
+
const addedConditionCodes = /* @__PURE__ */ new Set();
|
|
2929
2966
|
for (const cond of activeConditions) {
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2967
|
+
const conditionCode = templateUtilities.codeableConcept(cond.code);
|
|
2968
|
+
if (!addedConditionCodes.has(conditionCode)) {
|
|
2969
|
+
addedConditionCodes.add(conditionCode);
|
|
2970
|
+
html += `<tr id="${templateUtilities.narrativeLinkId(cond)}">
|
|
2971
|
+
<td class="Name">${conditionCode}</td>
|
|
2972
|
+
<td class="OnsetDate">${templateUtilities.renderDate(cond.onsetDateTime)}</td>
|
|
2973
|
+
<td class="RecordedDate">${templateUtilities.renderDate(cond.recordedDate)}</td>
|
|
2974
|
+
</tr>`;
|
|
2975
|
+
}
|
|
2935
2976
|
}
|
|
2936
2977
|
html += `</tbody>
|
|
2937
2978
|
</table>`;
|
|
@@ -3319,11 +3360,13 @@ var ComprehensiveIPSCompositionBuilder = class {
|
|
|
3319
3360
|
timezone,
|
|
3320
3361
|
true
|
|
3321
3362
|
);
|
|
3322
|
-
}
|
|
3363
|
+
}
|
|
3364
|
+
if (!narrative && sectionType in IPSMandatorySections) {
|
|
3323
3365
|
narrative = await NarrativeGenerator.createNarrativeAsync(
|
|
3324
3366
|
IPSMissingMandatorySectionContent[sectionType]
|
|
3325
3367
|
);
|
|
3326
|
-
}
|
|
3368
|
+
}
|
|
3369
|
+
if (!narrative) {
|
|
3327
3370
|
return this;
|
|
3328
3371
|
}
|
|
3329
3372
|
this.addSectionAsync(narrative, sectionType, validResources);
|
|
@@ -3341,13 +3384,21 @@ var ComprehensiveIPSCompositionBuilder = class {
|
|
|
3341
3384
|
}
|
|
3342
3385
|
});
|
|
3343
3386
|
}
|
|
3344
|
-
|
|
3387
|
+
let narrative = await NarrativeGenerator.generateNarrativeAsync(
|
|
3345
3388
|
sectionType,
|
|
3346
3389
|
summaryCompositions,
|
|
3347
3390
|
timezone,
|
|
3348
3391
|
true,
|
|
3349
3392
|
true
|
|
3350
3393
|
);
|
|
3394
|
+
if (!narrative && sectionType in IPSMandatorySections) {
|
|
3395
|
+
narrative = await NarrativeGenerator.createNarrativeAsync(
|
|
3396
|
+
IPSMissingMandatorySectionContent[sectionType]
|
|
3397
|
+
);
|
|
3398
|
+
}
|
|
3399
|
+
if (!narrative) {
|
|
3400
|
+
return this;
|
|
3401
|
+
}
|
|
3351
3402
|
this.addSectionAsync(narrative, sectionType, sectionResources);
|
|
3352
3403
|
return this;
|
|
3353
3404
|
}
|