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: