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 := ("", "", "", "", "", "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 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 "
" || "

Debug Variables
" || "Calculation Method Used: " || med_data_list[1].calculation_method || "
" || "Med_order_type: " || med_data_list.med_order_type || "
" || "Order_med_name: " || med_data_list.Order_med_name || "
" || "Order_med_freq: " || xml_med_frequency_list || "
" || "Order_med_dose_low: " || med_data_list.order_med_dose_low || "
" || "Order_med_significant_date: " || (med_data_list.order_med_significant_date as {{{SINGLE-QUOTE}}}DateTimeOffset{{{SINGLE-QUOTE}}}) || "
" || "Stop_dtm: " || (med_data_list.stop_dtm as {{{SINGLE-QUOTE}}}DateTimeOffset{{{SINGLE-QUOTE}}}) || "
" at dosage_alert; if med_data_list[1].calculation_method = "SUMMED" then write "
Calculated Start_dtm: " || (med_data_list.calcStart_dtm as {{{SINGLE-QUOTE}}}DateTimeOffset{{{SINGLE-QUOTE}}}) || "
" || "Calculated Stop_dtm: " || (med_data_list.calcStop_dtm as {{{SINGLE-QUOTE}}}DateTimeOffset{{{SINGLE-QUOTE}}}) || "
" || "Admin_dtm_list_calc_method: " || med_data_list.admin_dtm_list_calc_method || "
" || "Admin_dtm_list: " || med_data_list.admin_dtm_list || "

" at dosage_alert; //Debug Write Statement for my_num in (1 seqto (Count med_data_list)) do write "Admin_dtm_list in Object [" ||my_num|| "]: " || (med_data_list[my_num].admin_dtm_list as {{{SINGLE-QUOTE}}}DateTimeOffset{{{SINGLE-QUOTE}}}) || "
" at dosage_alert; enddo; endif; write "
Patient Info
" || " BirthDateTime: " || (debug_client_info_object.BirthDateTime as {{{SINGLE-QUOTE}}}DateTimeOffset{{{SINGLE-QUOTE}}}) || "
" || " BirthMonthNum: " ||debug_client_info_object.BirthMonthNum || "
" || " BirthTime: " || debug_client_info_object.BirthTime || "
" || " GenderCode: " || debug_client_info_object.GenderCode || "
" || " GenderTypeIntlCode: " || debug_client_info_object.GenderTypeIntlCode || "
" || " Weight: " || wt_kg || "
" || " Height: " || ht_cm || "
" at dosage_alert; write "Elapsed time: " || currentTime - EventTime || "
" // 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: