Skip to content
Merged

Dev #35

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
5f50b9e
add timeout, remove unnecessary logs.
Nov 16, 2022
fb0ae9a
Trailing changes
Dec 8, 2022
adbf0d4
match prefetch to current admin prefetch
kghoreshi Dec 2, 2022
b95e541
minor changes fixing prefetch formatting
kghoreshi Dec 2, 2022
24c30f6
support hydration
kghoreshi Dec 10, 2022
30b4ac7
match prefetch to current admin prefetch
kghoreshi Dec 2, 2022
fcb3688
minor changes fixing prefetch formatting
kghoreshi Dec 2, 2022
34dcad8
Removed indent.
Dec 13, 2022
21507b6
Merge pull request #29 from mcode/rems-283-timeout
smalho01 Dec 16, 2022
315107f
Merge pull request #30 from mcode/hydrate-prefetch
smalho01 Jan 5, 2023
f92ed15
Merge branch 'dev' into prefetch-changes
KeeyanGhoreshi Jan 5, 2023
f552688
Moved timeout parameter to satisfy fetch api
Jan 11, 2023
d9d1acf
Merge pull request #31 from mcode/rems-302-request404
kennyEung Jan 17, 2023
ab1d230
Add a new button to send a NCPDP SCRIPT NewRx message to the PIMS con…
plarocque4 Jan 24, 2023
3934d67
Merge pull request #28 from mcode/prefetch-changes
smalho01 Jan 25, 2023
32e570b
Merge branch 'dev' into 252-ncpdp-script
smalho01 Jan 26, 2023
f775845
Merge pull request #32 from mcode/252-ncpdp-script
smalho01 Jan 26, 2023
c588b4c
Update NCPDP SCRIPT NewRx message to contain the required fields and …
plarocque4 Feb 3, 2023
21f678d
Remove extra logging.
plarocque4 Feb 3, 2023
51296ad
Update the PIMS endpoint.
plarocque4 Feb 9, 2023
5e95bdc
initial integration commit
smalho01 Feb 9, 2023
cf15c63
fixed the reset rems admin button
smalho01 Feb 9, 2023
5bb54b2
Merge pull request #33 from mcode/required-fields
smalho01 Feb 9, 2023
96fe30e
Merge branch 'dev' into etasu-integration
smalho01 Feb 9, 2023
ed1985b
Update RequestBox.js
smalho01 Feb 14, 2023
3ceb230
Merge pull request #34 from mcode/etasu-integration
smalho01 Feb 14, 2023
573118b
Merge branch 'main' into dev
smalho01 Feb 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 19 additions & 69 deletions src/PrefetchTemplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,83 +6,33 @@ export class PrefetchTemplate {

const prefetchMap = new Map();

const COVERAGE_PREFETCH_QUERY = new PrefetchTemplate(
"Coverage?patient={{context.patientId}}");
const PRACTITIONER_PREFETCH = new PrefetchTemplate(
"{{context.userId}}");

const DEVICE_REQUEST_BUNDLE = new PrefetchTemplate(
"DeviceRequest?_id={{context.draftOrders.DeviceRequest.id}}"
+ "&_include=DeviceRequest:patient"
+ "&_include=DeviceRequest:performer"
+ "&_include=DeviceRequest:requester"
+ "&_include=DeviceRequest:device"
+ "&_include:iterate=PractitionerRole:organization"
+ "&_include:iterate=PractitionerRole:practitioner");
const REQUEST_PREFETCH = new PrefetchTemplate(
"MedicationRequest/{{context.medications.MedicationRequest.id}}");
const PATIENT_PREFETCH = new PrefetchTemplate("{{context.patientId}}");

const MEDICATION_REQUEST_BUNDLE = new PrefetchTemplate(
"MedicationRequest?_id={{context.medications.MedicationRequest.id}}"
+ "&_include=MedicationRequest:patient"
+ "&_include=MedicationRequest:intended-dispenser"
+ "&_include=MedicationRequest:requester:PractitionerRole"
+ "&_include=MedicationRequest:medication"
+ "&_include:iterate=PractitionerRole:organization"
+ "&_include:iterate=PractitionerRole:practitioner");

const MEDICATION_DISPENSE_BUNDLE = new PrefetchTemplate(
"MedicationDispense?_id={{context.medications.MedicationDispense.id}}"
+ "&_include=MedicationDispense:patient"
+ "&_include=MedicationDispense:intended-dispenser"
+ "&_include=MedicationDispense:requester:PractitionerRole"
+ "&_include=MedicationDispense:medication"
+ "&_include:iterate=PractitionerRole:organization"
+ "&_include:iterate=PractitionerRole:practitioner");

const NUTRITION_ORDER_BUNDLE = new PrefetchTemplate(
"NutritionOrder?_id={{context.draftOrders.NutritionOrder.id}}"
+ "&_include=NutritionOrder:patient"
+ "&_include=NutritionOrder:provider"
+ "&_include=NutritionOrder:requester"
+ "&_include=PractitionerRole:organization"
+ "&_include=PractitionerRole:practitioner"
+ "&_include=NutritionOrder:encounter"
+ "&_include=Encounter:location");

const SERVICE_REQUEST_BUNDLE = new PrefetchTemplate(
"ServiceRequest?_id={{context.draftOrders.ServiceRequest.id}}"
+ "&_include=ServiceRequest:patient"
+ "&_include=ServiceRequest:performer"
+ "&_include=ServiceRequest:requester"
+ "&_include:iterate=PractitionerRole:organization"
+ "&_include:iterate=PractitionerRole:practitioner");

const APPOINTMENT_BUNDLE = new PrefetchTemplate(
"appointmentBundle",
"Appointment?_id={{context.appointments.Appointment.id}}"
+ "&_include=Appointment:patient"
+ "&_include=Appointment:practitioner:PractitionerRole"
+ "&_include:iterate=PractitionerRole:organization"
+ "&_include:iterate=PractitionerRole:practitioner"
+ "&_include=Appointment:location");

const ENCOUNTER_BUNDLE = new PrefetchTemplate(
"encounterBundle",
"Encounter?_id={{context.encounterId}}"
+ "&_include=Encounter:patient"
+ "&_include=Encounter:service-provider"
+ "&_include=Encounter:practitioner"
+ "&_include=Encounter:location");

prefetchMap.set("Coverage", COVERAGE_PREFETCH_QUERY);
prefetchMap.set("DeviceRequest", DEVICE_REQUEST_BUNDLE);
prefetchMap.set("MedicationRequest", MEDICATION_REQUEST_BUNDLE);
prefetchMap.set("MedicationDispense", MEDICATION_DISPENSE_BUNDLE);
prefetchMap.set("ServiceRequest", SERVICE_REQUEST_BUNDLE);
prefetchMap.set("Encounter", ENCOUNTER_BUNDLE);
// prefetchMap.set("Coverage", COVERAGE_PREFETCH_QUERY);
prefetchMap.set("request", REQUEST_PREFETCH);
prefetchMap.set("practitioner", PRACTITIONER_PREFETCH);
prefetchMap.set("patient", PATIENT_PREFETCH);
// prefetchMap.set("ServiceRequest", SERVICE_REQUEST_BUNDLE);
// prefetchMap.set("Encounter", ENCOUNTER_BUNDLE);

return prefetchMap;
}

