From faae17372c058a930050033354686016ffd578f4 Mon Sep 17 00:00:00 2001 From: Patrick LaRocque Date: Wed, 7 Jan 2026 01:27:48 -0500 Subject: [PATCH 1/7] Add button to query for the PACIO patient discharge information and process the TOC. --- .env | 3 + src/components/RequestDashboard/Home.jsx | 2 +- .../RequestDashboard/SettingsSection.jsx | 241 +++++++++++++++++- src/util/data.js | 20 +- 4 files changed, 255 insertions(+), 11 deletions(-) diff --git a/.env b/.env index d4b9e1e..ef9f3d1 100644 --- a/.env +++ b/.env @@ -30,3 +30,6 @@ VITE_USE_PHARMACY_IN_PREFETCH = true VITE_INTERMEDIARY = http://localhost:3003 VITE_DISABLE_MEDICATION_STATUS = false VITE_PHARMACY_ID = pharm0111 +VITE_PACIO_EHR_COMPARISON_URL = https://michiganprimaryhealthcareassociates.org/fhir +VITE_PACIO_EHR_URL = https://gw.interop.community/paciosandbox2/open +VITE_PACIO_EHR_URL_QUERY = /Bundle?type=message&_lastUpdated=gt2025-12-22T23:00:45.000+00:00&_format=json diff --git a/src/components/RequestDashboard/Home.jsx b/src/components/RequestDashboard/Home.jsx index 61b538c..f9267b4 100644 --- a/src/components/RequestDashboard/Home.jsx +++ b/src/components/RequestDashboard/Home.jsx @@ -121,7 +121,7 @@ const Home = props => {
- +
); diff --git a/src/components/RequestDashboard/SettingsSection.jsx b/src/components/RequestDashboard/SettingsSection.jsx index e1a031e..c865916 100644 --- a/src/components/RequestDashboard/SettingsSection.jsx +++ b/src/components/RequestDashboard/SettingsSection.jsx @@ -33,12 +33,15 @@ import { ENCOUNTER_START, REMS_ETASU } from '../../util/data'; +import { getPatientFirstAndLastName } from '../../util/util'; import { actionTypes } from '../../containers/ContextProvider/reducer'; import { SettingsContext } from '../../containers/ContextProvider/SettingsProvider'; const ENDPOINT = [ORDER_SIGN, ORDER_SELECT, PATIENT_VIEW, ENCOUNTER_START, REMS_ETASU]; const SettingsSection = props => { + const { client, userId } = props; + const [state, dispatch, updateSetting, readSettings, saveSettings] = React.useContext(SettingsContext); @@ -95,16 +98,16 @@ const SettingsSection = props => { }); }; - const clearResource = - ({ ehrUrl, access_token }, type) => - () => { - console.log('Clear ' + type + 's from the EHR: ' + ehrUrl); - const client = FHIR.client({ - serverUrl: ehrUrl, - ...(access_token ? { tokenResponse: access_token } : {}) - }); + const clearResourceWithParams = + (type, params) => { + console.log('Clear ' + type + 's from the EHR'); + let query = type; + if (params != '') { + query = type+params; + console.log(' -> with params ' + params); + } client - .request(type, { flat: true }) + .request(query, { flat: true }) .then(result => { console.log(result); result.forEach(resource => { @@ -123,6 +126,36 @@ const SettingsSection = props => { .catch(e => { console.log('Failed to retrieve list of ' + type + 's'); console.log(e); + }); + }; + + const clearResource = + ( {}, type ) => + () => { + // Delete all resources of type type + clearResourceWithParams(type, ''); + }; + + const clearPatient = + ({ patientOfInterest }) => + () => { + console.log(`clear patient ${patientOfInterest}`) + + // Delete the MedicationRequests for the Patient + clearResourceWithParams('MedicationRequest', `?subject=${patientOfInterest}`); + + // Delete the Communications for the Patient + clearResourceWithParams('Communication', `?subject=${patientOfInterest}`); + + // Delete the Patient + let query = `Patient/${patientOfInterest}`; + client.delete(query) + .then(result => { + console.log(result); + }) + .catch(e => { + console.log('Failed to delete ' + query); + console.log(e); }); }; @@ -137,6 +170,185 @@ const SettingsSection = props => { }); }; + const createCommunication = (patientId, practitionerId, message) => { + const ts = Date.now(); + const currentDate = new Date(ts); + + const communication = { + resourceType: "Communication", + status: "in-progress", + category: [ + { + coding: [ + { + system: "http://acme.org/messagetypes", + code: "Alert" + } + ], + text: "Alert" + } + ], + subject: { + reference: "Patient/" + patientId + }, + sent: currentDate.toISOString(), + received: currentDate.toISOString(), + recipient: [ + { + reference: "Practitioner/" + practitionerId + } + ], + sender: { + reference: "Device/f001" + }, + payload: [ + { + contentString: message + } + ] + } + + return communication; + } + + const addCommunication = (patientId, message) => { + // add a communication notifying the practitioner that the resources were created + const communication = createCommunication(patientId, userId, message); + + client.create(communication) + .then(result => { + //console.log(result); + }) + .catch(e => { + console.log('Failed to add Communication to EHR'); + console.log(e); + }) + }; + + const parsePacioToc = (pacioToc) => { + console.log(' Parse PACIO TOC'); + let medicationRequestList = []; + let patient = null; + + pacioToc?.entry.forEach(tocEntry => { + const tocResource = tocEntry?.resource; + + switch (tocResource?.resourceType) { + case 'Patient': + // find the patient + console.log(' Found Patient'); + patient = tocResource; + break; + case 'Bundle': + console.log(' Process TOC Bundle'); + tocResource?.entry.forEach(bundleEntry => { + const bundleEntryResource = bundleEntry?.resource; + switch (bundleEntryResource?.resourceType) { + case 'MedicationRequest': + // find the MedicationRequests + console.log(' Found MedicationRequst'); + medicationRequestList.push(bundleEntryResource); + break; + } + }); + + break; + } + }); + + if (!patient) { + console.log('PACIO TOC missing Patient'); + console.log(tocResource); + return; + } + + // add the Patient to the EHR + client.create(patient) + .then(patientResult => { + let newPatientId = patientResult?.id; + console.log(` Added new patient (${getPatientFirstAndLastName(patientResult)} - ${newPatientId}) to EHR`) + addCommunication(newPatientId, `Added new patient (${getPatientFirstAndLastName(patientResult)}) to EHR`); + + // add the MedicationRequests to the EHR + medicationRequestList.forEach(medicationRequest => { + medicationRequest.subject.reference = `Patient/${newPatientId}`; + + client.create(medicationRequest) + .then(medicationRequestResult => { + console.log(` Added new MedicationRequest (for ${getPatientFirstAndLastName(patientResult)} - ${newPatientId}) to EHR`) + addCommunication(newPatientId, `Added new MedicationRequest for patient (${getPatientFirstAndLastName(patientResult)}) to EHR`); + }) + .catch(e => { + console.log(`Failed to add MedicationRequest to EHR`); + console.log(e); + }); + }); + + }) + .catch(e => { + console.log(`Failed to add Patient to EHR`); + console.log(e); + }) + }; + + const pollPacio = + ({ pacioEhrComparisonUrl, pacioEhrUrl, pacioEhrUrlQuery }) => + () => { + // connect to the PACIO FHIR server, assume it is an open FHIR server + const pacioFhirClient = FHIR.client({ + serverUrl: pacioEhrUrl + }); + + // pull the PACIO discharge notification + pacioFhirClient.request(pacioEhrUrlQuery) + .then(pacioDischarge => { + let pacioDischargeEntries = pacioDischarge?.entry[0]?.resource?.entry; + + let documentReference = null; + + for (const dischargeEntry of pacioDischargeEntries) { + const dischargeResource = dischargeEntry?.resource; + switch (dischargeResource?.resourceType) { + case 'MessageHeader': + console.log(' Process MessageHeader'); + const destination = dischargeResource?.destination[0]?.endpoint; + if (destination.toUpperCase() != pacioEhrComparisonUrl.toUpperCase()) { + console.log(`Message not meant for us (${destination}), skipping...`) + return; + } + break; + case 'DocumentReference': + console.log(' Process DocumentReference (TOC)'); + documentReference = dischargeResource; + break; + } + } + + if (!documentReference) { + console.log('PACIO Discharge Notification missing DocumentReference'); + console.log(pacioDischarge); + return; + } + + // pull the TOC from the PACIO server, assume same base url as discharge notification + const pacioTocUrl = documentReference?.content[0]?.attachment?.url; + let pacioTocQuery = pacioTocUrl.replace(pacioEhrUrl, ''); + + pacioFhirClient.request(pacioTocQuery) + .then(pacioToc => { + parsePacioToc(pacioToc); + }) + .catch(e => { + console.log('Failed to retrieve PACIO TOC'); + console.log(e); + }); + }) + .catch(e => { + console.log('Failed to retrieve PACIO Discharge Notification'); + console.log(e); + }) + }; + const resetHeaderDefinitions = [ { display: 'Reset PIMS Database', @@ -166,11 +378,22 @@ const SettingsSection = props => { reset: clearResource, parameter: 'Task' }, + { + display: 'Clear EHR Patient', + key: 'clearPatient', + reset: clearPatient, + }, { display: 'Reconnect EHR', key: 'reconnectEHR', reset: reconnectEhr, variant: 'contained' + }, + { + display: 'Poll PACIO Patient Discharge Notifications', + key: 'pollPACIO', + reset: pollPacio, + variant: 'contained' } ]; diff --git a/src/util/data.js b/src/util/data.js index 910383c..d71cf0a 100644 --- a/src/util/data.js +++ b/src/util/data.js @@ -101,7 +101,25 @@ const headerDefinitions = { type: 'check', default: false }, - + pacioEhrComparisonUrl: { + display: 'PACIO EHR Comparision URL', + type: 'input', + default: env.get('VITE_PACIO_EHR_COMPARISON_URL').asString() + }, + pacioEhrUrl: { + display: 'PACIO EHR URL', + type: 'input', + default: env.get('VITE_PACIO_EHR_URL').asString() + }, + pacioEhrUrlQuery: { + display: 'PACIO EHR URL Query', + type: 'input', + default: env.get('VITE_PACIO_EHR_URL_QUERY').asString() + }, + patientOfInterest: { + display: 'Patient ID (for Clear)', + type: 'input' + }, hookToSend: { display: 'Send hook on patient select', type: 'dropdown', From a28731c89dd5df85666053d955cf7fb45919db07 Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Wed, 7 Jan 2026 17:10:35 -0500 Subject: [PATCH 2/7] convert med statements to med requests --- .env | 1 + .../RequestDashboard/SettingsSection.jsx | 70 ++++++++++++++++--- src/util/data.js | 7 +- 3 files changed, 66 insertions(+), 12 deletions(-) diff --git a/.env b/.env index ef9f3d1..65bf609 100644 --- a/.env +++ b/.env @@ -33,3 +33,4 @@ VITE_PHARMACY_ID = pharm0111 VITE_PACIO_EHR_COMPARISON_URL = https://michiganprimaryhealthcareassociates.org/fhir VITE_PACIO_EHR_URL = https://gw.interop.community/paciosandbox2/open VITE_PACIO_EHR_URL_QUERY = /Bundle?type=message&_lastUpdated=gt2025-12-22T23:00:45.000+00:00&_format=json +VITE_PACIO_NEW_PRESCRIBER_ID=pra1234 \ No newline at end of file diff --git a/src/components/RequestDashboard/SettingsSection.jsx b/src/components/RequestDashboard/SettingsSection.jsx index c865916..7b671dc 100644 --- a/src/components/RequestDashboard/SettingsSection.jsx +++ b/src/components/RequestDashboard/SettingsSection.jsx @@ -227,7 +227,7 @@ const SettingsSection = props => { const parsePacioToc = (pacioToc) => { console.log(' Parse PACIO TOC'); - let medicationRequestList = []; + let medicationStatementList = []; let patient = null; pacioToc?.entry.forEach(tocEntry => { @@ -244,10 +244,10 @@ const SettingsSection = props => { tocResource?.entry.forEach(bundleEntry => { const bundleEntryResource = bundleEntry?.resource; switch (bundleEntryResource?.resourceType) { - case 'MedicationRequest': - // find the MedicationRequests - console.log(' Found MedicationRequst'); - medicationRequestList.push(bundleEntryResource); + case 'MedicationStatement': + // find the MedicationStatements + console.log(' Found MedicationStatement'); + medicationStatementList.push(bundleEntryResource); break; } }); @@ -262,6 +262,10 @@ const SettingsSection = props => { return; } + // Get the new prescriber ID from settings + const newPrescriberId = state.pacioNewPrescriberId; + console.log(` Converting MedicationStatements to MedicationRequests with prescriber: ${newPrescriberId}`); + // add the Patient to the EHR client.create(patient) .then(patientResult => { @@ -269,14 +273,58 @@ const SettingsSection = props => { console.log(` Added new patient (${getPatientFirstAndLastName(patientResult)} - ${newPatientId}) to EHR`) addCommunication(newPatientId, `Added new patient (${getPatientFirstAndLastName(patientResult)}) to EHR`); - // add the MedicationRequests to the EHR - medicationRequestList.forEach(medicationRequest => { - medicationRequest.subject.reference = `Patient/${newPatientId}`; + // Convert MedicationStatements to MedicationRequests and add to EHR + medicationStatementList.forEach(medicationStatement => { + // Create a new MedicationRequest from the MedicationStatement + const medicationRequest = { + resourceType: 'MedicationRequest', + meta: { + profile: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-medicationrequest'] + }, + status: 'active', + intent: 'order', + subject: { + reference: `Patient/${newPatientId}`, + display: getPatientFirstAndLastName(patientResult) + }, + authoredOn: new Date().toISOString().split('T')[0], + requester: { + reference: `Practitioner/${newPrescriberId}`, + display: 'Transfer Prescriber' + } + }; + + // Copy medication information + if (medicationStatement.medicationCodeableConcept) { + medicationRequest.medicationCodeableConcept = medicationStatement.medicationCodeableConcept; + } else if (medicationStatement.medicationReference) { + medicationRequest.medicationReference = medicationStatement.medicationReference; + } + + // Copy dosage if available + if (medicationStatement.dosage && medicationStatement.dosage.length > 0) { + medicationRequest.dosageInstruction = medicationStatement.dosage.map((dosage, index) => ({ + sequence: index + 1, + text: dosage.text, + timing: dosage.timing, + route: dosage.route, + doseAndRate: dosage.doseAndRate + })); + } + + // Add note about transfer + medicationRequest.note = [ + { + text: `Continued from previous care. Original medication statement: ${medicationStatement.id || 'unknown'}` + } + ]; + + const medName = medicationRequest.medicationCodeableConcept?.coding?.[0]?.display || 'Unknown medication'; client.create(medicationRequest) .then(medicationRequestResult => { - console.log(` Added new MedicationRequest (for ${getPatientFirstAndLastName(patientResult)} - ${newPatientId}) to EHR`) - addCommunication(newPatientId, `Added new MedicationRequest for patient (${getPatientFirstAndLastName(patientResult)}) to EHR`); + console.log(` Added new MedicationRequest for ${medName} (for ${getPatientFirstAndLastName(patientResult)} - ${newPatientId}) to EHR`) + addCommunication(newPatientId, `Added new MedicationRequest from MedicationStatement ${medName} - patient (${getPatientFirstAndLastName(patientResult)}) to EHR`); }) .catch(e => { console.log(`Failed to add MedicationRequest to EHR`); @@ -642,4 +690,4 @@ const SettingsSection = props => { ); }; -export default memo(SettingsSection); +export default memo(SettingsSection); \ No newline at end of file diff --git a/src/util/data.js b/src/util/data.js index d71cf0a..48a7ae8 100644 --- a/src/util/data.js +++ b/src/util/data.js @@ -120,6 +120,11 @@ const headerDefinitions = { display: 'Patient ID (for Clear)', type: 'input' }, + pacioNewPrescriberId: { + display: 'PACIO New Prescriber ID', + type: 'input', + default: env.get('VITE_PACIO_NEW_PRESCRIBER_ID').asString() + }, hookToSend: { display: 'Send hook on patient select', type: 'dropdown', @@ -367,4 +372,4 @@ export { REMS_ETASU, CDS_SERVICE, serviceEndpoints -}; +}; \ No newline at end of file From b9cda8207a0b2488f33d690d6e91cd9bb23b2a34 Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Wed, 7 Jan 2026 17:53:29 -0500 Subject: [PATCH 3/7] added coverage and patient id --- .env | 4 +- .../RequestDashboard/SettingsSection.jsx | 215 ++++++++++++------ src/util/data.js | 10 + 3 files changed, 159 insertions(+), 70 deletions(-) diff --git a/.env b/.env index 65bf609..045b912 100644 --- a/.env +++ b/.env @@ -33,4 +33,6 @@ VITE_PHARMACY_ID = pharm0111 VITE_PACIO_EHR_COMPARISON_URL = https://michiganprimaryhealthcareassociates.org/fhir VITE_PACIO_EHR_URL = https://gw.interop.community/paciosandbox2/open VITE_PACIO_EHR_URL_QUERY = /Bundle?type=message&_lastUpdated=gt2025-12-22T23:00:45.000+00:00&_format=json -VITE_PACIO_NEW_PRESCRIBER_ID=pra1234 \ No newline at end of file +VITE_PACIO_NEW_PRESCRIBER_ID=pra1234 +VITE_PACIO_PATIENT_ID=pat018 +VITE_PACIO_COVERAGE_ID=cov018 \ No newline at end of file diff --git a/src/components/RequestDashboard/SettingsSection.jsx b/src/components/RequestDashboard/SettingsSection.jsx index 7b671dc..721e692 100644 --- a/src/components/RequestDashboard/SettingsSection.jsx +++ b/src/components/RequestDashboard/SettingsSection.jsx @@ -225,7 +225,7 @@ const SettingsSection = props => { }) }; - const parsePacioToc = (pacioToc) => { + const parsePacioToc = async (pacioToc) => { console.log(' Parse PACIO TOC'); let medicationStatementList = []; let patient = null; @@ -258,85 +258,162 @@ const SettingsSection = props => { if (!patient) { console.log('PACIO TOC missing Patient'); - console.log(tocResource); return; } - // Get the new prescriber ID from settings + // Get settings const newPrescriberId = state.pacioNewPrescriberId; + const configuredPatientId = state.pacioPatientId; + const configuredCoverageId = state.pacioCoverageId; + console.log(` Converting MedicationStatements to MedicationRequests with prescriber: ${newPrescriberId}`); - // add the Patient to the EHR - client.create(patient) - .then(patientResult => { - let newPatientId = patientResult?.id; - console.log(` Added new patient (${getPatientFirstAndLastName(patientResult)} - ${newPatientId}) to EHR`) - addCommunication(newPatientId, `Added new patient (${getPatientFirstAndLastName(patientResult)}) to EHR`); - - // Convert MedicationStatements to MedicationRequests and add to EHR - medicationStatementList.forEach(medicationStatement => { - // Create a new MedicationRequest from the MedicationStatement - const medicationRequest = { - resourceType: 'MedicationRequest', - meta: { - profile: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-medicationrequest'] - }, - status: 'active', - intent: 'order', - subject: { - reference: `Patient/${newPatientId}`, - display: getPatientFirstAndLastName(patientResult) - }, - authoredOn: new Date().toISOString().split('T')[0], - requester: { - reference: `Practitioner/${newPrescriberId}`, - display: 'Transfer Prescriber' + // Determine which patient to use + let targetPatient = null; + + if (configuredPatientId) { + // Use configured patient ID + console.log(` Using configured patient ID: ${configuredPatientId}`); + try { + targetPatient = await client.request(`Patient/${configuredPatientId}`); + console.log(` Found patient: ${getPatientFirstAndLastName(targetPatient)} (${targetPatient.id})`); + } catch (e) { + console.log(` Error fetching configured patient ${configuredPatientId}:`, e); + } + } + + if (!targetPatient) { + // Create new patient from TOC bundle + console.log(' Creating new patient from TOC bundle'); + try { + targetPatient = await client.create(patient); + console.log(` Created new patient: ${getPatientFirstAndLastName(targetPatient)} (${targetPatient.id})`); + addCommunication(targetPatient.id, `Added new patient (${getPatientFirstAndLastName(targetPatient)}) from transfer of care`); + } catch (e) { + console.log(' Failed to create patient:', e); + return; + } + } else { + addCommunication(targetPatient.id, `Received transfer of care notification for patient (${getPatientFirstAndLastName(targetPatient)})`); + } + + // Determine which coverage to use + let coverageId = null; + + if (configuredCoverageId) { + // Use configured coverage ID + console.log(` Using configured coverage ID: ${configuredCoverageId}`); + try { + const coverageResult = await client.request(`Coverage/${configuredCoverageId}`); + if (coverageResult) { + coverageId = configuredCoverageId; + console.log(` Found coverage: ${coverageId}`); + } + } catch (e) { + console.log(` Error fetching configured coverage ${configuredCoverageId}:`, e); + } + } + + if (!coverageId) { + // Create new proper coverage + console.log(' Creating new coverage'); + try { + const coverage = { + resourceType: 'Coverage', + status: 'active', + beneficiary: { + reference: `Patient/${targetPatient.id}` + }, + subscriberId: '1EG4TE5MK73', + class: [ + { + type: { + system: 'http://hl7.org/fhir/coverage-class', + code: 'plan' + }, + value: 'Medicare Part A' } - }; + ], + payor: [{ + reference: 'Organization/org1234' + }] + }; + + const coverageResult = await client.create(coverage); + coverageId = coverageResult.id; + console.log(` Created new coverage: ${coverageId}`); + } catch (e) { + console.log(' Warning: Could not create coverage:', e); + } + } - // Copy medication information - if (medicationStatement.medicationCodeableConcept) { - medicationRequest.medicationCodeableConcept = medicationStatement.medicationCodeableConcept; - } else if (medicationStatement.medicationReference) { - medicationRequest.medicationReference = medicationStatement.medicationReference; - } + // Convert MedicationStatements to MedicationRequests + const patientId = targetPatient.id; + const patientName = getPatientFirstAndLastName(targetPatient); + console.log(` Creating MedicationRequests for patient ${patientName} (${patientId})`); + + for (const medicationStatement of medicationStatementList) { + // Create a new MedicationRequest from the MedicationStatement + const medicationRequest = { + resourceType: 'MedicationRequest', + meta: { + profile: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-medicationrequest'] + }, + status: 'active', + intent: 'order', + subject: { + reference: `Patient/${patientId}`, + display: patientName + }, + authoredOn: new Date().toISOString().split('T')[0], + requester: { + reference: `Practitioner/${newPrescriberId}`, + display: 'Transfer Prescriber' + } + }; - // Copy dosage if available - if (medicationStatement.dosage && medicationStatement.dosage.length > 0) { - medicationRequest.dosageInstruction = medicationStatement.dosage.map((dosage, index) => ({ - sequence: index + 1, - text: dosage.text, - timing: dosage.timing, - route: dosage.route, - doseAndRate: dosage.doseAndRate - })); - } + // Add insurance/coverage reference if available + if (coverageId) { + medicationRequest.insurance = [{ + reference: `Coverage/${coverageId}` + }]; + } - // Add note about transfer - medicationRequest.note = [ - { - text: `Continued from previous care. Original medication statement: ${medicationStatement.id || 'unknown'}` - } - ]; - - const medName = medicationRequest.medicationCodeableConcept?.coding?.[0]?.display || 'Unknown medication'; - - client.create(medicationRequest) - .then(medicationRequestResult => { - console.log(` Added new MedicationRequest for ${medName} (for ${getPatientFirstAndLastName(patientResult)} - ${newPatientId}) to EHR`) - addCommunication(newPatientId, `Added new MedicationRequest from MedicationStatement ${medName} - patient (${getPatientFirstAndLastName(patientResult)}) to EHR`); - }) - .catch(e => { - console.log(`Failed to add MedicationRequest to EHR`); - console.log(e); - }); - }); + // Copy medication information + if (medicationStatement.medicationCodeableConcept) { + medicationRequest.medicationCodeableConcept = medicationStatement.medicationCodeableConcept; + } else if (medicationStatement.medicationReference) { + medicationRequest.medicationReference = medicationStatement.medicationReference; + } - }) - .catch(e => { - console.log(`Failed to add Patient to EHR`); - console.log(e); - }) + // Copy dosage if available + if (medicationStatement.dosage && medicationStatement.dosage.length > 0) { + medicationRequest.dosageInstruction = medicationStatement.dosage.map((dosage, index) => ({ + sequence: index + 1, + text: dosage.text, + timing: dosage.timing, + route: dosage.route, + doseAndRate: dosage.doseAndRate + })); + } + + // Add note about transfer + medicationRequest.note = [ + { + text: `Continued from previous care. Original medication statement: ${medicationStatement.id || 'unknown'}` + } + ]; + + const medName = medicationRequest.medicationCodeableConcept?.coding?.[0]?.display || 'Unknown medication'; + + try { + const medicationRequestResult = await client.create(medicationRequest); + console.log(` Added new MedicationRequest for ${medName} (ID: ${medicationRequestResult.id})`); + addCommunication(patientId, `Added new MedicationRequest for ${medName} from transfer of care`); + } catch (e) { + console.log(` Failed to add MedicationRequest for ${medName}:`, e); + } + } }; const pollPacio = diff --git a/src/util/data.js b/src/util/data.js index 48a7ae8..0c04bd3 100644 --- a/src/util/data.js +++ b/src/util/data.js @@ -120,6 +120,16 @@ const headerDefinitions = { display: 'Patient ID (for Clear)', type: 'input' }, + pacioPatientId: { + display: 'PACIO Patient ID', + type: 'input', + default: env.get('VITE_PACIO_PATIENT_ID').asString() + }, + pacioCoverageId: { + display: 'PACIO Coverage ID', + type: 'input', + default: env.get('VITE_PACIO_COVERAGE_ID').asString() + }, pacioNewPrescriberId: { display: 'PACIO New Prescriber ID', type: 'input', From 5cb088e290d16c671a9d5cbc4da9a656ffa45ace Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Wed, 7 Jan 2026 18:51:06 -0500 Subject: [PATCH 4/7] fix clear patient issue and run prettier/lint --- src/PrefetchTemplate.js | 13 +- .../RequestDashboard/Communication.jsx | 73 ++++--- .../RequestDashboard/CommunicationsDialog.jsx | 99 ++++----- src/components/RequestDashboard/Home.jsx | 5 +- .../RequestDashboard/SettingsSection.jsx | 202 ++++++++++-------- src/components/SMARTBox/PatientBox.jsx | 2 +- src/util/data.js | 2 +- 7 files changed, 208 insertions(+), 188 deletions(-) diff --git a/src/PrefetchTemplate.js b/src/PrefetchTemplate.js index 573a880..7ee00ca 100644 --- a/src/PrefetchTemplate.js +++ b/src/PrefetchTemplate.js @@ -3,10 +3,9 @@ export class PrefetchTemplate { static generatePrefetchMap(settings = null) { // If no settings provided, use defaults from data.js - const includePharmacy = settings?.includePharmacyInPreFetch ?? - headerDefinitions.includePharmacyInPreFetch.default; - const pharmacyId = settings?.pharmacyId ?? - headerDefinitions.pharmacyId.default; + const includePharmacy = + settings?.includePharmacyInPreFetch ?? headerDefinitions.includePharmacyInPreFetch.default; + const pharmacyId = settings?.pharmacyId ?? headerDefinitions.pharmacyId.default; const prefetchMap = new Map(); @@ -64,7 +63,7 @@ export class PrefetchTemplate { ) { const prefetchMap = PrefetchTemplate.generatePrefetchMap(settings); const paramElementMap = PrefetchTemplate.generateParamElementMap(); - + var resolvedQueries = new Map(); for (var i = 0; i < prefetchKeys.length; i++) { var prefetchKey = prefetchKeys[i]; @@ -73,7 +72,7 @@ export class PrefetchTemplate { // Regex source: https://regexland.com/all-between-specified-characters/ var parametersToFill = query.match(/(?<={{).*?(?=}})/gs); var resolvedQuery = query.slice(); - + if (parametersToFill) { for (var j = 0; j < parametersToFill.length; j++) { var unresolvedParameter = parametersToFill[j]; @@ -135,4 +134,4 @@ export class PrefetchTemplate { getQuery() { return this.query; } -} \ No newline at end of file +} diff --git a/src/components/RequestDashboard/Communication.jsx b/src/components/RequestDashboard/Communication.jsx index ecf490b..05de736 100644 --- a/src/components/RequestDashboard/Communication.jsx +++ b/src/components/RequestDashboard/Communication.jsx @@ -1,45 +1,44 @@ -import { Button, Grid } from "@mui/material"; +import { Button, Grid } from '@mui/material'; import DeleteIcon from '@mui/icons-material/Delete'; import useStyles from './styles'; - const Communication = props => { - const classes = useStyles(); - const { communication, deleteCommunication } = props; + const classes = useStyles(); + const { communication, deleteCommunication } = props; - const convertTimeStamp = (timeStamp) => { - const date = new Date(timeStamp); - return date.toLocaleString(); - }; + const convertTimeStamp = timeStamp => { + const date = new Date(timeStamp); + return date.toLocaleString(); + }; - return ( -
- - - {`ID: ${communication.id}`} - - - {`Received: ${convertTimeStamp(communication.received)}`} - - - - - - {communication.payload[0].contentString} - - -
- ); + return ( +
+ + + {`ID: ${communication.id}`} + + + {`Received: ${convertTimeStamp(communication.received)}`} + + + + + + {communication.payload[0].contentString} + + +
+ ); }; -export default Communication; \ No newline at end of file +export default Communication; diff --git a/src/components/RequestDashboard/CommunicationsDialog.jsx b/src/components/RequestDashboard/CommunicationsDialog.jsx index ba7d7ef..cfe387a 100644 --- a/src/components/RequestDashboard/CommunicationsDialog.jsx +++ b/src/components/RequestDashboard/CommunicationsDialog.jsx @@ -6,7 +6,7 @@ import Badge from '@mui/material/Badge'; import Dialog from '@mui/material/Dialog'; import DialogTitle from '@mui/material/DialogTitle'; import DialogContent from '@mui/material/DialogContent'; -import { Refresh } from '@mui/icons-material' +import { Refresh } from '@mui/icons-material'; import { styled } from '@mui/material/styles'; import Paper from '@mui/material/Paper'; @@ -23,25 +23,23 @@ const CommunicationsDialog = props => { open: false }); - const debugLog = (message) => { + const debugLog = message => { console.log('CommunicationsDialog: ' + message); }; useEffect(() => { // reload on page load and dialog open if (state.initialLoad) { - setState(prevState => ({ ...prevState, initialLoad: false})); + setState(prevState => ({ ...prevState, initialLoad: false })); getCommunications(); } const interval = setInterval(() => { // page load... getCommunications(); - - }, 1000 * 5) // reload every 5 seconds + }, 1000 * 5); // reload every 5 seconds return () => clearInterval(interval); - }); const getCommunications = () => { @@ -56,9 +54,9 @@ const CommunicationsDialog = props => { loadCommunications(bundle); }); } - } + }; - const deleteCommunication = (id) => { + const deleteCommunication = id => { debugLog('deleteCommunication: ' + id); if (id) { state.client.delete(`Communication/${id}`).then(() => { @@ -66,15 +64,15 @@ const CommunicationsDialog = props => { getCommunications(); }); } - } + }; - const loadCommunications = (bundle) => { + const loadCommunications = bundle => { let count = bundle.length; - setState(prevState => ({ ...prevState, communicationCount: count, communications: bundle})); + setState(prevState => ({ ...prevState, communicationCount: count, communications: bundle })); }; const handleClose = () => { - setState(prevState => ({ ...prevState, open: false})); + setState(prevState => ({ ...prevState, open: false })); }; const Item = styled(Paper)(({ theme }) => ({ @@ -82,59 +80,64 @@ const CommunicationsDialog = props => { ...theme.typography.body2, padding: theme.spacing(1), textAlign: 'left', - color: theme.palette.text.secondary, + color: theme.palette.text.secondary })); const renderCommunications = () => { return ( - + {state.communications.map(communication => { return ( - + + + ); })} - + ); - } + }; return ( - { - setState(prevState => ({ ...prevState, open: true, initialLoad: true})); - }} > - - - - - - - - - Communications ({state.communicationCount}) - - - + { + setState(prevState => ({ ...prevState, open: true, initialLoad: true })); + }} + > + + + + + + + + + + Communications ({state.communicationCount}) + + + + - - - - - { renderCommunications() } - + - + {renderCommunications()} + ); }; -export default CommunicationsDialog; \ No newline at end of file +export default CommunicationsDialog; diff --git a/src/components/RequestDashboard/Home.jsx b/src/components/RequestDashboard/Home.jsx index f9267b4..ba322ec 100644 --- a/src/components/RequestDashboard/Home.jsx +++ b/src/components/RequestDashboard/Home.jsx @@ -12,7 +12,6 @@ import PatientSection from './PatientSection'; import SettingsSection from './SettingsSection'; import TasksSection from './TasksSection'; - import { logout } from '../../util/auth'; const Home = props => { @@ -86,9 +85,7 @@ const Home = props => { {section ? ( - +    {token.name}