1334 lines
61 KiB
Plaintext
1334 lines
61 KiB
Plaintext
maintenance:
|
|
|
|
title: Dose Range Check for Single, Average, and Total Daily Doses;;
|
|
mlmname: STD_DOSAGE;;
|
|
arden: version 2.5;;
|
|
version: 18.4;;
|
|
institution: Allscripts, Standard MLM;;
|
|
author: Allscripts Healthcare Solutions, Inc.;;
|
|
specialist: ;;
|
|
date: 2018-10-26;;
|
|
validation: testing;;
|
|
|
|
/* P r o p r i e t a r y N o t i c e */
|
|
/* Unpublished (c) 2013 - 2018 Allscripts Healthcare, LLC. and/or its affiliates. All Rights Reserved.
|
|
|
|
P r o p r i e t a r y N o t i c e: This software has been provided pursuant to a License Agreement, with
|
|
Allscripts Healthcare, LLC. and/or its affiliates, containing restrictions on its use. This software contains
|
|
valuable trade secrets and proprietary information of Allscripts Healthcare, LLC. and/or its affiliates and is
|
|
protected by trade secret and copyright law. This software may not be copied or distributed in any form or medium,
|
|
disclosed to any third parties, or used in any manner not provided for in said License Agreement except with prior
|
|
written authorization from Allscripts Healthcare, LLC. and/or its affiliates. Notice to U.S. Government Users:
|
|
This software is {{{SINGLE-QUOTE}}}Commercial Computer Software{{{SINGLE-QUOTE}}}.
|
|
|
|
All product names are the trademarks or registered trademarks of Allscripts Healthcare, LLC. and/or its affiliates.
|
|
*/
|
|
/* P r o p r i e t a r y N o t i c e */
|
|
|
|
library:
|
|
purpose: Provides Dosage Range Checking using the data from the Item-Catalog or Multum or both.
|
|
Also provides Multum Frequency checking and Contraindication warnings.
|
|
;;
|
|
explanation: The Dosage Range MLM uses the following BUSINESS RULES and CONFIGURATIONS:
|
|
|
|
1. This MLM is triggered for the following:
|
|
* Medication orders from Sunrise Clinical Manager or Sunrise Medication Manager
|
|
* Medication Outpatient orders from Order Reconciliation Manager
|
|
* Prescriptions from Prescription Writer
|
|
|
|
A medication entered as a Historical Session Type Order can also be checked,
|
|
when this option is turned on.
|
|
|
|
2. ITEM-CATALOG: When a dose range has been specified in the medication{{{SINGLE-QUOTE}}}s Item-Catalog,
|
|
all three criteria will be checked to determine if the specified dose is appropriate.
|
|
* Patient body surface area (BSA)
|
|
* Patient weight
|
|
* Patient age
|
|
|
|
3. MULTUM: When data are available from the Multum SQL Database (_MT),
|
|
the following checking can be done:
|
|
* Contraindications for the medication and the patient{{{SINGLE-QUOTE}}}s condition
|
|
* Frequency Interval check to determine if a medication is given too frequently
|
|
for the patient{{{SINGLE-QUOTE}}}s condition
|
|
* Dosage Range for the following criteria:
|
|
(a) Age
|
|
(b) Weight
|
|
(c) Gender
|
|
(d) Liver Disease
|
|
(e) Creatinine Clearance
|
|
(f) Hemo Dialysis
|
|
(g) Peritoneal Dialysis.
|
|
|
|
4. For dosage range checking, the MLM alerts if the Single, Total Average, or Total Daily
|
|
dose is outside of the recommended dose-ranges for the patient.
|
|
For some orders, the 24-Hour Total Dose is checked rather than the Total Daily Dose.
|
|
|
|
5. PRESCRIPTIONS and the HOME MEDICATIONS in Prescription Writer are checked using the
|
|
DOSE field, not the dose in the Instructions field.
|
|
|
|
6. MEDICATION ORDERS and OUTPATIENT ORDERS are checked at the ORDERED-DOSE, not the DOSE-PER.
|
|
* DOSE-PER is the dose in xxx/kg or xxx/m2 via the Dose Calculation dialog box.
|
|
* ORDERED-DOSE is the dose that will be sent to the Pharmacy system.
|
|
It can be calculated by multiplying Dose-Per times the patient{{{SINGLE-QUOTE}}}s weight or BSA.
|
|
Or it can be entered directly by user on Order Entry form without using the
|
|
Dose Calculation dialog.
|
|
|
|
7. IV-ADDITIVES are checked. However, drip-rate for the IV-additive is not considered
|
|
when doing dosage range checks; only the total amount in the IV-solution is checked.
|
|
NOTE: This MLM does not use Base Solution, Base Solution UOM, IV Rate,
|
|
or IV Rate UOM fields to perform Dose Range checking.
|
|
|
|
8. COMPLEX ORDERS are checked. The 24-Hour Total Dose is checked rather than the
|
|
Total Daily Dose and the Total Average Dose.
|
|
|
|
9. UNIT OF MEASURE (UOM) CONVERSIONS: The MEDICATION DOSE and its UOM are
|
|
converted to the DOSAGE RANGES UOM before the dose range is checked.
|
|
The MLM will use the SXAUnitOfMeasureConversion table to find an equivalent
|
|
UOM or a UOM that can be converted to, such as Gram to Mg/Kg.
|
|
When a UOM conversion occurs, the MLM retains the significant digits
|
|
of the medication{{{SINGLE-QUOTE}}}s dose. For example: 2000.5 MG is 2.0005 Grams.
|
|
If the MLM is unable to convert the medication{{{SINGLE-QUOTE}}}s UOM, a conversion error alert will be
|
|
generated, unless it is turned off.
|
|
|
|
10. ROUTE CONVERSIONS: When the MEDICATION ROUTE does not match the DOSAGE RANGE ROUTE,
|
|
the MLM will attempt to convert the route to the DOSAGE RANGE ROUTE using the
|
|
SXAMultumRouteConversion table. If the MLM is not able to convert the route,
|
|
an error alert will be generated stating the route is inapplicable or unrecognized,
|
|
unless the error message is turned off.
|
|
|
|
11. A dosage range alert will be generated when any medication dose is outside of the recommended
|
|
dose for: (1) single, (2) total average, (3) total daily dose or (4) 24-hour total.
|
|
When data are available, ALL dose ranges that are applicable for the patient{{{SINGLE-QUOTE}}}s conditions
|
|
(Age, BSA, Weight, Gender, Liver Disease, Creatinine Clearance, Hemo Dialysis,
|
|
Peritoneal Dialysis) will be checked.
|
|
|
|
A. SINGLE dose range will be checked first.
|
|
|
|
B. TOTAL AVERAGE dose will be checked second.
|
|
Total Average dose is calculated by converting medication frequency
|
|
(BID, Q18H, etc.) into number of times per day medication can be given
|
|
and then multiplying this number by single-dose.
|
|
For example, 100 mg Q18H (every 18 hours) has a Total Average dose of 133.3 mg
|
|
[100 mg single-dose x (24hr/18hr) times per day].
|
|
|
|
C. TOTAL DAILY dose will be checked third.
|
|
Total Daily dose is calculated by converting medication frequency
|
|
(BID, Q18H, etc.) into number of times per day medication can be given,
|
|
and then ROUNDING UP the number, and then multiplying rounded number by
|
|
single-dose. For example, 100 mg Q18H (every 18 hours) has a total daily dose
|
|
of 200 mg [100 mg single-dose x RoundUp (24hr/18hr) times per day].
|
|
|
|
D. 24-HOUR TOTAL DOSE can be used instead of the Average and Total Daily Doses.
|
|
24-Hour Total dose is calculated by:
|
|
(1) Estimating the dose administration times based on the medication frequency,
|
|
(2) Sorting their single doses into 24-hour intervals, and
|
|
(3) Summing the doses for the Total or the Average.
|
|
|
|
12. Patient AGE is required for MULTUM dose range checking.
|
|
AGE is optional for the ITEM-CATALOG dose range checking.
|
|
Age is calculated as follows:
|
|
Order{{{SINGLE-QUOTE}}}s SignificantDtm - Patient Birthday
|
|
Prescription{{{SINGLE-QUOTE}}}s StartDate - Patient Birthday
|
|
* If the patient has a missing BIRTH YEAR, then any dosage range check requiring
|
|
an AGE will not be done.
|
|
* If the patient has a missing BIRTH MONTH or BIRTH DAY, then any dosage range check requiring
|
|
an AGE will not be done if patient is less than 4 years old (based on the birth year).
|
|
* If the patient has a missing BIRTH TIME, then any dosage range checking requiring
|
|
an AGE in HOURS will not be done if the patient is less than 4 days old.
|
|
|
|
13. Patient HEIGHT, WEIGHT, SERUM CREATININE, and CREATININE CLEARANCE must be current in order
|
|
to use them for dosage range checking.
|
|
* Height and Weight are needed from some of the dosage range checks.
|
|
If the Height or Weight is needed, a missing or not current error alert will be generated,
|
|
unless they are turned off.
|
|
* If a directly measured Creatinine Clearance is not current, it is not used for
|
|
Multum dosage range checking.
|
|
* If Serum Creatinine is not current, the estimated Creatinine Clearance is not calculated
|
|
for Multum dosage range checking.
|
|
* Set the flags or environment profile for these data to indicate how many days old the data
|
|
can be for use in dose range checking.
|
|
|
|
14. Patient LIVER DISEASE, HEMODIALYSIS, and PERITONEAL DIALYSIS data
|
|
are used for Multum Dosage Range checking.
|
|
The data are retrieved from the data that is stored in the CV3PhysicalNoteDeclaration table.
|
|
This data is stored in the table through the PATIENT DRUG PROFILE dialog
|
|
or can be inserted by a clinical document, such as a Structured Note.
|
|
|
|
15. The ABSENCE OF AN ALERT can mean one of the following:
|
|
* The all the doses were within the acceptable range.
|
|
* The appropriate criteria could not be found; so the Dosage could not
|
|
be checked.
|
|
|
|
16. This MLM stores data for ALERT OUTCOMES TRACKING and for ALERT ABSTRACTS.
|
|
The Alert Abstract stores data for Orders, Prescriptions, and Home Medications.
|
|
It indicates if the alert is for a Contraindication, Frequency Interval too Short,
|
|
Outside Usual Dose Range, or a Data Issue.
|
|
|
|
17. This MLM displays alerts in a HTML Format.
|
|
It uses a Cascading Style Sheet (CSS) located in the STD_Func_Dosage_CSS MLM.
|
|
Enterprises may modify the CSS to change the font, font size, and colors in the alert message.
|
|
|
|
|
|
*****************************
|
|
* CONFIGURATION INFORMATION *
|
|
*****************************
|
|
1. There are several MLM flags to review and set in this MLM.
|
|
Please review the Asterisked Area in the Data Slot for these flags.
|
|
Details comments appear in GREEN above each flags describing its use and option settings.
|
|
|
|
2. There are three Environment Profiles that are used by this MLM.
|
|
Please review them in the Configuration Tool > Miscellaneous > Environment Profile
|
|
* CDS > Expert Drug Profile > Serum_Creatinine_Result_Name
|
|
* CDS > Expert Drug Profile > Valid_Serum_Creatinine_Days
|
|
* ClientInfo > BSAFormula
|
|
|
|
3. The enterprise can turn on/off the following using the
|
|
"Set Location for Dose Range Checking Data for MLM" field in the
|
|
"Dose Range Data and Contraindications" dialog of Multum Data Configuration Dictionary.
|
|
* Item Catalog Dose Range for Orders
|
|
* Item Catalog Dose Range for Prescriptions
|
|
* Multum Dose Range for Orders
|
|
* Multum Dose Range for Prescriptions
|
|
|
|
4. The Multum Dosage Range data is located in Multum SQL database (_MT).
|
|
The enterprise can customize the Multum dosage range data through the
|
|
"Dose Range Data and Contraindications" dialog in Multum Data Configuration Dictionary.
|
|
The enterprise may modify a dosage range row by:
|
|
* Excluding it
|
|
* Increasing/Decreasing the Enterprise Low/High data
|
|
* Allowing Override Rights
|
|
* Setting its hard-stops
|
|
* Turning off the display of the recommendation string
|
|
The enterprise may modify a contraindication row by:
|
|
* Excluding it
|
|
The entire criteria type (gender, liver disease, renal condition, or weight)
|
|
* May be turned off, if needed
|
|
When enterprise-customized dosage range is available, it is given preference
|
|
over the Multum _MT data.
|
|
|
|
5. The Item-Catalog must be mapped to a DOSE RANGE GROUP to provide Multum Dosage Range Checking.
|
|
Multum Dose Range Groups are used to consolidate dosage ranges for all Multum MMDC codes
|
|
that have the same dose ranges for the same Multum DNum.
|
|
Some of the Multum DNums have only one Multum Dose Range Group,
|
|
but most of the Multum DNums have more than one Multum Dose Range Group.
|
|
The Item-Catalog is mapped to Multum at the DNum Level rather than at the MMDC level.
|
|
If there is only one Dose Range Group for the Item-Catalog{{{SINGLE-QUOTE}}}s DNum,
|
|
then it can be auto-mapped and save.
|
|
If there is more than one Dose Range Group for the Item-Catalog{{{SINGLE-QUOTE}}}s DNum,
|
|
then Multum Dose Range Group must be manually mapped and saved.
|
|
Dose Range Group mapping can be done in the Drug Mapping Panel of the Item-Catalog
|
|
or in the Dose Range Group Mapping tab of the Drug Mapping Tool.
|
|
|
|
6. FREQUENCY DICTIONARY.
|
|
The frequency "Name" must be mapped to the
|
|
Multum frequency code in the "Drug Catalog Key" column.
|
|
When the Dictionary is not mapped to a Multum frequency code, the MLM will generate
|
|
an Unmapped Frequency error alert for orders, unless it is turned off.
|
|
In addition, the frequency "Name" must have a Frequency Definition.
|
|
The Frequency Definition is used to calculate the Total Daily, Total Average,
|
|
or 24-Hour Total Dose. A Frequency Definition of {{{SINGLE-QUOTE}}}None{{{SINGLE-QUOTE}}} will be interpreted to be
|
|
one dose for the Total Daily, Total Average, or 24-Hour Total Dose.
|
|
|
|
7. GENDER DICTIONARY.
|
|
The gender "Dictionary Code" must be mapped to an "Internal Code" code of
|
|
{{{SINGLE-QUOTE}}}F{{{SINGLE-QUOTE}}}, {{{SINGLE-QUOTE}}}M{{{SINGLE-QUOTE}}}, {{{SINGLE-QUOTE}}}O{{{SINGLE-QUOTE}}}, or {{{SINGLE-QUOTE}}}U{{{SINGLE-QUOTE}}}.
|
|
When the Dictionary is not mapped, the MLM will generate an Unmapped Gender error alert,
|
|
unless it is turned off. Note that mapping to an {{{SINGLE-QUOTE}}}O{{{SINGLE-QUOTE}}} or {{{SINGLE-QUOTE}}}U{{{SINGLE-QUOTE}}} Internal Code will still
|
|
result in a warning that the MLM can only check the dose range for females and males.
|
|
|
|
8. ROUTE DICTIONARY.
|
|
The route "Dictionary Code" must be mapped to the
|
|
Multum route code in the "Drug Catalog Key" column.
|
|
When the Dictionary is not mapped, the MLM will generate an Unmapped Route error alert,
|
|
unless it is turned off.
|
|
|
|
9. UNIT OF MEASURE (UOM) DICTIONARY.
|
|
The UOM "Dictionary Code" must be mapped to the
|
|
Multum UOM code in the "Drug Catalog Key" column.
|
|
When the Dictionary is not mapped, the MLM will generate an Unmapped UOM error alert,
|
|
unless it is turned off. In addition, the "Dictionary Code" must have a "Core UOM".
|
|
Dosage Range checking in in the Item-Catalog requires the following "Core UOM":
|
|
* BSA: M2
|
|
* Weight: kg, g, lb, oz
|
|
* Age: year, month, week, day
|
|
* Frequency Times: s, min, hr, day, week, month, year
|
|
|
|
10. ITEM-CATALOG{{{SINGLE-QUOTE}}}s DOSAGE RANGE PANEL.
|
|
The Unit of Measure dictionary is used to populate the data in this panel.
|
|
When the MLM checks dose-ranges, only "Criteria Unit" and "Dosage Per-Wt-or-M2" fields
|
|
are converted from facility-defined UOM (Dictionary Code) to System-defined "Core UOM";
|
|
the "Dosage Unit" is not converted.
|
|
|
|
11. ORDER FORM SETUP.
|
|
Ensure that the following fields are marked as required on the order form:
|
|
UOM, OrderRouteCode, and DosageLow and DoseCalc (whichever used).
|
|
If Frequency appears on the order form, mark it as required
|
|
when the user is expected to enter a frequency.
|
|
Medication Orders will receive a missing data alert when the Dose, UOM, Route, or Frequency
|
|
is missing, unless they are turned-off.
|
|
Prescriptions and Home Medications will NOT receive missing data alerts when the
|
|
Dose, UOM, Route, or Frequency are missing because the user is warned of this same information
|
|
through the Significant Data stars and message in Prescription Writer.
|
|
|
|
12. SYS_CALC_BSA MLM.
|
|
This MLM calculates the Body Surface Area (BSA) for Dosage Range MLMs.
|
|
It has two BSA formulas. If patient is 18.0 years or younger, Pediatric BSA formula is used.
|
|
If patient is older than 18.0 years, Standard BSA formula is used.
|
|
If age of patient cannot be determined due to missing birth year,
|
|
facility{{{SINGLE-QUOTE}}}s preference (standard or pediatric) in the enterprise profile BSAFormula
|
|
will be used to select BSA formula.
|
|
Should facility{{{SINGLE-QUOTE}}}s preference be needed and BSAFormula has not been set,
|
|
then Standard BSA formula will be used.
|
|
In addition, calculated BSA value is rounded to two decimal places.
|
|
|
|
13. STD_FUNC_DOSAGE_BASIS MLM.
|
|
When a facility adds codes to the CALCULATION OPTION Dictionary, dosage range checking
|
|
will NOT automatically adjust for any codes that use IDEAL or ADJUSTED weights in them.
|
|
You must manually add the codes in the STD_FUNC_DOSAGE_BASIS MLM.
|
|
If the MLM is not changed, then the dosage range checking that require a weight will be
|
|
done with the patient{{{SINGLE-QUOTE}}}s actual weight.
|
|
|
|
|
|
Change History:
|
|
09.30.2019 TMS Updated alert to require reason when alert presented to user not in physician/physician extender
|
|
group. CSR 37977
|
|
|
|
;;
|
|
|
|
keywords: single dose; average daily dose; total daily dose; multum; dosage range;;
|
|
|
|
citations:
|
|
{{+B}}Development{{-B}}: Drug information provided by Cerner Multum, Inc. Drug information can be customized and configured by local facility.
|
|
{{+B}}Funding{{-B}}: Cerner Multum, Inc.
|
|
{{+B}}Citations{{-B}}: None supplied by Cerner Multum, Inc.
|
|
|
|
{{+B}}Release{{-B}}: VantageRx Multum Database
|
|
;;
|
|
|
|
knowledge:
|
|
|
|
type: data-driven;;
|
|
data:
|
|
standard_libs := MLM {{{SINGLE-QUOTE}}}std_include_libs{{{SINGLE-QUOTE}}};
|
|
include standard_libs;
|
|
using "SCM.CDS.Core";
|
|
using namespace "CDS";
|
|
|
|
// include common data structures
|
|
std_dosage_includes := MLM {{{SINGLE-QUOTE}}}std_func_dosage_includes{{{SINGLE-QUOTE}}};
|
|
include std_dosage_includes;
|
|
|
|
/****************Make Changes To Spelling And Flags In This Section**************/
|
|
/* Set to true if logging is needed.*/
|
|
log_execution_info := false;
|
|
show_Debug_statements := false;
|
|
|
|
/* Set the text for the variable below to indicate whether to send the message */
|
|
/* or not. */
|
|
send_alert := "DoNotSend";
|
|
|
|
// The SYNC_ALERT_DIALOG flag controls the alert override, acknowledgement,
|
|
// comment, and document requirements in the Synchronous Alert Detail dialog.
|
|
// The variable is used to set the ALERT_DIALOG_SETTINGS for the synchronous alert.
|
|
// The following phrases must be placed in a single string:
|
|
// "No Override Allowed", "Must Acknowledge", "If Acknowledged",
|
|
// "Must Comment", "Must Document", "Conditionally Document", "Default", ""
|
|
// Example: "Must Acknowledge, Must Document"
|
|
// sync_alert_dialog := "";
|
|
|
|
// The ASYNC_ALERT_DIALOG flag controls the comment and document requirements when
|
|
// the alert is acknowledged in the Asynchronous Alert Detail dialog. The variable
|
|
// is used to set the ASYNC_ALERT_DIALOG_SETTINGS for the asynchronous alert.
|
|
// The following phrases must be placed in a single string:
|
|
// "If Acknowledged", "Must Comment",
|
|
// "Must Document", "Conditionally Document", "Default", ""
|
|
// Example: "If Acknowledged, Conditionally Document"
|
|
async_alert_dialog := "";
|
|
|
|
// If a document can be attached to the alert, specify its name within the quotes.
|
|
// Example: "Alert Override Document"
|
|
alert_override_document_name := "";
|
|
|
|
// If you are using "Conditionally Document" for one of the alert dialog settings,
|
|
// specify the phrases that can make the document mandatory.
|
|
// Put quotes around each phrase. Put them in a list using parentheses and commas.
|
|
// Example: ("Using different protocol", "Other Reason")
|
|
document_conditional_text_list := ();
|
|
|
|
// If you are using a User Defined Data Dictionary (UDDD), specify its name within
|
|
// the quotes.
|
|
// Example: "My Restricted Dictionary"
|
|
// UDDD_dictionary_name := "";
|
|
|
|
// If you are using UDDD, specify if is a restricted dictionary or not.
|
|
// Selections are: TRUE, FALSE
|
|
// UDDD_is_restricted := FALSE;
|
|
|
|
// Set this flag to true to issue an alert if patient age data is missing
|
|
alert_if_patient_age_is_missing := TRUE;
|
|
|
|
// Set this flag to true to issue an alert if patient gender data is missing
|
|
alert_if_patient_gender_is_missing := TRUE;
|
|
|
|
// Set this flag to true to issue an alert if patient height data is missing
|
|
// and the height is needed for a BSA calculation to check a BSA-based
|
|
// dosage range.
|
|
alert_if_patient_height_is_missing := TRUE;
|
|
|
|
// Set this flag to true to issue an alert if patient weight data is missing
|
|
alert_if_patient_weight_is_missing := TRUE;
|
|
|
|
// Set this flag to true to issue an alert if the medication{{{SINGLE-QUOTE}}}s route is missing
|
|
alert_if_route_is_missing := TRUE;
|
|
|
|
// Set this flag to true to issue an alert if the medication{{{SINGLE-QUOTE}}}s
|
|
// unit of measure (UOM) cannot be checked due to UOM conversion issues.
|
|
alert_if_UOM_conversion_issue := TRUE;
|
|
|
|
// Set this flag to true to issue an alert if the medication{{{SINGLE-QUOTE}}}s
|
|
// dose range cannot be checked due to a missing dose UOM.
|
|
alert_if_UOM_is_missing := TRUE;
|
|
|
|
// This is the Item-Catalog name used in an alert column
|
|
// for the "Usual Dose Range (Catalog)".
|
|
column_catalog_name := "(Catalog)";
|
|
|
|
// This is the Item-Catalog name used in an alert column
|
|
// for the "Usual Dose Range (Multum)".
|
|
column_Multum_name := "(Multum)";
|
|
|
|
// This flag is used to determine if a user should be warned
|
|
// when a DNUM-Level prescription cannot be checked for
|
|
// Multum dose range
|
|
// due to ambiguity.
|
|
// This occurs when there are too many
|
|
// Dose Range Group Names
|
|
// for the medication{{{SINGLE-QUOTE}}}s DNUM.
|
|
// TRUE = Alert will be displayed. This is the default setting.
|
|
// FALSE = Alert will not be displayed.
|
|
alert_if_cannot_check_DNUM_Rx_to_Multum := TRUE;
|
|
|
|
// This flag is used to determine if a user should be warned
|
|
// when a prescription cannot be checked for
|
|
// ITEM-CATALOG dose range due to ambiguity.
|
|
// This occurs when there are Item-Catalogs with the same
|
|
// DNUM that do not have a Dose Range Group defined
|
|
// or an MMDC number that can resolve the ambiguity.
|
|
// TRUE = Alert will be displayed.
|
|
// FALSE = Alert will not be displayed. This is the default setting.
|
|
alert_if_cannot_check_Rx_to_IC := FALSE;
|
|
|
|
// This flag is used to determine if a user should be warned
|
|
// when an unrecognized route cannot be checked for dose range.
|
|
// This occurs when a more specific route is needed,
|
|
// but a general route is auto-filled or selected.
|
|
// For example a specific route of Subcutaneous is needed
|
|
// but the route was auto-filled for a general route of Injectable.
|
|
// TRUE = Alert will be displayed. This is the default setting.
|
|
// FALSE = Alert will not be displayed.
|
|
alert_if_unrecognized_route := TRUE;
|
|
|
|
// This flag is used to list Multum RouteIDs from the DRC_Nomenclature
|
|
// table that are too general to be useful for most dose range checking.
|
|
// If the MLM can find a dose range that matches the route in this list,
|
|
// the route will be used to check the medication. But if the MLM
|
|
// cannot find a match, an unrecognized route warning maybe displayed.
|
|
unrecognized_route_list := (
|
|
2408, // compounding
|
|
2409 // injectable
|
|
);
|
|
|
|
// Set this flag to true to issue an alert if the route for
|
|
// an ORDER is not applicable for the medication.
|
|
alert_if_inapplicable_route_for_orders := TRUE;
|
|
|
|
// Set this flag to true to issue an alert if the route for
|
|
// a PRESCRIPTION is not applicable for the medication.
|
|
alert_if_inapplicable_route_for_rx := TRUE;
|
|
|
|
// Set this flag to a list of strings to indicate which
|
|
// kinds of unmapped data should be alerted about.
|
|
// "dose" {{{SINGLE-QUOTE}}} alerts about an unmapped drug
|
|
// "dose range group" {{{SINGLE-QUOTE}}} alerts about an unmapped dose range group
|
|
// "gender" {{{SINGLE-QUOTE}}} alerts about an unmapped gender
|
|
// "frequency" {{{SINGLE-QUOTE}}} alerts about an unmapped frequency
|
|
// "route"- alerts about an unmapped route
|
|
// "uom" {{{SINGLE-QUOTE}}} alerts about an unmapped unit of measure
|
|
// The default is to alert about all unmapped data.
|
|
// To turn off the alert for a specific kind unmapped data
|
|
// such as unmapped route, remove its string from the list.
|
|
// To totally turn off unmapped alerts, set the flag to an empty list ().
|
|
alert_if_unmapped_data := ("dose", "dose range group", "gender",
|
|
"frequency", "route", "uom");
|
|
|
|
// List the medication{{{SINGLE-QUOTE}}}s frequencies in the Frequency Dictionary that are
|
|
// intentionally unmapped because Multum Frequency Codes do not exist from them.
|
|
// Unmapped Frequency alerts will not occur for any of the frequencies in this list.
|
|
intentionally_unmapped_frequency_list := ("<Continuous>", "<Event-Based>",
|
|
"<Multiple>", "<User Schedule>", "<Variable Interval>", "q shift");
|
|
|
|
/* Set this flag to true to issue an alert when Average total exists, */
|
|
/* but cannot be accurately calculated due to irregular schedule. */
|
|
show_irregular_message := TRUE;
|
|
|
|
/* Set this flag to true to issue an alert when Average total exists, */
|
|
/* but cannot be accurately calculated due to a <User Schedule> Weekly schedule. */
|
|
show_user_scheduled_weekly_message := TRUE;
|
|
|
|
/* Set this flag to true to issue an alert when the MLM cannot check */
|
|
/* Dosage Range for orders with a duration under 24 hours */
|
|
show_under_24_hour_message := TRUE;
|
|
|
|
/* Set this flag to true to issue an alert when the MLM cannot check */
|
|
/* Dosage Range for orders that have a shift based frequency. The message */
|
|
/* will only be displayed for complex order types or regular orders using */
|
|
/* the SUMMED calculation method. */
|
|
show_has_shift_frequency_message := TRUE;
|
|
|
|
// To set the Serum Creatinine result name,
|
|
// edit the following environment profile:
|
|
// CDS/ExpertDrugProfile/SerumCreatinineResultName
|
|
// To set the Creatinine Clearance result name, set the flag below.
|
|
// This name must match the Order Item-Catalog name for Creatinine Clearance.
|
|
Creatinine_Clearance_Result_name := "Creatinine Clearance";
|
|
|
|
// To set the Valid Creatinine Clearance Days,
|
|
// edit the following environment profile:
|
|
// CDS/ExpertDrugProfile/ValidSerumCreatinineDays
|
|
// To set the number of days the Creatinine Clearance
|
|
// is considered valid for use in Dosage Range checking,
|
|
// set the flag below indicating the number of days.
|
|
valid_creatinine_clearance_days := 7;
|
|
|
|
// Set the name of the Estimated Creatinine Clearance formula
|
|
// that should be used for dosage range checking.
|
|
// This name is passed to the SYS_CALC_EST_CRCL MLM to
|
|
// calculate the Estimated Creatinine Clearance.
|
|
// The choices are: "Cockcroft-Gault" or "Jelliffe"
|
|
EstCrCl_equation_preference := "Cockcroft-Gault";
|
|
|
|
// Indicate if the BSA should be used in the Jelliffe
|
|
// calculation for Estimated Creatinine Clearance.
|
|
// This name is passed to the SYS_CALC_EST_CRCL MLM to
|
|
// calculate the Estimated Creatinine Clearance.
|
|
// The choices are: TRUE = use BSA, FALSE = do not use BSA.
|
|
EstCrC_calculate_with_BSA_preference := false;
|
|
|
|
// This flag uses a list of objects to determine the number of days
|
|
// a HEIGHT is considered valid for a patient age range.
|
|
// An empty list () means the flag is not used, and the patient{{{SINGLE-QUOTE}}}s
|
|
// most recent height will be used regardless of how old it is.
|
|
// The object is called Validity_Duration and has two values:
|
|
// * First is the number of days a height is considers valid.
|
|
// * Second is the upper patient age range in days, weeks, or years.
|
|
// Note: Do not use months to set these two values.
|
|
// The objects are sorted using the upper patient age range.
|
|
// The lower patient age range is inferred by the previous
|
|
// objects{{{SINGLE-QUOTE}}} upper patient age range.
|
|
// For example:
|
|
// (new Validity_Duration with 2 days, 28 days),
|
|
// (new Validity_Duration with 7 days, 90 days),
|
|
// means HEIGHT can be up to
|
|
// 2 days old for a patient that is >= 0 days and < 28 days old.
|
|
// 7 days old for a patient that is >= 28 days and < 90 days old.
|
|
// You can add as many objects as you need.
|
|
// Objects can listed in any sequence, since they are sorted before use.
|
|
|
|
valid_height_days_for_age :=
|
|
(new Validity_Duration with 2 days, 28 days),
|
|
(new Validity_Duration with 7 days, 90 days),
|
|
(new Validity_Duration with 15 days, 180 days),
|
|
(new Validity_Duration with 30 days, 1 year),
|
|
(new Validity_Duration with 45 days, 2 years),
|
|
(new Validity_Duration with 60 days, 12 years),
|
|
(new Validity_Duration with 90 days, 18 years),
|
|
(new Validity_Duration with 365 days, 150 years);
|
|
|
|
// This flag uses a list of objects to determine the number of days
|
|
// a WEIGHT is considered valid for a patient age range.
|
|
// An empty list () means the flag is not used, and the patient{{{SINGLE-QUOTE}}}s
|
|
// most recent weight will be used regardless of how old it is.
|
|
// The object is called Validity_Duration and has two values:
|
|
// * First is the number of days a weight is considers valid.
|
|
// * Second is the upper patient age range in days, weeks, or years.
|
|
// Note: Do NOT use months to set these two values.
|
|
// The objects are sorted using the upper patient age range.
|
|
// The lower patient age range is inferred by the previous
|
|
// objects{{{SINGLE-QUOTE}}} upper patient age range.
|
|
// For example:
|
|
// (new Validity_Duration with 2 days, 28 days),
|
|
// (new Validity_Duration with 7 days, 90 days),
|
|
// means WEIGHT can be up to
|
|
// 2 days old for a patient that is >= 0 days and < 28 days old.
|
|
// 7 days old for a patient that is >= 28 days and < 90 days old.
|
|
// You can add as many objects as you need.
|
|
// Objects can listed in any sequence, since they are sorted before use.
|
|
|
|
valid_weight_days_for_age :=
|
|
(new Validity_Duration with 2 days, 28 days),
|
|
(new Validity_Duration with 7 days, 90 days),
|
|
(new Validity_Duration with 15 days, 180 days),
|
|
(new Validity_Duration with 30 days, 150 years);
|
|
|
|
/* Change this limit if time off set is too small or large */
|
|
// How Much Time can the Start and Stop DTMs be off by
|
|
// before they affect Dosage-Range Checks for Complex Orders?
|
|
// Change the number in front of the keyword MINUTES to change the number of minutes.
|
|
// If you need to change interval to DAYS, change the number and the keyword to DAYS.
|
|
time_offset_limit := 15 MINUTES;
|
|
|
|
fire_on_UserCPOE := ("MD","DO","DDS","DPM","PA","PA-C","CRNP","IT");
|
|
fire_on_User := ("RN","RPh","US");
|
|
|
|
/* Get the current user{{{SINGLE-QUOTE}}}s occupation*/
|
|
(user_id,userguid) :=read last {UserInfo: idcode, guid};
|
|
|
|
UserCode, OrderRole := read last
|
|
{"Select occupationcode, orderroletype "
|
|
||" From cv3user with (nolock) "
|
|
||" Where Guid = " || SQL(userguid) };
|
|
|
|
|
|
|
|
If usercode in fire_on_UserCPOE then
|
|
sync_alert_dialog:= "";
|
|
UDDD_dictionary_name := "";
|
|
UDDD_is_restricted := FALSE;
|
|
continue_processing := true;
|
|
elseif usercode in fire_on_User then
|
|
sync_alert_dialog:= "Must Comment";
|
|
UDDD_dictionary_name := "AlertAckComment";
|
|
UDDD_is_restricted := TRUE;
|
|
continue_processing := true;
|
|
else continue_processing := false;
|
|
endif;
|
|
|
|
/* Change the message within the quotes if a different short-message is needed.*/
|
|
dosage_alert := destination { Alert } WITH
|
|
[alert_type := "Warning",
|
|
short_message :="Medication Dosage",
|
|
Priority :="HIGH",
|
|
Scope := "chart",
|
|
Rule_group :="HVC Drug Check",
|
|
rule_number := 1005,
|
|
Send_With_Order:= send_alert,
|
|
display_alert := TRUE,
|
|
alert_abstract:= "",
|
|
render_as := "HTML",
|
|
alert_dialog_settings := sync_alert_dialog,
|
|
async_alert_dialog_settings := async_alert_dialog,
|
|
document_name := alert_override_document_name,
|
|
document_conditional_text := document_conditional_text_list,
|
|
ack_comment_UDDD := UDDD_dictionary_name,
|
|
ack_comment_UDDD_is_restricted := UDDD_is_restricted];
|
|
|
|
|
|
/* The facility must map its Dictionary Codes to the Core UOM in the Units of */
|
|
/* MeasureDictionary. The MLM converts the facility-defined units of measure to */
|
|
/* the System-defined values in the Unit of Measure Dictionary called CoreUOM. */
|
|
/* The exception is the dose-units on the order entry form will not be converted. */
|
|
core_uom_const := new Core_UOM_OBJECT;
|
|
|
|
core_uom_const.lb_string:= "lb";
|
|
core_uom_const.gm_string:= "g";
|
|
core_uom_const.kg_string:= "kg";
|
|
core_uom_const.M2_string:= "M2";
|
|
core_uom_const.ounce_string:= "oz";
|
|
core_uom_const.day_string:= "day";
|
|
core_uom_const.hour_string:= "hr";
|
|
core_uom_const.minute_string:= "min";
|
|
core_uom_const.month_string:= "month";
|
|
core_uom_const.second_string:= "s";
|
|
core_uom_const.week_string:= "week";
|
|
core_uom_const.year_string:= "year";
|
|
|
|
// Change the spelling within the quotes to match the order TypeCode
|
|
order_enter_trigger:= event {OrderEnter User Order:
|
|
where TypeCode = "Medication"};
|
|
|
|
// Change the spelling within the quotes to match the order TypeCode
|
|
patient_group_order_enter_trigger:= event {OrderEnter Batch Order:
|
|
where TypeCode = "Medication"
|
|
and IsCreatedFromPatientGroupOrderTemplate = TRUE};
|
|
|
|
// Change the spelling within the quotes to match the order TypeCode
|
|
order_modify_trigger:= event {OrderModify User Order:
|
|
where TypeCode = "Medication"
|
|
and ComplexOrderType is in (0,1,3,5) };
|
|
|
|
// ---------------------------
|
|
// Outpatient Order Trigger Events
|
|
// ---------------------------
|
|
// Outpatient Prescription and Home Medication Orders,
|
|
// Comment out below triggers to exclude checking all Outpatient Orders
|
|
// To include Home Medications remove the line AND OrderAdditionalInfo.IsScript <> FALSE
|
|
outpatient_order_enter_trigger:= event {OutpatientOrderEnterNoIVAdditive User Order:
|
|
where TypeCode = "Medication"
|
|
AND OrderAdditionalInfo.IsScript <> FALSE};
|
|
|
|
outpatient_order_modify_trigger := event {OutpatientOrderModify User Order:
|
|
WHERE TypeCode = "Medication"
|
|
AND OrderAdditionalInfo.IsScript <> FALSE};
|
|
|
|
|
|
// Change the spelling within the quotes to match the order TypeCode
|
|
order_enter_pharmacy_perfect_trigger :=
|
|
event {OrderEnterPharmacyPerfect Any Order:
|
|
where TypeCode = "Medication"};
|
|
|
|
// Change the spelling within the quotes to match the order TypeCode
|
|
order_modify_pharmacy_perfect_trigger :=
|
|
event {OrderModifyPharmacyPerfect Any Order:
|
|
where TypeCode = "Medication"};
|
|
|
|
// Change the spelling within the quotes to match the order TypeCode
|
|
order_modify_pharmacy_trigger :=
|
|
event {OrderModifyPharmacy Any Order:
|
|
where TypeCode = "Medication"
|
|
and ComplexOrderType is in (0,1,3,5) };
|
|
|
|
|
|
// ---------------------------
|
|
// Prescription Trigger Events
|
|
// ---------------------------
|
|
// If necessary, remove prescription types "Rx", or "Hx"
|
|
// from the list to exclude that type from checking
|
|
prescription_enter_trigger := EVENT { PrescriptionEnter Any ClientPrescription
|
|
: WHERE PrescriptionTypeDescription in ("Rx")
|
|
AND exists Frequency
|
|
AND exists DoseUOM
|
|
AND exists Route
|
|
};
|
|
|
|
prescription_enter_trigger_Hx := EVENT { PrescriptionEnter Any ClientPrescription
|
|
: WHERE PrescriptionTypeDescription in ("Hx")
|
|
AND exists DoseAmount
|
|
AND exists Frequency
|
|
AND exists DoseUOM
|
|
AND exists Route
|
|
};
|
|
|
|
prescription_renew_trigger := EVENT { PrescriptionRenew Any ClientPrescription
|
|
: WHERE PrescriptionTypeDescription in ("Rx")
|
|
AND exists Frequency
|
|
AND exists DoseUOM
|
|
AND exists Route
|
|
};
|
|
|
|
|
|
/* Uncomment this section if you would like historical session type orders to evoke this mlm,
|
|
Otherwise, keep it commented out and this mlm will ignore historical session type orders.
|
|
If you uncomment this section, make sure to also uncomment the equivalent in the evoke clause.
|
|
|
|
order_alternate_enter_IV_trigger:= event{OrderAlternateEnterWithIVAdditive User Order:
|
|
where TypeCode = "Medication" AND AlternateOrderType = 1};
|
|
|
|
order_alternate_enter_NOIV_trigger:= event{OrderAlternateEnterNoIVAdditive User Order:
|
|
where TypeCode = "Medication" AND AlternateOrderType = 1};
|
|
|
|
order_alternate_modify_trigger:= event{OrderAlternateModify User Order:
|
|
where TypeCode = "Medication" AND AlternateOrderType = 1}; */
|
|
|
|
/******************************************************************************/
|
|
|
|
/* DO NOT CHANGE the following System-defined values */
|
|
catalog_drc_type_const := new Catalog_DRC_Criteria_Type_String_Object;
|
|
|
|
catalog_drc_type_const.age_average_daily_dose_string:= "Age - Average Daily";
|
|
catalog_drc_type_const.age_string:= "Age";
|
|
catalog_drc_type_const.age_total_daily_dose_string:= "Age - Total Daily";
|
|
catalog_drc_type_const.BSA_average_daily_dose_string:= "BSA - Average Daily";
|
|
catalog_drc_type_const.Body_Surface_Area_string:= "Body Surface Area (BSA)";
|
|
catalog_drc_type_const.BSA_total_daily_dose_string:= "BSA - Total Daily";
|
|
catalog_drc_type_const.weight_average_daily_dose_string:= "Weight - Average Daily";
|
|
catalog_drc_type_const.weight_string:= "Weight";
|
|
catalog_drc_type_const.weight_total_daily_dose_string:= "Weight - Total Daily";
|
|
|
|
user_data_weight_string:= "Weight";
|
|
user_data_height_string:= "Height";
|
|
|
|
medication_dose_modified := FALSE;
|
|
continue_processing := TRUE;
|
|
|
|
/*=============================================================================*/
|
|
|
|
// Executes only when this MLM is called by the editor
|
|
if called_by_editor
|
|
then
|
|
// object_choice can be "Order", or "ClientPrescription"
|
|
object_choice := "Order";
|
|
|
|
// If you want to run the MLM with a known Order or ClientPrescription,
|
|
// - set use_direct_object_retrival to true
|
|
// - set object_guid value to Order guid or the CDSUniqueIDGUID of ClientPrescription
|
|
use_direct_object_retrival := false;
|
|
object_guid := 9999999999999999 as string; // Set the object GUID when use_direct_object_retrival is true
|
|
|
|
if use_direct_object_retrival and exists object_guid
|
|
then
|
|
EvokingObject := call {{{SINGLE-QUOTE}}}CDSDataObject{{{SINGLE-QUOTE}}}.CreateObject with object_choice;
|
|
x := call EvokingObject.FindByGUID with object_guid;
|
|
else
|
|
if (object_choice = "Order") then
|
|
EvokingObject := read last { Order: this where Name = orderName };
|
|
else
|
|
EvokingObject:= read last
|
|
{ClientPrescription: This
|
|
WHERE PrescriptionTypeDescription in ("Rx", "Hx")
|
|
};
|
|
endif;
|
|
endif;
|
|
endif;
|
|
|
|
/* Declare the MLMs that can be called */
|
|
func_dosage_lists := MLM {{{SINGLE-QUOTE}}}STD_func_dosage_lists{{{SINGLE-QUOTE}}};
|
|
func_dosage_rx := MLM {{{SINGLE-QUOTE}}}STD_func_dosage_lists_rx{{{SINGLE-QUOTE}}};
|
|
func_dosage_compare := MLM {{{SINGLE-QUOTE}}}std_func_dosage_compare{{{SINGLE-QUOTE}}};
|
|
func_dosage_rules := MLM {{{SINGLE-QUOTE}}}STD_func_dosage_rules{{{SINGLE-QUOTE}}};
|
|
|
|
// Get the patient{{{SINGLE-QUOTE}}}s GUID
|
|
client_guid := read last { ClientInfo: GUID };
|
|
|
|
//--------------------------------------
|
|
// Get the current order{{{SINGLE-QUOTE}}}s information
|
|
//--------------------------------------
|
|
if (EvokingObject is Order)
|
|
then
|
|
(order_name,
|
|
chart_guid,
|
|
order_catalog_item_obj,
|
|
order_component_obj,
|
|
order_TaskScheduleDefinition_obj,
|
|
order_user_data_obj) := read last
|
|
{ Order: Name, ChartGUID, OrderCatalogMasterItem,
|
|
OrderComponent, TaskScheduleDefinition, OrderUserData
|
|
REFERENCING EvokingObject};
|
|
elseif (EvokingObject is ClientPrescription)
|
|
then
|
|
debug_prescription_entered := "Yes";
|
|
|
|
(evoking_rx_name,
|
|
chart_guid,
|
|
evoking_rx_start_date,
|
|
evoking_rx_stop_date,
|
|
evoking_rx_renewal_date,
|
|
evoking_rx_cds_unique_guid,
|
|
evoking_rx_generic_name_id,
|
|
evoking_rx_status_type,
|
|
evoking_rx_prescription_type,
|
|
client_guid,
|
|
evoking_med_source,
|
|
evoking_rx_is_tapering_dose,
|
|
evoking_rx_back_up ) := read last {ClientPrescription:
|
|
DrugName,
|
|
ChartGUID,
|
|
StartDate,
|
|
EndDate,
|
|
RenewalDate,
|
|
CDSUniqueIDGUID,
|
|
GenericNameID,
|
|
StatusType,
|
|
PrescriptionType,
|
|
ClientGUID,
|
|
AlertOnDemandSource,
|
|
IsTaperingDose,
|
|
BackUp
|
|
REFERENCING EvokingObject
|
|
WHERE PrescriptionTypeDescription in ("Rx", "Hx") };
|
|
|
|
// do not run MLM is prescription is a tapering dose.
|
|
if evoking_rx_is_tapering_dose
|
|
then
|
|
continue_processing := false;
|
|
endif;
|
|
endif;
|
|
|
|
// Get the client info for debug messages
|
|
debug_client_info_object := read last {ClientInfo: This };
|
|
|
|
/* If event is ORDER MODIFICATION, check to see if the order dosage is changed. */
|
|
/* Continuing processing if the dosage has changed for the modified order. */
|
|
If EvokingEventType = order_modify_trigger.Type
|
|
OR EvokingEventType = outpatient_order_modify_trigger.Type
|
|
OR EvokingEventType = order_modify_pharmacy_trigger.Type
|
|
/* Uncomment this section if you would like historical session type orders to evoke this mlm,
|
|
Otherwise, keep it commented out and this mlm will ignore historical session type orders.
|
|
If you uncomment this section, make sure to also uncomment the equivalent in the evoke clause.
|
|
OR EvokingEventType = order_alternate_modify_trigger.Type */
|
|
then
|
|
(medication_dose_modified,
|
|
current_ovc_list ) := call func_dosage_compare with time_offset_limit;
|
|
if not medication_dose_modified
|
|
then continue_processing := false;
|
|
else continue_processing := true;
|
|
endif;
|
|
endif;
|
|
|
|
If continue_processing
|
|
then
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* CHECK ITEM DOSAGE CONFIGURATION AND OTHER ORDERING INFO IF NEEDED */
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
// Get the dosage range data location
|
|
(use_item_catalog_dosage_data_for_order_bit,
|
|
use_item_catalog_dosage_data_for_rx_bit,
|
|
use_multum_dosage_data_for_order_bit,
|
|
use_multum_dosage_data_for_rx_bit) := read last
|
|
{"SELECT "
|
|
|| "max(case when eRef.ReferenceString = " || SQLEX("Item Catalog for Orders") || " then 1 else 0 end) as orderCat, "
|
|
|| "max(case when eRef.ReferenceString = " || SQLEX("Item Catalog for Prescriptions") || " then 1 else 0 end) as rxCat, "
|
|
|| "max(case when eRef.ReferenceString = " || SQLEX("Multum for Orders") || " then 1 else 0 end) as orderMultum ,"
|
|
|| "max(case when eRef.ReferenceString = " || SQLEX("Multum for Prescriptions") || " then 1 else 0 end) as rxMultum "
|
|
|| "FROM CV3MLMSettings mlmSetting "
|
|
|| "INNER JOIN CV3EnumReference eRef on (mlmSetting.DataValue = eRef.EnumValue "
|
|
|| " and eRef.TableName = " || SQLEX("Cv3MLMSettings")
|
|
|| " and eRef.ColumnName = " || SQLEX("MLM_Dose_Range_Location") || ") "
|
|
|| "WHERE mlmSetting.DataType = " || SQLEX("Dose Range Location") };
|
|
|
|
use_item_catalog_dosage_data_for_order := use_item_catalog_dosage_data_for_order_bit = 1;
|
|
use_item_catalog_dosage_data_for_rx := use_item_catalog_dosage_data_for_rx_bit = 1;
|
|
use_multum_dosage_data_for_order := use_multum_dosage_data_for_order_bit = 1;
|
|
use_multum_dosage_data_for_rx := use_multum_dosage_data_for_rx_bit = 1;
|
|
|
|
/* Get the reference to the CatalogItemDosage object */
|
|
order_catalog_item_dosage_obj:= read last
|
|
{OrderCatalogMasterItem: CatalogItemDosage
|
|
REFERENCING order_catalog_item_obj };
|
|
|
|
/* Get the current OrderUserData information */
|
|
(user_data_code,
|
|
user_value,
|
|
user_data_touched_when) := read
|
|
{OrderUserData: UserDataCode, Value, TouchedWhen
|
|
REFERENCING order_user_data_obj };
|
|
|
|
/* Get the dosage range HIGH from the item-catalog */
|
|
/* AND it must be one of the Criteria Type Codes that dosage range uses. */
|
|
/* It ignores NULL and LIFE-TIME dosage Criteria Type Codes */
|
|
(criteria_type,
|
|
range_high_codes,
|
|
criteria_gender_code_parent,
|
|
criteria_route_codes ) := read
|
|
{ CatalogItemDosage: CriteriaTypeCode, RangeHigh, GenderCode, RouteCode
|
|
REFERENCING order_catalog_item_dosage_obj
|
|
WHERE CriteriaTypeCode is in (catalog_drc_type_const.age_average_daily_dose_string,
|
|
catalog_drc_type_const.age_string, catalog_drc_type_const.age_total_daily_dose_string,
|
|
catalog_drc_type_const.BSA_average_daily_dose_string, catalog_drc_type_const.Body_Surface_Area_string,
|
|
catalog_drc_type_const.BSA_total_daily_dose_string, catalog_drc_type_const.weight_average_daily_dose_string,
|
|
catalog_drc_type_const.weight_string, catalog_drc_type_const.weight_total_daily_dose_string ) };
|
|
|
|
|
|
/* Only retrieve other data if medication has a Dosage range */
|
|
/* or has IV additives */
|
|
If exist(range_high_codes) and any(range_high_codes > 0)
|
|
OR exist order_component_obj
|
|
OR use_multum_dosage_data_for_order
|
|
OR use_multum_dosage_data_for_rx
|
|
OR use_item_catalog_dosage_data_for_order
|
|
OR use_item_catalog_dosage_data_for_rx
|
|
then
|
|
//------------------------------------------//
|
|
// Set up Height and Weight validity ranges
|
|
//------------------------------------------//
|
|
//
|
|
sorted_weight_validity := sort (valid_weight_days_for_age.ToAge);
|
|
|
|
weight_validity_count := count valid_weight_days_for_age;
|
|
|
|
// Set the from age
|
|
// first age range starts from 0
|
|
if (weight_validity_count >= 1)
|
|
then
|
|
curr_weight_validity := last(valid_weight_days_for_age where
|
|
valid_weight_days_for_age.ToAge = sorted_weight_validity[1]);
|
|
curr_weight_validity.FromAge := 0 seconds;
|
|
endif;
|
|
|
|
// All the subsequent age ranges use the previous ToAge value as FromAge
|
|
if (weight_validity_count > 1)
|
|
then
|
|
for ind in 2 seqto weight_validity_count
|
|
do
|
|
curr_weight_validity := last(valid_weight_days_for_age where
|
|
valid_weight_days_for_age.ToAge = sorted_weight_validity[ind]);
|
|
curr_weight_validity.FromAge := sorted_weight_validity[ind-1];
|
|
enddo;
|
|
endif;
|
|
|
|
sorted_height_validity := sort (valid_height_days_for_age.ToAge);
|
|
|
|
height_validity_count := count valid_height_days_for_age;
|
|
|
|
// Set the from age
|
|
// first age range starts from 0
|
|
if (height_validity_count >= 1)
|
|
then
|
|
curr_height_validity := last(valid_height_days_for_age where
|
|
valid_height_days_for_age.ToAge = sorted_height_validity[1]);
|
|
curr_height_validity.FromAge := 0 seconds;
|
|
endif;
|
|
|
|
// All the subsequent age ranges use the previous ToAge value as FromAge
|
|
if (height_validity_count > 1)
|
|
then
|
|
for ind in 2 seqto height_validity_count
|
|
do
|
|
curr_height_validity := last(valid_height_days_for_age where
|
|
valid_height_days_for_age.ToAge = sorted_height_validity[ind]);
|
|
curr_height_validity.FromAge := sorted_height_validity[ind-1];
|
|
enddo;
|
|
endif;
|
|
|
|
// Retrieve the facility{{{SINGLE-QUOTE}}}s scope preference for HEIGHT and WEIGHT
|
|
general_scope_for_ht := read last
|
|
{"SELECT CASE WHEN ScopeLevel = 3 THEN 1 ELSE 0 END "
|
|
|| " FROM CV3PhysicalNoteType "
|
|
|| " WHERE Code = " || SQLEX("Height")};
|
|
general_scope_for_wt := read last
|
|
{"SELECT CASE WHEN ScopeLevel = 3 THEN 1 ELSE 0 END "
|
|
|| " FROM CV3PhysicalNoteType "
|
|
|| " WHERE Code = " || SQLEX("Weight")};
|
|
|
|
// Set the scope to retrieve the Height
|
|
if general_scope_for_ht = 1
|
|
then ht_patient_chart_str:= "";
|
|
else ht_patient_chart_str:= " AND ChartGUID = " || SQLEX(chart_guid);
|
|
endif;
|
|
|
|
// Set the scope to retrieve the Weight
|
|
if general_scope_for_wt = 1
|
|
then wt_patient_chart_str:= "";
|
|
else wt_patient_chart_str:= " AND ChartGUID = " || SQLEX(chart_guid);
|
|
endif;
|
|
|
|
// Retrieve from database
|
|
// Warning--keep SQL in synch with business rules on patient height and weight
|
|
(ht_cm_from_profile_str,
|
|
ht_date) := read last
|
|
{"SELECT Text, isNull(Entered,TouchedWhen) as Entered "
|
|
|| " FROM CV3PhysicalNoteDeclaration"
|
|
|| " WHERE ClientGUID = " || SQLEX(client_guid)
|
|
|| ht_patient_chart_str
|
|
|| " AND Active = 1 "
|
|
|| " AND TypeCode = " || SQLEX("HEIGHT")
|
|
|| " AND Status = " || SQLEX("Active")
|
|
, PrimaryTime = Entered };
|
|
|
|
|
|
/* Get the patient{{{SINGLE-QUOTE}}}s current height (expected in centimeters) */
|
|
if user_data_height_string is not in user_data_code
|
|
then
|
|
ht_cm_str := ht_cm_from_profile_str;
|
|
else
|
|
/* Extract from user data object*/
|
|
ht_cm_str:= first (user_value where user_data_height_string = user_data_code);
|
|
|
|
if ( ht_cm_from_profile_str <> ht_cm_str
|
|
OR ht_cm_from_profile_str is NULL
|
|
OR EvokingEventType = order_alert_check.type)
|
|
then
|
|
ht_date := first (user_data_touched_when where user_data_height_string = user_data_code);
|
|
endif;
|
|
endif; /* if user_data_height_string */
|
|
|
|
(wt_gm_from_profile_str,
|
|
wt_date) := read last
|
|
{"SELECT Text, isNull(Entered,TouchedWhen) as Entered "
|
|
|| " FROM CV3PhysicalNoteDeclaration"
|
|
|| " WHERE ClientGUID = " || SQLEX(client_guid)
|
|
|| wt_patient_chart_str
|
|
|| " AND Active = 1 "
|
|
|| " AND TypeCode = " || SQLEX("WEIGHT")
|
|
|| " AND Status = " || SQLEX("Active")
|
|
, PrimaryTime = Entered };
|
|
|
|
/* Get the patient{{{SINGLE-QUOTE}}}s actual current weight (expected in grams) */
|
|
if user_data_weight_string is not in user_data_code
|
|
then
|
|
/* Convert weight in grams to kilograms */
|
|
wt_gm_str:= (wt_gm_from_profile_str as number)/1000;
|
|
else
|
|
/* Extract from user data object */
|
|
wt_gm_str:= first (user_value where user_data_weight_string = user_data_code);
|
|
|
|
if (wt_gm_from_profile_str <> wt_gm_str
|
|
OR wt_gm_from_profile_str is NULL
|
|
OR EvokingEventType = order_alert_check.type)
|
|
then
|
|
wt_date := first (user_data_touched_when where user_data_weight_string = user_data_code);
|
|
endif;
|
|
endif; // if user_data_weight_string is not in user_data_code
|
|
|
|
/* Convert strings to numbers */
|
|
ht_cm:= ht_cm_str as number;
|
|
wt_kg:= wt_gm_str as number;
|
|
|
|
// Save the patient data
|
|
patient_info := new Patient_Info_Obj;
|
|
|
|
patient_info.Weight := new Patient_Property_Obj;
|
|
patient_info.Weight.type := "Weight";
|
|
patient_info.Weight.value := wt_kg;
|
|
patient_info.Weight.date := wt_date;
|
|
patient_info.Weight.is_missing := ((wt_kg is NULL) or (wt_kg = 0));
|
|
|
|
patient_info.Height := new Patient_Property_Obj;
|
|
patient_info.Height.type := "Height";
|
|
patient_info.Height.value := ht_cm;
|
|
patient_info.Height.date := ht_date;
|
|
patient_info.Height.is_missing := ((ht_cm is NULL) or (ht_cm = 0));
|
|
|
|
// Create Alert_If_Missing_Obj
|
|
alert_if_missing_flags := new Alert_If_Missing_Obj;
|
|
alert_if_missing_flags.patient_age := alert_if_patient_age_is_missing;
|
|
alert_if_missing_flags.patient_height := alert_if_patient_height_is_missing;
|
|
alert_if_missing_flags.patient_weight := alert_if_patient_weight_is_missing;
|
|
alert_if_missing_flags.patient_gender := alert_if_patient_gender_is_missing;
|
|
alert_if_missing_flags.route := alert_if_route_is_missing;
|
|
alert_if_missing_flags.uom_conversion := alert_if_uom_conversion_issue;
|
|
alert_if_missing_flags.uom := alert_if_UOM_is_missing;
|
|
alert_if_missing_flags.cannot_check_DNum_Rx_to_Multum := alert_if_cannot_check_DNum_Rx_to_Multum;
|
|
alert_if_missing_flags.cannot_check_Rx_to_IC := alert_if_cannot_check_Rx_to_IC;
|
|
alert_if_missing_flags.cannot_check_generic_route := alert_if_unrecognized_route;
|
|
alert_if_missing_flags.inapplicable_route := (alert_if_inapplicable_route_for_orders and EvokingObject is Order )
|
|
OR (alert_if_inapplicable_route_for_rx and EvokingObject is ClientPrescription);
|
|
alert_if_missing_flags.unmapped_drug := any (alert_if_unmapped_data = "dose");
|
|
alert_if_missing_flags.unmapped_grouper := any (alert_if_unmapped_data = "dose range group");
|
|
alert_if_missing_flags.unmapped_gender := any (alert_if_unmapped_data = "gender");
|
|
alert_if_missing_flags.unmapped_route := any (alert_if_unmapped_data = "route");
|
|
alert_if_missing_flags.unmapped_uom := any (alert_if_unmapped_data = "uom");
|
|
alert_if_missing_flags.unmapped_frequency := any (alert_if_unmapped_data = "frequency");
|
|
|
|
// Get the list of routes that contain the unrecognized routes
|
|
(expanded_unrecognized_route_list) := read {
|
|
"SELECT multumRoute "
|
|
|| "FROM SXAMultumRouteConversion "
|
|
|| "WHERE DRCGrouperRoute in (" || SQLEX(unrecognized_route_list) || ")"
|
|
};
|
|
|
|
expanded_unrecognized_route_list := expanded_unrecognized_route_list as NUMBER;
|
|
expanded_unrecognized_route_list := expanded_unrecognized_route_list, unrecognized_route_list;
|
|
|
|
|
|
else // The order does not have dosage-range criteria, so stop processing
|
|
continue_processing := FALSE;
|
|
endif; //If exist(range_high_codes)
|
|
endif; //If continue_processing
|
|
|
|
// Get the last revision date of the Multum database, strip out time portion
|
|
revision_date := read last { "if exists (select 1 from [sys].[objects] where type={{{SINGLE-QUOTE}}}SN{{{SINGLE-QUOTE}}} and name = {{{SINGLE-QUOTE}}}SXAMTdatabase_infoSYN{{{SINGLE-QUOTE}}}) " ||
|
|
" select change_date from SXAMTdatabase_infoSYN" };
|
|
if revision_date is not NULL
|
|
then
|
|
revision_date := revision_date formatted with "%.2t";
|
|
revision_date_string := "\n{{+B}}Revision Date{{-B}}: " || revision_date;
|
|
endif;
|
|
|
|
;;
|
|
|
|
|
|
evoke: order_enter_trigger;
|
|
patient_group_order_enter_trigger;
|
|
order_modify_trigger;
|
|
outpatient_order_enter_trigger;
|
|
outpatient_order_modify_trigger;
|
|
order_enter_pharmacy_perfect_trigger;
|
|
order_modify_pharmacy_perfect_trigger;
|
|
order_modify_pharmacy_trigger;
|
|
prescription_enter_trigger;
|
|
prescription_enter_trigger_Hx;
|
|
prescription_renew_trigger;
|
|
|
|
/* Uncomment this section if you would like historical session type orders to evoke this mlm. Otherwise, keep it commented out.
|
|
If you uncomment this section, please make sure to also uncomment the equivalent event clauses.
|
|
order_alternate_enter_IV_trigger;
|
|
order_alternate_enter_NOIV_trigger;
|
|
order_alternate_modify_trigger;
|
|
*/
|
|
;
|
|
;;
|
|
|
|
logic:
|
|
/* Stop Processing MLM when continue_processing is false. */
|
|
if NOT continue_processing
|
|
then conclude false;
|
|
endif;
|
|
|
|
//------------------------------------------
|
|
// Create a List of Medication Data Objects
|
|
//------------------------------------------
|
|
if (EvokingObject is Order)
|
|
then
|
|
//These objects that contain data for regular medications,
|
|
//iv-additives, and complex orders
|
|
|
|
med_data_list := call func_dosage_lists with
|
|
ht_cm,
|
|
wt_kg,
|
|
current_ovc_list,
|
|
order_TaskScheduleDefinition_obj ;
|
|
|
|
use_multum_dosage_data := use_multum_dosage_data_for_order;
|
|
use_item_catalog_dosage_data := use_item_catalog_dosage_data_for_order;
|
|
else
|
|
// These objects contain data for prescription
|
|
(med_data_list, patient_info_dnum_grouper) := call func_dosage_rx with
|
|
ht_cm,
|
|
wt_kg;
|
|
|
|
patient_info.DNum_Grouper := patient_info_dnum_grouper;
|
|
|
|
use_multum_dosage_data := use_multum_dosage_data_for_rx;
|
|
use_item_catalog_dosage_data := use_item_catalog_dosage_data_for_rx;
|
|
endif;
|
|
|
|
// Set generic route flag based on the order_med_route_id
|
|
med_data_list.generic_route := med_data_list.order_med_route_id in expanded_unrecognized_route_list;
|
|
|
|
//Check one more time to see if there are dosage range criteria for the
|
|
//Routes that have been returned from the Med_Data objects.
|
|
//Only continue processing if there are criteria for the order{{{SINGLE-QUOTE}}}s routes
|
|
//Or the order have IV-Additives
|
|
IF ANY (med_data_list.order_med_route is in criteria_route_codes)
|
|
OR exist order_component_obj
|
|
OR use_multum_dosage_data
|
|
OR use_item_catalog_dosage_data
|
|
then
|
|
/*----------------------------------------------*/
|
|
/* Check the Dosage Ranges for All Medications */
|
|
/*----------------------------------------------*/
|
|
|
|
(alert_detail_text,
|
|
average_tracker_list,
|
|
total_tracker_list,
|
|
missing_data_list,
|
|
cannot_check_list,
|
|
med_with_hard_stop,
|
|
show_frequency_warning,
|
|
alert_abstract
|
|
) := call func_dosage_rules with
|
|
chart_GUID,
|
|
user_data_code,
|
|
user_value,
|
|
user_data_touched_when,
|
|
use_multum_dosage_data,
|
|
use_item_catalog_dosage_data,
|
|
catalog_drc_type_const,
|
|
core_uom_const,
|
|
ht_cm,
|
|
show_irregular_message,
|
|
show_under_24_hour_message,
|
|
show_has_shift_frequency_message,
|
|
show_user_scheduled_weekly_message,
|
|
intentionally_unmapped_frequency_list,
|
|
alert_if_missing_flags,
|
|
med_data_list,
|
|
patient_info,
|
|
valid_height_days_for_age,
|
|
valid_weight_days_for_age,
|
|
Creatinine_Clearance_Result_name,
|
|
valid_creatinine_clearance_days,
|
|
EstCrCl_equation_preference,
|
|
EstCrC_calculate_with_BSA_preference,
|
|
show_Debug_statements,
|
|
column_catalog_name,
|
|
column_Multum_name
|
|
;
|
|
|
|
// Check for Hard stop settings
|
|
if med_with_hard_stop then
|
|
dosage_alert.alert_dialog_settings := "No Override Allowed";
|
|
endif;
|
|
|
|
|
|
/*---------------*/
|
|
/* CLINICAL RULE */
|
|
/*---------------*/
|
|
|
|
if any (med_data_list.outside_single_dosage_range)
|
|
or any (med_data_list.contraindication_found)
|
|
or any (average_tracker_list.outside_average_daily_dose)
|
|
or any (total_tracker_list.outside_total_daily_dose)
|
|
or (any missing_data_list.missing_data_error)
|
|
or (any average_tracker_list.user_scheduled_weekly_used and show_user_scheduled_weekly_message )
|
|
or (any average_tracker_list.irregular_schedule_used and show_irregular_message)
|
|
or (any total_tracker_list.met_criteria_under_24_hours and show_under_24_hour_message)
|
|
or (any average_tracker_list.met_criteria_under_24_hours and show_under_24_hour_message)
|
|
or (any total_tracker_list.met_criteria_has_shift_frequency and show_has_shift_frequency_message)
|
|
or (any average_tracker_list.met_criteria_has_shift_frequency and show_has_shift_frequency_message)
|
|
or show_frequency_warning
|
|
then
|
|
conclude true;
|
|
endif;
|
|
endif; //if any (med_data_list.outside_single_dosage_range)
|
|
;;
|
|
|
|
action:
|
|
dosage_alert.alert_abstract := alert_abstract;
|
|
write alert_detail_text at dosage_alert;
|
|
|
|
if show_Debug_statements = true
|
|
then
|
|
xml_med_frequency_list := ();
|
|
for med_data_item in med_data_list
|
|
do
|
|
xml_med_frequency_list := xml_med_frequency_list, XML(med_data_item.order_med_frequency);
|
|
enddo;
|
|
|
|
//Debug Write Statement
|
|
write "<div id={{{SINGLE-QUOTE}}}DebugSection{{{SINGLE-QUOTE}}}>"
|
|
|| "<br><br><span style={{{SINGLE-QUOTE}}}{color=red; }{{{SINGLE-QUOTE}}}>Debug Variables</span><br>"
|
|
|| "<span style={{{SINGLE-QUOTE}}}{color=blue; }{{{SINGLE-QUOTE}}}>Calculation Method Used: </span>" || med_data_list[1].calculation_method || "<br>"
|
|
|| "<span style={{{SINGLE-QUOTE}}}{color=blue; }{{{SINGLE-QUOTE}}}>Med_order_type: </span>" || med_data_list.med_order_type || "<br>"
|
|
|| "<span style={{{SINGLE-QUOTE}}}{color=blue; }{{{SINGLE-QUOTE}}}>Order_med_name: </span>" || med_data_list.Order_med_name || "<br>"
|
|
|| "<span style={{{SINGLE-QUOTE}}}{color=blue; }{{{SINGLE-QUOTE}}}>Order_med_freq: </span>" || xml_med_frequency_list || "<br>"
|
|
|| "<span style={{{SINGLE-QUOTE}}}{color=blue; }{{{SINGLE-QUOTE}}}>Order_med_dose_low: </span>" || med_data_list.order_med_dose_low || "<br>"
|
|
|| "<span style={{{SINGLE-QUOTE}}}{color=blue; }{{{SINGLE-QUOTE}}}>Order_med_significant_date: </span>" || (med_data_list.order_med_significant_date as {{{SINGLE-QUOTE}}}DateTimeOffset{{{SINGLE-QUOTE}}}) || "<br>"
|
|
|| "<span style={{{SINGLE-QUOTE}}}{color=blue; }{{{SINGLE-QUOTE}}}>Stop_dtm: </span>" || (med_data_list.stop_dtm as {{{SINGLE-QUOTE}}}DateTimeOffset{{{SINGLE-QUOTE}}}) || "<br>"
|
|
at dosage_alert;
|
|
|
|
if med_data_list[1].calculation_method = "SUMMED"
|
|
then
|
|
write "<br><span style={{{SINGLE-QUOTE}}}{color=blue; }{{{SINGLE-QUOTE}}}>Calculated Start_dtm: </span>" || (med_data_list.calcStart_dtm as {{{SINGLE-QUOTE}}}DateTimeOffset{{{SINGLE-QUOTE}}}) || "<br>"
|
|
|| "<span style={{{SINGLE-QUOTE}}}{color=blue; }{{{SINGLE-QUOTE}}}>Calculated Stop_dtm: </span>" || (med_data_list.calcStop_dtm as {{{SINGLE-QUOTE}}}DateTimeOffset{{{SINGLE-QUOTE}}}) || "<br>"
|
|
|| "<span style={{{SINGLE-QUOTE}}}{color=blue; }{{{SINGLE-QUOTE}}}>Admin_dtm_list_calc_method: </span>" || med_data_list.admin_dtm_list_calc_method || "<br>"
|
|
|| "<span style={{{SINGLE-QUOTE}}}{color=blue; }{{{SINGLE-QUOTE}}}>Admin_dtm_list: </span>" || med_data_list.admin_dtm_list || "<br><br>"
|
|
at dosage_alert;
|
|
|
|
//Debug Write Statement
|
|
for my_num in (1 seqto (Count med_data_list)) do
|
|
write "<span style={{{SINGLE-QUOTE}}}{color=green; }{{{SINGLE-QUOTE}}}><b>Admin_dtm_list in Object [" ||my_num|| "]: </b></span>"
|
|
|| (med_data_list[my_num].admin_dtm_list as {{{SINGLE-QUOTE}}}DateTimeOffset{{{SINGLE-QUOTE}}})
|
|
|| "<br>"
|
|
at dosage_alert;
|
|
enddo;
|
|
endif;
|
|
|
|
write "<br><u>Patient Info </u><br>"
|
|
|| " BirthDateTime: " || (debug_client_info_object.BirthDateTime as {{{SINGLE-QUOTE}}}DateTimeOffset{{{SINGLE-QUOTE}}}) || "<br>"
|
|
|| " BirthMonthNum: " ||debug_client_info_object.BirthMonthNum || "<br>"
|
|
|| " BirthTime: " || debug_client_info_object.BirthTime || "<br>"
|
|
|| " GenderCode: " || debug_client_info_object.GenderCode || "<br>"
|
|
|| " GenderTypeIntlCode: " || debug_client_info_object.GenderTypeIntlCode || "<br>"
|
|
|| " Weight: " || wt_kg || "<br>"
|
|
|| " Height: " || ht_cm || "<br>"
|
|
|
|
at dosage_alert;
|
|
|
|
|
|
write "<span style={{{SINGLE-QUOTE}}}{color=red; }{{{SINGLE-QUOTE}}}>Elapsed time:</span> " || currentTime - EventTime
|
|
|| "</div>" // end DebugSection division
|
|
at dosage_alert;
|
|
|
|
endif;
|
|
|
|
if revision_date_string is not null
|
|
then
|
|
dosage_alert.references := dosage_alert.references || revision_date_string;
|
|
endif;
|
|
;;
|
|
Urgency: 80;;
|
|
end:
|