@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.js
CHANGED
|
@@ -87,6 +87,8 @@ var VITAL_SIGNS_SUMMARY_COMPONENT_MAP = {
|
|
|
87
87
|
"Diastolic Blood Pressure": "valueRatio.denominator.value",
|
|
88
88
|
"Default": "valueString"
|
|
89
89
|
};
|
|
90
|
+
var RESULT_SUMMARY_OBSERVATION_CATEGORIES = ["laboratory", "Lab", "LAB"];
|
|
91
|
+
var RESULT_SUMMARY_OBSERVATION_DATE_FILTER = 2 * 365 * 24 * 60 * 60 * 1e3;
|
|
90
92
|
var IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM = "https://fhir.icanbwell.com/4_0_0/CodeSystem/composition/";
|
|
91
93
|
|
|
92
94
|
// src/structures/ips_section_resource_map.ts
|
|
@@ -106,7 +108,7 @@ var IPSSectionResourceFilters = {
|
|
|
106
108
|
// Includes DeviceUseStatement. Device is needed for linked device details
|
|
107
109
|
["MedicalDeviceSection" /* MEDICAL_DEVICES */]: (resource) => ["DeviceUseStatement", "Device"].includes(resource.resourceType),
|
|
108
110
|
// Only include finalized diagnostic reports
|
|
109
|
-
["ResultsSection" /* DIAGNOSTIC_REPORTS */]: (resource) =>
|
|
111
|
+
["ResultsSection" /* DIAGNOSTIC_REPORTS */]: (resource) => resource.resourceType === "Observation" && resource.category?.some((cat) => cat.coding?.some((c) => RESULT_SUMMARY_OBSERVATION_CATEGORIES.includes(c.code))),
|
|
110
112
|
// Only include completed procedures
|
|
111
113
|
["HistoryOfProceduresSection" /* PROCEDURES */]: (resource) => resource.resourceType === "Procedure" && resource.status === "completed",
|
|
112
114
|
// Only include social history Observations
|
|
@@ -114,7 +116,7 @@ var IPSSectionResourceFilters = {
|
|
|
114
116
|
// Only include pregnancy history Observations
|
|
115
117
|
["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
118
|
// Only include Conditions or completed ClinicalImpressions
|
|
117
|
-
["FunctionalStatusSection" /* FUNCTIONAL_STATUS */]: (resource) => resource.resourceType === "Condition" || resource.resourceType === "ClinicalImpression" && resource.status === "completed",
|
|
119
|
+
["FunctionalStatusSection" /* FUNCTIONAL_STATUS */]: (resource) => resource.resourceType === "Condition" && resource.clinicalStatus?.coding?.some((c) => !["inactive", "resolved"].includes(c.code)) || resource.resourceType === "ClinicalImpression" && resource.status === "completed",
|
|
118
120
|
// Only include resolved medical history Conditions
|
|
119
121
|
["HistoryOfPastIllnessSection" /* MEDICAL_HISTORY */]: (resource) => resource.resourceType === "Condition" && resource.clinicalStatus?.coding?.some((c) => ["inactive", "resolved"].includes(c.code)),
|
|
120
122
|
// Only include active care plans
|
|
@@ -128,7 +130,7 @@ var IPSSectionSummaryCompositionFilter = {
|
|
|
128
130
|
["PlanOfCareSection" /* CARE_PLAN */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => c.system === IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM && c.code === "careplan_summary_document"),
|
|
129
131
|
["ImmunizationSection" /* IMMUNIZATIONS */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => c.system === IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM && c.code === "immunization_summary_document"),
|
|
130
132
|
["MedicationSummarySection" /* MEDICATIONS */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => c.system === IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM && c.code === "medication_summary_document"),
|
|
131
|
-
[
|
|
133
|
+
// [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)),
|
|
132
134
|
["HistoryOfProceduresSection" /* PROCEDURES */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => c.system === IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM && c.code === "procedure_summary_document")
|
|
133
135
|
};
|
|
134
136
|
var IPSSectionResourceHelper = class {
|
|
@@ -592,9 +594,18 @@ var TemplateUtilities = class {
|
|
|
592
594
|
}
|
|
593
595
|
return status;
|
|
594
596
|
}
|
|
597
|
+
formatFloatValue(value) {
|
|
598
|
+
if (typeof value === "number") {
|
|
599
|
+
return value.toFixed(2).replace(/\.?0+$/, "");
|
|
600
|
+
} else if (typeof value === "string" && !isNaN(Number(value))) {
|
|
601
|
+
return parseFloat(value).toFixed(2).replace(/\.?0+$/, "");
|
|
602
|
+
}
|
|
603
|
+
return value;
|
|
604
|
+
}
|
|
595
605
|
extractObservationSummaryValue(data, timezone) {
|
|
596
606
|
if (data["valueQuantity.value"] !== void 0) {
|
|
597
|
-
|
|
607
|
+
let value = data["valueQuantity.value"];
|
|
608
|
+
value = this.formatFloatValue(value);
|
|
598
609
|
const unit = data["valueQuantity.unit"];
|
|
599
610
|
return unit ? `${value} ${unit}` : `${value}`;
|
|
600
611
|
}
|
|
@@ -611,7 +622,9 @@ var TemplateUtilities = class {
|
|
|
611
622
|
return String(data["valueBoolean"]);
|
|
612
623
|
}
|
|
613
624
|
if (data["valueInteger"] !== void 0) {
|
|
614
|
-
|
|
625
|
+
let value = String(data["valueInteger"]);
|
|
626
|
+
value = this.formatFloatValue(value);
|
|
627
|
+
return value;
|
|
615
628
|
}
|
|
616
629
|
if (data["valueDateTime"] !== void 0) {
|
|
617
630
|
return this.renderTime(data["valueDateTime"], timezone);
|
|
@@ -631,7 +644,8 @@ var TemplateUtilities = class {
|
|
|
631
644
|
return this.renderTime(data["valueTime"], timezone);
|
|
632
645
|
}
|
|
633
646
|
if (data["valueSampledData.origin.value"] !== void 0 || data["valueSampledData.origin.unit"] !== void 0) {
|
|
634
|
-
|
|
647
|
+
let originValue = data["valueSampledData.origin.value"];
|
|
648
|
+
originValue = this.formatFloatValue(originValue);
|
|
635
649
|
const originUnit = data["valueSampledData.origin.unit"];
|
|
636
650
|
let result = "";
|
|
637
651
|
if (originValue !== void 0 && originUnit !== void 0) {
|
|
@@ -641,10 +655,10 @@ var TemplateUtilities = class {
|
|
|
641
655
|
} else if (originUnit !== void 0) {
|
|
642
656
|
result = `${originUnit}`;
|
|
643
657
|
}
|
|
644
|
-
const period = data["valueSampledData.period"];
|
|
645
|
-
const factor = data["valueSampledData.factor"];
|
|
646
|
-
const lowerLimit = data["valueSampledData.lowerLimit"];
|
|
647
|
-
const upperLimit = data["valueSampledData.upperLimit"];
|
|
658
|
+
const period = this.formatFloatValue(data["valueSampledData.period"]);
|
|
659
|
+
const factor = this.formatFloatValue(data["valueSampledData.factor"]);
|
|
660
|
+
const lowerLimit = this.formatFloatValue(data["valueSampledData.lowerLimit"]);
|
|
661
|
+
const upperLimit = this.formatFloatValue(data["valueSampledData.upperLimit"]);
|
|
648
662
|
const sampledData = data["valueSampledData.data"];
|
|
649
663
|
const extras = [];
|
|
650
664
|
if (period !== void 0) extras.push(`period: ${period}`);
|
|
@@ -680,14 +694,14 @@ var TemplateUtilities = class {
|
|
|
680
694
|
if (data["valueRatio.numerator.value"] !== void 0 || data["valueRatio.denominator.value"] !== void 0) {
|
|
681
695
|
let ratio = "";
|
|
682
696
|
if (data["valueRatio.numerator.value"] !== void 0) {
|
|
683
|
-
ratio += `${data["valueRatio.numerator.value"]}`;
|
|
697
|
+
ratio += `${this.formatFloatValue(data["valueRatio.numerator.value"])}`;
|
|
684
698
|
if (data["valueRatio.numerator.unit"] !== void 0) {
|
|
685
699
|
ratio += ` ${data["valueRatio.numerator.unit"]}`;
|
|
686
700
|
}
|
|
687
701
|
}
|
|
688
702
|
if (data["valueRatio.denominator.value"] !== void 0) {
|
|
689
703
|
ratio += " / ";
|
|
690
|
-
ratio += `${data["valueRatio.denominator.value"]}`;
|
|
704
|
+
ratio += `${this.formatFloatValue(data["valueRatio.denominator.value"])}`;
|
|
691
705
|
if (data["valueRatio.denominator.unit"] !== void 0) {
|
|
692
706
|
ratio += ` ${data["valueRatio.denominator.unit"]}`;
|
|
693
707
|
}
|
|
@@ -941,6 +955,313 @@ var TemplateUtilities = class {
|
|
|
941
955
|
|
|
942
956
|
// src/constants.ts
|
|
943
957
|
var ADDRESS_SIMILARITY_THRESHOLD = 70;
|
|
958
|
+
var LAB_LOINC_MAP = {
|
|
959
|
+
// METABOLIC PANELS (VERY COMMONLY ORDERED)
|
|
960
|
+
"Basic Metabolic Panel": [
|
|
961
|
+
"24321-2",
|
|
962
|
+
// Basic metabolic 2000 panel - Serum or Plasma
|
|
963
|
+
"51990-0"
|
|
964
|
+
// Basic metabolic 2000 panel - Blood
|
|
965
|
+
],
|
|
966
|
+
"Comprehensive Metabolic Panel": [
|
|
967
|
+
"24323-8"
|
|
968
|
+
// Comprehensive metabolic 2000 panel - Serum or Plasma
|
|
969
|
+
],
|
|
970
|
+
// CBC COMPONENTS
|
|
971
|
+
Hemoglobin: [
|
|
972
|
+
"718-7"
|
|
973
|
+
// Hemoglobin [Mass/volume] in Blood
|
|
974
|
+
],
|
|
975
|
+
Hematocrit: [
|
|
976
|
+
"4544-3"
|
|
977
|
+
// Hematocrit [Volume Fraction] of Blood by Automated count
|
|
978
|
+
],
|
|
979
|
+
"White Blood Cell Count": [
|
|
980
|
+
"6690-2"
|
|
981
|
+
// Leukocytes [///volume] in Blood by Automated count
|
|
982
|
+
],
|
|
983
|
+
"Platelet Count": [
|
|
984
|
+
"777-3"
|
|
985
|
+
// Platelets [///volume] in Blood by Automated count
|
|
986
|
+
],
|
|
987
|
+
"Complete Blood Count": [
|
|
988
|
+
"58410-2",
|
|
989
|
+
// CBC panel - Blood by Automated count
|
|
990
|
+
"57021-8",
|
|
991
|
+
// CBC W Auto Differential panel - Blood
|
|
992
|
+
"69738-3"
|
|
993
|
+
// CBC W Auto Differential panel - Blood by Automated count
|
|
994
|
+
],
|
|
995
|
+
// CHEMISTRY - GLUCOSE
|
|
996
|
+
Glucose: [
|
|
997
|
+
"2345-7",
|
|
998
|
+
// Glucose [Mass/volume] in Serum or Plasma
|
|
999
|
+
"1558-6",
|
|
1000
|
+
// Fasting glucose [Mass/volume] in Serum or Plasma
|
|
1001
|
+
"2339-0"
|
|
1002
|
+
// Glucose [Mass/volume] in Blood
|
|
1003
|
+
],
|
|
1004
|
+
// RENAL FUNCTION
|
|
1005
|
+
Creatinine: [
|
|
1006
|
+
"2160-0"
|
|
1007
|
+
// Creatinine [Mass/volume] in Serum or Plasma
|
|
1008
|
+
],
|
|
1009
|
+
"Blood Urea Nitrogen": [
|
|
1010
|
+
"3094-0",
|
|
1011
|
+
// Urea nitrogen [Mass/volume] in Serum or Plasma
|
|
1012
|
+
"6299-2"
|
|
1013
|
+
// Urea nitrogen [Mass/volume] in Blood
|
|
1014
|
+
],
|
|
1015
|
+
// ELECTROLYTES
|
|
1016
|
+
Sodium: [
|
|
1017
|
+
"2951-2"
|
|
1018
|
+
// Sodium [Moles/volume] in Serum or Plasma
|
|
1019
|
+
],
|
|
1020
|
+
Potassium: [
|
|
1021
|
+
"2823-3"
|
|
1022
|
+
// Potassium [Moles/volume] in Serum or Plasma
|
|
1023
|
+
],
|
|
1024
|
+
Chloride: [
|
|
1025
|
+
"2075-0"
|
|
1026
|
+
// Chloride [Moles/volume] in Serum or Plasma
|
|
1027
|
+
],
|
|
1028
|
+
Calcium: [
|
|
1029
|
+
"17861-6",
|
|
1030
|
+
// Calcium [Mass/volume] in Serum or Plasma
|
|
1031
|
+
"1994-3"
|
|
1032
|
+
// Calcium.ionized [Moles/volume] in Serum or Plasma
|
|
1033
|
+
],
|
|
1034
|
+
Magnesium: [
|
|
1035
|
+
"19123-9"
|
|
1036
|
+
// Magnesium [Mass/volume] in Serum or Plasma
|
|
1037
|
+
],
|
|
1038
|
+
Phosphate: [
|
|
1039
|
+
"14879-1"
|
|
1040
|
+
// Phosphate [Mass/volume] in Serum or Plasma
|
|
1041
|
+
],
|
|
1042
|
+
// PROTEINS
|
|
1043
|
+
Albumin: [
|
|
1044
|
+
"1751-7"
|
|
1045
|
+
// Albumin [Mass/volume] in Serum or Plasma
|
|
1046
|
+
],
|
|
1047
|
+
"Total Protein": [
|
|
1048
|
+
"2885-2"
|
|
1049
|
+
// Protein [Mass/volume] in Serum or Plasma
|
|
1050
|
+
],
|
|
1051
|
+
// LIVER FUNCTION
|
|
1052
|
+
Bilirubin: [
|
|
1053
|
+
"1975-2",
|
|
1054
|
+
// Bilirubin.total [Mass/volume] in Serum or Plasma
|
|
1055
|
+
"1968-7",
|
|
1056
|
+
// Bilirubin.direct [Mass/volume] in Serum or Plasma
|
|
1057
|
+
"1971-1"
|
|
1058
|
+
// Bilirubin.indirect [Mass/volume] in Serum or Plasma
|
|
1059
|
+
],
|
|
1060
|
+
"Alkaline Phosphatase": [
|
|
1061
|
+
"6768-6"
|
|
1062
|
+
// Alkaline phosphatase [Enzymatic activity/volume] in Serum or Plasma
|
|
1063
|
+
],
|
|
1064
|
+
AST: [
|
|
1065
|
+
"1920-8"
|
|
1066
|
+
// Aspartate aminotransferase [Enzymatic activity/volume] in Serum or Plasma
|
|
1067
|
+
],
|
|
1068
|
+
ALT: [
|
|
1069
|
+
"1742-6"
|
|
1070
|
+
// Alanine aminotransferase [Enzymatic activity/volume] in Serum or Plasma
|
|
1071
|
+
],
|
|
1072
|
+
GGT: [
|
|
1073
|
+
"2324-2"
|
|
1074
|
+
// Gamma glutamyl transferase [Enzymatic activity/volume] in Serum or Plasma
|
|
1075
|
+
],
|
|
1076
|
+
// ENDOCRINE
|
|
1077
|
+
TSH: [
|
|
1078
|
+
"3016-3"
|
|
1079
|
+
// Thyrotropin [Units/volume] in Serum or Plasma
|
|
1080
|
+
],
|
|
1081
|
+
"Free T4": [
|
|
1082
|
+
"3024-7"
|
|
1083
|
+
// Thyroxine (T4) free [Mass/volume] in Serum or Plasma
|
|
1084
|
+
],
|
|
1085
|
+
"Total T4": [
|
|
1086
|
+
"3026-2"
|
|
1087
|
+
// Thyroxine (T4) [Mass/volume] in Serum or Plasma
|
|
1088
|
+
],
|
|
1089
|
+
"Free T3": [
|
|
1090
|
+
"3051-0"
|
|
1091
|
+
// Triiodothyronine (T3) free [Mass/volume] in Serum or Plasma
|
|
1092
|
+
],
|
|
1093
|
+
"Total T3": [
|
|
1094
|
+
"3053-6"
|
|
1095
|
+
// Triiodothyronine (T3) [Mass/volume] in Serum or Plasma
|
|
1096
|
+
],
|
|
1097
|
+
HbA1c: [
|
|
1098
|
+
"4548-4",
|
|
1099
|
+
// Hemoglobin A1c/Hemoglobin.total in Blood
|
|
1100
|
+
"17856-6"
|
|
1101
|
+
// Hemoglobin A1c/Hemoglobin.total in Blood by HPLC
|
|
1102
|
+
],
|
|
1103
|
+
// LIPID PANEL
|
|
1104
|
+
"Lipid Panel": [
|
|
1105
|
+
"24331-1",
|
|
1106
|
+
// Lipid 1996 panel - Serum or Plasma
|
|
1107
|
+
"57698-3"
|
|
1108
|
+
// Lipid panel with direct LDL - Serum or Plasma
|
|
1109
|
+
],
|
|
1110
|
+
"Cholesterol Total": [
|
|
1111
|
+
"2093-3"
|
|
1112
|
+
// Cholesterol [Mass/volume] in Serum or Plasma
|
|
1113
|
+
],
|
|
1114
|
+
"HDL Cholesterol": [
|
|
1115
|
+
"2085-9"
|
|
1116
|
+
// Cholesterol in HDL [Mass/volume] in Serum or Plasma
|
|
1117
|
+
],
|
|
1118
|
+
"LDL Cholesterol": [
|
|
1119
|
+
"13457-7",
|
|
1120
|
+
// Cholesterol in LDL [Mass/volume] in Serum or Plasma by calculation
|
|
1121
|
+
"18262-6"
|
|
1122
|
+
// Cholesterol in LDL [Mass/volume] in Serum or Plasma by Direct assay
|
|
1123
|
+
],
|
|
1124
|
+
Triglycerides: [
|
|
1125
|
+
"2571-8"
|
|
1126
|
+
// Triglyceride [Mass/volume] in Serum or Plasma
|
|
1127
|
+
],
|
|
1128
|
+
// COAGULATION STUDIES (COMMONLY MISSING!)
|
|
1129
|
+
PT: [
|
|
1130
|
+
"5902-2"
|
|
1131
|
+
// Prothrombin time (PT)
|
|
1132
|
+
],
|
|
1133
|
+
INR: [
|
|
1134
|
+
"6301-6"
|
|
1135
|
+
// INR in Platelet poor plasma by Coagulation assay
|
|
1136
|
+
],
|
|
1137
|
+
PTT: [
|
|
1138
|
+
"3173-2",
|
|
1139
|
+
// aPTT in Blood by Coagulation assay
|
|
1140
|
+
"14979-9"
|
|
1141
|
+
// aPTT in Platelet poor plasma by Coagulation assay
|
|
1142
|
+
],
|
|
1143
|
+
Fibrinogen: [
|
|
1144
|
+
"3255-7"
|
|
1145
|
+
// Fibrinogen [Mass/volume] in Platelet poor plasma by Coagulation assay
|
|
1146
|
+
],
|
|
1147
|
+
"D-Dimer": [
|
|
1148
|
+
"48065-7",
|
|
1149
|
+
// D-dimer FEU [Mass/volume] in Platelet poor plasma
|
|
1150
|
+
"48066-5"
|
|
1151
|
+
// D-dimer DDU [Mass/volume] in Platelet poor plasma
|
|
1152
|
+
],
|
|
1153
|
+
// CARDIAC MARKERS (CRITICAL FOR ER!)
|
|
1154
|
+
"Troponin I": [
|
|
1155
|
+
"10839-9",
|
|
1156
|
+
// Troponin I.cardiac [Mass/volume] in Serum or Plasma
|
|
1157
|
+
"42757-5",
|
|
1158
|
+
// Troponin I.cardiac [Mass/volume] in Blood
|
|
1159
|
+
"89579-7"
|
|
1160
|
+
// Troponin I.cardiac [Mass/volume] in Serum or Plasma by High sensitivity method
|
|
1161
|
+
],
|
|
1162
|
+
"Troponin T": [
|
|
1163
|
+
"6598-7",
|
|
1164
|
+
// Troponin T.cardiac [Mass/volume] in Serum or Plasma
|
|
1165
|
+
"48425-3"
|
|
1166
|
+
// Troponin T.cardiac [Mass/volume] in Serum or Plasma by High sensitivity method
|
|
1167
|
+
],
|
|
1168
|
+
BNP: [
|
|
1169
|
+
"30934-4"
|
|
1170
|
+
// BNP [Mass/volume] in Serum or Plasma
|
|
1171
|
+
],
|
|
1172
|
+
"NT-proBNP": [
|
|
1173
|
+
"33762-6"
|
|
1174
|
+
// NT-proBNP [Mass/volume] in Serum or Plasma
|
|
1175
|
+
],
|
|
1176
|
+
"CK-MB": [
|
|
1177
|
+
"13969-1"
|
|
1178
|
+
// Creatine kinase.MB [Mass/volume] in Serum or Plasma
|
|
1179
|
+
],
|
|
1180
|
+
// INFLAMMATORY MARKERS
|
|
1181
|
+
CRP: [
|
|
1182
|
+
"1988-5",
|
|
1183
|
+
// C reactive protein [Mass/volume] in Serum or Plasma
|
|
1184
|
+
"30522-7"
|
|
1185
|
+
// C reactive protein [Mass/volume] in Serum or Plasma by High sensitivity method
|
|
1186
|
+
],
|
|
1187
|
+
ESR: [
|
|
1188
|
+
"30341-2",
|
|
1189
|
+
// Erythrocyte sedimentation rate by Westergren method
|
|
1190
|
+
"4537-7"
|
|
1191
|
+
// Erythrocyte sedimentation rate
|
|
1192
|
+
],
|
|
1193
|
+
// VITAMINS & MINERALS (VERY HIGH VOLUME!)
|
|
1194
|
+
"Vitamin D": [
|
|
1195
|
+
"1990-1",
|
|
1196
|
+
// Vitamin D [Mass/volume] in Serum or Plasma (obsolete, but still used)
|
|
1197
|
+
"14635-7",
|
|
1198
|
+
// 25-Hydroxyvitamin D3 [Mass/volume] in Serum or Plasma
|
|
1199
|
+
"62292-8"
|
|
1200
|
+
// 25-Hydroxyvitamin D2+D3 [Mass/volume] in Serum or Plasma
|
|
1201
|
+
],
|
|
1202
|
+
"Vitamin B12": [
|
|
1203
|
+
"2132-9"
|
|
1204
|
+
// Cobalamin (Vitamin B12) [Mass/volume] in Serum or Plasma
|
|
1205
|
+
],
|
|
1206
|
+
Folate: [
|
|
1207
|
+
"2284-8",
|
|
1208
|
+
// Folate [Mass/volume] in Serum or Plasma
|
|
1209
|
+
"15152-2"
|
|
1210
|
+
// Folate [Mass/volume] in Red Blood Cells
|
|
1211
|
+
],
|
|
1212
|
+
Iron: [
|
|
1213
|
+
"2498-4"
|
|
1214
|
+
// Iron [Mass/volume] in Serum or Plasma
|
|
1215
|
+
],
|
|
1216
|
+
Ferritin: [
|
|
1217
|
+
"2276-4"
|
|
1218
|
+
// Ferritin [Mass/volume] in Serum or Plasma
|
|
1219
|
+
],
|
|
1220
|
+
TIBC: [
|
|
1221
|
+
"2500-7"
|
|
1222
|
+
// Iron binding capacity [Mass/volume] in Serum or Plasma
|
|
1223
|
+
],
|
|
1224
|
+
// OTHER COMMON TESTS
|
|
1225
|
+
PSA: [
|
|
1226
|
+
"2857-1",
|
|
1227
|
+
// Prostate specific Ag [Mass/volume] in Serum or Plasma
|
|
1228
|
+
"10886-0"
|
|
1229
|
+
// Prostate specific Ag Free [Mass/volume] in Serum or Plasma
|
|
1230
|
+
],
|
|
1231
|
+
"Uric Acid": [
|
|
1232
|
+
"3084-1"
|
|
1233
|
+
// Urate [Mass/volume] in Serum or Plasma
|
|
1234
|
+
],
|
|
1235
|
+
LDH: [
|
|
1236
|
+
"2532-0",
|
|
1237
|
+
// Lactate dehydrogenase [Enzymatic activity/volume] in Serum or Plasma
|
|
1238
|
+
"14804-9"
|
|
1239
|
+
// Lactate dehydrogenase [Enzymatic activity/volume] in Serum or Plasma by Lactate to pyruvate reaction
|
|
1240
|
+
],
|
|
1241
|
+
Amylase: [
|
|
1242
|
+
"1798-8"
|
|
1243
|
+
// Amylase [Enzymatic activity/volume] in Serum or Plasma
|
|
1244
|
+
],
|
|
1245
|
+
Lipase: [
|
|
1246
|
+
"3040-3"
|
|
1247
|
+
// Lipase [Enzymatic activity/volume] in Serum or Plasma
|
|
1248
|
+
],
|
|
1249
|
+
hCG: [
|
|
1250
|
+
"21198-7",
|
|
1251
|
+
// Choriogonadotropin.beta subunit [Units/volume] in Serum or Plasma
|
|
1252
|
+
"2118-8",
|
|
1253
|
+
// Choriogonadotropin (pregnancy test) [Presence] in Serum or Plasma
|
|
1254
|
+
"2106-3"
|
|
1255
|
+
// Choriogonadotropin (pregnancy test) [Presence] in Urine
|
|
1256
|
+
],
|
|
1257
|
+
// URINALYSIS
|
|
1258
|
+
Urinalysis: [
|
|
1259
|
+
"24357-6",
|
|
1260
|
+
// Urinalysis macro (dipstick) panel - Urine
|
|
1261
|
+
"24356-8"
|
|
1262
|
+
// Urinalysis complete panel - Urine
|
|
1263
|
+
]
|
|
1264
|
+
};
|
|
944
1265
|
|
|
945
1266
|
// src/narratives/templates/typescript/PatientTemplate.ts
|
|
946
1267
|
var PatientTemplate = class _PatientTemplate {
|
|
@@ -1859,8 +2180,8 @@ var ProblemListTemplate = class _ProblemListTemplate {
|
|
|
1859
2180
|
let html = ``;
|
|
1860
2181
|
const activeConditions = resources.map((entry) => entry) || [];
|
|
1861
2182
|
activeConditions.sort((a, b) => {
|
|
1862
|
-
const dateA = a.
|
|
1863
|
-
const dateB = b.
|
|
2183
|
+
const dateA = a.recordedDate ? new Date(a.recordedDate).getTime() : 0;
|
|
2184
|
+
const dateB = b.recordedDate ? new Date(b.recordedDate).getTime() : 0;
|
|
1864
2185
|
return dateB - dateA;
|
|
1865
2186
|
});
|
|
1866
2187
|
html += `
|
|
@@ -1873,12 +2194,17 @@ var ProblemListTemplate = class _ProblemListTemplate {
|
|
|
1873
2194
|
</tr>
|
|
1874
2195
|
</thead>
|
|
1875
2196
|
<tbody>`;
|
|
2197
|
+
const addedConditionCodes = /* @__PURE__ */ new Set();
|
|
1876
2198
|
for (const cond of activeConditions) {
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
2199
|
+
const conditionCode = templateUtilities.codeableConcept(cond.code);
|
|
2200
|
+
if (!addedConditionCodes.has(conditionCode)) {
|
|
2201
|
+
addedConditionCodes.add(conditionCode);
|
|
2202
|
+
html += `<tr id="${templateUtilities.narrativeLinkId(cond)}">
|
|
2203
|
+
<td class="Name">${conditionCode}</td>
|
|
2204
|
+
<td class="OnsetDate">${templateUtilities.renderDate(cond.onsetDateTime)}</td>
|
|
2205
|
+
<td class="RecordedDate">${templateUtilities.renderDate(cond.recordedDate)}</td>
|
|
2206
|
+
</tr>`;
|
|
2207
|
+
}
|
|
1882
2208
|
}
|
|
1883
2209
|
html += `</tbody>
|
|
1884
2210
|
</table>`;
|
|
@@ -2060,6 +2386,12 @@ var MedicalDevicesTemplate = class _MedicalDevicesTemplate {
|
|
|
2060
2386
|
};
|
|
2061
2387
|
|
|
2062
2388
|
// src/narratives/templates/typescript/DiagnosticResultsTemplate.ts
|
|
2389
|
+
var loincToLabName = {};
|
|
2390
|
+
for (const [labName, loincCodes] of Object.entries(LAB_LOINC_MAP)) {
|
|
2391
|
+
for (const code of loincCodes) {
|
|
2392
|
+
loincToLabName[code] = labName;
|
|
2393
|
+
}
|
|
2394
|
+
}
|
|
2063
2395
|
var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
2064
2396
|
/**
|
|
2065
2397
|
* Generate HTML narrative for Diagnostic Results
|
|
@@ -2362,8 +2694,8 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2362
2694
|
</tr>
|
|
2363
2695
|
</thead>
|
|
2364
2696
|
<tbody>`;
|
|
2365
|
-
|
|
2366
|
-
|
|
2697
|
+
const observationAdded = /* @__PURE__ */ new Set();
|
|
2698
|
+
const diagnosticReportAdded = /* @__PURE__ */ new Set();
|
|
2367
2699
|
for (const resourceItem of resources) {
|
|
2368
2700
|
for (const rowData of resourceItem.section ?? []) {
|
|
2369
2701
|
const data = {};
|
|
@@ -2403,7 +2735,6 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2403
2735
|
}
|
|
2404
2736
|
}
|
|
2405
2737
|
if (resourceItem.title === "Observation|Labs Summary Grouped by Lab Code") {
|
|
2406
|
-
observationExists = true;
|
|
2407
2738
|
let date = data["effectiveDateTime"] ? templateUtilities.renderTime(data["effectiveDateTime"], timezone) : "";
|
|
2408
2739
|
if (!date && data["effectivePeriodStart"]) {
|
|
2409
2740
|
date = templateUtilities.renderTime(data["effectivePeriodStart"], timezone);
|
|
@@ -2412,48 +2743,59 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2412
2743
|
}
|
|
2413
2744
|
}
|
|
2414
2745
|
if (components.length > 0) {
|
|
2415
|
-
const groupName = data["code"]
|
|
2746
|
+
const groupName = data["code"] ? `${data["code"]} - ` : "";
|
|
2416
2747
|
for (const component of components) {
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
<
|
|
2423
|
-
|
|
2424
|
-
|
|
2748
|
+
const componentCode = `${groupName}${component["code"] ?? ""}`;
|
|
2749
|
+
if (componentCode && !observationAdded.has(componentCode)) {
|
|
2750
|
+
observationAdded.add(componentCode);
|
|
2751
|
+
this.formatSummaryObservationData(component);
|
|
2752
|
+
observationhtml += `
|
|
2753
|
+
<tr>
|
|
2754
|
+
<td>${componentCode}</td>
|
|
2755
|
+
<td>${component["formattedValue"] ?? "-"}</td>
|
|
2756
|
+
<td>${component["referenceRange"]?.trim() ?? "-"}</td>
|
|
2757
|
+
<td>${date ?? "-"}</td>
|
|
2758
|
+
</tr>`;
|
|
2759
|
+
}
|
|
2425
2760
|
}
|
|
2426
2761
|
} else {
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
<
|
|
2433
|
-
|
|
2434
|
-
|
|
2762
|
+
const code = data["code"] ?? "";
|
|
2763
|
+
if (code && !observationAdded.has(code)) {
|
|
2764
|
+
observationAdded.add(code);
|
|
2765
|
+
this.formatSummaryObservationData(data);
|
|
2766
|
+
observationhtml += `
|
|
2767
|
+
<tr>
|
|
2768
|
+
<td>${data["code"] ?? "-"}</td>
|
|
2769
|
+
<td>${data["formattedValue"] ?? "-"}</td>
|
|
2770
|
+
<td>${data["referenceRange"]?.trim() ?? "-"}</td>
|
|
2771
|
+
<td>${date ?? "-"}</td>
|
|
2772
|
+
</tr>`;
|
|
2773
|
+
}
|
|
2435
2774
|
}
|
|
2436
2775
|
} else if (resourceItem.title === "DiagnosticReportLab Summary Grouped by DiagnosticReport|Lab Code") {
|
|
2437
2776
|
if (data["status"] === "final") {
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
<
|
|
2443
|
-
|
|
2444
|
-
|
|
2777
|
+
const reportName = data["report"] ?? "";
|
|
2778
|
+
if (reportName && !diagnosticReportAdded.has(reportName)) {
|
|
2779
|
+
diagnosticReportAdded.add(reportName);
|
|
2780
|
+
diagnosticReporthtml += `
|
|
2781
|
+
<tr>
|
|
2782
|
+
<td>${data["report"] ?? "-"}</td>
|
|
2783
|
+
<td>${data["performer"] ?? "-"}</td>
|
|
2784
|
+
<td>${templateUtilities.renderTime(data["issued"], timezone) ?? "-"}</td>
|
|
2785
|
+
</tr>`;
|
|
2786
|
+
}
|
|
2445
2787
|
}
|
|
2446
2788
|
}
|
|
2447
2789
|
}
|
|
2448
2790
|
}
|
|
2449
|
-
if (
|
|
2791
|
+
if (observationAdded.size > 0) {
|
|
2450
2792
|
html += observationhtml;
|
|
2451
2793
|
html += `
|
|
2452
2794
|
</tbody>
|
|
2453
2795
|
</table>
|
|
2454
2796
|
</div>`;
|
|
2455
2797
|
}
|
|
2456
|
-
if (
|
|
2798
|
+
if (diagnosticReportAdded.size > 0) {
|
|
2457
2799
|
html += diagnosticReporthtml;
|
|
2458
2800
|
html += `
|
|
2459
2801
|
</tbody>
|
|
@@ -2462,7 +2804,7 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2462
2804
|
}
|
|
2463
2805
|
html += `
|
|
2464
2806
|
</div>`;
|
|
2465
|
-
return
|
|
2807
|
+
return observationAdded.size > 0 || diagnosticReportAdded.size > 0 ? html : void 0;
|
|
2466
2808
|
}
|
|
2467
2809
|
/**
|
|
2468
2810
|
* Internal static implementation that actually generates the narrative
|
|
@@ -2476,30 +2818,80 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2476
2818
|
const observations = this.getObservations(resources);
|
|
2477
2819
|
if (observations.length > 0) {
|
|
2478
2820
|
observations.sort((a, b) => {
|
|
2479
|
-
const dateA =
|
|
2480
|
-
const dateB =
|
|
2481
|
-
return dateA && dateB ?
|
|
2821
|
+
const dateA = this.getObservationDate(a);
|
|
2822
|
+
const dateB = this.getObservationDate(b);
|
|
2823
|
+
return dateA && dateB ? dateB.getTime() - dateA.getTime() : 0;
|
|
2482
2824
|
});
|
|
2825
|
+
this.filterObservationForLoincCodes(observations);
|
|
2483
2826
|
html += this.renderObservations(templateUtilities, observations, timezone);
|
|
2484
2827
|
}
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
diagnosticReports.
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2828
|
+
if (process.env.ENABLE_DIAGNOSTIC_REPORTS_IN_SUMMARY === "true") {
|
|
2829
|
+
const diagnosticReports = this.getDiagnosticReports(resources);
|
|
2830
|
+
if (diagnosticReports.length > 0) {
|
|
2831
|
+
diagnosticReports.sort((a, b) => {
|
|
2832
|
+
const dateA = a.issued;
|
|
2833
|
+
const dateB = b.issued;
|
|
2834
|
+
return dateA && dateB ? new Date(dateB).getTime() - new Date(dateA).getTime() : 0;
|
|
2835
|
+
});
|
|
2836
|
+
html += this.renderDiagnosticReports(templateUtilities, diagnosticReports, timezone);
|
|
2837
|
+
}
|
|
2493
2838
|
}
|
|
2494
2839
|
return html;
|
|
2495
2840
|
}
|
|
2841
|
+
static filterObservationForLoincCodes(observations) {
|
|
2842
|
+
const labsAdded = /* @__PURE__ */ new Set();
|
|
2843
|
+
const filteredObservations = [];
|
|
2844
|
+
for (const obs of observations) {
|
|
2845
|
+
const loincCode = this.getObservationLoincCode(obs);
|
|
2846
|
+
if (loincCode && loincToLabName[loincCode]) {
|
|
2847
|
+
const labName = loincToLabName[loincCode];
|
|
2848
|
+
if (!labsAdded.has(labName)) {
|
|
2849
|
+
labsAdded.add(labName);
|
|
2850
|
+
filteredObservations.push(obs);
|
|
2851
|
+
}
|
|
2852
|
+
}
|
|
2853
|
+
}
|
|
2854
|
+
observations.length = 0;
|
|
2855
|
+
observations.push(...filteredObservations);
|
|
2856
|
+
}
|
|
2857
|
+
static getObservationLoincCode(obs) {
|
|
2858
|
+
if (obs.code && obs.code.coding) {
|
|
2859
|
+
for (const coding of obs.code.coding) {
|
|
2860
|
+
if (coding.system && coding.system.toLowerCase().includes("loinc") && coding.code) {
|
|
2861
|
+
return coding.code;
|
|
2862
|
+
}
|
|
2863
|
+
}
|
|
2864
|
+
}
|
|
2865
|
+
return void 0;
|
|
2866
|
+
}
|
|
2867
|
+
static getObservationDate(obs) {
|
|
2868
|
+
let obsDate = void 0;
|
|
2869
|
+
if (obs.effectiveDateTime) {
|
|
2870
|
+
obsDate = new Date(obs.effectiveDateTime);
|
|
2871
|
+
} else if (obs.effectivePeriod) {
|
|
2872
|
+
if (obs.effectivePeriod.start) {
|
|
2873
|
+
obsDate = new Date(obs.effectivePeriod.start);
|
|
2874
|
+
} else if (obs.effectivePeriod.end) {
|
|
2875
|
+
obsDate = new Date(obs.effectivePeriod.end);
|
|
2876
|
+
}
|
|
2877
|
+
}
|
|
2878
|
+
return obsDate;
|
|
2879
|
+
}
|
|
2496
2880
|
/**
|
|
2497
2881
|
* Get all Observation resources from the resource array
|
|
2498
2882
|
* @param resources - FHIR resources array
|
|
2499
2883
|
* @returns Array of Observation resources
|
|
2500
2884
|
*/
|
|
2501
2885
|
static getObservations(resources) {
|
|
2502
|
-
return resources.filter((resourceItem) =>
|
|
2886
|
+
return resources.filter((resourceItem) => {
|
|
2887
|
+
if (resourceItem.resourceType === "Observation") {
|
|
2888
|
+
const obsDate = this.getObservationDate(resourceItem);
|
|
2889
|
+
if (obsDate && obsDate >= new Date(Date.now() - RESULT_SUMMARY_OBSERVATION_DATE_FILTER)) {
|
|
2890
|
+
return true;
|
|
2891
|
+
}
|
|
2892
|
+
}
|
|
2893
|
+
return false;
|
|
2894
|
+
}).map((resourceItem) => resourceItem);
|
|
2503
2895
|
}
|
|
2504
2896
|
/**
|
|
2505
2897
|
* Get all DiagnosticReport resources from the resource array
|
|
@@ -2517,32 +2909,35 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2517
2909
|
* @returns HTML string for rendering
|
|
2518
2910
|
*/
|
|
2519
2911
|
static renderObservations(templateUtilities, observations, timezone) {
|
|
2520
|
-
let html =
|
|
2521
|
-
|
|
2912
|
+
let html = "";
|
|
2913
|
+
if (process.env.ENABLE_DIAGNOSTIC_REPORTS_IN_SUMMARY === "true") {
|
|
2914
|
+
html += `
|
|
2915
|
+
<h3>Observations</h3>`;
|
|
2916
|
+
}
|
|
2917
|
+
html += `
|
|
2522
2918
|
<table>
|
|
2523
2919
|
<thead>
|
|
2524
2920
|
<tr>
|
|
2525
2921
|
<th>Code</th>
|
|
2526
2922
|
<th>Result</th>
|
|
2527
|
-
<th>Unit</th>
|
|
2528
|
-
<th>Interpretation</th>
|
|
2529
2923
|
<th>Reference Range</th>
|
|
2530
|
-
<th>Comments</th>
|
|
2531
2924
|
<th>Date</th>
|
|
2532
2925
|
</tr>
|
|
2533
2926
|
</thead>
|
|
2534
2927
|
<tbody>`;
|
|
2928
|
+
const observationAdded = /* @__PURE__ */ new Set();
|
|
2535
2929
|
for (const obs of observations) {
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
<
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2930
|
+
const obsCode = templateUtilities.codeableConcept(obs.code);
|
|
2931
|
+
if (!observationAdded.has(obsCode)) {
|
|
2932
|
+
observationAdded.add(obsCode);
|
|
2933
|
+
html += `
|
|
2934
|
+
<tr id="${templateUtilities.narrativeLinkId(obs)}">
|
|
2935
|
+
<td>${obsCode}</td>
|
|
2936
|
+
<td>${templateUtilities.extractObservationValue(obs)}</td>
|
|
2937
|
+
<td>${templateUtilities.concatReferenceRange(obs.referenceRange)}</td>
|
|
2938
|
+
<td>${obs.effectiveDateTime ? templateUtilities.renderTime(obs.effectiveDateTime, timezone) : obs.effectivePeriod ? templateUtilities.renderPeriod(obs.effectivePeriod, timezone) : ""}</td>
|
|
2939
|
+
</tr>`;
|
|
2940
|
+
}
|
|
2546
2941
|
}
|
|
2547
2942
|
html += `
|
|
2548
2943
|
</tbody>
|
|
@@ -2569,18 +2964,23 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2569
2964
|
</tr>
|
|
2570
2965
|
</thead>
|
|
2571
2966
|
<tbody>`;
|
|
2967
|
+
const diagnosticReportAdded = /* @__PURE__ */ new Set();
|
|
2572
2968
|
for (const report of reports) {
|
|
2573
|
-
|
|
2574
|
-
if (
|
|
2575
|
-
|
|
2969
|
+
const reportName = templateUtilities.codeableConcept(report.code);
|
|
2970
|
+
if (!diagnosticReportAdded.has(reportName)) {
|
|
2971
|
+
diagnosticReportAdded.add(reportName);
|
|
2972
|
+
let resultCount = "";
|
|
2973
|
+
if (report.result && Array.isArray(report.result)) {
|
|
2974
|
+
resultCount = `${report.result.length} result${report.result.length !== 1 ? "s" : ""}`;
|
|
2975
|
+
}
|
|
2976
|
+
html += `
|
|
2977
|
+
<tr id="${templateUtilities.narrativeLinkId(report)}">
|
|
2978
|
+
<td>${reportName}</td>
|
|
2979
|
+
<td>${templateUtilities.firstFromCodeableConceptList(report.category)}</td>
|
|
2980
|
+
<td>${resultCount}</td>
|
|
2981
|
+
<td>${report.issued ? templateUtilities.renderTime(report.issued, timezone) : ""}</td>
|
|
2982
|
+
</tr>`;
|
|
2576
2983
|
}
|
|
2577
|
-
html += `
|
|
2578
|
-
<tr id="${templateUtilities.narrativeLinkId(report)}">
|
|
2579
|
-
<td>${templateUtilities.codeableConcept(report.code)}</td>
|
|
2580
|
-
<td>${templateUtilities.firstFromCodeableConceptList(report.category)}</td>
|
|
2581
|
-
<td>${resultCount}</td>
|
|
2582
|
-
<td>${report.issued ? templateUtilities.renderTime(report.issued, timezone) : ""}</td>
|
|
2583
|
-
</tr>`;
|
|
2584
2984
|
}
|
|
2585
2985
|
html += `
|
|
2586
2986
|
</tbody>
|
|
@@ -2760,8 +3160,8 @@ var PastHistoryOfIllnessTemplate = class {
|
|
|
2760
3160
|
let html = ``;
|
|
2761
3161
|
const resolvedConditions = resources.map((entry) => entry) || [];
|
|
2762
3162
|
resolvedConditions.sort((a, b) => {
|
|
2763
|
-
const dateA = a.
|
|
2764
|
-
const dateB = b.
|
|
3163
|
+
const dateA = a.recordedDate ? new Date(a.recordedDate).getTime() : 0;
|
|
3164
|
+
const dateB = b.recordedDate ? new Date(b.recordedDate).getTime() : 0;
|
|
2765
3165
|
return dateB - dateA;
|
|
2766
3166
|
});
|
|
2767
3167
|
html += `
|
|
@@ -2775,13 +3175,18 @@ var PastHistoryOfIllnessTemplate = class {
|
|
|
2775
3175
|
</tr>
|
|
2776
3176
|
</thead>
|
|
2777
3177
|
<tbody>`;
|
|
3178
|
+
const addedConditionCodes = /* @__PURE__ */ new Set();
|
|
2778
3179
|
for (const cond of resolvedConditions) {
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
3180
|
+
const conditionCode = templateUtilities.codeableConcept(cond.code);
|
|
3181
|
+
if (!addedConditionCodes.has(conditionCode)) {
|
|
3182
|
+
addedConditionCodes.add(conditionCode);
|
|
3183
|
+
html += `<tr id="${templateUtilities.narrativeLinkId(cond)}">
|
|
3184
|
+
<td class="Name">${conditionCode}</td>
|
|
3185
|
+
<td class="OnsetDate">${templateUtilities.renderDate(cond.onsetDateTime)}</td>
|
|
3186
|
+
<td class="RecordedDate">${templateUtilities.renderDate(cond.recordedDate)}</td>
|
|
3187
|
+
<td class="ResolvedDate">${templateUtilities.renderDate(cond.abatementDateTime)}</td>
|
|
3188
|
+
</tr>`;
|
|
3189
|
+
}
|
|
2785
3190
|
}
|
|
2786
3191
|
html += `</tbody>
|
|
2787
3192
|
</table>`;
|
|
@@ -2906,20 +3311,14 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
|
|
|
2906
3311
|
const clinicalImpressions = [];
|
|
2907
3312
|
for (const resourceItem of resources) {
|
|
2908
3313
|
if (resourceItem.resourceType === "Condition") {
|
|
2909
|
-
|
|
2910
|
-
const isResolved = cond.clinicalStatus?.coding?.some(
|
|
2911
|
-
(c) => c.code === "resolved" || c.code === "inactive" || c.display?.toLowerCase().includes("resolved")
|
|
2912
|
-
);
|
|
2913
|
-
if (!isResolved) {
|
|
2914
|
-
activeConditions.push(cond);
|
|
2915
|
-
}
|
|
3314
|
+
activeConditions.push(resourceItem);
|
|
2916
3315
|
} else if (resourceItem.resourceType === "ClinicalImpression") {
|
|
2917
3316
|
clinicalImpressions.push(resourceItem);
|
|
2918
3317
|
}
|
|
2919
3318
|
}
|
|
2920
3319
|
activeConditions.sort((a, b) => {
|
|
2921
|
-
const dateA = a.
|
|
2922
|
-
const dateB = b.
|
|
3320
|
+
const dateA = a.recordedDate ? new Date(a.recordedDate).getTime() : 0;
|
|
3321
|
+
const dateB = b.recordedDate ? new Date(b.recordedDate).getTime() : 0;
|
|
2923
3322
|
return dateB - dateA;
|
|
2924
3323
|
});
|
|
2925
3324
|
clinicalImpressions.sort((a, b) => {
|
|
@@ -2938,12 +3337,17 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
|
|
|
2938
3337
|
</tr>
|
|
2939
3338
|
</thead>
|
|
2940
3339
|
<tbody>`;
|
|
3340
|
+
const addedConditionCodes = /* @__PURE__ */ new Set();
|
|
2941
3341
|
for (const cond of activeConditions) {
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
3342
|
+
const conditionCode = templateUtilities.codeableConcept(cond.code);
|
|
3343
|
+
if (!addedConditionCodes.has(conditionCode)) {
|
|
3344
|
+
addedConditionCodes.add(conditionCode);
|
|
3345
|
+
html += `<tr id="${templateUtilities.narrativeLinkId(cond)}">
|
|
3346
|
+
<td class="Name">${conditionCode}</td>
|
|
3347
|
+
<td class="OnsetDate">${templateUtilities.renderDate(cond.onsetDateTime)}</td>
|
|
3348
|
+
<td class="RecordedDate">${templateUtilities.renderDate(cond.recordedDate)}</td>
|
|
3349
|
+
</tr>`;
|
|
3350
|
+
}
|
|
2947
3351
|
}
|
|
2948
3352
|
html += `</tbody>
|
|
2949
3353
|
</table>`;
|