static generateParamElementMap() {
const paramElementMap = new Map();
// TODO - this should just be inferred based on context. Or rather
// the instructions from the hook about what context to fill in
// Quite literally, the "context" here refers to the "context" of the
// cds-hook, which as of now is just hard-coded in buildRequest.js
// Rather than do this, which searches the request resource for information,
// the cds-hook should be constructed and then the context used to actually make
// the appropriate requests.
paramElementMap.set('context.userId', ['requester', 'reference'])
paramElementMap.set('context.draftOrders.DeviceRequest.id', ['id']);
paramElementMap.set('context.medications.MedicationRequest.id', ['id']);
paramElementMap.set('context.medications.MedicationDispense.id', ['id']);
Expand Down
99 changes: 88 additions & 11 deletions src/components/RequestBox/RequestBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import FHIR from "fhirclient";
import SMARTBox from "../SMARTBox/SMARTBox";
import PatientBox from "../SMARTBox/PatientBox";
import CheckBox from '../Inputs/CheckBox';
import { defaultValues, shortNameMap } from "../../util/data";
import { types, defaultValues, shortNameMap } from "../../util/data";
import { getAge } from "../../util/fhir";
import buildNewRxRequest from '../../util/buildScript.2017071.js';
import _ from "lodash";
import "./request.css";
import { PrefetchTemplate } from "../../PrefetchTemplate";
Expand Down Expand Up @@ -57,9 +58,15 @@ export default class RequestBox extends Component {
prepPrefetch() {
const preppedResources = new Map();
Object.keys(this.state.prefetchedResources).forEach((resourceKey) => {
const resourceList = this.state.prefetchedResources[resourceKey].map((resource) => {
return resource;
})
let resourceList = []
if(Array.isArray(this.state.prefetchedResources[resourceKey])){
resourceList = this.state.prefetchedResources[resourceKey].map((resource) => {
return resource;
})
} else {
resourceList = this.state.prefetchedResources[resourceKey]
}

preppedResources.set(resourceKey, resourceList);
});
return preppedResources;
Expand Down Expand Up @@ -92,7 +99,7 @@ export default class RequestBox extends Component {
if(!prevState[elementName][key]){
prevState[elementName][key] = [];
}
return {[elementName]: {...prevState[elementName], [key]: [...prevState[elementName][key], text]}};
return {[elementName]: {...prevState[elementName], [key]: text}};
});
};

Expand Down Expand Up @@ -212,11 +219,16 @@ export default class RequestBox extends Component {
var renderedPrefetches = new Map();
requestResources.forEach((resourceList, resourceKey) => {
const renderedList = [];
resourceList.forEach((resource) => {
console.log("Request resources:" + JSON.stringify(requestResources));
console.log("Request key:" + resourceKey);
renderedList.push(this.renderResource(resource))
});
if(Array.isArray(resourceList)){
resourceList.forEach((resource) => {
console.log("Request resources:" + JSON.stringify(requestResources));
console.log("Request key:" + resourceKey);
renderedList.push(this.renderResource(resource))
});
} else {
renderedList.push(this.renderResource(resourceList))
}

renderedPrefetches.set(resourceKey, renderedList);
});
console.log(renderedPrefetches);
Expand Down Expand Up @@ -325,6 +337,64 @@ export default class RequestBox extends Component {
});
}

/**
* Send the NewRxRequestMessage to the Pharmacy Information System (PIMS)
*/
sendRx = (e) => {
console.log("sendRx: " + this.props.pimsUrl);

// build the NewRx Message
var newRx = buildNewRxRequest(this.state.prefetchedResources.patient,
this.state.prefetchedResources.practitioner,
this.state.request);
console.log(newRx);
const serializer = new XMLSerializer();

// send the message to the prescriber
this.props.consoleLog("Sending Rx to PIMS", types.info);
fetch(this.props.pimsUrl, {
method: 'POST',
//mode: 'no-cors',
headers: {
'Accept': 'application/xml',
'Content-Type': 'application/xml'
},
body: serializer.serializeToString(newRx)
})
.then(response => {
console.log("sendRx response: ");
console.log(response);
this.props.consoleLog("Successfully sent Rx to PIMS", types.info);
})
.catch(error => {
console.log("sendRx error: ");
this.props.consoleLog("Server returned error sending Rx to PIMS: ", types.error);
this.props.consoleLog(error.message);
console.log(error);
});

}

resetRemsAdmin = (e) => {
console.log("reset rems admin: " + "localhost:8090/etasu/reset");

fetch("http://localhost:8090/etasu/reset", {
method: 'POST',
})
.then(response => {
console.log("Reset rems admin etasu: ");
console.log(response);
this.props.consoleLog("Successfully reset rems admin etasu", types.info);
})
.catch(error => {
console.log("Reset rems admin error: ");
this.props.consoleLog("Server returned error when resetting rems admin etasu: ", types.error);
this.props.consoleLog(error.message);
console.log(error);
});

}

isOrderNotSelected() {
return Object.keys(this.state.request).length === 0;
}
Expand All @@ -341,6 +411,7 @@ export default class RequestBox extends Component {
}
const disableSendToCRD = this.isOrderNotSelected() || this.props.loading ;
const disableLaunchDTR = this.isOrderNotSelected() && Object.keys(this.state.response).length === 0;
const disableSendRx = this.isOrderNotSelected() || this.props.loading;
return (
<div>
<div className="request">
Expand Down Expand Up @@ -400,11 +471,17 @@ export default class RequestBox extends Component {
<div id="fse" className={"spinner " + (this.props.loading ? "visible" : "invisible")}>
<div className="ui active right inline loader"></div>
</div>
<button className={"submit-btn btn btn-class "} onClick={this.sendRx} disabled={disableSendRx}>
Send Rx to PIMS
</button>
<button className={"submit-btn btn btn-class "} onClick={this.relaunch} disabled={disableLaunchDTR}>
Relaunch DTR
</button>
<button className={"submit-btn btn btn-class "} onClick={this.submit} disabled={disableSendToCRD}>
Submit to CRD
Submit to REMS-Admin
</button>
<button className={"submit-btn btn btn-class "} onClick={this.resetRemsAdmin} disabled={disableSendToCRD}>
Reset REMS-Admin Database
</button>
</div>
);
Expand Down
Loading