@imranq2/fhirpatientsummary 1.0.25 → 1.0.27
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 +512 -108
- package/dist/index.js +512 -108
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -115,6 +115,8 @@ var VITAL_SIGNS_SUMMARY_COMPONENT_MAP = {
|
|
|
115
115
|
"Diastolic Blood Pressure": "valueRatio.denominator.value",
|
|
116
116
|
"Default": "valueString"
|
|
117
117
|
};
|
|
118
|
+
var RESULT_SUMMARY_OBSERVATION_CATEGORIES = ["laboratory", "Lab", "LAB"];
|
|
119
|
+
var RESULT_SUMMARY_OBSERVATION_DATE_FILTER = 2 * 365 * 24 * 60 * 60 * 1e3;
|
|
118
120
|
var IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM = "https://fhir.icanbwell.com/4_0_0/CodeSystem/composition/";
|
|
119
121
|
|
|
120
122
|
// src/structures/ips_section_resource_map.ts
|
|
@@ -134,7 +136,7 @@ var IPSSectionResourceFilters = {
|
|
|
134
136
|
// Includes DeviceUseStatement. Device is needed for linked device details
|
|
135
137
|
["MedicalDeviceSection" /* MEDICAL_DEVICES */]: (resource) => ["DeviceUseStatement", "Device"].includes(resource.resourceType),
|
|
136
138
|
// Only include finalized diagnostic reports
|
|
137
|
-
["ResultsSection" /* DIAGNOSTIC_REPORTS */]: (resource) =>
|
|
139
|
+
["ResultsSection" /* DIAGNOSTIC_REPORTS */]: (resource) => resource.resourceType === "Observation" && resource.category?.some((cat) => cat.coding?.some((c) => RESULT_SUMMARY_OBSERVATION_CATEGORIES.includes(c.code))),
|
|
138
140
|
// Only include completed procedures
|
|
139
141
|
["HistoryOfProceduresSection" /* PROCEDURES */]: (resource) => resource.resourceType === "Procedure" && resource.status === "completed",
|
|
140
142
|
// Only include social history Observations
|
|
@@ -142,7 +144,7 @@ var IPSSectionResourceFilters = {
|
|
|
142
144
|
// Only include pregnancy history Observations
|
|
143
145
|
["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
146
|
// Only include Conditions or completed ClinicalImpressions
|
|
145
|
-
["FunctionalStatusSection" /* FUNCTIONAL_STATUS */]: (resource) => resource.resourceType === "Condition" || resource.resourceType === "ClinicalImpression" && resource.status === "completed",
|
|
147
|
+
["FunctionalStatusSection" /* FUNCTIONAL_STATUS */]: (resource) => resource.resourceType === "Condition" && resource.clinicalStatus?.coding?.some((c) => !["inactive", "resolved"].includes(c.code)) || resource.resourceType === "ClinicalImpression" && resource.status === "completed",
|
|
146
148
|
// Only include resolved medical history Conditions
|
|
147
149
|
["HistoryOfPastIllnessSection" /* MEDICAL_HISTORY */]: (resource) => resource.resourceType === "Condition" && resource.clinicalStatus?.coding?.some((c) => ["inactive", "resolved"].includes(c.code)),
|
|
148
150
|
// Only include active care plans
|
|
@@ -156,7 +158,7 @@ var IPSSectionSummaryCompositionFilter = {
|
|
|
156
158
|
["PlanOfCareSection" /* CARE_PLAN */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => c.system === IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM && c.code === "careplan_summary_document"),
|
|
157
159
|
["ImmunizationSection" /* IMMUNIZATIONS */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => c.system === IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM && c.code === "immunization_summary_document"),
|
|
158
160
|
["MedicationSummarySection" /* MEDICATIONS */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => c.system === IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM && c.code === "medication_summary_document"),
|
|
159
|
-
[
|
|
161
|
+
// [IPSSections.DIAGNOSTIC_REPORTS]: (resource) => resource.resourceType === 'Composition' && resource.type?.coding?.some((c: any) => c.system === IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM && ["lab_summary_document", "diagnosticreportlab_summary_document"].includes(c.code)),
|
|
160
162
|
["HistoryOfProceduresSection" /* PROCEDURES */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => c.system === IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM && c.code === "procedure_summary_document")
|
|
161
163
|
};
|
|
162
164
|
var IPSSectionResourceHelper = class {
|
|
@@ -620,9 +622,18 @@ var TemplateUtilities = class {
|
|
|
620
622
|
}
|
|
621
623
|
return status;
|
|
622
624
|
}
|
|
625
|
+
formatFloatValue(value) {
|
|
626
|
+
if (typeof value === "number") {
|
|
627
|
+
return value.toFixed(2).replace(/\.?0+$/, "");
|
|
628
|
+
} else if (typeof value === "string" && !isNaN(Number(value))) {
|
|
629
|
+
return parseFloat(value).toFixed(2).replace(/\.?0+$/, "");
|
|
630
|
+
}
|
|
631
|
+
return value;
|
|
632
|
+
}
|
|
623
633
|
extractObservationSummaryValue(data, timezone) {
|
|
624
634
|
if (data["valueQuantity.value"] !== void 0) {
|
|
625
|
-
|
|
635
|
+
let value = data["valueQuantity.value"];
|
|
636
|
+
value = this.formatFloatValue(value);
|
|
626
637
|
const unit = data["valueQuantity.unit"];
|
|
627
638
|
return unit ? `${value} ${unit}` : `${value}`;
|
|
628
639
|
}
|
|
@@ -639,7 +650,9 @@ var TemplateUtilities = class {
|
|
|
639
650
|
return String(data["valueBoolean"]);
|
|
640
651
|
}
|
|
641
652
|
if (data["valueInteger"] !== void 0) {
|
|
642
|
-
|
|
653
|
+
let value = String(data["valueInteger"]);
|
|
654
|
+
value = this.formatFloatValue(value);
|
|
655
|
+
return value;
|
|
643
656
|
}
|
|
644
657
|
if (data["valueDateTime"] !== void 0) {
|
|
645
658
|
return this.renderTime(data["valueDateTime"], timezone);
|
|
@@ -659,7 +672,8 @@ var TemplateUtilities = class {
|
|
|
659
672
|
return this.renderTime(data["valueTime"], timezone);
|
|
660
673
|
}
|
|
661
674
|
if (data["valueSampledData.origin.value"] !== void 0 || data["valueSampledData.origin.unit"] !== void 0) {
|
|
662
|
-
|
|
675
|
+
let originValue = data["valueSampledData.origin.value"];
|
|
676
|
+
originValue = this.formatFloatValue(originValue);
|
|
663
677
|
const originUnit = data["valueSampledData.origin.unit"];
|
|
664
678
|
let result = "";
|
|
665
679
|
if (originValue !== void 0 && originUnit !== void 0) {
|
|
@@ -669,10 +683,10 @@ var TemplateUtilities = class {
|
|
|
669
683
|
} else if (originUnit !== void 0) {
|
|
670
684
|
result = `${originUnit}`;
|
|
671
685
|
}
|
|
672
|
-
const period = data["valueSampledData.period"];
|
|
673
|
-
const factor = data["valueSampledData.factor"];
|
|
674
|
-
const lowerLimit = data["valueSampledData.lowerLimit"];
|
|
675
|
-
const upperLimit = data["valueSampledData.upperLimit"];
|
|
686
|
+
const period = this.formatFloatValue(data["valueSampledData.period"]);
|
|
687
|
+
const factor = this.formatFloatValue(data["valueSampledData.factor"]);
|
|
688
|
+
const lowerLimit = this.formatFloatValue(data["valueSampledData.lowerLimit"]);
|
|
689
|
+
const upperLimit = this.formatFloatValue(data["valueSampledData.upperLimit"]);
|
|
676
690
|
const sampledData = data["valueSampledData.data"];
|
|
677
691
|
const extras = [];
|
|
678
692
|
if (period !== void 0) extras.push(`period: ${period}`);
|
|
@@ -708,14 +722,14 @@ var TemplateUtilities = class {
|
|
|
708
722
|
if (data["valueRatio.numerator.value"] !== void 0 || data["valueRatio.denominator.value"] !== void 0) {
|
|
709
723
|
let ratio = "";
|
|
710
724
|
if (data["valueRatio.numerator.value"] !== void 0) {
|
|
711
|
-
ratio += `${data["valueRatio.numerator.value"]}`;
|
|
725
|
+
ratio += `${this.formatFloatValue(data["valueRatio.numerator.value"])}`;
|
|
712
726
|
if (data["valueRatio.numerator.unit"] !== void 0) {
|
|
713
727
|
ratio += ` ${data["valueRatio.numerator.unit"]}`;
|
|
714
728
|
}
|
|
715
729
|
}
|
|
716
730
|
if (data["valueRatio.denominator.value"] !== void 0) {
|
|
717
731
|
ratio += " / ";
|
|
718
|
-
ratio += `${data["valueRatio.denominator.value"]}`;
|
|
732
|
+
ratio += `${this.formatFloatValue(data["valueRatio.denominator.value"])}`;
|
|
719
733
|
if (data["valueRatio.denominator.unit"] !== void 0) {
|
|
720
734
|
ratio += ` ${data["valueRatio.denominator.unit"]}`;
|
|
721
735
|
}
|
|
@@ -969,6 +983,313 @@ var TemplateUtilities = class {
|
|
|
969
983
|
|
|
970
984
|
// src/constants.ts
|
|
971
985
|
var ADDRESS_SIMILARITY_THRESHOLD = 70;
|
|
986
|
+
var LAB_LOINC_MAP = {
|
|
987
|
+
// METABOLIC PANELS (VERY COMMONLY ORDERED)
|
|
988
|
+
"Basic Metabolic Panel": [
|
|
989
|
+
"24321-2",
|
|
990
|
+
// Basic metabolic 2000 panel - Serum or Plasma
|
|
991
|
+
"51990-0"
|
|
992
|
+
// Basic metabolic 2000 panel - Blood
|
|
993
|
+
],
|
|
994
|
+
"Comprehensive Metabolic Panel": [
|
|
995
|
+
"24323-8"
|
|
996
|
+
// Comprehensive metabolic 2000 panel - Serum or Plasma
|
|
997
|
+
],
|
|
998
|
+
// CBC COMPONENTS
|
|
999
|
+
Hemoglobin: [
|
|
1000
|
+
"718-7"
|
|
1001
|
+
// Hemoglobin [Mass/volume] in Blood
|
|
1002
|
+
],
|
|
1003
|
+
Hematocrit: [
|
|
1004
|
+
"4544-3"
|
|
1005
|
+
// Hematocrit [Volume Fraction] of Blood by Automated count
|
|
1006
|
+
],
|
|
1007
|
+
"White Blood Cell Count": [
|
|
1008
|
+
"6690-2"
|
|
1009
|
+
// Leukocytes [///volume] in Blood by Automated count
|
|
1010
|
+
],
|
|
1011
|
+
"Platelet Count": [
|
|
1012
|
+
"777-3"
|
|
1013
|
+
// Platelets [///volume] in Blood by Automated count
|
|
1014
|
+
],
|
|
1015
|
+
"Complete Blood Count": [
|
|
1016
|
+
"58410-2",
|
|
1017
|
+
// CBC panel - Blood by Automated count
|
|
1018
|
+
"57021-8",
|
|
1019
|
+
// CBC W Auto Differential panel - Blood
|
|
1020
|
+
"69738-3"
|
|
1021
|
+
// CBC W Auto Differential panel - Blood by Automated count
|
|
1022
|
+
],
|
|
1023
|
+
// CHEMISTRY - GLUCOSE
|
|
1024
|
+
Glucose: [
|
|
1025
|
+
"2345-7",
|
|
1026
|
+
// Glucose [Mass/volume] in Serum or Plasma
|
|
1027
|
+
"1558-6",
|
|
1028
|
+
// Fasting glucose [Mass/volume] in Serum or Plasma
|
|
1029
|
+
"2339-0"
|
|
1030
|
+
// Glucose [Mass/volume] in Blood
|
|
1031
|
+
],
|
|
1032
|
+
// RENAL FUNCTION
|
|
1033
|
+
Creatinine: [
|
|
1034
|
+
"2160-0"
|
|
1035
|
+
// Creatinine [Mass/volume] in Serum or Plasma
|
|
1036
|
+
],
|
|
1037
|
+
"Blood Urea Nitrogen": [
|
|
1038
|
+
"3094-0",
|
|
1039
|
+
// Urea nitrogen [Mass/volume] in Serum or Plasma
|
|
1040
|
+
"6299-2"
|
|
1041
|
+
// Urea nitrogen [Mass/volume] in Blood
|
|
1042
|
+
],
|
|
1043
|
+
// ELECTROLYTES
|
|
1044
|
+
Sodium: [
|
|
1045
|
+
"2951-2"
|
|
1046
|
+
// Sodium [Moles/volume] in Serum or Plasma
|
|
1047
|
+
],
|
|
1048
|
+
Potassium: [
|
|
1049
|
+
"2823-3"
|
|
1050
|
+
// Potassium [Moles/volume] in Serum or Plasma
|
|
1051
|
+
],
|
|
1052
|
+
Chloride: [
|
|
1053
|
+
"2075-0"
|
|
1054
|
+
// Chloride [Moles/volume] in Serum or Plasma
|
|
1055
|
+
],
|
|
1056
|
+
Calcium: [
|
|
1057
|
+
"17861-6",
|
|
1058
|
+
// Calcium [Mass/volume] in Serum or Plasma
|
|
1059
|
+
"1994-3"
|
|
1060
|
+
// Calcium.ionized [Moles/volume] in Serum or Plasma
|
|
1061
|
+
],
|
|
1062
|
+
Magnesium: [
|
|
1063
|
+
"19123-9"
|
|
1064
|
+
// Magnesium [Mass/volume] in Serum or Plasma
|
|
1065
|
+
],
|
|
1066
|
+
Phosphate: [
|
|
1067
|
+
"14879-1"
|
|
1068
|
+
// Phosphate [Mass/volume] in Serum or Plasma
|
|
1069
|
+
],
|
|
1070
|
+
// PROTEINS
|
|
1071
|
+
Albumin: [
|
|
1072
|
+
"1751-7"
|
|
1073
|
+
// Albumin [Mass/volume] in Serum or Plasma
|
|
1074
|
+
],
|
|
1075
|
+
"Total Protein": [
|
|
1076
|
+
"2885-2"
|
|
1077
|
+
// Protein [Mass/volume] in Serum or Plasma
|
|
1078
|
+
],
|
|
1079
|
+
// LIVER FUNCTION
|
|
1080
|
+
Bilirubin: [
|
|
1081
|
+
"1975-2",
|
|
1082
|
+
// Bilirubin.total [Mass/volume] in Serum or Plasma
|
|
1083
|
+
"1968-7",
|
|
1084
|
+
// Bilirubin.direct [Mass/volume] in Serum or Plasma
|
|
1085
|
+
"1971-1"
|
|
1086
|
+
// Bilirubin.indirect [Mass/volume] in Serum or Plasma
|
|
1087
|
+
],
|
|
1088
|
+
"Alkaline Phosphatase": [
|
|
1089
|
+
"6768-6"
|
|
1090
|
+
// Alkaline phosphatase [Enzymatic activity/volume] in Serum or Plasma
|
|
1091
|
+
],
|
|
1092
|
+
AST: [
|
|
1093
|
+
"1920-8"
|
|
1094
|
+
// Aspartate aminotransferase [Enzymatic activity/volume] in Serum or Plasma
|
|
1095
|
+
],
|
|
1096
|
+
ALT: [
|
|
1097
|
+
"1742-6"
|
|
1098
|
+
// Alanine aminotransferase [Enzymatic activity/volume] in Serum or Plasma
|
|
1099
|
+
],
|
|
1100
|
+
GGT: [
|
|
1101
|
+
"2324-2"
|
|
1102
|
+
// Gamma glutamyl transferase [Enzymatic activity/volume] in Serum or Plasma
|
|
1103
|
+
],
|
|
1104
|
+
// ENDOCRINE
|
|
1105
|
+
TSH: [
|
|
1106
|
+
"3016-3"
|
|
1107
|
+
// Thyrotropin [Units/volume] in Serum or Plasma
|
|
1108
|
+
],
|
|
1109
|
+
"Free T4": [
|
|
1110
|
+
"3024-7"
|
|
1111
|
+
// Thyroxine (T4) free [Mass/volume] in Serum or Plasma
|
|
1112
|
+
],
|
|
1113
|
+
"Total T4": [
|
|
1114
|
+
"3026-2"
|
|
1115
|
+
// Thyroxine (T4) [Mass/volume] in Serum or Plasma
|
|
1116
|
+
],
|
|
1117
|
+
"Free T3": [
|
|
1118
|
+
"3051-0"
|
|
1119
|
+
// Triiodothyronine (T3) free [Mass/volume] in Serum or Plasma
|
|
1120
|
+
],
|
|
1121
|
+
"Total T3": [
|
|
1122
|
+
"3053-6"
|
|
1123
|
+
// Triiodothyronine (T3) [Mass/volume] in Serum or Plasma
|
|
1124
|
+
],
|
|
1125
|
+
HbA1c: [
|
|
1126
|
+
"4548-4",
|
|
1127
|
+
// Hemoglobin A1c/Hemoglobin.total in Blood
|
|
1128
|
+
"17856-6"
|
|
1129
|
+
// Hemoglobin A1c/Hemoglobin.total in Blood by HPLC
|
|
1130
|
+
],
|
|
1131
|
+
// LIPID PANEL
|
|
1132
|
+
"Lipid Panel": [
|
|
1133
|
+
"24331-1",
|
|
1134
|
+
// Lipid 1996 panel - Serum or Plasma
|
|
1135
|
+
"57698-3"
|
|
1136
|
+
// Lipid panel with direct LDL - Serum or Plasma
|
|
1137
|
+
],
|
|
1138
|
+
"Cholesterol Total": [
|
|
1139
|
+
"2093-3"
|
|
1140
|
+
// Cholesterol [Mass/volume] in Serum or Plasma
|
|
1141
|
+
],
|
|
1142
|
+
"HDL Cholesterol": [
|
|
1143
|
+
"2085-9"
|
|
1144
|
+
// Cholesterol in HDL [Mass/volume] in Serum or Plasma
|
|
1145
|
+
],
|
|
1146
|
+
"LDL Cholesterol": [
|
|
1147
|
+
"13457-7",
|
|
1148
|
+
// Cholesterol in LDL [Mass/volume] in Serum or Plasma by calculation
|
|
1149
|
+
"18262-6"
|
|
1150
|
+
// Cholesterol in LDL [Mass/volume] in Serum or Plasma by Direct assay
|
|
1151
|
+
],
|
|
1152
|
+
Triglycerides: [
|
|
1153
|
+
"2571-8"
|
|
1154
|
+
// Triglyceride [Mass/volume] in Serum or Plasma
|
|
1155
|
+
],
|
|
1156
|
+
// COAGULATION STUDIES (COMMONLY MISSING!)
|
|
1157
|
+
PT: [
|
|
1158
|
+
"5902-2"
|
|
1159
|
+
// Prothrombin time (PT)
|
|
1160
|
+
],
|
|
1161
|
+
INR: [
|
|
1162
|
+
"6301-6"
|
|
1163
|
+
// INR in Platelet poor plasma by Coagulation assay
|
|
1164
|
+
],
|
|
1165
|
+
PTT: [
|
|
1166
|
+
"3173-2",
|
|
1167
|
+
// aPTT in Blood by Coagulation assay
|
|
1168
|
+
"14979-9"
|
|
1169
|
+
// aPTT in Platelet poor plasma by Coagulation assay
|
|
1170
|
+
],
|
|
1171
|
+
Fibrinogen: [
|
|
1172
|
+
"3255-7"
|
|
1173
|
+
// Fibrinogen [Mass/volume] in Platelet poor plasma by Coagulation assay
|
|
1174
|
+
],
|
|
1175
|
+
"D-Dimer": [
|
|
1176
|
+
"48065-7",
|
|
1177
|
+
// D-dimer FEU [Mass/volume] in Platelet poor plasma
|
|
1178
|
+
"48066-5"
|
|
1179
|
+
// D-dimer DDU [Mass/volume] in Platelet poor plasma
|
|
1180
|
+
],
|
|
1181
|
+
// CARDIAC MARKERS (CRITICAL FOR ER!)
|
|
1182
|
+
"Troponin I": [
|
|
1183
|
+
"10839-9",
|
|
1184
|
+
// Troponin I.cardiac [Mass/volume] in Serum or Plasma
|
|
1185
|
+
"42757-5",
|
|
1186
|
+
// Troponin I.cardiac [Mass/volume] in Blood
|
|
1187
|
+
"89579-7"
|
|
1188
|
+
// Troponin I.cardiac [Mass/volume] in Serum or Plasma by High sensitivity method
|
|
1189
|
+
],
|
|
1190
|
+
"Troponin T": [
|
|
1191
|
+
"6598-7",
|
|
1192
|
+
// Troponin T.cardiac [Mass/volume] in Serum or Plasma
|
|
1193
|
+
"48425-3"
|
|
1194
|
+
// Troponin T.cardiac [Mass/volume] in Serum or Plasma by High sensitivity method
|
|
1195
|
+
],
|
|
1196
|
+
BNP: [
|
|
1197
|
+
"30934-4"
|
|
1198
|
+
// BNP [Mass/volume] in Serum or Plasma
|
|
1199
|
+
],
|
|
1200
|
+
"NT-proBNP": [
|
|
1201
|
+
"33762-6"
|
|
1202
|
+
// NT-proBNP [Mass/volume] in Serum or Plasma
|
|
1203
|
+
],
|
|
1204
|
+
"CK-MB": [
|
|
1205
|
+
"13969-1"
|
|
1206
|
+
// Creatine kinase.MB [Mass/volume] in Serum or Plasma
|
|
1207
|
+
],
|
|
1208
|
+
// INFLAMMATORY MARKERS
|
|
1209
|
+
CRP: [
|
|
1210
|
+
"1988-5",
|
|
1211
|
+
// C reactive protein [Mass/volume] in Serum or Plasma
|
|
1212
|
+
"30522-7"
|
|
1213
|
+
// C reactive protein [Mass/volume] in Serum or Plasma by High sensitivity method
|
|
1214
|
+
],
|
|
1215
|
+
ESR: [
|
|
1216
|
+
"30341-2",
|
|
1217
|
+
// Erythrocyte sedimentation rate by Westergren method
|
|
1218
|
+
"4537-7"
|
|
1219
|
+
// Erythrocyte sedimentation rate
|
|
1220
|
+
],
|
|
1221
|
+
// VITAMINS & MINERALS (VERY HIGH VOLUME!)
|
|
1222
|
+
"Vitamin D": [
|
|
1223
|
+
"1990-1",
|
|
1224
|
+
// Vitamin D [Mass/volume] in Serum or Plasma (obsolete, but still used)
|
|
1225
|
+
"14635-7",
|
|
1226
|
+
// 25-Hydroxyvitamin D3 [Mass/volume] in Serum or Plasma
|
|
1227
|
+
"62292-8"
|
|
1228
|
+
// 25-Hydroxyvitamin D2+D3 [Mass/volume] in Serum or Plasma
|
|
1229
|
+
],
|
|
1230
|
+
"Vitamin B12": [
|
|
1231
|
+
"2132-9"
|
|
1232
|
+
// Cobalamin (Vitamin B12) [Mass/volume] in Serum or Plasma
|
|
1233
|
+
],
|
|
1234
|
+
Folate: [
|
|
1235
|
+
"2284-8",
|
|
1236
|
+
// Folate [Mass/volume] in Serum or Plasma
|
|
1237
|
+
"15152-2"
|
|
1238
|
+
// Folate [Mass/volume] in Red Blood Cells
|
|
1239
|
+
],
|
|
1240
|
+
Iron: [
|
|
1241
|
+
"2498-4"
|
|
1242
|
+
// Iron [Mass/volume] in Serum or Plasma
|
|
1243
|
+
],
|
|
1244
|
+
Ferritin: [
|
|
1245
|
+
"2276-4"
|
|
1246
|
+
// Ferritin [Mass/volume] in Serum or Plasma
|
|
1247
|
+
],
|
|
1248
|
+
TIBC: [
|
|
1249
|
+
"2500-7"
|
|
1250
|
+
// Iron binding capacity [Mass/volume] in Serum or Plasma
|
|
1251
|
+
],
|
|
1252
|
+
// OTHER COMMON TESTS
|
|
1253
|
+
PSA: [
|
|
1254
|
+
"2857-1",
|
|
1255
|
+
// Prostate specific Ag [Mass/volume] in Serum or Plasma
|
|
1256
|
+
"10886-0"
|
|
1257
|
+
// Prostate specific Ag Free [Mass/volume] in Serum or Plasma
|
|
1258
|
+
],
|
|
1259
|
+
"Uric Acid": [
|
|
1260
|
+
"3084-1"
|
|
1261
|
+
// Urate [Mass/volume] in Serum or Plasma
|
|
1262
|
+
],
|
|
1263
|
+
LDH: [
|
|
1264
|
+
"2532-0",
|
|
1265
|
+
// Lactate dehydrogenase [Enzymatic activity/volume] in Serum or Plasma
|
|
1266
|
+
"14804-9"
|
|
1267
|
+
// Lactate dehydrogenase [Enzymatic activity/volume] in Serum or Plasma by Lactate to pyruvate reaction
|
|
1268
|
+
],
|
|
1269
|
+
Amylase: [
|
|
1270
|
+
"1798-8"
|
|
1271
|
+
// Amylase [Enzymatic activity/volume] in Serum or Plasma
|
|
1272
|
+
],
|
|
1273
|
+
Lipase: [
|
|
1274
|
+
"3040-3"
|
|
1275
|
+
// Lipase [Enzymatic activity/volume] in Serum or Plasma
|
|
1276
|
+
],
|
|
1277
|
+
hCG: [
|
|
1278
|
+
"21198-7",
|
|
1279
|
+
// Choriogonadotropin.beta subunit [Units/volume] in Serum or Plasma
|
|
1280
|
+
"2118-8",
|
|
1281
|
+
// Choriogonadotropin (pregnancy test) [Presence] in Serum or Plasma
|
|
1282
|
+
"2106-3"
|
|
1283
|
+
// Choriogonadotropin (pregnancy test) [Presence] in Urine
|
|
1284
|
+
],
|
|
1285
|
+
// URINALYSIS
|
|
1286
|
+
Urinalysis: [
|
|
1287
|
+
"24357-6",
|
|
1288
|
+
// Urinalysis macro (dipstick) panel - Urine
|
|
1289
|
+
"24356-8"
|
|
1290
|
+
// Urinalysis complete panel - Urine
|
|
1291
|
+
]
|
|
1292
|
+
};
|
|
972
1293
|
|
|
973
1294
|
// src/narratives/templates/typescript/PatientTemplate.ts
|
|
974
1295
|
var PatientTemplate = class _PatientTemplate {
|
|
@@ -1887,8 +2208,8 @@ var ProblemListTemplate = class _ProblemListTemplate {
|
|
|
1887
2208
|
let html = ``;
|
|
1888
2209
|
const activeConditions = resources.map((entry) => entry) || [];
|
|
1889
2210
|
activeConditions.sort((a, b) => {
|
|
1890
|
-
const dateA = a.
|
|
1891
|
-
const dateB = b.
|
|
2211
|
+
const dateA = a.recordedDate ? new Date(a.recordedDate).getTime() : 0;
|
|
2212
|
+
const dateB = b.recordedDate ? new Date(b.recordedDate).getTime() : 0;
|
|
1892
2213
|
return dateB - dateA;
|
|
1893
2214
|
});
|
|
1894
2215
|
html += `
|
|
@@ -1901,12 +2222,17 @@ var ProblemListTemplate = class _ProblemListTemplate {
|
|
|
1901
2222
|
</tr>
|
|
1902
2223
|
</thead>
|
|
1903
2224
|
<tbody>`;
|
|
2225
|
+
const addedConditionCodes = /* @__PURE__ */ new Set();
|
|
1904
2226
|
for (const cond of activeConditions) {
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
2227
|
+
const conditionCode = templateUtilities.codeableConcept(cond.code);
|
|
2228
|
+
if (!addedConditionCodes.has(conditionCode)) {
|
|
2229
|
+
addedConditionCodes.add(conditionCode);
|
|
2230
|
+
html += `<tr id="${templateUtilities.narrativeLinkId(cond)}">
|
|
2231
|
+
<td class="Name">${conditionCode}</td>
|
|
2232
|
+
<td class="OnsetDate">${templateUtilities.renderDate(cond.onsetDateTime)}</td>
|
|
2233
|
+
<td class="RecordedDate">${templateUtilities.renderDate(cond.recordedDate)}</td>
|
|
2234
|
+
</tr>`;
|
|
2235
|
+
}
|
|
1910
2236
|
}
|
|
1911
2237
|
html += `</tbody>
|
|
1912
2238
|
</table>`;
|
|
@@ -2088,6 +2414,12 @@ var MedicalDevicesTemplate = class _MedicalDevicesTemplate {
|
|
|
2088
2414
|
};
|
|
2089
2415
|
|
|
2090
2416
|
// src/narratives/templates/typescript/DiagnosticResultsTemplate.ts
|
|
2417
|
+
var loincToLabName = {};
|
|
2418
|
+
for (const [labName, loincCodes] of Object.entries(LAB_LOINC_MAP)) {
|
|
2419
|
+
for (const code of loincCodes) {
|
|
2420
|
+
loincToLabName[code] = labName;
|
|
2421
|
+
}
|
|
2422
|
+
}
|
|
2091
2423
|
var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
2092
2424
|
/**
|
|
2093
2425
|
* Generate HTML narrative for Diagnostic Results
|
|
@@ -2390,8 +2722,8 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2390
2722
|
</tr>
|
|
2391
2723
|
</thead>
|
|
2392
2724
|
<tbody>`;
|
|
2393
|
-
|
|
2394
|
-
|
|
2725
|
+
const observationAdded = /* @__PURE__ */ new Set();
|
|
2726
|
+
const diagnosticReportAdded = /* @__PURE__ */ new Set();
|
|
2395
2727
|
for (const resourceItem of resources) {
|
|
2396
2728
|
for (const rowData of resourceItem.section ?? []) {
|
|
2397
2729
|
const data = {};
|
|
@@ -2431,7 +2763,6 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2431
2763
|
}
|
|
2432
2764
|
}
|
|
2433
2765
|
if (resourceItem.title === "Observation|Labs Summary Grouped by Lab Code") {
|
|
2434
|
-
observationExists = true;
|
|
2435
2766
|
let date = data["effectiveDateTime"] ? templateUtilities.renderTime(data["effectiveDateTime"], timezone) : "";
|
|
2436
2767
|
if (!date && data["effectivePeriodStart"]) {
|
|
2437
2768
|
date = templateUtilities.renderTime(data["effectivePeriodStart"], timezone);
|
|
@@ -2440,48 +2771,59 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2440
2771
|
}
|
|
2441
2772
|
}
|
|
2442
2773
|
if (components.length > 0) {
|
|
2443
|
-
const groupName = data["code"]
|
|
2774
|
+
const groupName = data["code"] ? `${data["code"]} - ` : "";
|
|
2444
2775
|
for (const component of components) {
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
<
|
|
2451
|
-
|
|
2452
|
-
|
|
2776
|
+
const componentCode = `${groupName}${component["code"] ?? ""}`;
|
|
2777
|
+
if (componentCode && !observationAdded.has(componentCode)) {
|
|
2778
|
+
observationAdded.add(componentCode);
|
|
2779
|
+
this.formatSummaryObservationData(component);
|
|
2780
|
+
observationhtml += `
|
|
2781
|
+
<tr>
|
|
2782
|
+
<td>${componentCode}</td>
|
|
2783
|
+
<td>${component["formattedValue"] ?? "-"}</td>
|
|
2784
|
+
<td>${component["referenceRange"]?.trim() ?? "-"}</td>
|
|
2785
|
+
<td>${date ?? "-"}</td>
|
|
2786
|
+
</tr>`;
|
|
2787
|
+
}
|
|
2453
2788
|
}
|
|
2454
2789
|
} else {
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
<
|
|
2461
|
-
|
|
2462
|
-
|
|
2790
|
+
const code = data["code"] ?? "";
|
|
2791
|
+
if (code && !observationAdded.has(code)) {
|
|
2792
|
+
observationAdded.add(code);
|
|
2793
|
+
this.formatSummaryObservationData(data);
|
|
2794
|
+
observationhtml += `
|
|
2795
|
+
<tr>
|
|
2796
|
+
<td>${data["code"] ?? "-"}</td>
|
|
2797
|
+
<td>${data["formattedValue"] ?? "-"}</td>
|
|
2798
|
+
<td>${data["referenceRange"]?.trim() ?? "-"}</td>
|
|
2799
|
+
<td>${date ?? "-"}</td>
|
|
2800
|
+
</tr>`;
|
|
2801
|
+
}
|
|
2463
2802
|
}
|
|
2464
2803
|
} else if (resourceItem.title === "DiagnosticReportLab Summary Grouped by DiagnosticReport|Lab Code") {
|
|
2465
2804
|
if (data["status"] === "final") {
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
<
|
|
2471
|
-
|
|
2472
|
-
|
|
2805
|
+
const reportName = data["report"] ?? "";
|
|
2806
|
+
if (reportName && !diagnosticReportAdded.has(reportName)) {
|
|
2807
|
+
diagnosticReportAdded.add(reportName);
|
|
2808
|
+
diagnosticReporthtml += `
|
|
2809
|
+
<tr>
|
|
2810
|
+
<td>${data["report"] ?? "-"}</td>
|
|
2811
|
+
<td>${data["performer"] ?? "-"}</td>
|
|
2812
|
+
<td>${templateUtilities.renderTime(data["issued"], timezone) ?? "-"}</td>
|
|
2813
|
+
</tr>`;
|
|
2814
|
+
}
|
|
2473
2815
|
}
|
|
2474
2816
|
}
|
|
2475
2817
|
}
|
|
2476
2818
|
}
|
|
2477
|
-
if (
|
|
2819
|
+
if (observationAdded.size > 0) {
|
|
2478
2820
|
html += observationhtml;
|
|
2479
2821
|
html += `
|
|
2480
2822
|
</tbody>
|
|
2481
2823
|
</table>
|
|
2482
2824
|
</div>`;
|
|
2483
2825
|
}
|
|
2484
|
-
if (
|
|
2826
|
+
if (diagnosticReportAdded.size > 0) {
|
|
2485
2827
|
html += diagnosticReporthtml;
|
|
2486
2828
|
html += `
|
|
2487
2829
|
</tbody>
|
|
@@ -2490,7 +2832,7 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2490
2832
|
}
|
|
2491
2833
|
html += `
|
|
2492
2834
|
</div>`;
|
|
2493
|
-
return
|
|
2835
|
+
return observationAdded.size > 0 || diagnosticReportAdded.size > 0 ? html : void 0;
|
|
2494
2836
|
}
|
|
2495
2837
|
/**
|
|
2496
2838
|
* Internal static implementation that actually generates the narrative
|
|
@@ -2504,30 +2846,80 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2504
2846
|
const observations = this.getObservations(resources);
|
|
2505
2847
|
if (observations.length > 0) {
|
|
2506
2848
|
observations.sort((a, b) => {
|
|
2507
|
-
const dateA =
|
|
2508
|
-
const dateB =
|
|
2509
|
-
return dateA && dateB ?
|
|
2849
|
+
const dateA = this.getObservationDate(a);
|
|
2850
|
+
const dateB = this.getObservationDate(b);
|
|
2851
|
+
return dateA && dateB ? dateB.getTime() - dateA.getTime() : 0;
|
|
2510
2852
|
});
|
|
2853
|
+
this.filterObservationForLoincCodes(observations);
|
|
2511
2854
|
html += this.renderObservations(templateUtilities, observations, timezone);
|
|
2512
2855
|
}
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
diagnosticReports.
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2856
|
+
if (process.env.ENABLE_DIAGNOSTIC_REPORTS_IN_SUMMARY === "true") {
|
|
2857
|
+
const diagnosticReports = this.getDiagnosticReports(resources);
|
|
2858
|
+
if (diagnosticReports.length > 0) {
|
|
2859
|
+
diagnosticReports.sort((a, b) => {
|
|
2860
|
+
const dateA = a.issued;
|
|
2861
|
+
const dateB = b.issued;
|
|
2862
|
+
return dateA && dateB ? new Date(dateB).getTime() - new Date(dateA).getTime() : 0;
|
|
2863
|
+
});
|
|
2864
|
+
html += this.renderDiagnosticReports(templateUtilities, diagnosticReports, timezone);
|
|
2865
|
+
}
|
|
2521
2866
|
}
|
|
2522
2867
|
return html;
|
|
2523
2868
|
}
|
|
2869
|
+
static filterObservationForLoincCodes(observations) {
|
|
2870
|
+
const labsAdded = /* @__PURE__ */ new Set();
|
|
2871
|
+
const filteredObservations = [];
|
|
2872
|
+
for (const obs of observations) {
|
|
2873
|
+
const loincCode = this.getObservationLoincCode(obs);
|
|
2874
|
+
if (loincCode && loincToLabName[loincCode]) {
|
|
2875
|
+
const labName = loincToLabName[loincCode];
|
|
2876
|
+
if (!labsAdded.has(labName)) {
|
|
2877
|
+
labsAdded.add(labName);
|
|
2878
|
+
filteredObservations.push(obs);
|
|
2879
|
+
}
|
|
2880
|
+
}
|
|
2881
|
+
}
|
|
2882
|
+
observations.length = 0;
|
|
2883
|
+
observations.push(...filteredObservations);
|
|
2884
|
+
}
|
|
2885
|
+
static getObservationLoincCode(obs) {
|
|
2886
|
+
if (obs.code && obs.code.coding) {
|
|
2887
|
+
for (const coding of obs.code.coding) {
|
|
2888
|
+
if (coding.system && coding.system.toLowerCase().includes("loinc") && coding.code) {
|
|
2889
|
+
return coding.code;
|
|
2890
|
+
}
|
|
2891
|
+
}
|
|
2892
|
+
}
|
|
2893
|
+
return void 0;
|
|
2894
|
+
}
|
|
2895
|
+
static getObservationDate(obs) {
|
|
2896
|
+
let obsDate = void 0;
|
|
2897
|
+
if (obs.effectiveDateTime) {
|
|
2898
|
+
obsDate = new Date(obs.effectiveDateTime);
|
|
2899
|
+
} else if (obs.effectivePeriod) {
|
|
2900
|
+
if (obs.effectivePeriod.start) {
|
|
2901
|
+
obsDate = new Date(obs.effectivePeriod.start);
|
|
2902
|
+
} else if (obs.effectivePeriod.end) {
|
|
2903
|
+
obsDate = new Date(obs.effectivePeriod.end);
|
|
2904
|
+
}
|
|
2905
|
+
}
|
|
2906
|
+
return obsDate;
|
|
2907
|
+
}
|
|
2524
2908
|
/**
|
|
2525
2909
|
* Get all Observation resources from the resource array
|
|
2526
2910
|
* @param resources - FHIR resources array
|
|
2527
2911
|
* @returns Array of Observation resources
|
|
2528
2912
|
*/
|
|
2529
2913
|
static getObservations(resources) {
|
|
2530
|
-
return resources.filter((resourceItem) =>
|
|
2914
|
+
return resources.filter((resourceItem) => {
|
|
2915
|
+
if (resourceItem.resourceType === "Observation") {
|
|
2916
|
+
const obsDate = this.getObservationDate(resourceItem);
|
|
2917
|
+
if (obsDate && obsDate >= new Date(Date.now() - RESULT_SUMMARY_OBSERVATION_DATE_FILTER)) {
|
|
2918
|
+
return true;
|
|
2919
|
+
}
|
|
2920
|
+
}
|
|
2921
|
+
return false;
|
|
2922
|
+
}).map((resourceItem) => resourceItem);
|
|
2531
2923
|
}
|
|
2532
2924
|
/**
|
|
2533
2925
|
* Get all DiagnosticReport resources from the resource array
|
|
@@ -2545,32 +2937,35 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2545
2937
|
* @returns HTML string for rendering
|
|
2546
2938
|
*/
|
|
2547
2939
|
static renderObservations(templateUtilities, observations, timezone) {
|
|
2548
|
-
let html =
|
|
2549
|
-
|
|
2940
|
+
let html = "";
|
|
2941
|
+
if (process.env.ENABLE_DIAGNOSTIC_REPORTS_IN_SUMMARY === "true") {
|
|
2942
|
+
html += `
|
|
2943
|
+
<h3>Observations</h3>`;
|
|
2944
|
+
}
|
|
2945
|
+
html += `
|
|
2550
2946
|
<table>
|
|
2551
2947
|
<thead>
|
|
2552
2948
|
<tr>
|
|
2553
2949
|
<th>Code</th>
|
|
2554
2950
|
<th>Result</th>
|
|
2555
|
-
<th>Unit</th>
|
|
2556
|
-
<th>Interpretation</th>
|
|
2557
2951
|
<th>Reference Range</th>
|
|
2558
|
-
<th>Comments</th>
|
|
2559
2952
|
<th>Date</th>
|
|
2560
2953
|
</tr>
|
|
2561
2954
|
</thead>
|
|
2562
2955
|
<tbody>`;
|
|
2956
|
+
const observationAdded = /* @__PURE__ */ new Set();
|
|
2563
2957
|
for (const obs of observations) {
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
<
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2958
|
+
const obsCode = templateUtilities.codeableConcept(obs.code);
|
|
2959
|
+
if (!observationAdded.has(obsCode)) {
|
|
2960
|
+
observationAdded.add(obsCode);
|
|
2961
|
+
html += `
|
|
2962
|
+
<tr id="${templateUtilities.narrativeLinkId(obs)}">
|
|
2963
|
+
<td>${obsCode}</td>
|
|
2964
|
+
<td>${templateUtilities.extractObservationValue(obs)}</td>
|
|
2965
|
+
<td>${templateUtilities.concatReferenceRange(obs.referenceRange)}</td>
|
|
2966
|
+
<td>${obs.effectiveDateTime ? templateUtilities.renderTime(obs.effectiveDateTime, timezone) : obs.effectivePeriod ? templateUtilities.renderPeriod(obs.effectivePeriod, timezone) : ""}</td>
|
|
2967
|
+
</tr>`;
|
|
2968
|
+
}
|
|
2574
2969
|
}
|
|
2575
2970
|
html += `
|
|
2576
2971
|
</tbody>
|
|
@@ -2597,18 +2992,23 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2597
2992
|
</tr>
|
|
2598
2993
|
</thead>
|
|
2599
2994
|
<tbody>`;
|
|
2995
|
+
const diagnosticReportAdded = /* @__PURE__ */ new Set();
|
|
2600
2996
|
for (const report of reports) {
|
|
2601
|
-
|
|
2602
|
-
if (
|
|
2603
|
-
|
|
2997
|
+
const reportName = templateUtilities.codeableConcept(report.code);
|
|
2998
|
+
if (!diagnosticReportAdded.has(reportName)) {
|
|
2999
|
+
diagnosticReportAdded.add(reportName);
|
|
3000
|
+
let resultCount = "";
|
|
3001
|
+
if (report.result && Array.isArray(report.result)) {
|
|
3002
|
+
resultCount = `${report.result.length} result${report.result.length !== 1 ? "s" : ""}`;
|
|
3003
|
+
}
|
|
3004
|
+
html += `
|
|
3005
|
+
<tr id="${templateUtilities.narrativeLinkId(report)}">
|
|
3006
|
+
<td>${reportName}</td>
|
|
3007
|
+
<td>${templateUtilities.firstFromCodeableConceptList(report.category)}</td>
|
|
3008
|
+
<td>${resultCount}</td>
|
|
3009
|
+
<td>${report.issued ? templateUtilities.renderTime(report.issued, timezone) : ""}</td>
|
|
3010
|
+
</tr>`;
|
|
2604
3011
|
}
|
|
2605
|
-
html += `
|
|
2606
|
-
<tr id="${templateUtilities.narrativeLinkId(report)}">
|
|
2607
|
-
<td>${templateUtilities.codeableConcept(report.code)}</td>
|
|
2608
|
-
<td>${templateUtilities.firstFromCodeableConceptList(report.category)}</td>
|
|
2609
|
-
<td>${resultCount}</td>
|
|
2610
|
-
<td>${report.issued ? templateUtilities.renderTime(report.issued, timezone) : ""}</td>
|
|
2611
|
-
</tr>`;
|
|
2612
3012
|
}
|
|
2613
3013
|
html += `
|
|
2614
3014
|
</tbody>
|
|
@@ -2788,8 +3188,8 @@ var PastHistoryOfIllnessTemplate = class {
|
|
|
2788
3188
|
let html = ``;
|
|
2789
3189
|
const resolvedConditions = resources.map((entry) => entry) || [];
|
|
2790
3190
|
resolvedConditions.sort((a, b) => {
|
|
2791
|
-
const dateA = a.
|
|
2792
|
-
const dateB = b.
|
|
3191
|
+
const dateA = a.recordedDate ? new Date(a.recordedDate).getTime() : 0;
|
|
3192
|
+
const dateB = b.recordedDate ? new Date(b.recordedDate).getTime() : 0;
|
|
2793
3193
|
return dateB - dateA;
|
|
2794
3194
|
});
|
|
2795
3195
|
html += `
|
|
@@ -2803,13 +3203,18 @@ var PastHistoryOfIllnessTemplate = class {
|
|
|
2803
3203
|
</tr>
|
|
2804
3204
|
</thead>
|
|
2805
3205
|
<tbody>`;
|
|
3206
|
+
const addedConditionCodes = /* @__PURE__ */ new Set();
|
|
2806
3207
|
for (const cond of resolvedConditions) {
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
3208
|
+
const conditionCode = templateUtilities.codeableConcept(cond.code);
|
|
3209
|
+
if (!addedConditionCodes.has(conditionCode)) {
|
|
3210
|
+
addedConditionCodes.add(conditionCode);
|
|
3211
|
+
html += `<tr id="${templateUtilities.narrativeLinkId(cond)}">
|
|
3212
|
+
<td class="Name">${conditionCode}</td>
|
|
3213
|
+
<td class="OnsetDate">${templateUtilities.renderDate(cond.onsetDateTime)}</td>
|
|
3214
|
+
<td class="RecordedDate">${templateUtilities.renderDate(cond.recordedDate)}</td>
|
|
3215
|
+
<td class="ResolvedDate">${templateUtilities.renderDate(cond.abatementDateTime)}</td>
|
|
3216
|
+
</tr>`;
|
|
3217
|
+
}
|
|
2813
3218
|
}
|
|
2814
3219
|
html += `</tbody>
|
|
2815
3220
|
</table>`;
|
|
@@ -2934,20 +3339,14 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
|
|
|
2934
3339
|
const clinicalImpressions = [];
|
|
2935
3340
|
for (const resourceItem of resources) {
|
|
2936
3341
|
if (resourceItem.resourceType === "Condition") {
|
|
2937
|
-
|
|
2938
|
-
const isResolved = cond.clinicalStatus?.coding?.some(
|
|
2939
|
-
(c) => c.code === "resolved" || c.code === "inactive" || c.display?.toLowerCase().includes("resolved")
|
|
2940
|
-
);
|
|
2941
|
-
if (!isResolved) {
|
|
2942
|
-
activeConditions.push(cond);
|
|
2943
|
-
}
|
|
3342
|
+
activeConditions.push(resourceItem);
|
|
2944
3343
|
} else if (resourceItem.resourceType === "ClinicalImpression") {
|
|
2945
3344
|
clinicalImpressions.push(resourceItem);
|
|
2946
3345
|
}
|
|
2947
3346
|
}
|
|
2948
3347
|
activeConditions.sort((a, b) => {
|
|
2949
|
-
const dateA = a.
|
|
2950
|
-
const dateB = b.
|
|
3348
|
+
const dateA = a.recordedDate ? new Date(a.recordedDate).getTime() : 0;
|
|
3349
|
+
const dateB = b.recordedDate ? new Date(b.recordedDate).getTime() : 0;
|
|
2951
3350
|
return dateB - dateA;
|
|
2952
3351
|
});
|
|
2953
3352
|
clinicalImpressions.sort((a, b) => {
|
|
@@ -2966,12 +3365,17 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
|
|
|
2966
3365
|
</tr>
|
|
2967
3366
|
</thead>
|
|
2968
3367
|
<tbody>`;
|
|
3368
|
+
const addedConditionCodes = /* @__PURE__ */ new Set();
|
|
2969
3369
|
for (const cond of activeConditions) {
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
3370
|
+
const conditionCode = templateUtilities.codeableConcept(cond.code);
|
|
3371
|
+
if (!addedConditionCodes.has(conditionCode)) {
|
|
3372
|
+
addedConditionCodes.add(conditionCode);
|
|
3373
|
+
html += `<tr id="${templateUtilities.narrativeLinkId(cond)}">
|
|
3374
|
+
<td class="Name">${conditionCode}</td>
|
|
3375
|
+
<td class="OnsetDate">${templateUtilities.renderDate(cond.onsetDateTime)}</td>
|
|
3376
|
+
<td class="RecordedDate">${templateUtilities.renderDate(cond.recordedDate)}</td>
|
|
3377
|
+
</tr>`;
|
|
3378
|
+
}
|
|
2975
3379
|
}
|
|
2976
3380
|
html += `</tbody>
|
|
2977
3381
|
</table>`;
|