Files
St.Clair/MLMStripper/bin/Debug/SCH/SCH_CITALOPRAM_MEDICATION_ALERTS.mlm

509 lines
21 KiB
Plaintext

maintenance:
title: SCH_CITALOPRAM_MEDICATION_ALERTS;;
mlmname: SCH_CITALOPRAM_MEDICATION_ALERTS;;
arden: version 2.5;;
version: 6.10;;
institution: St Clair;;
author: Juliet M. Johns, Allscripts Corp;;
specialist: Juliet M. Johns;;
date: 2015-11-10;;
validation: testing;;
library:
purpose: Statin Medication Alerts
;;
explanation: MLM will read user dictionary table and display alerts based on citalopram drug interaction conflicts.
Change history
11.10.2015 JML CSR 33122: Created.
12.22.2015 JML Moved to Production.
;;
keywords: citalopram, drug, alerts
;;
knowledge:
type: data-driven;;
data:
// Specify which .NET assemblies need to be loaded for ObjectsPlus
standard_libs := MLM {{{SINGLE-QUOTE}}}std_include_libs{{{SINGLE-QUOTE}}};
include standard_libs;
//Additional include MLMs
str_parse := mlm {{{SINGLE-QUOTE}}}UTIL_STRING_PARSE{{{SINGLE-QUOTE}}};
create_aoa_object := MLM {{{SINGLE-QUOTE}}}STD_Func_Create_Alert_Action_Object{{{SINGLE-QUOTE}}};
//Formatting constants
SP := " ";
CR := 13 formatted with "%c";
LF := 10 formatted with "%c";
CRLF:= CR||LF;
TAB := 9 formatted with "%c";
messageA := SP;
messageB := SP;
messageC := SP;
//Variable Declaration
send_alert := "DoNotSend"; //Send message or not
error_occurred := false; //Error handler
error_message := ""; //Error message
log_execution_info := false;
rule_matches := false;
do_alert := false;
found_unsubmitted_meds := false;
found_existing_meds := false;
ordered_citalopram := false;
aa_lst := ();
msg_string := "";
alert_msg_lst := ();
//Debug via MLM editor
if called_by_editor then
EvokingObject := read last {Order: THIS
where Name="Esomeprazole 20mg DR Cap" };
endif;
//Citalopram list of drug interactions to alert on
citalopram_conflict_list := ("A|Citalopram|20|mg|>|esomeprazole|mg",
"A|Citalopram|20|mg|>|omeprazole|mg",
"A|Citalopram|20|mg|>|lansoprazole|mg",
"B|Citalopram|20|mg|>|oxcarbazepine|mg",
"B|Citalopram|20|mg|>|letrozole|mg",
"C|Citalopram|20|mg|>|fluconazole|mg",
"C|Citalopram|20|mg|>|voriconazole|mg",
"D|Citalopram|20|mg|>|modafinil|mg",
"D|Citalopram|20|mg|>|fluvoxamine|mg",
"D|Citalopram|20|mg|>|isoniazid|mg");
citalopram_order_enter := event { OrderEnter User Order : where TypeCode = "Medication" };
citalopram_alert_dest := destination {alert} with
[alert_type := "Warning",
short_message := "Citalopram Medication Alert",
priority := "low",
scope := "Chart",
rule_group := "Citalopram Meds",
rule_number := 4056,
send_with_order := send_alert,
alert_dialog_settings := "",
display_alert := true];
//Retrieve values from evoking object
(client_guid, chart_guid, visit_guid,
evoking_orderName, evoking_orderGUID,
evoking_significantDtm, catalog_item_obj,
ordered_uomValue, ordered_doseValue) := READ LAST { Order : ClientGUID, ChartGUID, ClientVisitGUID, Name, GUID, SignificantDtm,
OrderCatalogMasterItem, UOM, DosageLow
REFERENCING EvokingObject };
(catalog_classTypeValueObj,
evoking_orderCatalogMasterItemGUID) := READ LAST { OrderCatalogMasterItem : CatalogClassTypeValue, GUID
REFERENCING catalog_item_obj };
//Retrieve initial medications involved in citalopram custom user list
(classTypeValue_codeList, classTypeValue_valueList) := read { CatalogClassTypeValue : Code, Value
REFERENCING catalog_classTypeValueObj WHERE code = "PRX_Citalopram_Medications" };
//Parse the medications involved in the citalopram custom user list
class_valueList := call str_parse WITH classTypeValue_valueList[1], ",";
class_value := class_valueList[1];
//Ordered med exists in the citalopram custom user list
if ( class_value is not null ) then
//Citalopram ordered
if ( class_value matches pattern "citalopram%" ) then
ordered_citalopram := true;
//Retrieve list of unsubmitted orders that conflict with citalopram
(unsub_med_list,
unsub_med_dose,
unsub_med_uom,
unsub_oGUID,
unsub_oCatGUID) := READ { Unsubmitted Order : Name, DosageLow, UOM, GUID, OrderCatalogMasterItemGUID
WHERE ( ( Name matches pattern "esomeprazole%" AND UOM = "mg" )
OR ( Name matches pattern "omeprazole%" AND UOM = "mg" )
OR ( Name matches pattern "lansoprazole%" AND UOM = "mg" )
OR ( Name matches pattern "oxcarbazepine%" AND UOM = "mg" )
OR ( Name matches pattern "letrozole%" AND UOM = "mg" )
OR ( Name matches pattern "fluconazole%" AND UOM = "mg" )
OR ( Name matches pattern "voriconazole%" AND UOM = "mg" )
OR ( Name matches pattern "modafinil%" AND UOM = "mg" )
OR ( Name matches pattern "fluvoxamine%" AND UOM = "mg" )
OR ( Name matches pattern "isoniazid%" AND UOM = "mg" ) ) };
if ( exists unsub_med_list ) then
found_unsubmitted_meds := true;
endif;
//Now check for existing meds
(existing_meds_list,
existing_meds_name,
existing_meds_dose,
existing_meds_UOM,
existing_order_guid,
existing_order_oCat_guid ) := READ {"SELECT CASE WHEN CHARINDEX({{{SINGLE-QUOTE}}} {{{SINGLE-QUOTE}}}, o.NAME, 1) = 0 THEN LEFT(o.NAME, LEN(o.NAME) - 1)"
|| " WHEN CHARINDEX({{{SINGLE-QUOTE}}} {{{SINGLE-QUOTE}}}, o.NAME, 1) > 0 THEN LEFT(o.Name, (CHARINDEX({{{SINGLE-QUOTE}}} {{{SINGLE-QUOTE}}}, o.NAME, 1) - 1))"
|| " ELSE o.Name END, o.Name, ot.OrderDosageLow, ot.OrderUom, o.GUID, o.OrderCatalogMasterItemGUID"
|| " FROM CV3ClientVisit cv WITH (NOLOCK) JOIN CV3Order o WITH (NOLOCK)"
|| " ON cv.ClientGUID = o.ClientGUID"
|| " AND cv.GUID = o.ClientVisitGUID"
|| " AND cv.ChartGUID = o.ChartGUID"
|| " JOIN CV3OrderAddnlInfo oai WITH (NOLOCK)"
|| " ON o.GUID = oai.GUID"
|| " JOIN CV3OrderTask ot WITH (NOLOCK)"
|| " ON o.GUID = ot.OrderGUID"
|| " WHERE cv.ClientGUID = " || SQL(EvokingObject.ClientGUID)
|| " AND cv.GUID = " || SQL(EvokingObject.ClientVisitGUID)
|| " AND cv.ChartGUID = " || SQL(EvokingObject.ChartGUID)
|| " AND ((o.Name LIKE {{{SINGLE-QUOTE}}}esomeprazole%{{{SINGLE-QUOTE}}} AND ot.OrderUOM = {{{SINGLE-QUOTE}}}mg{{{SINGLE-QUOTE}}})"
|| " OR (o.Name like {{{SINGLE-QUOTE}}}omeprazole%{{{SINGLE-QUOTE}}} AND ot.OrderUom = {{{SINGLE-QUOTE}}}mg{{{SINGLE-QUOTE}}})"
|| " OR (o.Name LIKE {{{SINGLE-QUOTE}}}lansoprazole%{{{SINGLE-QUOTE}}} AND ot.OrderUom = {{{SINGLE-QUOTE}}}mg{{{SINGLE-QUOTE}}})"
|| " OR (o.Name LIKE {{{SINGLE-QUOTE}}}oxcarbazepine%{{{SINGLE-QUOTE}}} AND ot.OrderUom = {{{SINGLE-QUOTE}}}mg{{{SINGLE-QUOTE}}})"
|| " OR (o.Name LIKE {{{SINGLE-QUOTE}}}letrozole%{{{SINGLE-QUOTE}}} AND ot.OrderUom = {{{SINGLE-QUOTE}}}mg{{{SINGLE-QUOTE}}})"
|| " OR ( o.Name LIKE {{{SINGLE-QUOTE}}}fluconazole%{{{SINGLE-QUOTE}}} AND ot.OrderUOM = {{{SINGLE-QUOTE}}}mg{{{SINGLE-QUOTE}}})"
|| " OR (o.Name LIKE {{{SINGLE-QUOTE}}}voriconazole%{{{SINGLE-QUOTE}}} AND ot.OrderUom = {{{SINGLE-QUOTE}}}mg{{{SINGLE-QUOTE}}})"
|| " OR (o.Name LIKE {{{SINGLE-QUOTE}}}modafinil%{{{SINGLE-QUOTE}}} AND ot.OrderUom = {{{SINGLE-QUOTE}}}mg{{{SINGLE-QUOTE}}})"
|| " OR (o.Name LIKE {{{SINGLE-QUOTE}}}fluvoxamine%{{{SINGLE-QUOTE}}} AND ot.OrderUom = {{{SINGLE-QUOTE}}}mg{{{SINGLE-QUOTE}}})"
|| " OR (o.Name LIKE {{{SINGLE-QUOTE}}}isoniazid%{{{SINGLE-QUOTE}}} AND ot.OrderUOM = {{{SINGLE-QUOTE}}}mg{{{SINGLE-QUOTE}}}))"
|| " AND ((o.OrderStatusLevelNum > 15"
|| " AND o.OrderStatusLevelNum NOT IN ({{{SINGLE-QUOTE}}}69{{{SINGLE-QUOTE}}}, {{{SINGLE-QUOTE}}}70{{{SINGLE-QUOTE}}},{{{SINGLE-QUOTE}}}100{{{SINGLE-QUOTE}}}))"
|| " OR o.OrderStatusCode = {{{SINGLE-QUOTE}}}HOLD{{{SINGLE-QUOTE}}})"};
if ( exists existing_meds_list ) then
found_existing_meds := true;
endif;
if ( exists existing_meds_list OR exists unsub_med_list ) then
rule_matches := true;
endif;
else
//Ordered med was not citalopram; look for unsubmitted order
(unsub_citalopram_list,
unsub_citalopram_dose,
unsub_citalopram_uom,
unsub_citalopram_oGuid,
unsub_citalopram_oCatGuid) := READ { Unsubmitted Order : Name, DosageLow, UOM, Guid, OrderCatalogMasterItemGUID
WHERE Name matches pattern "citalopram%" AND UOM = "mg" };
if ( exists unsub_citalopram_list ) then
found_unsubmitted_meds := true;
endif;
//Check patient{{{SINGLE-QUOTE}}}s chart for existing citalopram order
(existing_citalopram_list,
existing_citalopram_med,
existing_citalopram_dose,
existing_citalopram_uom,
existing_citalopram_oGuid,
existing_citalopram_oCatGuid) := READ {"SELECT LEFT(o.Name, (CHARINDEX({{{SINGLE-QUOTE}}} {{{SINGLE-QUOTE}}}, o.NAME, 1) - 1)), o.Name, ot.OrderDosageLow, ot.OrderUom, o.GUID, o.OrderCatalogMasterItemGUID"
|| " FROM CV3ClientVisit cv WITH (NOLOCK) JOIN CV3Order o WITH (NOLOCK)"
|| " ON cv.ClientGUID = o.ClientGUID"
|| " AND cv.GUID = o.ClientVisitGUID"
|| " AND cv.ChartGUID = o.ChartGUID"
|| " JOIN CV3OrderAddnlInfo oai WITH (NOLOCK)"
|| " ON o.GUID = oai.GUID"
|| " JOIN CV3OrderTask ot WITH (NOLOCK)"
|| " ON o.GUID = ot.OrderGUID"
|| " WHERE cv.ClientGUID = " || SQL(EvokingObject.ClientGUID)
|| " AND cv.GUID = " || SQL(EvokingObject.ClientVisitGUID)
|| " AND cv.ChartGUID = " || SQL(EvokingObject.ChartGUID)
|| " AND (o.Name LIKE {{{SINGLE-QUOTE}}}citalopram%{{{SINGLE-QUOTE}}} AND ot.OrderUOM = {{{SINGLE-QUOTE}}}mg{{{SINGLE-QUOTE}}})"
|| " AND ((o.OrderStatusLevelNum > 15"
|| " AND o.OrderStatusLevelNum NOT IN ({{{SINGLE-QUOTE}}}69{{{SINGLE-QUOTE}}}, {{{SINGLE-QUOTE}}}70{{{SINGLE-QUOTE}}},{{{SINGLE-QUOTE}}}100{{{SINGLE-QUOTE}}}))"
|| " OR o.OrderStatusCode = {{{SINGLE-QUOTE}}}HOLD{{{SINGLE-QUOTE}}})"};
if ( exists existing_citalopram_list ) then
found_existing_meds := true;
endif;
if ( exists existing_citalopram_list OR exists unsub_citalopram_list ) then
rule_matches := true;
endif;
endif; //End ordered med = citalopram
if ( rule_matches ) then
//Loop through citalopram conflict list
for i in ( 1 seqto ( count citalopram_conflict_list ) ) do
citalopram_rule := call str_parse with citalopram_conflict_list[i], "|";
rule_class_type := citalopram_rule[1]; //Class Type
rule_med := citalopram_rule[2]; //Citalopram med
rule_dose := citalopram_rule[3]; //Citalopram dose
rule_uom := citalopram_rule[4]; //citalopram uom
rule_op := citalopram_rule[5]; //operation for citalopram
rule_conflict := citalopram_rule[6]; //Med that conflicts with citalopram
rule_conflict_uom := citalopram_rule[7]; //Med uom that conflicts with citalopram
//Ordered med = citalopram
if ( ordered_citalopram ) then
//does ordered med = appropriate rule
if ( rule_med = class_value ) then
if ( rule_op = ">" ) then
rule_matches := ( (ordered_doseValue as number) > (rule_dose as number) );
rule_matches := ( rule_matches AND ( (ordered_uomValue as string) = (rule_uom as string) ) );
else
rule_matches := false;
endif;
if ( rule_matches ) then
if ( found_unsubmitted_meds ) then
//Conflict med in my unsubmitted order list
for k in (1 seqto ( count unsub_med_list )) do
found := FIND LOWERCASE rule_conflict IN STRING LOWERCASE unsub_med_list[k] STARTING AT 1;
if ( (found as number) = 1 ) then
if ( rule_conflict_uom = unsub_med_uom[k] ) then
do_alert := true;
msg_string := "Due to increased risk of QT prolongation, please lower {{+B}}{{+R}}" || rule_med
|| "{{-R}}{{-B}} to " || rule_dose || rule_uom || " or change {{+B}}{{+R}}" || rule_conflict
|| "{{-R}}{{-B}}";
if ( rule_class_type = "A" ) then
msg_string := msg_string || " to another PPI such as pantoprazole.";
elseif ( rule_class_type = "B" ) then
msg_string := msg_string || " to an alternative agent, if clinically appropriate.";
elseif ( rule_class_type = "C" ) then
msg_string := msg_string || " to an alternative antifungal.";
elseif ( rule_class_type = "D" ) then
msg_string := msg_string || " to an alternative agent.";
endif;
alert_msg_lst := alert_msg_lst, msg_string;
alert_action := call create_aoa_object WITH "CV3Order", "CV3Order";
alert_action.EvokingEnterpriseItemID := evoking_orderCatalogMasterItemGUID;
alert_action.EvokingObjectID := evoking_orderGUID;
alert_action.ObjectName := evoking_orderName;
alert_action.ActionItemStatus := "Unsubmitted";
alert_action.ActionEvent := "DC-Cancel";
alert_action.ActionItemID := unsub_oGuid[k];
alert_action.ActionItemName := unsub_med_list[k];
alert_action.ActionEnterpriseItemID := unsub_oCatGUID[k];
alert_action.MLMName := "SCH_CITALOPRAM_MEDICATION_ALERTS";
alert_action.ShortMessage := "This is the UNSUBMITTED Medication to DC-Cancel. This medication conflicts with the Citalopram you are trying to order.";
aa_lst := aa_lst, alert_action;
endif;
endif;
enddo;
endif;
if ( found_existing_meds ) then
//Conflict med in existing med list
if ( rule_conflict IN existing_meds_list AND rule_conflict_uom IN existing_meds_uom ) then
//Loop through existing conflict medications
for j IN ( 1 seqto ( count existing_meds_list ) ) do
if ( rule_conflict = existing_meds_list[j] ) then
do_alert := true;
msg_string := "Due to increased risk of QT prolongation, please lower {{+B}}{{+R}}" || rule_med
|| "{{-R}}{{-B}} to " || rule_dose || rule_uom || " or change {{+B}}{{+R}}" || rule_conflict
|| "{{-R}}{{-B}}";
if ( rule_class_type = "A" ) then
msg_string := msg_string || " to another PPI such as pantoprazole.";
elseif ( rule_class_type = "B" ) then
msg_string := msg_string || " to an alternative agent, if clinically appropriate.";
elseif ( rule_class_type = "C" ) then
msg_string := msg_string || " to an alternative antifungal.";
elseif ( rule_class_type = "D" ) then
msg_string := msg_string || " to an alternative agent.";
endif;
alert_msg_lst := alert_msg_lst, msg_string;
alert_action := call create_aoa_object WITH "CV3Order","CV3Order";
alert_action.EvokingEnterpriseItemID := evoking_orderCatalogMasterItemGUID;
alert_action.EvokingItemID := evoking_orderGUID;
alert_action.ObjectName := evoking_orderName;
alert_action.ActionItemStatus := "Existing";
alert_action.ActionEvent := "DC-Cancel";
alert_action.ActionItemID := existing_order_guid[j];
alert_action.ItemName := existing_meds_name[j];
alert_action.ActionEnterpriseItemID := existing_order_oCat_guid[j];
alert_action.MLMName := "SCH_CITALOPRAM_MEDICATION_ALERTS";
alert_action.ShortMessage := "This is the EXISTING Medication to DC-Cancel. This medication conflicts with the Citalopram you are trying to order.";
aa_lst := aa_lst, alert_action;
endif;
enddo;
endif;
endif; //end found_unsubmitted_meds = true
endif;
endif; // end rule_med = class_value
//Ordered med NOT citalopram
else
if ( rule_conflict = class_value AND rule_conflict_uom = ordered_uomValue ) then
if ( found_unsubmitted_meds ) then
for m IN ( 1 seqto (count unsub_citalopram_list) ) do
found := FIND LOWERCASE rule_med IN STRING LOWERCASE unsub_citalopram_list[m] STARTING AT 1;
if ( (found as number) <> 0 ) then
if ( rule_op = ">" ) then
rule_matches := ( (unsub_citalopram_dose[m] as number) > (rule_dose as number) );
rule_matches := ( rule_matches AND ( (unsub_citalopram_uom[m] as string) = (rule_uom as string) ) );
else
rule_matches := false;
endif;
if ( rule_matches ) then
do_alert := true;
msg_string := "Due to increased risk of QT prolongation, please lower {{+B}}{{+R}}" || rule_med
|| "{{-R}}{{-B}} to {{+B}}{{+R}}" || rule_dose || rule_uom
|| "{{-R}}{{-B}} or change {{+B}}{{+R}}" || rule_conflict || "{{-R}}{{-B}}";
if ( rule_class_type = "A" ) then
msg_string := msg_string || " to another PPI such as pantoprazole.";
elseif ( rule_class_type = "B" ) then
msg_string := msg_string || " to an alternative agent, if clinically appropriate.";
elseif ( rule_class_type = "C" ) then
msg_string := msg_string || " to an alternative antifungal.";
elseif ( rule_class_type = "D" ) then
msg_string := msg_string || " to an alternative agent.";
endif;
alert_msg_lst := alert_msg_lst, msg_string;
alert_action := call create_aoa_object WITH "CV3Order","CV3Order";
alert_action.EvokingEnterpriseItemID := evoking_orderCatalogMasterItemGUID;
alert_action.EvokingObjectID := evoking_orderGUID;
alert_action.EvokingObjectName := evoking_orderName;
alert_action.ActionItemStatus := "Unsubmitted";
alert_action.ActionEvent := "DC-Cancel";
alert_action.ActionItemID := unsub_citalopram_oGuid[m];
alert_action.ActionItemName := unsub_citalopram_list[m];
alert_action.ActionEnterpriseItemID := unsub_citalopram_oCatGuid[m];
alert_action.MLMName := "SCH_CITALOPRAM_MEDICATION_ALERTS";
alert_action.ShortMessage := "This is the UNSUBMITTED citalopram order to DC-Cancel. Citalopram conflicts with the medication that you are trying to order.";
aa_lst := aa_lst, alert_action;
endif;
endif;
enddo;
endif;
if ( found_existing_meds ) then
//No unsubmitted citalopram; check patient{{{SINGLE-QUOTE}}}s chart
if ( rule_med IN existing_citalopram_list ) then
for l IN ( 1 seqto (count existing_citalopram_list) ) do
if ( rule_op = ">" ) then
rule_matches := ( (existing_citalopram_dose[l] as number) > (rule_dose as number) );
rule_matches := ( rule_matches AND ( (existing_citalopram_uom[l] as string) = (rule_uom as string) ) );
else
rule_matches := false;
endif;
if (rule_matches) then
do_alert := true;
msg_string := "Due to increased risk of QT prolongation, please lower {{+B}}{{+R}}" || rule_med
|| "{{-R}}{{-B}} to {{+B}}{{+R}}" || rule_dose || rule_uom
|| "{{-R}}{{-B}} or change {{+B}}{{+R}}" || rule_conflict || "{{-R}}{{-B}}";
if ( rule_class_type = "A" ) then
msg_string := msg_string || " to another PPI such as pantoprazole.";
elseif ( rule_class_type = "B" ) then
msg_string := msg_string || " to an alternative agent, if clinically appropriate.";
elseif ( rule_class_type = "C" ) then
msg_string := msg_string || " to an alternative antifungal.";
elseif ( rule_class_type = "D" ) then
msg_string := msg_string || " to an alternative agent.";
endif;
alert_msg_lst := alert_msg_lst, msg_string;
alert_action := call create_aoa_object WITH "CV3Order","CV3Order";
alert_action.EvokingEnterpriseItemID := evoking_orderCatalogMasterItemGUID;
alert_action.EvokingItemID := evoking_orderGUID;
alert_action.EvokingObjectName := evoking_orderName;
alert_action.ActionItemStatus := "Existing";
alert_action.ActionEvent := "DC-Cancel";
alert_action.ActionItemID := existing_citalopram_oGuid[l];
alert_action.ActionItemName := existing_citalopram_med[l];
alert_action.ActionEnterpriseItemID := existing_citalopram_oCatGUID[l];
alert_action.MLMName := "SCH_CITALOPRAM_MEDICATION_ALERTS";
alert_action.ShortMessage := "This is the EXISTING citalopram medication to DC-Cancel. Citalopram conflicts with the medication that you are trying to order.";
aa_lst := aa_lst, alert_action;
endif;
enddo;
endif;
endif;
endif; //End rule_conflict = class_value
endif; //End ordered_citalopram = true
enddo; //End looping through existing meds
endif; //end rule_matches
endif; //End class_value is not null
;;
priority: 50
;;
evoke:
citalopram_order_enter;
;;
logic:
conclude do_alert;
;;
action:
if ( do_alert ) then
final_msg := "";
for i IN (1 seqto count alert_msg_lst ) do
if ( final_msg = "" ) then
final_msg := alert_msg_lst[i];
else
final_msg := final_msg || "\n\n" || alert_msg_lst[i];
endif;
enddo;
write final_msg at citalopram_alert_dest;
attach aa_lst to citalopram_alert_dest;
endif;
;;
Urgency: 50;;
end: