maintenance: title: SCH_ED_TAMIFLU_AUTO_ORDER ;; mlmname: SCH_ED_TAMIFLU_AUTO_ORDER;; arden: version 2.5;; version: 0.00;; institution: St. Clair Hospital ;; author: Sandy Zhang ;; specialist: Amy Georgulis ;; date: 2018-09-18;; validation: testing;; library: purpose: Patients who came through the ED with Flu would receive a STAT/Now/Once dose of Tamiflu and remaining doses would be neglected due to disconnect in transition of care. This MLM will auto-order Tamiflu for a patient based on our algorithm below. ;; explanation: Change History: 09-18-2018 SZ CSR #36408 - Tamiflu transition orders ;; keywords: ;; citations: ;; knowledge: type: data-driven;; data: standard_libs := MLM {{{SINGLE-QUOTE}}}std_include_libs{{{SINGLE-QUOTE}}}; include standard_libs; error_occurred := false; error_message := ""; str_parse := mlm {{{SINGLE-QUOTE}}}UTIL_STRING_PARSE{{{SINGLE-QUOTE}}}; CrCl_info:= mlm {{{SINGLE-QUOTE}}}SCH_Func_Creatinine_Clearance{{{SINGLE-QUOTE}}}; log_execution_info := false; // declare MLM that will generate order into worksheet SCH_FUNC_CREATE_MED_ORDER_WORKSHEET := MLM {{{SINGLE-QUOTE}}}SCH_FUNC_CREATE_MED_ORDER_WORKSHEET{{{SINGLE-QUOTE}}}; // Can be evoked by any {{{SINGLE-QUOTE}}}transition orders{{{SINGLE-QUOTE}}} order sets, but not the hospitalist one order_set_enter_event := event {OrderSetEnter User OrderSet : where OrderSetName matches pattern "%transition orders%" and OrderSetName <> "Transition Orders- Hospitalist" }; // get guids userguid := read last {UserInfo: guid}; (ClientVisitGuid, ChartGuid, ClientGuid, CurrentLocation, LocationGuid, VisitStatus, AdmitDtm) := read last {ClientVisit: GUID, ChartGUID, ClientGUID, CurrentLocation, CurrentLocationGUID, VisitStatus, AdmitDtm }; create_order := False; //////////////////////////////////////////////////////////////////////////// // Filter #1 - STAT/Now/Once order for Tamiflu //////////////////////////////////////////////////////////////////////////// /*********************************************************************************************************************************/ // checks for active oseltamivir (Tamiflu) STAT order during this visit // If exist, then that means patient was given a treatment dose of Tamiflu for strong evidence of flu (STAT_Order, STAT_Order_freq) := read last { " select o.name, o.FrequencyCode" || " from cv3ordercatalogmasteritem as ocmi with (nolock) " || " join cv3order as o with (nolock)on o.ordercatalogmasteritemguid = ocmi.guid " || " and o.ClientGUID = " || ClientGuid || " and o.ChartGUID = " || ChartGuid || " and o.ClientVisitGUID= " || ClientVisitGuid || " " || " and (o.name like {{{SINGLE-QUOTE}}}%oseltamivir%{{{SINGLE-QUOTE}}}) " || " and (o.FrequencyCode = {{{SINGLE-QUOTE}}}STAT{{{SINGLE-QUOTE}}}" || " or o.FrequencyCode = {{{SINGLE-QUOTE}}}Now{{{SINGLE-QUOTE}}}" || " or o.FrequencyCode = {{{SINGLE-QUOTE}}}Once{{{SINGLE-QUOTE}}})" || " and o.OrderStatusLevelNum >= 15 " || " and o.SignificantDtm > getdate()-2" // || " and o.OrderStatusLevelNum not in (69, 70) " // STAT order of Tamiflu does not need to be active, b/c it may be d/ced after it{{{SINGLE-QUOTE}}}s taken? }; if (exist STAT_Order) then create_order := True; Check_active_STAT_order := "active STAT/Now/Once order for Tamiflu was detected, patient might need inpatient Tamiflu orders"; endif; //////////////////////////////////////////////////////////////////////////// // Filter #2 - If patient is < 18 years old, give alert to have user create the order //////////////////////////////////////////////////////////////////////////// /*********************************************************************************************************************************/ /* Get the patient{{{SINGLE-QUOTE}}}s age */ (client_birthdatetime):= read last { ClientInfo: Birthdatetime}; client_age_in_seconds:= Now - client_birthdatetime; client_age:= truncate( client_age_in_seconds / (1 year) ); if (client_age < 18) and (create_order = true) then // By this point we have decided an order needs to be created, give user the dialogue message to decide if they want the order Messagetext := "This patient received a dose of oseltamivir (Tamiflu) while in the ED. Please order ongoing oseltamivir for this patient to prevent an interruption of antiviral therapy." || "\n\nPatient is " || client_age || " year(s) old, please manually place oseltamivir (Tamiflu) order based off weight and age." ; dialogResult := call {{{SINGLE-QUOTE}}}MessageBox{{{SINGLE-QUOTE}}}.Show with Messagetext ,"Oseltamivir (Tamiflu) Auto-order","OK" as {{{SINGLE-QUOTE}}}MessageBoxButtons{{{SINGLE-QUOTE}}}; create_order := False; endif; //if (client_age < 18) and (create_order = true) and then // if a stat order of Tamiflu exists, then continue if (create_order = true) then //////////////////////////////////////////////////////////////////////////// // Filter #3 - Active nonSTAT order for Tamiflu //////////////////////////////////////////////////////////////////////////// /*********************************************************************************************************************************/ // Check for active non-stat order (anything with frequency that{{{SINGLE-QUOTE}}}s not STAT, Now, or Once) within past 2 days. (Active_nonSTAT_Order, Active_nonSTAT_Order_freq) := read last { " select o.name, o.FrequencyCode" || " from cv3ordercatalogmasteritem as ocmi with (nolock) " || " join cv3order as o with (nolock)on o.ordercatalogmasteritemguid = ocmi.guid " || " and o.ClientGUID = " || ClientGuid || " and o.ChartGUID = " || ChartGuid || " and o.ClientVisitGUID= " || ClientVisitGuid || " " || " and (o.name like {{{SINGLE-QUOTE}}}%oseltamivir%{{{SINGLE-QUOTE}}}) " || " and (o.FrequencyCode <> {{{SINGLE-QUOTE}}}STAT{{{SINGLE-QUOTE}}})" || " and (o.FrequencyCode <> {{{SINGLE-QUOTE}}}Now{{{SINGLE-QUOTE}}})" || " and (o.FrequencyCode <> {{{SINGLE-QUOTE}}}Once{{{SINGLE-QUOTE}}})" || " and o.OrderStatusLevelNum >= 15 " || " and o.OrderStatusLevelNum not in (69, 70) " || " and o.SignificantDtm > getdate()-2" }; if (exist Active_nonSTAT_Order) then create_order := False; Check_active_nonSTAT_order := "active STAT order for Tamiflu was detected, patient will need inpatient Tamiflu orders"; endif; /*********************************************************************************************************************************/ //////////////////////////////////////////////////////////////////////////// // order creation //////////////////////////////////////////////////////////////////////////// /*********************************************************************************************************************************/ if (create_order = true) then // If the user selects another careprovider (Nurse or US entry), pass the requestors user ID if userguid <> EVOKINGOBJECT.CareProviderGUID then userguid := EVOKINGOBJECT.CareProviderGUID; endif; /***********************************************************/ // Version 1 from SCH_DrugLevelMonitoring Creatinine, CreateDTM := read last {"Select top 1 bo.value, o.performeddtm " || " From cv3order as o with (nolock) " || " join cv3basicobservation as bo with (nolock) " || " on o.clientguid = bo.clientguid " || " and o.chartguid = bo.chartguid " || " and o.guid = bo.orderguid " || " and bo.status = {{{SINGLE-QUOTE}}}F{{{SINGLE-QUOTE}}} " || " and bo.Active = 1 " || " And bo.IsHistory = 0 " || " join cv3ordercatalogmasteritem as ocmi with (nolock) " || " on ocmi.guid = o.ordercatalogmasteritemguid " || " and ocmi.active = 1 " || " where o.clientguid = " || SQL(clientguid) || " and o.performeddtm >= " || SQL(AdmitDtm) || " and bo.itemname = {{{SINGLE-QUOTE}}}Creatinine Plasma/Serum{{{SINGLE-QUOTE}}} " || " order by o.performeddtm desc " }; creatinine_number := Creatinine as number; if Creatinine is not Null then (CrCl_Message, Crcl_Value, SCRfromMLM, wt, patientage) := call CrCl_info with (ClientVisitGuid, ChartGuid, ClientGuid, creatinine_number); // get doses of meds based off this CrCl dose endif; if (Crcl_Value > 60) or (Crcl_Value is null) then // declare Tamiflu order details/variable OrderName := "Oseltamivir 75mg Cap"; ItemModifier := "- CrCl > 60, Q12H, x 9 doses"; ItemVersion := ""; creation_reason := "from Tamiflu Protocol"; OrderFrequency := "Q12H"; special_instructions_value_Mod := ""; new_order_desc := "75mg Q12H x 9 doses"; // Default dosing is Q12H DosesPerDay := 2; FrequencyInterval := 12; FrequencyTimeUOM := "hr(s)"; endif; // if (Crcl_Value > 60) or (Crcl_Value is null) then if (Crcl_Value >= 30) and (Crcl_Value <= 60) then // declare Tamiflu order details/variable OrderName := "Oseltamivir 30mg Cap"; ItemModifier := "- CrCl 30-60, Q12H, x 9 doses"; ItemVersion := ""; creation_reason := "from Tamiflu Protocol"; OrderFrequency := "Q12H"; special_instructions_value_Mod := ""; new_order_desc := "30mg Q12H x 9 doses"; // Q12H frequency DosesPerDay := 2; FrequencyInterval := 12; FrequencyTimeUOM := "hr(s)"; endif; // if (Crcl_Value >= 30) or (Crcl_Value <= 60) then if (Crcl_Value >= 10) and (Crcl_Value <= 29.9) then // declare Tamiflu order details/variable OrderName := "Oseltamivir 30mg Cap"; ItemModifier := "- CrCl 10-29.9, Q24H, x 4 doses"; ItemVersion := ""; creation_reason := "from Tamiflu Protocol"; OrderFrequency := "Q24H"; special_instructions_value_Mod := ""; new_order_desc := "30mg Q24H x 4 doses"; // Q24H frequency DosesPerDay := 1; FrequencyInterval := 24; FrequencyTimeUOM := "hr(s)"; endif; // if (Crcl_Value >= 10) or (Crcl_Value <= 29.9) then if (Crcl_Value < 10) then // declare Tamiflu order details/variable OrderName := "Oseltamivir 30mg Cap"; ItemModifier := "- CrCl < 10, Q48H, x 2 doses"; ItemVersion := ""; creation_reason := "from Tamiflu Protocol"; OrderFrequency := "Q48H"; special_instructions_value_Mod := ""; new_order_desc := "30mg Q48H x 2 doses"; // Q48H frequency DosesPerDay := 1; FrequencyInterval := 48; FrequencyTimeUOM := "hr(s)"; endif; // if (Crcl_Value < 10) then // gather guids for creating order //Active_ClientVisitGUID := this_communication.ClientVisitGUID; Active_OrderGUID:= PrimaryObjdetail.GUID; location_guid := read last {"select CurrentLocationGUID from CV3ClientVisit where GUID=" || SQL(ClientVisitGuid)}; // By this point we have decided an order needs to be created, give user the dialogue message to decide if they want the order Messagetext := "This patient received a dose of oseltamivir (Tamiflu) while in the ED. Please order ongoing oseltamivir for this patient to prevent an interruption of antiviral therapy." || " Recommended oseltamivir dose for this patient based on renal function is " || new_order_desc || "\n\nDo you want to order oseltamivir " || new_order_desc || " ?" || "\n\nSelecting {{{SINGLE-QUOTE}}}Yes{{{SINGLE-QUOTE}}} will add it to the order worksheet." ; dialogResult := call {{{SINGLE-QUOTE}}}MessageBox{{{SINGLE-QUOTE}}}.Show with Messagetext ,"Oseltamivir (Tamiflu) Auto-order","YesNo" as {{{SINGLE-QUOTE}}}MessageBoxButtons{{{SINGLE-QUOTE}}}; if((dialogResult as string) = "Yes") then /*****************************************************************************************************/ /*****************************************************************************************************/ // Imported from FORM_Antibiotic_Scheduling // Purpose: to auto-schedule tamiflu dose the same way other abx are being auto-scheduled // example: if 14:46, then schedule for 16:00 start time /*****************************************************************************************************/ /*****************************************************************************************************/ // GATHER INFORMATION ABOUT MOST RECENTLY ADMINISTERED ORDER (past 2 days) OF Tamiflu (ExistingOrderLastGiven, ExistingOrderFrequency, ExistingOrderHoursSinceGiven, ExistingOrderName, ExistingOrderTherapeuticCategory, ExistingOrderDrugKey, ExistingRoute, ExistingNextTaskPending, ExistingNextTaskCanceled) := read last { " select oto.performedfromdtm, o.FrequencyCode, datediff (HH, oto.performedfromdtm, getdate()), " || " o.name, ocmi.TherapeuticCategory, dm.DrugKey, ot.OrderRoute " || " ,(select top 1 oto2.SignificantDtm from cv3ordertaskoccurrence oto2 with (nolock) " || " where oto2.clientguid = ot.clientguid and oto2.orderguid = o.guid and oto2.ordertaskguid = ot.guid " || " and oto2.SignificantDtm > getdate()-2 and oto2.taskstatuscode = {{{SINGLE-QUOTE}}}Pending{{{SINGLE-QUOTE}}}) " || " ,(select top 1 oto2.SignificantDtm from cv3ordertaskoccurrence oto2 with (nolock) " || " where oto2.clientguid = ot.clientguid and oto2.orderguid = o.guid and oto2.ordertaskguid = ot.guid " || " and oto2.SignificantDtm > getdate()-2 and oto2.taskstatuscode = {{{SINGLE-QUOTE}}}Canceled{{{SINGLE-QUOTE}}}) " || " from cv3ordercatalogmasteritem ocmi with (nolock) " || " join cv3drugmapping dm with (nolock) on dm.catalogitemguid = ocmi.guid " || " join cv3order o with (nolock)on o.ordercatalogmasteritemguid = ocmi.guid " || " and o.ClientGUID = " || ClientGuid || " " || " and o.TypeCode = {{{SINGLE-QUOTE}}}Medication{{{SINGLE-QUOTE}}} and ocmi.TherapeuticCategory = {{{SINGLE-QUOTE}}}anti-infectives | antiviral agents{{{SINGLE-QUOTE}}}" || " and o.Name like {{{SINGLE-QUOTE}}}%oseltamivir%{{{SINGLE-QUOTE}}}" || " join cv3ordertask ot with (nolock) on ot.clientguid = o.clientguid and ot.orderguid = o.guid " || " join cv3ordertaskoccurrence as oto with (nolock) on oto.clientguid = ot.clientguid and oto.orderguid = ot.orderguid " || " and oto.ordertaskguid = ot.guid and oto.SignificantDtm > getdate()-2 and oto.taskstatuscode = {{{SINGLE-QUOTE}}}Performed{{{SINGLE-QUOTE}}} " || " order by oto.performedfromdtm " }; CurrentMinute:= extract minute NOW; CurrentHour := extract hour NOW; NextHour := extract hour NOW + 1; HourAfterNext:= extract hour NOW + 2; CalculatedHour := NextHour; yesterday := extract day NOW - 1; today := extract day NOW; tomorrow := extract day NOW + 1; dayafter := extract day NOW + 2; LastGivenMin := extract minute ExistingOrderLastGiven; LastGivenHour := extract hour ExistingOrderLastGiven; LastGivenDay := extract day ExistingOrderLastGiven; TargetHour := extract hour ExistingOrderLastGiven + FrequencyInterval; TargetDate := ExistingOrderLastGiven; // SCHEDULED TIME ADJUSTMENTS - for variable start time frequencies If TargetHour is not null and FrequencyTimeUOM = "hr(s)" then If (LastGivenMin >= 45) then TargetHour := TargetHour + 1; endif; // Adjust for Calculated Dose Hour greater than 24 (next dose falls after midnight today) If TargetHour < 24 then TargetHour := TargetHour; ElseIf TargetHour >= 24 and TargetHour < 48 then TargetHour := TargetHour - 24; TargetDate := TargetDate + 1 day; ElseIf TargetHour >= 48 then TargetHour := TargetHour - 48; TargetDate := TargetDate + 2 day; endif; // Adjust for Calculated Dose Time that is in the past...begin now (existing med has missed recent doses) TimeNow := (extract year NOW) FORMATTED WITH "%2.2d" || (extract month NOW) FORMATTED WITH "%2.2d" || (extract day NOW) FORMATTED WITH "%2.2d" || (extract hour NOW) FORMATTED WITH "%2.2d" || (extract minute NOW) FORMATTED WITH "%2.2d"; TimeScheduled:= (extract year TargetDate) FORMATTED WITH "%2.2d" || (extract month TargetDate) FORMATTED WITH "%2.2d" || (extract day TargetDate) FORMATTED WITH "%2.2d" || TargetHour FORMATTED WITH "%2.2d" || "00"; // This means we are already past the time for which the dose should have been scheduled // Set the dose to be scheduled ASAP to the nearest hour if (TimeScheduled <= TimeNow) then CalculatedHour := NextHour; TargetDate := NOW; if (CurrentMinute >= 45) then CalculatedHour := CalculatedHour + 1; endif; If (CalculatedHour >= 24) then CalculatedHour := CalculatedHour - 24; TargetDate := TargetDate + 1 day; endif; checkpoint := "TimeScheduled <= TimeNow (This means we are already past the time for which the dose should have been scheduled, so schedule for next hour)"; // adjust hours if calculatedhour lands within the bedtime window of 0:00-05:59 or If (CalculatedHour >= 0 and CalculatedHour <= 5) then CalculatedHour := 06; ElseIf (CalculatedHour >= 12 and CalculatedHour <= 17 and FrequencyInterval = 12) then CalculatedHour := 18; endif; else // If TimeScheduled > TimeNow is true then (dose should be scheduled in future) CalculatedHour := TargetHour; TargetDate := TargetDate; checkpoint := "TimeScheduled > TimeNow (dose should be scheduled in future)"; if (FrequencyInterval = 12) then // adjust hours if calculatedhour lands within the bedtime window of 0:00-05:59 or 12:00-17:59 (b/c Q12H would cause subsequent doses to be in the bedtime window, ex. 14:30 -> 02:30) If (TargetHour >= 0 and TargetHour <= 2) then if (CurrentHour < 23) then CalculatedHour := 23; TargetDate := TargetDate - 1 day; else CalculatedHour := 06; endif; path := "A"; ElseIf (TargetHour >= 3 and TargetHour <= 5) then CalculatedHour := 06; path := "B"; ElseIf (TargetHour >= 12 and TargetHour <= 14) then if (CurrentHour < 11) then CalculatedHour := 11; else CalculatedHour := 18; endif; path := "C"; ElseIf (TargetHour >= 15 and TargetHour <= 17) then CalculatedHour := 18; path := "D"; endif; // If (TargetHour >= 0 and TargetHour <= 2) then ElseIf (FrequencyInterval = 24 or FrequencyInterval = 48) then // adjust hours if calculatedhour lands within the bedtime window of 0:00-05:59 If (TargetHour >= 0 and TargetHour <= 2) then if (CurrentHour < 23) then CalculatedHour := 23; TargetDate := TargetDate - 1 day; else CalculatedHour := 06; endif; path := "A"; ElseIf (TargetHour >= 3 and TargetHour <= 5) then CalculatedHour := 06; path := "B"; endif; // If (TargetHour >= 0 and TargetHour <= 2) then endif; // if (FrequencyInterval = 12) then endif; //if (TimeScheduled <= TimeNow) then // Format the date and time as required for worksheet order creation CalculatedTime := CalculatedHour || ":00"; RequestedTime := CalculatedTime; TargetDAY := extract day TargetDate; // translate day to the right term for worksheet order creation if (TargetDAY = today) then RequestedDate := "T"; endif; if (TargetDAY = tomorrow) then RequestedDate := "T+1"; endif; if (TargetDAY = dayafter) then RequestedDate := "T+2"; endif; // call MLM that to generate worksheet order Create_Worksheet_Order := call SCH_FUNC_CREATE_MED_ORDER_WORKSHEET with OrderName, ItemModifier, ItemVersion, creation_reason, OrderFrequency, Active_OrderGUID, ClientVisitGuid, location_guid, UserGuid, special_instructions_value_Mod, RequestedDate, RequestedTime ; /*********************************************************/ else // If TargetHour is not null and FrequencyTimeUOM = "hr(s)" then // This means TargetHour is null because our query did not find a lastgiven dose (Tamiflu stat order is on file for pt, but not charted as given) // Action: default new order to next hour, make sure it{{{SINGLE-QUOTE}}}s not in bedtime dose range and adjust start time if needed CalculatedHour := NextHour; TargetDate := NOW; if (CurrentMinute >= 45) then CalculatedHour := CalculatedHour + 1; endif; If (CalculatedHour >= 24) then CalculatedHour := CalculatedHour - 24; TargetDate := TargetDate + 1 day; endif; // adjust hours if calculatedhour lands within the bedtime window of 0:00-05:59 or If (CalculatedHour >= 0 and CalculatedHour <= 5) then CalculatedHour := 06; ElseIf (CalculatedHour >= 12 and CalculatedHour <= 17 and FrequencyInterval = 12) then CalculatedHour := 18; endif; // Format the date and time as required for worksheet order creation CalculatedTime := CalculatedHour || ":00"; RequestedTime := CalculatedTime; TargetDAY := extract day TargetDate; // translate day to the right term for worksheet order creation if (TargetDAY = today) then RequestedDate := "T"; endif; if (TargetDAY = tomorrow) then RequestedDate := "T+1"; endif; if (TargetDAY = dayafter) then RequestedDate := "T+2"; endif; // call MLM that to generate worksheet order Create_Worksheet_Order := call SCH_FUNC_CREATE_MED_ORDER_WORKSHEET with OrderName, ItemModifier, ItemVersion, creation_reason, OrderFrequency, Active_OrderGUID, ClientVisitGuid, location_guid, UserGuid, special_instructions_value_Mod, RequestedDate, RequestedTime ; /*********************************************************/ endif; // If TargetHour is not null and FrequencyTimeUOM = "hr(s)" then endif; //if((dialogResult as string) = "Yes") then endif; //if (create_order = true) then endif; //if (create_order = true) then ;; priority: 50 ;; evoke: order_set_enter_event; ;; logic: conclude true; ;; action: ;; Urgency: 50;; end: