Initial Checking with all 820 MLMs

This commit is contained in:
2020-02-02 00:54:01 -05:00
parent c59dc6de2e
commit 840d0432f4
828 changed files with 239162 additions and 0 deletions

View File

@@ -0,0 +1,554 @@
maintenance:
title: Dosing recommendations based on age, weight, or total dose;;
mlmname: SCH_Misc_Dosing_Recommendations;;
arden: version 2;;
version: 5.50;;
institution: St Clair;;
author: Teresa Spicuzza, Allscripts Corp;;
specialist: Teresa Spicuzza;;
date: 2012-08-20;;
validation: testing;;
library:
purpose: Dosing Recommendations and Warnings based on age or weight
;;
explanation: MLM will read table and suggest dosing based upon medication, dose and patient age or weight.
Change history
08.20.2012 TMS Created CSR 30865
09.05.2012 TMS Added drug ordered information to dialog of alert CSR 30865
06.05.2013 TMS Updated with additional rules to accommodate additional drugs. CSR 31334
05.31.2017 TMS Updated with rule J for additional drugs. CSR 35636
05.16.2018 TMS Add "With Dialysis Treatment" to Frequency retrievals that contain As Ordered. CSR 33940
06.25.2018 TMS Add New Rule type "K" to present same drug/age alert as Rule D, except to suppress it for
users with an OrderRoleType of "Anesthesia Physician". CSR 36984
09.30.2019 TMS Updated alert to require reason when alert presented to user not in physician/physician extender
group. CSR 37977
;;
keywords: Dosing
;;
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;
error_occurred := false;
error_message := "";
str_parse := mlm {{{SINGLE-QUOTE}}}UTIL_STRING_PARSE{{{SINGLE-QUOTE}}};
log_execution_info := false;
//Set the text for this variable to indicate whether to send the message or not
send_alert := "DoNotSend";
//alert_settings := "";
//--------------------------------------------------------------------
if called_by_editor
then
EvokingObject := read last {Order: THIS
where Name="Ketorolac Inj" };
endif;
doalert := false;
SupressAlertFlag := false;
order_enter_event := event { OrderEnter User Order: where TypeCode = "Medication"};
(CatalogItemObj, FrequencyValue, UOMValue, DoseValue, OrderName, AdminIns, UserSchedType ,UserSchedDays, UserSchedDoses, OrderingProviderGuid, StopDtm) := read last
{Order: OrderCatalogMasterItem, FrequencyCode, UOM, DosageLow, Name, AdminInstructions, Interval, DaysInInterval, DoseMultiplier, CareProviderGuid, StopDtm
REFERENCING EvokingObject};
CatalogClassTypeValueObj := read last {OrderCatalogMasterItem: CatalogClassTypeValue,
REFERENCING CatalogItemObj};
ClassTypeValue_code_list, ClassTypeValue_value_list := read {CatalogClassTypeValue: Code, Value
REFERENCING CatalogClassTypeValueObj where code = "PRX_MiscDosing"};
/* Get the OrderAdditionalInfo object pointer */
OrderAdditionalInfoObj := read last { Order: OrderAdditionalInfo
REFERENCING EvokingObject };
/* Get information from the OrderAdditionalInfo object */
(SummaryLine, FreqfromTime,FreqUOM, StopAfterValue, StopAfterOption) := read last { OrderAdditionalInfo: FreqSummaryLine, FreqFromTime, FreqUOM, StopAfterValue, StopAfterOption
REFERENCING OrderAdditionalInfoObj };
// (Defintiontype, freqfromtime2, freqtimetovalue, frequom2) := read
// { " select Definitiontype,timefromvalue, timetovalue, timeuom from CV3Frequency "
// || " where Code = " || SQL(summaryline) };
/* Get the OrderUserData object pointer */
OrderUserDataObj := read last
{ Order: OrderUserData
REFERENCING EvokingObject };
for r in (1 seqto(count(OrderUserDataObj))) do
CurOrder_UserDataFields := OrderUserDataObj[r];
(userdatacodelist, valuelist ) := read { OrderUserData: UserDataCode, Value REFERENCING CurOrder_UserDataFields } ;
for s in (1 seqto(count(userdatacodelist))) do
if ((userdatacodelist [s] = "PRX_Suppress_Alert_Flag") and valuelist [s] = "1" ) then
SupressAlertFlag := True;
endif;
enddo;
enddo;
PainMgtDoc := read
{ " select Guid from CV3CareProvider "
|| " where DisplayName = {{{SINGLE-QUOTE}}}Spicuzza, Teresa{{{SINGLE-QUOTE}}}"
|| " or DisplayName = {{{SINGLE-QUOTE}}}Rivero-Becerra, Jorge N{{{SINGLE-QUOTE}}}"
};
If OrderingProviderGuid in PainMgtDoc then PainMgtOverride := True; else PainMgtOverride := False; endif;
// fire_on_User := ("IT","MD","DO","DDS","DPM","PA","PA-C","CRNP","RPh");
fire_on_UserCPOE := ("MD","DO","DDS","DPM","PA","PA-C","CRNP","IT");
fire_on_User := ("RN","RPh");
// fire_on_User := ("tspicuzza","deiler","shead","gfino","ccorbettit", "dwarnick",
// "dmiklavichis","ageorgulis","dbellissimo","kbaumgarte");
/* Get the current user{{{SINGLE-QUOTE}}}s occupation*/
(user_id,userguid) :=read last {UserInfo: idcode, guid};
UserCode, OrderRole := read last
{"Select occupationcode, orderroletype "
||" From cv3user with (nolock) "
||" Where Guid = " || SQL(userguid) };
// continue_processing:= user_id in fire_on_User;
// continue_processing:= usercode in fire_on_User;
If usercode in fire_on_UserCPOE then
alert_settings := "";
UDDD_dictionary_name := "";
UDDD_is_restricted := FALSE;
continue_processing := true;
elseif usercode in fire_on_User then
alert_settings := "Must Comment";
UDDD_dictionary_name := "AlertAckComment";
UDDD_is_restricted := TRUE;
continue_processing := true;
else continue_processing := false;
endif;
dose_alert_dest := destination {alert} with
[alert_type := "Warning",
short_message := "Dosing Recommendation",
priority := "High",
scope := "Chart",
rule_group := "Dosing Recommendations",
rule_number := 4080,
send_with_order := send_alert,
alert_dialog_settings := alert_settings,
ack_comment_UDDD := UDDD_dictionary_name,
ack_comment_UDDD_is_restricted := UDDD_is_restricted,
display_alert := true];
for r in (1 seqto 1) do
classvaluelist := call str_parse with ClassTypeValue_value_list [r],",";
classvalue := classvaluelist[1];
enddo;
if EvokingEvent = order_enter_event and continue_processing = true and SupressAlertFlag = False then
if "PRX_MiscDosing" in ClassTypeValue_code_list then
continue := "yes";
else
continue := "no";
endif;
endif;
If continue = "yes" then
(schedtime, freqcode, timefrom, timeuom) := read last
{" select fsd.ScheduledTime, cft.FrequencyCode, cft.TimeFromValue, cft.TimeUom from CV3CodedFreqTranslation cft"
|| " join CV3FixedScheduleDefinition fsd on fsd.ParentGUID = cft.guid "
|| " where cft.FrequencyCode = " || sql(frequencyvalue) || " and FrequencyClass = {{{SINGLE-QUOTE}}}<Default>{{{SINGLE-QUOTE}}} and cft.Active = 1"
|| " order by fsd.ScheduledTime "
};
(TimesPerDay) := read last {" select count (fsd.ScheduledTime) from CV3CodedFreqTranslation cft"
|| " join CV3FixedScheduleDefinition fsd on fsd.ParentGUID = cft.guid "
|| " where cft.FrequencyCode = " || sql(frequencyvalue) || " and FrequencyClass = {{{SINGLE-QUOTE}}}<Default>{{{SINGLE-QUOTE}}} and cft.Active = 1"
};
Oncegroup := ("Now", "STAT", "Once", "One Time", "Today,", "Load", "Pre-procedure",
"Post-procedure","Pre-Transfusion", "Post-Transfusion","Between Blood",
"PRE OP,", "POST OP", "As Ordered", "As Directed", "Given in Infusion Center",
"Given in Delivery Room", "With Dialysis Treatment");
If frequencyvalue in Oncegroup then
frequencygroup := "OneTime";
else frequencygroup := "Other";
endif;
If frequencyvalue <> "<User Schedule>" and frequencygroup <> "OneTime" then
If timefrom = 1 and timeuom = "day" then
If TimesPerDay = 1 then frequencygroup := "Q24H"; Freqfactor := 24; endif;
If TimesPerDay = 2 then frequencygroup := "Q12H"; Freqfactor := 12; endif;
If TimesPerDay = 3 then frequencygroup := "Q8H"; Freqfactor := 8; endif;
If TimesPerDay = 4 then frequencygroup := "Q6H"; Freqfactor := 6; endif;
If TimesPerDay = 6 then frequencygroup := "Q4H"; Freqfactor := 4; endif;
If TimesPerDay = 8 then frequencygroup := "Q3H"; Freqfactor := 3; endif;
If TimesPerDay = 12 then frequencygroup := "Q2H"; Freqfactor := 2; endif;
If TimesPerDay = 24 then frequencygroup := "Q1H"; Freqfactor := 1; endif;
elseif timefrom = 2 and timeuom = "day" then
If TimesPerDay = 1 then frequencygroup := "Q48H"; endif;
endif;
endif;
If frequencyvalue = "<User Schedule>" then
If UserSchedType = "Weekly" then
If UserSchedDays <= 2 and UserSchedDoses = 1 then
frequencygroup := "Q7D";
endif;
elseif UserSchedType = "Daily" and UserSchedDays = 1 and FreqFromTime = 1 and FreqUom = "day" then
If UserSchedDoses = 1 then frequencygroup := "Q24H"; Freqfactor := 24; endif;
If UserSchedDoses = 2 then frequencygroup := "Q12H"; Freqfactor := 12; endif;
If UserSchedDoses = 3 then frequencygroup := "Q8H"; Freqfactor := 8; endif;
If UserSchedDoses = 4 then frequencygroup := "Q6H"; Freqfactor := 6; endif;
If UserSchedDoses = 6 then frequencygroup := "Q4H"; Freqfactor := 4; endif;
If UserSchedDoses = 8 then frequencygroup := "Q3H"; Freqfactor := 3; endif;
If UserSchedDoses = 12 then frequencygroup := "Q2H"; Freqfactor := 2; endif;
If UserSchedDoses = 24 then frequencygroup := "Q1H"; Freqfactor := 1; endif;
elseif UserSchedType = "Daily" and UserSchedDays = 1 and FreqFromTime = 2 and FreqUom = "day" then
If UserSchedDoses = 1 then frequencygroup := "Q48H"; endif;
endif;
endif; //If frequencyvalue = "<User Schedule>"
DurationFactor := StopAfterValue;
If StopAfterOption = 2 then DurationType := "Hours"; endif;
If StopAfterOption = 3 then DurationType := "Mins"; endif;
If StopAfterOption = 4 then DurationType := "Times"; endif;
If StopAfterOption = 1 then DurationType := "Days"; endif;
If StopAfterOption = 0 then DurationFactor := 1; DurationType := "Days"; endif;
// Calculate the Total Daily Dose //
If (DoseValue as number) > 0 then
If (UserSchedDoses as number) > 0 and UserSchedType = "Daily" and UserSchedDays = 1 then
If DurationType = "Days" then
TotalDailyDose := ((UserSchedDoses as number) * (DoseValue as number));
elseif DurationType = "Times" and (DurationFactor as number) < (UserSchedDoses as number) then
TotalDailyDose := ((DurationFactor as number) * (DoseValue as number));
elseif DurationType = "Hours" and (DurationFactor as number) <= 24 then
TotalDailyDose := (Int((DurationFactor as number)/(FreqFactor as number))) * (DoseValue as number);
elseif DurationType = "Mins" and (DurationFactor as number) <= 999 then
TotalDailyDose := (Int((DurationFactor as number) / 60)/(FreqFactor as number)) * (DoseValue as number);
endif;
elseif (TimesPerDay as number) > 0 then
TotalDailyDose := ((TimesPerDay as number) * (DoseValue as number));
If DurationType = "Days" then
TotalDailyDose := ((TimesPerDay as number) * (DoseValue as number));
elseif DurationType = "Times" and (DurationFactor as number) < (TimesPerDay as number) then
TotalDailyDose := ((DurationFactor as number) * (DoseValue as number));
elseif DurationType = "Hours" and (DurationFactor as number) <= 24 then
TotalDailyDose := (Int((DurationFactor as number)/(FreqFactor as number))) * (DoseValue as number);
elseif DurationType = "Mins" and (DurationFactor as number) <= 999 then
TotalDailyDose := (Int((DurationFactor as number) / 60)/(FreqFactor as number)) * (DoseValue as number);
endif;
else TotalDailyDose := "Unknown";
endif;
endif;
(ClientVisitGuid, ChartGuid, ClientGuid, CurrentLocation, LocationGuid, VisitStatus) := read last {ClientVisit: GUID, ChartGUID, ClientGUID, CurrentLocation, CurrentLocationGUID, VisitStatus };
(UserGUID ) := read last { UserInfo: GUID };
// Get the patient age
(birthdate,dobM,dobD,birth_year, patientgender ) := read last { ClientInfo: BirthDate, BirthMonthNum, BirthDayNum, BirthYearNum, gendercode };
patientAge := (NOW - birthdate) / (1 year);
patientage:= (int (patientage));
// Get the patient weight
wtgm := read last
{ " Select Text from CV3PhysicalNoteDeclaration "
|| " where ClientGUID = " || SQL(ClientGuid)
|| " and ClientVisitGUID = " || SQL(ClientVisitGuid)
|| " and TypeCode = {{{SINGLE-QUOTE}}}weight{{{SINGLE-QUOTE}}} "
|| " order by Entered asc "
};
patientwt := (wtgm as number) / 1000;
// Loop through dictionary to parse fields needed to see if rule exists for ordered drug.
if continue = "yes" then
medlist := ();
medlist := read { "select value from cv3userdictionaryvalue v with (nolock)"
|| " where userdictionarycode = {{{SINGLE-QUOTE}}}PRX_Misc_Dosing_Rules{{{SINGLE-QUOTE}}} "
|| " and active = {{{SINGLE-QUOTE}}}1{{{SINGLE-QUOTE}}} "
};
NumRules:= count medlist;
for k in (1 seqto (NumRules)) do
rules := call str_parse with medlist[k],"|";
RuleClass := rules[1];
RuleType := rules[2];
RuleMsgType := rules[3];
RuleOrder := rules[4];
RuleDose := rules[5];
RuleDoseTD := rules[6];
RuleUOM := rules[7];
RuleRoute := rules[8];
RuleFreqQual := rules[9];
RuleFreq := rules[10];
RuleAge := rules[11];
RuleWtLow := rules[12];
RuleWtHi := rules[13];
RuleMsg := rules[14];
// Compare ordering info with rule info and process when match found.
If RuleClass = classvalue and ruletype = "A" then
If ((DoseValue as number)> (RuleDose as number)) and UOMValue = RuleUom then
If RuleFreqQual = "Is" and Frequencygroup = RuleFreq then
alert_message := "{{+B}} Ordered: "||OrderName || " " || DoseValue || " "|| UomValue|| ", " || SummaryLine
|| "\n\n {{+R}}" || Rulemsg || "{{-R}} {{-B}}";
doalert := true;
elseif RuleFreqQual = "IsNot" and Frequencygroup <> RuleFreq then
alert_message := "{{+B}} Ordered: "||OrderName || " " || DoseValue || " "|| UomValue|| ", " || SummaryLine
|| " \n\n {{+R}}" || Rulemsg || "{{-R}} {{-B}}";
doalert := true;
endif;
endif;
elseif RuleClass = classvalue and ruletype = "B" then
If ((DoseValue as number)> (RuleDoseHi as number)) and UOMValue = RuleUom then
If RuleFreqQual = "Is" and Frequencygroup = RuleFreq then
alert_message := "{{+B}} Ordered: "||OrderName || " " || DoseValue || " "|| UomValue|| ", " || SummaryLine
|| "\n This patient is " || patientage || " years old."
|| "\n\n {{+R}} " || Rulemsg || "{{-R}} {{-B}}";
doalert := true;
elseif RuleFreqQual = "IsNot" and Frequencygroup <> RuleFreq then
alert_message := "{{+B}} Ordered: "||OrderName || " " || DoseValue || " "|| UomValue|| ", " || SummaryLine
|| "\n\n {{+R}}" || Rulemsg || "{{-R}} {{-B}}";
doalert := true;
endif;
endif;
elseif RuleClass = classvalue and ruletype = "C" then
If ((PatientWt as number) < (RuleWtLow as number)) and ((DoseValue as number)>= (RuleDose as number)) and UOMValue = RuleUom then
alert_message := "{{+B}} Ordered: "||OrderName || " " || DoseValue || " "|| UomValue|| ", " || SummaryLine
|| "\n\n {{+R}}" || Rulemsg || "{{-R}} {{-B}}";
doalert := true;
endif;
elseif RuleClass = classvalue and ruletype = "D" then
If ((PatientAge as number) > (RuleAge as number)) then
alert_message := "{{+B}} Ordered: "||OrderName || " " || DoseValue || " "|| UomValue|| ", " || SummaryLine
|| "\n This patient is " || patientage || " years old."
|| "\n\n {{+R}} " || Rulemsg || "{{-R}} {{-B}}";
doalert := true;
endif;
elseif RuleClass = classvalue and ruletype = "E" then
If ((PatientAge as number) > (RuleAge as number)) and ((TotalDailyDose as number) > (RuleDoseTD as number)) then
alert_message := "{{+B}} Ordered: "||OrderName || " " || DoseValue || " "|| UomValue|| ", " || SummaryLine
|| "\n The total daily dose for this order is " || TotalDailyDose || UOMValue
|| "\n\n {{+R}} " || Rulemsg || "{{-R}} {{-B}}";
doalert := true;
endif;
elseif RuleClass = classvalue and ruletype = "F" then
If RuleMsgType = "PMO" and PainMgtOverride = false then
If ((DoseValue as number) > (RuleDose as number)) then
alert_message := "{{+B}} Ordered: "||OrderName || " " || DoseValue || " "|| UomValue|| ", " || SummaryLine
|| "\n\n {{+R}}" || Rulemsg || "{{-R}} {{-B}}";
doalert := true;
endif;
endif;
elseif RuleClass = classvalue and ruletype = "G" then
If RuleMsgType = "PMO" and PainMgtOverride = false then
If ((TotalDailyDose as number) > (RuleDoseTD as number)) then
alert_message := "{{+B}} Ordered: "||OrderName || " " || DoseValue || " "|| UomValue|| ", " || SummaryLine
|| "\n The total daily dose for this order is " || TotalDailyDose || UOMValue
|| "\n\n {{+R}} " || Rulemsg || "{{-R}} {{-B}}";
doalert := true;
endif;
endif;
elseif RuleClass = classvalue and ruletype = "H" then
If RuleUOM = "mg/kg/day" and UomValue = "mg" then
TotalDosePerWgt := (RuleDose as number) * (patientwt as number);
If ((TotalDailyDose as number) > (TotalDosePerWgt as number)) then
alert_message := "{{+B}} Ordered: "||OrderName || " " || DoseValue || " " || UomValue|| ", " || SummaryLine
|| "\n The total daily dose for this order is " || TotalDailyDose || UOMValue
|| "\n\n {{+R}} " || Rulemsg || "{{-R}} {{-B}}";
doalert := true;
endif;
endif;
elseif RuleClass = classvalue and ruletype = "J" then
If ((PatientAge as number) > (RuleAge as number)) and ((DoseValue as number) > (RuleDose as number)) then
alert_message := "{{+B}} Ordered: "||OrderName || " " || DoseValue || " "|| UomValue|| ", " || SummaryLine
|| "\n This patient is " || patientage || " years old."
|| "\n\n {{+R}} " || Rulemsg || "{{-R}} {{-B}}";
doalert := true;
endif;
elseif RuleClass = classvalue and ruletype = "K" and OrderRole <> "Anesthesia Physician" then
If ((PatientAge as number) > (RuleAge as number)) then
alert_message := "{{+B}} Ordered: "||OrderName || " " || DoseValue || " "|| UomValue|| ", " || SummaryLine
|| "\n This patient is " || patientage || " years old."
|| "\n\n {{+R}} " || Rulemsg || "{{-R}} {{-B}}";
doalert := true;
endif;
elseif RuleClass = classvalue and ruletype = "L" and (StopAfterOption = 0 and StopDtm is null) then
If RuleFreqQual = "Is" and Frequencygroup = RuleFreq then
alert_message := "{{+B}} Ordered: "||OrderName || " " || DoseValue || " "|| UomValue|| ", " || SummaryLine
|| "\n\n {{+R}} " || Rulemsg || "{{-R}} {{-B}}";
doalert := true;
elseif RuleFreqQual = "IsNot" and Frequencygroup <> RuleFreq then
alert_message := "{{+B}} Ordered: "||OrderName || " " || DoseValue || " "|| UomValue|| ", " || SummaryLine
|| "\n\n {{+R}} " || Rulemsg || "{{-R}} {{-B}}";
doalert := true;
endif;
elseif RuleClass = classvalue and ruletype = "M" and (StopAfterOption = 0 and StopDtm is null) then
//Digoxin alert only
If RuleFreqQual = "IsNot" and Frequencygroup not in ("Q24H","Q48H","OneTime") then
If UserCode = "RPh" then
alert_settings := "Must Comment";
else
alert_settings := "No Override Allowed";
endif;
alert_message := "{{+B}} Ordered: "||OrderName || " " || DoseValue || " "|| UomValue|| ", " || SummaryLine
|| "\n\n {{+R}} " || Rulemsg || "{{-R}} {{-B}}";
doalert := true;
endif;
else
nomessage := "";
endif;
enddo;
endif;
endif;
;;
priority: 50
;;
evoke: order_enter_event;
;;
logic:
if called_by_editor
then
conclude false;
endif;
//----------------------------------------------------------------
// If there is no evoking object then do nothing, this can
// only be true for the MLM Editor
//----------------------------------------------------------------
if EvokingObject is null
then
conclude false;
endif;
if continue = "no"
then
conclude false;
endif;
conclude doalert;
;;
action:
write alert_message at dose_alert_dest
;;
Urgency: 50;;
end: