@imranq2/fhirpatientsummary 1.0.35 → 1.0.36

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 CHANGED
@@ -201,7 +201,8 @@ var IPSSectionSummaryCompositionFilter = {
201
201
  var IPSSectionSummaryIPSCompositionFilter = {
202
202
  ["Patient" /* PATIENT */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => codingMatches(c, "ips_patient_summary_document", IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM)),
203
203
  ["VitalSignsSection" /* VITAL_SIGNS */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => codingMatches(c, "ips_vital_summary_document", IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM)),
204
- ["SocialHistorySection" /* SOCIAL_HISTORY */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => codingMatches(c, "ips_social_history_summary_document", IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM))
204
+ ["SocialHistorySection" /* SOCIAL_HISTORY */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => codingMatches(c, "ips_social_history_summary_document", IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM)),
205
+ ["FunctionalStatusSection" /* FUNCTIONAL_STATUS */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => codingMatches(c, ["ips_functional_status_condition_summary_document", "ips_functional_status_clinical_impression_summary_document"], IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM))
205
206
  };
206
207
  var IPSSectionResourceHelper = class {
207
208
  static getResourceFilterForSection(section) {
@@ -4033,6 +4034,130 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
4033
4034
  generateNarrative(resources, timezone) {
4034
4035
  return _FunctionalStatusTemplate.generateStaticNarrative(resources, timezone);
4035
4036
  }
4037
+ /**
4038
+ * Generate HTML narrative for Functional Status Condition & ClinicalImpression resources using summary
4039
+ * @param resources - FHIR Composition resources
4040
+ * @param timezone - Optional timezone to use for date formatting (e.g., 'America/New_York', 'Europe/London')
4041
+ * @param now - Optional current date for filtering
4042
+ * @returns HTML string for rendering
4043
+ */
4044
+ generateSummaryNarrative(resources, timezone) {
4045
+ const templateUtilities = new TemplateUtilities(resources);
4046
+ let html = `
4047
+ <div>
4048
+ <p>This section summarizes key conditions and assessments related to the person's functional status and ability to perform daily activities.</p>`;
4049
+ let conditionHtml = `
4050
+ <div>
4051
+ <h3>Conditions</h3>
4052
+ <table>
4053
+ <thead>
4054
+ <tr>
4055
+ <th>Problem</th>
4056
+ <th>Code (System)</th>
4057
+ <th>Onset Date</th>
4058
+ <th>Recorded Date</th>
4059
+ </tr>
4060
+ </thead>
4061
+ <tbody>`;
4062
+ let clinicalImpressionsHtml = `
4063
+ <div>
4064
+ <h3>Clinical Impressions</h3>
4065
+ <table>
4066
+ <thead>
4067
+ <tr>
4068
+ <th>Name</th>
4069
+ <th>Date</th>
4070
+ <th>Code (System)</th>
4071
+ <th>Description</th>
4072
+ <th>Summary</th>
4073
+ </tr>
4074
+ </thead>
4075
+ <tbody>`;
4076
+ const conditionsAdded = /* @__PURE__ */ new Set();
4077
+ const clinicalImpressionsAdded = /* @__PURE__ */ new Set();
4078
+ for (const resourceItem of resources) {
4079
+ for (const rowData of resourceItem.section ?? []) {
4080
+ const sectionCodeableConcept = rowData.code;
4081
+ const data = {};
4082
+ for (const columnData of rowData.section ?? []) {
4083
+ if (columnData.title) {
4084
+ data[columnData.title] = templateUtilities.renderTextAsHtml(
4085
+ columnData.text?.div ?? ""
4086
+ );
4087
+ }
4088
+ }
4089
+ if (resourceItem.title === "Condition|Condition Summary Grouped by Functional Status Code") {
4090
+ let date = data["onsetDateTime"] ? templateUtilities.renderTime(data["onsetDateTime"], timezone) : "";
4091
+ if (!date && data["onsetPeriod.start"]) {
4092
+ date = templateUtilities.renderTime(
4093
+ data["onsetPeriod.start"],
4094
+ timezone
4095
+ );
4096
+ if (data["onsetPeriod.end"]) {
4097
+ date += " - " + templateUtilities.renderTime(data["onsetPeriod.end"], timezone);
4098
+ }
4099
+ }
4100
+ const problem = data["Condition Name"];
4101
+ if (problem && !conditionsAdded.has(problem)) {
4102
+ if (problem.toLowerCase() === "unknown") {
4103
+ continue;
4104
+ }
4105
+ conditionsAdded.add(problem);
4106
+ conditionHtml += `
4107
+ <tr>
4108
+ <td>${templateUtilities.capitalizeFirstLetter(problem)}</td>
4109
+ <td>${templateUtilities.codeableConceptCoding(sectionCodeableConcept)}</td>
4110
+ <td>${date}</td>
4111
+ <td>${templateUtilities.renderTime(data["recordedDate"], timezone) ?? ""}</td>
4112
+ </tr>`;
4113
+ }
4114
+ } else if (resourceItem.title === "Clinical Impression|Clinical Impression Summary") {
4115
+ let date = data["effectiveDateTime"] ? templateUtilities.renderTime(data["effectiveDateTime"], timezone) : "";
4116
+ if (!date && data["effectivePeriod.start"]) {
4117
+ date = templateUtilities.renderTime(
4118
+ data["effectivePeriod.start"],
4119
+ timezone
4120
+ );
4121
+ if (data["effectivePeriod.end"]) {
4122
+ date += " - " + templateUtilities.renderTime(data["effectivePeriod.end"], timezone);
4123
+ }
4124
+ }
4125
+ const name = data["Clinical Impression Name"];
4126
+ if (name && !clinicalImpressionsAdded.has(name)) {
4127
+ if (name?.toLowerCase() === "unknown") {
4128
+ continue;
4129
+ }
4130
+ clinicalImpressionsAdded.add(name);
4131
+ clinicalImpressionsHtml += `
4132
+ <tr>
4133
+ <td>${templateUtilities.capitalizeFirstLetter(name)}</td>
4134
+ <td>${date ?? ""}</td>
4135
+ <td>${templateUtilities.codeableConceptCoding(sectionCodeableConcept)}</td>
4136
+ <td>${data["Description"] ?? ""}</td>
4137
+ <td>${data["Summary"] ?? ""}</td>
4138
+ </tr>`;
4139
+ }
4140
+ }
4141
+ }
4142
+ }
4143
+ if (conditionsAdded.size > 0) {
4144
+ html += conditionHtml;
4145
+ html += `
4146
+ </tbody>
4147
+ </table>
4148
+ </div>`;
4149
+ }
4150
+ if (clinicalImpressionsAdded.size > 0) {
4151
+ html += clinicalImpressionsHtml;
4152
+ html += `
4153
+ </tbody>
4154
+ </table>
4155
+ </div>`;
4156
+ }
4157
+ html += `
4158
+ </div>`;
4159
+ return conditionsAdded.size > 0 || clinicalImpressionsAdded.size > 0 ? html : void 0;
4160
+ }
4036
4161
  /**
4037
4162
  * Internal static implementation that actually generates the narrative
4038
4163
  * @param resources - FHIR resources array containing Observation resources
package/dist/index.js CHANGED
@@ -173,7 +173,8 @@ var IPSSectionSummaryCompositionFilter = {
173
173
  var IPSSectionSummaryIPSCompositionFilter = {
174
174
  ["Patient" /* PATIENT */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => codingMatches(c, "ips_patient_summary_document", IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM)),
175
175
  ["VitalSignsSection" /* VITAL_SIGNS */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => codingMatches(c, "ips_vital_summary_document", IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM)),
176
- ["SocialHistorySection" /* SOCIAL_HISTORY */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => codingMatches(c, "ips_social_history_summary_document", IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM))
176
+ ["SocialHistorySection" /* SOCIAL_HISTORY */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => codingMatches(c, "ips_social_history_summary_document", IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM)),
177
+ ["FunctionalStatusSection" /* FUNCTIONAL_STATUS */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => codingMatches(c, ["ips_functional_status_condition_summary_document", "ips_functional_status_clinical_impression_summary_document"], IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM))
177
178
  };
178
179
  var IPSSectionResourceHelper = class {
179
180
  static getResourceFilterForSection(section) {
@@ -4005,6 +4006,130 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
4005
4006
  generateNarrative(resources, timezone) {
4006
4007
  return _FunctionalStatusTemplate.generateStaticNarrative(resources, timezone);
4007
4008
  }
4009
+ /**
4010
+ * Generate HTML narrative for Functional Status Condition & ClinicalImpression resources using summary
4011
+ * @param resources - FHIR Composition resources
4012
+ * @param timezone - Optional timezone to use for date formatting (e.g., 'America/New_York', 'Europe/London')
4013
+ * @param now - Optional current date for filtering
4014
+ * @returns HTML string for rendering
4015
+ */
4016
+ generateSummaryNarrative(resources, timezone) {
4017
+ const templateUtilities = new TemplateUtilities(resources);
4018
+ let html = `
4019
+ <div>
4020
+ <p>This section summarizes key conditions and assessments related to the person's functional status and ability to perform daily activities.</p>`;
4021
+ let conditionHtml = `
4022
+ <div>
4023
+ <h3>Conditions</h3>
4024
+ <table>
4025
+ <thead>
4026
+ <tr>
4027
+ <th>Problem</th>
4028
+ <th>Code (System)</th>
4029
+ <th>Onset Date</th>
4030
+ <th>Recorded Date</th>
4031
+ </tr>
4032
+ </thead>
4033
+ <tbody>`;
4034
+ let clinicalImpressionsHtml = `
4035
+ <div>
4036
+ <h3>Clinical Impressions</h3>
4037
+ <table>
4038
+ <thead>
4039
+ <tr>
4040
+ <th>Name</th>
4041
+ <th>Date</th>
4042
+ <th>Code (System)</th>
4043
+ <th>Description</th>
4044
+ <th>Summary</th>
4045
+ </tr>
4046
+ </thead>
4047
+ <tbody>`;
4048
+ const conditionsAdded = /* @__PURE__ */ new Set();
4049
+ const clinicalImpressionsAdded = /* @__PURE__ */ new Set();
4050
+ for (const resourceItem of resources) {
4051
+ for (const rowData of resourceItem.section ?? []) {
4052
+ const sectionCodeableConcept = rowData.code;
4053
+ const data = {};
4054
+ for (const columnData of rowData.section ?? []) {
4055
+ if (columnData.title) {
4056
+ data[columnData.title] = templateUtilities.renderTextAsHtml(
4057
+ columnData.text?.div ?? ""
4058
+ );
4059
+ }
4060
+ }
4061
+ if (resourceItem.title === "Condition|Condition Summary Grouped by Functional Status Code") {
4062
+ let date = data["onsetDateTime"] ? templateUtilities.renderTime(data["onsetDateTime"], timezone) : "";
4063
+ if (!date && data["onsetPeriod.start"]) {
4064
+ date = templateUtilities.renderTime(
4065
+ data["onsetPeriod.start"],
4066
+ timezone
4067
+ );
4068
+ if (data["onsetPeriod.end"]) {
4069
+ date += " - " + templateUtilities.renderTime(data["onsetPeriod.end"], timezone);
4070
+ }
4071
+ }
4072
+ const problem = data["Condition Name"];
4073
+ if (problem && !conditionsAdded.has(problem)) {
4074
+ if (problem.toLowerCase() === "unknown") {
4075
+ continue;
4076
+ }
4077
+ conditionsAdded.add(problem);
4078
+ conditionHtml += `
4079
+ <tr>
4080
+ <td>${templateUtilities.capitalizeFirstLetter(problem)}</td>
4081
+ <td>${templateUtilities.codeableConceptCoding(sectionCodeableConcept)}</td>
4082
+ <td>${date}</td>
4083
+ <td>${templateUtilities.renderTime(data["recordedDate"], timezone) ?? ""}</td>
4084
+ </tr>`;
4085
+ }
4086
+ } else if (resourceItem.title === "Clinical Impression|Clinical Impression Summary") {
4087
+ let date = data["effectiveDateTime"] ? templateUtilities.renderTime(data["effectiveDateTime"], timezone) : "";
4088
+ if (!date && data["effectivePeriod.start"]) {
4089
+ date = templateUtilities.renderTime(
4090
+ data["effectivePeriod.start"],
4091
+ timezone
4092
+ );
4093
+ if (data["effectivePeriod.end"]) {
4094
+ date += " - " + templateUtilities.renderTime(data["effectivePeriod.end"], timezone);
4095
+ }
4096
+ }
4097
+ const name = data["Clinical Impression Name"];
4098
+ if (name && !clinicalImpressionsAdded.has(name)) {
4099
+ if (name?.toLowerCase() === "unknown") {
4100
+ continue;
4101
+ }
4102
+ clinicalImpressionsAdded.add(name);
4103
+ clinicalImpressionsHtml += `
4104
+ <tr>
4105
+ <td>${templateUtilities.capitalizeFirstLetter(name)}</td>
4106
+ <td>${date ?? ""}</td>
4107
+ <td>${templateUtilities.codeableConceptCoding(sectionCodeableConcept)}</td>
4108
+ <td>${data["Description"] ?? ""}</td>
4109
+ <td>${data["Summary"] ?? ""}</td>
4110
+ </tr>`;
4111
+ }
4112
+ }
4113
+ }
4114
+ }
4115
+ if (conditionsAdded.size > 0) {
4116
+ html += conditionHtml;
4117
+ html += `
4118
+ </tbody>
4119
+ </table>
4120
+ </div>`;
4121
+ }
4122
+ if (clinicalImpressionsAdded.size > 0) {
4123
+ html += clinicalImpressionsHtml;
4124
+ html += `
4125
+ </tbody>
4126
+ </table>
4127
+ </div>`;
4128
+ }
4129
+ html += `
4130
+ </div>`;
4131
+ return conditionsAdded.size > 0 || clinicalImpressionsAdded.size > 0 ? html : void 0;
4132
+ }
4008
4133
  /**
4009
4134
  * Internal static implementation that actually generates the narrative
4010
4135
  * @param resources - FHIR resources array containing Observation resources
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imranq2/fhirpatientsummary",
3
- "version": "1.0.35",
3
+ "version": "1.0.36",
4
4
  "description": "A template for creating npm packages using TypeScript and VSCode",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",