Files
St.Clair/MLMStripper/bin/Debug/STD/STD_DRUG_INTERACTION.mlm

1677 lines
68 KiB
Plaintext

maintenance:
title: Drug Interaction Checking;;
mlmname: STD_DRUG_INTERACTION;;
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: Alerts the person ordering if the ordered medication interacts
with any existing meds, or has a general interaction with food.
Provides Actions on Alerts when a drug-drug interaction occurs,
but not for a drug-food interaction.
;;
explanation: Any medication order, outpatient medication order, or prescription evokes this MLM.
It uses drug vendor information in the Multum database to check the current medication
against existing medications.
The existing medications can be in 3 categories:
1. CURRENT: a status level number of 50 (i.e. active),
and not currently suspended.
2. PENDING (INACTIVE): a status level number of less than 50,
or a status level number of 50 and currently suspended.
3. UNSUBMITTED: on the order/or prescription worksheet,
but not submitted yet.
To use this MLM the Drug mapping must be completed.
This MLM works with Drug Interaction information configured by the site
using the Multum Data Configuration, Config Tool.
This allows the site to override the Multum data with:
the severity level that should alert
which drugs to exclude from checking
site defined severity levels
site defined interaction text
site defined Drug Interaction Override rights
Only the master order from Complex and Multiple Frequencies Orders are checked.
Child orders (ComplexOrderType of 2,4,6) are not checked.
The following ComplexOrderType values define the type of order:
0 or NULL - regular order
1 - Sequential Complex Dose Master
2 - Sequential Complex Dose Child Order
3 - Concurrent Complex Dose Master
4 - Concurrent Complex Dose Child Order
5 - Multiple Frequencies Master
6 - Multiple Frequencies Child Order
Only prescriptions that have StatusType = 1(Active) or StatusType =
5(Unapproved) are checked.
Only medications belonging to the session types as defined in the following list
variables will be checked against the evoking order (e.g.
at_discharge_session_list, at_in_house_session_list, or
at_historical_session_list, at_prescription_session_list,
at_prescription_historical_session_list, or at_outpatient_session_list).
STD_FUNC_COMMUNITY_DATA_RETRIEVAL_RULES- Checks for a user{{{SINGLE-QUOTE}}}s right to ignore
a patient{{{SINGLE-QUOTE}}}s community medication allergy data when allergy check performed. This is a required MLM.
The list variable corresponding to the session type of the order being entered
is used.
Change History
10.25.2013 TMS Updated new 6.1 version with St. Clair Customization from 5.5 version. CSR 31299
07.15.2015 TMS Updated new 15.1 version with St. Clair Customization from 6.1 version. CSR 33555
03.08.2016 TMS Added 2 new evoking events and added qualifiers to 2 existing events to allow for
ordering of heparin and alteplase by sheath or intracatheter without presenting
the user with a drug interaction alert when ordered from the Post Initiation
Catheter Directed Thrombolytic Therapy Order Set. CSR 33758
06.01.2016 TMS Added new evoking event for orders from FBC Order Sets to allow
entry of Toradol and Ibuprofen (which is started after Toradol is complete)
to be ordered without presenting a drug interaction alert. CSR 34052
10.14.2016 TMS Added SCH customization to new standard MLM version for 16.1 Upgrade CSR 35130
12.05.2018 TMS Added exclusion for Methyprednisolone and Infliximab Drug interaction when ordered together
from the Intravenous Infliximab (Remicade) or Infliximab-dyyb (Inflectra) Physician Order Set CSR 36315
03.19.2019 TMS Added SCH customization from 16.3 to 18.4 version. CSR 37676
09.30.2019 TMS Updated alert to require reason when alert presented to user not in physician/physician extender
group. CSR 37977
;;
keywords: interaction;;
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}}Release{{-B}}: VantageRx Multum Database
;;
knowledge:
type: data-driven;;
data:
//******************Make Changes To Spelling And Flags In This Section*******************
// Set to true if logging is needed.
log_execution_info := false;
// Set the text for the variable below to indicate whether to send the message or not.
send_alert := "DoNotSend";
// Set a flag indicating whether un-mapped drugs are to be reported
// in the alert message or should be ignored.
alert_if_unmapped := FALSE;
// Set a flag indicating whether or not Actions on Alerts should be generated
generate_actions_on_alerts := TRUE;
// Set flag indicating whether or not drug-food interactions are to be considered.
alert_drug_food := FALSE;
// Set this flag to TRUE to include community data in drug interaction checking
enable_community_data_medication_alerts := false;
// Set flag to exclude pending Community Medications that are older that
// the days specified by the flag value
// Set the value to null to turn off the exclusion filter and include all
// pending community medications:
// exclude_pending_community_meds_older_than_days := null;
exclude_pending_community_meds_older_than_days := 366;
// Enum values for Community Medication defined
enum_rx_type_Community_Med := 5;
// Enter the list of triggers that you want to exclude from community medication interaction checking.
// The trigger names must be strings. Use double-quotes around the trigger name.
//
// The following are triggers that can be placed in the list:
// ("PrescriptionInit", "PrescriptionRenew")
// ("OrderInitNoIVAdditives", "OrderEnterNoIVAdditives", "OrderEnterWithIVAdditives")
// ("OrderModify")
// ("OutpatientOrderInitNoIVAdditive", "OutpatientOrderModify", "OutpatientOrderEnterNoIVAdditive")
// ("OrderEnterPharmacyPerfect", "OrderModifyPharmacyPerfect")
// ("AlertCheckingOrder", "AlertCheckingClientPrescription")
// ("OrderAlternateEnterWithIVAdditive", "OrderAlternateInitNoIVAdditive", "OrderAlternateModify")
//
// The default is an empty list (). It means that no triggers are excluded.
community_data_excluded_triggers_list:= ();
//Enter the text to differentiate community data in drug interaction checking
//Sites can change the default " (Pending)" pending Community Medication identifier string
// by changing the MLM flag.
pending_community_medication_alert_text :=" (Pending)" ;
// Set the list variables with the session types of existing orders against which
// the current order will be checked. The possible values for these variables are
// one or more types from the following list ("Discharge", "Inhouse", Outpatient Rx,
// Outpatient Hx,"Historical", "Prescriptions", "Historical Prescriptions",
// "Community Medication").
//
// Set the list variables with the session types of existing prescriptions against which
// the current prescription will be checked. The possible values for these variables are
// one or more types from the following list ("Discharge", "Inhouse", Outpatient Rx,
// Outpatient Hx, "Historical", "Prescriptions", "Historical Prescriptions",
// "Community Medication").
//
// The default setting is to check for drug interaction checking between
// - current order entered during a discharge session type and existing discharge orders,
// - current order entered during an in-house session type and existing in-house orders
// - current order entered during historical session type and existing historical orders.
// - current prescription entered and existing and historical prescriptions.
// - current historical prescriptions entered and existing and historical prescriptions
// and community medication
// - current outpatient orders entered and existing outpatient orders and community medication
// at_discharge_session_list:= ("Discharge", "Community Medication");
at_discharge_session_list:= ("Discharge");
// at_in_house_session_list:= ("Inhouse", "Community Medication", "Prescriptions");
at_in_house_session_list:= ("Inhouse");
// at_historical_session_list:= ("Historical", "Community Medication");
// at_outpatient_session_list := ("Outpatient Rx", "Outpatient Hx", "Community Medication");
at_outpatient_session_list := ("Outpatient Rx", "Outpatient Hx");
// at_prescription_session_list:= ("Prescriptions", "Historical Prescriptions",
// "Community Medication", "Inhouse");
at_prescription_session_list:= ("Prescriptions", "Historical Prescriptions");
// at_prescription_historical_session_list:= ("Prescriptions", "Historical Prescriptions",
// "Community Medication");
at_prescription_historical_session_list:= ("Community Medication");
// 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 restrict dictionary or not.
// Selections are: TRUE, FALSE
// UDDD_is_restricted := FALSE;
fire_on_UserCPOE := ("MD","DO","DDS","DPM","PA","PA-C","CRNP","IT");
fire_on_User := ("RN","RPh");
/* Get the current user{{{SINGLE-QUOTE}}}s occupation*/
userguid :=read last {UserInfo: guid};
UserCode := read last
{"Select occupationcode "
||" 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.
interact_alert := DESTINATION {Alert} WITH
[ alert_type:= warning,
short_message:="Drug Interaction",
priority:= "high",
scope:= Chart,
rule_group:= "HVC Drug Check",
rule_number:= 2005,
send_with_order := send_alert,
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
];
//---------------------
// Order Trigger Events
//---------------------
new_regular_med_order_not_in_set := event {OrderInitNoIVAdditives User Order:
WHERE TypeCode = "Medication" AND IsPartOfSet = FALSE};
new_regular_med_patient_group_order_not_in_set := event {OrderInitNoIVAdditives Batch Order:
WHERE TypeCode = "Medication" AND IsPartOfSet = FALSE AND IsCreatedFromPatientGroupOrderTemplate = TRUE};
new_regular_med_order_in_set := event {OrderEnterNoIVAdditives User Order:
WHERE TypeCode = "Medication" AND IsPartOfSet = TRUE
and ((OrderSetName <> "Post Initiation Catheter Directed Thrombolytic Therapy" )
or (OrderSetName <> "Abdominal Hysterectomy Post Op" )
or (OrderSetName <> "FBC C Section Physician Orders" )
or (OrderSetName <> "Vaginal Hysterectomy Post Op" )
or (OrderSetName <> "Laparoscopic Hysterectomy" ) ) };
new_IV_order := event {OrderEnterWithIVAdditives User Order:
WHERE TypeCode = "Medication" and (OrderSetName <> "Post Initiation Catheter Directed Thrombolytic Therapy" ) };
new_IV_patient_group_order := event {OrderEnterWithIVAdditives Batch Order:
WHERE TypeCode = "Medication" AND IsCreatedFromPatientGroupOrderTemplate = TRUE};
order_modify_trigger:= event {OrderModify User Order:
WHERE TypeCode = "Medication" };
new_rad_med_order_in_set := event {OrderEnterNoIVAdditives User Order:
WHERE TypeCode = "Medication" AND IsPartOfSet = TRUE
and (OrderSetName = "Post Initiation Catheter Directed Thrombolytic Therapy" and OrderRouteCode = "IV" ) };
fbc_med_order_in_set := event {OrderEnterNoIVAdditives User Order:
WHERE TypeCode = "Medication" AND IsPartOfSet = TRUE
and (OrderSetName in "FBC C Section Physician Orders", "Abdominal Hysterectomy Post Op", "Vaginal Hysterectomy Post Op", "Laparoscopic Hysterectomy") };
new_rad_IV_order := event {OrderEnterWithIVAdditives User Order:
WHERE TypeCode = "Medication" and (OrderSetName = "Post Initiation Catheter Directed Thrombolytic Therapy" and OrderRouteCode = "IV" ) };
// --------------------------------------------------
// Outpatient Prescription and Home Medication Orders
//---------------------------------------------------
// Comment out below triggers to exclude checking all Outpatient Orders
// To include Home Medications remove the code {{{SINGLE-QUOTE}}}AND OrderAddtionalInfo.IsScript <> FALSE{{{SINGLE-QUOTE}}}
outpatient_order_entry_trigger := event {OutpatientOrderEnterNoIVAdditive User Order:
WHERE TypeCode = "Medication" AND IsPartOfSet = TRUE
AND OrderAdditionalInfo.IsScript <> FALSE};
outpatient_order_init_trigger := event {OutpatientOrderInitNoIVAdditive User Order:
WHERE TypeCode = "Medication" AND IsPartOfSet = FALSE
AND OrderAdditionalInfo.IsScript <> FALSE};
outpatient_order_modify_trigger := event {OutpatientOrderModify User Order:
WHERE TypeCode = "Medication"
AND OrderAdditionalInfo.IsScript <> FALSE};
//------------------------
// Pharmacy Trigger Events
//------------------------
pharm_order_enter := event {OrderEnterPharmacyPerfect Any Order:
WHERE TypeCode = "Medication"};
pharm_order_modify :=
event {OrderModifyPharmacyPerfect Any Order:
WHERE TypeCode = "Medication"};
// ---------------------------
// Prescription Trigger Events
// ---------------------------
// Remove prescription types "Rx", or "Hx" from the list
// to exclude that type from checking
// Uncomment the line with {{{SINGLE-QUOTE}}}and SourceApplicationType NOT in (10, 15){{{SINGLE-QUOTE}}} if the alerts
// from this MLM should not occur in the {{{SINGLE-QUOTE}}}Meds from Other Sources{{{SINGLE-QUOTE}}} dialog when the user
// accepts a Surescripts or Community Medication as a Sunrise Home Medication.
// * 10 = SureScripts Medication
// * 15 = Community Medication (from dbMotion)
//
// Depending on the required behavior, edit the {{{SINGLE-QUOTE}}}(10, 15){{{SINGLE-QUOTE}}} as follows:
// * Exclude (10) to suppress the alert for SureScripts Medications
// * Exclude (15) to suppress alerts for Community Medications
// * Exclude (10, 15) to suppress alerts for both SureScripts and Community Medications
// * Don{{{SINGLE-QUOTE}}}t exclude any of 10 or 15 to show alerts for both (default)
any_new_prescription := EVENT { PrescriptionInit Any ClientPrescription
:WHERE PrescriptionTypeDescription in ("Rx","Hx")
//and SourceApplicationType NOT in (10, 15)
};
// Remove prescription types "Rx" from the list
// to exclude that type from checking
any_renew_prescription := EVENT { PrescriptionRenew Any ClientPrescription
:WHERE PrescriptionTypeDescription in ("Rx")
};
// ------------------------------
// Alert On Demand Trigger Events
// ------------------------------
order_alert_check := event {AlertCheckingOrder User Order
: WHERE ComplexOrderType not in (2, 4, 6)
AND IsHeld = FALSE
AND IsSuspended = FALSE
};
prescription_alert_check := event {AlertCheckingClientPrescription
User ClientPrescription
};
/* 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:= event{OrderAlternateEnterWithIVAdditive User Order:
where TypeCode = "Medication" AND AlternateOrderType = 1};
order_alternate_init_NOIV:= event{OrderAlternateInitNoIVAdditive User Order:
where TypeCode = "Medication" AND AlternateOrderType = 1};
order_alternate_modify:= event{OrderAlternateModify User Order:
where TypeCode = "Medication" AND AlternateOrderType = 1}; */
//**************************************************************************************
// Execute this only when this MLM is called by the editor
if called_by_editor
then
// Define object choice "Order", or "ClientPrescription"
Object_Choice :=
//"ClientPrescription";
"Order";
if (object_choice = "Order") then
EvokingObject:= read last
{Order: This
WHERE TypeCode = "Medication"
AND
Name = "isoniazid"
//Name = "acetaminophen"
//name = "Acetaminophen-Codeine"
//name = "Morphine"
};
else
EvokingObject:= read last
{ClientPrescription: This
WHERE PrescriptionTypeDescription in ("Rx", "Hx")
};
endif;
if (EvokingObject is null) then
// no order or prescription was found for the patient
// create a dummy prescription
evoking_rx_name := "morphine";
evoking_rx_cds_unique_guid := "123456";
evoking_rx_generic_name_id := 17;
evoking_rx_type := "Rx";
endif;
endif;
// Declare MLMs that can be called
func_drug_interaction_actions := MLM {{{SINGLE-QUOTE}}}STD_func_drug_interaction_actions{{{SINGLE-QUOTE}}};
func_session_type_filter := MLM {{{SINGLE-QUOTE}}}STD_FUNC_SESSION_TYPE_FILTER{{{SINGLE-QUOTE}}};
func_Alert_On_Demand_Filter := MLM {{{SINGLE-QUOTE}}}STD_Func_Alert_On_Demand_Filter{{{SINGLE-QUOTE}}};
func_multum_references := MLM {{{SINGLE-QUOTE}}}STD_FUNC_MULTUM_REFERENCES{{{SINGLE-QUOTE}}};
func_community_data_retrieval_rules:= MLM {{{SINGLE-QUOTE}}}STD_FUNC_COMMUNITY_DATA_RETRIEVAL_RULES{{{SINGLE-QUOTE}}};
// Used for building up references.
referenceDate_displayed := false;
// Retrieve user guid from State object
(user_guid) := read last { StateInfo: UserGUID};
// Retrieve clientvisit guid from State object
(visit_guid) := read last { StateInfo: visitGuid};
// Order status level number of active orders.
ActiveLevelNum := 50;
// Set the child order types
complex_child_order_type := (2,4,6);
// Initialize to TRUE
// continue_processing := TRUE;
// Custom code to only fire alert for nurses, doctors, and pharmacists
// fire_on_User := ("RN","IT","RPh","MD","DO","DDS","DPM","PA","PA-C","CRNP");
/* Get the current user{{{SINGLE-QUOTE}}}s occupation*/
// userguid :=read last {UserInfo: guid};
// UserCode := read last
// {"Select occupationcode "
// ||" From cv3user with (nolock) "
// ||" Where Guid = " || SQL(userguid) };
// continue_processing:= usercode in fire_on_User;
// IV-Additive TYPES are used to store additives in CV3OrderComponent.Type
// If more than two IV-additive types are used, add them to this list
// Note: Type 3 was used for calculated IV-dosage in CV3.1.2,
// but is not used in current version of SCM
iv_additive_type_list := 0, 3;
// Set Levels for Maximum found Severity Numbers
minimum_level := "Minor";
moderate_level := "Moderate";
major_level := "{{+B}}Major{{-B}}";
//Initialize variable to community medication string
community_medication_abstract_text := " (Community Data)";
// Initialize input XML parameter
evoking_order_parameter_xml := "";
evoking_rx_parameter_xml := "";
unsubmitted_order_parameter_xml := "";
unsub_rx_parameter_xml := "";
filter_rx_parameter_xml := "";
community_medication_parameter_xml := "";
if (EvokingObject is Order)
then
// Get information from the Order that evoked the MLM
(evoking_order_name,
evoking_order_guid,
evoking_catalog_item_guid,
evoking_order_additive_object_pointers,
evoking_order_alternate_order_type,
evoking_order_is_for_discharge,
evoking_order_significant_dtm,
evoking_order_requested_dtm,
evoking_order_entered_dtm,
client_guid,
evoking_med_source,
evoking_order_backup_object_pointers,
evoking_order_additional_info
) := read last
{Order: Name,
GUID,
OrderCatalogMasterItemGUID,
OrderComponent,
AlternateOrderType,
IsForDischarge,
SignificantDtm,
RequestedDtm,
Entered,
ClientGUID,
AlertOnDemandSource,
Backup,
OrderAdditionalInfo
REFERENCING EvokingObject };
(evoking_order_isScript) := read last
{OrderAdditionalInfo: IsScript REFERENCING
evoking_order_additional_info};
// When present, add additive names to this list current orders
if exist evoking_order_additive_object_pointers
then
(evoking_additive_name_list,
evoking_additive_GUID_list,
evoking_component_GUID_list) := read
{OrderComponent: Name, OrderCatalogMasterItemGUID, GUID
REFERENCING evoking_order_additive_object_pointers
where (Dosage AS Number) > 0 };
endif;
elseif (EvokingObject is ClientPrescription)
then
(evoking_rx_name,
evoking_rx_cds_unique_guid,
evoking_rx_generic_name_id,
evoking_rx_start_dtm,
evoking_rx_renewal_dtm,
evoking_rx_type,
client_guid,
evoking_med_source,
evoking_dispensed_detail_id ) := read last {ClientPrescription:
DrugName,
CDSUniqueIDGUID,
GenericNameID,
StartDate,
RenewalDate,
PrescriptionType,
ClientGUID,
AlertOnDemandSource,
DispensedDetailID
REFERENCING EvokingObject };
if (evoking_rx_renewal_dtm is NULL)
then
evoking_rx_significant_dtm := evoking_rx_start_dtm;
else
evoking_rx_significant_dtm := evoking_rx_renewal_dtm;
endif;
endif;
// When the flag is set to TRUE, the alert generated for all users does include dbMotion medication data
// that conflicts with current medication that triggered the call to the Interaction MLM.
if(enable_community_data_medication_alerts = true)
then
// mlm name is passed to STD_FUNC_COMMUNITY_DATA_RETRIEVAL_RULES which is responsible for user right{{{SINGLE-QUOTE}}}s
mlm_Name := "STD_DRUG_INTERACTION";
//To make sure that the below SUB MLM is called only when the flag is true.
(can_perform,can_retrieve_data_obj) := call func_community_data_retrieval_rules with
(
EvokingObject,
EvokingEventType,
mlm_Name,
community_data_excluded_triggers_list
);
else
can_perform := true;
endif;
if (can_perform = true)
then
is_alert_on_demand := false;
if (EvokingEventType = order_alert_check.type OR
EvokingEventType = prescription_alert_check.type)
then
alert_on_demand_obj := read last {StateInfo: AlertOnDemand};
aod_check_against_flag := alert_on_demand_obj.AlertCheckAgainstSelection;
// Get the session type bit flags and prescription type filter
// from the AlertCheckAgainstSelection flag
(order_table_name,
include_in_house_session_type_orders,
include_historical_session_type_orders,
include_discharge_session_type_orders,
include_outpatient_rx_session_type_orders,
include_outpatient_hx_session_type_orders,
unsubmitted_session_type_bit_flags,
unsubmitted_prescriptions_filter_list,
filter_prescriptions_query,
prescriptions_type_filter_list,
include_community_medication):= call func_Alert_On_Demand_Filter with
(aod_check_against_flag,
can_retrieve_data_obj.PendingImportedMedications);
is_alert_on_demand := true;
else
// Get the order table and filter query to filter the existing
// database orders that will be checked against the entered order.
// Get the session type bit flags to filter the unsubmitted orders
// that will be checked against the entered order.
(order_table_name,
filter_orders_query,
session_type_bit_flags,
filter_prescriptions_query,
prescriptions_type_filter_list,
include_in_house_session_type_orders,
include_historical_session_type_orders,
include_discharge_session_type_orders,
include_outpatient_rx_session_type_orders,
include_outpatient_hx_session_type_orders,
include_community_medication) :=
call func_session_type_filter with
(at_in_house_session_list,
at_historical_session_list,
at_discharge_session_list,
at_outpatient_session_list,
at_prescription_session_list,
at_prescription_historical_session_list,
can_retrieve_data_obj.PendingImportedMedications,
evoking_order_is_for_discharge,
evoking_order_alternate_order_type,
evoking_rx_type);
unsubmitted_prescriptions_filter_list := prescriptions_type_filter_list;
endif;
//for modify, only continue if IV additives have been added
if ( EvokingEventType = order_modify_trigger.type ) OR
( EvokingEventType = order_alternate_modify.type )
then
evoking_order_component_backup_object_pointers :=
evoking_order_backup_object_pointers.OrderComponent;
(backup_component_GUID_list) := read
{OrderComponent: GUID
REFERENCING evoking_order_component_backup_object_pointers
where (Dosage AS Number) > 0 };
if evoking_component_GUID_list IS NULL then
continue_processing := FALSE;
else
NewComponents := ();
num_components := count (evoking_component_GUID_list);
for J in (1 seqto num_components ) do
one_new_component:= evoking_component_GUID_list[J];
if NOT one_new_component IN backup_component_GUID_list
then
NewComponents:= NewComponents, one_new_component;
endif;
enddo;
if count (NewComponents) = 0 then
continue_processing := FALSE;
endif;
endif; //if NewComponentGUIDlist is NULL
endif;
if continue_processing
then
// If the evoking medication source is from a catalog,
// change the status to say "Selected " order/prescription
if (evoking_med_source = "EvokingCatalog")
then
evoking_is_selected := 1;
else
evoking_is_selected := 0;
endif;
// Add evoking object information in the input XML parameter
if (EvokingObject is Order)
then
evoking_order_parameter_xml :=
" <Order " ||
" IsEvoking= {{{SINGLE-QUOTE}}}1{{{SINGLE-QUOTE}}} " ||
" IsSelected={{{SINGLE-QUOTE}}}" || XMLEX(evoking_is_selected) || "{{{SINGLE-QUOTE}}} " ||
" GUID={{{SINGLE-QUOTE}}}" || evoking_order_guid || "{{{SINGLE-QUOTE}}} " ||
" Name={{{SINGLE-QUOTE}}}" || XMLEX(evoking_order_name) || "{{{SINGLE-QUOTE}}} " ||
" CatalogGUID={{{SINGLE-QUOTE}}}" || evoking_catalog_item_guid || "{{{SINGLE-QUOTE}}}" ||
" OrderOrAdditiveName={{{SINGLE-QUOTE}}}" || XMLEX(evoking_order_name) || "{{{SINGLE-QUOTE}}}" ||
" StartDtm={{{SINGLE-QUOTE}}}" || XMLEX(evoking_order_significant_dtm) || "{{{SINGLE-QUOTE}}}" ||
" RequestedDtm={{{SINGLE-QUOTE}}}" || XMLEX(evoking_order_requested_dtm) || "{{{SINGLE-QUOTE}}}" ||
" EnteredDtm={{{SINGLE-QUOTE}}}" || XMLEX(evoking_order_entered_dtm) || "{{{SINGLE-QUOTE}}}" ||
" AlternateOrderType={{{SINGLE-QUOTE}}}" || XMLEX(evoking_order_alternate_order_type) || "{{{SINGLE-QUOTE}}}" ||
" IsScript={{{SINGLE-QUOTE}}}" || XMLEX(evoking_order_isScript) || "{{{SINGLE-QUOTE}}}" ||
" ItemType={{{SINGLE-QUOTE}}}Regular{{{SINGLE-QUOTE}}}" ||
"/>\n";
additive_index_list := 1 seqto count (evoking_additive_GUID_list);
for additive_ind in additive_index_list do
evoking_additive_cat_GUID := evoking_additive_GUID_list[additive_ind];
evoking_additive_name := evoking_additive_name_list[additive_ind];
if (evoking_additive_cat_GUID is not null) then
evoking_additive_xml :=
" <Order " ||
" IsEvoking = {{{SINGLE-QUOTE}}}1{{{SINGLE-QUOTE}}} " ||
" IsSelected={{{SINGLE-QUOTE}}}" || XMLEX(evoking_is_selected) || "{{{SINGLE-QUOTE}}} " ||
" GUID={{{SINGLE-QUOTE}}}" || evoking_order_guid || "{{{SINGLE-QUOTE}}} " ||
" Name={{{SINGLE-QUOTE}}}" || XMLEX(evoking_order_name) || "{{{SINGLE-QUOTE}}} " ||
" CatalogGUID={{{SINGLE-QUOTE}}}" || evoking_additive_cat_GUID || "{{{SINGLE-QUOTE}}}" ||
" OrderOrAdditiveName={{{SINGLE-QUOTE}}}" || XMLEX(evoking_additive_name) || "{{{SINGLE-QUOTE}}}" ||
" StartDtm={{{SINGLE-QUOTE}}}" || XMLEX(evoking_order_significant_dtm) || "{{{SINGLE-QUOTE}}}" ||
" RequestedDtm={{{SINGLE-QUOTE}}}" || XMLEX(evoking_order_requested_dtm) || "{{{SINGLE-QUOTE}}}" ||
" EnteredDtm={{{SINGLE-QUOTE}}}" || XMLEX(evoking_order_entered_dtm) || "{{{SINGLE-QUOTE}}}" ||
" AlternateOrderType={{{SINGLE-QUOTE}}}" || XMLEX(evoking_order_alternate_order_type) || "{{{SINGLE-QUOTE}}}" ||
" IsScript={{{SINGLE-QUOTE}}}" || XMLEX(evoking_order_isScript) || "{{{SINGLE-QUOTE}}}" ||
" ItemType={{{SINGLE-QUOTE}}}Additive{{{SINGLE-QUOTE}}}" ||
"/>\n";
evoking_order_parameter_xml := evoking_order_parameter_xml || evoking_additive_xml;
endif;
enddo;
evoking_item_guid := evoking_order_guid;
evoking_item_name := evoking_order_name;
else
evoking_rx_parameter_xml :=
" <Prescription " ||
" IsEvoking = {{{SINGLE-QUOTE}}}1{{{SINGLE-QUOTE}}} " ||
" IsSelected={{{SINGLE-QUOTE}}}" || XMLEX(evoking_is_selected) || "{{{SINGLE-QUOTE}}} " ||
" GUID={{{SINGLE-QUOTE}}}" || evoking_rx_cds_unique_guid || "{{{SINGLE-QUOTE}}} " ||
" Name={{{SINGLE-QUOTE}}}" || XMLEX(evoking_rx_name) || "{{{SINGLE-QUOTE}}} " ||
" GenericNameID={{{SINGLE-QUOTE}}}" || evoking_rx_generic_name_id || "{{{SINGLE-QUOTE}}} " ||
" StartDtm={{{SINGLE-QUOTE}}}" || XMLEX(evoking_rx_significant_dtm) || "{{{SINGLE-QUOTE}}}" ||
"/>\n";
evoking_item_guid := evoking_rx_cds_unique_guid;
evoking_item_name := evoking_rx_name;
endif; // END if EvokingObject - for adding evoking object info
unsubmitted_session_flag_override := false;
if (is_alert_on_demand AND not include_in_house_session_type_orders)
then
include_in_house_session_type_orders := true;
unsubmitted_session_flag_override := true;
endif;
// Get the unsubmitted orders
// that should be checked for drug interactions.
// These are New or Modified orders
(unsub_intended_action_list,
unsub_order_name_list,
unsub_order_guid_list,
unsub_catalog_item_guid_list,
unsub_order_additiveobj_list,
unsub_order_significant_dtm_list,
unsub_order_requested_dtm_list,
unsub_order_entered_dtm_list,
unsub_order_med_source_list,
unsub_alternate_order_type_list,
unsub_additional_order_info_list ) := read
{Unsubmitted Order: IntendedAction, Name, GUID, OrderCatalogMasterItemGUID, OrderComponent, SignificantDtm, RequestedDtm, Entered,
AlertOnDemandSource, AlternateOrderType, OrderAdditionalInfo
WHERE TypeCode = "Medication"
AND (evoking_order_GUID is NULL
OR GUID <> evoking_order_GUID )
AND ComplexOrderType IS NOT IN complex_child_order_type
AND (IntendedAction is NULL
OR IntendedAction is in ("Add New", "Modify", "Modified", "Suspend"))
AND not( (not include_in_house_session_type_orders AND (AlternateOrderType = 0 AND IsForDischarge = false)) OR
(not include_historical_session_type_orders AND AlternateOrderType = 1) OR
(not include_discharge_session_type_orders AND IsForDischarge) OR
(not include_outpatient_rx_session_type_orders AND (AlternateOrderType = 2 AND OrderAdditionalInfo.IsScript = true)) OR
(not include_outpatient_hx_session_type_orders AND (AlternateOrderType = 2 AND OrderAdditionalInfo.IsScript = false)))
};
if (unsubmitted_session_flag_override)
then
include_in_house_session_type_orders := false;
endif;
// For each unsubmitted order, add the order-name and additive info (if any),
// to the list of unsubmitted order names to be processed.
unsubmitted_order_parameter_xml := "";
index_list := 1 seqto count (unsub_order_name_list);
for JJ in index_list do
If EVOKINGOBJECT.OrderSetName in ("FBC C Section Physician Orders", "Abdominal Hysterectomy Post Op", "Vaginal Hysterectomy Post Op", "Laparoscopic Hysterectomy")
and ((EVOKINGOBJECT.Name = "Ibuprofen 800mg Tab") or (EVOKINGOBJECT.Name = "Ketorolac Inj")) then
addtolist := false;
elseif EVOKINGOBJECT.OrderSetName = "tPA (Alteplase) for the Treatment of Pulmonary Embolism (PE)"
and ((EVOKINGOBJECT.Name = "Alteplase") or (EVOKINGOBJECT.Name matches pattern "Heparin%")) then
addtolist := false;
elseif EVOKINGOBJECT.OrderSetName = "Intravenous Infliximab (Remicade) or Infliximab-dyyb (Inflectra) Physician Order Set"
and ((EVOKINGOBJECT.Name = "MethylPREDNISolone Inj") or (EVOKINGOBJECT.Name matches pattern "Infliximab%")) then
addtolist := false;
else
addtolist := true;
endif;
unsub_order_guid := unsub_order_guid_list[JJ];
unsub_cat_guid := unsub_catalog_item_guid_list[JJ];
unsub_additiveObj := unsub_order_additiveobj_list[JJ];
unsub_order_name := unsub_order_name_list[JJ];
unsub_order_significant_dtm := unsub_order_significant_dtm_list[JJ];
unsub_order_requested_dtm := unsub_order_requested_dtm_list[JJ];
unsub_order_entered_dtm := unsub_order_entered_dtm_list[JJ];
unsub_order_med_source := unsub_order_med_source_list[JJ];
unsub_alternate_order_type := unsub_alternate_order_type_list[JJ];
unsub_order_additional_info := unsub_additional_order_info_list[JJ];
unsub_order_isScript := read last {OrderAdditionalInfo: IsScript REFERENCING unsub_order_additional_info};
if (unsub_order_med_source = "EvokingCatalog" OR
unsub_order_med_source = "SelectedCatalog" )
then
unsub_is_selected := 1;
else
unsub_is_selected := 0;
endif;
If addtolist = true then
unsubmitted_order_parameter_xml := unsubmitted_order_parameter_xml||
" <Order " ||
" IsEvoking={{{SINGLE-QUOTE}}}0{{{SINGLE-QUOTE}}} " ||
" IsSelected={{{SINGLE-QUOTE}}}" || XMLEX(unsub_is_selected) || "{{{SINGLE-QUOTE}}} " ||
" GUID={{{SINGLE-QUOTE}}}" || unsub_order_guid || "{{{SINGLE-QUOTE}}} " ||
" Name={{{SINGLE-QUOTE}}}" || XMLEX(unsub_order_name) || "{{{SINGLE-QUOTE}}} " ||
" CatalogGUID={{{SINGLE-QUOTE}}}" || unsub_cat_guid || "{{{SINGLE-QUOTE}}}" ||
" OrderOrAdditiveName={{{SINGLE-QUOTE}}}" || XMLEX(unsub_order_name) || "{{{SINGLE-QUOTE}}}" ||
" StartDtm={{{SINGLE-QUOTE}}}" || XMLEX(unsub_order_significant_dtm) || "{{{SINGLE-QUOTE}}}" ||
" RequestedDtm={{{SINGLE-QUOTE}}}" || XMLEX(unsub_order_requested_dtm) || "{{{SINGLE-QUOTE}}}" ||
" EnteredDtm={{{SINGLE-QUOTE}}}" || XMLEX(unsub_order_entered_dtm) || "{{{SINGLE-QUOTE}}}" ||
" AlternateOrderType={{{SINGLE-QUOTE}}}" || XMLEX(unsub_alternate_order_type) || "{{{SINGLE-QUOTE}}}" ||
" IsScript={{{SINGLE-QUOTE}}}" || XMLEX(unsub_order_isScript) || "{{{SINGLE-QUOTE}}}" ||
" ItemType={{{SINGLE-QUOTE}}}Regular{{{SINGLE-QUOTE}}}" ||
"/>\n";
// If there is are additives obtain the info
if exist unsub_additiveObj
then
(temp_additive_name_list,
temp_item_guid_list):= read
{ OrderComponent: Name, OrderCatalogMasterItemGUID
REFERENCING unsub_additiveObj
where (Dosage AS Number) > 0 };
// Equalize the length of the lists
additive_index_list := 1 seqto count(temp_additive_name_list);
for additive_ind in additive_index_list do
unsubmitted_additive_cat_GUID := temp_item_guid_list[additive_ind];
unsubmitted_additive_name := temp_additive_name_list[additive_ind];
if (unsubmitted_additive_cat_GUID is not null)
then
unsubmitted_additive_xml :=
" <Order " ||
" IsEvoking={{{SINGLE-QUOTE}}}0{{{SINGLE-QUOTE}}} " ||
" IsSelected={{{SINGLE-QUOTE}}}" || XMLEX(unsub_is_selected) || "{{{SINGLE-QUOTE}}} " ||
" GUID={{{SINGLE-QUOTE}}}" || unsub_order_guid || "{{{SINGLE-QUOTE}}} " ||
" Name={{{SINGLE-QUOTE}}}" || XMLEX(unsub_order_name) || "{{{SINGLE-QUOTE}}} " ||
" CatalogGUID={{{SINGLE-QUOTE}}}" || unsubmitted_additive_cat_GUID || "{{{SINGLE-QUOTE}}}" ||
" OrderOrAdditiveName={{{SINGLE-QUOTE}}}" || XMLEX(unsubmitted_additive_name) || "{{{SINGLE-QUOTE}}}" ||
" StartDtm={{{SINGLE-QUOTE}}}" || XMLEX(unsub_order_significant_dtm) || "{{{SINGLE-QUOTE}}}" ||
" RequestedDtm={{{SINGLE-QUOTE}}}" || XMLEX(unsub_order_requested_dtm) || "{{{SINGLE-QUOTE}}}" ||
" EnteredDtm={{{SINGLE-QUOTE}}}" || XMLEX(unsub_order_entered_dtm) || "{{{SINGLE-QUOTE}}}" ||
" AlternateOrderType={{{SINGLE-QUOTE}}}" || XMLEX(unsub_alternate_order_type) || "{{{SINGLE-QUOTE}}}" ||
" IsScript={{{SINGLE-QUOTE}}}" || XMLEX(unsub_order_isScript) || "{{{SINGLE-QUOTE}}}" ||
" ItemType={{{SINGLE-QUOTE}}}Additive{{{SINGLE-QUOTE}}}" ||
"/>\n";
unsubmitted_order_parameter_xml :=
unsubmitted_order_parameter_xml || unsubmitted_additive_xml;
endif;
enddo; //for additive_index_list
endif; //if exist unsub_additiveObj
endif; //if C-Section order
enddo; //for for JJ
// Get the unsubmitted prescriptions
// that should be checked for therapeutic duplication.
// These are New or Modified prescriptions
(unsub_rx_name_list,
unsub_rx_cds_unique_guid_list,
unsub_rx_generic_name_id_list,
unsub_rx_start_dtm_list,
unsub_rx_renewal_dtm_list,
unsub_rx_prescription_type_list,
unsub_rx_med_source_list ) := read
{Unsubmitted ClientPrescription:
DrugName,
CDSUniqueIDGUID,
GenericNameID,
StartDate,
RenewalDate,
PrescriptionType,
AlertOnDemandSource
WHERE PrescriptionType in unsubmitted_prescriptions_filter_list
};
unsub_rx_parameter_xml := "";
unsub_rx_index_list := 1 seqto count(unsub_rx_name_list);
for unsub_rx_ind in unsub_rx_index_list
do
unsub_rx_cds_unique_guid :=
unsub_rx_cds_unique_guid_list[unsub_rx_ind];
unsub_rx_name :=
unsub_rx_name_list[unsub_rx_ind];
unsub_rx_generic_name_id :=
unsub_rx_generic_name_id_list[unsub_rx_ind];
unsub_rx_med_source := unsub_rx_med_source_list[unsub_rx_ind];
unsub_rx_prescription_type := unsub_rx_prescription_type_list[unsub_rx_ind];
if (unsub_rx_med_source = "EvokingCatalog" OR
unsub_rx_med_source = "SelectedCatalog" )
then
unsub_is_selected := 1;
else
unsub_is_selected := 0;
endif;
if (unsub_rx_renewal_dtm_list[unsub_rx_ind] is not null)
then
unsub_rx_significant_dtm := unsub_rx_renewal_dtm_list[unsub_rx_ind];
else
unsub_rx_significant_dtm := unsub_rx_start_dtm_list[unsub_rx_ind];
endif;
unsub_rx_parameter_xml := unsub_rx_parameter_xml ||
" <Prescription " ||
" IsEvoking = {{{SINGLE-QUOTE}}}0{{{SINGLE-QUOTE}}} " ||
" IsSelected={{{SINGLE-QUOTE}}}" || XMLEX(unsub_is_selected) || "{{{SINGLE-QUOTE}}} " ||
" PrescriptionType = {{{SINGLE-QUOTE}}}" || XMLEX(unsub_rx_prescription_type) || "{{{SINGLE-QUOTE}}} " ||
" GUID={{{SINGLE-QUOTE}}}" || unsub_rx_cds_unique_guid || "{{{SINGLE-QUOTE}}} " ||
" Name={{{SINGLE-QUOTE}}}" || XMLEX(unsub_rx_name) || "{{{SINGLE-QUOTE}}} " ||
" GenericNameID={{{SINGLE-QUOTE}}}" || unsub_rx_generic_name_id || "{{{SINGLE-QUOTE}}} " ||
" StartDtm={{{SINGLE-QUOTE}}}" || XMLEX(unsub_rx_significant_dtm) || "{{{SINGLE-QUOTE}}}" ||
"/>\n";
enddo; // END for unsub_rx_ind
for rx_type in prescriptions_type_filter_list
do
filter_rx_parameter_xml := filter_rx_parameter_xml ||
" <FilterPrescriptionType " ||
" PrescriptionType={{{SINGLE-QUOTE}}}" || rx_type || "{{{SINGLE-QUOTE}}} " ||
" />\n";
enddo;
// Community medication parameter
orig_pending_community_med_str := "";
if (evoking_dispensed_detail_id is not null)
then
orig_pending_community_med_str := " OriginalCommunityMedicationId={{{SINGLE-QUOTE}}}" ||
XMLEX(evoking_dispensed_detail_id) || "{{{SINGLE-QUOTE}}}";
endif;
// exclude pending community medication parameter
exclude_older_than_days_str := "";
if (exclude_pending_community_meds_older_than_days is not null)
then
exclude_older_than_days_str := " ExcludeOlderThanDays={{{SINGLE-QUOTE}}}"|| XMLEX(exclude_pending_community_meds_older_than_days) || "{{{SINGLE-QUOTE}}}";
endif;
community_medication_parameter_xml := community_medication_parameter_xml ||
" <CommunityMedication " ||
" IsIncluded={{{SINGLE-QUOTE}}}"|| XMLEX(include_community_medication) || "{{{SINGLE-QUOTE}}}" ||
orig_pending_community_med_str ||
exclude_older_than_days_str ||
" ExistingHomeMedClientVisitGUID={{{SINGLE-QUOTE}}}"|| visit_guid || "{{{SINGLE-QUOTE}}}" ||
" />\n";
//-----------------//
// Initializations //
//-----------------//
// Initialize the alert message variables
alert_header_msg := "";
indent := " ";
msg_unmapped_str := "{{+B}}Unmapped{{-B}} (NOT checked for drug interactions)\n";
msg_detail_str := "{{+B}}Details for {{-B}}";
msg_severity_list := minimum_level, moderate_level, major_level;
//********************************************************
// Initial Max severity level
//--------------------------------------//
// Loop Through The Drugs Being Ordered //
//--------------------------------------//
// This can be more than one item if IV additives are being ordered.
alert_to_display := false;
alert_detail_major := "";
alert_detail_moderate := "";
alert_detail_minor := "";
alert_detail_food := "";
int_msg_header_drugs := "";
int_msg_header_foods := "";
evoking_unmapped_drug_names := ();
concomit_unmapped_drug_names := ();
alert_abstract_ingredient_names := ();
alert_abstract_str := "";
unmapped_alert_abstract_str := "";
prev_med_display_name := "";
input_parameter_xml := "\n<ROOT>\n" ||
evoking_order_parameter_xml ||
evoking_rx_parameter_xml ||
unsubmitted_order_parameter_xml ||
unsub_rx_parameter_xml ||
filter_rx_parameter_xml ||
community_medication_parameter_xml ||
"</ROOT>\n";
//Declare the Med_Data_Object
Med_Data_Object := OBJECT [
reference_title,
current_order_ID,
drug2ID
];
// Get the last revision date of the Multum database, strip out time portion
revision_date := read last { "select change_date from SXAMTdatabase_infoSYN" };
revision_date := revision_date formatted with "%.2t";
revision_date_string := "\n{{+B}}Revision Date{{-B}}: " || revision_date;
mdo_reference_list:=();
// need to convert boolean value to a bit
alert_drug_food_flag := alert_drug_food as number;
(
interaction_current_order_name_list,
interaction_current_drug_name_list,
interaction_current_ingredient_name_list,
interaction_current_drug_ID_list,
interaction_current_item_type_list, // regular, or additive
interaction_current_is_combo_list,
interaction_severity_text,
interaction_text_list,
interaction_type_list,
interaction_level_list,
interaction_sequence_list,
interaction_concomit_order_name_list,
interaction_concomit_drug_name_list,
interaction_concomit_ingredient_name_list,
interaction_concomit_drug_ID_list,
interaction_concomit_order_guid_list,
interaction_concomit_order_catalog_item_guid_list,
interaction_concomit_item_type_list, // regular, or additive
interaction_concomit_item_status_list, // evoking, unsubmitted, or existing
interaction_concomit_order_status_num_list,
interaction_concomit_is_suspended_list,
interaction_concomit_is_order_list,
interaction_concomit_is_combo_list,
interaction_concomit_start_date_list,
interaction_concomit_requested_date_list,
interaction_concomit_entered_date_list,
interaction_concomit_alternate_order_type_list,
interaction_concomit_is_script_list,
interaction_concomit_prescriptiontype_list
):= read{" SXADrugInteractionCheckingPr "
|| SQL(input_parameter_xml) || ", "
|| SQL(evoking_item_guid) || ", "
|| SQL(client_guid) || ", "
|| SQL(user_guid) || ", "
|| SQL(include_in_house_session_type_orders) || ", "
|| SQL(include_discharge_session_type_orders) || ", "
|| SQL(include_historical_session_type_orders) || ", "
|| SQL(include_outpatient_rx_session_type_orders) || ", "
|| SQL(include_outpatient_hx_session_type_orders) || ", "
|| SQL(alert_drug_food_flag)};
// process each interaction
nTotalInteractions := count(interaction_concomit_drug_ID_list);
// Alert message processing for the previous evoking drug is done
// at the top of the loop, when the evoking drug changes
// Add an extra index to the loop to handle the last evoking drug
nIndexInteractions := 1 seqto (nTotalInteractions + 1);
for YY in nIndexInteractions do
current_order_name := interaction_current_order_name_list[YY];
current_drug_name := interaction_current_drug_name_list[YY];
current_ingredient_name := interaction_current_ingredient_name_list[YY];
current_order_ID := interaction_current_drug_ID_list[YY];
current_is_iv_additive := interaction_current_item_type_list[YY] = "Additive";
current_is_combo := interaction_current_is_combo_list[YY];
current_interaction_type := interaction_type_list[YY];
current_is_order := interaction_concomit_is_order_list[YY];
//-----------------------------------------------//
// Format current evoking drug display name
//-----------------------------------------------//
// Single ingredient medication - order_name
// Codeine
// Combo drug - order_name (COMPONENT: ingredient_name)
// Aspirin-Codeine (COMPONENT CODEINE)
// Additive - <medication display name> in order_name
// Aspirin-Codeine (COMPONENT CODEINE) additive in Lidocaine 5% Soln
if current_is_combo then
current_med_display_name := current_drug_name || " (COMPONENT:" || current_ingredient_name || ")";
else
current_med_display_name := current_drug_name;
endif;
current_med_display_name := "{{+B}}{{+R}}" || current_med_display_name || "{{-R}}{{-B}}";
if ( current_is_iv_additive ) then
current_med_display_name := current_med_display_name || " additive in " || current_order_name;
endif;
//---------------------------------------------------//
// Handle interactions for the current evoking drug
//---------------------------------------------------//
// Interactions are sorted by evoking drug, so once
// it moves to the next evoking drug, create the header
// for the previous evoking drug
if (current_med_display_name <> prev_med_display_name)
then
// Generate alert message if there are interactions or unmapped med is found
if (found_interactions)
then
//----------------------------------//
// Create INTERACTION Alert Message //
//----------------------------------//
alert_to_display := true;
max_current_sev_level := max(current_sev_level_list);
max_sev := msg_severity_list[max_current_sev_level];
if (nInteractions = 1) then
curr_header_msg := "There is an {{+B}}{{+R}}interaction{{-R}}{{-B}} ";
else
curr_header_msg := "There are " || "{{+B}}{{+R}}" || nInteractions || " interactions{{-R}}{{-B}} ";
endif;
med_display_type := "medication";
if (evoking_order_alternate_order_type = 2) then
if ( evoking_order_isScript ) then
med_display_type := "prescription";
else
med_display_type := "home medication";
endif;
endif;
curr_header_msg := curr_header_msg
|| "with the " || prev_med_display_name || " " || med_display_type || ".\n"
|| "(Max severity is " || max_sev || ")\n"
|| int_msg_header_drugs
|| int_msg_header_foods
|| "\n";
alert_header_msg := alert_header_msg || curr_header_msg;
endif;
// Initialize values for the new evoking drug
nInteractions := 0;
found_interactions := false;
current_sev_level_list := ();
int_msg_header_drugs := "";
int_msg_header_foods := "";
alert_detail_header_current_med := msg_detail_str || current_med_display_name || "-";
endif;
// The last item in the for loop is beyond
// the interaction list (nTotalInteractions+1)
// Only process valid interactions
if (YY <= nTotalInteractions)
then
prev_med_display_name := current_med_display_name;
if (current_order_ID is null)
then
evoking_unmapped_drug_names := evoking_unmapped_drug_names, current_med_display_name;
if (current_drug_name not in alert_abstract_ingredient_names)
then
alert_abstract_ingredient_names := alert_abstract_ingredient_names, current_drug_name;
if (unmapped_alert_abstract_str <> "")
then
unmapped_alert_abstract_str := unmapped_alert_abstract_str || ", ";
endif;
unmapped_alert_abstract_str := unmapped_alert_abstract_str || "Unmapped - " || current_drug_name;
endif;
else
drug2OrderName := interaction_concomit_order_name_list[YY];
drug2DrugName := interaction_concomit_drug_name_list[YY];
drug2IngredientName := interaction_concomit_ingredient_name_list[YY];
drug2ID := interaction_concomit_drug_ID_list[YY];
drug2ItemStatus := interaction_concomit_item_status_list[YY];
drug2IsAdditive := interaction_concomit_item_type_list[YY] = "Additive";
int_sev_level := (interaction_level_list[YY]) as number;
int_sevtext := interaction_severity_text[YY];
inttext := interaction_text_list[YY];
drug2OrderStausNum := interaction_concomit_order_status_num_list[YY];
drug2IsSuspended := interaction_concomit_is_suspended_list[YY];
drug2IsCombo := interaction_concomit_is_combo_list[YY];
drug2StartDate := interaction_concomit_start_date_list[YY];
drug2RequestedDate := interaction_concomit_requested_date_list[YY];
drug2EnteredDate := interaction_concomit_entered_date_list[YY];
drug2AlternateOrderType := interaction_concomit_alternate_order_type_list[YY];
drug2IsScript := interaction_concomit_is_script_list[YY];
drug2PrescriptionType := interaction_concomit_prescriptiontype_list[YY];
//-----------------------------------------------//
// Format concomit drug display name
//-----------------------------------------------//
// Single ingredient medication - order_name
// Codeine
// Combo drug - order_name (COMPONENT: ingredient_name)
// Aspirin-Codeine (COMPONENT CODEINE)
// Additive - <medication display name> in order_name
// Aspirin-Codeine (COMPONENT CODEINE) additive in Lidocaine 5% Soln
if drug2IsCombo
then
drug2DisplayName := drug2DrugName || "(COMPONENT: " || drug2IngredientName || ")";
else
drug2DisplayName := drug2DrugName;
endif;
drug2DisplayName := "{{+C}}" || drug2DisplayName || "{{-C}}";
if (drug2IsAdditive)
then
drug2DisplayName := drug2DisplayName || " additive in " || drug2OrderName;
endif;
//-----------------------------------------------//
// Check for Interaction and Format Message //
//-----------------------------------------------//
if drug2ID is not null then
IsFood := drug2ID MATCHES PATTERN "food%";
// Check if interacting drug is from an order in the database
drug_is_in_database := drug2ItemStatus MATCHES PATTERN "existing%";
IsCurrent := (drug2OrderStausNum = ActiveLevelNum) and (drug2IsSuspended = false);
IsInactive := ((drug2OrderStausNum = ActiveLevelNum) and (drug2IsSuspended = true)) or (drug2OrderStausNum < ActiveLevelNum);
// Check if interacting drug is an Unsubmitted drug
IsUnsubmitted := NOT (drug_is_in_database or IsFood);
current_sev_level_list := current_sev_level_list, int_sev_level;
if (IsFood or IsUnsubmitted or IsCurrent or IsInactive)
then
found_interactions := TRUE;
nInteractions := nInteractions + 1;
current_sev_level_list := current_sev_level_list, int_sev_level;
alert_interaction_detail := alert_detail_header_current_med || drug2DisplayName;
//appending the "Pending" flag
if(enable_community_data_medication_alerts = true AND drug2PrescriptionType = enum_rx_type_Community_Med)
then
int_sevtext :=int_sevtext ||"{{+B}}"|| pending_community_medication_alert_text ||"{{-B}}" ;
endif;
if (not IsFood)
then
int_msg_header_drugs := int_msg_header_drugs || indent || drug2DisplayName || ": " || int_sevtext || "\n";
drug2DatePrefix := "Start Date: ";
drug2StatusSuffix := "Order";
// Format the start date string
if (current_is_order)
then
if (drug2AlternateOrderType = 2)
then
if (drug2RequestedDate is NULL or drug2RequestedDate = "")
then
drug2DatePrefix := "Entered Date: ";
endif;
if (drug2IsScript)
then
drug2StatusSuffix := "Prescription";
else
drug2StatusSuffix := "Home Medication";
endif;
elseif (drug2AlternateOrderType = 1)
then
drug2StatusSuffix := "";
endif;
// Order Start time is formatted as MON-DD HH:MM
drug2_date_time_str := drug2StartDate formatted with "%.4t";
else
//is prescription
if (drug2StartDate is NULL)
then
drug2_date_time_str := "<N/A>";
else
// Prescription Start time is formatted as MON-DD
drug2_date_time_str := drug2StartDate formatted with "%.2t";
endif;
//Status string of the Details header line should display as "Pending Community Medication" in blue for pending Community Medication
if(drug2PrescriptionType = 1)
then
drug2StatusSuffix := "Prescription";
elseif(drug2PrescriptionType = 3)
then
drug2StatusSuffix := "Home Medication";
elseif(enable_community_data_medication_alerts = true AND drug2PrescriptionType = 5)
then
drug2StatusSuffix := "Community Medication";
endif;
endif;
alert_interaction_detail := alert_interaction_detail || " " ||
drug2DatePrefix || drug2_date_time_str || " " ||
" Status: " || "{{+C}}"|| drug2ItemStatus || " " || drug2StatusSuffix ||"{{-C}}" || "\n";
else
int_msg_header_foods := int_msg_header_foods ||
indent || drug2DisplayName || ": " || int_sevtext || "\n";
alert_interaction_detail := alert_interaction_detail || "\n";
endif;
alert_interaction_detail := alert_interaction_detail || inttext || "\n\n";
if (drug2IngredientName not in alert_abstract_ingredient_names)
then
alert_abstract_ingredient_names := alert_abstract_ingredient_names, drug2IngredientName;
if (alert_abstract_str <> "")
then
alert_abstract_str := alert_abstract_str || ", ";
endif;
alert_abstract_str := alert_abstract_str || drug2IngredientName;
// Add the phrase community_medication_abstract_text next to the Medication, when it is a Community Medication
if(enable_community_data_medication_alerts = true AND drug2PrescriptionType = enum_rx_type_Community_Med)
then
alert_abstract_str := alert_abstract_str || community_medication_abstract_text;
endif;
endif;
if (isFood)
then
alert_detail_food := alert_detail_food || alert_interaction_detail;
elseif (int_sev_level = 3)
then
alert_detail_major := alert_detail_major || alert_interaction_detail;
elseif (int_sev_level = 2)
then
alert_detail_moderate := alert_detail_moderate || alert_interaction_detail;
elseif (int_sev_level = 1)
then
alert_detail_minor := alert_detail_minor || alert_interaction_detail;
endif;
endif;
else // (drug2ID is null)
// If we are to alert on unmapped drugs then create message
if (alert_if_unmapped)
then
concomit_unmapped_drug_names := concomit_unmapped_drug_names,
drug2DisplayName;
if (drug2IngredientName not in alert_abstract_ingredient_names)
then
alert_abstract_ingredient_names := alert_abstract_ingredient_names, drug2IngredientName;
if (unmapped_alert_abstract_str <> "")
then
unmapped_alert_abstract_str := unmapped_alert_abstract_str || ", ";
endif;
unmapped_alert_abstract_str := unmapped_alert_abstract_str || "Unmapped - " || drug2IngredientName;
endif;
endif;
endif;
endif; // end IF current_order_ID is unmapped
if current_order_ID is not null AND drug2ID is not null
then
temp_mdo_cross_list := ();
temp_mdo_map_list := ();
instance := new Med_Data_Object;
instance.reference_title := current_ingredient_name || " - " || drug2IngredientName;
instance.current_order_ID := current_order_ID;
instance.drug2ID := drug2ID;
if exist mdo_reference_list
then
temp_mdo_cross_list := mdo_reference_list
where mdo_reference_list.drug2ID = current_order_ID
and mdo_reference_list.current_order_ID = drug2ID;
temp_mdo_map_list := mdo_reference_list
where mdo_reference_list.current_order_ID = current_order_ID
and mdo_reference_list.drug2ID = drug2ID;
endif;
if (not exist temp_mdo_cross_list) and (not exist temp_mdo_map_list)
then
mdo_reference_list := mdo_reference_list, instance;
endif;
endif;
endif;
enddo;
// Initialize to empty
alert_unmapped_evoking_msg := "";
alert_unmapped_concomit_msg := "";
If alert_if_unmapped
then
// Now process any unmapped drugs that were being ordered
nUnmappedEvoking := count (evoking_unmapped_drug_names);
If nUnmappedEvoking > 0
then
alert_to_display := true;
index_list := 1 seqto nUnmappedEvoking;
for evoking_ind in index_list do
unmapped_order_name := evoking_unmapped_drug_names[evoking_ind];
alert_unmapped_evoking_msg := alert_unmapped_evoking_msg ||
"Your medication for " || unmapped_order_name
|| " was {{+B}}not checked for possible"
|| " interactions{{-B}} with other patient medications."
|| " Please use an alternate plan to do the check."
|| " \n\n This drug was not checked because it is unmapped."
|| "\n\n";
enddo;
endif;
// Now process any unmapped unsubmitted or existing drugs
nUnmappedConcomit := count(concomit_unmapped_drug_names);
nActualInteractions := nTotalInteractions - (nUnmappedEvoking + nUnmappedConcomit);
If nUnmappedConcomit > 0
then
alert_to_display := true;
if (combined_alert_msg <> "")
then
combined_alert_msg := combined_alert_msg || draw_line;
endif;
if (nActualInteractions = 0)
then
alert_unmapped_concomit_msg :=
"{{+B}}{{+R}}" || evoking_item_name || "{{-R}}{{-B}}" || " was not checked for drug interactions"
|| " with the following medication(s):\n" || indent || "{{+B}}Unmapped Medications{{-B}}\n";
indent := indent || " ";
else
if (nUnmappedConcomit = 1)
then
med_str := "is an {{+B}}Unmapped Medication{{-B}}";
else
med_str := "are {{+B}}" || nUnmappedConcomit || " Unmapped Medications{{-B}}";
endif;
alert_unmapped_concomit_msg := alert_unmapped_concomit_msg || "There " || med_str || " not checked for drug interactions\n";
endif;
index_list := 1 seqto nUnmappedConcomit;
for concomit_ind in index_list do
unmappedDrugName := concomit_unmapped_drug_names[concomit_ind];
alert_unmapped_concomit_msg := alert_unmapped_concomit_msg || indent
|| unmappedDrugName || "\n";
enddo;
alert_unmapped_concomit_msg := alert_unmapped_concomit_msg || "\n";
endif;
// Add the unmapped drugs at the end of the alert abstract
if nUnmappedEvoking > 0 OR nUnmappedConcomit > 0
then
if (alert_abstract_str <> "")
then
alert_abstract_str := alert_abstract_str || ", " ;
endif;
alert_abstract_str := alert_abstract_str || unmapped_alert_abstract_str;
endif;
endif;
combined_alert_msg := "";
if (alert_to_display)
then
combined_alert_msg :=
alert_header_msg ||
alert_unmapped_evoking_msg ||
alert_unmapped_concomit_msg ||
alert_detail_major ||
alert_detail_moderate ||
alert_detail_minor ||
alert_detail_food;
interact_alert.alert_abstract := alert_abstract_str;
endif;
endif;
complete_multum_references := "";
sorted_obj_list := SORT reference_title DATA mdo_reference_list;
if exist sorted_obj_list
then
// Display citiations details
citations_string := "{{+B}}Citations{{-B}}:\n {{+I}}Note: The following citations"
|| " are from Cerner Multum, Inc. If your local facility has modified the"
|| " explanation of the conflict in the alert message, the citations below"
|| " may or may not apply.{{-I}}";
number_list := 1 seqto count(sorted_obj_list);
for JJ in number_list do
reference_title := sorted_obj_list[JJ].reference_title;
current_order_ID := sorted_obj_list[JJ].current_order_ID;
drug2ID := sorted_obj_list[JJ].drug2ID;
(multum_references, multum_date, ref_count) := call func_multum_references with
null, // Formatting
"drgint",
reference_title,
current_order_ID,
drug2ID;
if multum_references is not null
then
if complete_multum_references is null or complete_multum_references = ""
then
complete_multum_references := multum_references;
else
complete_multum_references := complete_multum_references || multum_references;
endif;
endif;
enddo;
else
// Display citiations details : None
citations_string := "{{+B}}Citations{{-B}}: None";
endif;
interact_alert.references := interact_alert.references || revision_date_string
|| "\n\n" || citations_string || "\n\n" || complete_multum_references;
referenceDate_displayed := true;
endif;
;;
evoke:
new_regular_med_order_not_in_set;
new_regular_med_patient_group_order_not_in_set;
new_regular_med_order_in_set;
new_IV_order;
new_IV_patient_group_order;
order_modify_trigger;
new_rad_med_order_in_set;
fbc_med_order_in_set;
new_rad_IV_Order;
// outpatient_order_entry_trigger;
outpatient_order_init_trigger;
outpatient_order_modify_trigger;
// pharm_order_enter;
// pharm_order_modify;
any_new_prescription;
// any_renew_prescription;
order_alert_check;
// prescription_alert_check;
//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;
order_alternate_init_NOIV;
order_alternate_modify;
*/
;;
logic:
//----------------------------//
// Generate Actions on Alerts //
//----------------------------//
if generate_actions_on_alerts
and alert_to_display
then
// - the DRUG-DRUG Interaction for Actions on Alerts
// - no the Drug-Food Inactions for Alert On Demand
// - only orders
interaction_is_for_aoa :=
(interaction_current_drug_ID_list is not null) AND
(interaction_concomit_drug_ID_list is not NULL) AND
(interaction_concomit_is_order_list = true);
aoa_current_drug_name_list:= interaction_current_drug_name_list
where interaction_is_for_aoa;
aoa_current_item_type_list := interaction_current_item_type_list
where interaction_is_for_aoa;
aoa_severity_text := interaction_severity_text
where interaction_is_for_aoa;
aoa_concomit_drug_name_list := interaction_concomit_drug_name_list
where interaction_is_for_aoa;
aoa_concomit_order_name_list := interaction_concomit_order_name_list
where interaction_is_for_aoa;
aoa_concomit_order_guid_list := interaction_concomit_order_guid_list
where interaction_is_for_aoa;
aoa_concomit_order_catalog_item_guid_list :=
interaction_concomit_order_catalog_item_guid_list
where interaction_is_for_aoa;
aoa_concomit_item_type_list := interaction_concomit_item_type_list
where interaction_is_for_aoa;
aoa_concomit_item_status_list := interaction_concomit_item_status_list
where interaction_is_for_aoa;
aoa_concomit_is_suspended_list := interaction_concomit_is_suspended_list
where interaction_is_for_aoa;
alert_action_list := call func_drug_interaction_actions WITH
aoa_current_drug_name_list,
aoa_current_item_type_list, // Regular or IVAdditive
aoa_severity_text,
aoa_concomit_drug_name_list,
aoa_concomit_order_name_list, //All containing orders
aoa_concomit_order_guid_list, //All orders including additives
aoa_concomit_order_catalog_item_guid_list,
aoa_concomit_item_type_list, // Regular or IVAdditive
aoa_concomit_item_status_list, // Evoking, Unsubmitted, or Exising
aoa_concomit_is_suspended_list,
evoking_catalog_item_guid,
evoking_order_guid,
evoking_order_name;
if exist alert_action_list
then
alert_actions_exist := true;
else
alert_actions_exist := false;
endif;
endif;
//---------------//
// Clinical Rule //
//---------------//
if alert_to_display
then
conclude true;
else
conclude false;
endif;
;;
action:
write combined_alert_msg at interact_alert;
// Only attach actions, when they exist
if alert_actions_exist
then
attach alert_action_list to interact_alert;
endif;
;;
Urgency: 70;;
end: